From 914c16d1d6bd5be910f2633cb443cbecab70363d Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Sat, 28 Dec 2024 19:55:55 +0000 Subject: [PATCH] tr2/lara/hair: refactor hair control This separates out the interpolated and non-interpolated control into their own functions for improved readability. --- src/tr2/game/lara/hair.c | 357 ++++++++++++++++++++------------------- 1 file changed, 185 insertions(+), 172 deletions(-) diff --git a/src/tr2/game/lara/hair.c b/src/tr2/game/lara/hair.c index 02b3a577d..6aceec297 100644 --- a/src/tr2/game/lara/hair.c +++ b/src/tr2/game/lara/hair.c @@ -18,11 +18,190 @@ typedef struct __PACKING { } HAIR_SEGMENT; static bool m_IsFirstHair; +static SPHERE m_HairSpheres[HAIR_SEGMENTS - 1]; static XYZ_32 m_HairVelocity[HAIR_SEGMENTS + 1]; static HAIR_SEGMENT m_HairSegments[HAIR_SEGMENTS + 1]; static int32_t m_HairWind; -void Lara_Hair_Initialise(void) +static void M_CalculateSpheres(const FRAME_INFO *frame); +static void M_CalculateSpheres_I( + const FRAME_INFO *frame1, const FRAME_INFO *frame2, int32_t frac, + int32_t rate); + +static void M_CalculateSpheres(const FRAME_INFO *const frame) +{ + const int16_t *mesh_rots = frame->mesh_rots; + Matrix_TranslateRel(frame->offset.x, frame->offset.y, frame->offset.z); + Matrix_RotYXZsuperpack(&mesh_rots, 0); + + Matrix_Push(); + const int16_t *mesh = g_Lara.mesh_ptrs[LM_HIPS]; + Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); + m_HairSpheres[0].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[0].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[0].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[0].r = mesh[3]; + Matrix_Pop(); + + const int32_t *bone = &g_AnimBones[g_Objects[O_LARA].bone_idx]; + Matrix_TranslateRel(bone[25], bone[26], bone[27]); + if (g_Lara.weapon_item != NO_ITEM && g_Lara.gun_type == LGT_M16 + && (g_Items[g_Lara.weapon_item].current_anim_state == 0 + || g_Items[g_Lara.weapon_item].current_anim_state == 2 + || g_Items[g_Lara.weapon_item].current_anim_state == 4)) { + mesh_rots = + &g_Lara.right_arm.frame_base + [g_Lara.right_arm.frame_num + * (g_Anims[g_Lara.right_arm.anim_num].interpolation >> 8) + + FBBOX_ROT]; + Matrix_RotYXZsuperpack(&mesh_rots, 7); + } else { + Matrix_RotYXZsuperpack(&mesh_rots, 6); + } + Matrix_RotYXZ(g_Lara.torso_y_rot, g_Lara.torso_x_rot, g_Lara.torso_z_rot); + Matrix_Push(); + mesh = g_Lara.mesh_ptrs[LM_TORSO]; + Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); + m_HairSpheres[1].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[1].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[1].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[1].r = mesh[3]; + Matrix_Pop(); + + Matrix_Push(); + Matrix_TranslateRel(bone[29], bone[30], bone[31]); + Matrix_RotYXZsuperpack(&mesh_rots, 0); + + mesh = g_Lara.mesh_ptrs[LM_UARM_R]; + Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); + m_HairSpheres[3].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[3].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[3].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[3].r = mesh[3] * 3 / 2; + Matrix_Pop(); + + Matrix_Push(); + Matrix_TranslateRel(bone[41], bone[42], bone[43]); + Matrix_RotYXZsuperpack(&mesh_rots, 2); + mesh = g_Lara.mesh_ptrs[LM_UARM_L]; + Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); + m_HairSpheres[4].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[4].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[4].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[4].r = mesh[3] * 3 / 2; + Matrix_Pop(); + + Matrix_TranslateRel(bone[53], bone[54], bone[55]); + Matrix_RotYXZsuperpack(&mesh_rots, 2); + Matrix_RotYXZ(g_Lara.head_y_rot, g_Lara.head_x_rot, g_Lara.head_z_rot); + + Matrix_Push(); + mesh = g_Lara.mesh_ptrs[LM_HEAD]; + Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); + m_HairSpheres[2].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[2].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[2].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[2].r = mesh[3]; + Matrix_Pop(); + + Matrix_TranslateRel(0, -23, -55); +} + +static void M_CalculateSpheres_I( + const FRAME_INFO *const frame1, const FRAME_INFO *const frame2, + const int32_t frac, const int32_t rate) +{ + const int16_t *mesh_rots1 = frame1->mesh_rots; + const int16_t *mesh_rots2 = frame2->mesh_rots; + Matrix_InitInterpolate(frac, rate); + Matrix_TranslateRel_ID( + frame1->offset.x, frame1->offset.y, frame1->offset.z, frame2->offset.x, + frame2->offset.y, frame2->offset.z); + Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 0); + + Matrix_Push_I(); + const int16_t *mesh = g_Lara.mesh_ptrs[LM_HIPS]; + Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); + Matrix_Interpolate(); + m_HairSpheres[0].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[0].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[0].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[0].r = mesh[3]; + Matrix_Pop_I(); + + const int32_t *bone = &g_AnimBones[g_Objects[O_LARA].bone_idx]; + Matrix_TranslateRel_I(bone[25], bone[26], bone[27]); + if (g_Lara.weapon_item != NO_ITEM && g_Lara.gun_type == LGT_M16 + && (g_Items[g_Lara.weapon_item].current_anim_state == 0 + || g_Items[g_Lara.weapon_item].current_anim_state == 2 + || g_Items[g_Lara.weapon_item].current_anim_state == 4)) { + mesh_rots1 = + &g_Lara.right_arm.frame_base + [g_Lara.right_arm.frame_num + * (g_Anims[g_Lara.right_arm.anim_num].interpolation >> 8) + + FBBOX_ROT]; + mesh_rots2 = mesh_rots1; + Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 7); + } else { + Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 6); + } + Matrix_RotYXZ_I(g_Lara.torso_y_rot, g_Lara.torso_x_rot, g_Lara.torso_z_rot); + + Matrix_Push_I(); + mesh = g_Lara.mesh_ptrs[LM_TORSO]; + Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); + Matrix_Interpolate(); + m_HairSpheres[1].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[1].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[1].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[1].r = mesh[3]; + Matrix_Pop_I(); + + Matrix_Push_I(); + Matrix_TranslateRel_I(bone[29], bone[30], bone[31]); + Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 0); + + mesh = g_Lara.mesh_ptrs[LM_UARM_R]; + Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); + Matrix_Interpolate(); + m_HairSpheres[3].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[3].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[3].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[3].r = mesh[3] * 3 / 2; + Matrix_Pop_I(); + + Matrix_Push_I(); + Matrix_TranslateRel_I(bone[41], bone[42], bone[43]); + Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 2); + + mesh = g_Lara.mesh_ptrs[LM_UARM_L]; + Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); + Matrix_Interpolate(); + m_HairSpheres[4].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[4].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[4].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[4].r = mesh[3] * 3 / 2; + Matrix_Pop_I(); + + Matrix_TranslateRel_I(bone[53], bone[54], bone[55]); + Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 2); + Matrix_RotYXZ_I(g_Lara.head_y_rot, g_Lara.head_x_rot, g_Lara.head_z_rot); + + Matrix_Push_I(); + mesh = g_Lara.mesh_ptrs[LM_HEAD]; + Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); + Matrix_Interpolate(); + m_HairSpheres[2].x = g_MatrixPtr->_03 >> W2V_SHIFT; + m_HairSpheres[2].y = g_MatrixPtr->_13 >> W2V_SHIFT; + m_HairSpheres[2].z = g_MatrixPtr->_23 >> W2V_SHIFT; + m_HairSpheres[2].r = mesh[3]; + Matrix_Pop_I(); + + Matrix_TranslateRel_I(0, -23, -55); + Matrix_Interpolate(); +} + +void __cdecl Lara_Hair_Initialise(void) { const int32_t *const bone_base = &g_AnimBones[g_Objects[O_LARA_HAIR].bone_idx]; @@ -78,182 +257,16 @@ void Lara_Hair_Control(const bool in_cutscene) frac = 0; } - const int32_t *bone; - const int16_t *mesh; - SPHERE spheres[5]; - Matrix_PushUnit(); g_MatrixPtr->_03 = g_LaraItem->pos.x << W2V_SHIFT; g_MatrixPtr->_13 = g_LaraItem->pos.y << W2V_SHIFT; g_MatrixPtr->_23 = g_LaraItem->pos.z << W2V_SHIFT; Matrix_RotYXZ(g_LaraItem->rot.y, g_LaraItem->rot.x, g_LaraItem->rot.z); - if (frac != 0) { - const int16_t *mesh_rots1 = frame1->mesh_rots; - const int16_t *mesh_rots2 = frame2->mesh_rots; - Matrix_InitInterpolate(frac, rate); - Matrix_TranslateRel_ID( - frame1->offset.x, frame1->offset.y, frame1->offset.z, - frame2->offset.x, frame2->offset.y, frame2->offset.z); - Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 0); - - Matrix_Push_I(); - mesh = g_Lara.mesh_ptrs[LM_HIPS]; - Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); - Matrix_Interpolate(); - spheres[0].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[0].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[0].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[0].r = mesh[3]; - Matrix_Pop_I(); - - bone = &g_AnimBones[g_Objects[O_LARA].bone_idx]; - Matrix_TranslateRel_I(bone[25], bone[26], bone[27]); - if (g_Lara.weapon_item != NO_ITEM && g_Lara.gun_type == LGT_M16 - && (g_Items[g_Lara.weapon_item].current_anim_state == 0 - || g_Items[g_Lara.weapon_item].current_anim_state == 2 - || g_Items[g_Lara.weapon_item].current_anim_state == 4)) { - mesh_rots1 = - &g_Lara.right_arm.frame_base - [g_Lara.right_arm.frame_num - * (g_Anims[g_Lara.right_arm.anim_num].interpolation - >> 8) - + FBBOX_ROT]; - mesh_rots2 = mesh_rots1; - Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 7); - } else { - Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 6); - } - Matrix_RotYXZ_I( - g_Lara.torso_y_rot, g_Lara.torso_x_rot, g_Lara.torso_z_rot); - - Matrix_Push_I(); - mesh = g_Lara.mesh_ptrs[LM_TORSO]; - Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); - Matrix_Interpolate(); - spheres[1].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[1].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[1].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[1].r = mesh[3]; - Matrix_Pop_I(); - - Matrix_Push_I(); - Matrix_TranslateRel_I(bone[29], bone[30], bone[31]); - Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 0); - - mesh = g_Lara.mesh_ptrs[LM_UARM_R]; - Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); - Matrix_Interpolate(); - spheres[3].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[3].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[3].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[3].r = mesh[3] * 3 / 2; - Matrix_Pop_I(); - - Matrix_Push_I(); - Matrix_TranslateRel_I(bone[41], bone[42], bone[43]); - Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 2); - mesh = g_Lara.mesh_ptrs[LM_UARM_L]; - Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); - Matrix_Interpolate(); - spheres[4].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[4].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[4].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[4].r = mesh[3] * 3 / 2; - Matrix_Pop_I(); - - Matrix_TranslateRel_I(bone[53], bone[54], bone[55]); - Matrix_RotYXZsuperpack_I(&mesh_rots1, &mesh_rots2, 2); - Matrix_RotYXZ_I( - g_Lara.head_y_rot, g_Lara.head_x_rot, g_Lara.head_z_rot); - Matrix_Push_I(); - mesh = g_Lara.mesh_ptrs[LM_HEAD]; - Matrix_TranslateRel_I(mesh[0], mesh[1], mesh[2]); - Matrix_Interpolate(); - spheres[2].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[2].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[2].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[2].r = mesh[3]; - Matrix_Pop_I(); - - Matrix_TranslateRel_I(0, -23, -55); - Matrix_Interpolate(); + if (frac == 0) { + M_CalculateSpheres(frame1); } else { - const int16_t *mesh_rots = frame1->mesh_rots; - Matrix_TranslateRel( - frame1->offset.x, frame1->offset.y, frame1->offset.z); - Matrix_RotYXZsuperpack(&mesh_rots, 0); - Matrix_Push(); - mesh = g_Lara.mesh_ptrs[LM_HIPS]; - Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); - spheres[0].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[0].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[0].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[0].r = mesh[3]; - Matrix_Pop(); - - bone = &g_AnimBones[g_Objects[O_LARA].bone_idx]; - Matrix_TranslateRel(bone[25], bone[26], bone[27]); - if (g_Lara.weapon_item != NO_ITEM && g_Lara.gun_type == LGT_M16 - && (g_Items[g_Lara.weapon_item].current_anim_state == 0 - || g_Items[g_Lara.weapon_item].current_anim_state == 2 - || g_Items[g_Lara.weapon_item].current_anim_state == 4)) { - mesh_rots = - &g_Lara.right_arm.frame_base - [g_Lara.right_arm.frame_num - * (g_Anims[g_Lara.right_arm.anim_num].interpolation - >> 8) - + FBBOX_ROT]; - Matrix_RotYXZsuperpack(&mesh_rots, 7); - } else { - Matrix_RotYXZsuperpack(&mesh_rots, 6); - } - Matrix_RotYXZ( - g_Lara.torso_y_rot, g_Lara.torso_x_rot, g_Lara.torso_z_rot); - Matrix_Push(); - mesh = g_Lara.mesh_ptrs[LM_TORSO]; - Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); - spheres[1].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[1].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[1].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[1].r = mesh[3]; - Matrix_Pop(); - - Matrix_Push(); - Matrix_TranslateRel(bone[29], bone[30], bone[31]); - Matrix_RotYXZsuperpack(&mesh_rots, 0); - mesh = g_Lara.mesh_ptrs[LM_UARM_R]; - Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); - spheres[3].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[3].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[3].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[3].r = mesh[3] * 3 / 2; - Matrix_Pop(); - - Matrix_Push(); - Matrix_TranslateRel(bone[41], bone[42], bone[43]); - Matrix_RotYXZsuperpack(&mesh_rots, 2); - mesh = g_Lara.mesh_ptrs[LM_UARM_L]; - Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); - spheres[4].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[4].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[4].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[4].r = mesh[3] * 3 / 2; - Matrix_Pop(); - - Matrix_TranslateRel(bone[53], bone[54], bone[55]); - Matrix_RotYXZsuperpack(&mesh_rots, 2); - Matrix_RotYXZ(g_Lara.head_y_rot, g_Lara.head_x_rot, g_Lara.head_z_rot); - Matrix_Push(); - mesh = g_Lara.mesh_ptrs[LM_HEAD]; - Matrix_TranslateRel(mesh[0], mesh[1], mesh[2]); - spheres[2].x = g_MatrixPtr->_03 >> W2V_SHIFT; - spheres[2].y = g_MatrixPtr->_13 >> W2V_SHIFT; - spheres[2].z = g_MatrixPtr->_23 >> W2V_SHIFT; - spheres[2].r = mesh[3]; - Matrix_Pop(); - - Matrix_TranslateRel(0, -23, -55); + M_CalculateSpheres_I(frame1, frame2, frac, rate); } const XYZ_32 pos = { @@ -263,7 +276,7 @@ void Lara_Hair_Control(const bool in_cutscene) }; Matrix_Pop(); - bone = &g_AnimBones[g_Objects[O_LARA_HAIR].bone_idx]; + const int32_t *bone = &g_AnimBones[g_Objects[O_LARA_HAIR].bone_idx]; HAIR_SEGMENT *const fs = &m_HairSegments[0]; fs->pos.x = pos.x; @@ -361,7 +374,7 @@ void Lara_Hair_Control(const bool in_cutscene) } for (int32_t j = 0; j < 5; j++) { - const SPHERE *const sphere = &spheres[j]; + const SPHERE *const sphere = &m_HairSpheres[j]; const int32_t dx = s->pos.x - sphere->x; const int32_t dy = s->pos.y - sphere->y; const int32_t dz = s->pos.z - sphere->z;