Skip to content

Commit

Permalink
Draw empty hands when applicable
Browse files Browse the repository at this point in the history
  • Loading branch information
fholger committed Aug 25, 2023
1 parent f08159f commit 48fba34
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 5 deletions.
66 changes: 63 additions & 3 deletions Sources/CryGame C++/Solution1/CryGame/Hand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ void CHand::Init()
m_pCharacter->StartAnimation(defaultIdle,ccap);
m_pCharacter->Update();
m_pCharacter->ForceUpdate();
m_pCharacter->EnableLastIdleAnimationRestart(0);
HideOtherHand();
m_pCharacter->SetFlags(m_pCharacter->GetFlags() | CS_FLAG_DRAW_NEAR);
}
}

Expand All @@ -52,21 +55,78 @@ void CHand::Reset()
}
}

void CHand::Update(const Vec3& pos, const Ang3& angles)
void CHand::Update(const Matrix34& controllerTransform)
{
if (!m_pCharacter)
return;

m_pCharacter->Update();
m_pCharacter->ForceUpdate();
m_pCharacter->ForceReskin();
ICryBone* bone = m_pCharacter->GetBoneByName(GetHandBone());
Matrix34 gripTransform = ((Matrix34)GetTransposed44(bone->GetAbsoluteMatrix())) * Matrix34::CreateTranslationMat(Vec3(0, -0.1f, -0.018f));

Matrix34 handTransform = controllerTransform * gripTransform.GetInverted();
m_pos = handTransform.GetTranslation();
m_ang = ToAnglesDeg(handTransform);
}

void CHand::Render(const SRendParams& _RendParams)
void CHand::Render(const SRendParams& _RendParams, const Vec3& basePos)
{
if (!m_pCharacter)
return;

HideUpperArms(GetHandBone());
HideUpperArms(GetOtherHandBone());

if (m_pCharacter->GetFlags()&CS_FLAG_DRAW_MODEL)
{
SRendParams RendParams = _RendParams;
RendParams.vPos = m_pos;
RendParams.vAngles = m_ang;
m_pCharacter->Draw(RendParams, basePos);
}
}

void CHand::HideUpperArms(const char* boneName)
{
ICryBone* bone = m_pCharacter->GetBoneByName(boneName);

m_pCharacter->Draw(RendParams, m_pos);
Vec3 pos = bone->GetAbsoluteMatrix().GetTranslationOLD();

// scale the parent bones to zero to effectively hide those parts of the arms - we only want to see the hands in VR
// this will create some weird cut off at the hands, but it is the best we can do in code, without editing all the models
bone = bone->GetParent();
for (int i = 0; i < 3 && bone != nullptr; ++i)
{
Matrix44& m = const_cast<Matrix44&>(bone->GetAbsoluteMatrix());
m = Matrix44(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
m.SetTranslationOLD(pos);
bone = bone->GetParent();
}
}

void CHand::HideOtherHand()
{
ICryBone* bone = m_pCharacter->GetBoneByName(GetOtherHandBone());
if (!bone || !bone->GetParent())
return;
bone = bone->GetParent()->GetParent();
if (!bone)
return;

Matrix44 zeroScale(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
bone->DoNotCalculateBoneRelativeMatrix(true);
Matrix44& boneMatrix = const_cast<Matrix44&>(bone->GetRelativeMatrix());
boneMatrix = zeroScale;
}

const char* CHand::GetHandBone() const
{
return m_handSide == 1 ? "Bone03" : "Bone19";
}

const char* CHand::GetOtherHandBone() const
{
return m_handSide == 1 ? "Bone19" : "Bone03";
}
10 changes: 8 additions & 2 deletions Sources/CryGame C++/Solution1/CryGame/Hand.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ class CHand
void Init();
void Reset();

void Update(const Vec3& pos, const Ang3& angles);
void Render(const SRendParams& _RendParams);
void Update(const Matrix34& controllerTransform);
void Render(const SRendParams& _RendParams, const Vec3& basePos);

private:
void HideUpperArms(const char* boneName);
void HideOtherHand();

const char* GetHandBone() const;
const char* GetOtherHandBone() const;

int m_handSide;
ICryCharInstance* m_pCharacter;
CPlayer* m_pPlayer;
Expand Down
34 changes: 34 additions & 0 deletions Sources/CryGame C++/Solution1/CryGame/XPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,15 @@ CPlayer::~CPlayer()
delete m_pDynLight;
m_pDynLight=NULL;
}

for (int i = 0; i < 2; ++i)
{
if (m_handModel[i])
{
delete m_handModel[i];
m_handModel[i] = nullptr;
}
}
}

//////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -458,6 +467,12 @@ bool CPlayer::Init()

GoStand();

for (int i = 0; i < 2; ++i)
{
m_handModel[i] = new CHand(i, this);
m_handModel[i]->Init();
}

return true;
}

Expand Down Expand Up @@ -4987,6 +5002,25 @@ void CPlayer::OnDraw(const SRendParams & _RendParams)
// if nRecursionLevel is not 0 - use only 3tp person view ( for reflections )
int nRecursionLevel = (int)m_pGame->GetSystem()->GetIRenderer()->EF_Query(EFQ_RecurseLevel) - 1;


if (m_bFirstPerson && !nRecursionLevel && !GetVehicle() && !m_pMountedWeapon)
{
bool hideOffHand = GetSelectedWeapon() && (m_twoHandWeaponMode || m_stats.reloading);
if (!hideOffHand)
{
Matrix34 worldControllerTransform = GetWorldControllerTransform(m_offHand) * Matrix33::CreateRotationY(gf_PI_DIV_2);
m_handModel[m_offHand]->Update(worldControllerTransform);
m_handModel[m_offHand]->Render(_RendParams, m_pEntity->GetPos());
}

if (!GetSelectedWeapon())
{
Matrix34 worldControllerTransform = GetWorldControllerTransform(m_mainHand) * Matrix33::CreateRotationY(-gf_PI_DIV_2);
m_handModel[m_mainHand]->Update(worldControllerTransform);
m_handModel[m_mainHand]->Render(_RendParams, m_pEntity->GetPos());
}
}

// draw first person weapon
if(m_bFirstPerson && !nRecursionLevel && m_stats.drawfpweapon && m_nSelectedWeaponID != -1)
{
Expand Down
4 changes: 4 additions & 0 deletions Sources/CryGame C++/Solution1/CryGame/XPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "ScriptObjectStream.h"
#include "ScriptObjectVector.h"
#include "FireType.h"
#include "Hand.h"
#include "SynchedRandomSeed.h" // CSynchedRandomSeed

//////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1169,6 +1170,9 @@ enum eInVehiclestate
Vec3 m_swingDir;

Vec3 m_prevFireAngles;

// visible bare hands
CHand* m_handModel[2] = { nullptr };
};

#endif // __GAME_PLAYER_H__

0 comments on commit 48fba34

Please sign in to comment.