Skip to content

Commit e028811

Browse files
committed
Better first person death cam WIP
1 parent 05dd544 commit e028811

File tree

5 files changed

+56
-29
lines changed

5 files changed

+56
-29
lines changed

src/xrGame/Actor.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,7 @@ bool CActor::FirstPersonBodyEnabled()
15321532

15331533
bool CActor::FirstPersonBodyActive()
15341534
{
1535-
return m_firstPersonBody && FirstPersonBodyEnabled();
1535+
return m_firstPersonBody;
15361536
}
15371537

15381538
void CActor::RenderFirstPersonBody(u32 context_id, IRenderable* root)
@@ -1553,7 +1553,6 @@ void CActor::RenderFirstPersonBody(u32 context_id, IRenderable* root)
15531553
IKinematics* realBodyK = Visual()->dcast_PKinematics();
15541554

15551555
// adjust body position
1556-
Fvector camdir = { cam_Active()->Direction().x, 0.f, cam_Active()->Direction().z }; // ignore Y (vertical) value
15571556
m_firstPersonBodyXform = XFORM();
15581557

15591558
// Add body to render
@@ -1604,13 +1603,20 @@ void CActor::RenderFirstPersonBody(u32 context_id, IRenderable* root)
16041603
kinematics->LL_SetBoneVisible(boneId, hide ? FALSE : TRUE, TRUE);
16051604
}
16061605

1607-
// Update camera position
1606+
// Update FP camera position
1607+
Fmatrix head_bone_xform;
1608+
Fmatrix BoneMatrixRes;
1609+
Fmatrix BoneMatrix;
1610+
Fobb BoneOBB = kinematics->LL_GetBox(kinematics->LL_BoneID("bip01_head"));
1611+
BoneOBB.xform_full(head_bone_xform);
1612+
BoneMatrixRes.mul(kinematics->LL_GetTransform(kinematics->LL_BoneID("bip01_head")), head_bone_xform);
1613+
head_bone_xform.mul(m_firstPersonBodyXform, BoneMatrixRes);
1614+
1615+
//m_firstPersonCameraXform.set(head_bone_xform);
16081616
m_firstPersonCameraXform.set(m_firstPersonBodyXform);
1609-
m_firstPersonCameraXform.mulB_43(realBodyK->LL_GetTransform(realBodyK->LL_BoneID("eyelid_1"))); // should be a bone that is inbetween the eye bones (maybe more accurate than using bip01_head)
1617+
m_firstPersonCameraXform.mulB_43(realBodyK->LL_GetTransform(realBodyK->LL_BoneID("bip01_head")));
16101618

16111619
#ifdef DEBUG
1612-
Fvector ypr;
1613-
m_firstPersonBodyXform.getHPB(ypr);
16141620
string1024 text;
16151621
CGameFont* F = UI().Font().pFontArial14;
16161622
F->SetAligment(CGameFont::alLeft);
@@ -1620,13 +1626,17 @@ void CActor::RenderFirstPersonBody(u32 context_id, IRenderable* root)
16201626
F->OutNext(text);
16211627
xr_sprintf(text, "first person body direction [%3.3f %3.3f %3.3f]", m_firstPersonBodyXform.k.x, m_firstPersonBodyXform.k.y, m_firstPersonBodyXform.k.z);
16221628
F->OutNext(text);
1623-
xr_sprintf(text, "head position [%3.3f %3.3f %3.3f]", m_firstPersonCameraXform.c.x, m_firstPersonCameraXform.c.y, m_firstPersonCameraXform.c.z);
1629+
xr_sprintf(text, "m_firstPersonCameraXform pos [%3.3f %3.3f %3.3f]", m_firstPersonCameraXform.c.x, m_firstPersonCameraXform.c.y, m_firstPersonCameraXform.c.z);
1630+
F->OutNext(text);
1631+
xr_sprintf(text, "m_firstPersonCameraXform dir [%3.3f %3.3f %3.3f]", m_firstPersonCameraXform.k.x, m_firstPersonCameraXform.k.y, m_firstPersonCameraXform.k.z);
1632+
F->OutNext(text);
1633+
xr_sprintf(text, "m_firstPersonCameraXform norm [%3.3f %3.3f %3.3f]", m_firstPersonCameraXform.j.x, m_firstPersonCameraXform.j.y, m_firstPersonCameraXform.j.z);
16241634
F->OutNext(text);
1625-
xr_sprintf(text, "head direction [%3.3f %3.3f %3.3f]", m_firstPersonCameraXform.k.x, m_firstPersonCameraXform.k.y, m_firstPersonCameraXform.k.z);
1635+
xr_sprintf(text, "cameras[eacFirstEye] vPosition [%3.3f %3.3f %3.3f]", cameras[eacFirstEye]->vPosition.x, cameras[eacFirstEye]->vPosition.y, cameras[eacFirstEye]->vPosition.z);
16261636
F->OutNext(text);
1627-
xr_sprintf(text, "camera position [%3.3f %3.3f %3.3f]", cam_Active()->Position().x, cam_Active()->Position().y, cam_Active()->Position().z);
1637+
xr_sprintf(text, "cameras[eacFirstEye] vDirection [%3.3f %3.3f %3.3f]", cameras[eacFirstEye]->vDirection.x, cameras[eacFirstEye]->vDirection.y, cameras[eacFirstEye]->vDirection.z);
16281638
F->OutNext(text);
1629-
xr_sprintf(text, "camera direction [%3.3f %3.3f %3.3f]", cam_Active()->Direction().x, cam_Active()->Direction().y, cam_Active()->Direction().z);
1639+
xr_sprintf(text, "cameras[eacFirstEye] vNormal [%3.3f %3.3f %3.3f]", cameras[eacFirstEye]->vNormal.x, cameras[eacFirstEye]->vNormal.y, cameras[eacFirstEye]->vNormal.z);
16301640
F->OutNext(text);
16311641
#endif // DEBUG
16321642
}

src/xrGame/Actor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ class CActor : public CEntityAlive,
111111
xr_unordered_map<u16, bool> m_firstPersonBodyBonesToIgnoreAnims;
112112
Fmatrix m_firstPersonBodyXform{};
113113
Fmatrix m_firstPersonCameraXform{};
114+
Fvector m_firstPersonCameraRot{};
115+
114116
Lock render_lock{};
115117

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

src/xrGame/ActorCameras.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -362,37 +362,46 @@ void CActor::cam_Update(float dt, float fFOV)
362362

363363
CCameraBase* C = cam_Active();
364364

365-
if (psActorFlags.test(AF_FIRST_PERSON_BODY) && eacFirstEye == cam_active) // override camera position / direction for first person body
365+
if (FirstPersonBodyActive()) // update camera position with offset for first person body
366366
{
367-
if (!g_Alive()) //first person death cam
368-
{
369-
point = m_firstPersonCameraXform.c;
370-
}
371-
else
372-
{
373-
point = m_firstPersonCameraXform.c;
374-
point.y += g_first_person_cam_offset.y;
375-
Fvector camdir = { cam_Active()->Direction().x, 0.f, cam_Active()->Direction().z }; // ignore Y (vertical) value
376-
point.add(camdir.normalize().mul(g_first_person_cam_offset.z));
377-
}
367+
point = m_firstPersonCameraXform.c;
368+
point.y += g_first_person_cam_offset.y;
369+
Fvector camdir = { cam_Active()->Direction().x, 0.f, cam_Active()->Direction().z };
370+
point.add(camdir.normalize().mul(g_first_person_cam_offset.z));
378371
}
379372

380373
C->Update(point, dangle);
381-
382-
if (psActorFlags.test(AF_FIRST_PERSON_BODY) && eacFirstEye == cam_active && !g_Alive()) // manually update position for first person death because it gets overridden in `Update`
383-
C->vDirection.set(m_firstPersonCameraXform.k);
384-
385374
C->f_fov = fFOV;
386375

387376
if (eacFirstEye != cam_active)
388377
{
389378
cameras[eacFirstEye]->Update(point, dangle);
390379
cameras[eacFirstEye]->f_fov = fFOV;
391380
}
392-
if (Level().CurrentEntity() == this)
381+
382+
if (FirstPersonBodyActive() && !g_Alive()) // override camera position / direction for first person body on death
393383
{
394-
collide_camera(*cameras[eacFirstEye], _viewport_near, this);
384+
Fvector point2 = m_firstPersonCameraXform.c;
385+
point2.y += g_first_person_cam_offset.y;
386+
Fvector camdir = { cameras[eacFirstEye]->Direction().x, 0.f, cameras[eacFirstEye]->Direction().z };
387+
if (!fis_zero(g_first_person_cam_offset.z))
388+
point2.add(camdir.normalize().mul(g_first_person_cam_offset.z));
389+
390+
_viewport_near = VIEWPORT_NEAR - 0.08f;
391+
cameras[eacFirstEye]->Update(point2, dangle);
392+
cameras[eacFirstEye]->f_fov = fFOV;
393+
if (m_firstPersonCameraXform.k.magnitude() > 0.f)
394+
{
395+
point2.mad(m_firstPersonCameraXform.i, .15f);
396+
cameras[eacFirstEye]->vDirection.set(m_firstPersonCameraXform.k);
397+
cameras[eacFirstEye]->vNormal.set(m_firstPersonCameraXform.i);
398+
cameras[eacFirstEye]->vPosition.set(point2);
399+
}
395400
}
401+
402+
else if (Level().CurrentEntity() == this)
403+
collide_camera(*cameras[eacFirstEye], _viewport_near, this);
404+
396405
if (psActorFlags.test(AF_PSP))
397406
{
398407
Cameras().UpdateFromCamera(C);

src/xrGame/CameraFirstEye.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ void CCameraFirstEye::Update(Fvector& point, Fvector& noise_dangle)
7575

7676
void CCameraFirstEye::Move(int cmd, float val, float factor)
7777
{
78+
CActor* pActor = smart_cast<CActor*>(parent);
79+
if (pActor && !pActor->g_Alive() && pActor->FirstPersonBodyEnabled())
80+
return;
81+
7882
if (bClampPitch)
7983
{
8084
while (pitch < lim_pitch[0])

src/xrGame/CharacterPhysicsSupport.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,9 @@ bool CCharacterPhysicsSupport::CollisionCorrectObjPos(const Fvector& start_from,
723723
activation_res, vbox, activation_pos, mXFORM, not_collide_characters, set_rotation, &m_EntityAlife);
724724
//////////////////
725725

726-
m_EntityAlife.Position().sub(activation_res, shift);
726+
auto actor = smart_cast<CActor*>(&m_EntityAlife);
727+
if (!(actor && actor->FirstPersonBodyEnabled() && !actor->g_Alive()))
728+
m_EntityAlife.Position().sub(activation_res, shift);
727729

728730
if (m_pPhysicsShell)
729731
m_pPhysicsShell->EnableCollision();

0 commit comments

Comments
 (0)