Work on character animation

This commit is contained in:
Jack Andersen 2016-08-21 10:39:18 -10:00
parent d125b4769e
commit 670eb998d4
35 changed files with 460 additions and 102 deletions

View File

@ -1083,10 +1083,25 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
Log.report(logvisor::Fatal, _S("'%s' not found as file"), Log.report(logvisor::Fatal, _S("'%s' not found as file"),
yamlPath.getRelativePath().c_str()); yamlPath.getRelativePath().c_str());
athena::io::FileReader yamlReader(yamlPath.getAbsolutePath()); FILE* yamlFp = hecl::Fopen(yamlPath.getAbsolutePath().c_str(), _S("r"));
if (!BigYAML::ValidateFromYAMLFile<ANCS>(yamlReader)) if (!yamlFp)
Log.report(logvisor::Fatal, _S("can't open '%s' for reading"),
yamlPath.getRelativePath().c_str());
if (!BigYAML::ValidateFromYAMLFile<ANCS>(yamlFp))
{
Log.report(logvisor::Fatal, _S("'%s' is not urde::DNAMP1::ANCS type"), Log.report(logvisor::Fatal, _S("'%s' is not urde::DNAMP1::ANCS type"),
yamlPath.getRelativePath().c_str()); 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 ancs;
ancs.read(yamlReader); ancs.read(yamlReader);

View File

@ -26,7 +26,7 @@ namespace urde
void ViewManager::BuildTestPART(urde::IObjectStore& objStore) void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
{ {
#if 0 #if 1
SObjectTag samusCharSet = m_projManager.TagFromPath(_S("MP1/Shared/ANCS_77289A4A.blend")); SObjectTag samusCharSet = m_projManager.TagFromPath(_S("MP1/Shared/ANCS_77289A4A.blend"));
SObjectTag platModel = m_projManager.TagFromPath(_S("MP1/Shared/CMDL_6FA561D0.blend")); SObjectTag platModel = m_projManager.TagFromPath(_S("MP1/Shared/CMDL_6FA561D0.blend"));
SObjectTag bgModel = m_projManager.TagFromPath(_S("MP1/Shared/CMDL_BC34D54C.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 (m_vm.m_modelTest.IsLoaded())
{ {
#if 0
CModelFlags flags; CModelFlags flags;
flags.m_extendedShaderIdx = 0; flags.m_extendedShaderIdx = 0;
@ -131,6 +132,8 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
//g_Renderer->DoThermalBlendHot(); //g_Renderer->DoThermalBlendHot();
//m_spaceWarpFilter.setStrength(std::sin(m_theta * 5.f) * 0.5f + 0.5f); //m_spaceWarpFilter.setStrength(std::sin(m_theta * 5.f) * 0.5f + 0.5f);
//m_spaceWarpFilter.draw(zeus::CVector2f{0.f, 0.f}); //m_spaceWarpFilter.draw(zeus::CVector2f{0.f, 0.f});
#endif
} }
if (m_vm.m_partGen) 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->Update(1.f / 60.f);
m_vm.m_moviePlayer->DrawFrame(); m_vm.m_moviePlayer->DrawFrame();
} }
g_GameState->GetWorldTransitionManager()->Draw();
} }
specter::View* ViewManager::BuildSpaceViews() specter::View* ViewManager::BuildSpaceViews()

View File

@ -275,7 +275,7 @@ public:
TUniqueId AllocateUniqueId(); TUniqueId AllocateUniqueId();
const std::shared_ptr<CPlayerState>& GetPlayerState() const {return x8b8_playerState;} const std::shared_ptr<CPlayerState>& GetPlayerState() const {return x8b8_playerState;}
CRandom16& GetActiveRandom() {return x8fc_random;} CRandom16* GetActiveRandom() {return x900_activeRandom;}
CRumbleManager& GetRumbleManager() {return *x88c_rumbleManager;} CRumbleManager& GetRumbleManager() {return *x88c_rumbleManager;}
CCameraFilterPass& GetCameraFilterPass(int idx) {return xb84_camFilterPasses[idx];} CCameraFilterPass& GetCameraFilterPass(int idx) {return xb84_camFilterPasses[idx];}

View File

@ -301,6 +301,9 @@ public:
T* operator->() {return GetObj();} T* operator->() {return GetObj();}
const T* operator->() const {return GetObj();} const T* operator->() const {return GetObj();}
void Unlock() {TToken<T>::Unlock(); m_obj = nullptr;} void Unlock() {TToken<T>::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 <class T> template <class T>
@ -309,9 +312,9 @@ class TLockedToken : public TCachedToken<T>
public: public:
TLockedToken() = default; TLockedToken() = default;
TLockedToken(const TLockedToken& other) : TCachedToken<T>(other) { CToken::Lock(); } TLockedToken(const TLockedToken& other) : TCachedToken<T>(other) { CToken::Lock(); }
TLockedToken& operator=(const TLockedToken& other) { CToken::operator=(other); CToken::Lock(); return *this; } TLockedToken& operator=(const TLockedToken& other) { TCachedToken<T>::operator=(other); CToken::Lock(); return *this; }
TLockedToken(const CToken& other) : TCachedToken<T>(other) { CToken::Lock(); } TLockedToken(const CToken& other) : TCachedToken<T>(other) { CToken::Lock(); }
TLockedToken& operator=(const CToken& other) { CToken::operator=(other); CToken::Lock(); return *this; } TLockedToken& operator=(const CToken& other) { TCachedToken<T>::operator=(other); CToken::Lock(); return *this; }
TLockedToken(CToken&& other) : TCachedToken<T>(std::move(other)) { CToken::Lock(); } TLockedToken(CToken&& other) : TCachedToken<T>(std::move(other)) { CToken::Lock(); }
}; };

View File

@ -78,7 +78,7 @@ void CCameraManager::Update(float dt, CStateManager& stateMgr)
it = x18_shakers.erase(it); it = x18_shakers.erase(it);
continue; continue;
} }
x30_shakeOffset += it->GeneratePoint(dt, stateMgr.GetActiveRandom()); x30_shakeOffset += it->GeneratePoint(dt, *stateMgr.GetActiveRandom());
++it; ++it;
} }

View File

@ -15,6 +15,7 @@
#include "CAnimTreeNode.hpp" #include "CAnimTreeNode.hpp"
#include "CAnimPerSegmentData.hpp" #include "CAnimPerSegmentData.hpp"
#include "CSegStatementSet.hpp" #include "CSegStatementSet.hpp"
#include "CStateManager.hpp"
namespace urde namespace urde
{ {
@ -83,7 +84,7 @@ static void AdvanceAnimationTree(std::weak_ptr<CAnimTreeNode>& anim, const CChar
{ {
} }
void CAnimData::AdvanceAdditiveAnims(float dt) SAdvancementDeltas CAnimData::AdvanceAdditiveAnims(float dt)
{ {
CCharAnimTime time(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 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<CVertexMorphEffect>& morphEffect, const rstl::optional_object<CVertexMorphEffect>& 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<CVertexMorphEffect>& morphEffect, const rstl::optional_object<CVertexMorphEffect>& 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() void CAnimData::PreRender()
@ -246,7 +264,7 @@ void CAnimData::PreRender()
{ {
RecalcPoseBuilder(nullptr); RecalcPoseBuilder(nullptr);
x220_31_poseCached = true; 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;
SAdvancementDeltas CAnimData::Advance(float, const zeus::CVector3f&, CStateManager& stateMgr, bool) 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 {}; 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::AdvanceIgnoreParticles(float, CRandom16&, 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_);
}
}
} }
void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f&, zeus::CQuaternion&) SAdvancementDeltas CAnimData::AdvanceIgnoreParticles(float dt, CRandom16& random, bool b1)
{ {
bool b2;
return DoAdvance(dt, b2, random, b1);
}
void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::CQuaternion& quat)
{
SAdvancementResults results;
std::shared_ptr<IAnimReader> 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<CModel>& model, const TLockedToken<CSkinRules>& skinRules) void CAnimData::SetXRayModel(const TLockedToken<CModel>& model, const TLockedToken<CSkinRules>& skinRules)
@ -292,10 +452,12 @@ void CAnimData::SetInfraModel(const TLockedToken<CModel>& 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<CVertexMorphEffect>& morphEffect, const rstl::optional_object<CVertexMorphEffect>& morphEffect,
const float* morphMagnitudes) const const float* morphMagnitudes)
{ {
model.Calculate(pose, drawFlags, morphEffect, morphMagnitudes);
} }
void CAnimData::AdvanceParticles(const zeus::CTransform& xf, float, void CAnimData::AdvanceParticles(const zeus::CTransform& xf, float,

View File

@ -12,6 +12,41 @@
enum class EUserEventType 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 namespace urde
@ -41,6 +76,7 @@ class CBoolPOINode;
class CInt32POINode; class CInt32POINode;
class CParticlePOINode; class CParticlePOINode;
class CSoundPOINode; class CSoundPOINode;
class IAnimReader;
struct SAdvancementDeltas; struct SAdvancementDeltas;
class CAnimData class CAnimData
@ -61,16 +97,17 @@ class CAnimData
ResId x1d8_selfId; ResId x1d8_selfId;
zeus::CVector3f x1dc_; zeus::CVector3f x1dc_;
zeus::CQuaternion x1e8_; zeus::CQuaternion x1e8_;
std::shared_ptr<CAnimTreeNode> x1f8_animRoot; std::shared_ptr<IAnimReader> x1f8_animRoot;
std::shared_ptr<CTransitionManager> x1fc_transMgr; std::shared_ptr<CTransitionManager> x1fc_transMgr;
float x200_ = 1.f; float x200_speedScale = 1.f;
u32 x204_charIdx; u32 x204_charIdx;
u16 x208_defaultAnim; u16 x208_defaultAnim;
u32 x20c_passedBoolCount = 0; u32 x20c_passedBoolCount = 0;
u32 x210_passedIntCount = 0; u32 x210_passedIntCount = 0;
u32 x214_passedParticleCount = 0; u32 x214_passedParticleCount = 0;
u32 x218_passedSoundCount = 0; u32 x218_passedSoundCount = 0;
u32 x21c_ = 0;
union union
{ {
@ -83,7 +120,7 @@ class CAnimData
bool x220_27_ : 1; bool x220_27_ : 1;
bool x220_28_ : 1; bool x220_28_ : 1;
bool x220_29_ : 1; bool x220_29_ : 1;
bool x220_30_ : 1; bool x220_30_poseBuilt : 1;
bool x220_31_poseCached : 1; bool x220_31_poseCached : 1;
}; };
}; };
@ -122,8 +159,8 @@ public:
ResId GetEventResourceIdForAnimResourceId(ResId) const; ResId GetEventResourceIdForAnimResourceId(ResId) const;
void AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet); void AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet);
void AdvanceAdditiveAnims(float); SAdvancementDeltas AdvanceAdditiveAnims(float);
void UpdateAdditiveAnims(float); SAdvancementDeltas UpdateAdditiveAnims(float);
bool IsAdditiveAnimation(u32) const; bool IsAdditiveAnimation(u32) const;
std::shared_ptr<CAnimTreeNode> GetAdditiveAnimationTree(u32) const; std::shared_ptr<CAnimTreeNode> GetAdditiveAnimationTree(u32) const;
bool IsAdditiveAnimationActive(u32) const; bool IsAdditiveAnimationActive(u32) const;
@ -152,27 +189,30 @@ public:
std::shared_ptr<CAnimationManager> GetAnimationManager() const; std::shared_ptr<CAnimationManager> GetAnimationManager() const;
void RecalcPoseBuilder(const CCharAnimTime*); void RecalcPoseBuilder(const CCharAnimTime*);
void RenderAuxiliary(const CFrustumPlanes& frustum) const; 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<CVertexMorphEffect>& morphEffect, const std::experimental::optional<CVertexMorphEffect>& morphEffect,
const float* morphMagnitudes) const; const float* morphMagnitudes);
void SetupRender(const CSkinnedModel& model, void SetupRender(CSkinnedModel& model,
const CModelFlags& drawFlags,
const std::experimental::optional<CVertexMorphEffect>& morphEffect, const std::experimental::optional<CVertexMorphEffect>& morphEffect,
const float* morphMagnitudes) const; const float* morphMagnitudes);
static void DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags);
void PreRender(); void PreRender();
void BuildPose(); void BuildPose();
void PrimitiveSetToTokenVector(const std::set<CPrimitive>& primSet, std::vector<CToken>& tokensOut); void PrimitiveSetToTokenVector(const std::set<CPrimitive>& primSet, std::vector<CToken>& tokensOut);
void GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set<CPrimitive>& primsOut) const; void GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set<CPrimitive>& primsOut) const;
void SetAnimation(const CAnimPlaybackParms& parms, bool); void SetAnimation(const CAnimPlaybackParms& parms, bool);
void DoAdvance(float, bool&, CRandom16&, bool); SAdvancementDeltas DoAdvance(float, bool&, CRandom16&, bool);
SAdvancementDeltas Advance(float, const zeus::CVector3f&, CStateManager& stateMgr, bool); SAdvancementDeltas Advance(float, const zeus::CVector3f&, CStateManager& stateMgr, TAreaId aid, bool);
SAdvancementDeltas AdvanceIgnoreParticles(float, CRandom16&, bool); SAdvancementDeltas AdvanceIgnoreParticles(float, CRandom16&, bool);
void AdvanceAnim(CCharAnimTime& time, zeus::CVector3f&, zeus::CQuaternion&); void AdvanceAnim(CCharAnimTime& time, zeus::CVector3f&, zeus::CQuaternion&);
void SetXRayModel(const TLockedToken<CModel>& model, const TLockedToken<CSkinRules>& skinRules); void SetXRayModel(const TLockedToken<CModel>& model, const TLockedToken<CSkinRules>& skinRules);
void SetInfraModel(const TLockedToken<CModel>& model, const TLockedToken<CSkinRules>& skinRules); void SetInfraModel(const TLockedToken<CModel>& model, const TLockedToken<CSkinRules>& skinRules);
void PoseSkinnedModel(const CSkinnedModel& model, const CPoseAsTransforms& pose, static void PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose,
const CModelFlags& drawFlags,
const std::experimental::optional<CVertexMorphEffect>& morphEffect, const std::experimental::optional<CVertexMorphEffect>& morphEffect,
const float* morphMagnitudes) const; const float* morphMagnitudes);
void AdvanceParticles(const zeus::CTransform& xf, float dt, void AdvanceParticles(const zeus::CTransform& xf, float dt,
const zeus::CVector3f&, CStateManager& stateMgr); const zeus::CVector3f&, CStateManager& stateMgr);
void GetAverageVelocity(int) const; void GetAverageVelocity(int) const;

View File

@ -5,7 +5,7 @@ namespace urde
{ {
CBoolPOINode::CBoolPOINode() 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) CBoolPOINode::CBoolPOINode(CInputStream& in)
: CPOINode(in), x38_val(in.readBool()) {} : CPOINode(in), x38_val(in.readBool()) {}

View File

@ -1,5 +1,7 @@
#include "CCharAnimTime.hpp" #include "CCharAnimTime.hpp"
#include <algorithm> #include <algorithm>
#include <cmath>
#include <float.h>
namespace urde namespace urde
{ {
@ -19,6 +21,11 @@ bool CCharAnimTime::EqualsZero() const
return (m_time == 0.f); return (m_time == 0.f);
} }
bool CCharAnimTime::EpsilonZero() const
{
return (std::fabs(m_time) < FLT_EPSILON);
}
bool CCharAnimTime::GreaterThanZero() const bool CCharAnimTime::GreaterThanZero() const
{ {
if (EqualsZero()) if (EqualsZero())

View File

@ -30,6 +30,7 @@ public:
operator float() const {return m_time;} operator float() const {return m_time;}
bool EqualsZero() const; bool EqualsZero() const;
bool EpsilonZero() const;
bool GreaterThanZero() const; bool GreaterThanZero() const;
bool operator ==(const CCharAnimTime& other) const; bool operator ==(const CCharAnimTime& other) const;
bool operator !=(const CCharAnimTime& other) const; bool operator !=(const CCharAnimTime& other) const;

View File

@ -31,14 +31,14 @@ CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag,
charInfo.GetModelId(), charInfo.GetModelId(),
charInfo.GetSkinRulesId(), charInfo.GetSkinRulesId(),
charInfo.GetCharLayoutInfoId(), charInfo.GetCharLayoutInfoId(),
CSkinnedModel::EDataOwnership::One)); 0));
case 1: case 1:
return TToken<CSkinnedModel>::GetIObjObjectFor( return TToken<CSkinnedModel>::GetIObjObjectFor(
std::make_unique<CMorphableSkinnedModel>(*g_SimplePool, std::make_unique<CMorphableSkinnedModel>(*g_SimplePool,
charInfo.GetIceModelId(), charInfo.GetIceModelId(),
charInfo.GetIceSkinRulesId(), charInfo.GetIceSkinRulesId(),
charInfo.GetCharLayoutInfoId(), charInfo.GetCharLayoutInfoId(),
CSkinnedModel::EDataOwnership::One)); 0));
default: default:
break; break;
} }

View File

@ -43,6 +43,7 @@ class CHierarchyPoseBuilder
public: public:
CHierarchyPoseBuilder(const CLayoutDescription& layout); CHierarchyPoseBuilder(const CLayoutDescription& layout);
bool HasRoot() const { return xcf0_hasRoot; }
void BuildTransform(const CSegId& boneId, zeus::CTransform& xfOut) const; void BuildTransform(const CSegId& boneId, zeus::CTransform& xfOut) const;
void BuildNoScale(CPoseAsTransforms& pose); void BuildNoScale(CPoseAsTransforms& pose);
void Insert(const CSegId& boneId, const zeus::CQuaternion& quat); void Insert(const CSegId& boneId, const zeus::CQuaternion& quat);

View File

@ -5,7 +5,7 @@ namespace urde
{ {
CInt32POINode::CInt32POINode() 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) CInt32POINode::CInt32POINode(CInputStream& in)
: CPOINode(in), x38_val(in.readUint32Big()), x3c_locatorName(in.readString()) {} : CPOINode(in), x38_val(in.readUint32Big()), x3c_locatorName(in.readString()) {}

View File

@ -240,10 +240,10 @@ SAdvancementDeltas CModelData::AdvanceAnimationIgnoreParticles(float dt, CRandom
return {}; return {};
} }
SAdvancementDeltas CModelData::AdvanceAnimation(float dt, CStateManager& stateMgr, bool flag) SAdvancementDeltas CModelData::AdvanceAnimation(float dt, CStateManager& stateMgr, TAreaId aid, bool flag)
{ {
if (x10_animData) if (x10_animData)
return x10_animData->Advance(dt, x0_particleScale, stateMgr, flag); return x10_animData->Advance(dt, x0_particleScale, stateMgr, aid, flag);
else else
return {}; return {};
} }
@ -292,13 +292,13 @@ void CModelData::RenderThermal(const zeus::CTransform& xf,
if (x10_animData) if (x10_animData)
{ {
const CSkinnedModel& model = PickAnimatedModel(EWhichModel::Thermal); CSkinnedModel& model = PickAnimatedModel(EWhichModel::Thermal);
x10_animData->SetupRender(model, {}, nullptr); x10_animData->SetupRender(model, drawFlags, {}, nullptr);
model.Draw(drawFlags); model.Draw(drawFlags);
} }
else else
{ {
const TLockedToken<CModel>& model = PickStaticModel(EWhichModel::Thermal); TLockedToken<CModel>& model = PickStaticModel(EWhichModel::Thermal);
model->Draw(drawFlags); model->Draw(drawFlags);
} }
} }

View File

@ -119,7 +119,7 @@ public:
zeus::CTransform GetLocatorTransformDynamic(const std::string& name, const CCharAnimTime* time) const; zeus::CTransform GetLocatorTransformDynamic(const std::string& name, const CCharAnimTime* time) const;
zeus::CTransform GetLocatorTransform(const std::string& name) const; zeus::CTransform GetLocatorTransform(const std::string& name) const;
SAdvancementDeltas AdvanceAnimationIgnoreParticles(float dt, CRandom16&, bool); 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 IsAnimating() const;
bool IsInFrustum(const zeus::CTransform& xf, const CFrustumPlanes& frustum) const; bool IsInFrustum(const zeus::CTransform& xf, const CFrustumPlanes& frustum) const;
void RenderParticles(const CFrustumPlanes& frustum) const; void RenderParticles(const CFrustumPlanes& frustum) const;

View File

@ -3,29 +3,29 @@
namespace urde 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) u32 index, bool c, float weight, u32 e, u32 f)
: x4_(1), : x4_(1),
x8_name(name), x8_name(name),
x18_(a), x18_type(type),
x1c_time(time), x1c_time(time),
x24_index(index), x24_index(index),
x28_(c), x28_(c),
x2c_weight(weight), x2c_weight(weight),
x30_(e), x30_charIdx(e),
x34_(f) x34_flags(f)
{} {}
CPOINode::CPOINode(CInputStream& in) CPOINode::CPOINode(CInputStream& in)
: x4_(in.readUint16Big()), : x4_(in.readUint16Big()),
x8_name(in.readString()), x8_name(in.readString()),
x18_(in.readUint16Big()), x18_type(EPOIType(in.readUint16Big())),
x1c_time(in), x1c_time(in),
x24_index(in.readUint32Big()), x24_index(in.readUint32Big()),
x28_(in.readBool()), x28_(in.readBool()),
x2c_weight(in.readFloatBig()), x2c_weight(in.readFloatBig()),
x30_(in.readUint32Big()), x30_charIdx(in.readUint32Big()),
x34_(in.readUint32Big()) x34_flags(in.readUint32Big())
{} {}
} }

View File

@ -7,27 +7,42 @@
namespace urde namespace urde
{ {
enum class EPOIType : u16
{
Loop = 0,
EmptyBool = 1,
EmptyInt32 = 2,
Particle = 5,
UserEvent = 6,
RandRate = 7,
Sound = 8,
};
class CPOINode class CPOINode
{ {
protected: protected:
u16 x4_ = 1; u16 x4_ = 1;
std::string x8_name; std::string x8_name;
u16 x18_; EPOIType x18_type;
CCharAnimTime x1c_time; CCharAnimTime x1c_time;
u32 x24_index; u32 x24_index;
bool x28_; bool x28_;
float x2c_weight; float x2c_weight;
u32 x30_; u32 x30_charIdx = -1;
u32 x34_; u32 x34_flags;
public: 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); CPOINode(CInputStream& in);
virtual ~CPOINode() = default; virtual ~CPOINode() = default;
const std::string& GetName() const {return x8_name;} const std::string& GetName() const {return x8_name;}
const CCharAnimTime& GetTime() const {return x1c_time;} const CCharAnimTime& GetTime() const {return x1c_time;}
EPOIType GetPoiType() const { return x18_type; }
u32 GetIndex() const {return x24_index;} u32 GetIndex() const {return x24_index;}
float GetWeight() const { return x2c_weight; } float GetWeight() const { return x2c_weight; }
u32 GetCharIdx() const { return x30_charIdx; }
u32 GetFlags() const { return x34_flags; }
}; };
} }

View File

@ -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)
{
}
} }

View File

@ -14,6 +14,9 @@ class CParticleDatabase
public: public:
void CacheParticleDesc(const CCharacterInfo::CParticleResData& desc); void CacheParticleDesc(const CCharacterInfo::CParticleResData& desc);
void SetModulationColorAllActiveEffects(const zeus::CColor& color); 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);
}; };
} }

View File

@ -5,7 +5,7 @@ namespace urde
{ {
CParticlePOINode::CParticlePOINode() 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) CParticlePOINode::CParticlePOINode(CInputStream& in)
: CPOINode(in), x38_data(in) {} : CPOINode(in), x38_data(in) {}

View File

@ -1,4 +1,5 @@
#include "CSkinBank.hpp" #include "CSkinBank.hpp"
#include "CPoseAsTransforms.hpp"
namespace urde namespace urde
{ {
@ -11,4 +12,11 @@ CSkinBank::CSkinBank(CInputStream& in)
x0_segments.emplace_back(in); x0_segments.emplace_back(in);
} }
void CSkinBank::GetBankTransforms(std::vector<const zeus::CTransform*>& out,
const CPoseAsTransforms& pose) const
{
for (CSegId id : x0_segments)
out.push_back(&pose.GetTransform(id));
}
} }

View File

@ -6,12 +6,15 @@
namespace urde namespace urde
{ {
class CPoseAsTransforms;
class CSkinBank class CSkinBank
{ {
std::vector<CSegId> x0_segments; std::vector<CSegId> x0_segments;
public: public:
CSkinBank(CInputStream& in); CSkinBank(CInputStream& in);
void GetBankTransforms(std::vector<const zeus::CTransform*>& out,
const CPoseAsTransforms& pose) const;
}; };
} }

View File

@ -7,6 +7,7 @@
namespace urde namespace urde
{ {
class CPoseAsTransforms;
class CSkinRules class CSkinRules
{ {
@ -14,6 +15,11 @@ class CSkinRules
public: public:
CSkinRules(CInputStream& in); CSkinRules(CInputStream& in);
void BuildAccumulatedTransforms(); void BuildAccumulatedTransforms();
void GetBankTransforms(std::vector<const zeus::CTransform*>& out,
const CPoseAsTransforms& pose, int skinBankIdx) const
{
x0_skinBanks[skinBankIdx].GetBankTransforms(out, pose);
}
}; };
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params); CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params);

View File

@ -5,7 +5,7 @@ namespace urde
{ {
CSoundPOINode::CSoundPOINode() 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), x38_sfxId(0),
x3c_falloff(0.f), x3c_falloff(0.f),
x40_maxDist(0.f) x40_maxDist(0.f)
@ -18,7 +18,7 @@ CSoundPOINode::CSoundPOINode(CInputStream& in)
x40_maxDist(in.readFloatBig()) 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, const CCharAnimTime& time, u32 b, bool c,
float d, u32 e, u32 f, u32 sfxId, float falloff, float maxDist) float d, u32 e, u32 f, u32 sfxId, float falloff, float maxDist)
: CPOINode(name, a, time, b, c, d, e, f), : CPOINode(name, a, time, b, c, d, e, f),

View File

@ -16,7 +16,7 @@ class CSoundPOINode : public CPOINode
public: public:
CSoundPOINode(); CSoundPOINode();
CSoundPOINode(CInputStream& in); CSoundPOINode(CInputStream& in);
CSoundPOINode(const std::string& name, u16 a, CSoundPOINode(const std::string& name, EPOIType type,
const CCharAnimTime& time, u32 b, bool c, const CCharAnimTime& time, u32 b, bool c,
float d, u32 e, u32 f, u32 sfxId, float falloff, float maxDist); float d, u32 e, u32 f, u32 sfxId, float falloff, float maxDist);

View File

@ -615,7 +615,7 @@ void CBooRenderer::DrawXRayOutline(const zeus::CAABox& aabb)
if (bitmap[c] & (1 << b)) if (bitmap[c] & (1 << b))
{ {
CBooModel* model = item.x10_models[c * 32 + b]; CBooModel* model = item.x10_models[c * 32 + b];
model->UpdateUniformData(flags); model->UpdateUniformData(flags, nullptr, nullptr);
const CBooSurface* surf = model->x38_firstUnsortedSurface; const CBooSurface* surf = model->x38_firstUnsortedSurface;
while (surf) while (surf)
{ {

View File

@ -17,6 +17,8 @@ namespace urde
class IObjectStore; class IObjectStore;
class CTexture; class CTexture;
class CLight; class CLight;
class CSkinRules;
class CPoseAsTransforms;
struct CModelFlags struct CModelFlags
{ {
@ -62,6 +64,7 @@ class CBooModel
friend class CModel; friend class CModel;
friend class CBooRenderer; friend class CBooRenderer;
friend class CMetroidModelInstance; friend class CMetroidModelInstance;
friend class CSkinnedModel;
public: public:
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet; using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
using UVAnimation = DataSpec::DNAMP1::MaterialSet::Material::UVAnimation; using UVAnimation = DataSpec::DNAMP1::MaterialSet::Material::UVAnimation;
@ -125,10 +128,18 @@ public:
void RemapMaterialData(SShader& shader); void RemapMaterialData(SShader& shader);
bool TryLockTextures() const; bool TryLockTextures() const;
void UnlockTextures() const; void UnlockTextures() const;
void UpdateUniformData(const CModelFlags& flags) const; void UpdateUniformData(const CModelFlags& flags,
void DrawAlpha(const CModelFlags& flags) const; const CSkinRules* cskr,
void DrawNormal(const CModelFlags& flags) const; const CPoseAsTransforms* pose) const;
void Draw(const CModelFlags& flags) 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 const MaterialSet::Material& GetMaterialByIndex(int idx) const
{ {

View File

@ -7,6 +7,7 @@
#include "boo/graphicsdev/Metal.hpp" #include "boo/graphicsdev/Metal.hpp"
#include "Shaders/CModelShaders.hpp" #include "Shaders/CModelShaders.hpp"
#include "Graphics/CBooRenderer.hpp" #include "Graphics/CBooRenderer.hpp"
#include "Character/CSkinRules.hpp"
#include "GameGlobalObjects.hpp" #include "GameGlobalObjects.hpp"
#include <array> #include <array>
@ -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<u8*>(m_uniformBuffer->map(m_uniformDataSize)); u8* dataOut = reinterpret_cast<u8*>(m_uniformBuffer->map(m_uniformDataSize));
u8* dataCur = dataOut; u8* dataCur = dataOut;
@ -464,7 +467,41 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags) const
if (m_skinBankCount) if (m_skinBankCount)
{ {
/* Skinned */ /* Skinned */
std::vector<const zeus::CTransform*> bankTransforms;
bankTransforms.reserve(m_weightVecCount*4);
for (size_t i=0 ; i<m_skinBankCount ; ++i) for (size_t i=0 ; i<m_skinBankCount ; ++i)
{
if (cskr && pose)
{
cskr->GetBankTransforms(bankTransforms, *pose, i);
for (size_t w=0 ; w<m_weightVecCount*4 ; ++w)
{
zeus::CMatrix4f& mv = reinterpret_cast<zeus::CMatrix4f&>(*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<m_weightVecCount*4 ; ++w)
{
zeus::CMatrix4f& mvinv = reinterpret_cast<zeus::CMatrix4f&>(*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();
}
else
{ {
for (size_t w=0 ; w<m_weightVecCount*4 ; ++w) for (size_t w=0 ; w<m_weightVecCount*4 ; ++w)
{ {
@ -478,6 +515,7 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags) const
mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
dataCur += sizeof(zeus::CMatrix4f); dataCur += sizeof(zeus::CMatrix4f);
} }
}
zeus::CMatrix4f& proj = reinterpret_cast<zeus::CMatrix4f&>(*dataCur); zeus::CMatrix4f& proj = reinterpret_cast<zeus::CMatrix4f&>(*dataCur);
proj = CGraphics::GetPerspectiveProjectionMatrix(true); proj = CGraphics::GetPerspectiveProjectionMatrix(true);
dataCur += sizeof(zeus::CMatrix4f); dataCur += sizeof(zeus::CMatrix4f);
@ -524,29 +562,35 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags) const
m_uniformBuffer->unmap(); 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()) if (TryLockTextures())
{ {
UpdateUniformData(flags); UpdateUniformData(flags, cskr, pose);
DrawAlphaSurfaces(flags); DrawAlphaSurfaces(flags);
} }
} }
void CBooModel::DrawNormal(const CModelFlags& flags) const void CBooModel::DrawNormal(const CModelFlags& flags,
const CSkinRules* cskr,
const CPoseAsTransforms* pose) const
{ {
if (TryLockTextures()) if (TryLockTextures())
{ {
UpdateUniformData(flags); UpdateUniformData(flags, cskr, pose);
DrawNormalSurfaces(flags); DrawNormalSurfaces(flags);
} }
} }
void CBooModel::Draw(const CModelFlags& flags) const void CBooModel::Draw(const CModelFlags& flags,
const CSkinRules* cskr,
const CPoseAsTransforms* pose) const
{ {
if (TryLockTextures()) if (TryLockTextures())
{ {
UpdateUniformData(flags); UpdateUniformData(flags, cskr, pose);
DrawSurfaces(flags); DrawSurfaces(flags);
} }
} }
@ -667,19 +711,19 @@ void CModel::VerifyCurrentShader(int shaderIdx) const
void CModel::DrawSortedParts(const CModelFlags& flags) const void CModel::DrawSortedParts(const CModelFlags& flags) const
{ {
VerifyCurrentShader(flags.m_matSetIdx); VerifyCurrentShader(flags.m_matSetIdx);
x28_modelInst->DrawAlpha(flags); x28_modelInst->DrawAlpha(flags, nullptr, nullptr);
} }
void CModel::DrawUnsortedParts(const CModelFlags& flags) const void CModel::DrawUnsortedParts(const CModelFlags& flags) const
{ {
VerifyCurrentShader(flags.m_matSetIdx); VerifyCurrentShader(flags.m_matSetIdx);
x28_modelInst->DrawNormal(flags); x28_modelInst->DrawNormal(flags, nullptr, nullptr);
} }
void CModel::Draw(const CModelFlags& flags) const void CModel::Draw(const CModelFlags& flags) const
{ {
VerifyCurrentShader(flags.m_matSetIdx); VerifyCurrentShader(flags.m_matSetIdx);
x28_modelInst->Draw(flags); x28_modelInst->Draw(flags, nullptr, nullptr);
} }
void CModel::Touch(int shaderIdx) const void CModel::Touch(int shaderIdx) const

View File

@ -3,29 +3,43 @@
namespace urde namespace urde
{ {
CSkinnedModel::CSkinnedModel(const TLockedToken<CModel>& model, CSkinnedModel::CSkinnedModel(TLockedToken<CModel> model,
const TLockedToken<CSkinRules>& skinRules, TLockedToken<CSkinRules> skinRules,
const TLockedToken<CCharLayoutInfo>& layoutInfo) TLockedToken<CCharLayoutInfo> layoutInfo,
int shaderIdx)
: x4_model(model), x10_skinRules(skinRules), x1c_layoutInfo(layoutInfo) : x4_model(model), x10_skinRules(skinRules), x1c_layoutInfo(layoutInfo)
{ {
m_modelInst = model->MakeNewInstance(shaderIdx);
} }
CSkinnedModel::CSkinnedModel(IObjectStore& store, ResId model, CSkinnedModel::CSkinnedModel(IObjectStore& store, ResId model,
ResId skinRules, ResId layoutInfo, 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, void CSkinnedModel::Calculate(const CPoseAsTransforms& pose,
const rstl::optional_object<CVertexMorphEffect>&) const CModelFlags& drawFlags,
const rstl::optional_object<CVertexMorphEffect>& 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, CMorphableSkinnedModel::CMorphableSkinnedModel(IObjectStore& store, ResId model,
ResId skinRules, ResId layoutInfo, ResId skinRules, ResId layoutInfo,
EDataOwnership ownership) int shaderIdx)
: CSkinnedModel(store, model, skinRules, layoutInfo, ownership) : CSkinnedModel(store, model, skinRules, layoutInfo, shaderIdx)
{ {
} }

View File

@ -16,6 +16,7 @@ class IObjectStore;
class CSkinnedModel class CSkinnedModel
{ {
friend class CBooModel;
std::unique_ptr<CBooModel> m_modelInst; std::unique_ptr<CBooModel> m_modelInst;
TLockedToken<CModel> x4_model; TLockedToken<CModel> x4_model;
TLockedToken<CSkinRules> x10_skinRules; TLockedToken<CSkinRules> x10_skinRules;
@ -26,25 +27,29 @@ public:
Zero, Zero,
One One
}; };
CSkinnedModel(const TLockedToken<CModel>& model, CSkinnedModel(TLockedToken<CModel> model,
const TLockedToken<CSkinRules>& skinRules, TLockedToken<CSkinRules> skinRules,
const TLockedToken<CCharLayoutInfo>& layoutInfo); TLockedToken<CCharLayoutInfo> layoutInfo,
int shaderIdx);
CSkinnedModel(IObjectStore& store, ResId model, ResId skinRules, CSkinnedModel(IObjectStore& store, ResId model, ResId skinRules,
ResId layoutInfo, EDataOwnership ownership); ResId layoutInfo, int shaderIdx);
TLockedToken<CModel>& GetModel() {return x4_model;} TLockedToken<CModel>& GetModel() {return x4_model;}
TLockedToken<CSkinRules>& GetSkinRules() {return x10_skinRules;} TLockedToken<CSkinRules>& GetSkinRules() {return x10_skinRules;}
TLockedToken<CCharLayoutInfo>& GetLayoutInfo() {return x1c_layoutInfo;} TLockedToken<CCharLayoutInfo>& GetLayoutInfo() {return x1c_layoutInfo;}
void Calculate(const CPoseAsTransforms& pose, const std::experimental::optional<CVertexMorphEffect>&); void Calculate(const CPoseAsTransforms& pose,
void Draw(const CModelFlags& drawFlags) const {} const CModelFlags& drawFlags,
const std::experimental::optional<CVertexMorphEffect>& morphEffect,
const float* morphMagnitudes);
void Draw(const CModelFlags& drawFlags) const;
}; };
class CMorphableSkinnedModel : public CSkinnedModel class CMorphableSkinnedModel : public CSkinnedModel
{ {
public: public:
CMorphableSkinnedModel(IObjectStore& store, ResId model, ResId skinRules, CMorphableSkinnedModel(IObjectStore& store, ResId model, ResId skinRules,
ResId layoutInfo, EDataOwnership ownership); ResId layoutInfo, int shaderIdx);
}; };
} }

View File

@ -28,7 +28,7 @@ CCameraBlurFilter::CCameraBlurFilter()
void CCameraBlurFilter::draw(float amount) void CCameraBlurFilter::draw(float amount)
{ {
if (amount == 0.f) if (amount <= 0.f)
return; return;
SClipScreenRect clipRect = {}; SClipScreenRect clipRect = {};

View File

@ -197,6 +197,7 @@ void CWorldTransManager::DrawFirstPass()
360.f + 180.f - 90.f)); 360.f + 180.f - 90.f));
CGraphics::SetViewPointMatrix(rotateXf * translateXf); CGraphics::SetViewPointMatrix(rotateXf * translateXf);
DrawAllModels(); DrawAllModels();
m_camblur.draw(x4_modelData->x1c8_blurResult);
} }
void CWorldTransManager::DrawSecondPass() void CWorldTransManager::DrawSecondPass()

View File

@ -8,6 +8,7 @@
#include "Graphics/CLight.hpp" #include "Graphics/CLight.hpp"
#include "Graphics/Shaders/CColoredQuadFilter.hpp" #include "Graphics/Shaders/CColoredQuadFilter.hpp"
#include "Graphics/Shaders/CTexturedQuadFilter.hpp" #include "Graphics/Shaders/CTexturedQuadFilter.hpp"
#include "Graphics/Shaders/CCameraBlurFilter.hpp"
namespace urde namespace urde
{ {
@ -83,6 +84,7 @@ private:
CTexturedQuadFilter m_dissolve = { CCameraFilterPass::EFilterType::Blend, CTexturedQuadFilter m_dissolve = { CCameraFilterPass::EFilterType::Blend,
CGraphics::g_SpareTexture }; CGraphics::g_SpareTexture };
CWideScreenFilter m_widescreen = { CCameraFilterPass::EFilterType::Blend }; CWideScreenFilter m_widescreen = { CCameraFilterPass::EFilterType::Blend };
CCameraBlurFilter m_camblur;
static int GetSuitCharIdx(); static int GetSuitCharIdx();
void DrawFirstPass(); void DrawFirstPass();

2
hecl

@ -1 +1 @@
Subproject commit 53ae402b2b130e6d0e1742d0a9d864223149c8ac Subproject commit 667c476f2e78ac6aedef9faba4783ade01dfbd47

@ -1 +1 @@
Subproject commit d8186d24b70a8ca885b4bd3e19e1f5402c076191 Subproject commit 4260ea58f19648d6548b0c25488bfb8b47d0263b