Initial CAnimData implementation and other support classes

This commit is contained in:
Jack Andersen 2016-04-12 12:28:08 -10:00
parent 14e0468adf
commit 795b77fe48
29 changed files with 367 additions and 81 deletions

View File

@ -1093,9 +1093,8 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
/* Set Character Resource IDs */
for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(ch.cmdl);
if (path)
ch.cskr = path.ensureAuxInfo(_S("skin"));
hecl::SystemStringView chSysName(ch.name);
ch.cskr = inPath.getWithExtension((_S('.') + chSysName.sys_str()).c_str(), true).ensureAuxInfo(_S("CSKR"));
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes)
{
@ -1104,23 +1103,21 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
if (sub.armature >= 0)
{
const DNAANCS::Actor::Armature& arm = actor.armatures[sub.armature];
hecl::SystemStringView chSysName(arm.name);
ch.cinf = inPath.ensureAuxInfo(chSysName.c_str());
hecl::SystemStringView armSysName(arm.name);
ch.cinf = inPath.getWithExtension((_S('.') + armSysName.sys_str()).c_str(), true).ensureAuxInfo(_S("CINF"));
break;
}
}
}
path = UniqueIDBridge::TranslatePakIdToPath(ch.cmdlOverlay);
if (path)
ch.cskrOverlay = path.ensureAuxInfo(_S("skin"));
ch.cskrOverlay = inPath.getWithExtension((_S('.') + chSysName.sys_str() + _S(".over")).c_str(), true).ensureAuxInfo(_S("CSKR"));
}
/* Set Animation Resource IDs */
ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) -> bool
{
hecl::SystemStringView sysStr(prim.animName);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("ANIM"));
prim.animId = pathOut;
return true;
});
@ -1131,7 +1128,7 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
for (const DNAANCS::Actor::Armature& arm : actor.armatures)
{
hecl::SystemStringView sysStr(arm.name);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("CINF"));
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
@ -1143,15 +1140,15 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
/* Write out CSKR resources */
for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(ch.cmdl);
hecl::ProjectPath modelPath = UniqueIDBridge::TranslatePakIdToPath(ch.cmdl);
if (path.getPathType() != hecl::ProjectPath::Type::File)
Log.report(logvisor::Fatal, _S("unable to resolve '%s'"), path.getRelativePath().c_str());
if (modelPath.getPathType() != hecl::ProjectPath::Type::File)
Log.report(logvisor::Fatal, _S("unable to resolve '%s'"), modelPath.getRelativePath().c_str());
hecl::ProjectPath skinIntPath = path.getCookedPath(SpecEntMP1PC).getWithExtension(_S(".skinint"));
if (skinIntPath.getModtime() < path.getModtime())
if (!modelCookFunc(path))
Log.report(logvisor::Fatal, _S("unable to cook '%s'"), path.getRelativePath().c_str());
hecl::ProjectPath skinIntPath = modelPath.getCookedPath(SpecEntMP1PC).getWithExtension(_S(".skinint"));
if (skinIntPath.getModtime() < modelPath.getModtime())
if (!modelCookFunc(modelPath))
Log.report(logvisor::Fatal, _S("unable to cook '%s'"), modelPath.getRelativePath().c_str());
athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024*32, false);
if (skinIO.hasError())
@ -1181,7 +1178,8 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
skinIO.close();
hecl::ProjectPath skinPath = path.getCookedPath(SpecEntMP1PC).getWithExtension(_S(".skin"));
hecl::SystemStringView sysStr(ch.name);
hecl::ProjectPath skinPath = inPath.getCookedPath(SpecEntMP1PC).getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("CSKR"));
athena::io::FileWriter skinOut(skinPath.getAbsolutePath(), true, false);
if (skinOut.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
@ -1208,7 +1206,7 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
for (const DNAANCS::Actor::Action& act : actor.actions)
{
hecl::SystemStringView sysStr(act.name);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("ANIM"));
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),

View File

@ -134,17 +134,7 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
#endif
/* Special multi-resource intermediates */
if (pathTag.type == SBIG('CMDL'))
{
hecl::ProjectPath subPath(path, ".|skin");
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
if (pathTag)
{
m_tagToPath[pathTag] = path;
WriteTag(cacheWriter, pathTag, path);
}
}
else if (pathTag.type == SBIG('ANCS'))
if (pathTag.type == SBIG('ANCS'))
{
hecl::BlenderConnection& conn = m_backgroundBlender.getBlenderConnection();
if (!conn.openBlend(path) || conn.getBlendType() != hecl::BlenderConnection::BlendType::Actor)
@ -152,12 +142,25 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
hecl::BlenderConnection::DataStream ds = conn.beginData();
std::vector<std::string> armatureNames = ds.getArmatureNames();
std::vector<std::string> subtypeNames = ds.getSubtypeNames();
std::vector<std::string> actionNames = ds.getActionNames();
for (const std::string& arm : armatureNames)
{
hecl::SystemStringView sysStr(arm);
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
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);
}
}
for (const std::string& sub : subtypeNames)
{
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)
{
@ -169,7 +172,7 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
for (const std::string& act : actionNames)
{
hecl::SystemStringView sysStr(act);
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true).ensureAuxInfo(_S("ANIM"));
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
if (pathTag)
{

View File

@ -10,6 +10,7 @@
#include "Runtime/Graphics/CModel.hpp"
#include "Runtime/Graphics/CTexture.hpp"
#include "Runtime/Character/CCharLayoutInfo.hpp"
#include "Runtime/Character/CSkinRules.hpp"
#include "Runtime/Character/CAnimCharacterSet.hpp"
#include "Runtime/Character/CAllFormatsAnimSource.hpp"
#include "Runtime/Character/CAnimPOIData.hpp"
@ -34,6 +35,7 @@ ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& client
m_factoryMgr.AddFactory(FOURCC('FONT'), FFactoryFunc(FRasterFontFactory));
m_factoryMgr.AddFactory(FOURCC('CMDL'), FMemFactoryFunc(FModelFactory));
m_factoryMgr.AddFactory(FOURCC('CINF'), FFactoryFunc(FCharLayoutInfo));
m_factoryMgr.AddFactory(FOURCC('CSKR'), FFactoryFunc(FSkinRulesFactory));
m_factoryMgr.AddFactory(FOURCC('ANCS'), FFactoryFunc(FAnimCharacterSet));
m_factoryMgr.AddFactory(FOURCC('ANIM'), FFactoryFunc(AnimSourceFactory));
m_factoryMgr.AddFactory(FOURCC('EVNT'), FFactoryFunc(AnimPOIDataFactory));
@ -56,16 +58,17 @@ SObjectTag ProjectResourceFactoryMP1::TagFromPath(const hecl::ProjectPath& path,
switch (conn.getBlendType())
{
case hecl::BlenderConnection::BlendType::Mesh:
if (!path.getAuxInfo().compare(_S("skin")))
{
if (!conn.getRigged())
return {};
return {SBIG('CSKR'), path.hash().val32()};
}
return {SBIG('CMDL'), path.hash().val32()};
case hecl::BlenderConnection::BlendType::Actor:
if (path.getAuxInfo().size())
{
if (!path.getAuxInfo().compare(_S("CINF")))
return {SBIG('CINF'), path.hash().val32()};
else if (!path.getAuxInfo().compare(_S("CSKR")))
return {SBIG('CSKR'), path.hash().val32()};
else if (!path.getAuxInfo().compare(_S("ANIM")))
return {SBIG('ANIM'), path.hash().val32()};
}
return {SBIG('ANCS'), path.hash().val32()};
case hecl::BlenderConnection::BlendType::Area:
return {SBIG('MREA'), path.hash().val32()};

View File

@ -0,0 +1,35 @@
#include "CAnimData.hpp"
#include "CCharacterInfo.hpp"
#include "CCharLayoutInfo.hpp"
#include "Graphics/CSkinnedModel.hpp"
#include "CCharacterFactory.hpp"
#include "CAnimationManager.hpp"
#include "CTransitionManager.hpp"
namespace urde
{
CAnimData::CAnimData(TResId id, const CCharacterInfo& character, int a, int b, bool c,
const TLockedToken<CCharLayoutInfo>& layout,
const TToken<CSkinnedModel>& model,
const std::weak_ptr<CAnimSysContext>& ctx,
const std::shared_ptr<CAnimationManager>& animMgr,
const std::shared_ptr<CTransitionManager>& transMgr,
const TLockedToken<CCharacterFactory>& charFactory)
: x0_charFactory(charFactory),
xc_charInfo(character),
xcc_layoutData(layout),
xd8_modelData(model),
xfc_animCtx(ctx.lock()),
x100_animMgr(animMgr),
x1d8_selfId(id),
x1fc_transMgr(transMgr),
x204_b(b),
x208_a(a),
x21c_25_c(c),
x220_pose(layout->GetSegIdList().GetList().size()),
x2f8_poseBuilder(layout)
{
}
}

View File

@ -1,12 +1,108 @@
#ifndef __PSHAG_CANIMDATA_HPP__
#define __PSHAG_CANIMDATA_HPP__
#include "RetroTypes.hpp"
#include "CToken.hpp"
#include "CCharacterInfo.hpp"
#include "CParticleDatabase.hpp"
#include "CPoseAsTransforms.hpp"
#include "CHierarchyPoseBuilder.hpp"
#include "optional.hpp"
namespace urde
{
class CCharLayoutInfo;
class CSkinnedModel;
class CAnimSysContext;
class CAnimationManager;
class CTransitionManager;
class CCharacterFactory;
class IMetaAnim;
class CLayoutDescription
{
public:
class CScaledLayoutDescription
{
TLockedToken<CCharLayoutInfo> x0_layoutToken;
float xc_scale;
std::experimental::optional<zeus::CVector3f> x10_scaleVec;
};
private:
TLockedToken<CCharLayoutInfo> x0_layoutToken;
std::experimental::optional<CScaledLayoutDescription> xc_scaled;
public:
CLayoutDescription(const TLockedToken<CCharLayoutInfo>& token)
: x0_layoutToken(token) {}
};
class CAnimData
{
TLockedToken<CCharacterFactory> x0_charFactory;
CCharacterInfo xc_charInfo;
TLockedToken<CCharLayoutInfo> xcc_layoutData;
TCachedToken<CSkinnedModel> xd8_modelData;
// TLockedToken<CSkinnedModelWithAvgNormals> xe4_modelAvgNormalData;
std::shared_ptr<CSkinnedModel> xf4_xrayModel;
std::shared_ptr<CSkinnedModel> xf8_infraModel;
std::shared_ptr<CAnimSysContext> xfc_animCtx;
std::shared_ptr<CAnimationManager> x100_animMgr;
u32 x104_ = 0;
zeus::CAABox x108_aabb;
CParticleDatabase x120_particleDB;
TResId x1d8_selfId;
zeus::CVector3f x1dc_;
zeus::CQuaternion x1e8_;
std::shared_ptr<IMetaAnim> x1f8_animRoot;
std::shared_ptr<CTransitionManager> x1fc_transMgr;
float x200_ = 1.f;
u32 x204_b;
u16 x208_a;
u32 x20c_passedBoolCount = 0;
u32 x210_passedIntCount = 0;
u32 x214_passedParticleCount = 0;
u32 x218_passedSoundCount = 0;
union
{
u32 x21c_flags = 0;
struct
{
bool x21c_24_ : 1;
bool x21c_25_c : 1;
bool x21c_26_ : 1;
bool x21c_27_ : 1;
bool x21c_28_ : 1;
bool x21c_29_ : 1;
bool x21c_30_ : 1;
bool x21c_31_ : 1;
};
};
CPoseAsTransforms x220_pose;
CHierarchyPoseBuilder x2f8_poseBuilder;
u32 x101c_ = -1;
u32 x1020_ = -1;
float x1024_ = 1.f;
bool x1028_ = true;
u32 x102c_ = 0;
u32 x1030_ = 0;
bool x1034_ = false;
u32 x1038_ = 0;
u32 x103c_ = 0;
u32 x1040_ = 0;
u32 x1044_ = 0;
public:
CAnimData(TResId, const CCharacterInfo& character, int a, int b, bool c,
const TLockedToken<CCharLayoutInfo>& layout,
const TToken<CSkinnedModel>& model,
const std::weak_ptr<CAnimSysContext>& ctx,
const std::shared_ptr<CAnimationManager>& animMgr,
const std::shared_ptr<CTransitionManager>& transMgr,
const TLockedToken<CCharacterFactory>& charFactory);
static void InitializeCache()
{
}

View File

@ -123,8 +123,7 @@ void CAnimSource::CalcAverageVelocity()
CAnimSource::CAnimSource(CInputStream& in, IObjectStore& store)
: x0_duration(in),
x8_interval(in.readFloatBig()),
xc_(in.readUint32Big()),
x8_interval(in),
x10_frameCount(in.readUint32Big()),
x1c_rootBone(in),
x20_rotationChannels(ReadIndexTable(in)),
@ -174,7 +173,7 @@ const std::vector<CBoolPOINode>& CAnimSource::GetBoolPOIStream() const
zeus::CQuaternion CAnimSource::GetRotation(const CSegId& seg, const CCharAnimTime& time) const
{
u8 rotIdx = x20_rotationChannels[seg.GetId()];
u8 rotIdx = x20_rotationChannels[seg];
if (rotIdx != 0xff)
{
u32 frameIdx = unsigned(time / x8_interval);
@ -201,7 +200,7 @@ zeus::CQuaternion CAnimSource::GetRotation(const CSegId& seg, const CCharAnimTim
zeus::CVector3f CAnimSource::GetOffset(const CSegId& seg, const CCharAnimTime& time) const
{
u8 rotIdx = x20_rotationChannels[seg.GetId()];
u8 rotIdx = x20_rotationChannels[seg];
if (rotIdx != 0xff)
{
u8 transIdx = x30_translationChannels[rotIdx];
@ -232,7 +231,7 @@ zeus::CVector3f CAnimSource::GetOffset(const CSegId& seg, const CCharAnimTime& t
bool CAnimSource::HasOffset(const CSegId& seg) const
{
u8 rotIdx = x20_rotationChannels[seg.GetId()];
u8 rotIdx = x20_rotationChannels[seg];
if (rotIdx == 0xff)
return false;
u8 transIdx = x30_translationChannels[rotIdx];

View File

@ -51,8 +51,7 @@ class CAnimSource
{
friend class CAnimSourceInfo;
CCharAnimTime x0_duration;
float x8_interval;
u32 xc_;
CCharAnimTime x8_interval;
u32 x10_frameCount;
CSegId x1c_rootBone;
std::vector<u8> x20_rotationChannels;

View File

View File

@ -0,0 +1,13 @@
#ifndef __PSHAG_CANIMATIONMANAGER_HPP__
#define __PSHAG_CANIMATIONMANAGER_HPP__
namespace urde
{
class CAnimationManager
{
};
}
#endif // __PSHAG_CANIMATIONMANAGER_HPP__

View File

@ -34,6 +34,7 @@ class CCharLayoutInfo
std::map<std::string, CSegId> x18_segIdMap;
public:
CCharLayoutInfo(CInputStream& in);
const CSegIdList& GetSegIdList() const {return x8_segIdList;}
};
CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream&, const CVParamTransfer&);

View File

@ -6,6 +6,10 @@
namespace urde
{
class CAnimSysContext
{
};
class CCharacterFactory : public IFactory
{
public:

View File

@ -3,9 +3,12 @@
namespace urde
{
class CLayoutDescription;
class CHierarchyPoseBuilder
{
public:
CHierarchyPoseBuilder(const CLayoutDescription& layout);
};
}

View File

@ -11,7 +11,7 @@ add_library(RuntimeCommonCharacter
CTransitionDatabaseGame.hpp
CHierarchyPoseBuilder.hpp CHierarchyPoseBuilder.cpp
CPoseAsTransforms.hpp CPoseAsTransforms.cpp
CVirtualBone.hpp CVirtualBone.cpp
CSkinBank.hpp CSkinBank.cpp
CCharLayoutInfo.hpp CCharLayoutInfo.cpp
CSegIdList.hpp CSegIdList.cpp
CSegId.hpp CSegId.cpp
@ -27,7 +27,9 @@ add_library(RuntimeCommonCharacter
CPASAnimParm.hpp CPASAnimParm.cpp
CEffectComponent.hpp CEffectComponent.cpp
CAnimation.hpp CAnimation.cpp
CAnimationManager.hpp CAnimationManager.cpp
CTransition.hpp CTransition.cpp
CTransitionManager.hpp CTransitionManager.cpp
CMetaAnimFactory.hpp CMetaAnimFactory.cpp
CMetaAnimPlay.hpp CMetaAnimPlay.cpp
CMetaAnimBlend.hpp CMetaAnimBlend.cpp
@ -55,6 +57,7 @@ add_library(RuntimeCommonCharacter
CHalfTransition.hpp CHalfTransition.cpp
CTimeScaleFunctions.hpp CTimeScaleFunctions.cpp
CParticleData.hpp CParticleData.cpp
CParticleDatabase.hpp CParticleDatabase.cpp
CAnimPOIData.hpp CAnimPOIData.cpp
CPOINode.hpp CPOINode.cpp
CBoolPOINode.hpp CBoolPOINode.cpp

View File

View File

@ -0,0 +1,13 @@
#ifndef __PSHAG_CPARTICLEDATABASE_HPP__
#define __PSHAG_CPARTICLEDATABASE_HPP__
namespace urde
{
class CParticleDatabase
{
};
}
#endif // __PSHAG_CPARTICLEDATABASE_HPP__

View File

@ -0,0 +1,63 @@
#include "CPoseAsTransforms.hpp"
namespace urde
{
CPoseAsTransforms::CPoseAsTransforms(u8 boneCount)
: x1_count(boneCount), xd0_transformArr(new zeus::CTransform[boneCount])
{}
bool CPoseAsTransforms::ContainsDataFor(const CSegId& id) const
{
const std::pair<CSegId, CSegId>& link = x8_links[id];
if (link.first != 0xff || link.second != 0xff)
return true;
return false;
}
void CPoseAsTransforms::Clear()
{
for (u32 i=0 ; i<100 ; ++i)
x8_links[i] = std::make_pair(CSegId(), CSegId());
xd4_lastInserted = 0;
x0_nextId = 0;
}
void CPoseAsTransforms::AccumulateScaledTransform(const CSegId& id,
zeus::CMatrix3f& rotation,
float scale) const
{
rotation.addScaledMatrix(GetRotation(id), scale);
}
const zeus::CTransform& CPoseAsTransforms::GetTransform(const CSegId& id) const
{
const std::pair<CSegId, CSegId>& link = x8_links[id];
return xd0_transformArr[link.second];
}
const zeus::CVector3f& CPoseAsTransforms::GetOffset(const CSegId& id) const
{
const std::pair<CSegId, CSegId>& link = x8_links[id];
return xd0_transformArr[link.second].m_origin;
}
const zeus::CMatrix3f& CPoseAsTransforms::GetRotation(const CSegId& id) const
{
const std::pair<CSegId, CSegId>& link = x8_links[id];
return xd0_transformArr[link.second].m_basis;
}
void CPoseAsTransforms::Insert(const CSegId& id,
const zeus::CMatrix3f& rotation,
const zeus::CVector3f& offset)
{
xd0_transformArr[x0_nextId] = zeus::CTransform(rotation, offset);
std::pair<CSegId, CSegId>& link = x8_links[id];
link.first = xd4_lastInserted;
link.second = x0_nextId;
xd4_lastInserted = id;
++x0_nextId;
}
}

View File

@ -1,11 +1,29 @@
#ifndef __PSHAG_CPOSEASTRANSFORMS_HPP__
#define __PSHAG_CPOSEASTRANSFORMS_HPP__
#include "RetroTypes.hpp"
#include "CSegId.hpp"
#include "zeus/CTransform.hpp"
namespace urde
{
class CPoseAsTransforms
{
CSegId x0_nextId = 0;
CSegId x1_count;
std::pair<CSegId, CSegId> x8_links[100];
std::unique_ptr<zeus::CTransform[]> xd0_transformArr;
CSegId xd4_lastInserted = 0;
public:
CPoseAsTransforms(u8 boneCount);
bool ContainsDataFor(const CSegId& id) const;
void Clear();
void AccumulateScaledTransform(const CSegId& id, zeus::CMatrix3f& rotation, float scale) const;
const zeus::CTransform& GetTransform(const CSegId& id) const;
const zeus::CVector3f& GetOffset(const CSegId& id) const;
const zeus::CMatrix3f& GetRotation(const CSegId& id) const;
void Insert(const CSegId& id, const zeus::CMatrix3f& rotation, const zeus::CVector3f& offset);
};
}

View File

@ -13,9 +13,11 @@ class CSegId
u8 x0_segId = 0xff;
public:
CSegId() = default;
CSegId(u8 id) : x0_segId(id) {}
CSegId(CInputStream& in) : x0_segId(in.readUint32Big()) {}
operator bool() const {return x0_segId != 0xff;}
u8 GetId() const {return x0_segId;}
CSegId& operator++() {++x0_segId; return *this;}
CSegId& operator--() {--x0_segId; return *this;}
operator u8() const {return x0_segId;}
};
}

View File

@ -12,6 +12,7 @@ class CSegIdList
std::vector<CSegId> x0_list;
public:
CSegIdList(CInputStream& in);
const std::vector<CSegId>& GetList() const {return x0_list;}
};
}

View File

@ -0,0 +1,14 @@
#include "CSkinBank.hpp"
namespace urde
{
CSkinBank::CSkinBank(CInputStream& in)
{
u32 boneCount = in.readUint32Big();
x0_segments.reserve(boneCount);
for (u32 i=0 ; i<boneCount ; ++i)
x0_segments.emplace_back(in);
}
}

View File

@ -0,0 +1,19 @@
#ifndef __PSHAG_CSKINBANK_HPP__
#define __PSHAG_CSKINBANK_HPP__
#include "IOStreams.hpp"
#include "CSegId.hpp"
namespace urde
{
class CSkinBank
{
std::vector<CSegId> x0_segments;
public:
CSkinBank(CInputStream& in);
};
}
#endif // __PSHAG_CSKINBANK_HPP__

View File

@ -1,10 +1,20 @@
#include "CSkinRules.hpp"
#include "CToken.hpp"
namespace urde
{
CSkinRules::CSkinRules(CInputStream& in)
{
u32 bankCount = in.readUint32Big();
x0_skinBanks.reserve(bankCount);
for (u32 i=0 ; i<bankCount ; ++i)
x0_skinBanks.emplace_back(in);
}
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params)
{
return TToken<CSkinRules>::GetIObjObjectFor(std::make_unique<CSkinRules>(in));
}
}

View File

@ -2,18 +2,22 @@
#define __PSHAG_CSKINRULES_HPP__
#include "RetroTypes.hpp"
#include "CVirtualBone.hpp"
#include "CSkinBank.hpp"
#include "CFactoryMgr.hpp"
namespace urde
{
class CSkinRules
{
std::vector<CVirtualBone> x0_bones;
std::vector<CSkinBank> x0_skinBanks;
public:
CSkinRules(CInputStream& in);
void BuildAccumulatedTransforms();
};
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params);
}
#endif // __PSHAG_CSKINRULES_HPP__

View File

View File

@ -0,0 +1,13 @@
#ifndef __PSHAG_CTRANSITIONMANAGER_HPP__
#define __PSHAG_CTRANSITIONMANAGER_HPP__
namespace urde
{
class CTransitionManager
{
};
}
#endif // __PSHAG_CTRANSITIONMANAGER_HPP__

View File

@ -1,11 +0,0 @@
#include "CVirtualBone.hpp"
namespace urde
{
CVirtualBone::CVirtualBone(CInputStream& in)
{
}
}

View File

@ -1,17 +0,0 @@
#ifndef __PSHAG_CVIRTUALBONE_HPP__
#define __PSHAG_CVIRTUALBONE_HPP__
#include "IOStreams.hpp"
namespace urde
{
class CVirtualBone
{
public:
CVirtualBone(CInputStream& in);
};
}
#endif // __PSHAG_CVIRTUALBONE_HPP__

2
hecl

@ -1 +1 @@
Subproject commit ca8f24d78bbe80c5d61ed0f25d83176be204f1b8
Subproject commit fad67a063140c1b0946122a5f94aaa412f1a4c2a

@ -1 +1 @@
Subproject commit 5272e08fc7584dc45890707123a16eac2ed16b20
Subproject commit 87e8161a2bb7aa6e6447b7f149cdf3ed014a0dae