From 7bbf6df39a7d1735f611f79aad83b282a83dc507 Mon Sep 17 00:00:00 2001 From: Dethrace Engineering Department <78985374+dethrace-labs@users.noreply.github.com> Date: Sat, 3 Dec 2022 14:14:28 +1300 Subject: [PATCH] Fix vehicle suspension so that it actually works (#252) * fixes suspension travel (#221) * tidy floats * Extra fixes (#253) Co-authored-by: Anonymous Maarten --- src/DETHRACE/common/car.c | 56 +++---- src/DETHRACE/common/world.c | 321 +++++++++++++++++++----------------- 2 files changed, 194 insertions(+), 183 deletions(-) diff --git a/src/DETHRACE/common/car.c b/src/DETHRACE/common/car.c index 761279f9..e23d4d18 100644 --- a/src/DETHRACE/common/car.c +++ b/src/DETHRACE/common/car.c @@ -4281,8 +4281,8 @@ void MungeCarGraphics(tU32 pFrame_period) { } else if (!gOn_me_wheels_start) { gOn_me_wheels_start = the_time; } else if (the_time - gOn_me_wheels_start > 500 - && (the_car->last_special_volume == NULL - || the_car->last_special_volume->gravity_multiplier == 1.0f)) { + && (the_car->last_special_volume == NULL + || the_car->last_special_volume->gravity_multiplier == 1.0f)) { DoFancyHeadup(kFancyHeadupCunningStuntBonus); EarnCredits(gCunning_stunt_bonus[gProgram_state.skill_level]); gLast_cunning_stunt = PDGetTotalTime(); @@ -4295,8 +4295,7 @@ void MungeCarGraphics(tU32 pFrame_period) { } } if (the_car->driver != eDriver_local_human && the_car->car_model_variable) { - distance_from_camera = Vector3DistanceSquared(&the_car->car_master_actor->t.t.translate.t, - (br_vector3*)gCamera_to_world.m[3]) / gCar_simplification_factor[gGraf_spec_index][gCar_simplification_level]; + distance_from_camera = Vector3DistanceSquared(&the_car->car_master_actor->t.t.translate.t, (br_vector3*)gCamera_to_world.m[3]) / gCar_simplification_factor[gGraf_spec_index][gCar_simplification_level]; if (gNet_mode != eNet_mode_none && gNet_players[gIt_or_fox].car == the_car) { distance_from_camera = 0.f; } @@ -4322,7 +4321,7 @@ void MungeCarGraphics(tU32 pFrame_period) { } else { if (gProgram_state.current_depth_effect.type == eDepth_effect_fog) { the_material = gProgram_state.standard_screen_fog; - } else if (gProgram_state.current_depth_effect.sky_texture != NULL) { + } else if (gProgram_state.current_depth_effect.sky_texture != NULL) { the_material = gProgram_state.standard_screen; } else { the_material = gProgram_state.standard_screen_dark; @@ -4448,12 +4447,12 @@ void ViewOpponent() { void ToggleCarToCarCollisions() { LOG_TRACE("()"); - gCar_car_collisions = !gCar_car_collisions; - if (gCar_car_collisions) { - NewTextHeadupSlot(4, 0, 3000, -4, "Car Car Collisions"); - } else { - NewTextHeadupSlot(4, 0, 3000, -4, "Ghost Cars"); - } + gCar_car_collisions = !gCar_car_collisions; + if (gCar_car_collisions) { + NewTextHeadupSlot(4, 0, 3000, -4, "Car Car Collisions"); + } else { + NewTextHeadupSlot(4, 0, 3000, -4, "Ghost Cars"); + } } // IDA: void __cdecl SwapCar() @@ -5536,7 +5535,7 @@ void FlyCar(tCar_spec* c, br_scalar dt) { static br_scalar vel = 0.f; tFace_ref faces[20]; tBounds bnds; - int i; // Added by DethRace + int i; // Added by DethRace br_scalar tmp_scalar1; // Added by DethRace br_scalar tmp_scalar2; // Added by DethRace br_vector3 tmp1; // Added by DethRace @@ -6915,32 +6914,27 @@ void SetCarSuspGiveAndHeight(tCar_spec* pCar, br_scalar pFront_give_factor, br_s int i; LOG_TRACE("(%p, %f, %f, %f, %f, %f)", pCar, pFront_give_factor, pRear_give_factor, pDamping_factor, pExtra_front_height, pExtra_rear_height); +#define UNK_SUSPENION_FACTOR 5.0f + front_give = pCar->susp_give[1] * pFront_give_factor * WORLD_SCALE; rear_give = pCar->susp_give[0] * pRear_give_factor * WORLD_SCALE; damping = pCar->damping * pDamping_factor; ratio = fabs((pCar->wpos[0].v[2] - pCar->cmpos.v[2]) / (pCar->wpos[2].v[2] - pCar->cmpos.v[2])); - pCar->sk[0] = pCar->M / (ratio + 1.0) * 5.0 / rear_give; - pCar->sb[0] = pCar->M / (ratio + 1.0) * sqrt(5.0) / sqrt(rear_give); - ratio = 1.0 / ratio; - pCar->sk[1] = pCar->M / (ratio + 1.0) * 5.0 / front_give; - pCar->sb[1] = pCar->M / (ratio + 1.0) * sqrt(5.0) / sqrt(front_give); - pCar->sb[0] = pCar->sb[0] * damping; - pCar->sb[1] = pCar->sb[1] * damping; + pCar->sk[0] = pCar->M / (ratio + 1.0f) * UNK_SUSPENION_FACTOR / rear_give; + pCar->sb[0] = pCar->M / (ratio + 1.0f) * sqrt(UNK_SUSPENION_FACTOR) / sqrt(rear_give); + ratio = 1.0f / ratio; + pCar->sk[1] = pCar->M / (ratio + 1.0f) * UNK_SUSPENION_FACTOR / front_give; + pCar->sb[1] = pCar->M / (ratio + 1.0f) * sqrt(UNK_SUSPENION_FACTOR) / sqrt(front_give); + + pCar->sb[0] *= damping; + pCar->sb[1] *= damping; pCar->susp_height[0] = pCar->ride_height + rear_give + pExtra_rear_height; pCar->susp_height[1] = pCar->ride_height + front_give + pExtra_front_height; - if (rear_give >= front_give) { - i = -rear_give; - } else { - i = -front_give; - } - if (pExtra_rear_height >= pExtra_front_height) { - i -= pExtra_rear_height; - } else { - i -= pExtra_front_height; - } - pCar->bounds[0].min.v[1] = i; - pCar->bounds[0].min.v[1] = pCar->bounds[0].min.v[1] / WORLD_SCALE; + pCar->bounds[0].min.v[1] = -MAX(rear_give, front_give) + -MAX(pExtra_rear_height, pExtra_front_height); + pCar->bounds[0].min.v[1] /= WORLD_SCALE; + +#undef UNK_SUSPENION_FACTOR } // IDA: int __usercall TestForCarInSensiblePlace@(tCar_spec *car@) diff --git a/src/DETHRACE/common/world.c b/src/DETHRACE/common/world.c index 96330835..2cabc9a3 100644 --- a/src/DETHRACE/common/world.c +++ b/src/DETHRACE/common/world.c @@ -850,12 +850,13 @@ void AddFunkGrooveBinding(int pSlot_number, float* pPeriod_address) { void ControlBoundFunkGroove(int pSlot_number, float pValue) { LOG_TRACE("(%d, %f)", pSlot_number, pValue); - if (pSlot_number >= 0) { - if (pSlot_number >= COUNT_OF(gGroove_funk_bindings)) { - FatalError(kFatalError_UsedRefNumGrooveFunkOutOfRange); - } - *gGroove_funk_bindings[pSlot_number] = pValue; + if (pSlot_number < 0) { + return; } + if (pSlot_number >= COUNT_OF(gGroove_funk_bindings)) { + FatalError(kFatalError_UsedRefNumGrooveFunkOutOfRange); + } + *gGroove_funk_bindings[pSlot_number] = pValue; } // IDA: float __usercall ControlBoundFunkGroovePlus@(int pSlot_number@, float pValue) @@ -1470,7 +1471,7 @@ void AddGroovidelics(FILE* pF, int pOwner, br_actor* pParent_actor, int pRef_off if (Vector3IsZero(&the_groove->path_data.straight_info.centre)) { BrVector3Copy(&the_groove->path_data.straight_info.centre, - &the_groove->actor->t.t.translate.t); + &the_groove->actor->t.t.translate.t); } if (the_groove->path_mode == eMove_controlled || the_groove->path_mode == eMove_absolute) { AddFunkGrooveBinding(pRef_offset + GetAnInt(pF), &the_groove->path_data.straight_info.period); @@ -2702,9 +2703,9 @@ void LoadTrack(char* pFile_name, tTrack_spec* pTrack_spec, tRace_info* pRace_inf GetThreeScalars(f, &spec->bounds.max.v[0], &spec->bounds.max.v[1], &spec->bounds.max.v[2]); BrMatrix34Identity(&spec->mat); for (k = 0; k < 3; ++k) { - // FIXME: not 100% sure this is correct - spec->mat.m[3][k] = (spec->bounds.max.v[k] + spec->bounds.min.v[k]) / 2.f; - spec->mat.m[k][k] = spec->bounds.max.v[k] - spec->bounds.min.v[k]; + // FIXME: not 100% sure this is correct + spec->mat.m[3][k] = (spec->bounds.max.v[k] + spec->bounds.min.v[k]) / 2.f; + spec->mat.m[k][k] = spec->bounds.max.v[k] - spec->bounds.min.v[k]; } ParseSpecialVolume(f, spec, NULL); } @@ -2980,49 +2981,48 @@ br_scalar NormaliseDegreeAngle(br_scalar pAngle) { return pAngle; } - #define SAW(T, PERIOD) (fmodf((T), (PERIOD)) / (PERIOD)) -#define MOVE_FUNK_PARAMETER(DEST, MODE, PERIOD, AMPLITUDE, FLASH_VALUE) \ - do { \ - switch (MODE) { \ - case eMove_continuous: \ - if ((PERIOD) == 0.f) { \ - DEST = 0.f; \ - } else { \ - DEST = (AMPLITUDE) * SAW(f_the_time, (PERIOD)); \ - } \ - break; \ - case eMove_controlled: \ - DEST = (PERIOD) * (AMPLITUDE); \ - break; \ - case eMove_absolute: \ - DEST = (PERIOD); \ - break; \ - case eMove_linear: \ - if ((PERIOD) == 0.f) { \ - DEST = 0.f; \ - } else { \ - DEST = (AMPLITUDE) * MapSawToTriangle(SAW(f_the_time, (PERIOD))); \ - } \ - break; \ - case eMove_flash: \ - if (2 * fmodf(f_the_time, (PERIOD)) > (PERIOD)) { \ - DEST = (FLASH_VALUE); \ - } else { \ - DEST = -(FLASH_VALUE); \ - } \ - break; \ - case eMove_harmonic: \ - if ((PERIOD) == 0.f) { \ - DEST = 0.f; \ - } else { \ - DEST = (AMPLITUDE) * BR_SIN(BR_ANGLE_DEG(SAW(f_the_time, (PERIOD)) * 360)); \ - } \ - break; \ - default: \ - TELL_ME_IF_WE_PASS_THIS_WAY(); \ - } \ +#define MOVE_FUNK_PARAMETER(DEST, MODE, PERIOD, AMPLITUDE, FLASH_VALUE) \ + do { \ + switch (MODE) { \ + case eMove_continuous: \ + if ((PERIOD) == 0.f) { \ + DEST = 0.f; \ + } else { \ + DEST = (AMPLITUDE)*SAW(f_the_time, (PERIOD)); \ + } \ + break; \ + case eMove_controlled: \ + DEST = (PERIOD) * (AMPLITUDE); \ + break; \ + case eMove_absolute: \ + DEST = (PERIOD); \ + break; \ + case eMove_linear: \ + if ((PERIOD) == 0.f) { \ + DEST = 0.f; \ + } else { \ + DEST = (AMPLITUDE)*MapSawToTriangle(SAW(f_the_time, (PERIOD))); \ + } \ + break; \ + case eMove_flash: \ + if (2 * fmodf(f_the_time, (PERIOD)) > (PERIOD)) { \ + DEST = (FLASH_VALUE); \ + } else { \ + DEST = -(FLASH_VALUE); \ + } \ + break; \ + case eMove_harmonic: \ + if ((PERIOD) == 0.f) { \ + DEST = 0.f; \ + } else { \ + DEST = (AMPLITUDE)*BR_SIN(BR_ANGLE_DEG(SAW(f_the_time, (PERIOD)) * 360)); \ + } \ + break; \ + default: \ + TELL_ME_IF_WE_PASS_THIS_WAY(); \ + } \ } while (0) // IDA: void __cdecl FunkThoseTronics() @@ -3323,50 +3323,51 @@ void PathGrooveBastard(tGroovidelic_spec* pGroove, tU32 pTime, br_matrix34* pMat br_scalar pos; LOG_TRACE("(%p, %d, %p, %d)", pGroove, pTime, pMat, pInterrupt_it); - pos = 0; if (pGroove->path_type == eGroove_path_straight) { - if (pGroove->path_data.straight_info.x_delta != 0.0) { + if (pGroove->path_data.straight_info.x_delta != 0.0f) { switch (pGroove->path_mode) { case eMove_continuous: - if (pGroove->path_data.straight_info.period != 0.0) { - pos = fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.x_delta; + if (pGroove->path_data.straight_info.period == 0.0f) { + pos = 0.f; + } else { + pos = fmodf(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.x_delta; } break; case eMove_controlled: pos = pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.x_delta; break; - case eMove_absolute: pos = pGroove->path_data.straight_info.period; break; case eMove_flash: - if (fmod(pTime, pGroove->path_data.straight_info.period) * 2.0 <= pGroove->path_data.straight_info.period) { + if (fmodf(pTime, pGroove->path_data.straight_info.period) * 2.0f <= pGroove->path_data.straight_info.period) { pos = pGroove->path_data.straight_info.x_delta; } else { pos = -pGroove->path_data.straight_info.x_delta; } break; case eMove_harmonic: - if (pGroove->path_data.straight_info.period != 0.0) { - pos = sin( - BrAngleToRadian( - BrDegreeToAngle( - fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * 360.0))) + if (pGroove->path_data.straight_info.period == 0.0f) { + pos = 0.f; + } else { + pos = sinf(BrAngleToRadian(BrDegreeToAngle(fmodf(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * 360.0f))) * pGroove->path_data.straight_info.x_delta; } break; case eMove_linear: - if (pGroove->path_data.straight_info.period != 0.0) { - pos = MapSawToTriangle(fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period) + if (pGroove->path_data.straight_info.period == 0.0f) { + pos = 0.f; + } else { + pos = MapSawToTriangle(fmodf(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period) * pGroove->path_data.straight_info.x_delta; } break; - case eMove_none: - break; + default: + TELL_ME_IF_WE_PASS_THIS_WAY(); } - pos = pGroove->path_data.straight_info.centre.v[0] + pos; + pos += pGroove->path_data.straight_info.centre.v[0]; if (pInterrupt_it) { pGroove->path_resumption_value = pos; if (pMat->m[3][0] <= pos) { @@ -3374,63 +3375,65 @@ void PathGrooveBastard(tGroovidelic_spec* pGroove, tU32 pTime, br_matrix34* pMat } else { pGroove->path_interrupt_status = eInterrupt_less_than; } - } else if (pGroove->path_interrupt_status) { - if (pGroove->path_interrupt_status == eInterrupt_less_than) { - if (pGroove->path_resumption_value > pos) { - pGroove->path_interrupt_status = eInterrupt_none; - pGroove->actor->t.t.translate.t = pGroove->path_data.straight_info.centre; - pMat->m[3][0] = pos; - } - } else if (pGroove->path_resumption_value < pos) { + } else if (pGroove->path_interrupt_status == eInterrupt_none) { + BrVector3Copy(&pGroove->actor->t.t.translate.t, &pGroove->path_data.straight_info.centre); + pMat->m[3][0] = pos; + } else if (pGroove->path_interrupt_status == eInterrupt_less_than) { + if (pGroove->path_resumption_value > pos) { pGroove->path_interrupt_status = eInterrupt_none; - pGroove->actor->t.t.euler.t = pGroove->path_data.straight_info.centre; + BrVector3Copy(&pGroove->actor->t.t.translate.t, &pGroove->path_data.straight_info.centre); pMat->m[3][0] = pos; } + } else if (pGroove->path_resumption_value < pos) { + pGroove->path_interrupt_status = eInterrupt_none; + BrVector3Copy(&pGroove->actor->t.t.euler.t, &pGroove->path_data.straight_info.centre); + pMat->m[3][0] = pos; } } - if (pGroove->path_data.straight_info.y_delta != 0.0) { - pos = 0; + if (pGroove->path_data.straight_info.y_delta != 0.0f) { switch (pGroove->path_mode) { case eMove_continuous: - if (pGroove->path_data.straight_info.period != 0.0) { - pos = fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.y_delta; + if (pGroove->path_data.straight_info.period == 0.0f) { + pos = 0.f; + } else { + pos = fmodf(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.y_delta; } break; case eMove_controlled: pos = pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.y_delta; break; - case eMove_absolute: pos = pGroove->path_data.straight_info.period; break; case eMove_flash: - if (fmod(pTime, pGroove->path_data.straight_info.period) * 2.0 <= pGroove->path_data.straight_info.period) { + if (fmodf(pTime, pGroove->path_data.straight_info.period) * 2.0f <= pGroove->path_data.straight_info.period) { pos = pGroove->path_data.straight_info.y_delta; } else { pos = -pGroove->path_data.straight_info.y_delta; } break; case eMove_harmonic: - if (pGroove->path_data.straight_info.period != 0.0) { - pos = sin( - BrAngleToRadian( - BrDegreeToAngle( - fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * 360.0))) + if (pGroove->path_data.straight_info.period == 0.0) { + pos = 0.f; + } else { + pos = sinf(BrAngleToRadian(BrDegreeToAngle(fmodf(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * 360.0f))) * pGroove->path_data.straight_info.y_delta; } break; case eMove_linear: - if (pGroove->path_data.straight_info.period != 0.0) { - pos = MapSawToTriangle(fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period) + if (pGroove->path_data.straight_info.period == 0.0f) { + pos = 0.f; + } else { + pos = MapSawToTriangle(fmodf(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period) * pGroove->path_data.straight_info.y_delta; } break; - case eMove_none: - break; + default: + TELL_ME_IF_WE_PASS_THIS_WAY(); } - pos = pGroove->path_data.straight_info.centre.v[1] + pos; + pos += pGroove->path_data.straight_info.centre.v[1]; if (pInterrupt_it) { pGroove->path_resumption_value = pos; if (pMat->m[3][1] <= pos) { @@ -3438,27 +3441,29 @@ void PathGrooveBastard(tGroovidelic_spec* pGroove, tU32 pTime, br_matrix34* pMat } else { pGroove->path_interrupt_status = eInterrupt_less_than; } - } else if (pGroove->path_interrupt_status) { - if (pGroove->path_interrupt_status == eInterrupt_less_than) { - if (pGroove->path_resumption_value > pos) { - pGroove->path_interrupt_status = eInterrupt_none; - pGroove->actor->t.t.translate.t = pGroove->path_data.straight_info.centre; - pMat->m[3][1] = pos; - } - } else if (pGroove->path_resumption_value < pos) { + } else if (pGroove->path_interrupt_status == eInterrupt_none) { + BrVector3Copy(&pGroove->actor->t.t.translate.t, &pGroove->path_data.straight_info.centre); + pMat->m[3][1] = pos; + } else if (pGroove->path_interrupt_status == eInterrupt_less_than) { + if (pGroove->path_resumption_value > pos) { pGroove->path_interrupt_status = eInterrupt_none; - pGroove->actor->t.t.euler.t = pGroove->path_data.straight_info.centre; + BrVector3Copy(&pGroove->actor->t.t.translate.t, &pGroove->path_data.straight_info.centre); pMat->m[3][1] = pos; } + } else if (pGroove->path_resumption_value < pos) { + pGroove->path_interrupt_status = eInterrupt_none; + pGroove->actor->t.t.euler.t = pGroove->path_data.straight_info.centre; + pMat->m[3][1] = pos; } } - if (pGroove->path_data.straight_info.z_delta != 0.0) { - pos = 0; + if (pGroove->path_data.straight_info.z_delta != 0.0f) { switch (pGroove->path_mode) { case eMove_continuous: - if (pGroove->path_data.straight_info.period != 0.0) { - pos = fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.z_delta; + if (pGroove->path_data.straight_info.period == 0.0f) { + pos = 0.f; + } else { + pos = fmodf(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.z_delta; } break; case eMove_controlled: @@ -3468,32 +3473,33 @@ void PathGrooveBastard(tGroovidelic_spec* pGroove, tU32 pTime, br_matrix34* pMat pos = pGroove->path_data.straight_info.period; break; case eMove_flash: - if (fmod(pTime, pGroove->path_data.straight_info.period) * 2.0 <= pGroove->path_data.straight_info.period) { + if (fmodf(pTime, pGroove->path_data.straight_info.period) * 2.0f <= pGroove->path_data.straight_info.period) { pos = pGroove->path_data.straight_info.z_delta; } else { pos = -pGroove->path_data.straight_info.z_delta; } break; case eMove_harmonic: - if (pGroove->path_data.straight_info.period != 0.0) { - pos = sin( - BrAngleToRadian( - BrDegreeToAngle( - fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * 360.0))) + if (pGroove->path_data.straight_info.period == 0.0f) { + pos = 0.f; + } else { + pos = sinf(BrAngleToRadian(BrDegreeToAngle(fmodf(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * 360.0f))) * pGroove->path_data.straight_info.z_delta; } break; case eMove_linear: - if (pGroove->path_data.straight_info.period != 0.0) { - pos = MapSawToTriangle(fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period) + if (pGroove->path_data.straight_info.period == 0.0f) { + pos = 0.f; + } else { + pos = MapSawToTriangle(fmodf(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period) * pGroove->path_data.straight_info.z_delta; } break; - case eMove_none: - break; + default: + TELL_ME_IF_WE_PASS_THIS_WAY(); } - pos = pGroove->path_data.straight_info.centre.v[1] + pos; + pos += pGroove->path_data.straight_info.centre.v[1]; if (pInterrupt_it) { pGroove->path_resumption_value = pos; if (pMat->m[3][2] <= pos) { @@ -3501,62 +3507,74 @@ void PathGrooveBastard(tGroovidelic_spec* pGroove, tU32 pTime, br_matrix34* pMat } else { pGroove->path_interrupt_status = eInterrupt_less_than; } - } else if (pGroove->path_interrupt_status) { - if (pGroove->path_interrupt_status == eInterrupt_less_than) { + } else { + if (pGroove->path_interrupt_status == eInterrupt_none) { + BrVector3Copy(&pGroove->actor->t.t.translate.t, &pGroove->path_data.straight_info.centre); + pMat->m[3][2] = pos; + } else if (pGroove->path_interrupt_status == eInterrupt_less_than) { if (pGroove->path_resumption_value > pos) { pGroove->path_interrupt_status = eInterrupt_none; - pGroove->actor->t.t.translate.t = pGroove->path_data.straight_info.centre; + BrVector3Copy(&pGroove->actor->t.t.translate.t, &pGroove->path_data.straight_info.centre); pMat->m[3][2] = pos; } } else if (pGroove->path_resumption_value < pos) { pGroove->path_interrupt_status = eInterrupt_none; - pGroove->actor->t.t.euler.t = pGroove->path_data.straight_info.centre; + BrVector3Copy(&pGroove->actor->t.t.translate.t, &pGroove->path_data.straight_info.centre); pMat->m[3][2] = pos; } } } - pGroove->object_position = pGroove->actor->t.t.translate.t; + BrVector3Copy(&pGroove->object_position, &pGroove->actor->t.t.translate.t); } else if (pGroove->path_type == eGroove_path_circular) { - pGroove->actor->t.t.translate.t = pGroove->path_data.circular_info.centre; + BrVector3Copy(&pGroove->actor->t.t.translate.t, &pGroove->path_data.circular_info.centre); if (pGroove->path_data.circular_info.axis == eGroove_axis_y) { - if (pGroove->path_data.circular_info.period != 0.0) { - pos = cos(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius; - pMat->m[3][0] = pGroove->path_data.circular_info.centre.v[0] + pos; + if (pGroove->path_data.circular_info.period == 0.0f) { + pos = 0.f; + } else { + pos = cosf(BrAngleToRadian(BrDegreeToAngle(fmodf(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0f))) * pGroove->path_data.circular_info.radius; } - + pMat->m[3][0] = pGroove->path_data.circular_info.centre.v[0] + pos; } else if (pGroove->path_data.circular_info.axis == eGroove_axis_z) { - if (pGroove->path_data.circular_info.period != 0.0) { - pos = sin(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius; - pMat->m[3][0] = pGroove->path_data.circular_info.centre.v[0] + pos; - } - } - if (pGroove->path_data.circular_info.axis) { - if (pGroove->path_data.circular_info.axis == eGroove_axis_z) { - if (pGroove->path_data.circular_info.period != 0.0) { - pos = cos(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius; - pMat->m[3][1] = pGroove->path_data.circular_info.centre.v[1] + pos; - } + if (pGroove->path_data.circular_info.period == 0.0f) { + pos = 0.f; } else { - if (pGroove->path_data.circular_info.period != 0.0) { - pos = sin(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius; - pMat->m[3][1] = pGroove->path_data.circular_info.centre.v[1] + pos; - } + pos = sinf(BrAngleToRadian(BrDegreeToAngle(fmodf(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0f))) * pGroove->path_data.circular_info.radius; } + pMat->m[3][0] = pGroove->path_data.circular_info.centre.v[0] + pos; } - if (pGroove->path_data.circular_info.axis) { - if (pGroove->path_data.circular_info.axis == eGroove_axis_y) { - if (pGroove->path_data.circular_info.period != 0.0) { - pos = sin(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius; - pMat->m[3][2] = pGroove->path_data.circular_info.centre.v[2] + pos; - } + + if (pGroove->path_data.circular_info.axis == eGroove_axis_x) { + if (pGroove->path_data.circular_info.period == 0.0f) { + pos = 0.f; } else { - if (pGroove->path_data.circular_info.period != 0.0) { - pos = cos(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius; - pMat->m[3][2] = pGroove->path_data.circular_info.centre.v[2] + pos; - } + pos = sinf(BrAngleToRadian(BrDegreeToAngle(fmodf(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0f))) * pGroove->path_data.circular_info.radius; } - pGroove->object_position = pGroove->actor->t.t.translate.t; + pMat->m[3][1] = pGroove->path_data.circular_info.centre.v[1] + pos; + } else if (pGroove->path_data.circular_info.axis == eGroove_axis_z) { + if (pGroove->path_data.circular_info.period == 0.0f) { + pos = 0.f; + } else { + pos = cosf(BrAngleToRadian(BrDegreeToAngle(fmodf(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0f))) * pGroove->path_data.circular_info.radius; + } + pMat->m[3][1] = pGroove->path_data.circular_info.centre.v[1] + pos; } + + if (pGroove->path_data.circular_info.axis == eGroove_axis_x) { + if (pGroove->path_data.circular_info.period == 0.0f) { + pos = 0.f; + } else { + pos = cosf(BrAngleToRadian(BrDegreeToAngle(fmodf(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0f))) * pGroove->path_data.circular_info.radius; + } + pMat->m[3][2] = pGroove->path_data.circular_info.centre.v[1] + pos; + } else if (pGroove->path_data.circular_info.axis == eGroove_axis_z) { + if (pGroove->path_data.circular_info.period == 0.0f) { + pos = 0.f; + } else { + pos = sinf(BrAngleToRadian(BrDegreeToAngle(fmodf(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0f))) * pGroove->path_data.circular_info.radius; + } + pMat->m[3][2] = pGroove->path_data.circular_info.centre.v[1] + pos; + } + BrVector3Copy(&pGroove->object_position, &pGroove->actor->t.t.translate.t); } } @@ -4378,7 +4396,6 @@ void DropActor(int pIndex) { BrVector3Set(&side_vector, 0.f, -1.f, 0.f); } else { BrVector3Set(&side_vector, 0.f, 0.f, -1.f); - } new_transform.type = BR_TRANSFORM_LOOK_UP; BrVector3Cross(&new_transform.t.look_up.look, &the_list[face_bastard].normal, &side_vector);