Skip to content

Commit cf937a1

Browse files
committed
Refactor, fix camera collision moving first person body
1 parent 2e5e61c commit cf937a1

File tree

7 files changed

+48
-34
lines changed

7 files changed

+48
-34
lines changed

src/Layers/xrRender/r__dsgraph_build.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ void R_dsgraph_structure::build_subspace()
793793
IGameObject* O = g_pGameLevel->CurrentViewEntity();
794794
if (O)
795795
{
796-
O->RenderBodyWithoutHeadAndArms(context_id, O);
796+
O->RenderFirstPersonBody(context_id, O);
797797
CROS_impl* R = (CROS_impl*)O->ROS();
798798
if (R)
799799
R->update(O);

src/xrEngine/xr_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ class XR_NOVTABLE IGameObject
308308
virtual void ShouldProcessOnRender(bool should_process) = 0;
309309
virtual void OnRender() = 0;
310310
#endif
311-
virtual void RenderBodyWithoutHeadAndArms(u32 context_id, IRenderable* root) {};
311+
virtual void RenderFirstPersonBody(u32 context_id, IRenderable* root) {};
312312
virtual void reinit() = 0;
313313
virtual void reload(pcstr section) = 0;
314314
// network

src/xrGame/Actor.cpp

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,22 @@ void CActor::Load(LPCSTR section)
461461
m_sInventoryBoxUseAction = "inventory_box_use";
462462
//---------------------------------------------------------------------
463463
m_sHeadShotParticle = READ_IF_EXISTS(pSettings, r_string, section, "HeadShotParticle", 0);
464+
465+
// initialize bones for first person body
466+
m_firstPersonBodyBonesToHide =
467+
{
468+
{ Visual()->dcast_PKinematics()->LL_BoneID("bip01_head"), true},
469+
{ Visual()->dcast_PKinematics()->LL_BoneID("bip01_neck"), true },
470+
{ Visual()->dcast_PKinematics()->LL_BoneID("bip01_l_clavicle"), true },
471+
{ Visual()->dcast_PKinematics()->LL_BoneID("bip01_r_clavicle"), true },
472+
};
473+
474+
m_firstPersonBodyBonesToIgnoreAnims =
475+
{
476+
{ Visual()->dcast_PKinematics()->LL_BoneID("bip01_spine"), true },
477+
{ Visual()->dcast_PKinematics()->LL_BoneID("bip01_spine1"), true },
478+
{ Visual()->dcast_PKinematics()->LL_BoneID("bip01_spine2"), true },
479+
};
464480
}
465481

466482
void CActor::PHHit(SHit& H) { m_pPhysics_support->in_Hit(H, false); }
@@ -1513,42 +1529,23 @@ bool CActor::renderable_ShadowGenerate()
15131529
}
15141530

15151531
extern float g_first_person_body_offset;
1516-
void CActor::RenderBodyWithoutHeadAndArms(u32 context_id, IRenderable* root)
1532+
void CActor::RenderFirstPersonBody(u32 context_id, IRenderable* root)
15171533
{
1518-
if (!(psActorFlags.test(AF_FIRST_PERSON_BODY)) || cam_active != eacFirstEye)
1519-
return;
1520-
1521-
if (!m_firstPersonBody) // initialize our fp body and bone sets
1534+
if (!m_firstPersonBody && psActorFlags.test(AF_FIRST_PERSON_BODY) && cam_active == eacFirstEye) // initialize first person body if necessary
15221535
{
15231536
m_firstPersonBody = GEnv.Render->model_Duplicate(Visual());
1524-
IKinematics* kinematics = m_firstPersonBody->dcast_PKinematics();
1525-
1526-
m_firstPersonBodyBonesToHide =
1527-
{
1528-
{ kinematics->LL_BoneID("bip01_head"), true },
1529-
{ kinematics->LL_BoneID("bip01_neck"), true },
1530-
{ kinematics->LL_BoneID("bip01_l_clavicle"), true },
1531-
{ kinematics->LL_BoneID("bip01_r_clavicle"), true },
1532-
};
1533-
1534-
m_firstPersonBodyBonesToIgnoreAnims =
1535-
{
1536-
{ kinematics->LL_BoneID("bip01_spine"), true },
1537-
{ kinematics->LL_BoneID("bip01_spine1"), true },
1538-
{ kinematics->LL_BoneID("bip01_spine2"), true },
1539-
};
1540-
15411537
g_SetAnimation(mstate_real, true); // Yohji: hacky way to reset anim state / bones when our visual changes
1542-
15431538
return;
15441539
}
15451540

15461541
IKinematics* kinematics = m_firstPersonBody->dcast_PKinematics();
1542+
IKinematics* realBodyK = Visual()->dcast_PKinematics();
15471543

1544+
// adjust body position
15481545
Fvector camdir = { cam_Active()->Direction().x, 0.f, cam_Active()->Direction().z }; // ignore Y (vertical) value
15491546
Fmatrix trans = XFORM();
15501547
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 render in correct place
1548+
XFORM().translate_over(trans.c); // move our original body to where our first person body is, so shadow renders in correct place
15521549

15531550
// Add body to render
15541551
GEnv.Render->add_Visual(context_id, root, m_firstPersonBody, trans);
@@ -1561,14 +1558,18 @@ void CActor::RenderBodyWithoutHeadAndArms(u32 context_id, IRenderable* root)
15611558
if (m_firstPersonBodyBonesToIgnoreAnims[i])
15621559
continue;
15631560

1564-
kinematics->LL_GetTransform(i).set(Visual()->dcast_PKinematics()->LL_GetTransform(i));
1565-
kinematics->LL_GetTransform_R(i).set(Visual()->dcast_PKinematics()->LL_GetTransform_R(i));
1561+
kinematics->LL_GetTransform(i).set(realBodyK->LL_GetTransform(i));
1562+
kinematics->LL_GetTransform_R(i).set(realBodyK->LL_GetTransform_R(i));
15661563
}
15671564

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

1569+
// Update head position
1570+
headPosition.set(trans);
1571+
headPosition.mulB_43(realBodyK->LL_GetTransform(realBodyK->LL_BoneID("bip01_head")));
1572+
15721573
#ifdef DEBUG
15731574
Fvector ypr;
15741575
trans.getHPB(ypr);
@@ -1577,7 +1578,11 @@ void CActor::RenderBodyWithoutHeadAndArms(u32 context_id, IRenderable* root)
15771578
F->SetAligment(CGameFont::alLeft);
15781579
F->OutSetI(-.9, 0);
15791580
F->SetColor(color_rgba(255, 0, 0, 255));
1580-
xr_sprintf(text, "fp legs position [%3.3f %3.3f %3.3f] rotation [%3.3f %3.3f %3.3f]", trans.c.x, trans.c.y, trans.c.z, ypr.x, ypr.y, ypr.z);
1581+
xr_sprintf(text, "first person body position [%3.3f %3.3f %3.3f]", trans.c.x, trans.c.y, trans.c.z);
1582+
F->OutNext(text);
1583+
xr_sprintf(text, "head position [%3.3f %3.3f %3.3f]", headPosition.c.x, headPosition.c.y, headPosition.c.z);
1584+
F->OutNext(text);
1585+
xr_sprintf(text, "camera position [%3.3f %3.3f %3.3f]", cam_Active()->Position().x, cam_Active()->Position().y, cam_Active()->Position().z);
15811586
F->OutNext(text);
15821587
#endif // DEBUG
15831588
}

src/xrGame/Actor.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,13 @@ class CActor : public CEntityAlive,
102102
// Render
103103
void renderable_Render(u32 context_id, IRenderable* root) override;
104104
virtual bool renderable_ShadowGenerate();
105-
virtual void RenderBodyWithoutHeadAndArms(u32 context_id, IRenderable* root);
105+
// First person body
106+
virtual void RenderFirstPersonBody(u32 context_id, IRenderable* root);
106107
IRenderVisual* m_firstPersonBody{};
107108
xr_unordered_map<u16, bool> m_firstPersonBodyBonesToHide;
108109
xr_unordered_map<u16, bool> m_firstPersonBodyBonesToIgnoreAnims;
110+
Fmatrix headPosition{};
111+
109112
void feel_sound_new(IGameObject* who, int type, const CSound_UserDataPtr& user_data,
110113
const Fvector& position, float power) override;
111114
virtual Feel::Sound* dcast_FeelSound() { return this; }

src/xrGame/ActorCameras.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,10 @@ void CActor::cam_Update(float dt, float fFOV)
370370
}
371371
if (Level().CurrentEntity() == this)
372372
{
373-
collide_camera(*cameras[eacFirstEye], _viewport_near, this);
373+
if (m_firstPersonBody)
374+
collide_camera(*cameras[eacFirstEye], _viewport_near, this, headPosition.c);
375+
else
376+
collide_camera(*cameras[eacFirstEye], _viewport_near, this);
374377
}
375378
if (psActorFlags.test(AF_PSP))
376379
{

src/xrPhysics/ActorCameraCollision.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ bool test_camera_collide(
332332
return test_camera_box(box_size, xform, l_actor);
333333
}
334334

335-
void collide_camera(CCameraBase& camera, float _viewport_near, IPhysicsShellHolder* l_actor)
335+
void collide_camera(CCameraBase& camera, float _viewport_near, IPhysicsShellHolder* l_actor, Fvector posOverride)
336336
{
337337
// CPhysicsShellHolder* l_actor = smart_cast<CPhysicsShellHolder*>( Level().CurrentEntity() );
338338
VERIFY(l_actor);
@@ -366,6 +366,9 @@ void collide_camera(CCameraBase& camera, float _viewport_near, IPhysicsShellHold
366366
if (dbg_draw_camera_collision)
367367
shell->dbg_draw_geometry(1, color_xrgb(0, 255, 0));
368368
#endif
369-
roote->GetGlobalPositionDynamic(&camera.vPosition);
369+
if (posOverride.magnitude() > 0.f)
370+
roote->GetGlobalPositionDynamic(&posOverride);
371+
else
372+
roote->GetGlobalPositionDynamic(&camera.vPosition);
370373
camera.vPosition.mad(camera.Direction(), -_viewport_near / 2.f);
371374
}

src/xrPhysics/ActorCameraCollision.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ extern XRPHYSICS_API float camera_collision_character_shift_z;
1010
#endif
1111
XRPHYSICS_API bool test_camera_box(const Fvector& box_size, const Fmatrix& xform, IPhysicsShellHolder* l_actor);
1212
XRPHYSICS_API bool test_camera_collide(CCameraBase& camera, float _viewport_near, IPhysicsShellHolder* l_actor, Fvector& vPosOffset, float fBoxSizeMod); //--#SM+#--
13-
XRPHYSICS_API void collide_camera(CCameraBase& camera, float _viewport_near, IPhysicsShellHolder* l_actor);
13+
XRPHYSICS_API void collide_camera(CCameraBase& camera, float _viewport_near, IPhysicsShellHolder* l_actor, Fvector posOverride = Fvector{});

0 commit comments

Comments
 (0)