mirror of https://github.com/AxioDL/metaforce.git
Initial CIkChain implementation
This commit is contained in:
parent
ef43c3319b
commit
bf91bdc332
|
@ -216,9 +216,9 @@ public:
|
||||||
CSegId GetLocatorSegId(const std::string& name) const;
|
CSegId GetLocatorSegId(const std::string& name) const;
|
||||||
zeus::CAABox GetBoundingBox(const zeus::CTransform& xf) const;
|
zeus::CAABox GetBoundingBox(const zeus::CTransform& xf) const;
|
||||||
zeus::CAABox GetBoundingBox() const;
|
zeus::CAABox GetBoundingBox() const;
|
||||||
|
|
||||||
static void FreeCache();
|
static void FreeCache();
|
||||||
static void InitializeCache();
|
static void InitializeCache();
|
||||||
|
const CHierarchyPoseBuilder& GetPoseBuilder() const { return x2fc_poseBuilder; }
|
||||||
const CParticleDatabase& GetParticleDB() const { return x120_particleDB; }
|
const CParticleDatabase& GetParticleDB() const { return x120_particleDB; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ void CHierarchyPoseBuilder::RecursivelyBuildNoScale(const CSegId& boneId, const
|
||||||
if (x0_layoutDesc.GetScaledLayoutDescription())
|
if (x0_layoutDesc.GetScaledLayoutDescription())
|
||||||
{
|
{
|
||||||
const CLayoutDescription::CScaledLayoutDescription& desc = *x0_layoutDesc.GetScaledLayoutDescription();
|
const CLayoutDescription::CScaledLayoutDescription& desc = *x0_layoutDesc.GetScaledLayoutDescription();
|
||||||
bindOffset = desc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId);
|
bindOffset = desc.ScaledLayout()->GetFromRootUnrotated(boneId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bindOffset = x0_layoutDesc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId);
|
bindOffset = x0_layoutDesc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId);
|
||||||
|
@ -70,8 +70,8 @@ void CHierarchyPoseBuilder::RecursivelyBuild(const CSegId& boneId, const CTreeNo
|
||||||
if (x0_layoutDesc.GetScaledLayoutDescription())
|
if (x0_layoutDesc.GetScaledLayoutDescription())
|
||||||
{
|
{
|
||||||
const CLayoutDescription::CScaledLayoutDescription& desc = *x0_layoutDesc.GetScaledLayoutDescription();
|
const CLayoutDescription::CScaledLayoutDescription& desc = *x0_layoutDesc.GetScaledLayoutDescription();
|
||||||
scale = desc.GetScale();
|
scale = desc.GlobalScale();
|
||||||
bindOffset = desc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId);
|
bindOffset = desc.ScaledLayout()->GetFromRootUnrotated(boneId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -103,8 +103,8 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor
|
||||||
float scale;
|
float scale;
|
||||||
if (x0_layoutDesc.GetScaledLayoutDescription())
|
if (x0_layoutDesc.GetScaledLayoutDescription())
|
||||||
{
|
{
|
||||||
layoutInfoTok = x0_layoutDesc.GetScaledLayoutDescription()->GetCharLayoutInfo();
|
layoutInfoTok = x0_layoutDesc.GetScaledLayoutDescription()->ScaledLayout();
|
||||||
scale = x0_layoutDesc.GetScaledLayoutDescription()->GetScale();
|
scale = x0_layoutDesc.GetScaledLayoutDescription()->GlobalScale();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -171,7 +171,7 @@ CHierarchyPoseBuilder::CHierarchyPoseBuilder(const CLayoutDescription& layout)
|
||||||
{
|
{
|
||||||
TLockedToken<CCharLayoutInfo> layoutInfoTok;
|
TLockedToken<CCharLayoutInfo> layoutInfoTok;
|
||||||
if (layout.GetScaledLayoutDescription())
|
if (layout.GetScaledLayoutDescription())
|
||||||
layoutInfoTok = layout.GetScaledLayoutDescription()->GetCharLayoutInfo();
|
layoutInfoTok = layout.GetScaledLayoutDescription()->ScaledLayout();
|
||||||
else
|
else
|
||||||
layoutInfoTok = layout.GetCharLayoutInfo();
|
layoutInfoTok = layout.GetCharLayoutInfo();
|
||||||
const CCharLayoutInfo& layoutInfo = *layoutInfoTok.GetObj();
|
const CCharLayoutInfo& layoutInfo = *layoutInfoTok.GetObj();
|
||||||
|
|
|
@ -46,6 +46,7 @@ class CHierarchyPoseBuilder
|
||||||
public:
|
public:
|
||||||
CHierarchyPoseBuilder(const CLayoutDescription& layout);
|
CHierarchyPoseBuilder(const CLayoutDescription& layout);
|
||||||
|
|
||||||
|
const TLockedToken<CCharLayoutInfo> CharLayoutInfo() const { return x0_layoutDesc.ScaledLayout(); }
|
||||||
bool HasRoot() const { return xcf0_hasRoot; }
|
bool HasRoot() const { return xcf0_hasRoot; }
|
||||||
void BuildTransform(const CSegId& boneId, zeus::CTransform& xfOut) const;
|
void BuildTransform(const CSegId& boneId, zeus::CTransform& xfOut) const;
|
||||||
void BuildNoScale(CPoseAsTransforms& pose);
|
void BuildNoScale(CPoseAsTransforms& pose);
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "Character/CIkChain.hpp"
|
||||||
|
#include "Character/CAnimData.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
void CIkChain::Update(float dt)
|
||||||
|
{
|
||||||
|
if (x44_24_activated)
|
||||||
|
x40_time = zeus::min(x40_time + dt, 1.f);
|
||||||
|
else
|
||||||
|
x40_time = zeus::max(0.f, x40_time - dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIkChain::Deactivate()
|
||||||
|
{
|
||||||
|
x44_24_activated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIkChain::Activate(const CAnimData& animData, const CSegId& segId, const zeus::CTransform& xf)
|
||||||
|
{
|
||||||
|
const CHierarchyPoseBuilder& posBuilder = animData.GetPoseBuilder();
|
||||||
|
x0_ = segId;
|
||||||
|
|
||||||
|
const TLockedToken<CCharLayoutInfo>& info = posBuilder.CharLayoutInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIkChain::Solve(zeus::CQuaternion& q1, zeus::CQuaternion& q2, const zeus::CVector3f& vec)
|
||||||
|
{
|
||||||
|
const float mag = vec.magnitude();
|
||||||
|
const float magSq = mag * mag;
|
||||||
|
const float twoMag = (2.0f * mag);
|
||||||
|
float f29 = std::acos(zeus::clamp(-1.f, (((x20_ * magSq) + x20_) - (x1c_ * x1c_)) / (twoMag * x20_), 1.f));
|
||||||
|
float f30 = std::acos(zeus::clamp(-1.f, ((x1c_ * (magSq - (x20_ * x20_))) + x1c_) / (twoMag * x1c_), 1.f));
|
||||||
|
|
||||||
|
zeus::CVector3f vecA = q2.transform(x10_);
|
||||||
|
zeus::CVector3f crossVecA = x4_.cross(vecA);
|
||||||
|
float crossAMag = crossVecA.magnitude();
|
||||||
|
crossVecA *= (1.f / crossVecA.magnitude());
|
||||||
|
float angle = std::asin(zeus::min(crossAMag, 1.f));
|
||||||
|
if (x4_.dot(vecA) < 0.f)
|
||||||
|
angle = M_PIF - angle;
|
||||||
|
q2 = zeus::CQuaternion::fromAxisAngle(crossVecA, (f30 + f29) - angle) * q2;
|
||||||
|
zeus::CVector3f v1 = q1.transform((x1c_ * x4_) + (x20_ * q2.transform(x10_)));
|
||||||
|
zeus::CVector3f v2 = q1.transform(vec);
|
||||||
|
zeus::CVector3f crossVecB = v1.normalized().cross((1.f / mag) * v2);
|
||||||
|
angle = std::asin(zeus::min(crossVecB.magnitude(), 1.f));
|
||||||
|
if (v1.dot((1.f / mag) * v2) < 0.f)
|
||||||
|
angle = M_PIF - angle;
|
||||||
|
|
||||||
|
q1 = zeus::CQuaternion::fromAxisAngle(crossVecB * (1.f / crossVecB.magnitude()), angle) * q1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef __URDE_CIKCHAIN_HPP__
|
||||||
|
#define __URDE_CIKCHAIN_HPP__
|
||||||
|
|
||||||
|
#include "RetroTypes.hpp"
|
||||||
|
#include "zeus/CTransform.hpp"
|
||||||
|
#include "zeus/CVector3f.hpp"
|
||||||
|
#include "zeus/CQuaternion.hpp"
|
||||||
|
#include "Character/CSegId.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
class CAnimData;
|
||||||
|
class CSegId;
|
||||||
|
class CIkChain
|
||||||
|
{
|
||||||
|
CSegId x0_;
|
||||||
|
CSegId x1_;
|
||||||
|
CSegId x2_;
|
||||||
|
zeus::CVector3f x4_;
|
||||||
|
zeus::CVector3f x10_;
|
||||||
|
float x1c_;
|
||||||
|
float x20_;
|
||||||
|
zeus::CQuaternion x24_;
|
||||||
|
zeus::CVector3f x34_;
|
||||||
|
float x40_time = 0.f;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
bool x44_24_activated : 1;
|
||||||
|
};
|
||||||
|
u8 x44_dummy = 0;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
CIkChain() = default;
|
||||||
|
|
||||||
|
bool GetActive() const;
|
||||||
|
void Update(float);
|
||||||
|
void Deactivate();
|
||||||
|
void Activate(const CAnimData&, const CSegId&, const zeus::CTransform&);
|
||||||
|
void PreRender(CAnimData&, const zeus::CTransform&, const zeus::CVector3f&);
|
||||||
|
void Solve(zeus::CQuaternion&, zeus::CQuaternion&, const zeus::CVector3f&);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __URDE_CIKCHAIN_HPP__
|
|
@ -18,8 +18,8 @@ public:
|
||||||
float xc_scale;
|
float xc_scale;
|
||||||
std::experimental::optional<zeus::CVector3f> x10_scaleVec;
|
std::experimental::optional<zeus::CVector3f> x10_scaleVec;
|
||||||
public:
|
public:
|
||||||
const TLockedToken<CCharLayoutInfo>& GetCharLayoutInfo() const {return x0_layoutToken;}
|
const TLockedToken<CCharLayoutInfo>& ScaledLayout() const {return x0_layoutToken;}
|
||||||
float GetScale() const {return xc_scale;}
|
float GlobalScale() const {return xc_scale;}
|
||||||
const std::experimental::optional<zeus::CVector3f>& GetScaleVec() const {return x10_scaleVec;}
|
const std::experimental::optional<zeus::CVector3f>& GetScaleVec() const {return x10_scaleVec;}
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
|
@ -33,6 +33,13 @@ public:
|
||||||
GetScaledLayoutDescription() const {return xc_scaled;}
|
GetScaledLayoutDescription() const {return xc_scaled;}
|
||||||
|
|
||||||
const TLockedToken<CCharLayoutInfo>& GetCharLayoutInfo() const {return x0_layoutToken;}
|
const TLockedToken<CCharLayoutInfo>& GetCharLayoutInfo() const {return x0_layoutToken;}
|
||||||
|
bool UsesScale() const { return bool(xc_scaled); }
|
||||||
|
const TLockedToken<CCharLayoutInfo>& ScaledLayout() const
|
||||||
|
{
|
||||||
|
if (UsesScale())
|
||||||
|
return xc_scaled->ScaledLayout();
|
||||||
|
return x0_layoutToken;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ set(CHARACTER_SOURCES
|
||||||
CSegIdList.hpp CSegIdList.cpp
|
CSegIdList.hpp CSegIdList.cpp
|
||||||
CSegId.hpp CSegId.cpp
|
CSegId.hpp CSegId.cpp
|
||||||
TSegIdMap.hpp
|
TSegIdMap.hpp
|
||||||
|
CIkChain.hpp CIkChain.cpp
|
||||||
CSkinRules.hpp CSkinRules.cpp
|
CSkinRules.hpp CSkinRules.cpp
|
||||||
CAnimCharacterSet.hpp CAnimCharacterSet.cpp
|
CAnimCharacterSet.hpp CAnimCharacterSet.cpp
|
||||||
CAnimationSet.hpp CAnimationSet.cpp
|
CAnimationSet.hpp CAnimationSet.cpp
|
||||||
|
|
|
@ -89,8 +89,9 @@ enum class ECoverDirection
|
||||||
|
|
||||||
enum class EBodyType
|
enum class EBodyType
|
||||||
{
|
{
|
||||||
|
Zero,
|
||||||
One,
|
One,
|
||||||
Two = 2,
|
Two,
|
||||||
Three
|
Three
|
||||||
};
|
};
|
||||||
enum class EBodyStateCmd
|
enum class EBodyStateCmd
|
||||||
|
|
|
@ -177,7 +177,7 @@ enum class EScriptObjectState
|
||||||
enum class EScriptObjectMessage
|
enum class EScriptObjectMessage
|
||||||
{
|
{
|
||||||
None = -1,
|
None = -1,
|
||||||
UNKM1 = 0,
|
UNKM0 = 0,
|
||||||
Activate = 1,
|
Activate = 1,
|
||||||
UNKM2 = 2,
|
UNKM2 = 2,
|
||||||
Close = 3,
|
Close = 3,
|
||||||
|
@ -195,7 +195,7 @@ enum class EScriptObjectMessage
|
||||||
Stop = 15,
|
Stop = 15,
|
||||||
StopAndReset = 16,
|
StopAndReset = 16,
|
||||||
ToggleActive = 17,
|
ToggleActive = 17,
|
||||||
UNKM3 = 18,
|
UNKM18 = 18,
|
||||||
Action = 19,
|
Action = 19,
|
||||||
Play = 20,
|
Play = 20,
|
||||||
Alert = 21,
|
Alert = 21,
|
||||||
|
|
Loading…
Reference in New Issue