From 1a884666eccef1d8a199038342f07b818e4ad25a Mon Sep 17 00:00:00 2001 From: Dethrace Engineering Department <78985374+dethrace-labs@users.noreply.github.com> Date: Thu, 5 May 2022 05:05:52 +1200 Subject: [PATCH] Offroad effects (#128) * dust and bumpiness --- src/DETHRACE/common/car.c | 28 ++++++++++++++++++--- src/DETHRACE/common/spark.c | 50 +++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/DETHRACE/common/car.c b/src/DETHRACE/common/car.c index 5a3c1099..338062e9 100644 --- a/src/DETHRACE/common/car.c +++ b/src/DETHRACE/common/car.c @@ -999,9 +999,9 @@ void FinishCars(tU32 pLast_frame_time, tU32 pTime) { car->lf_sus_position = (car->ride_height - car->oldd[2]) / WORLD_SCALE; car->rf_sus_position = (car->ride_height - car->oldd[3]) / WORLD_SCALE; for (wheel = 0; wheel < 4; wheel++) { - if (car->oldd[wheel] < car->susp_height[wheel >> 1] && gCurrent_race.material_modifiers[car->material_index[wheel]].smoke_type >= 2 - && !car->doing_nothing_flag) + if (car->oldd[wheel] < car->susp_height[wheel >> 1] && gCurrent_race.material_modifiers[car->material_index[wheel]].smoke_type >= 2 && !car->doing_nothing_flag) { GenerateContinuousSmoke(car, wheel, pTime); + } } } } @@ -1698,7 +1698,29 @@ void DoBumpiness(tCar_spec* c, br_vector3* wheel_pos, br_vector3* norm, br_scala tMaterial_modifiers* mat_list; LOG_TRACE("(%p, %p, %p, %p, %d)", c, wheel_pos, norm, d, n); - STUB_ONCE(); + tv.v[0] = c->nor[n].v[0] * d[n] + wheel_pos[n].v[0]; + tv.v[2] = c->nor[n].v[2] * d[n] + wheel_pos[n].v[2]; + + x = abs((int)(512.0f * tv.v[0])) % 2048; + y = abs((int)(512.0f * tv.v[2])) % 2048; + + if (x > 1024) { + x = 2048 - x; + } + if (y > 1024) { + y = 2048 - y; + } + if (x + y <= 1024) { + delta = x + y; + } else { + delta = 2048 - x - y; + } + delta -= 400; + if (delta < 0) { + delta = 0; + } + mat_list = gCurrent_race.material_modifiers; + d[n] = delta * mat_list[c->material_index[n]].bumpiness / 42400.0f * norm[n].v[1] + d[n]; } // IDA: void __usercall CalcForce(tCar_spec *c@, br_scalar dt) diff --git a/src/DETHRACE/common/spark.c b/src/DETHRACE/common/spark.c index 5a1b6b9f..26990f41 100644 --- a/src/DETHRACE/common/spark.c +++ b/src/DETHRACE/common/spark.c @@ -1106,7 +1106,53 @@ void GenerateContinuousSmoke(tCar_spec* pCar, int wheel, tU32 pTime) { int colour; LOG_TRACE("(%p, %d, %d)", pCar, wheel, pTime); - STUB_ONCE(); + if (pCar->dust_time[wheel] > pTime) { + pCar->dust_time[wheel] -= pTime; + return; + } + pCar->dust_time[wheel] += IRandomBetween(200, 400) - pTime; + if (pCar->dust_time[wheel] < 0) { + pCar->dust_time[wheel] = 0; + } + BrVector3Cross(&tv, &pCar->omega, &pCar->wpos[wheel]); + BrVector3Scale(&vcs, &pCar->velocity_car_space, WORLD_SCALE * 1000.0f); + BrVector3Accumulate(&vcs, &tv); + ts = BrVector3LengthSquared(&vcs); + if (ts < 25.0f) { + return; + } + decay_factor = sqrtf(ts) / 25.0f; + if (decay_factor > 1.0f) { + decay_factor = 1.0f; + } + BrVector3InvScale(&tv, &pCar->wpos[wheel], WORLD_SCALE); + tv.v[1] -= pCar->oldd[wheel] / WORLD_SCALE; + + alpha = -1000.0f; + if (vcs.v[2] > 0.0f) { + alpha = (pCar->bounds[0].min.v[2] - tv.v[2]) / vcs.v[2]; + } else if (vcs.v[2] < 0.0f) { + alpha = (pCar->bounds[0].max.v[2] - tv.v[2]) / vcs.v[2]; + } + + beta = -1000.0f; + if (vcs.v[0] > 0.0f) { + beta = (pCar->bounds[0].min.v[0] - tv.v[0]) / vcs.v[0]; + } else if (vcs.v[0] < 0.0f) { + beta = (pCar->bounds[0].max.v[0] - tv.v[0]) / vcs.v[0]; + } + + ts = MAX(alpha, beta); + BrVector3Scale(&pos, &vcs, ts); + BrVector3Accumulate(&tv, &pos); + BrMatrix34ApplyP(&pos, &tv, &pCar->car_master_actor->t.t.mat); + BrMatrix34ApplyV(&v, &vcs, &pCar->car_master_actor->t.t.mat); + + colour = gDust_rotate + gCurrent_race.material_modifiers[pCar->material_index[wheel]].smoke_type - 2; + while (colour >= gNum_dust_tables) { + colour -= gNum_dust_tables; + } + CreatePuffOfSmoke(&pos, &v, decay_factor, decay_factor * 2, colour + 8, pCar); } // IDA: void __cdecl DustRotate() @@ -1234,7 +1280,7 @@ void CreatePuffOfSmoke(br_vector3* pos, br_vector3* v, br_scalar strength, br_sc } BrVector3InvScale(&gSmoke[gSmoke_num].v, v, WORLD_SCALE); - gSmoke[gSmoke_num].v.v[1] = gSmoke[gSmoke_num].v.v[1] + 0.1449275362318841; + gSmoke[gSmoke_num].v.v[1] = gSmoke[gSmoke_num].v.v[1] + (1.0f / WORLD_SCALE); gSmoke[gSmoke_num].pos = *pos; gSmoke[gSmoke_num].radius = 0.05; if ((pType & 0xF) == 7) {