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 "Runtime/IObj.hpp"
|
||||
|
||||
#define DUMP_CACHE_FILL 1
|
||||
|
||||
namespace urde
|
||||
{
|
||||
static logvisor::Module Log("urde::ProjectResourceFactoryBase");
|
||||
|
@ -93,6 +95,15 @@ static void WriteTag(athena::io::YAMLDocWriter& cacheWriter,
|
|||
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,
|
||||
athena::io::YAMLDocWriter& cacheWriter,
|
||||
athena::io::YAMLDocWriter& nameWriter,
|
||||
|
@ -127,10 +138,8 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
|||
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
||||
m_tagToPath[pathTag] = path;
|
||||
WriteTag(cacheWriter, pathTag, path);
|
||||
#if 1
|
||||
fprintf(stderr, "%s %08X %s\n",
|
||||
pathTag.type.toString().c_str(), uint32_t(pathTag.id),
|
||||
path.getRelativePathUTF8().c_str());
|
||||
#if DUMP_CACHE_FILL
|
||||
DumpCacheAdd(pathTag, path);
|
||||
#endif
|
||||
|
||||
/* Special multi-resource intermediates */
|
||||
|
@ -150,11 +159,11 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
|||
hecl::SystemStringView sysStr(arm);
|
||||
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("CINF"));
|
||||
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
||||
if (pathTag)
|
||||
{
|
||||
m_tagToPath[pathTag] = path;
|
||||
WriteTag(cacheWriter, pathTag, path);
|
||||
}
|
||||
m_tagToPath[pathTag] = subPath;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
#if DUMP_CACHE_FILL
|
||||
DumpCacheAdd(pathTag, subPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (const std::string& sub : subtypeNames)
|
||||
|
@ -162,11 +171,11 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
|||
hecl::SystemStringView sysStr(sub);
|
||||
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("CSKR"));
|
||||
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
||||
if (pathTag)
|
||||
{
|
||||
m_tagToPath[pathTag] = path;
|
||||
WriteTag(cacheWriter, pathTag, path);
|
||||
}
|
||||
m_tagToPath[pathTag] = subPath;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
#if DUMP_CACHE_FILL
|
||||
DumpCacheAdd(pathTag, subPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (const std::string& act : actionNames)
|
||||
|
@ -174,11 +183,11 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
|||
hecl::SystemStringView sysStr(act);
|
||||
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("ANIM"));
|
||||
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
||||
if (pathTag)
|
||||
{
|
||||
m_tagToPath[pathTag] = path;
|
||||
WriteTag(cacheWriter, pathTag, path);
|
||||
}
|
||||
m_tagToPath[pathTag] = subPath;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
#if DUMP_CACHE_FILL
|
||||
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
|
||||
{
|
||||
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))
|
||||
{
|
||||
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 "CAnimationManager.hpp"
|
||||
#include "CTransitionManager.hpp"
|
||||
#include "CAdditiveAnimPlayback.hpp"
|
||||
#include "IAnimReader.hpp"
|
||||
|
||||
namespace urde
|
||||
|
@ -46,8 +47,9 @@ CAnimData::CAnimData(ResId id,
|
|||
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)
|
||||
|
|
|
@ -36,6 +36,7 @@ class CSkinRules;
|
|||
class CAnimTreeNode;
|
||||
class CSegIdList;
|
||||
class CSegStatementSet;
|
||||
class CAdditiveAnimPlayback;
|
||||
struct SAdvancementDeltas;
|
||||
|
||||
class CAnimData
|
||||
|
@ -96,7 +97,7 @@ class CAnimData
|
|||
u32 x1038_ = 0;
|
||||
u32 x103c_ = 0;
|
||||
u32 x1040_ = 0;
|
||||
u32 x1044_ = 0;
|
||||
rstl::reserved_vector<std::pair<u32, CAdditiveAnimPlayback>, 8> x1044_additiveAnims;
|
||||
|
||||
public:
|
||||
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 "CAnimPOIData.hpp"
|
||||
#include "CSegId.hpp"
|
||||
#include "CSegIdList.hpp"
|
||||
#include "CSegStatementSet.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -148,7 +150,37 @@ void CAnimSource::GetSegStatementSet(const CSegIdList& list,
|
|||
if (std::fabs(remTime) < 0.00001f)
|
||||
remTime = 0.f;
|
||||
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
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
const std::vector<CParticlePOINode>& GetParticlePOIStream() const;
|
||||
const std::vector<CInt32POINode>& GetInt32POIStream() 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::CVector3f GetOffset(const CSegId& seg, const CCharAnimTime& time) const;
|
||||
bool HasOffset(const CSegId& seg) const;
|
||||
|
|
|
@ -241,61 +241,210 @@ CAnimSourceReaderBase::CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&&
|
|||
const CCharAnimTime& time)
|
||||
: x4_sourceInfo(std::move(sourceInfo)), xc_curTime(time) {}
|
||||
|
||||
SAdvancementResults CAnimSourceReader::VGetAdvancementResults(const CCharAnimTime& a,
|
||||
const CCharAnimTime& b) const
|
||||
CAnimSourceReaderBase::CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
|
||||
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
|
||||
{
|
||||
return std::make_shared<CAnimSourceReader>(*this);
|
||||
}
|
||||
|
||||
void CAnimSourceReader::VGetSegStatementSet(const CSegIdList& list,
|
||||
CSegStatementSet& setOut) const
|
||||
{
|
||||
x54_source->GetSegStatementSet(list, setOut, xc_curTime);
|
||||
}
|
||||
|
||||
void CAnimSourceReader::VGetSegStatementSet(const CSegIdList& list,
|
||||
CSegStatementSet& setOut,
|
||||
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
|
||||
{
|
||||
return x54_source->GetDuration() - xc_curTime;
|
||||
}
|
||||
|
||||
void CAnimSourceReader::VGetSteadyStateAnimInfo() const
|
||||
CSteadyStateAnimInfo CAnimSourceReader::VGetSteadyStateAnimInfo() const
|
||||
{
|
||||
return x64_steadyStateInfo;
|
||||
}
|
||||
|
||||
bool CAnimSourceReader::VHasOffset(const CSegId& seg) const
|
||||
{
|
||||
return x54_source->HasOffset(seg);
|
||||
}
|
||||
|
||||
zeus::CVector3f CAnimSourceReader::VGetOffset(const CSegId& seg) const
|
||||
{
|
||||
return x54_source->GetOffset(seg, xc_curTime);
|
||||
}
|
||||
|
||||
zeus::CVector3f CAnimSourceReader::VGetOffset(const CSegId& seg,
|
||||
const CCharAnimTime& time) const
|
||||
{
|
||||
return x54_source->GetOffset(seg, time);
|
||||
}
|
||||
|
||||
zeus::CQuaternion CAnimSourceReader::VGetRotation(const CSegId& seg) const
|
||||
{
|
||||
return x54_source->GetRotation(seg, xc_curTime);
|
||||
}
|
||||
|
||||
CAnimSourceReader::CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source,
|
||||
|
@ -304,10 +453,15 @@ CAnimSourceReader::CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& sourc
|
|||
x54_source(source)
|
||||
{
|
||||
CAnimSource* sourceData = x54_source.GetObj();
|
||||
x64_duration = sourceData->GetDuration();
|
||||
x6c_curRootOffset = sourceData->GetOffset(sourceData->GetRootBoneId(), time);
|
||||
x64_steadyStateInfo.x64_duration = sourceData->GetDuration();
|
||||
x64_steadyStateInfo.x6c_curRootOffset = sourceData->GetOffset(sourceData->GetRootBoneId(), 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
|
||||
{
|
||||
protected:
|
||||
std::unique_ptr<IAnimSourceInfo> x4_sourceInfo;
|
||||
CCharAnimTime xc_curTime;
|
||||
u32 x14_passedBoolCount = 0;
|
||||
|
@ -56,11 +57,13 @@ class CAnimSourceReaderBase : public IAnimReader
|
|||
protected:
|
||||
void PostConstruct(const CCharAnimTime& time);
|
||||
void UpdatePOIStates();
|
||||
|
||||
CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
|
||||
const CAnimSourceReaderBase& other);
|
||||
public:
|
||||
CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
|
||||
const CCharAnimTime& time);
|
||||
|
||||
|
||||
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 VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||
|
@ -77,11 +80,10 @@ public:
|
|||
class CAnimSourceReader : public CAnimSourceReaderBase
|
||||
{
|
||||
TSubAnimTypeToken<CAnimSource> x54_source;
|
||||
CCharAnimTime x64_duration;
|
||||
zeus::CVector3f x6c_curRootOffset;
|
||||
bool x78_ = false;
|
||||
CSteadyStateAnimInfo x64_steadyStateInfo;
|
||||
public:
|
||||
CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source, const CCharAnimTime& time);
|
||||
CAnimSourceReader(const CAnimSourceReader& other);
|
||||
|
||||
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
|
||||
bool VSupportsReverseView() const {return true;}
|
||||
|
@ -92,7 +94,7 @@ public:
|
|||
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
|
||||
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
|
||||
CCharAnimTime VGetTimeRemaining() const;
|
||||
void VGetSteadyStateAnimInfo() const;
|
||||
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
|
||||
bool VHasOffset(const CSegId& seg) const;
|
||||
zeus::CVector3f VGetOffset(const CSegId& seg) const;
|
||||
zeus::CVector3f VGetOffset(const CSegId& seg, const CCharAnimTime& time) const;
|
||||
|
|
|
@ -5,24 +5,11 @@
|
|||
#include "CAnimation.hpp"
|
||||
#include "CTransition.hpp"
|
||||
#include "CHalfTransition.hpp"
|
||||
#include "CAdditiveAnimPlayback.hpp"
|
||||
|
||||
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
|
||||
{
|
||||
u16 x0_tableCount;
|
||||
|
|
|
@ -6,13 +6,12 @@ namespace urde
|
|||
|
||||
zeus::CVector3f CCharLayoutInfo::GetFromParentUnrotated(const CSegId& id) const
|
||||
{
|
||||
const CCharLayoutNode::Bone& bone = x0_node->GetBone(id);
|
||||
const CSegId& prev = x0_node->GetPrevBone(bone.x0_parentId);
|
||||
if (prev == 0xff)
|
||||
const CCharLayoutNode::Bone& bone = x0_node->GetBoneMap()[id];
|
||||
if (!x0_node->GetBoneMap().HasElement(bone.x0_parentId))
|
||||
return bone.x4_origin;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -34,11 +33,8 @@ CCharLayoutNode::CCharLayoutNode(CInputStream& in)
|
|||
for (u32 i=0 ; i<count ; ++i)
|
||||
{
|
||||
u32 thisId = in.readUint32Big();
|
||||
Bone& bone = x6c_bones[thisId];
|
||||
Bone& bone = x0_boneMap[thisId];
|
||||
bone.read(in);
|
||||
x8_prevBones[thisId] = x1_curPrevBone;
|
||||
x1_curPrevBone = thisId;
|
||||
++x0_boneCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "IOStreams.hpp"
|
||||
#include "CSegIdList.hpp"
|
||||
#include "CSegId.hpp"
|
||||
#include "TSegIdMap.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -20,15 +21,10 @@ public:
|
|||
void read(CInputStream& in);
|
||||
};
|
||||
private:
|
||||
CSegId x0_boneCount = 0;
|
||||
CSegId x1_curPrevBone = 0;
|
||||
CSegId x8_prevBones[100];
|
||||
Bone x6c_bones[100];
|
||||
TSegIdMap<Bone> x0_boneMap;
|
||||
public:
|
||||
CCharLayoutNode(CInputStream& in);
|
||||
|
||||
const Bone& GetBone(const CSegId& id) const {return x6c_bones[id];}
|
||||
const CSegId& GetPrevBone(const CSegId& id) const {return x8_prevBones[id];}
|
||||
const TSegIdMap<Bone>& GetBoneMap() const {return x0_boneMap;}
|
||||
};
|
||||
|
||||
class CCharLayoutInfo
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "CRandom16.hpp"
|
||||
#include "CPrimitive.hpp"
|
||||
#include "CAnimData.hpp"
|
||||
#include "CAdditiveAnimPlayback.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "Graphics/CSkinnedModel.hpp"
|
||||
|
||||
|
|
|
@ -8,30 +8,26 @@ namespace urde
|
|||
void CHierarchyPoseBuilder::BuildIntoHierarchy(const CCharLayoutInfo& layout,
|
||||
const CSegId& boneId, const CSegId& nullId)
|
||||
{
|
||||
const CSegId& idA = x8_prevBones[boneId];
|
||||
if (idA == 0xff)
|
||||
if (!x0_treeMap.HasElement(boneId))
|
||||
{
|
||||
const CCharLayoutNode::Bone& bone = layout.GetRootNode()->GetBone(boneId);
|
||||
const CCharLayoutNode::Bone& bone = layout.GetRootNode()->GetBoneMap()[boneId];
|
||||
if (bone.x0_parentId == nullId)
|
||||
{
|
||||
xcec_rootId = boneId;
|
||||
xcf0_hasRoot = true;
|
||||
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
|
||||
x6c_nodes[boneId] = CTreeNode(origin);
|
||||
x0_treeMap[boneId] = CTreeNode(origin);
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildIntoHierarchy(layout, bone.x0_parentId, nullId);
|
||||
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
|
||||
CTreeNode& pNode = x6c_nodes[bone.x0_parentId];
|
||||
CTreeNode& pNode = x0_treeMap[bone.x0_parentId];
|
||||
CTreeNode node(origin);
|
||||
node.x1_sibling = pNode.x0_child;
|
||||
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;
|
||||
while (curBone != 0)
|
||||
{
|
||||
const CTreeNode& node = x6c_nodes[curBone];
|
||||
const CTreeNode& node = x0_treeMap[curBone];
|
||||
RecursivelyBuild(curBone, node, pose, quat, xf, xfOffset);
|
||||
curBone = node.x1_sibling;
|
||||
}
|
||||
|
@ -77,7 +73,7 @@ void CHierarchyPoseBuilder::RecursivelyBuild(const CSegId& boneId, const CTreeNo
|
|||
CSegId curBone = node.x0_child;
|
||||
while (curBone != 0)
|
||||
{
|
||||
const CTreeNode& node = x6c_nodes[curBone];
|
||||
const CTreeNode& node = x0_treeMap[curBone];
|
||||
RecursivelyBuild(curBone, node, pose, quat, quat, xfOffset);
|
||||
curBone = node.x1_sibling;
|
||||
}
|
||||
|
@ -106,7 +102,7 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor
|
|||
while (curId != 2)
|
||||
{
|
||||
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)
|
||||
{
|
||||
CSegId& thisId = id[-1];
|
||||
const CTreeNode& node = x6c_nodes[thisId];
|
||||
const CTreeNode& node = x0_treeMap[thisId];
|
||||
accumRot *= node.x4_rotation;
|
||||
accumPos += accumXF * node.x14_offset;
|
||||
if (scale == 1.f)
|
||||
|
@ -132,7 +128,7 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor
|
|||
void CHierarchyPoseBuilder::BuildNoScale(CPoseAsTransforms& pose)
|
||||
{
|
||||
pose.Clear();
|
||||
const CTreeNode& node = x6c_nodes[xcec_rootId];
|
||||
const CTreeNode& node = x0_treeMap[xcec_rootId];
|
||||
zeus::CQuaternion quat;
|
||||
zeus::CMatrix3f mtx;
|
||||
zeus::CVector3f vec;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __URDE_CHIERARCHYPOSEBUILDER_HPP__
|
||||
|
||||
#include "CSegId.hpp"
|
||||
#include "TSegIdMap.hpp"
|
||||
#include "zeus/CQuaternion.hpp"
|
||||
#include "CLayoutDescription.hpp"
|
||||
|
||||
|
@ -13,10 +14,6 @@ class CPoseAsTransforms;
|
|||
|
||||
class CHierarchyPoseBuilder
|
||||
{
|
||||
CSegId x0_boneCount = 0;
|
||||
CSegId x1_curPrevBone = 0;
|
||||
CSegId x8_prevBones[100];
|
||||
|
||||
struct CTreeNode
|
||||
{
|
||||
CSegId x0_child = 0;
|
||||
|
@ -26,7 +23,8 @@ class CHierarchyPoseBuilder
|
|||
CTreeNode() = default;
|
||||
CTreeNode(const zeus::CVector3f& offset) : x14_offset(offset) {}
|
||||
};
|
||||
CTreeNode x6c_nodes[100];
|
||||
TSegIdMap<CTreeNode> x0_treeMap;
|
||||
|
||||
CSegId xcec_rootId;
|
||||
bool xcf0_hasRoot = false;
|
||||
CLayoutDescription xcf4_layoutDesc;
|
||||
|
|
|
@ -71,6 +71,8 @@ add_library(RuntimeCommonCharacter
|
|||
CAnimSource.hpp CAnimSource.cpp
|
||||
CAllFormatsAnimSource.hpp CAllFormatsAnimSource.cpp
|
||||
CSegStatementSet.hpp CSegStatementSet.cpp
|
||||
CAnimPerSegmentData.hpp
|
||||
CAdditiveAnimPlayback.hpp CAdditiveAnimPlayback.cpp
|
||||
CActorLights.hpp CActorLights.cpp
|
||||
CAnimSysContext.hpp
|
||||
CBodyState.hpp)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "GameGlobalObjects.hpp"
|
||||
#include "CAssetFactory.hpp"
|
||||
#include "CCharacterFactory.hpp"
|
||||
#include "CAdditiveAnimPlayback.hpp"
|
||||
|
||||
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__
|
||||
#define __URDE_CSEGSTATEMENTSET_HPP__
|
||||
|
||||
#include "CAnimPerSegmentData.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CSegIdList;
|
||||
class CCharLayoutInfo;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct CSteadyStateAnimInfo
|
||||
{
|
||||
CCharAnimTime x64_duration;
|
||||
zeus::CVector3f x6c_curRootOffset;
|
||||
bool x78_ = false;
|
||||
};
|
||||
|
||||
class IAnimReader
|
||||
{
|
||||
public:
|
||||
|
@ -36,7 +43,7 @@ public:
|
|||
virtual bool IsCAnimTreeNode() const {return false;}
|
||||
virtual SAdvancementResults VAdvanceView(const CCharAnimTime& a)=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 zeus::CVector3f VGetOffset(const CSegId& seg) const=0;
|
||||
virtual zeus::CQuaternion VGetRotation(const CSegId& seg) const=0;
|
||||
|
|
|
@ -10,9 +10,46 @@ namespace urde
|
|||
template <class T>
|
||||
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:
|
||||
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