From a3490767400352aa704137818742413bcb3635e3 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 3 Sep 2016 16:27:35 -1000 Subject: [PATCH] Several CAnimData integrations --- Runtime/Character/CAdditiveAnimPlayback.cpp | 6 +- Runtime/Character/CAdditiveAnimPlayback.hpp | 6 +- Runtime/Character/CAllFormatsAnimSource.hpp | 4 +- Runtime/Character/CAnimData.cpp | 275 ++++++++++++++++--- Runtime/Character/CAnimData.hpp | 27 +- Runtime/Character/CAnimPlaybackParms.hpp | 14 +- Runtime/Character/CAnimSource.hpp | 1 + Runtime/Character/CAnimTreeBlend.cpp | 46 ++++ Runtime/Character/CAnimTreeBlend.hpp | 21 +- Runtime/Character/CAnimTreeDoubleChild.cpp | 77 ++++++ Runtime/Character/CAnimTreeDoubleChild.hpp | 14 + Runtime/Character/CAnimTreeTweenBase.cpp | 39 +++ Runtime/Character/CAnimTreeTweenBase.hpp | 25 ++ Runtime/Character/CAnimationManager.cpp | 13 + Runtime/Character/CAnimationManager.hpp | 5 + Runtime/Character/CCharLayoutInfo.cpp | 5 +- Runtime/Character/CCharacterInfo.hpp | 3 + Runtime/Character/CFBStreamedCompression.cpp | 64 +++++ Runtime/Character/CFBStreamedCompression.hpp | 3 + Runtime/Character/CHierarchyPoseBuilder.cpp | 34 +-- Runtime/Character/CHierarchyPoseBuilder.hpp | 7 +- Runtime/Character/CMakeLists.txt | 1 + Runtime/Character/CModelData.cpp | 7 +- Runtime/Character/CModelData.hpp | 5 +- Runtime/Character/CParticleDatabase.cpp | 9 + Runtime/Character/CParticleDatabase.hpp | 6 + Runtime/Character/CTransitionManager.cpp | 14 + Runtime/Character/CTransitionManager.hpp | 3 + Runtime/Character/CTreeUtils.cpp | 20 ++ Runtime/Character/CTreeUtils.hpp | 21 ++ Runtime/Character/IMetaTrans.hpp | 7 + Runtime/Character/TSegIdMap.hpp | 45 +-- Runtime/Graphics/CFrustumPlanes.cpp | 30 -- Runtime/Graphics/CFrustumPlanes.hpp | 24 -- Runtime/Graphics/CMakeLists.txt | 1 - Runtime/Graphics/CSkinnedModel.hpp | 8 +- Runtime/World/CMorphBall.hpp | 5 +- 37 files changed, 721 insertions(+), 174 deletions(-) create mode 100644 Runtime/Character/CTreeUtils.cpp create mode 100644 Runtime/Character/CTreeUtils.hpp delete mode 100644 Runtime/Graphics/CFrustumPlanes.cpp delete mode 100644 Runtime/Graphics/CFrustumPlanes.hpp diff --git a/Runtime/Character/CAdditiveAnimPlayback.cpp b/Runtime/Character/CAdditiveAnimPlayback.cpp index 52bbbd444..e875667fd 100644 --- a/Runtime/Character/CAdditiveAnimPlayback.cpp +++ b/Runtime/Character/CAdditiveAnimPlayback.cpp @@ -7,10 +7,10 @@ namespace urde { CAdditiveAnimPlayback::CAdditiveAnimPlayback(const std::weak_ptr& anim, - float weight, bool a, const CAdditiveAnimationInfo& info, bool b) -: x0_info(info), x8_anim(anim.lock()), xc_targetWeight(weight), x14_a(a) + float weight, bool active, const CAdditiveAnimationInfo& info, bool b) +: x0_info(info), x8_anim(anim.lock()), xc_targetWeight(weight), x14_active(active) { - if (!a && b) + if (!active && b) x20_ = true; } diff --git a/Runtime/Character/CAdditiveAnimPlayback.hpp b/Runtime/Character/CAdditiveAnimPlayback.hpp index 609aaca3a..0367f60b2 100644 --- a/Runtime/Character/CAdditiveAnimPlayback.hpp +++ b/Runtime/Character/CAdditiveAnimPlayback.hpp @@ -43,12 +43,12 @@ private: std::shared_ptr x8_anim; float xc_targetWeight; float x10_curWeight = 0.f; - bool x14_a; + bool x14_active; float x18_weightTimer = 0.f; EAdditivePlaybackPhase x1c_phase = EAdditivePlaybackPhase::FadingIn; bool x20_ = false; public: - CAdditiveAnimPlayback(const std::weak_ptr& anim, float weight, bool a, + CAdditiveAnimPlayback(const std::weak_ptr& anim, float weight, bool active, const CAdditiveAnimationInfo& info, bool b); void AddToSegStatementSet(const CSegIdList& list, const CCharLayoutInfo&, CSegStatementSet&) const; @@ -56,7 +56,7 @@ public: void FadeOut(); void SetWeight(float w); float GetTargetWeight() const {return xc_targetWeight;} - bool GetA() const {return x14_a;} + bool IsActive() const {return x14_active;} const std::shared_ptr& GetAnim() const {return x8_anim;} }; diff --git a/Runtime/Character/CAllFormatsAnimSource.hpp b/Runtime/Character/CAllFormatsAnimSource.hpp index dd9d0ef6e..e3962e183 100644 --- a/Runtime/Character/CAllFormatsAnimSource.hpp +++ b/Runtime/Character/CAllFormatsAnimSource.hpp @@ -34,7 +34,9 @@ class CAnimFormatUnion public: CAnimFormatUnion(CInputStream& in, IObjectStore& store); ~CAnimFormatUnion(); - operator CAnimSource&() {return *reinterpret_cast(x4_storage);} + EAnimFormat GetFormat() const { return x0_format; } + const CAnimSource& GetAsCAnimSource() const { return *reinterpret_cast(x4_storage); } + const CFBStreamedCompression& GetAsCFBStreamedCompression() const { return *reinterpret_cast(x4_storage); } }; class CAllFormatsAnimSource : public CAnimFormatUnion diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index 3916a37e4..5e4200ea1 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -16,6 +16,11 @@ #include "CAnimPerSegmentData.hpp" #include "CSegStatementSet.hpp" #include "CStateManager.hpp" +#include "CAnimPlaybackParms.hpp" +#include "CAnimTreeBlend.hpp" +#include "CPrimitive.hpp" +#include "CAllFormatsAnimSource.hpp" +#include "GameGlobalObjects.hpp" namespace urde { @@ -75,7 +80,7 @@ ResId CAnimData::GetEventResourceIdForAnimResourceId(ResId id) const void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet) { - for (std::pair& additive : x1048_additiveAnims) + for (std::pair& additive : x434_additiveAnims) if (additive.second.GetTargetWeight() > 0.00001f) additive.second.AddToSegStatementSet(list, *xcc_layoutData.GetObj(), stSet); } @@ -88,9 +93,9 @@ SAdvancementDeltas CAnimData::AdvanceAdditiveAnims(float dt) { CCharAnimTime time(dt); - for (std::pair& additive : x1048_additiveAnims) + for (std::pair& additive : x434_additiveAnims) { - if (additive.second.GetA()) + if (additive.second.IsActive()) { while (time.GreaterThanZero() && std::fabs(time) >= 0.00001f) { @@ -112,19 +117,37 @@ SAdvancementDeltas CAnimData::UpdateAdditiveAnims(float dt) return AdvanceAdditiveAnims(dt); } -bool CAnimData::IsAdditiveAnimation(u32) const +bool CAnimData::IsAdditiveAnimation(u32 idx) const { - return false; + auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), + [&](const std::pair& pair) -> bool { + return pair.first == idx; + }); + if (search == x434_additiveAnims.cend()) + return false; + return true; } -std::shared_ptr CAnimData::GetAdditiveAnimationTree(u32) const +std::shared_ptr CAnimData::GetAdditiveAnimationTree(u32 idx) const { - return {}; + auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), + [&](const std::pair& pair) -> bool { + return pair.first == idx; + }); + if (search == x434_additiveAnims.cend()) + return {}; + return search->second.GetAnim(); } -bool CAnimData::IsAdditiveAnimationActive(u32) const +bool CAnimData::IsAdditiveAnimationActive(u32 idx) const { - return false; + auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), + [&](const std::pair& pair) -> bool { + return pair.first == idx; + }); + if (search == x434_additiveAnims.cend()) + return {}; + return search->second.IsActive(); } void CAnimData::DelAdditiveAnimation(u32) @@ -137,21 +160,23 @@ void CAnimData::AddAdditiveAnimation(u32, float, bool, bool) std::shared_ptr CAnimData::GetAnimationManager() { - return {}; + return x100_animMgr; } -void CAnimData::SetPhase(float) +void CAnimData::SetPhase(float ph) { + x1f8_animRoot->VSetPhase(ph); } -void CAnimData::Touch(const CSkinnedModel& model, int) const +void CAnimData::Touch(const CSkinnedModel& model, int shadIdx) const { + const_cast(*model.GetModelInst()).Touch(shadIdx); } SAdvancementDeltas CAnimData::GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const { - return {}; + return x1f8_animRoot->VGetAdvancementResults(a, b).x8_deltas; } CCharAnimTime CAnimData::GetTimeOfUserEvent(EUserEventType, const CCharAnimTime& time) const @@ -159,12 +184,14 @@ CCharAnimTime CAnimData::GetTimeOfUserEvent(EUserEventType, const CCharAnimTime& return {}; } -void CAnimData::MultiplyPlaybackRate(float) +void CAnimData::MultiplyPlaybackRate(float mul) { + x200_speedScale += mul; } -void CAnimData::SetPlaybackRate(float) +void CAnimData::SetPlaybackRate(float set) { + x200_speedScale = set; } void CAnimData::SetRandomPlaybackRate(CRandom16&) @@ -172,7 +199,7 @@ void CAnimData::SetRandomPlaybackRate(CRandom16&) } void CAnimData::CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms, - const std::weak_ptr& node) + const std::shared_ptr& node) { } @@ -202,29 +229,69 @@ zeus::CTransform CAnimData::GetLocatorTransform(const std::string& name, const C return GetLocatorTransform(xcc_layoutData->GetSegIdFromString(name), time); } -bool CAnimData::IsAnimTimeRemaining(float, const std::string& name) const +bool CAnimData::IsAnimTimeRemaining(float rem, const std::string& name) const { - return false; + if (!x1f8_animRoot) + return false; + return float(x1f8_animRoot->VGetTimeRemaining()) <= rem; } float CAnimData::GetAnimTimeRemaining(const std::string& name) const { - return 0.f; + float rem = x1f8_animRoot->VGetTimeRemaining(); + if (x200_speedScale) + return rem / x200_speedScale; + return rem; } -float CAnimData::GetAnimationDuration(int) const +float CAnimData::GetAnimationDuration(int animIn) const { - return 0.f; + std::shared_ptr anim = x100_animMgr->GetMetaAnimation(xc_charInfo.GetAnimationIndex(animIn)); + std::set prims; + anim->GetUniquePrimitives(prims); + + SObjectTag tag{FOURCC('ANIM'), 0}; + float durAccum = 0.f; + for (const CPrimitive& prim : prims) + { + tag.id = prim.GetAnimResId(); + TLockedToken animRes = xfc_animCtx->xc_store.GetObj(tag); + + CCharAnimTime dur; + switch (animRes->GetFormat()) + { + case EAnimFormat::Uncompressed: + default: + { + const CAnimSource& src = animRes->GetAsCAnimSource(); + dur = src.GetDuration(); + break; + } + case EAnimFormat::BitstreamCompressed: + case EAnimFormat::BitstreamCompressed24: + { + const CFBStreamedCompression& src = animRes->GetAsCFBStreamedCompression(); + dur = src.GetAnimationDuration(); + break; + } + } + + durAccum += dur; + } + + if (anim->GetType() == EMetaAnimType::Random) + return durAccum / float(prims.size()); + return durAccum; } std::shared_ptr CAnimData::GetAnimSysContext() const { - return {}; + return xfc_animCtx; } std::shared_ptr CAnimData::GetAnimationManager() const { - return {}; + return x100_animMgr; } void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time) @@ -249,8 +316,9 @@ void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time) } } -void CAnimData::RenderAuxiliary(const CFrustumPlanes& frustum) const +void CAnimData::RenderAuxiliary(const zeus::CFrustum& frustum) const { + const_cast(x120_particleDB).AddToRendererClipped(frustum); } void CAnimData::Render(CSkinnedModel& model, const CModelFlags& drawFlags, @@ -291,18 +359,99 @@ void CAnimData::PreRender() void CAnimData::BuildPose() { + if (!x220_31_poseCached) + { + RecalcPoseBuilder(nullptr); + x220_31_poseCached = true; + x220_30_poseBuilt = false; + } + + if (!x220_30_poseBuilt) + { + x2fc_poseBuilder.BuildNoScale(x224_pose); + x220_30_poseBuilt = true; + } } -void CAnimData::PrimitiveSetToTokenVector(const std::set& primSet, std::vector& tokensOut) +void CAnimData::PrimitiveSetToTokenVector(const std::set& primSet, + std::vector& tokensOut, bool preLock) { + tokensOut.reserve(primSet.size()); + + SObjectTag tag{FOURCC('ANIM'), 0}; + for (const CPrimitive& prim : primSet) + { + tag.id = prim.GetAnimResId(); + tokensOut.push_back(g_SimplePool->GetObj(tag)); + if (preLock) + tokensOut.back().Lock(); + } } void CAnimData::GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set& primsOut) const { + std::shared_ptr animA = + GetAnimationManager()->GetMetaAnimation(xc_charInfo.GetAnimationIndex(parms.x0_animA)); + animA->GetUniquePrimitives(primsOut); + + if (parms.x4_animB != -1) + { + std::shared_ptr animB = + GetAnimationManager()->GetMetaAnimation(xc_charInfo.GetAnimationIndex(parms.x4_animB)); + animB->GetUniquePrimitives(primsOut); + } } -void CAnimData::SetAnimation(const CAnimPlaybackParms& parms, bool) +void CAnimData::SetAnimation(const CAnimPlaybackParms& parms, bool noTrans) { + if (parms.x0_animA == x40c_playbackParms.x0_animA || + (parms.x4_animB != x40c_playbackParms.x4_animB && + parms.x8_blendWeight == x40c_playbackParms.x8_blendWeight && + parms.x8_blendWeight != 1.f) || + parms.x4_animB == -1) + { + if (x220_29_) + return; + } + + x40c_playbackParms.x0_animA = parms.x0_animA; + x40c_playbackParms.x4_animB = parms.x4_animB; + x40c_playbackParms.x8_blendWeight = parms.x8_blendWeight; + x200_speedScale = 1.f; + x208_defaultAnim = parms.x0_animA; + + u32 animIdxA = xc_charInfo.GetAnimationIndex(parms.x0_animA); + + ResetPOILists(); + + std::shared_ptr blendNode; + if (parms.x4_animB != -1) + { + u32 animIdxB = xc_charInfo.GetAnimationIndex(parms.x4_animB); + + std::shared_ptr treeA = + GetAnimationManager()->GetAnimationTree(animIdxA, CMetaAnimTreeBuildOrders::NoSpecialOrders()); + std::shared_ptr treeB = + GetAnimationManager()->GetAnimationTree(animIdxB, CMetaAnimTreeBuildOrders::NoSpecialOrders()); + + blendNode = std::make_shared(false, treeA, treeB, parms.x8_blendWeight, + CAnimTreeBlend::CreatePrimitiveName(treeA, treeB, + parms.x8_blendWeight)); + } + else + { + blendNode = GetAnimationManager()->GetAnimationTree(animIdxA, CMetaAnimTreeBuildOrders::NoSpecialOrders()); + } + + if (!noTrans) + x1f8_animRoot = x1fc_transMgr->GetTransitionTree(x1f8_animRoot, blendNode); + else + x1f8_animRoot = blendNode; + + x220_24_animating = parms.xc_animating; + CalcPlaybackAlignmentParms(parms, blendNode); + ResetPOILists(); + x220_29_ = true; } SAdvancementDeltas CAnimData::DoAdvance(float dt, bool& b1, CRandom16& random, bool advTree) @@ -417,7 +566,7 @@ void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus:: if (simplified->IsCAnimTreeNode()) { if (x1f8_animRoot != simplified) - x1f8_animRoot = std::move(simplified); + x1f8_animRoot = std::static_pointer_cast(std::move(simplified)); } else x1f8_animRoot.reset(); @@ -467,10 +616,12 @@ void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus:: void CAnimData::SetXRayModel(const TLockedToken& model, const TLockedToken& skinRules) { + xf4_xrayModel = std::make_shared(model, skinRules, xd8_modelData->GetLayoutInfo(), 0); } void CAnimData::SetInfraModel(const TLockedToken& model, const TLockedToken& skinRules) { + xf8_infraModel = std::make_shared(model, skinRules, xd8_modelData->GetLayoutInfo(), 0); } void CAnimData::PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, @@ -481,32 +632,90 @@ void CAnimData::PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& model.Calculate(pose, drawFlags, morphEffect, morphMagnitudes); } -void CAnimData::AdvanceParticles(const zeus::CTransform& xf, float, - const zeus::CVector3f&, CStateManager& stateMgr) +void CAnimData::AdvanceParticles(const zeus::CTransform& xf, float dt, + const zeus::CVector3f& vec, CStateManager& stateMgr) { + x120_particleDB.Update(dt, x224_pose, *xcc_layoutData, xf, vec, stateMgr); } -void CAnimData::GetAverageVelocity(int) const +float CAnimData::GetAverageVelocity(int animIn) const { + std::shared_ptr anim = x100_animMgr->GetMetaAnimation(xc_charInfo.GetAnimationIndex(animIn)); + std::set prims; + anim->GetUniquePrimitives(prims); + + SObjectTag tag{FOURCC('ANIM'), 0}; + float velAccum = 0.f; + float durAccum = 0.f; + for (const CPrimitive& prim : prims) + { + tag.id = prim.GetAnimResId(); + TLockedToken animRes = xfc_animCtx->xc_store.GetObj(tag); + + CCharAnimTime dur; + float avgVel; + switch (animRes->GetFormat()) + { + case EAnimFormat::Uncompressed: + default: + { + const CAnimSource& src = animRes->GetAsCAnimSource(); + dur = src.GetDuration(); + avgVel = src.GetAverageVelocity(); + break; + } + case EAnimFormat::BitstreamCompressed: + case EAnimFormat::BitstreamCompressed24: + { + const CFBStreamedCompression& src = animRes->GetAsCFBStreamedCompression(); + dur = src.GetAnimationDuration(); + avgVel = src.GetAverageVelocity(); + break; + } + } + + velAccum += dur * avgVel; + durAccum += dur; + } + + if (durAccum > 0.f) + return velAccum / durAccum; + return 0.f; } void CAnimData::ResetPOILists() { + x20c_passedBoolCount = 0; + x210_passedIntCount = 0; + x214_passedParticleCount = 0; + x218_passedSoundCount = 0; } CSegId CAnimData::GetLocatorSegId(const std::string& name) const { - return {}; + return xcc_layoutData->GetSegIdFromString(name); } zeus::CAABox CAnimData::GetBoundingBox(const zeus::CTransform& xf) const { - return {}; + return GetBoundingBox().getTransformedAABox(xf); } zeus::CAABox CAnimData::GetBoundingBox() const { - return {}; + auto aabbList = xc_charInfo.GetAnimBBoxList(); + if (aabbList.empty()) + return x108_aabb; + + CAnimTreeEffectiveContribution contrib = x1f8_animRoot->GetContributionOfHighestInfluence(); + auto search = std::find_if(aabbList.cbegin(), aabbList.cend(), + [&](const std::pair& other) -> bool { + return contrib.x4_name == other.first; + }); + if (search == aabbList.cend()) + return x108_aabb; + + return search->second; } } diff --git a/Runtime/Character/CAnimData.hpp b/Runtime/Character/CAnimData.hpp index 22b6d69cf..c9bf19bbe 100644 --- a/Runtime/Character/CAnimData.hpp +++ b/Runtime/Character/CAnimData.hpp @@ -9,6 +9,7 @@ #include "CHierarchyPoseBuilder.hpp" #include "CAdditiveAnimPlayback.hpp" #include "CCharLayoutInfo.hpp" +#include "CAnimPlaybackParms.hpp" #include enum class EUserEventType @@ -62,9 +63,7 @@ class CCharacterFactory; class IMetaAnim; struct CModelFlags; class CVertexMorphEffect; -class CFrustumPlanes; class CPrimitive; -class CAnimPlaybackParms; class CRandom16; class CStateManager; class CCharAnimTime; @@ -98,7 +97,7 @@ class CAnimData ResId x1d8_selfId; zeus::CVector3f x1dc_; zeus::CQuaternion x1e8_; - std::shared_ptr x1f8_animRoot; + std::shared_ptr x1f8_animRoot; std::shared_ptr x1fc_transMgr; float x200_speedScale = 1.f; @@ -129,17 +128,8 @@ class CAnimData CPoseAsTransforms x224_pose; CHierarchyPoseBuilder x2fc_poseBuilder; - u32 x1020_ = -1; - u32 x10204_ = -1; - float x1028_ = 1.f; - bool x102c_ = true; - u32 x1030_ = 0; - u32 x1034_ = 0; - bool x1038_ = false; - u32 x103c_ = 0; - u32 x1040_ = 0; - u32 x1044_ = 0; - rstl::reserved_vector, 8> x1048_additiveAnims; + CAnimPlaybackParms x40c_playbackParms; + rstl::reserved_vector, 8> x434_additiveAnims; static rstl::reserved_vector g_BoolPOINodes; static rstl::reserved_vector g_Int32POINodes; @@ -177,7 +167,7 @@ public: void SetPlaybackRate(float); void SetRandomPlaybackRate(CRandom16&); void CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms, - const std::weak_ptr& node); + const std::shared_ptr& node); zeus::CTransform GetLocatorTransform(CSegId id, const CCharAnimTime* time) const; zeus::CTransform GetLocatorTransform(const std::string& name, const CCharAnimTime* time) const; bool IsAnimTimeRemaining(float, const std::string& name) const; @@ -189,7 +179,7 @@ public: std::shared_ptr GetAnimSysContext() const; std::shared_ptr GetAnimationManager() const; void RecalcPoseBuilder(const CCharAnimTime*); - void RenderAuxiliary(const CFrustumPlanes& frustum) const; + void RenderAuxiliary(const zeus::CFrustum& frustum) const; void Render(CSkinnedModel& model, const CModelFlags& drawFlags, const std::experimental::optional& morphEffect, const float* morphMagnitudes); @@ -200,7 +190,8 @@ public: static void DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags); void PreRender(); void BuildPose(); - void PrimitiveSetToTokenVector(const std::set& primSet, std::vector& tokensOut); + static void PrimitiveSetToTokenVector(const std::set& primSet, + std::vector& tokensOut, bool preLock); void GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set& primsOut) const; void SetAnimation(const CAnimPlaybackParms& parms, bool); SAdvancementDeltas DoAdvance(float, bool&, CRandom16&, bool advTree); @@ -216,7 +207,7 @@ public: const float* morphMagnitudes); void AdvanceParticles(const zeus::CTransform& xf, float dt, const zeus::CVector3f&, CStateManager& stateMgr); - void GetAverageVelocity(int) const; + float GetAverageVelocity(int animIn) const; void ResetPOILists(); CSegId GetLocatorSegId(const std::string& name) const; zeus::CAABox GetBoundingBox(const zeus::CTransform& xf) const; diff --git a/Runtime/Character/CAnimPlaybackParms.hpp b/Runtime/Character/CAnimPlaybackParms.hpp index ad80f3f50..c06a1e6a3 100644 --- a/Runtime/Character/CAnimPlaybackParms.hpp +++ b/Runtime/Character/CAnimPlaybackParms.hpp @@ -7,10 +7,11 @@ namespace urde { class CAnimPlaybackParms { - s32 x0_defaultAnim; - s32 x4_; - float x8_scale; - bool xc_loop; + friend class CAnimData; + s32 x0_animA = -1; + s32 x4_animB = -1; + float x8_blendWeight = 1.f; + bool xc_animating = true; s32 x10_ = 0; s32 x14_ = 0; bool x18_ = false; @@ -18,8 +19,9 @@ class CAnimPlaybackParms s32 x20_ = 0; s32 x24_ = 0; public: - CAnimPlaybackParms(s32 defaultAnim, s32 b, float scale, bool loop) - : x0_defaultAnim(defaultAnim), x4_(b), x8_scale(scale), xc_loop(loop) + CAnimPlaybackParms() = default; + CAnimPlaybackParms(s32 animA, s32 animB, float blendWeight, bool animating) + : x0_animA(animA), x4_animB(animB), x8_blendWeight(blendWeight), xc_animating(animating) {} }; } diff --git a/Runtime/Character/CAnimSource.hpp b/Runtime/Character/CAnimSource.hpp index e8cc440cd..4db67a0ec 100644 --- a/Runtime/Character/CAnimSource.hpp +++ b/Runtime/Character/CAnimSource.hpp @@ -75,6 +75,7 @@ public: const std::vector& GetInt32POIStream() const; const std::vector& GetBoolPOIStream() const; const TCachedToken& GetPOIData() const {return x58_evntData;} + float GetAverageVelocity() const { return x60_averageVelocity; } zeus::CQuaternion GetRotation(const CSegId& seg, const CCharAnimTime& time) const; zeus::CVector3f GetOffset(const CSegId& seg, const CCharAnimTime& time) const; bool HasOffset(const CSegId& seg) const; diff --git a/Runtime/Character/CAnimTreeBlend.cpp b/Runtime/Character/CAnimTreeBlend.cpp index e69de29bb..f5c09cbd7 100644 --- a/Runtime/Character/CAnimTreeBlend.cpp +++ b/Runtime/Character/CAnimTreeBlend.cpp @@ -0,0 +1,46 @@ +#include "CAnimTreeBlend.hpp" + +namespace urde +{ + +std::string CAnimTreeBlend::CreatePrimitiveName(const std::shared_ptr& a, + const std::shared_ptr& b, + float scale) +{ + return ""; +} + +CAnimTreeBlend::CAnimTreeBlend(bool b1, + const std::shared_ptr& a, + const std::shared_ptr& b, + float blendWeight, const std::string& name) +: CAnimTreeTweenBase(b1, a, b, 1 | 2, name), x24_blendWeight(blendWeight) +{ + +} + +SAdvancementResults CAnimTreeBlend::VAdvanceView(const CCharAnimTime& a) +{ +} + +CCharAnimTime CAnimTreeBlend::VGetTimeRemaining() const +{ +} + +CSteadyStateAnimInfo CAnimTreeBlend::VGetSteadyStateAnimInfo() const +{ +} + +std::shared_ptr CAnimTreeBlend::VClone() const +{ +} + +void CAnimTreeBlend::SetBlendingWeight(float w) +{ +} + +float CAnimTreeBlend::VGetBlendingWeight() const +{ +} + +} diff --git a/Runtime/Character/CAnimTreeBlend.hpp b/Runtime/Character/CAnimTreeBlend.hpp index 5ed3fee17..dc9bc2664 100644 --- a/Runtime/Character/CAnimTreeBlend.hpp +++ b/Runtime/Character/CAnimTreeBlend.hpp @@ -1,11 +1,30 @@ #ifndef __URDE_CANIMTREEBLEND_HPP__ #define __URDE_CANIMTREEBLEND_HPP__ +#include "CAnimTreeTweenBase.hpp" + namespace urde { -class CAnimTreeBlend +class CAnimTreeBlend : public CAnimTreeTweenBase { + float x24_blendWeight; +public: + static std::string CreatePrimitiveName(const std::shared_ptr& a, + const std::shared_ptr& b, + float scale); + + CAnimTreeBlend(bool, + const std::shared_ptr& a, + const std::shared_ptr& b, + float blendWeight, const std::string& name); + + SAdvancementResults VAdvanceView(const CCharAnimTime& a); + CCharAnimTime VGetTimeRemaining() const; + CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const; + std::shared_ptr VClone() const; + void SetBlendingWeight(float w); + float VGetBlendingWeight() const; }; } diff --git a/Runtime/Character/CAnimTreeDoubleChild.cpp b/Runtime/Character/CAnimTreeDoubleChild.cpp index e69de29bb..616516629 100644 --- a/Runtime/Character/CAnimTreeDoubleChild.cpp +++ b/Runtime/Character/CAnimTreeDoubleChild.cpp @@ -0,0 +1,77 @@ +#include "CAnimTreeDoubleChild.hpp" + +namespace urde +{ + +CAnimTreeDoubleChild::CAnimTreeDoubleChild(const std::shared_ptr& a, + const std::shared_ptr& b, + const std::string& name) +: CAnimTreeNode(name), x14_a(a), x18_b(b) +{ +} + +SAdvancementResults CAnimTreeDoubleChild::VAdvanceView(const CCharAnimTime& a) +{ +} + +u32 CAnimTreeDoubleChild::VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, + u32 capacity, u32 iterator, u32) const +{ +} + +u32 CAnimTreeDoubleChild::VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, + u32 capacity, u32 iterator, u32) const +{ +} + +u32 CAnimTreeDoubleChild::VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, + u32 capacity, u32 iterator, u32) const +{ +} + +u32 CAnimTreeDoubleChild::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, + u32 capacity, u32 iterator, u32) const +{ +} + +bool CAnimTreeDoubleChild::VGetBoolPOIState(const char* name) const +{ +} + +s32 CAnimTreeDoubleChild::VGetInt32POIState(const char* name) const +{ +} + +CParticleData::EParentedMode CAnimTreeDoubleChild::VGetParticlePOIState(const char* name) const +{ +} + +void CAnimTreeDoubleChild::VSetPhase(float) +{ +} + +SAdvancementResults CAnimTreeDoubleChild::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const +{ +} + +u32 CAnimTreeDoubleChild::Depth() const +{ +} + +CAnimTreeEffectiveContribution CAnimTreeDoubleChild::VGetContributionOfHighestInfluence() const +{ +} + +u32 CAnimTreeDoubleChild::VGetNumChildren() const +{ +} + +std::shared_ptr CAnimTreeDoubleChild::VGetBestUnblendedChild() const +{ +} + +void CAnimTreeDoubleChild::VGetWeightedReaders(std::vector>>& out, float w) const +{ +} + +} diff --git a/Runtime/Character/CAnimTreeDoubleChild.hpp b/Runtime/Character/CAnimTreeDoubleChild.hpp index f208b2ccb..846576df9 100644 --- a/Runtime/Character/CAnimTreeDoubleChild.hpp +++ b/Runtime/Character/CAnimTreeDoubleChild.hpp @@ -8,7 +8,12 @@ namespace urde class CAnimTreeDoubleChild : public CAnimTreeNode { + std::shared_ptr x14_a; + std::shared_ptr x18_b; public: + CAnimTreeDoubleChild(const std::shared_ptr& a, + const std::shared_ptr& b, + const std::string& name); SAdvancementResults VAdvanceView(const CCharAnimTime& a); u32 VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 capacity, u32 iterator, u32) const; u32 VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, u32 capacity, u32 iterator, u32) const; @@ -23,6 +28,15 @@ public: CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const; u32 VGetNumChildren() const; std::shared_ptr VGetBestUnblendedChild() const; + void VGetWeightedReaders(std::vector>>& out, float w) const; + + virtual float VGetLeftChildWeight() const=0; + float GetLeftChildWeight() const { return VGetLeftChildWeight(); } + virtual float VGetRightChildWeight() const=0; + float GetRightChildWeight() const { return VGetRightChildWeight(); } + + const std::shared_ptr& GetLeftChild() const { return x14_a; } + const std::shared_ptr& GetRightChild() const { return x18_b; } }; } diff --git a/Runtime/Character/CAnimTreeTweenBase.cpp b/Runtime/Character/CAnimTreeTweenBase.cpp index e69de29bb..18a71c39a 100644 --- a/Runtime/Character/CAnimTreeTweenBase.cpp +++ b/Runtime/Character/CAnimTreeTweenBase.cpp @@ -0,0 +1,39 @@ +#include "CAnimTreeTweenBase.hpp" + +namespace urde +{ + +CAnimTreeTweenBase::CAnimTreeTweenBase(bool b1, + const std::shared_ptr& a, + const std::shared_ptr& b, + int flags, const std::string& name) +: CAnimTreeDoubleChild(a, b, name), x1c_flags(flags), x20_31_b1(b1) +{ +} + +void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const +{ +} + +void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, + const CCharAnimTime& time) const +{ +} + +bool CAnimTreeTweenBase::VHasOffset(const CSegId& seg) const +{ +} + +zeus::CVector3f CAnimTreeTweenBase::VGetOffset(const CSegId& seg) const +{ +} + +zeus::CQuaternion CAnimTreeTweenBase::VGetRotation(const CSegId& seg) const +{ +} + +std::shared_ptr CAnimTreeTweenBase::VSimplified() +{ +} + +} diff --git a/Runtime/Character/CAnimTreeTweenBase.hpp b/Runtime/Character/CAnimTreeTweenBase.hpp index 7f1d16db1..0edc8d298 100644 --- a/Runtime/Character/CAnimTreeTweenBase.hpp +++ b/Runtime/Character/CAnimTreeTweenBase.hpp @@ -8,6 +8,31 @@ namespace urde class CAnimTreeTweenBase : public CAnimTreeDoubleChild { + int x1c_flags; + bool x20_31_b1; + bool x20_30_b2 = false; +public: + CAnimTreeTweenBase(bool, + const std::shared_ptr& a, + const std::shared_ptr& b, + int, const std::string& name); + + virtual void SetBlendingWeight(float w)=0; + virtual float VGetBlendingWeight() const=0; + + float GetBlendingWeight() const { return VGetBlendingWeight(); } + + float VGetLeftChildWeight() const { return 1.f - GetBlendingWeight(); } + float VGetRightChildWeight() const { return GetBlendingWeight(); } + + void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const; + void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const; + bool VHasOffset(const CSegId& seg) const; + zeus::CVector3f VGetOffset(const CSegId& seg) const; + zeus::CQuaternion VGetRotation(const CSegId& seg) const; + + std::shared_ptr VSimplified(); + bool ShouldCullTree() const { return false; } }; } diff --git a/Runtime/Character/CAnimationManager.cpp b/Runtime/Character/CAnimationManager.cpp index 5277494ce..bb6f3df0e 100644 --- a/Runtime/Character/CAnimationManager.cpp +++ b/Runtime/Character/CAnimationManager.cpp @@ -1,6 +1,7 @@ #include "CAnimationManager.hpp" #include "CAnimationDatabaseGame.hpp" #include "CTransitionDatabaseGame.hpp" +#include "IMetaAnim.hpp" namespace urde { @@ -10,4 +11,16 @@ const CAnimationDatabaseGame* CAnimationManager::GetAnimationDatabase() const return x0_animDB.GetObj(); } +std::shared_ptr +CAnimationManager::GetAnimationTree(u32 animIdx, const CMetaAnimTreeBuildOrders& orders) const +{ + const std::shared_ptr& anim = x0_animDB->GetMetaAnim(animIdx); + return anim->GetAnimationTree(x8_sysCtx, orders); +} + +const std::shared_ptr& CAnimationManager::GetMetaAnimation(u32 idx) const +{ + return x0_animDB->GetMetaAnim(idx); +} + } diff --git a/Runtime/Character/CAnimationManager.hpp b/Runtime/Character/CAnimationManager.hpp index 864e2a40c..b2a3f541d 100644 --- a/Runtime/Character/CAnimationManager.hpp +++ b/Runtime/Character/CAnimationManager.hpp @@ -9,6 +9,9 @@ namespace urde class CAnimationDatabaseGame; class CTransitionDatabaseGame; class CSimplePool; +class CAnimTreeNode; +class CMetaAnimTreeBuildOrders; +class IMetaAnim; class CAnimationManager { @@ -20,6 +23,8 @@ public: : x0_animDB(animDB), x8_sysCtx(sysCtx) {} const CAnimationDatabaseGame* GetAnimationDatabase() const; + std::shared_ptr GetAnimationTree(u32, const CMetaAnimTreeBuildOrders& orders) const; + const std::shared_ptr& GetMetaAnimation(u32) const; }; } diff --git a/Runtime/Character/CCharLayoutInfo.cpp b/Runtime/Character/CCharLayoutInfo.cpp index a5e0742f8..224d2805c 100644 --- a/Runtime/Character/CCharLayoutInfo.cpp +++ b/Runtime/Character/CCharLayoutInfo.cpp @@ -37,9 +37,10 @@ void CCharLayoutNode::Bone::read(CInputStream& in) } CCharLayoutNode::CCharLayoutNode(CInputStream& in) +: x0_boneMap(in.readUint32Big()) { - u32 count = in.readUint32Big(); - for (u32 i=0 ; i>& GetAnimBBoxList() const { return x88_aabbs; } + ResId GetIceModelId() const {return xa8_cmdlOverlay;} ResId GetIceSkinRulesId() const {return xac_cskrOverlay;} const CParticleResData& GetParticleResData() const {return x44_partRes;} + u32 GetAnimationIndex(u32 idx) const { return xb0_animIdxs[idx]; } }; } diff --git a/Runtime/Character/CFBStreamedCompression.cpp b/Runtime/Character/CFBStreamedCompression.cpp index 4e374059b..5e2f975b3 100644 --- a/Runtime/Character/CFBStreamedCompression.cpp +++ b/Runtime/Character/CFBStreamedCompression.cpp @@ -1,4 +1,5 @@ #include "CFBStreamedCompression.hpp" +#include "CFBStreamedAnimReader.hpp" namespace urde { @@ -13,6 +14,8 @@ CFBStreamedCompression::CFBStreamedCompression(CInputStream& in, IObjectStore& o if (x4_evnt) x8_evntToken = objStore.GetObj(SObjectTag{FOURCC('EVNT'), x4_evnt}); + + x10_averageVelocity = CalculateAverageVelocity(GetPerChannelHeaders()); } const u32* CFBStreamedCompression::GetTimes() const @@ -217,4 +220,65 @@ u32 CFBStreamedCompression::ComputeBitstreamWords(const u8* chans) return (totalBits * keyCount + 31) / 32; } +float CFBStreamedCompression::CalculateAverageVelocity(const u8* chans) +{ + u32 boneChanCount = *reinterpret_cast(chans); + chans += 4; + + u32 keyCount; + u32 rootIdx = 0; + if (m_pc) + { + keyCount = *reinterpret_cast(chans + 0x4); + for (u32 c=0 ; c(chans); + if (boneId == 3) + break; + ++rootIdx; + + chans += 0x8; + u32 tKeyCount = *reinterpret_cast(chans + 0xc); + chans += 0x10; + if (tKeyCount) + chans += 0xc; + } + } + else + { + keyCount = *reinterpret_cast(chans + 0x4); + for (u32 c=0 ; c(chans); + if (boneId == 3) + break; + ++rootIdx; + + chans += 0x6; + u16 tKeyCount = *reinterpret_cast(chans + 0x9); + chans += 0xb; + if (tKeyCount) + chans += 0x9; + } + } + + CBitLevelLoader loader(GetBitstreamPointer()); + CFBStreamedAnimReaderTotals tempTotals(*this); + tempTotals.CalculateDown(); + const float* floats = tempTotals.GetFloats(rootIdx); + zeus::CVector3f transCompA(floats[4], floats[5], floats[6]); + + float accumMag = 0.f; + for (u32 i=0 ; i x8_evntToken; std::unique_ptr xc_rotsAndOffs; + float x10_averageVelocity; zeus::CVector3f x14_rootOffset; u8* ReadBoneChannelDescriptors(u8* out, CInputStream& in); u32 ComputeBitstreamWords(const u8* chans); std::unique_ptr GetRotationsAndOffsets(u32 words, CInputStream& in); + float CalculateAverageVelocity(const u8* chans); public: CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc); @@ -72,6 +74,7 @@ public: const u8* GetBitstreamPointer() const; bool IsLooping() const { return MainHeader().looping; } CCharAnimTime GetAnimationDuration() const { return MainHeader().duration; } + float GetAverageVelocity() const { return x10_averageVelocity; } const zeus::CVector3f& GetRootOffset() const { return x14_rootOffset; } bool HasPOIData() const { return x8_evntToken; } const std::vector& GetBoolPOIStream() const { return x8_evntToken->GetBoolPOIStream(); } diff --git a/Runtime/Character/CHierarchyPoseBuilder.cpp b/Runtime/Character/CHierarchyPoseBuilder.cpp index fe2f79c76..41748800d 100644 --- a/Runtime/Character/CHierarchyPoseBuilder.cpp +++ b/Runtime/Character/CHierarchyPoseBuilder.cpp @@ -8,7 +8,7 @@ namespace urde void CHierarchyPoseBuilder::BuildIntoHierarchy(const CCharLayoutInfo& layout, const CSegId& boneId, const CSegId& nullId) { - if (!x0_treeMap.HasElement(boneId)) + if (!x38_treeMap.HasElement(boneId)) { const CCharLayoutNode::Bone& bone = layout.GetRootNode()->GetBoneMap()[boneId]; if (bone.x0_parentId == nullId) @@ -16,17 +16,17 @@ void CHierarchyPoseBuilder::BuildIntoHierarchy(const CCharLayoutInfo& layout, xcec_rootId = boneId; xcf0_hasRoot = true; zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId); - x0_treeMap[boneId] = CTreeNode(origin); + x38_treeMap[boneId] = CTreeNode(origin); } else { BuildIntoHierarchy(layout, bone.x0_parentId, nullId); zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId); - CTreeNode& pNode = x0_treeMap[bone.x0_parentId]; + CTreeNode& pNode = x38_treeMap[bone.x0_parentId]; CTreeNode node(origin); node.x1_sibling = pNode.x0_child; pNode.x0_child = boneId; - x0_treeMap[boneId] = node; + x38_treeMap[boneId] = node; } } } @@ -43,7 +43,7 @@ void CHierarchyPoseBuilder::RecursivelyBuildNoScale(const CSegId& boneId, const CSegId curBone = node.x0_child; while (curBone != 0) { - const CTreeNode& node = x0_treeMap[curBone]; + const CTreeNode& node = x38_treeMap[curBone]; RecursivelyBuild(curBone, node, pose, quat, xf, xfOffset); curBone = node.x1_sibling; } @@ -56,8 +56,8 @@ void CHierarchyPoseBuilder::RecursivelyBuild(const CSegId& boneId, const CTreeNo zeus::CQuaternion quat = parentRot * node.x4_rotation; float scale; - if (xcf4_layoutDesc.GetScaledLayoutDescription()) - scale = xcf4_layoutDesc.GetScaledLayoutDescription()->GetScale(); + if (x0_layoutDesc.GetScaledLayoutDescription()) + scale = x0_layoutDesc.GetScaledLayoutDescription()->GetScale(); else scale = 1.f; @@ -73,7 +73,7 @@ void CHierarchyPoseBuilder::RecursivelyBuild(const CSegId& boneId, const CTreeNo CSegId curBone = node.x0_child; while (curBone != 0) { - const CTreeNode& node = x0_treeMap[curBone]; + const CTreeNode& node = x38_treeMap[curBone]; RecursivelyBuild(curBone, node, pose, quat, quat, xfOffset); curBone = node.x1_sibling; } @@ -83,14 +83,14 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor { TLockedToken layoutInfoTok; float scale; - if (xcf4_layoutDesc.GetScaledLayoutDescription()) + if (x0_layoutDesc.GetScaledLayoutDescription()) { - layoutInfoTok = xcf4_layoutDesc.GetScaledLayoutDescription()->GetCharLayoutInfo(); - scale = xcf4_layoutDesc.GetScaledLayoutDescription()->GetScale(); + layoutInfoTok = x0_layoutDesc.GetScaledLayoutDescription()->GetCharLayoutInfo(); + scale = x0_layoutDesc.GetScaledLayoutDescription()->GetScale(); } else { - layoutInfoTok = xcf4_layoutDesc.GetCharLayoutInfo(); + layoutInfoTok = x0_layoutDesc.GetCharLayoutInfo(); scale = 1.f; } const CCharLayoutInfo& layoutInfo = *layoutInfoTok.GetObj(); @@ -112,7 +112,7 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor for (CSegId* id=&buildIDs[idCount] ; id != buildIDs ; --id) { CSegId& thisId = id[-1]; - const CTreeNode& node = x0_treeMap[thisId]; + const CTreeNode& node = x38_treeMap[thisId]; accumRot *= node.x4_rotation; accumPos += accumXF * node.x14_offset; if (scale == 1.f) @@ -128,7 +128,7 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor void CHierarchyPoseBuilder::BuildNoScale(CPoseAsTransforms& pose) { pose.Clear(); - const CTreeNode& node = x0_treeMap[xcec_rootId]; + const CTreeNode& node = x38_treeMap[xcec_rootId]; zeus::CQuaternion quat; zeus::CMatrix3f mtx; zeus::CVector3f vec; @@ -137,16 +137,16 @@ void CHierarchyPoseBuilder::BuildNoScale(CPoseAsTransforms& pose) void CHierarchyPoseBuilder::Insert(const CSegId& boneId, const zeus::CQuaternion& quat) { - x0_treeMap[boneId] = CTreeNode(quat); + x38_treeMap[boneId] = CTreeNode(quat); } void CHierarchyPoseBuilder::Insert(const CSegId& boneId, const zeus::CQuaternion& quat, const zeus::CVector3f& offset) { - x0_treeMap[boneId] = CTreeNode(quat, offset); + x38_treeMap[boneId] = CTreeNode(quat, offset); } CHierarchyPoseBuilder::CHierarchyPoseBuilder(const CLayoutDescription& layout) -: xcf4_layoutDesc(layout) +: x0_layoutDesc(layout), x38_treeMap(layout.GetCharLayoutInfo()->GetSegIdList().GetList().size()) { TLockedToken layoutInfoTok; if (layout.GetScaledLayoutDescription()) diff --git a/Runtime/Character/CHierarchyPoseBuilder.hpp b/Runtime/Character/CHierarchyPoseBuilder.hpp index 6513a948f..986d45a7e 100644 --- a/Runtime/Character/CHierarchyPoseBuilder.hpp +++ b/Runtime/Character/CHierarchyPoseBuilder.hpp @@ -14,6 +14,10 @@ class CPoseAsTransforms; class CHierarchyPoseBuilder { + CLayoutDescription x0_layoutDesc; + bool x34_ = 0; + + struct CTreeNode { CSegId x0_child = 0; @@ -26,11 +30,10 @@ class CHierarchyPoseBuilder CTreeNode(const zeus::CQuaternion& quat, const zeus::CVector3f& offset) : x4_rotation(quat), x14_offset(offset) {} }; - TSegIdMap x0_treeMap; + TSegIdMap x38_treeMap; CSegId xcec_rootId; bool xcf0_hasRoot = false; - CLayoutDescription xcf4_layoutDesc; void BuildIntoHierarchy(const CCharLayoutInfo& layout, const CSegId& boneId, const CSegId& nullId); diff --git a/Runtime/Character/CMakeLists.txt b/Runtime/Character/CMakeLists.txt index b97a25fd6..9a3865e3f 100644 --- a/Runtime/Character/CMakeLists.txt +++ b/Runtime/Character/CMakeLists.txt @@ -50,6 +50,7 @@ set(CHARACTER_SOURCES CAnimTreeSequence.hpp CAnimTreeSequence.cpp CSequenceHelper.hpp CSequenceHelper.cpp CAnimTreeAnimReaderContainer.hpp CAnimTreeAnimReaderContainer.cpp + CTreeUtils.hpp CTreeUtils.cpp CAnimTreeBlend.hpp CAnimTreeBlend.cpp CAnimTreeNode.hpp CAnimTreeNode.cpp CAnimTreeScale.hpp CAnimTreeScale.cpp diff --git a/Runtime/Character/CModelData.cpp b/Runtime/Character/CModelData.cpp index 5e04bd0a3..ff0373d8b 100644 --- a/Runtime/Character/CModelData.cpp +++ b/Runtime/Character/CModelData.cpp @@ -3,7 +3,6 @@ #include "IAnimReader.hpp" #include "Graphics/CGraphics.hpp" #include "Graphics/CSkinnedModel.hpp" -#include "Graphics/CFrustumPlanes.hpp" #include "Graphics/CVertexMorphEffect.hpp" #include "Editor/ProjectManager.hpp" #include "CActorLights.hpp" @@ -266,14 +265,14 @@ bool CModelData::IsAnimating() const } bool CModelData::IsInFrustum(const zeus::CTransform& xf, - const CFrustumPlanes& frustum) const + const zeus::CFrustum& frustum) const { if (!x10_animData && !x1c_normalModel) return true; - return frustum.BoxInFrustumPlanes(GetBounds(xf)); + return frustum.aabbFrustumTest(GetBounds(xf)); } -void CModelData::RenderParticles(const CFrustumPlanes& frustum) const +void CModelData::RenderParticles(const zeus::CFrustum& frustum) const { if (x10_animData) x10_animData->RenderAuxiliary(frustum); diff --git a/Runtime/Character/CModelData.hpp b/Runtime/Character/CModelData.hpp index 79aeec138..23f197ced 100644 --- a/Runtime/Character/CModelData.hpp +++ b/Runtime/Character/CModelData.hpp @@ -16,7 +16,6 @@ class CStateManager; class CActorLights; struct CModelFlags; class CRandom16; -class CFrustumPlanes; class CAnimData; class CModel; class CSkinnedModel; @@ -128,8 +127,8 @@ public: SAdvancementDeltas AdvanceAnimationIgnoreParticles(float dt, CRandom16&, bool advTree); SAdvancementDeltas AdvanceAnimation(float dt, CStateManager& stateMgr, TAreaId aid, bool advTree); bool IsAnimating() const; - bool IsInFrustum(const zeus::CTransform& xf, const CFrustumPlanes& frustum) const; - void RenderParticles(const CFrustumPlanes& frustum) const; + bool IsInFrustum(const zeus::CTransform& xf, const zeus::CFrustum& frustum) const; + void RenderParticles(const zeus::CFrustum& frustum) const; void Touch(EWhichModel, int shaderIdx); void Touch(const CStateManager& stateMgr, int shaderIdx); void RenderThermal(const zeus::CTransform& xf, const zeus::CColor& a, const zeus::CColor& b); diff --git a/Runtime/Character/CParticleDatabase.cpp b/Runtime/Character/CParticleDatabase.cpp index 92d72b664..15e75a4e7 100644 --- a/Runtime/Character/CParticleDatabase.cpp +++ b/Runtime/Character/CParticleDatabase.cpp @@ -20,4 +20,13 @@ void CParticleDatabase::StartEffect(const std::string& name, u32 flags, const CP { } +void CParticleDatabase::Update(float dt, const CPoseAsTransforms& pose, const CCharLayoutInfo& charInfo, + const zeus::CTransform& xf, const zeus::CVector3f& vec, CStateManager& stateMgr) +{ +} + +void CParticleDatabase::AddToRendererClipped(const zeus::CFrustum& frustum) +{ +} + } diff --git a/Runtime/Character/CParticleDatabase.hpp b/Runtime/Character/CParticleDatabase.hpp index 6f60482c9..b0c774445 100644 --- a/Runtime/Character/CParticleDatabase.hpp +++ b/Runtime/Character/CParticleDatabase.hpp @@ -3,10 +3,13 @@ #include "CCharacterInfo.hpp" #include "CParticleGenInfo.hpp" +#include "zeus/CFrustum.hpp" #include namespace urde { +class CPoseAsTransforms; +class CCharLayoutInfo; class CParticleDatabase { @@ -17,6 +20,9 @@ public: void SuspendAllActiveEffects(CStateManager& stateMgr); void StartEffect(const std::string& name, u32 flags, const CParticleData& data, const zeus::CVector3f& scale, CStateManager& stateMgr, TAreaId aid, u32 unk1); + void Update(float dt, const CPoseAsTransforms& pose, const CCharLayoutInfo& charInfo, + const zeus::CTransform& xf, const zeus::CVector3f& vec, CStateManager& stateMgr); + void AddToRendererClipped(const zeus::CFrustum& frustum); }; } diff --git a/Runtime/Character/CTransitionManager.cpp b/Runtime/Character/CTransitionManager.cpp index e69de29bb..9b9c76703 100644 --- a/Runtime/Character/CTransitionManager.cpp +++ b/Runtime/Character/CTransitionManager.cpp @@ -0,0 +1,14 @@ +#include "CTransitionManager.hpp" +#include "CTreeUtils.hpp" + +namespace urde +{ + +std::shared_ptr +CTransitionManager::GetTransitionTree(const std::shared_ptr& a, + const std::shared_ptr& b) const +{ + return CTreeUtils::GetTransitionTree(a, b, x0_animCtx); +} + +} diff --git a/Runtime/Character/CTransitionManager.hpp b/Runtime/Character/CTransitionManager.hpp index 7b4dea426..548d9c547 100644 --- a/Runtime/Character/CTransitionManager.hpp +++ b/Runtime/Character/CTransitionManager.hpp @@ -9,12 +9,15 @@ namespace urde class CTransitionDatabaseGame; class CRandom16; class CSimplePool; +class CAnimTreeNode; class CTransitionManager { CAnimSysContext x0_animCtx; public: CTransitionManager(const CAnimSysContext& sysCtx) : x0_animCtx(sysCtx) {} + std::shared_ptr GetTransitionTree(const std::shared_ptr& a, + const std::shared_ptr& b) const; }; } diff --git a/Runtime/Character/CTreeUtils.cpp b/Runtime/Character/CTreeUtils.cpp new file mode 100644 index 000000000..510c26c18 --- /dev/null +++ b/Runtime/Character/CTreeUtils.cpp @@ -0,0 +1,20 @@ +#include "CTreeUtils.hpp" +#include "CAnimTreeNode.hpp" +#include "CAnimSysContext.hpp" +#include "CTransitionDatabaseGame.hpp" +#include "IMetaTrans.hpp" + +namespace urde +{ + +std::shared_ptr CTreeUtils::GetTransitionTree(const std::shared_ptr& a, + const std::shared_ptr& b, + const CAnimSysContext& animCtx) +{ + CAnimTreeEffectiveContribution contribA = a->GetContributionOfHighestInfluence(); + CAnimTreeEffectiveContribution contribB = b->GetContributionOfHighestInfluence(); + return animCtx.x0_transDB->GetMetaTrans(contribA.GetAnimDatabaseIndex(), + contribB.GetAnimDatabaseIndex())->GetTransitionTree(a, b, animCtx); +} + +} diff --git a/Runtime/Character/CTreeUtils.hpp b/Runtime/Character/CTreeUtils.hpp new file mode 100644 index 000000000..e56748be9 --- /dev/null +++ b/Runtime/Character/CTreeUtils.hpp @@ -0,0 +1,21 @@ +#ifndef __URDE_CTREEUTILS_HPP__ +#define __URDE_CTREEUTILS_HPP__ + +#include "RetroTypes.hpp" + +namespace urde +{ +class CAnimTreeNode; +class CAnimSysContext; + +class CTreeUtils +{ +public: + static std::shared_ptr GetTransitionTree(const std::shared_ptr& a, + const std::shared_ptr& b, + const CAnimSysContext& animCtx); +}; + +} + +#endif // __URDE_CTREEUTILS_HPP__ diff --git a/Runtime/Character/IMetaTrans.hpp b/Runtime/Character/IMetaTrans.hpp index 27caf18f6..df0c76115 100644 --- a/Runtime/Character/IMetaTrans.hpp +++ b/Runtime/Character/IMetaTrans.hpp @@ -24,6 +24,13 @@ public: const std::weak_ptr& b, const CAnimSysContext& animSys) const=0; virtual EMetaTransType GetType() const=0; + + std::shared_ptr GetTransitionTree(const std::weak_ptr& a, + const std::weak_ptr& b, + const CAnimSysContext& animSys) + { + return VGetTransitionTree(a, b, animSys); + } }; } diff --git a/Runtime/Character/TSegIdMap.hpp b/Runtime/Character/TSegIdMap.hpp index d85006a56..ca2cb95f9 100644 --- a/Runtime/Character/TSegIdMap.hpp +++ b/Runtime/Character/TSegIdMap.hpp @@ -11,45 +11,52 @@ template class TSegIdMap { CSegId x0_boneCount = 0; - CSegId x1_curPrevBone = 0; - u32 x4_capacity = 100; - CSegId x8_prevBones[100]; - T x6c_bones[100]; + CSegId x1_capacity = 0; + u32 x4_maxCapacity = 100; + std::pair x8_indirectionMap[100]; + std::unique_ptr xd0_bones; + CSegId xd4_curPrevBone = 0; public: + TSegIdMap(const CSegId& capacity) : x1_capacity(capacity), xd0_bones(new T[capacity]) {} T& operator[](const CSegId& id) {return SetElement(id);} - const T& operator[](const CSegId& id) const {return x6c_bones[id];} + const T& operator[](const CSegId& id) const {return xd0_bones[id];} T& SetElement(const CSegId& id, T&& obj) { - x6c_bones[id] = std::move(obj); - if (x8_prevBones[id] == 0xff) + xd0_bones[id] = std::move(obj); + if (x8_indirectionMap[id].first == 0xff) { - x8_prevBones[id] = x1_curPrevBone; - x1_curPrevBone = id; + x8_indirectionMap[id].first = xd4_curPrevBone; + x8_indirectionMap[id].second = x0_boneCount; + xd4_curPrevBone = id; ++x0_boneCount; } - return x6c_bones[id]; + return xd0_bones[id]; } T& SetElement(const CSegId& id) { - if (x8_prevBones[id] == 0xff) + if (x8_indirectionMap[id].first == 0xff) { - x8_prevBones[id] = x1_curPrevBone; - x1_curPrevBone = id; + x8_indirectionMap[id].first = xd4_curPrevBone; + x8_indirectionMap[id].second = x0_boneCount; + xd4_curPrevBone = id; ++x0_boneCount; } - return x6c_bones[id]; + return xd0_bones[id]; } void DelElement(const CSegId& id) { - if (x8_prevBones[id] != 0xff) + if (x8_indirectionMap[id].first != 0xff) { - if (id == x1_curPrevBone) - x1_curPrevBone = x8_prevBones[id]; - x8_prevBones[id] = 0xff; + if (id == xd4_curPrevBone) + xd4_curPrevBone = x8_indirectionMap[id].first; + x8_indirectionMap[id].first = 0xff; + x8_indirectionMap[id].second = 0xff; --x0_boneCount; } } - bool HasElement(const CSegId& id) const {return x8_prevBones[id] != 0xff;} + bool HasElement(const CSegId& id) const {return x8_indirectionMap[id].first != 0xff;} + + u32 GetCapacity() const { return x1_capacity; } }; } diff --git a/Runtime/Graphics/CFrustumPlanes.cpp b/Runtime/Graphics/CFrustumPlanes.cpp deleted file mode 100644 index 30f81fd32..000000000 --- a/Runtime/Graphics/CFrustumPlanes.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "CFrustumPlanes.hpp" - -namespace urde -{ - -CFrustumPlanes::CFrustumPlanes(const zeus::CTransform& cameraXf, float, float, float, bool, float) -{ -} - -bool CFrustumPlanes::PointInFrustumPlanes(const zeus::CVector3f& point) const -{ - return false; -} - -bool CFrustumPlanes::SphereInFrustumPlanes(const zeus::CSphere& sphere) const -{ - return false; -} - -bool CFrustumPlanes::BoxInFrustumPlanes(const zeus::CAABox& box) const -{ - return false; -} - -bool CFrustumPlanes::BoxInFrustumPlanes(const rstl::optional_object& box) const -{ - return false; -} - -} diff --git a/Runtime/Graphics/CFrustumPlanes.hpp b/Runtime/Graphics/CFrustumPlanes.hpp deleted file mode 100644 index 91f8d5e10..000000000 --- a/Runtime/Graphics/CFrustumPlanes.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __URDE_CFRUSTUMPLANES_HPP__ -#define __URDE_CFRUSTUMPLANES_HPP__ - -#include "zeus/CTransform.hpp" -#include "zeus/CAABox.hpp" -#include "rstl.hpp" - -namespace urde -{ - -class CFrustumPlanes -{ -public: - CFrustumPlanes(const zeus::CTransform& cameraXf, float, float, float, bool, float); - - bool PointInFrustumPlanes(const zeus::CVector3f& point) const; - bool SphereInFrustumPlanes(const zeus::CSphere& sphere) const; - bool BoxInFrustumPlanes(const zeus::CAABox& box) const; - bool BoxInFrustumPlanes(const rstl::optional_object& box) const; -}; - -} - -#endif // __URDE_CFRUSTUMPLANES_HPP__ diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index 3d4531a47..edb6d6507 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -36,7 +36,6 @@ set(GRAPHICS_SOURCES CSkinnedModel.hpp CSkinnedModel.cpp CVertexMorphEffect.hpp CVertexMorphEffect.cpp CMoviePlayer.hpp CMoviePlayer.cpp - CFrustumPlanes.hpp CFrustumPlanes.cpp CGraphicsPalette.hpp CGraphicsPalette.cpp CPVSVisSet.hpp CPVSVisSet.cpp CPVSVisOctree.hpp CPVSVisOctree.cpp diff --git a/Runtime/Graphics/CSkinnedModel.hpp b/Runtime/Graphics/CSkinnedModel.hpp index 96ba9f6f6..15a353ca3 100644 --- a/Runtime/Graphics/CSkinnedModel.hpp +++ b/Runtime/Graphics/CSkinnedModel.hpp @@ -34,10 +34,10 @@ public: CSkinnedModel(IObjectStore& store, ResId model, ResId skinRules, ResId layoutInfo, int shaderIdx); - TLockedToken& GetModel() {return x4_model;} - std::unique_ptr& GetModelInst() {return m_modelInst;} - TLockedToken& GetSkinRules() {return x10_skinRules;} - TLockedToken& GetLayoutInfo() {return x1c_layoutInfo;} + const TLockedToken& GetModel() const {return x4_model;} + const std::unique_ptr& GetModelInst() const {return m_modelInst;} + const TLockedToken& GetSkinRules() const {return x10_skinRules;} + const TLockedToken& GetLayoutInfo() const {return x1c_layoutInfo;} void Calculate(const CPoseAsTransforms& pose, const CModelFlags& drawFlags, diff --git a/Runtime/World/CMorphBall.hpp b/Runtime/World/CMorphBall.hpp index 0592084af..d779f38f2 100644 --- a/Runtime/World/CMorphBall.hpp +++ b/Runtime/World/CMorphBall.hpp @@ -13,7 +13,6 @@ class CActorLights; class CPlayer; class CDamageInfo; class CFinalInput; -class CFrustumPlanes; class CScriptWater; class CStateManager; @@ -91,7 +90,7 @@ public: zeus::CTransform GetPrimitiveTransform() const { return {}; } void DrawCollisionPrimitive() const {} void GetMinimumAlignmentSpeed() const {} - void PreRender(CStateManager&, const CFrustumPlanes&); + void PreRender(CStateManager&, const zeus::CFrustum&); void Render(const CStateManager&, const CActorLights*) const {} void ResetMorphBallTransitionFlash() {} void UpdateMorphBallTransitionFlash(float) {} @@ -108,7 +107,7 @@ public: void DisableHalfPipeStatus() {} void BallCloseToCollision(const CStateManager&, float) const {} void CollidedWith(const TUniqueId&, const CCollisionInfoList&, CStateManager&) {} - void IsInFrustum(const CFrustumPlanes&) const {} + void IsInFrustum(const zeus::CFrustum&) const {} void ComputeLiftForces(const zeus::CVector3f&, const zeus::CVector3f&, const CStateManager&) {} void CalculateSurfaceFriction() const {} void ApplyGravity(CStateManager&) {}