mirror of https://github.com/AxioDL/metaforce.git
CAnimSourceReader imps
This commit is contained in:
parent
3bab36faba
commit
e51a657ec1
|
@ -1,6 +1,8 @@
|
||||||
#include "ProjectResourceFactoryBase.hpp"
|
#include "ProjectResourceFactoryBase.hpp"
|
||||||
#include "Runtime/IObj.hpp"
|
#include "Runtime/IObj.hpp"
|
||||||
|
|
||||||
|
#define DUMP_CACHE_FILL 1
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
static logvisor::Module Log("urde::ProjectResourceFactoryBase");
|
static logvisor::Module Log("urde::ProjectResourceFactoryBase");
|
||||||
|
@ -93,6 +95,15 @@ static void WriteTag(athena::io::YAMLDocWriter& cacheWriter,
|
||||||
cacheWriter.leaveSubVector();
|
cacheWriter.leaveSubVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DUMP_CACHE_FILL
|
||||||
|
static void DumpCacheAdd(const SObjectTag& pathTag, const hecl::ProjectPath& path)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s %08X %s\n",
|
||||||
|
pathTag.type.toString().c_str(), uint32_t(pathTag.id),
|
||||||
|
path.getRelativePathUTF8().c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::ProjectPath& dir,
|
void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::ProjectPath& dir,
|
||||||
athena::io::YAMLDocWriter& cacheWriter,
|
athena::io::YAMLDocWriter& cacheWriter,
|
||||||
athena::io::YAMLDocWriter& nameWriter,
|
athena::io::YAMLDocWriter& nameWriter,
|
||||||
|
@ -127,10 +138,8 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
||||||
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
||||||
m_tagToPath[pathTag] = path;
|
m_tagToPath[pathTag] = path;
|
||||||
WriteTag(cacheWriter, pathTag, path);
|
WriteTag(cacheWriter, pathTag, path);
|
||||||
#if 1
|
#if DUMP_CACHE_FILL
|
||||||
fprintf(stderr, "%s %08X %s\n",
|
DumpCacheAdd(pathTag, path);
|
||||||
pathTag.type.toString().c_str(), uint32_t(pathTag.id),
|
|
||||||
path.getRelativePathUTF8().c_str());
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Special multi-resource intermediates */
|
/* Special multi-resource intermediates */
|
||||||
|
@ -150,11 +159,11 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
||||||
hecl::SystemStringView sysStr(arm);
|
hecl::SystemStringView sysStr(arm);
|
||||||
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("CINF"));
|
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("CINF"));
|
||||||
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
||||||
if (pathTag)
|
m_tagToPath[pathTag] = subPath;
|
||||||
{
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
m_tagToPath[pathTag] = path;
|
#if DUMP_CACHE_FILL
|
||||||
WriteTag(cacheWriter, pathTag, path);
|
DumpCacheAdd(pathTag, subPath);
|
||||||
}
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const std::string& sub : subtypeNames)
|
for (const std::string& sub : subtypeNames)
|
||||||
|
@ -162,11 +171,11 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
||||||
hecl::SystemStringView sysStr(sub);
|
hecl::SystemStringView sysStr(sub);
|
||||||
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("CSKR"));
|
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("CSKR"));
|
||||||
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
||||||
if (pathTag)
|
m_tagToPath[pathTag] = subPath;
|
||||||
{
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
m_tagToPath[pathTag] = path;
|
#if DUMP_CACHE_FILL
|
||||||
WriteTag(cacheWriter, pathTag, path);
|
DumpCacheAdd(pathTag, subPath);
|
||||||
}
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const std::string& act : actionNames)
|
for (const std::string& act : actionNames)
|
||||||
|
@ -174,11 +183,11 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
||||||
hecl::SystemStringView sysStr(act);
|
hecl::SystemStringView sysStr(act);
|
||||||
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("ANIM"));
|
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("ANIM"));
|
||||||
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
||||||
if (pathTag)
|
m_tagToPath[pathTag] = subPath;
|
||||||
{
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
m_tagToPath[pathTag] = path;
|
#if DUMP_CACHE_FILL
|
||||||
WriteTag(cacheWriter, pathTag, path);
|
DumpCacheAdd(pathTag, subPath);
|
||||||
}
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,13 @@ void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj)
|
||||||
|
|
||||||
SObjectTag ProjectResourceFactoryMP1::TagFromPath(const hecl::ProjectPath& path, hecl::BlenderToken& btok) const
|
SObjectTag ProjectResourceFactoryMP1::TagFromPath(const hecl::ProjectPath& path, hecl::BlenderToken& btok) const
|
||||||
{
|
{
|
||||||
|
if (!path.getAuxInfo().compare(_S("CINF")))
|
||||||
|
return SObjectTag(SBIG('CINF'), path.hash().val32());
|
||||||
|
else if (!path.getAuxInfo().compare(_S("CSKR")))
|
||||||
|
return SObjectTag(SBIG('CSKR'), path.hash().val32());
|
||||||
|
else if (!path.getAuxInfo().compare(_S("ANIM")))
|
||||||
|
return SObjectTag(SBIG('ANIM'), path.hash().val32());
|
||||||
|
|
||||||
if (hecl::IsPathBlend(path))
|
if (hecl::IsPathBlend(path))
|
||||||
{
|
{
|
||||||
hecl::BlenderConnection& conn = btok.getBlenderConnection();
|
hecl::BlenderConnection& conn = btok.getBlenderConnection();
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "CAdditiveAnimPlayback.hpp"
|
||||||
|
#include "CSegStatementSet.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
CAdditiveAnimPlayback::CAdditiveAnimPlayback(const std::weak_ptr<CAnimTreeNode>& anim, float weight, bool a,
|
||||||
|
const CAdditiveAnimationInfo& info, bool b)
|
||||||
|
: x0_info(info), x8_anim(anim), xc_weight(weight), x14_a(a)
|
||||||
|
{
|
||||||
|
if (!a && b)
|
||||||
|
x20_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAdditiveAnimPlayback::AddToSegStatementSet(const CSegIdList& list,
|
||||||
|
const CCharLayoutInfo&,
|
||||||
|
CSegStatementSet&) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAdditiveAnimPlayback::Update(float dt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAdditiveAnimPlayback::FadeOut()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAdditiveAnimPlayback::SetWeight(float w)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef __URDE_CADDITIVEANIMPLAYBACK_HPP__
|
||||||
|
#define __URDE_CADDITIVEANIMPLAYBACK_HPP__
|
||||||
|
|
||||||
|
#include "RetroTypes.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
class CAnimTreeNode;
|
||||||
|
class CAdditiveAnimationInfo;
|
||||||
|
class CSegIdList;
|
||||||
|
class CCharLayoutInfo;
|
||||||
|
class CSegStatementSet;
|
||||||
|
|
||||||
|
class CAdditiveAnimationInfo
|
||||||
|
{
|
||||||
|
float x0_a = 0.f;
|
||||||
|
float x4_b = 0.f;
|
||||||
|
public:
|
||||||
|
void read(CInputStream& in)
|
||||||
|
{
|
||||||
|
x0_a = in.readFloatBig();
|
||||||
|
x4_b = in.readFloatBig();
|
||||||
|
}
|
||||||
|
CAdditiveAnimationInfo() = default;
|
||||||
|
CAdditiveAnimationInfo(CInputStream& in) {read(in);}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CAdditiveAnimPlayback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class EAdditivePlaybackState
|
||||||
|
{
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
Three,
|
||||||
|
Four
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
CAdditiveAnimationInfo x0_info;
|
||||||
|
std::weak_ptr<CAnimTreeNode> x8_anim;
|
||||||
|
float xc_weight;
|
||||||
|
float x10_ = 0.f;
|
||||||
|
bool x14_a;
|
||||||
|
float x18_ = 0.f;
|
||||||
|
EAdditivePlaybackState x1c_ = EAdditivePlaybackState::One;
|
||||||
|
bool x20_ = false;
|
||||||
|
public:
|
||||||
|
CAdditiveAnimPlayback(const std::weak_ptr<CAnimTreeNode>& anim, float weight, bool a,
|
||||||
|
const CAdditiveAnimationInfo& info, bool b);
|
||||||
|
|
||||||
|
void AddToSegStatementSet(const CSegIdList& list, const CCharLayoutInfo&, CSegStatementSet&) const;
|
||||||
|
void Update(float dt);
|
||||||
|
void FadeOut();
|
||||||
|
void SetWeight(float w);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __URDE_CADDITIVEANIMPLAYBACK_HPP__
|
|
@ -5,6 +5,7 @@
|
||||||
#include "CCharacterFactory.hpp"
|
#include "CCharacterFactory.hpp"
|
||||||
#include "CAnimationManager.hpp"
|
#include "CAnimationManager.hpp"
|
||||||
#include "CTransitionManager.hpp"
|
#include "CTransitionManager.hpp"
|
||||||
|
#include "CAdditiveAnimPlayback.hpp"
|
||||||
#include "IAnimReader.hpp"
|
#include "IAnimReader.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
|
@ -46,8 +47,9 @@ CAnimData::CAnimData(ResId id,
|
||||||
xe4_iceModelData = *iceModel;
|
xe4_iceModelData = *iceModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResId CAnimData::GetEventResourceIdForAnimResourceId(ResId) const
|
ResId CAnimData::GetEventResourceIdForAnimResourceId(ResId id) const
|
||||||
{
|
{
|
||||||
|
return x0_charFactory->GetEventResourceIdForAnimResourceId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet)
|
void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet)
|
||||||
|
|
|
@ -36,6 +36,7 @@ class CSkinRules;
|
||||||
class CAnimTreeNode;
|
class CAnimTreeNode;
|
||||||
class CSegIdList;
|
class CSegIdList;
|
||||||
class CSegStatementSet;
|
class CSegStatementSet;
|
||||||
|
class CAdditiveAnimPlayback;
|
||||||
struct SAdvancementDeltas;
|
struct SAdvancementDeltas;
|
||||||
|
|
||||||
class CAnimData
|
class CAnimData
|
||||||
|
@ -96,7 +97,7 @@ class CAnimData
|
||||||
u32 x1038_ = 0;
|
u32 x1038_ = 0;
|
||||||
u32 x103c_ = 0;
|
u32 x103c_ = 0;
|
||||||
u32 x1040_ = 0;
|
u32 x1040_ = 0;
|
||||||
u32 x1044_ = 0;
|
rstl::reserved_vector<std::pair<u32, CAdditiveAnimPlayback>, 8> x1044_additiveAnims;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CAnimData(ResId,
|
CAnimData(ResId,
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef __URDE_CANIMPERSEGMENTDATA_HPP__
|
||||||
|
#define __URDE_CANIMPERSEGMENTDATA_HPP__
|
||||||
|
|
||||||
|
#include "zeus/CQuaternion.hpp"
|
||||||
|
#include "zeus/CVector3f.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
struct CAnimPerSegmentData
|
||||||
|
{
|
||||||
|
zeus::CQuaternion x0_rotation;
|
||||||
|
zeus::CVector3f x10_offset;
|
||||||
|
bool x1c_hasOffset = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __URDE_CANIMPERSEGMENTDATA_HPP__
|
|
@ -1,6 +1,8 @@
|
||||||
#include "CAnimSource.hpp"
|
#include "CAnimSource.hpp"
|
||||||
#include "CAnimPOIData.hpp"
|
#include "CAnimPOIData.hpp"
|
||||||
#include "CSegId.hpp"
|
#include "CSegId.hpp"
|
||||||
|
#include "CSegIdList.hpp"
|
||||||
|
#include "CSegStatementSet.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -148,7 +150,37 @@ void CAnimSource::GetSegStatementSet(const CSegIdList& list,
|
||||||
if (std::fabs(remTime) < 0.00001f)
|
if (std::fabs(remTime) < 0.00001f)
|
||||||
remTime = 0.f;
|
remTime = 0.f;
|
||||||
float t = ClampZeroToOne(remTime / x8_interval);
|
float t = ClampZeroToOne(remTime / x8_interval);
|
||||||
/* TODO: Finish */
|
const u32 floatsPerFrame = x40_data.x10_transPerFrame * 3 + x40_data.xc_rotPerFrame * 4;
|
||||||
|
const u32 rotFloatsPerFrame = x40_data.xc_rotPerFrame * 4;
|
||||||
|
|
||||||
|
for (const CSegId& id : list.GetList())
|
||||||
|
{
|
||||||
|
u8 rotIdx = x20_rotationChannels[id];
|
||||||
|
if (rotIdx != 0xff)
|
||||||
|
{
|
||||||
|
const float* frameDataA =
|
||||||
|
&x40_data.x0_storage[frameIdx*floatsPerFrame+rotIdx*4];
|
||||||
|
const float* frameDataB =
|
||||||
|
&x40_data.x0_storage[(frameIdx+1)*floatsPerFrame+rotIdx*4];
|
||||||
|
|
||||||
|
zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]);
|
||||||
|
zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[3]);
|
||||||
|
set.x4_segData[id].x0_rotation = zeus::CQuaternion::slerp(quatA, quatB, t);
|
||||||
|
|
||||||
|
u8 transIdx = x30_translationChannels[rotIdx];
|
||||||
|
if (transIdx != 0xff)
|
||||||
|
{
|
||||||
|
const float* frameDataA =
|
||||||
|
&x40_data.x0_storage[frameIdx*floatsPerFrame+rotFloatsPerFrame+transIdx*3];
|
||||||
|
const float* frameDataB =
|
||||||
|
&x40_data.x0_storage[(frameIdx-1)*floatsPerFrame+rotFloatsPerFrame+transIdx*3];
|
||||||
|
zeus::CVector3f vecA(frameDataA[0], frameDataA[1], frameDataA[2]);
|
||||||
|
zeus::CVector3f vecB(frameDataB[0], frameDataB[1], frameDataB[2]);
|
||||||
|
set.x4_segData[id].x10_offset = zeus::CVector3f::lerp(vecA, vecB, t);
|
||||||
|
set.x4_segData[id].x1c_hasOffset = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<CSoundPOINode>& CAnimSource::GetSoundPOIStream() const
|
const std::vector<CSoundPOINode>& CAnimSource::GetSoundPOIStream() const
|
||||||
|
|
|
@ -74,6 +74,7 @@ public:
|
||||||
const std::vector<CParticlePOINode>& GetParticlePOIStream() const;
|
const std::vector<CParticlePOINode>& GetParticlePOIStream() const;
|
||||||
const std::vector<CInt32POINode>& GetInt32POIStream() const;
|
const std::vector<CInt32POINode>& GetInt32POIStream() const;
|
||||||
const std::vector<CBoolPOINode>& GetBoolPOIStream() const;
|
const std::vector<CBoolPOINode>& GetBoolPOIStream() const;
|
||||||
|
const TCachedToken<CAnimPOIData>& GetPOIData() const {return x58_evntData;}
|
||||||
zeus::CQuaternion GetRotation(const CSegId& seg, const CCharAnimTime& time) const;
|
zeus::CQuaternion GetRotation(const CSegId& seg, const CCharAnimTime& time) const;
|
||||||
zeus::CVector3f GetOffset(const CSegId& seg, const CCharAnimTime& time) const;
|
zeus::CVector3f GetOffset(const CSegId& seg, const CCharAnimTime& time) const;
|
||||||
bool HasOffset(const CSegId& seg) const;
|
bool HasOffset(const CSegId& seg) const;
|
||||||
|
|
|
@ -241,61 +241,210 @@ CAnimSourceReaderBase::CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&&
|
||||||
const CCharAnimTime& time)
|
const CCharAnimTime& time)
|
||||||
: x4_sourceInfo(std::move(sourceInfo)), xc_curTime(time) {}
|
: x4_sourceInfo(std::move(sourceInfo)), xc_curTime(time) {}
|
||||||
|
|
||||||
SAdvancementResults CAnimSourceReader::VGetAdvancementResults(const CCharAnimTime& a,
|
CAnimSourceReaderBase::CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
|
||||||
const CCharAnimTime& b) const
|
const CAnimSourceReaderBase& other)
|
||||||
|
: x4_sourceInfo(std::move(sourceInfo)),
|
||||||
|
xc_curTime(other.xc_curTime),
|
||||||
|
x14_passedBoolCount(other.x14_passedBoolCount),
|
||||||
|
x18_passedIntCount(other.x18_passedIntCount),
|
||||||
|
x1c_passedParticleCount(other.x1c_passedParticleCount),
|
||||||
|
x20_passedSoundCount(other.x20_passedSoundCount),
|
||||||
|
x24_boolStates(other.x24_boolStates),
|
||||||
|
x34_int32States(other.x34_int32States),
|
||||||
|
x44_particleStates(other.x44_particleStates)
|
||||||
|
{}
|
||||||
|
|
||||||
|
SAdvancementResults CAnimSourceReader::VGetAdvancementResults(const CCharAnimTime& dt,
|
||||||
|
const CCharAnimTime& startOff) const
|
||||||
{
|
{
|
||||||
|
SAdvancementResults ret;
|
||||||
|
CCharAnimTime accum = xc_curTime + startOff;
|
||||||
|
|
||||||
|
if (xc_curTime + startOff >= x54_source->GetDuration())
|
||||||
|
{
|
||||||
|
ret.x0_remTime = dt;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else if (dt.EqualsZero())
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCharAnimTime prevTime = accum;
|
||||||
|
accum += dt;
|
||||||
|
CCharAnimTime remTime;
|
||||||
|
if (accum > x54_source->GetDuration())
|
||||||
|
{
|
||||||
|
remTime = accum - x54_source->GetDuration();
|
||||||
|
accum = x54_source->GetDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimSourceReader::VSetPhase(float)
|
zeus::CQuaternion ra = x54_source->GetRotation(3, prevTime).inverse();
|
||||||
|
zeus::CQuaternion rb = x54_source->GetRotation(3, accum);
|
||||||
|
ret.x0_remTime = remTime;
|
||||||
|
ret.x8_deltas.xc_rotDelta = rb * ra;
|
||||||
|
|
||||||
|
if (x54_source->HasOffset(3))
|
||||||
{
|
{
|
||||||
|
zeus::CVector3f ta = x54_source->GetOffset(3, prevTime);
|
||||||
|
zeus::CVector3f tb = x54_source->GetOffset(3, accum);
|
||||||
|
ret.x8_deltas.x0_posDelta = zeus::CMatrix3f(rb) * (tb - ta);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAdvancementResults CAnimSourceReader::VReverseView(const CCharAnimTime& time)
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAnimSourceReader::VSetPhase(float phase)
|
||||||
{
|
{
|
||||||
|
xc_curTime = phase * x54_source->GetDuration();
|
||||||
|
if (x54_source->GetPOIData())
|
||||||
|
{
|
||||||
|
UpdatePOIStates();
|
||||||
|
if (!xc_curTime.GreaterThanZero())
|
||||||
|
{
|
||||||
|
x14_passedBoolCount = 0;
|
||||||
|
x18_passedIntCount = 0;
|
||||||
|
x1c_passedParticleCount = 0;
|
||||||
|
x20_passedSoundCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SAdvancementResults CAnimSourceReader::VReverseView(const CCharAnimTime& dt)
|
||||||
|
{
|
||||||
|
SAdvancementResults ret;
|
||||||
|
|
||||||
|
if (xc_curTime.EqualsZero())
|
||||||
|
{
|
||||||
|
ret.x0_remTime = dt;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else if (dt.EqualsZero())
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCharAnimTime prevTime = xc_curTime;
|
||||||
|
xc_curTime -= dt;
|
||||||
|
CCharAnimTime remTime;
|
||||||
|
if (xc_curTime < CCharAnimTime())
|
||||||
|
{
|
||||||
|
remTime = CCharAnimTime() - xc_curTime;
|
||||||
|
xc_curTime = CCharAnimTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x54_source->GetPOIData())
|
||||||
|
UpdatePOIStates();
|
||||||
|
|
||||||
|
zeus::CQuaternion ra = x54_source->GetRotation(3, prevTime).inverse();
|
||||||
|
zeus::CQuaternion rb = x54_source->GetRotation(3, xc_curTime);
|
||||||
|
ret.x0_remTime = remTime;
|
||||||
|
ret.x8_deltas.xc_rotDelta = rb * ra;
|
||||||
|
|
||||||
|
if (x54_source->HasOffset(3))
|
||||||
|
{
|
||||||
|
zeus::CVector3f ta = x54_source->GetOffset(3, prevTime);
|
||||||
|
zeus::CVector3f tb = x54_source->GetOffset(3, xc_curTime);
|
||||||
|
ret.x8_deltas.x0_posDelta = zeus::CMatrix3f(rb) * (tb - ta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IAnimReader> CAnimSourceReader::VClone() const
|
std::shared_ptr<IAnimReader> CAnimSourceReader::VClone() const
|
||||||
{
|
{
|
||||||
|
return std::make_shared<CAnimSourceReader>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimSourceReader::VGetSegStatementSet(const CSegIdList& list,
|
void CAnimSourceReader::VGetSegStatementSet(const CSegIdList& list,
|
||||||
CSegStatementSet& setOut) const
|
CSegStatementSet& setOut) const
|
||||||
{
|
{
|
||||||
|
x54_source->GetSegStatementSet(list, setOut, xc_curTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimSourceReader::VGetSegStatementSet(const CSegIdList& list,
|
void CAnimSourceReader::VGetSegStatementSet(const CSegIdList& list,
|
||||||
CSegStatementSet& setOut,
|
CSegStatementSet& setOut,
|
||||||
const CCharAnimTime& time) const
|
const CCharAnimTime& time) const
|
||||||
{
|
{
|
||||||
|
x54_source->GetSegStatementSet(list, setOut, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAdvancementResults CAnimSourceReader::VAdvanceView(const CCharAnimTime& a)
|
SAdvancementResults CAnimSourceReader::VAdvanceView(const CCharAnimTime& dt)
|
||||||
{
|
{
|
||||||
|
SAdvancementResults ret;
|
||||||
|
|
||||||
|
if (xc_curTime >= x54_source->GetDuration())
|
||||||
|
{
|
||||||
|
ret.x0_remTime = dt;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else if (dt.EqualsZero())
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCharAnimTime prevTime = xc_curTime;
|
||||||
|
xc_curTime += dt;
|
||||||
|
CCharAnimTime remTime;
|
||||||
|
if (xc_curTime > x54_source->GetDuration())
|
||||||
|
{
|
||||||
|
remTime = xc_curTime - x54_source->GetDuration();
|
||||||
|
xc_curTime = x54_source->GetDuration();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x54_source->GetPOIData())
|
||||||
|
UpdatePOIStates();
|
||||||
|
|
||||||
|
zeus::CQuaternion ra = x54_source->GetRotation(3, prevTime).inverse();
|
||||||
|
zeus::CQuaternion rb = x54_source->GetRotation(3, xc_curTime);
|
||||||
|
ret.x0_remTime = remTime;
|
||||||
|
ret.x8_deltas.xc_rotDelta = rb * ra;
|
||||||
|
|
||||||
|
if (x54_source->HasOffset(3))
|
||||||
|
{
|
||||||
|
zeus::CVector3f ta = x54_source->GetOffset(3, prevTime);
|
||||||
|
zeus::CVector3f tb = x54_source->GetOffset(3, xc_curTime);
|
||||||
|
ret.x8_deltas.x0_posDelta = zeus::CMatrix3f(rb) * (tb - ta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CCharAnimTime CAnimSourceReader::VGetTimeRemaining() const
|
CCharAnimTime CAnimSourceReader::VGetTimeRemaining() const
|
||||||
{
|
{
|
||||||
|
return x54_source->GetDuration() - xc_curTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimSourceReader::VGetSteadyStateAnimInfo() const
|
CSteadyStateAnimInfo CAnimSourceReader::VGetSteadyStateAnimInfo() const
|
||||||
{
|
{
|
||||||
|
return x64_steadyStateInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAnimSourceReader::VHasOffset(const CSegId& seg) const
|
bool CAnimSourceReader::VHasOffset(const CSegId& seg) const
|
||||||
{
|
{
|
||||||
|
return x54_source->HasOffset(seg);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CVector3f CAnimSourceReader::VGetOffset(const CSegId& seg) const
|
zeus::CVector3f CAnimSourceReader::VGetOffset(const CSegId& seg) const
|
||||||
{
|
{
|
||||||
|
return x54_source->GetOffset(seg, xc_curTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CVector3f CAnimSourceReader::VGetOffset(const CSegId& seg,
|
zeus::CVector3f CAnimSourceReader::VGetOffset(const CSegId& seg,
|
||||||
const CCharAnimTime& time) const
|
const CCharAnimTime& time) const
|
||||||
{
|
{
|
||||||
|
return x54_source->GetOffset(seg, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CQuaternion CAnimSourceReader::VGetRotation(const CSegId& seg) const
|
zeus::CQuaternion CAnimSourceReader::VGetRotation(const CSegId& seg) const
|
||||||
{
|
{
|
||||||
|
return x54_source->GetRotation(seg, xc_curTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimSourceReader::CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source,
|
CAnimSourceReader::CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source,
|
||||||
|
@ -304,10 +453,15 @@ CAnimSourceReader::CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& sourc
|
||||||
x54_source(source)
|
x54_source(source)
|
||||||
{
|
{
|
||||||
CAnimSource* sourceData = x54_source.GetObj();
|
CAnimSource* sourceData = x54_source.GetObj();
|
||||||
x64_duration = sourceData->GetDuration();
|
x64_steadyStateInfo.x64_duration = sourceData->GetDuration();
|
||||||
x6c_curRootOffset = sourceData->GetOffset(sourceData->GetRootBoneId(), time);
|
x64_steadyStateInfo.x6c_curRootOffset = sourceData->GetOffset(sourceData->GetRootBoneId(), time);
|
||||||
PostConstruct(time);
|
PostConstruct(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CAnimSourceReader::CAnimSourceReader(const CAnimSourceReader& other)
|
||||||
|
: CAnimSourceReaderBase(std::make_unique<CAnimSourceInfo>(other.x54_source), other),
|
||||||
|
x54_source(other.x54_source), x64_steadyStateInfo(other.x64_steadyStateInfo)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
|
|
||||||
class CAnimSourceReaderBase : public IAnimReader
|
class CAnimSourceReaderBase : public IAnimReader
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
std::unique_ptr<IAnimSourceInfo> x4_sourceInfo;
|
std::unique_ptr<IAnimSourceInfo> x4_sourceInfo;
|
||||||
CCharAnimTime xc_curTime;
|
CCharAnimTime xc_curTime;
|
||||||
u32 x14_passedBoolCount = 0;
|
u32 x14_passedBoolCount = 0;
|
||||||
|
@ -56,11 +57,13 @@ class CAnimSourceReaderBase : public IAnimReader
|
||||||
protected:
|
protected:
|
||||||
void PostConstruct(const CCharAnimTime& time);
|
void PostConstruct(const CCharAnimTime& time);
|
||||||
void UpdatePOIStates();
|
void UpdatePOIStates();
|
||||||
|
CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
|
||||||
|
const CAnimSourceReaderBase& other);
|
||||||
public:
|
public:
|
||||||
CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
|
CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
|
||||||
const CCharAnimTime& time);
|
const CCharAnimTime& time);
|
||||||
|
|
||||||
|
|
||||||
u32 VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
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;
|
u32 VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
u32 VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
u32 VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
@ -77,11 +80,10 @@ public:
|
||||||
class CAnimSourceReader : public CAnimSourceReaderBase
|
class CAnimSourceReader : public CAnimSourceReaderBase
|
||||||
{
|
{
|
||||||
TSubAnimTypeToken<CAnimSource> x54_source;
|
TSubAnimTypeToken<CAnimSource> x54_source;
|
||||||
CCharAnimTime x64_duration;
|
CSteadyStateAnimInfo x64_steadyStateInfo;
|
||||||
zeus::CVector3f x6c_curRootOffset;
|
|
||||||
bool x78_ = false;
|
|
||||||
public:
|
public:
|
||||||
CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source, const CCharAnimTime& time);
|
CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source, const CCharAnimTime& time);
|
||||||
|
CAnimSourceReader(const CAnimSourceReader& other);
|
||||||
|
|
||||||
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
|
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
|
||||||
bool VSupportsReverseView() const {return true;}
|
bool VSupportsReverseView() const {return true;}
|
||||||
|
@ -92,7 +94,7 @@ public:
|
||||||
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
|
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
|
||||||
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
|
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
|
||||||
CCharAnimTime VGetTimeRemaining() const;
|
CCharAnimTime VGetTimeRemaining() const;
|
||||||
void VGetSteadyStateAnimInfo() const;
|
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
|
||||||
bool VHasOffset(const CSegId& seg) const;
|
bool VHasOffset(const CSegId& seg) const;
|
||||||
zeus::CVector3f VGetOffset(const CSegId& seg) const;
|
zeus::CVector3f VGetOffset(const CSegId& seg) const;
|
||||||
zeus::CVector3f VGetOffset(const CSegId& seg, const CCharAnimTime& time) const;
|
zeus::CVector3f VGetOffset(const CSegId& seg, const CCharAnimTime& time) const;
|
||||||
|
|
|
@ -5,24 +5,11 @@
|
||||||
#include "CAnimation.hpp"
|
#include "CAnimation.hpp"
|
||||||
#include "CTransition.hpp"
|
#include "CTransition.hpp"
|
||||||
#include "CHalfTransition.hpp"
|
#include "CHalfTransition.hpp"
|
||||||
|
#include "CAdditiveAnimPlayback.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
class CAdditiveAnimationInfo
|
|
||||||
{
|
|
||||||
float x0_a = 0.f;
|
|
||||||
float x4_b = 0.f;
|
|
||||||
public:
|
|
||||||
void read(CInputStream& in)
|
|
||||||
{
|
|
||||||
x0_a = in.readFloatBig();
|
|
||||||
x4_b = in.readFloatBig();
|
|
||||||
}
|
|
||||||
CAdditiveAnimationInfo() = default;
|
|
||||||
CAdditiveAnimationInfo(CInputStream& in) {read(in);}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CAnimationSet
|
class CAnimationSet
|
||||||
{
|
{
|
||||||
u16 x0_tableCount;
|
u16 x0_tableCount;
|
||||||
|
|
|
@ -6,13 +6,12 @@ namespace urde
|
||||||
|
|
||||||
zeus::CVector3f CCharLayoutInfo::GetFromParentUnrotated(const CSegId& id) const
|
zeus::CVector3f CCharLayoutInfo::GetFromParentUnrotated(const CSegId& id) const
|
||||||
{
|
{
|
||||||
const CCharLayoutNode::Bone& bone = x0_node->GetBone(id);
|
const CCharLayoutNode::Bone& bone = x0_node->GetBoneMap()[id];
|
||||||
const CSegId& prev = x0_node->GetPrevBone(bone.x0_parentId);
|
if (!x0_node->GetBoneMap().HasElement(bone.x0_parentId))
|
||||||
if (prev == 0xff)
|
|
||||||
return bone.x4_origin;
|
return bone.x4_origin;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const CCharLayoutNode::Bone& pBone = x0_node->GetBone(bone.x0_parentId);
|
const CCharLayoutNode::Bone& pBone = x0_node->GetBoneMap()[bone.x0_parentId];
|
||||||
return bone.x4_origin - pBone.x4_origin;
|
return bone.x4_origin - pBone.x4_origin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,11 +33,8 @@ CCharLayoutNode::CCharLayoutNode(CInputStream& in)
|
||||||
for (u32 i=0 ; i<count ; ++i)
|
for (u32 i=0 ; i<count ; ++i)
|
||||||
{
|
{
|
||||||
u32 thisId = in.readUint32Big();
|
u32 thisId = in.readUint32Big();
|
||||||
Bone& bone = x6c_bones[thisId];
|
Bone& bone = x0_boneMap[thisId];
|
||||||
bone.read(in);
|
bone.read(in);
|
||||||
x8_prevBones[thisId] = x1_curPrevBone;
|
|
||||||
x1_curPrevBone = thisId;
|
|
||||||
++x0_boneCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "IOStreams.hpp"
|
#include "IOStreams.hpp"
|
||||||
#include "CSegIdList.hpp"
|
#include "CSegIdList.hpp"
|
||||||
#include "CSegId.hpp"
|
#include "CSegId.hpp"
|
||||||
|
#include "TSegIdMap.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -20,15 +21,10 @@ public:
|
||||||
void read(CInputStream& in);
|
void read(CInputStream& in);
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
CSegId x0_boneCount = 0;
|
TSegIdMap<Bone> x0_boneMap;
|
||||||
CSegId x1_curPrevBone = 0;
|
|
||||||
CSegId x8_prevBones[100];
|
|
||||||
Bone x6c_bones[100];
|
|
||||||
public:
|
public:
|
||||||
CCharLayoutNode(CInputStream& in);
|
CCharLayoutNode(CInputStream& in);
|
||||||
|
const TSegIdMap<Bone>& GetBoneMap() const {return x0_boneMap;}
|
||||||
const Bone& GetBone(const CSegId& id) const {return x6c_bones[id];}
|
|
||||||
const CSegId& GetPrevBone(const CSegId& id) const {return x8_prevBones[id];}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CCharLayoutInfo
|
class CCharLayoutInfo
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "CRandom16.hpp"
|
#include "CRandom16.hpp"
|
||||||
#include "CPrimitive.hpp"
|
#include "CPrimitive.hpp"
|
||||||
#include "CAnimData.hpp"
|
#include "CAnimData.hpp"
|
||||||
|
#include "CAdditiveAnimPlayback.hpp"
|
||||||
#include "GameGlobalObjects.hpp"
|
#include "GameGlobalObjects.hpp"
|
||||||
#include "Graphics/CSkinnedModel.hpp"
|
#include "Graphics/CSkinnedModel.hpp"
|
||||||
|
|
||||||
|
|
|
@ -8,30 +8,26 @@ namespace urde
|
||||||
void CHierarchyPoseBuilder::BuildIntoHierarchy(const CCharLayoutInfo& layout,
|
void CHierarchyPoseBuilder::BuildIntoHierarchy(const CCharLayoutInfo& layout,
|
||||||
const CSegId& boneId, const CSegId& nullId)
|
const CSegId& boneId, const CSegId& nullId)
|
||||||
{
|
{
|
||||||
const CSegId& idA = x8_prevBones[boneId];
|
if (!x0_treeMap.HasElement(boneId))
|
||||||
if (idA == 0xff)
|
|
||||||
{
|
{
|
||||||
const CCharLayoutNode::Bone& bone = layout.GetRootNode()->GetBone(boneId);
|
const CCharLayoutNode::Bone& bone = layout.GetRootNode()->GetBoneMap()[boneId];
|
||||||
if (bone.x0_parentId == nullId)
|
if (bone.x0_parentId == nullId)
|
||||||
{
|
{
|
||||||
xcec_rootId = boneId;
|
xcec_rootId = boneId;
|
||||||
xcf0_hasRoot = true;
|
xcf0_hasRoot = true;
|
||||||
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
|
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
|
||||||
x6c_nodes[boneId] = CTreeNode(origin);
|
x0_treeMap[boneId] = CTreeNode(origin);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BuildIntoHierarchy(layout, bone.x0_parentId, nullId);
|
BuildIntoHierarchy(layout, bone.x0_parentId, nullId);
|
||||||
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
|
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
|
||||||
CTreeNode& pNode = x6c_nodes[bone.x0_parentId];
|
CTreeNode& pNode = x0_treeMap[bone.x0_parentId];
|
||||||
CTreeNode node(origin);
|
CTreeNode node(origin);
|
||||||
node.x1_sibling = pNode.x0_child;
|
node.x1_sibling = pNode.x0_child;
|
||||||
pNode.x0_child = boneId;
|
pNode.x0_child = boneId;
|
||||||
x6c_nodes[boneId] = node;
|
x0_treeMap[boneId] = node;
|
||||||
}
|
}
|
||||||
x8_prevBones[boneId] = x1_curPrevBone;
|
|
||||||
x1_curPrevBone = boneId;
|
|
||||||
++x0_boneCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +43,7 @@ void CHierarchyPoseBuilder::RecursivelyBuildNoScale(const CSegId& boneId, const
|
||||||
CSegId curBone = node.x0_child;
|
CSegId curBone = node.x0_child;
|
||||||
while (curBone != 0)
|
while (curBone != 0)
|
||||||
{
|
{
|
||||||
const CTreeNode& node = x6c_nodes[curBone];
|
const CTreeNode& node = x0_treeMap[curBone];
|
||||||
RecursivelyBuild(curBone, node, pose, quat, xf, xfOffset);
|
RecursivelyBuild(curBone, node, pose, quat, xf, xfOffset);
|
||||||
curBone = node.x1_sibling;
|
curBone = node.x1_sibling;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +73,7 @@ void CHierarchyPoseBuilder::RecursivelyBuild(const CSegId& boneId, const CTreeNo
|
||||||
CSegId curBone = node.x0_child;
|
CSegId curBone = node.x0_child;
|
||||||
while (curBone != 0)
|
while (curBone != 0)
|
||||||
{
|
{
|
||||||
const CTreeNode& node = x6c_nodes[curBone];
|
const CTreeNode& node = x0_treeMap[curBone];
|
||||||
RecursivelyBuild(curBone, node, pose, quat, quat, xfOffset);
|
RecursivelyBuild(curBone, node, pose, quat, quat, xfOffset);
|
||||||
curBone = node.x1_sibling;
|
curBone = node.x1_sibling;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +102,7 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor
|
||||||
while (curId != 2)
|
while (curId != 2)
|
||||||
{
|
{
|
||||||
buildIDs[idCount++] = curId;
|
buildIDs[idCount++] = curId;
|
||||||
curId = layoutInfo.GetRootNode()->GetBone(curId).x0_parentId;
|
curId = layoutInfo.GetRootNode()->GetBoneMap()[curId].x0_parentId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +112,7 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor
|
||||||
for (CSegId* id=&buildIDs[idCount] ; id != buildIDs ; --id)
|
for (CSegId* id=&buildIDs[idCount] ; id != buildIDs ; --id)
|
||||||
{
|
{
|
||||||
CSegId& thisId = id[-1];
|
CSegId& thisId = id[-1];
|
||||||
const CTreeNode& node = x6c_nodes[thisId];
|
const CTreeNode& node = x0_treeMap[thisId];
|
||||||
accumRot *= node.x4_rotation;
|
accumRot *= node.x4_rotation;
|
||||||
accumPos += accumXF * node.x14_offset;
|
accumPos += accumXF * node.x14_offset;
|
||||||
if (scale == 1.f)
|
if (scale == 1.f)
|
||||||
|
@ -132,7 +128,7 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor
|
||||||
void CHierarchyPoseBuilder::BuildNoScale(CPoseAsTransforms& pose)
|
void CHierarchyPoseBuilder::BuildNoScale(CPoseAsTransforms& pose)
|
||||||
{
|
{
|
||||||
pose.Clear();
|
pose.Clear();
|
||||||
const CTreeNode& node = x6c_nodes[xcec_rootId];
|
const CTreeNode& node = x0_treeMap[xcec_rootId];
|
||||||
zeus::CQuaternion quat;
|
zeus::CQuaternion quat;
|
||||||
zeus::CMatrix3f mtx;
|
zeus::CMatrix3f mtx;
|
||||||
zeus::CVector3f vec;
|
zeus::CVector3f vec;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __URDE_CHIERARCHYPOSEBUILDER_HPP__
|
#define __URDE_CHIERARCHYPOSEBUILDER_HPP__
|
||||||
|
|
||||||
#include "CSegId.hpp"
|
#include "CSegId.hpp"
|
||||||
|
#include "TSegIdMap.hpp"
|
||||||
#include "zeus/CQuaternion.hpp"
|
#include "zeus/CQuaternion.hpp"
|
||||||
#include "CLayoutDescription.hpp"
|
#include "CLayoutDescription.hpp"
|
||||||
|
|
||||||
|
@ -13,10 +14,6 @@ class CPoseAsTransforms;
|
||||||
|
|
||||||
class CHierarchyPoseBuilder
|
class CHierarchyPoseBuilder
|
||||||
{
|
{
|
||||||
CSegId x0_boneCount = 0;
|
|
||||||
CSegId x1_curPrevBone = 0;
|
|
||||||
CSegId x8_prevBones[100];
|
|
||||||
|
|
||||||
struct CTreeNode
|
struct CTreeNode
|
||||||
{
|
{
|
||||||
CSegId x0_child = 0;
|
CSegId x0_child = 0;
|
||||||
|
@ -26,7 +23,8 @@ class CHierarchyPoseBuilder
|
||||||
CTreeNode() = default;
|
CTreeNode() = default;
|
||||||
CTreeNode(const zeus::CVector3f& offset) : x14_offset(offset) {}
|
CTreeNode(const zeus::CVector3f& offset) : x14_offset(offset) {}
|
||||||
};
|
};
|
||||||
CTreeNode x6c_nodes[100];
|
TSegIdMap<CTreeNode> x0_treeMap;
|
||||||
|
|
||||||
CSegId xcec_rootId;
|
CSegId xcec_rootId;
|
||||||
bool xcf0_hasRoot = false;
|
bool xcf0_hasRoot = false;
|
||||||
CLayoutDescription xcf4_layoutDesc;
|
CLayoutDescription xcf4_layoutDesc;
|
||||||
|
|
|
@ -71,6 +71,8 @@ add_library(RuntimeCommonCharacter
|
||||||
CAnimSource.hpp CAnimSource.cpp
|
CAnimSource.hpp CAnimSource.cpp
|
||||||
CAllFormatsAnimSource.hpp CAllFormatsAnimSource.cpp
|
CAllFormatsAnimSource.hpp CAllFormatsAnimSource.cpp
|
||||||
CSegStatementSet.hpp CSegStatementSet.cpp
|
CSegStatementSet.hpp CSegStatementSet.cpp
|
||||||
|
CAnimPerSegmentData.hpp
|
||||||
|
CAdditiveAnimPlayback.hpp CAdditiveAnimPlayback.cpp
|
||||||
CActorLights.hpp CActorLights.cpp
|
CActorLights.hpp CActorLights.cpp
|
||||||
CAnimSysContext.hpp
|
CAnimSysContext.hpp
|
||||||
CBodyState.hpp)
|
CBodyState.hpp)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "GameGlobalObjects.hpp"
|
#include "GameGlobalObjects.hpp"
|
||||||
#include "CAssetFactory.hpp"
|
#include "CAssetFactory.hpp"
|
||||||
#include "CCharacterFactory.hpp"
|
#include "CCharacterFactory.hpp"
|
||||||
|
#include "CAdditiveAnimPlayback.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "CSegStatementSet.hpp"
|
||||||
|
#include "CSegIdList.hpp"
|
||||||
|
#include "CCharLayoutInfo.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
void CSegStatementSet::Add(const CSegIdList& list, const CCharLayoutInfo& layout,
|
||||||
|
const CSegStatementSet& other, float weight)
|
||||||
|
{
|
||||||
|
for (const CSegId& id : list.GetList())
|
||||||
|
{
|
||||||
|
x4_segData[id].x0_rotation *= zeus::CQuaternion::slerp(zeus::CQuaternion::skNoRotation,
|
||||||
|
other.x4_segData[id].x0_rotation, weight);
|
||||||
|
if (other.x4_segData[id].x1c_hasOffset && x4_segData[id].x1c_hasOffset)
|
||||||
|
{
|
||||||
|
zeus::CVector3f off = other.x4_segData[id].x10_offset - layout.GetFromParentUnrotated(id);
|
||||||
|
x4_segData[id].x10_offset += off * weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,21 @@
|
||||||
#ifndef __URDE_CSEGSTATEMENTSET_HPP__
|
#ifndef __URDE_CSEGSTATEMENTSET_HPP__
|
||||||
#define __URDE_CSEGSTATEMENTSET_HPP__
|
#define __URDE_CSEGSTATEMENTSET_HPP__
|
||||||
|
|
||||||
|
#include "CAnimPerSegmentData.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
class CSegIdList;
|
||||||
|
class CCharLayoutInfo;
|
||||||
|
|
||||||
class CSegStatementSet
|
class CSegStatementSet
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
/* Used to be a pointer to arbitrary subclass-provided storage,
|
||||||
|
* now it's a self-stored array */
|
||||||
|
CAnimPerSegmentData x4_segData[100];
|
||||||
|
void Add(const CSegIdList& list, const CCharLayoutInfo& layout,
|
||||||
|
const CSegStatementSet& other, float weight);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,13 @@ struct SAdvancementResults
|
||||||
SAdvancementDeltas x8_deltas;
|
SAdvancementDeltas x8_deltas;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CSteadyStateAnimInfo
|
||||||
|
{
|
||||||
|
CCharAnimTime x64_duration;
|
||||||
|
zeus::CVector3f x6c_curRootOffset;
|
||||||
|
bool x78_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
class IAnimReader
|
class IAnimReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -36,7 +43,7 @@ public:
|
||||||
virtual bool IsCAnimTreeNode() const {return false;}
|
virtual bool IsCAnimTreeNode() const {return false;}
|
||||||
virtual SAdvancementResults VAdvanceView(const CCharAnimTime& a)=0;
|
virtual SAdvancementResults VAdvanceView(const CCharAnimTime& a)=0;
|
||||||
virtual CCharAnimTime VGetTimeRemaining() const=0;
|
virtual CCharAnimTime VGetTimeRemaining() const=0;
|
||||||
virtual void VGetSteadyStateAnimInfo() const=0;
|
virtual CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const=0;
|
||||||
virtual bool VHasOffset(const CSegId& seg) const=0;
|
virtual bool VHasOffset(const CSegId& seg) const=0;
|
||||||
virtual zeus::CVector3f VGetOffset(const CSegId& seg) const=0;
|
virtual zeus::CVector3f VGetOffset(const CSegId& seg) const=0;
|
||||||
virtual zeus::CQuaternion VGetRotation(const CSegId& seg) const=0;
|
virtual zeus::CQuaternion VGetRotation(const CSegId& seg) const=0;
|
||||||
|
|
|
@ -10,9 +10,46 @@ namespace urde
|
||||||
template <class T>
|
template <class T>
|
||||||
class TSegIdMap
|
class TSegIdMap
|
||||||
{
|
{
|
||||||
std::map<CSegId, T> x0_map;
|
CSegId x0_boneCount = 0;
|
||||||
|
CSegId x1_curPrevBone = 0;
|
||||||
|
u32 x4_capacity = 100;
|
||||||
|
CSegId x8_prevBones[100];
|
||||||
|
T x6c_bones[100];
|
||||||
public:
|
public:
|
||||||
const T& AccessElement(const CSegId& id) const {return x0_map[id];}
|
T& operator[](const CSegId& id) {return SetElement(id);}
|
||||||
|
const T& operator[](const CSegId& id) const {return x6c_bones[id];}
|
||||||
|
T& SetElement(const CSegId& id, T&& obj)
|
||||||
|
{
|
||||||
|
x6c_bones[id] = std::move(obj);
|
||||||
|
if (x8_prevBones[id] == 0xff)
|
||||||
|
{
|
||||||
|
x8_prevBones[id] = x1_curPrevBone;
|
||||||
|
x1_curPrevBone = id;
|
||||||
|
++x0_boneCount;
|
||||||
|
}
|
||||||
|
return x6c_bones[id];
|
||||||
|
}
|
||||||
|
T& SetElement(const CSegId& id)
|
||||||
|
{
|
||||||
|
if (x8_prevBones[id] == 0xff)
|
||||||
|
{
|
||||||
|
x8_prevBones[id] = x1_curPrevBone;
|
||||||
|
x1_curPrevBone = id;
|
||||||
|
++x0_boneCount;
|
||||||
|
}
|
||||||
|
return x6c_bones[id];
|
||||||
|
}
|
||||||
|
void DelElement(const CSegId& id)
|
||||||
|
{
|
||||||
|
if (x8_prevBones[id] != 0xff)
|
||||||
|
{
|
||||||
|
if (id == x1_curPrevBone)
|
||||||
|
x1_curPrevBone = x8_prevBones[id];
|
||||||
|
x8_prevBones[id] = 0xff;
|
||||||
|
--x0_boneCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool HasElement(const CSegId& id) const {return x8_prevBones[id] != 0xff;}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
2
specter
2
specter
|
@ -1 +1 @@
|
||||||
Subproject commit e40a836ea15a2a2c06a2a8c8ba511db23d4395de
|
Subproject commit 36cd3fbf9dafdd9c83268593dfcd905edea32a9a
|
Loading…
Reference in New Issue