From 670eb998d468fc658998ae251291571fdbe171e7 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 21 Aug 2016 10:39:18 -1000 Subject: [PATCH] Work on character animation --- DataSpec/DNAMP1/ANCS.cpp | 19 +- Editor/ViewManager.cpp | 6 +- Runtime/CStateManager.hpp | 2 +- Runtime/CToken.hpp | 7 +- Runtime/Camera/CCameraManager.cpp | 2 +- Runtime/Character/CAnimData.cpp | 192 ++++++++++++++++-- Runtime/Character/CAnimData.hpp | 68 +++++-- Runtime/Character/CBoolPOINode.cpp | 2 +- Runtime/Character/CCharAnimTime.cpp | 7 + Runtime/Character/CCharAnimTime.hpp | 1 + Runtime/Character/CCharacterFactory.cpp | 4 +- Runtime/Character/CHierarchyPoseBuilder.hpp | 1 + Runtime/Character/CInt32POINode.cpp | 2 +- Runtime/Character/CModelData.cpp | 10 +- Runtime/Character/CModelData.hpp | 2 +- Runtime/Character/CPOINode.cpp | 14 +- Runtime/Character/CPOINode.hpp | 23 ++- Runtime/Character/CParticleDatabase.cpp | 13 ++ Runtime/Character/CParticleDatabase.hpp | 3 + Runtime/Character/CParticlePOINode.cpp | 2 +- Runtime/Character/CSkinBank.cpp | 8 + Runtime/Character/CSkinBank.hpp | 3 + Runtime/Character/CSkinRules.hpp | 6 + Runtime/Character/CSoundPOINode.cpp | 4 +- Runtime/Character/CSoundPOINode.hpp | 2 +- Runtime/Graphics/CBooRenderer.cpp | 2 +- Runtime/Graphics/CModel.hpp | 19 +- Runtime/Graphics/CModelBoo.cpp | 80 ++++++-- Runtime/Graphics/CSkinnedModel.cpp | 30 ++- Runtime/Graphics/CSkinnedModel.hpp | 19 +- .../Graphics/Shaders/CCameraBlurFilter.cpp | 2 +- Runtime/World/CWorldTransManager.cpp | 1 + Runtime/World/CWorldTransManager.hpp | 2 + hecl | 2 +- specter | 2 +- 35 files changed, 460 insertions(+), 102 deletions(-) diff --git a/DataSpec/DNAMP1/ANCS.cpp b/DataSpec/DNAMP1/ANCS.cpp index a37264df6..1b3690716 100644 --- a/DataSpec/DNAMP1/ANCS.cpp +++ b/DataSpec/DNAMP1/ANCS.cpp @@ -1083,10 +1083,25 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, Log.report(logvisor::Fatal, _S("'%s' not found as file"), yamlPath.getRelativePath().c_str()); - athena::io::FileReader yamlReader(yamlPath.getAbsolutePath()); - if (!BigYAML::ValidateFromYAMLFile(yamlReader)) + FILE* yamlFp = hecl::Fopen(yamlPath.getAbsolutePath().c_str(), _S("r")); + if (!yamlFp) + Log.report(logvisor::Fatal, _S("can't open '%s' for reading"), + yamlPath.getRelativePath().c_str()); + + if (!BigYAML::ValidateFromYAMLFile(yamlFp)) + { Log.report(logvisor::Fatal, _S("'%s' is not urde::DNAMP1::ANCS type"), yamlPath.getRelativePath().c_str()); + } + + athena::io::YAMLDocReader yamlReader; + yaml_parser_set_input_file(yamlReader.getParser(), yamlFp); + if (!yamlReader.parse()) + { + Log.report(logvisor::Fatal, _S("unable to parse '%s'"), + yamlPath.getRelativePath().c_str()); + } + fclose(yamlFp); ANCS ancs; ancs.read(yamlReader); diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index 5a546c5cd..db0d2a892 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -26,7 +26,7 @@ namespace urde void ViewManager::BuildTestPART(urde::IObjectStore& objStore) { -#if 0 +#if 1 SObjectTag samusCharSet = m_projManager.TagFromPath(_S("MP1/Shared/ANCS_77289A4A.blend")); SObjectTag platModel = m_projManager.TagFromPath(_S("MP1/Shared/CMDL_6FA561D0.blend")); SObjectTag bgModel = m_projManager.TagFromPath(_S("MP1/Shared/CMDL_BC34D54C.blend")); @@ -93,6 +93,7 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ) if (m_vm.m_modelTest.IsLoaded()) { +#if 0 CModelFlags flags; flags.m_extendedShaderIdx = 0; @@ -131,6 +132,8 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ) //g_Renderer->DoThermalBlendHot(); //m_spaceWarpFilter.setStrength(std::sin(m_theta * 5.f) * 0.5f + 0.5f); //m_spaceWarpFilter.draw(zeus::CVector2f{0.f, 0.f}); +#endif + } if (m_vm.m_partGen) { @@ -167,6 +170,7 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ) m_vm.m_moviePlayer->Update(1.f / 60.f); m_vm.m_moviePlayer->DrawFrame(); } + g_GameState->GetWorldTransitionManager()->Draw(); } specter::View* ViewManager::BuildSpaceViews() diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index eaa40179c..fb3bd49e9 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -275,7 +275,7 @@ public: TUniqueId AllocateUniqueId(); const std::shared_ptr& GetPlayerState() const {return x8b8_playerState;} - CRandom16& GetActiveRandom() {return x8fc_random;} + CRandom16* GetActiveRandom() {return x900_activeRandom;} CRumbleManager& GetRumbleManager() {return *x88c_rumbleManager;} CCameraFilterPass& GetCameraFilterPass(int idx) {return xb84_camFilterPasses[idx];} diff --git a/Runtime/CToken.hpp b/Runtime/CToken.hpp index 2983dc7a5..4691a4479 100644 --- a/Runtime/CToken.hpp +++ b/Runtime/CToken.hpp @@ -301,6 +301,9 @@ public: T* operator->() {return GetObj();} const T* operator->() const {return GetObj();} void Unlock() {TToken::Unlock(); m_obj = nullptr;} + + TCachedToken& operator=(const TCachedToken& other) { CToken::operator=(other); m_obj = nullptr; return *this; } + TCachedToken& operator=(const CToken& other) { CToken::operator=(other); m_obj = nullptr; return *this; } }; template @@ -309,9 +312,9 @@ class TLockedToken : public TCachedToken public: TLockedToken() = default; TLockedToken(const TLockedToken& other) : TCachedToken(other) { CToken::Lock(); } - TLockedToken& operator=(const TLockedToken& other) { CToken::operator=(other); CToken::Lock(); return *this; } + TLockedToken& operator=(const TLockedToken& other) { TCachedToken::operator=(other); CToken::Lock(); return *this; } TLockedToken(const CToken& other) : TCachedToken(other) { CToken::Lock(); } - TLockedToken& operator=(const CToken& other) { CToken::operator=(other); CToken::Lock(); return *this; } + TLockedToken& operator=(const CToken& other) { TCachedToken::operator=(other); CToken::Lock(); return *this; } TLockedToken(CToken&& other) : TCachedToken(std::move(other)) { CToken::Lock(); } }; diff --git a/Runtime/Camera/CCameraManager.cpp b/Runtime/Camera/CCameraManager.cpp index e0d75452e..2f207cf65 100644 --- a/Runtime/Camera/CCameraManager.cpp +++ b/Runtime/Camera/CCameraManager.cpp @@ -78,7 +78,7 @@ void CCameraManager::Update(float dt, CStateManager& stateMgr) it = x18_shakers.erase(it); continue; } - x30_shakeOffset += it->GeneratePoint(dt, stateMgr.GetActiveRandom()); + x30_shakeOffset += it->GeneratePoint(dt, *stateMgr.GetActiveRandom()); ++it; } diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index a9c5d7a86..075250b00 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -15,6 +15,7 @@ #include "CAnimTreeNode.hpp" #include "CAnimPerSegmentData.hpp" #include "CSegStatementSet.hpp" +#include "CStateManager.hpp" namespace urde { @@ -83,7 +84,7 @@ static void AdvanceAnimationTree(std::weak_ptr& anim, const CChar { } -void CAnimData::AdvanceAdditiveAnims(float dt) +SAdvancementDeltas CAnimData::AdvanceAdditiveAnims(float dt) { CCharAnimTime time(dt); @@ -102,8 +103,11 @@ void CAnimData::AdvanceAdditiveAnims(float dt) } } -void CAnimData::UpdateAdditiveAnims(float) +SAdvancementDeltas CAnimData::UpdateAdditiveAnims(float dt) { + + + return AdvanceAdditiveAnims(dt); } bool CAnimData::IsAdditiveAnimation(u32) const @@ -228,16 +232,30 @@ void CAnimData::RenderAuxiliary(const CFrustumPlanes& frustum) const { } -void CAnimData::Render(const CSkinnedModel& model, const CModelFlags& drawFlags, +void CAnimData::Render(CSkinnedModel& model, const CModelFlags& drawFlags, const rstl::optional_object& morphEffect, - const float* morphMagnitudes) const + const float* morphMagnitudes) { + SetupRender(model, drawFlags, morphEffect, morphMagnitudes); + DrawSkinnedModel(model, drawFlags); } -void CAnimData::SetupRender(const CSkinnedModel& model, +void CAnimData::SetupRender(CSkinnedModel& model, + const CModelFlags& drawFlags, const rstl::optional_object& morphEffect, - const float* morphMagnitudes) const + const float* morphMagnitudes) { + if (!x220_30_poseBuilt) + { + x2fc_poseBuilder.BuildNoScale(x224_pose); + x220_30_poseBuilt = true; + } + PoseSkinnedModel(model, x224_pose, drawFlags, morphEffect, morphMagnitudes); +} + +void CAnimData::DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags) +{ + model.Draw(flags); } void CAnimData::PreRender() @@ -246,7 +264,7 @@ void CAnimData::PreRender() { RecalcPoseBuilder(nullptr); x220_31_poseCached = true; - x220_30_ = false; + x220_30_poseBuilt = false; } } @@ -266,22 +284,164 @@ void CAnimData::SetAnimation(const CAnimPlaybackParms& parms, bool) { } -void CAnimData::DoAdvance(float, bool&, CRandom16&, bool) +SAdvancementDeltas CAnimData::DoAdvance(float dt, bool& b1, CRandom16& random, bool b2) { + b1 = false; + + zeus::CVector3f offsetPre, offsetPost; + zeus::CQuaternion quatPre, quatPost; + + ResetPOILists(); + float scaleDt = dt * x200_speedScale; + if (x2fc_poseBuilder.HasRoot()) + { + SAdvancementDeltas deltas = UpdateAdditiveAnims(scaleDt); + offsetPre = deltas.x0_posDelta; + quatPre = deltas.xc_rotDelta; + } + + if (!x220_24_animating) + { + b1 = true; + return {}; + } + + if (x220_29_) + { + x220_29_ = false; + b1 = true; + } + + if (b2) + { + SetRandomPlaybackRate(random); + CCharAnimTime time(scaleDt); + if (x220_25_loop) + { + while (time.GreaterThanZero() && !time.EpsilonZero()) + { + x210_passedIntCount += x1f8_animRoot->GetInt32POIList(time, g_Int32POINodes.data(), 16, x210_passedIntCount, 0); + x20c_passedBoolCount += x1f8_animRoot->GetBoolPOIList(time, g_BoolPOINodes.data(), 16, x20c_passedBoolCount, 0); + x214_passedParticleCount += x1f8_animRoot->GetParticlePOIList(time, g_ParticlePOINodes.data(), 16, x214_passedParticleCount, 0); + x218_passedSoundCount += x1f8_animRoot->GetSoundPOIList(time, g_SoundPOINodes.data(), 16, x218_passedSoundCount, 0); + AdvanceAnim(time, offsetPost, quatPost); + } + } + else + { + CCharAnimTime remTime = x1f8_animRoot->VGetTimeRemaining(); + while (remTime.GreaterThanZero() && !remTime.EpsilonZero()) + { + x210_passedIntCount += x1f8_animRoot->GetInt32POIList(time, g_Int32POINodes.data(), 16, x210_passedIntCount, 0); + x20c_passedBoolCount += x1f8_animRoot->GetBoolPOIList(time, g_BoolPOINodes.data(), 16, x20c_passedBoolCount, 0); + x214_passedParticleCount += x1f8_animRoot->GetParticlePOIList(time, g_ParticlePOINodes.data(), 16, x214_passedParticleCount, 0); + x218_passedSoundCount += x1f8_animRoot->GetSoundPOIList(time, g_SoundPOINodes.data(), 16, x218_passedSoundCount, 0); + AdvanceAnim(time, offsetPost, quatPost); + remTime = x1f8_animRoot->VGetTimeRemaining(); + time = std::max(0.f, std::min(float(remTime), float(time))); + if (remTime.EpsilonZero()) + { + x220_24_animating = false; + x1dc_ = zeus::CVector3f::skZero; + x220_28_ = false; + x220_26_ = false; + } + } + } + + x220_31_poseCached = false; + x220_30_poseBuilt = false; + } + + return {offsetPost + offsetPre, quatPost * quatPre}; } -SAdvancementDeltas CAnimData::Advance(float, const zeus::CVector3f&, CStateManager& stateMgr, bool) +SAdvancementDeltas CAnimData::Advance(float dt, const zeus::CVector3f& scale, + CStateManager& stateMgr, TAreaId aid, bool b1) { - return {}; + bool b2; + return DoAdvance(dt, b2, *stateMgr.GetActiveRandom(), b1); + if (b2) + x120_particleDB.SuspendAllActiveEffects(stateMgr); + + for (CParticlePOINode& node : g_ParticlePOINodes) + { + if (node.GetCharIdx() == -1 || node.GetCharIdx() == x204_charIdx) + { + x120_particleDB.StartEffect(node.GetName(), node.GetFlags(), node.GetParticleData(), + scale, stateMgr, aid, x21c_); + } + } } -SAdvancementDeltas CAnimData::AdvanceIgnoreParticles(float, CRandom16&, bool) +SAdvancementDeltas CAnimData::AdvanceIgnoreParticles(float dt, CRandom16& random, bool b1) { - return {}; + bool b2; + return DoAdvance(dt, b2, random, b1); } -void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f&, zeus::CQuaternion&) +void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::CQuaternion& quat) { + SAdvancementResults results; + std::shared_ptr simplified; + + if (x104_) + { + results = x1f8_animRoot->VAdvanceView(time); + simplified = x1f8_animRoot->VSimplified(); + } + + if (simplified) + { + if (simplified->IsCAnimTreeNode()) + { + if (x1f8_animRoot != simplified) + x1f8_animRoot = std::move(simplified); + } + else + x1f8_animRoot.reset(); + } + + if ((x220_28_ || x220_27_) && x210_passedIntCount > 0) + { + for (CInt32POINode& node : g_Int32POINodes) + { + if (node.GetPoiType() == EPOIType::UserEvent) + { + switch (EUserEventType(node.GetValue())) + { + case EUserEventType::AlignTargetPosStart: + { + x220_26_ = true; + break; + } + case EUserEventType::AlignTargetPos: + { + x1dc_ = zeus::CVector3f::skZero; + x220_28_ = false; + x220_26_ = false; + break; + } + case EUserEventType::AlignTargetRot: + { + x1e8_ = zeus::CQuaternion::skNoRotation; + x220_27_ = false; + break; + } + default: break; + } + } + } + } + + offset += results.x8_deltas.x0_posDelta; + if (x220_26_) + offset += x1dc_ * time; + + zeus::CQuaternion rot = results.x8_deltas.xc_rotDelta * x1e8_; + quat = quat * rot; + x1dc_ = rot.transform(x1dc_); + time = results.x0_remTime; } void CAnimData::SetXRayModel(const TLockedToken& model, const TLockedToken& skinRules) @@ -292,10 +452,12 @@ void CAnimData::SetInfraModel(const TLockedToken& model, const TLockedTo { } -void CAnimData::PoseSkinnedModel(const CSkinnedModel& model, const CPoseAsTransforms& pose, +void CAnimData::PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, + const CModelFlags& drawFlags, const rstl::optional_object& morphEffect, - const float* morphMagnitudes) const + const float* morphMagnitudes) { + model.Calculate(pose, drawFlags, morphEffect, morphMagnitudes); } void CAnimData::AdvanceParticles(const zeus::CTransform& xf, float, diff --git a/Runtime/Character/CAnimData.hpp b/Runtime/Character/CAnimData.hpp index 40b2f4806..8a56f0aa8 100644 --- a/Runtime/Character/CAnimData.hpp +++ b/Runtime/Character/CAnimData.hpp @@ -12,6 +12,41 @@ enum class EUserEventType { + Projectile, + EggLay, + LoopedSoundStop, + AlignTargetPos, + AlignTargetRot, + ChangeMaterial, + Delete, + GenerateEnd, + DamageOn, + DamageOff, + AlignTargetPosStart, + DeGenerate, + Landing, + TakeOff, + FadeIn, + FadeOut, + ScreenShake, + BeginAction, + EndAction, + BecomeRagDoll, + IkLock, + IkRelease, + BreakLockOn, + BecomeShootThrough, + RemoveCollision, + ObjectPickUp, + ObjectDrop, + EventStart, + EventStop, + Activate, + Deactivate, + SoundPlay, + SoundStop, + EffectOn, + EffectOff }; namespace urde @@ -41,6 +76,7 @@ class CBoolPOINode; class CInt32POINode; class CParticlePOINode; class CSoundPOINode; +class IAnimReader; struct SAdvancementDeltas; class CAnimData @@ -61,16 +97,17 @@ 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_ = 1.f; + float x200_speedScale = 1.f; u32 x204_charIdx; u16 x208_defaultAnim; u32 x20c_passedBoolCount = 0; u32 x210_passedIntCount = 0; u32 x214_passedParticleCount = 0; u32 x218_passedSoundCount = 0; + u32 x21c_ = 0; union { @@ -83,7 +120,7 @@ class CAnimData bool x220_27_ : 1; bool x220_28_ : 1; bool x220_29_ : 1; - bool x220_30_ : 1; + bool x220_30_poseBuilt : 1; bool x220_31_poseCached : 1; }; }; @@ -122,8 +159,8 @@ public: ResId GetEventResourceIdForAnimResourceId(ResId) const; void AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet); - void AdvanceAdditiveAnims(float); - void UpdateAdditiveAnims(float); + SAdvancementDeltas AdvanceAdditiveAnims(float); + SAdvancementDeltas UpdateAdditiveAnims(float); bool IsAdditiveAnimation(u32) const; std::shared_ptr GetAdditiveAnimationTree(u32) const; bool IsAdditiveAnimationActive(u32) const; @@ -152,27 +189,30 @@ public: std::shared_ptr GetAnimationManager() const; void RecalcPoseBuilder(const CCharAnimTime*); void RenderAuxiliary(const CFrustumPlanes& frustum) const; - void Render(const CSkinnedModel& model, const CModelFlags& drawFlags, + void Render(CSkinnedModel& model, const CModelFlags& drawFlags, const std::experimental::optional& morphEffect, - const float* morphMagnitudes) const; - void SetupRender(const CSkinnedModel& model, + const float* morphMagnitudes); + void SetupRender(CSkinnedModel& model, + const CModelFlags& drawFlags, const std::experimental::optional& morphEffect, - const float* morphMagnitudes) const; + const float* morphMagnitudes); + static void DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags); void PreRender(); void BuildPose(); void PrimitiveSetToTokenVector(const std::set& primSet, std::vector& tokensOut); void GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set& primsOut) const; void SetAnimation(const CAnimPlaybackParms& parms, bool); - void DoAdvance(float, bool&, CRandom16&, bool); - SAdvancementDeltas Advance(float, const zeus::CVector3f&, CStateManager& stateMgr, bool); + SAdvancementDeltas DoAdvance(float, bool&, CRandom16&, bool); + SAdvancementDeltas Advance(float, const zeus::CVector3f&, CStateManager& stateMgr, TAreaId aid, bool); SAdvancementDeltas AdvanceIgnoreParticles(float, CRandom16&, bool); void AdvanceAnim(CCharAnimTime& time, zeus::CVector3f&, zeus::CQuaternion&); void SetXRayModel(const TLockedToken& model, const TLockedToken& skinRules); void SetInfraModel(const TLockedToken& model, const TLockedToken& skinRules); - void PoseSkinnedModel(const CSkinnedModel& model, const CPoseAsTransforms& pose, - const std::experimental::optional& morphEffect, - const float* morphMagnitudes) const; + static void PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, + const CModelFlags& drawFlags, + const std::experimental::optional& morphEffect, + const float* morphMagnitudes); void AdvanceParticles(const zeus::CTransform& xf, float dt, const zeus::CVector3f&, CStateManager& stateMgr); void GetAverageVelocity(int) const; diff --git a/Runtime/Character/CBoolPOINode.cpp b/Runtime/Character/CBoolPOINode.cpp index 53ce406b1..385e3bbce 100644 --- a/Runtime/Character/CBoolPOINode.cpp +++ b/Runtime/Character/CBoolPOINode.cpp @@ -5,7 +5,7 @@ namespace urde { CBoolPOINode::CBoolPOINode() -: CPOINode("root", 1, CCharAnimTime(), -1, false, 1.f, -1, 0) {} +: CPOINode("root", EPOIType::EmptyBool, CCharAnimTime(), -1, false, 1.f, -1, 0) {} CBoolPOINode::CBoolPOINode(CInputStream& in) : CPOINode(in), x38_val(in.readBool()) {} diff --git a/Runtime/Character/CCharAnimTime.cpp b/Runtime/Character/CCharAnimTime.cpp index 093ba706d..0d36aad19 100644 --- a/Runtime/Character/CCharAnimTime.cpp +++ b/Runtime/Character/CCharAnimTime.cpp @@ -1,5 +1,7 @@ #include "CCharAnimTime.hpp" #include +#include +#include namespace urde { @@ -19,6 +21,11 @@ bool CCharAnimTime::EqualsZero() const return (m_time == 0.f); } +bool CCharAnimTime::EpsilonZero() const +{ + return (std::fabs(m_time) < FLT_EPSILON); +} + bool CCharAnimTime::GreaterThanZero() const { if (EqualsZero()) diff --git a/Runtime/Character/CCharAnimTime.hpp b/Runtime/Character/CCharAnimTime.hpp index 98a453f86..b8c54ec6f 100644 --- a/Runtime/Character/CCharAnimTime.hpp +++ b/Runtime/Character/CCharAnimTime.hpp @@ -30,6 +30,7 @@ public: operator float() const {return m_time;} bool EqualsZero() const; + bool EpsilonZero() const; bool GreaterThanZero() const; bool operator ==(const CCharAnimTime& other) const; bool operator !=(const CCharAnimTime& other) const; diff --git a/Runtime/Character/CCharacterFactory.cpp b/Runtime/Character/CCharacterFactory.cpp index f324fc915..77d63c654 100644 --- a/Runtime/Character/CCharacterFactory.cpp +++ b/Runtime/Character/CCharacterFactory.cpp @@ -31,14 +31,14 @@ CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag, charInfo.GetModelId(), charInfo.GetSkinRulesId(), charInfo.GetCharLayoutInfoId(), - CSkinnedModel::EDataOwnership::One)); + 0)); case 1: return TToken::GetIObjObjectFor( std::make_unique(*g_SimplePool, charInfo.GetIceModelId(), charInfo.GetIceSkinRulesId(), charInfo.GetCharLayoutInfoId(), - CSkinnedModel::EDataOwnership::One)); + 0)); default: break; } diff --git a/Runtime/Character/CHierarchyPoseBuilder.hpp b/Runtime/Character/CHierarchyPoseBuilder.hpp index d0d705ad4..6513a948f 100644 --- a/Runtime/Character/CHierarchyPoseBuilder.hpp +++ b/Runtime/Character/CHierarchyPoseBuilder.hpp @@ -43,6 +43,7 @@ class CHierarchyPoseBuilder public: CHierarchyPoseBuilder(const CLayoutDescription& layout); + bool HasRoot() const { return xcf0_hasRoot; } void BuildTransform(const CSegId& boneId, zeus::CTransform& xfOut) const; void BuildNoScale(CPoseAsTransforms& pose); void Insert(const CSegId& boneId, const zeus::CQuaternion& quat); diff --git a/Runtime/Character/CInt32POINode.cpp b/Runtime/Character/CInt32POINode.cpp index 714f0de7b..eed32b368 100644 --- a/Runtime/Character/CInt32POINode.cpp +++ b/Runtime/Character/CInt32POINode.cpp @@ -5,7 +5,7 @@ namespace urde { CInt32POINode::CInt32POINode() -: CPOINode("root", 2, CCharAnimTime(), -1, false, 1.f, -1, 0), x38_val(0), x3c_locatorName("root") {} +: CPOINode("root", EPOIType::EmptyInt32, CCharAnimTime(), -1, false, 1.f, -1, 0), x38_val(0), x3c_locatorName("root") {} CInt32POINode::CInt32POINode(CInputStream& in) : CPOINode(in), x38_val(in.readUint32Big()), x3c_locatorName(in.readString()) {} diff --git a/Runtime/Character/CModelData.cpp b/Runtime/Character/CModelData.cpp index 754d176e0..8881936e3 100644 --- a/Runtime/Character/CModelData.cpp +++ b/Runtime/Character/CModelData.cpp @@ -240,10 +240,10 @@ SAdvancementDeltas CModelData::AdvanceAnimationIgnoreParticles(float dt, CRandom return {}; } -SAdvancementDeltas CModelData::AdvanceAnimation(float dt, CStateManager& stateMgr, bool flag) +SAdvancementDeltas CModelData::AdvanceAnimation(float dt, CStateManager& stateMgr, TAreaId aid, bool flag) { if (x10_animData) - return x10_animData->Advance(dt, x0_particleScale, stateMgr, flag); + return x10_animData->Advance(dt, x0_particleScale, stateMgr, aid, flag); else return {}; } @@ -292,13 +292,13 @@ void CModelData::RenderThermal(const zeus::CTransform& xf, if (x10_animData) { - const CSkinnedModel& model = PickAnimatedModel(EWhichModel::Thermal); - x10_animData->SetupRender(model, {}, nullptr); + CSkinnedModel& model = PickAnimatedModel(EWhichModel::Thermal); + x10_animData->SetupRender(model, drawFlags, {}, nullptr); model.Draw(drawFlags); } else { - const TLockedToken& model = PickStaticModel(EWhichModel::Thermal); + TLockedToken& model = PickStaticModel(EWhichModel::Thermal); model->Draw(drawFlags); } } diff --git a/Runtime/Character/CModelData.hpp b/Runtime/Character/CModelData.hpp index 033429cc8..928ec8ff4 100644 --- a/Runtime/Character/CModelData.hpp +++ b/Runtime/Character/CModelData.hpp @@ -119,7 +119,7 @@ public: zeus::CTransform GetLocatorTransformDynamic(const std::string& name, const CCharAnimTime* time) const; zeus::CTransform GetLocatorTransform(const std::string& name) const; SAdvancementDeltas AdvanceAnimationIgnoreParticles(float dt, CRandom16&, bool); - SAdvancementDeltas AdvanceAnimation(float dt, CStateManager& stateMgr, bool); + SAdvancementDeltas AdvanceAnimation(float dt, CStateManager& stateMgr, TAreaId aid, bool); bool IsAnimating() const; bool IsInFrustum(const zeus::CTransform& xf, const CFrustumPlanes& frustum) const; void RenderParticles(const CFrustumPlanes& frustum) const; diff --git a/Runtime/Character/CPOINode.cpp b/Runtime/Character/CPOINode.cpp index 4c91a138c..696824d6f 100644 --- a/Runtime/Character/CPOINode.cpp +++ b/Runtime/Character/CPOINode.cpp @@ -3,29 +3,29 @@ namespace urde { -CPOINode::CPOINode(const std::string& name, u16 a, const CCharAnimTime& time, +CPOINode::CPOINode(const std::string& name, EPOIType type, const CCharAnimTime& time, u32 index, bool c, float weight, u32 e, u32 f) : x4_(1), x8_name(name), - x18_(a), + x18_type(type), x1c_time(time), x24_index(index), x28_(c), x2c_weight(weight), - x30_(e), - x34_(f) + x30_charIdx(e), + x34_flags(f) {} CPOINode::CPOINode(CInputStream& in) : x4_(in.readUint16Big()), x8_name(in.readString()), - x18_(in.readUint16Big()), + x18_type(EPOIType(in.readUint16Big())), x1c_time(in), x24_index(in.readUint32Big()), x28_(in.readBool()), x2c_weight(in.readFloatBig()), - x30_(in.readUint32Big()), - x34_(in.readUint32Big()) + x30_charIdx(in.readUint32Big()), + x34_flags(in.readUint32Big()) {} } diff --git a/Runtime/Character/CPOINode.hpp b/Runtime/Character/CPOINode.hpp index 5aaec4d2a..64a1d627e 100644 --- a/Runtime/Character/CPOINode.hpp +++ b/Runtime/Character/CPOINode.hpp @@ -7,27 +7,42 @@ namespace urde { +enum class EPOIType : u16 +{ + Loop = 0, + EmptyBool = 1, + EmptyInt32 = 2, + Particle = 5, + UserEvent = 6, + RandRate = 7, + Sound = 8, +}; + class CPOINode { protected: u16 x4_ = 1; std::string x8_name; - u16 x18_; + EPOIType x18_type; CCharAnimTime x1c_time; u32 x24_index; bool x28_; float x2c_weight; - u32 x30_; - u32 x34_; + u32 x30_charIdx = -1; + u32 x34_flags; public: - CPOINode(const std::string& name, u16, const CCharAnimTime& time, u32 index, bool, float weight, u32, u32); + CPOINode(const std::string& name, EPOIType type, const CCharAnimTime& time, + u32 index, bool, float weight, u32 charIdx, u32 flags); CPOINode(CInputStream& in); virtual ~CPOINode() = default; const std::string& GetName() const {return x8_name;} const CCharAnimTime& GetTime() const {return x1c_time;} + EPOIType GetPoiType() const { return x18_type; } u32 GetIndex() const {return x24_index;} float GetWeight() const { return x2c_weight; } + u32 GetCharIdx() const { return x30_charIdx; } + u32 GetFlags() const { return x34_flags; } }; } diff --git a/Runtime/Character/CParticleDatabase.cpp b/Runtime/Character/CParticleDatabase.cpp index e8eb00b94..92d72b664 100644 --- a/Runtime/Character/CParticleDatabase.cpp +++ b/Runtime/Character/CParticleDatabase.cpp @@ -7,4 +7,17 @@ void CParticleDatabase::CacheParticleDesc(const CCharacterInfo::CParticleResData { } +void CParticleDatabase::SetModulationColorAllActiveEffects(const zeus::CColor& color) +{ +} + +void CParticleDatabase::SuspendAllActiveEffects(CStateManager& stateMgr) +{ +} + +void CParticleDatabase::StartEffect(const std::string& name, u32 flags, const CParticleData& data, + const zeus::CVector3f& scale, CStateManager& stateMgr, TAreaId aid, u32 unk1) +{ +} + } diff --git a/Runtime/Character/CParticleDatabase.hpp b/Runtime/Character/CParticleDatabase.hpp index d6498c1f4..6f60482c9 100644 --- a/Runtime/Character/CParticleDatabase.hpp +++ b/Runtime/Character/CParticleDatabase.hpp @@ -14,6 +14,9 @@ class CParticleDatabase public: void CacheParticleDesc(const CCharacterInfo::CParticleResData& desc); void SetModulationColorAllActiveEffects(const zeus::CColor& color); + 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); }; } diff --git a/Runtime/Character/CParticlePOINode.cpp b/Runtime/Character/CParticlePOINode.cpp index 6da2c62bc..b34a53542 100644 --- a/Runtime/Character/CParticlePOINode.cpp +++ b/Runtime/Character/CParticlePOINode.cpp @@ -5,7 +5,7 @@ namespace urde { CParticlePOINode::CParticlePOINode() -: CPOINode("root", 5, CCharAnimTime(), -1, false, 1.f, -1, 0) {} +: CPOINode("root", EPOIType::Particle, CCharAnimTime(), -1, false, 1.f, -1, 0) {} CParticlePOINode::CParticlePOINode(CInputStream& in) : CPOINode(in), x38_data(in) {} diff --git a/Runtime/Character/CSkinBank.cpp b/Runtime/Character/CSkinBank.cpp index 134ac5436..541dc1a55 100644 --- a/Runtime/Character/CSkinBank.cpp +++ b/Runtime/Character/CSkinBank.cpp @@ -1,4 +1,5 @@ #include "CSkinBank.hpp" +#include "CPoseAsTransforms.hpp" namespace urde { @@ -11,4 +12,11 @@ CSkinBank::CSkinBank(CInputStream& in) x0_segments.emplace_back(in); } +void CSkinBank::GetBankTransforms(std::vector& out, + const CPoseAsTransforms& pose) const +{ + for (CSegId id : x0_segments) + out.push_back(&pose.GetTransform(id)); +} + } diff --git a/Runtime/Character/CSkinBank.hpp b/Runtime/Character/CSkinBank.hpp index 5812b2a99..0e8b65d29 100644 --- a/Runtime/Character/CSkinBank.hpp +++ b/Runtime/Character/CSkinBank.hpp @@ -6,12 +6,15 @@ namespace urde { +class CPoseAsTransforms; class CSkinBank { std::vector x0_segments; public: CSkinBank(CInputStream& in); + void GetBankTransforms(std::vector& out, + const CPoseAsTransforms& pose) const; }; } diff --git a/Runtime/Character/CSkinRules.hpp b/Runtime/Character/CSkinRules.hpp index a406aeaa2..5064cbb8a 100644 --- a/Runtime/Character/CSkinRules.hpp +++ b/Runtime/Character/CSkinRules.hpp @@ -7,6 +7,7 @@ namespace urde { +class CPoseAsTransforms; class CSkinRules { @@ -14,6 +15,11 @@ class CSkinRules public: CSkinRules(CInputStream& in); void BuildAccumulatedTransforms(); + void GetBankTransforms(std::vector& out, + const CPoseAsTransforms& pose, int skinBankIdx) const + { + x0_skinBanks[skinBankIdx].GetBankTransforms(out, pose); + } }; CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params); diff --git a/Runtime/Character/CSoundPOINode.cpp b/Runtime/Character/CSoundPOINode.cpp index c3e2b035e..11d9ac4c0 100644 --- a/Runtime/Character/CSoundPOINode.cpp +++ b/Runtime/Character/CSoundPOINode.cpp @@ -5,7 +5,7 @@ namespace urde { CSoundPOINode::CSoundPOINode() -: CPOINode("root", 8, CCharAnimTime(), -1, false, 1.f, -1, 0), +: CPOINode("root", EPOIType::Sound, CCharAnimTime(), -1, false, 1.f, -1, 0), x38_sfxId(0), x3c_falloff(0.f), x40_maxDist(0.f) @@ -18,7 +18,7 @@ CSoundPOINode::CSoundPOINode(CInputStream& in) x40_maxDist(in.readFloatBig()) {} -CSoundPOINode::CSoundPOINode(const std::string& name, u16 a, +CSoundPOINode::CSoundPOINode(const std::string& name, EPOIType a, const CCharAnimTime& time, u32 b, bool c, float d, u32 e, u32 f, u32 sfxId, float falloff, float maxDist) : CPOINode(name, a, time, b, c, d, e, f), diff --git a/Runtime/Character/CSoundPOINode.hpp b/Runtime/Character/CSoundPOINode.hpp index 4ad0e0c69..55197c2b1 100644 --- a/Runtime/Character/CSoundPOINode.hpp +++ b/Runtime/Character/CSoundPOINode.hpp @@ -16,7 +16,7 @@ class CSoundPOINode : public CPOINode public: CSoundPOINode(); CSoundPOINode(CInputStream& in); - CSoundPOINode(const std::string& name, u16 a, + CSoundPOINode(const std::string& name, EPOIType type, const CCharAnimTime& time, u32 b, bool c, float d, u32 e, u32 f, u32 sfxId, float falloff, float maxDist); diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index 3b4208b8a..cdacc8f4b 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -615,7 +615,7 @@ void CBooRenderer::DrawXRayOutline(const zeus::CAABox& aabb) if (bitmap[c] & (1 << b)) { CBooModel* model = item.x10_models[c * 32 + b]; - model->UpdateUniformData(flags); + model->UpdateUniformData(flags, nullptr, nullptr); const CBooSurface* surf = model->x38_firstUnsortedSurface; while (surf) { diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index 0700d807f..7a0edbe0a 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -17,6 +17,8 @@ namespace urde class IObjectStore; class CTexture; class CLight; +class CSkinRules; +class CPoseAsTransforms; struct CModelFlags { @@ -62,6 +64,7 @@ class CBooModel friend class CModel; friend class CBooRenderer; friend class CMetroidModelInstance; + friend class CSkinnedModel; public: using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet; using UVAnimation = DataSpec::DNAMP1::MaterialSet::Material::UVAnimation; @@ -125,10 +128,18 @@ public: void RemapMaterialData(SShader& shader); bool TryLockTextures() const; void UnlockTextures() const; - void UpdateUniformData(const CModelFlags& flags) const; - void DrawAlpha(const CModelFlags& flags) const; - void DrawNormal(const CModelFlags& flags) const; - void Draw(const CModelFlags& flags) const; + void UpdateUniformData(const CModelFlags& flags, + const CSkinRules* cskr, + const CPoseAsTransforms* pose) const; + void DrawAlpha(const CModelFlags& flags, + const CSkinRules* cskr, + const CPoseAsTransforms* pose) const; + void DrawNormal(const CModelFlags& flags, + const CSkinRules* cskr, + const CPoseAsTransforms* pose) const; + void Draw(const CModelFlags& flags, + const CSkinRules* cskr, + const CPoseAsTransforms* pose) const; const MaterialSet::Material& GetMaterialByIndex(int idx) const { diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index 0504b7124..0d05f9587 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -7,6 +7,7 @@ #include "boo/graphicsdev/Metal.hpp" #include "Shaders/CModelShaders.hpp" #include "Graphics/CBooRenderer.hpp" +#include "Character/CSkinRules.hpp" #include "GameGlobalObjects.hpp" #include @@ -456,7 +457,9 @@ void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet } } -void CBooModel::UpdateUniformData(const CModelFlags& flags) const +void CBooModel::UpdateUniformData(const CModelFlags& flags, + const CSkinRules* cskr, + const CPoseAsTransforms* pose) const { u8* dataOut = reinterpret_cast(m_uniformBuffer->map(m_uniformDataSize)); u8* dataCur = dataOut; @@ -464,19 +467,54 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags) const if (m_skinBankCount) { /* Skinned */ + std::vector bankTransforms; + bankTransforms.reserve(m_weightVecCount*4); for (size_t i=0 ; i(*dataCur); - mv = CGraphics::g_GXModelView.toMatrix4f(); - dataCur += sizeof(zeus::CMatrix4f); + cskr->GetBankTransforms(bankTransforms, *pose, i); + + for (size_t w=0 ; w(*dataCur); + if (w >= bankTransforms.size()) + mv = CGraphics::g_GXModelView.toMatrix4f(); + else + mv = (CGraphics::g_GXModelView * *bankTransforms[w]).toMatrix4f(); + dataCur += sizeof(zeus::CMatrix4f); + } + for (size_t w=0 ; w(*dataCur); + if (w >= bankTransforms.size()) + mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); + else + { + zeus::CTransform xf = (CGraphics::g_GXModelView * *bankTransforms[w]).inverse(); + xf.origin.zeroOut(); + xf.basis.transpose(); + mvinv = xf.toMatrix4f(); + } + dataCur += sizeof(zeus::CMatrix4f); + } + + bankTransforms.clear(); } - for (size_t w=0 ; w(*dataCur); - mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); - dataCur += sizeof(zeus::CMatrix4f); + for (size_t w=0 ; w(*dataCur); + mv = CGraphics::g_GXModelView.toMatrix4f(); + dataCur += sizeof(zeus::CMatrix4f); + } + for (size_t w=0 ; w(*dataCur); + mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); + dataCur += sizeof(zeus::CMatrix4f); + } } zeus::CMatrix4f& proj = reinterpret_cast(*dataCur); proj = CGraphics::GetPerspectiveProjectionMatrix(true); @@ -524,29 +562,35 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags) const m_uniformBuffer->unmap(); } -void CBooModel::DrawAlpha(const CModelFlags& flags) const +void CBooModel::DrawAlpha(const CModelFlags& flags, + const CSkinRules* cskr, + const CPoseAsTransforms* pose) const { if (TryLockTextures()) { - UpdateUniformData(flags); + UpdateUniformData(flags, cskr, pose); DrawAlphaSurfaces(flags); } } -void CBooModel::DrawNormal(const CModelFlags& flags) const +void CBooModel::DrawNormal(const CModelFlags& flags, + const CSkinRules* cskr, + const CPoseAsTransforms* pose) const { if (TryLockTextures()) { - UpdateUniformData(flags); + UpdateUniformData(flags, cskr, pose); DrawNormalSurfaces(flags); } } -void CBooModel::Draw(const CModelFlags& flags) const +void CBooModel::Draw(const CModelFlags& flags, + const CSkinRules* cskr, + const CPoseAsTransforms* pose) const { if (TryLockTextures()) { - UpdateUniformData(flags); + UpdateUniformData(flags, cskr, pose); DrawSurfaces(flags); } } @@ -667,19 +711,19 @@ void CModel::VerifyCurrentShader(int shaderIdx) const void CModel::DrawSortedParts(const CModelFlags& flags) const { VerifyCurrentShader(flags.m_matSetIdx); - x28_modelInst->DrawAlpha(flags); + x28_modelInst->DrawAlpha(flags, nullptr, nullptr); } void CModel::DrawUnsortedParts(const CModelFlags& flags) const { VerifyCurrentShader(flags.m_matSetIdx); - x28_modelInst->DrawNormal(flags); + x28_modelInst->DrawNormal(flags, nullptr, nullptr); } void CModel::Draw(const CModelFlags& flags) const { VerifyCurrentShader(flags.m_matSetIdx); - x28_modelInst->Draw(flags); + x28_modelInst->Draw(flags, nullptr, nullptr); } void CModel::Touch(int shaderIdx) const diff --git a/Runtime/Graphics/CSkinnedModel.cpp b/Runtime/Graphics/CSkinnedModel.cpp index d2a46e81b..2594dc759 100644 --- a/Runtime/Graphics/CSkinnedModel.cpp +++ b/Runtime/Graphics/CSkinnedModel.cpp @@ -3,29 +3,43 @@ namespace urde { -CSkinnedModel::CSkinnedModel(const TLockedToken& model, - const TLockedToken& skinRules, - const TLockedToken& layoutInfo) +CSkinnedModel::CSkinnedModel(TLockedToken model, + TLockedToken skinRules, + TLockedToken layoutInfo, + int shaderIdx) : x4_model(model), x10_skinRules(skinRules), x1c_layoutInfo(layoutInfo) { - + m_modelInst = model->MakeNewInstance(shaderIdx); } CSkinnedModel::CSkinnedModel(IObjectStore& store, ResId model, ResId skinRules, ResId layoutInfo, - EDataOwnership ownership) + int shaderIdx) +: CSkinnedModel(store.GetObj(SObjectTag{FOURCC('CMDL'), model}), + store.GetObj(SObjectTag{FOURCC('CSKR'), skinRules}), + store.GetObj(SObjectTag{FOURCC('CINF'), layoutInfo}), + shaderIdx) { } void CSkinnedModel::Calculate(const CPoseAsTransforms& pose, - const rstl::optional_object&) + const CModelFlags& drawFlags, + const rstl::optional_object& morphEffect, + const float* morphMagnitudes) { + m_modelInst->UpdateUniformData(drawFlags, x10_skinRules.GetObj(), &pose); +} + +void CSkinnedModel::Draw(const CModelFlags& drawFlags) const +{ + if (m_modelInst->TryLockTextures()) + m_modelInst->DrawSurfaces(drawFlags); } CMorphableSkinnedModel::CMorphableSkinnedModel(IObjectStore& store, ResId model, ResId skinRules, ResId layoutInfo, - EDataOwnership ownership) -: CSkinnedModel(store, model, skinRules, layoutInfo, ownership) + int shaderIdx) +: CSkinnedModel(store, model, skinRules, layoutInfo, shaderIdx) { } diff --git a/Runtime/Graphics/CSkinnedModel.hpp b/Runtime/Graphics/CSkinnedModel.hpp index c157a5dd7..7183d5308 100644 --- a/Runtime/Graphics/CSkinnedModel.hpp +++ b/Runtime/Graphics/CSkinnedModel.hpp @@ -16,6 +16,7 @@ class IObjectStore; class CSkinnedModel { + friend class CBooModel; std::unique_ptr m_modelInst; TLockedToken x4_model; TLockedToken x10_skinRules; @@ -26,25 +27,29 @@ public: Zero, One }; - CSkinnedModel(const TLockedToken& model, - const TLockedToken& skinRules, - const TLockedToken& layoutInfo); + CSkinnedModel(TLockedToken model, + TLockedToken skinRules, + TLockedToken layoutInfo, + int shaderIdx); CSkinnedModel(IObjectStore& store, ResId model, ResId skinRules, - ResId layoutInfo, EDataOwnership ownership); + ResId layoutInfo, int shaderIdx); TLockedToken& GetModel() {return x4_model;} TLockedToken& GetSkinRules() {return x10_skinRules;} TLockedToken& GetLayoutInfo() {return x1c_layoutInfo;} - void Calculate(const CPoseAsTransforms& pose, const std::experimental::optional&); - void Draw(const CModelFlags& drawFlags) const {} + void Calculate(const CPoseAsTransforms& pose, + const CModelFlags& drawFlags, + const std::experimental::optional& morphEffect, + const float* morphMagnitudes); + void Draw(const CModelFlags& drawFlags) const; }; class CMorphableSkinnedModel : public CSkinnedModel { public: CMorphableSkinnedModel(IObjectStore& store, ResId model, ResId skinRules, - ResId layoutInfo, EDataOwnership ownership); + ResId layoutInfo, int shaderIdx); }; } diff --git a/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp b/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp index 5cb0cda8e..f530ac2d1 100644 --- a/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp +++ b/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp @@ -28,7 +28,7 @@ CCameraBlurFilter::CCameraBlurFilter() void CCameraBlurFilter::draw(float amount) { - if (amount == 0.f) + if (amount <= 0.f) return; SClipScreenRect clipRect = {}; diff --git a/Runtime/World/CWorldTransManager.cpp b/Runtime/World/CWorldTransManager.cpp index 3964563aa..970867efd 100644 --- a/Runtime/World/CWorldTransManager.cpp +++ b/Runtime/World/CWorldTransManager.cpp @@ -197,6 +197,7 @@ void CWorldTransManager::DrawFirstPass() 360.f + 180.f - 90.f)); CGraphics::SetViewPointMatrix(rotateXf * translateXf); DrawAllModels(); + m_camblur.draw(x4_modelData->x1c8_blurResult); } void CWorldTransManager::DrawSecondPass() diff --git a/Runtime/World/CWorldTransManager.hpp b/Runtime/World/CWorldTransManager.hpp index cbb7b6df1..5df6ee304 100644 --- a/Runtime/World/CWorldTransManager.hpp +++ b/Runtime/World/CWorldTransManager.hpp @@ -8,6 +8,7 @@ #include "Graphics/CLight.hpp" #include "Graphics/Shaders/CColoredQuadFilter.hpp" #include "Graphics/Shaders/CTexturedQuadFilter.hpp" +#include "Graphics/Shaders/CCameraBlurFilter.hpp" namespace urde { @@ -83,6 +84,7 @@ private: CTexturedQuadFilter m_dissolve = { CCameraFilterPass::EFilterType::Blend, CGraphics::g_SpareTexture }; CWideScreenFilter m_widescreen = { CCameraFilterPass::EFilterType::Blend }; + CCameraBlurFilter m_camblur; static int GetSuitCharIdx(); void DrawFirstPass(); diff --git a/hecl b/hecl index 53ae402b2..667c476f2 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 53ae402b2b130e6d0e1742d0a9d864223149c8ac +Subproject commit 667c476f2e78ac6aedef9faba4783ade01dfbd47 diff --git a/specter b/specter index d8186d24b..4260ea58f 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit d8186d24b70a8ca885b4bd3e19e1f5402c076191 +Subproject commit 4260ea58f19648d6548b0c25488bfb8b47d0263b