Skip to content

Commit

Permalink
Move body transforms to updateCL, fixes first person body jitter (thx…
Browse files Browse the repository at this point in the history
… Valerok)
  • Loading branch information
yohjimane committed Aug 17, 2023
1 parent fa6781e commit 157f32b
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 15 deletions.
33 changes: 18 additions & 15 deletions src/xrGame/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1034,8 +1034,21 @@ float CActor::currentFOV()
}
}

extern float g_first_person_body_offset;
void CActor::UpdateCL()
{
if (m_firstPersonBody)
{
// adjust body position
Fvector camdir = { cam_Active()->Direction().x, 0.f, cam_Active()->Direction().z }; // ignore Y (vertical) value
firstPersonBodyXform.set(XFORM());
firstPersonBodyXform.c.add(camdir.normalize().mul(g_first_person_body_offset)); // push model back so it doesn't look weird (default value: -0.75f)
// Update head position
IKinematics* realBodyK = Visual()->dcast_PKinematics();
headPosition.set(firstPersonBodyXform);
headPosition.mulB_43(realBodyK->LL_GetTransform(realBodyK->LL_BoneID("bip01_head")));
}

if (g_Alive() && Level().CurrentViewEntity() == this)
{
if (CurrentGameUI() && !CurrentGameUI()->TopInputReceiver() && !m_holder)
Expand Down Expand Up @@ -1515,6 +1528,8 @@ void CActor::shedule_Update(u32 DT)
#include "debug_renderer.h"
void CActor::renderable_Render(u32 context_id, IRenderable* root)
{
if (m_firstPersonBody)
XFORM().translate_over(firstPersonBodyXform.c); // move our original body to where our first person body is, so shadow renders in correct place
VERIFY(_valid(XFORM()));
inherited::renderable_Render(context_id, root);
CInventoryOwner::renderable_Render(context_id, root);
Expand All @@ -1528,7 +1543,6 @@ bool CActor::renderable_ShadowGenerate()
return inherited::renderable_ShadowGenerate();
}

extern float g_first_person_body_offset;
void CActor::RenderFirstPersonBody(u32 context_id, IRenderable* root)
{
if (!(psActorFlags.test(AF_FIRST_PERSON_BODY) && cam_active == eacFirstEye))
Expand All @@ -1544,14 +1558,8 @@ void CActor::RenderFirstPersonBody(u32 context_id, IRenderable* root)
IKinematics* kinematics = m_firstPersonBody->dcast_PKinematics();
IKinematics* realBodyK = Visual()->dcast_PKinematics();

// adjust body position
Fvector camdir = { cam_Active()->Direction().x, 0.f, cam_Active()->Direction().z }; // ignore Y (vertical) value
Fmatrix trans = XFORM();
trans.c.add(camdir.normalize().mul(g_first_person_body_offset)); // push model back so it doesn't look weird (default value: -0.75f)
XFORM().translate_over(trans.c); // move our original body to where our first person body is, so shadow renders in correct place

// Add body to render
GEnv.Render->add_Visual(context_id, root, m_firstPersonBody, trans);
GEnv.Render->add_Visual(context_id, root, m_firstPersonBody, firstPersonBodyXform);
m_firstPersonBody->getVisData().hom_frame = Device.dwFrame;

// Copy transforms from actual body visual, excluding bones we don't want to animate
Expand All @@ -1561,27 +1569,22 @@ void CActor::RenderFirstPersonBody(u32 context_id, IRenderable* root)
if (m_firstPersonBodyBonesToIgnoreAnims[i])
continue;

kinematics->LL_GetTransform(i).set(realBodyK->LL_GetTransform(i));
kinematics->LL_GetTransform_R(i).set(realBodyK->LL_GetTransform_R(i));
}

// Hide bones
for (auto [boneId, vis] : m_firstPersonBodyBonesToHide)
kinematics->LL_SetBoneVisible(boneId, !vis, true);

// Update head position
headPosition.set(trans);
headPosition.mulB_43(realBodyK->LL_GetTransform(realBodyK->LL_BoneID("bip01_head")));

#ifdef DEBUG
Fvector ypr;
trans.getHPB(ypr);
firstPersonBodyXform.getHPB(ypr);
string1024 text;
CGameFont* F = UI().Font().pFontArial14;
F->SetAligment(CGameFont::alLeft);
F->OutSetI(-.9, 0);
F->SetColor(color_rgba(255, 0, 0, 255));
xr_sprintf(text, "first person body position [%3.3f %3.3f %3.3f]", trans.c.x, trans.c.y, trans.c.z);
xr_sprintf(text, "first person body position [%3.3f %3.3f %3.3f]", firstPersonBodyXform.c.x, firstPersonBodyXform.c.y, firstPersonBodyXform.c.z);
F->OutNext(text);
xr_sprintf(text, "head position [%3.3f %3.3f %3.3f]", headPosition.c.x, headPosition.c.y, headPosition.c.z);
F->OutNext(text);
Expand Down
1 change: 1 addition & 0 deletions src/xrGame/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class CActor : public CEntityAlive,
IRenderVisual* m_firstPersonBody{};
xr_unordered_map<u16, bool> m_firstPersonBodyBonesToHide;
xr_unordered_map<u16, bool> m_firstPersonBodyBonesToIgnoreAnims;
Fmatrix firstPersonBodyXform{};
Fmatrix headPosition{};

void feel_sound_new(IGameObject* who, int type, const CSound_UserDataPtr& user_data,
Expand Down

0 comments on commit 157f32b

Please sign in to comment.