Skip to content

Commit 157f32b

Browse files
committed
Move body transforms to updateCL, fixes first person body jitter (thx Valerok)
1 parent fa6781e commit 157f32b

File tree

2 files changed

+19
-15
lines changed

2 files changed

+19
-15
lines changed

src/xrGame/Actor.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,8 +1034,21 @@ float CActor::currentFOV()
10341034
}
10351035
}
10361036

1037+
extern float g_first_person_body_offset;
10371038
void CActor::UpdateCL()
10381039
{
1040+
if (m_firstPersonBody)
1041+
{
1042+
// adjust body position
1043+
Fvector camdir = { cam_Active()->Direction().x, 0.f, cam_Active()->Direction().z }; // ignore Y (vertical) value
1044+
firstPersonBodyXform.set(XFORM());
1045+
firstPersonBodyXform.c.add(camdir.normalize().mul(g_first_person_body_offset)); // push model back so it doesn't look weird (default value: -0.75f)
1046+
// Update head position
1047+
IKinematics* realBodyK = Visual()->dcast_PKinematics();
1048+
headPosition.set(firstPersonBodyXform);
1049+
headPosition.mulB_43(realBodyK->LL_GetTransform(realBodyK->LL_BoneID("bip01_head")));
1050+
}
1051+
10391052
if (g_Alive() && Level().CurrentViewEntity() == this)
10401053
{
10411054
if (CurrentGameUI() && !CurrentGameUI()->TopInputReceiver() && !m_holder)
@@ -1515,6 +1528,8 @@ void CActor::shedule_Update(u32 DT)
15151528
#include "debug_renderer.h"
15161529
void CActor::renderable_Render(u32 context_id, IRenderable* root)
15171530
{
1531+
if (m_firstPersonBody)
1532+
XFORM().translate_over(firstPersonBodyXform.c); // move our original body to where our first person body is, so shadow renders in correct place
15181533
VERIFY(_valid(XFORM()));
15191534
inherited::renderable_Render(context_id, root);
15201535
CInventoryOwner::renderable_Render(context_id, root);
@@ -1528,7 +1543,6 @@ bool CActor::renderable_ShadowGenerate()
15281543
return inherited::renderable_ShadowGenerate();
15291544
}
15301545

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

1547-
// adjust body position
1548-
Fvector camdir = { cam_Active()->Direction().x, 0.f, cam_Active()->Direction().z }; // ignore Y (vertical) value
1549-
Fmatrix trans = XFORM();
1550-
trans.c.add(camdir.normalize().mul(g_first_person_body_offset)); // push model back so it doesn't look weird (default value: -0.75f)
1551-
XFORM().translate_over(trans.c); // move our original body to where our first person body is, so shadow renders in correct place
1552-
15531561
// Add body to render
1554-
GEnv.Render->add_Visual(context_id, root, m_firstPersonBody, trans);
1562+
GEnv.Render->add_Visual(context_id, root, m_firstPersonBody, firstPersonBodyXform);
15551563
m_firstPersonBody->getVisData().hom_frame = Device.dwFrame;
15561564

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

1564-
kinematics->LL_GetTransform(i).set(realBodyK->LL_GetTransform(i));
15651572
kinematics->LL_GetTransform_R(i).set(realBodyK->LL_GetTransform_R(i));
15661573
}
15671574

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

1572-
// Update head position
1573-
headPosition.set(trans);
1574-
headPosition.mulB_43(realBodyK->LL_GetTransform(realBodyK->LL_BoneID("bip01_head")));
1575-
15761579
#ifdef DEBUG
15771580
Fvector ypr;
1578-
trans.getHPB(ypr);
1581+
firstPersonBodyXform.getHPB(ypr);
15791582
string1024 text;
15801583
CGameFont* F = UI().Font().pFontArial14;
15811584
F->SetAligment(CGameFont::alLeft);
15821585
F->OutSetI(-.9, 0);
15831586
F->SetColor(color_rgba(255, 0, 0, 255));
1584-
xr_sprintf(text, "first person body position [%3.3f %3.3f %3.3f]", trans.c.x, trans.c.y, trans.c.z);
1587+
xr_sprintf(text, "first person body position [%3.3f %3.3f %3.3f]", firstPersonBodyXform.c.x, firstPersonBodyXform.c.y, firstPersonBodyXform.c.z);
15851588
F->OutNext(text);
15861589
xr_sprintf(text, "head position [%3.3f %3.3f %3.3f]", headPosition.c.x, headPosition.c.y, headPosition.c.z);
15871590
F->OutNext(text);

src/xrGame/Actor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class CActor : public CEntityAlive,
107107
IRenderVisual* m_firstPersonBody{};
108108
xr_unordered_map<u16, bool> m_firstPersonBodyBonesToHide;
109109
xr_unordered_map<u16, bool> m_firstPersonBodyBonesToIgnoreAnims;
110+
Fmatrix firstPersonBodyXform{};
110111
Fmatrix headPosition{};
111112

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

0 commit comments

Comments
 (0)