mirror of https://github.com/AxioDL/metaforce.git
Initial CCharLayoutInfo implementation
This commit is contained in:
parent
68c1ac8978
commit
e661fa6f2b
|
@ -9,6 +9,7 @@
|
||||||
#include "CINF.hpp"
|
#include "CINF.hpp"
|
||||||
#include "CSKR.hpp"
|
#include "CSKR.hpp"
|
||||||
#include "ANIM.hpp"
|
#include "ANIM.hpp"
|
||||||
|
#include "EVNT.hpp"
|
||||||
#include "athena/FileReader.hpp"
|
#include "athena/FileReader.hpp"
|
||||||
|
|
||||||
namespace DataSpec
|
namespace DataSpec
|
||||||
|
@ -540,16 +541,16 @@ struct ANCS : BigYAML
|
||||||
hecl::ProjectPath blendPath = outPath.getWithExtension(_S(".blend"));
|
hecl::ProjectPath blendPath = outPath.getWithExtension(_S(".blend"));
|
||||||
hecl::ProjectPath::Type blendType = blendPath.getPathType();
|
hecl::ProjectPath::Type blendType = blendPath.getPathType();
|
||||||
|
|
||||||
|
ANCS ancs;
|
||||||
|
ancs.read(rs);
|
||||||
|
|
||||||
if (force ||
|
if (force ||
|
||||||
yamlType == hecl::ProjectPath::Type::None ||
|
yamlType == hecl::ProjectPath::Type::None ||
|
||||||
blendType == hecl::ProjectPath::Type::None)
|
blendType == hecl::ProjectPath::Type::None)
|
||||||
{
|
{
|
||||||
ANCS ancs;
|
|
||||||
ancs.read(rs);
|
|
||||||
|
|
||||||
if (force || yamlType == hecl::ProjectPath::Type::None)
|
if (force || yamlType == hecl::ProjectPath::Type::None)
|
||||||
{
|
{
|
||||||
FILE* fp = hecl::Fopen(yamlPath.getAbsolutePath().c_str(), _S("wb"));
|
FILE* fp = hecl::Fopen(yamlPath.getAbsolutePath().c_str(), _S("w"));
|
||||||
ancs.toYAMLFile(fp);
|
ancs.toYAMLFile(fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
@ -562,6 +563,32 @@ struct ANCS : BigYAML
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extract EVNTs */
|
||||||
|
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animRes;
|
||||||
|
ancs.getAnimationResInfo(animRes);
|
||||||
|
for (const auto& res : animRes)
|
||||||
|
{
|
||||||
|
if (res.second.evntId)
|
||||||
|
{
|
||||||
|
hecl::SystemStringView sysStr(res.second.name);
|
||||||
|
hecl::ProjectPath evntYamlPath = outPath.getWithExtension((hecl::SystemString(_S(".")) +
|
||||||
|
sysStr.sys_str() +
|
||||||
|
_S(".evnt.yaml")).c_str());
|
||||||
|
hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType();
|
||||||
|
|
||||||
|
if (force || evntYamlType == hecl::ProjectPath::Type::None)
|
||||||
|
{
|
||||||
|
EVNT evnt;
|
||||||
|
if (pakRouter.lookupAndReadDNA(res.second.evntId, evnt, true))
|
||||||
|
{
|
||||||
|
FILE* fp = hecl::Fopen(evntYamlPath.getAbsolutePath().c_str(), _S("w"));
|
||||||
|
evnt.toYAMLFile(fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,22 +639,76 @@ struct ANCS : BigYAML
|
||||||
ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) -> bool
|
ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) -> bool
|
||||||
{
|
{
|
||||||
hecl::SystemStringView sysStr(prim.animName);
|
hecl::SystemStringView sysStr(prim.animName);
|
||||||
prim.animId = inPath.ensureAuxInfo(sysStr.c_str());
|
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
|
||||||
|
prim.animId = pathOut;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
std::unordered_map<std::string, atInt32> boneIdMap;
|
||||||
|
|
||||||
/* Write out CINF resources */
|
/* Write out CINF resources */
|
||||||
for (const DNAANCS::Actor::Armature& arm : actor.armatures)
|
for (const DNAANCS::Actor::Armature& arm : actor.armatures)
|
||||||
{
|
{
|
||||||
hecl::SystemStringView sysStr(arm.name);
|
hecl::SystemStringView sysStr(arm.name);
|
||||||
hecl::ProjectPath pathOut = inPath.getWithExtension(sysStr.c_str(), true);
|
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
|
||||||
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
|
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
|
||||||
if (w.hasError())
|
if (w.hasError())
|
||||||
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"), pathOut.getRelativePath().c_str());
|
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
|
||||||
CINF cinf(arm);
|
pathOut.getRelativePath().c_str());
|
||||||
|
CINF cinf(arm, boneIdMap);
|
||||||
cinf.write(w);
|
cinf.write(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write out ANIM resources */
|
||||||
|
ancs.animationSet.animResources.reserve(actor.actions.size());
|
||||||
|
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);
|
||||||
|
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
|
||||||
|
if (w.hasError())
|
||||||
|
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
|
||||||
|
pathOut.getRelativePath().c_str());
|
||||||
|
ANIM anim(act, boneIdMap);
|
||||||
|
|
||||||
|
ancs.animationSet.animResources.emplace_back();
|
||||||
|
ancs.animationSet.animResources.back().animId = pathOut;
|
||||||
|
|
||||||
|
/* Check for associated EVNT YAML */
|
||||||
|
hecl::ProjectPath evntYamlPath = inPath.getWithExtension((hecl::SystemString(_S(".")) +
|
||||||
|
sysStr.sys_str() +
|
||||||
|
_S(".evnt.yaml")).c_str(), true);
|
||||||
|
if (evntYamlPath.getPathType() == hecl::ProjectPath::Type::File)
|
||||||
|
{
|
||||||
|
FILE* fp = hecl::Fopen(evntYamlPath.getAbsolutePath().c_str(), _S("r"));
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
EVNT evnt;
|
||||||
|
evnt.fromYAMLFile(fp);
|
||||||
|
fclose(fp);
|
||||||
|
anim.m_anim->evnt = evntYamlPath;
|
||||||
|
|
||||||
|
hecl::ProjectPath evntYamlOut = pathOut.getWithExtension(_S(".evnt"));
|
||||||
|
athena::io::FileWriter w(evntYamlOut.getAbsolutePath(), true, false);
|
||||||
|
if (w.hasError())
|
||||||
|
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
|
||||||
|
evntYamlOut.getRelativePath().c_str());
|
||||||
|
|
||||||
|
evnt.write(w);
|
||||||
|
ancs.animationSet.animResources.back().evntId = evntYamlPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
anim.write(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write out ANCS */
|
||||||
|
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
|
||||||
|
if (w.hasError())
|
||||||
|
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
|
||||||
|
outPath.getRelativePath().c_str());
|
||||||
|
ancs.write(w);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -428,5 +428,76 @@ size_t ANIM::ANIM2::binarySize(size_t __isz) const
|
||||||
return __isz + DNAANIM::ComputeBitstreamSize(frames.size(), channels);
|
return __isz + DNAANIM::ComputeBitstreamSize(frames.size(), channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ANIM::ANIM(const BlenderAction& act, const std::unordered_map<std::string, atInt32>& idMap)
|
||||||
|
{
|
||||||
|
m_anim.reset(new struct ANIM0);
|
||||||
|
IANIM& newAnim = *m_anim;
|
||||||
|
|
||||||
|
newAnim.bones.reserve(act.channels.size());
|
||||||
|
size_t extChanCount = 0;
|
||||||
|
for (const BlenderAction::Channel& chan : act.channels)
|
||||||
|
{
|
||||||
|
auto search = idMap.find(chan.boneName);
|
||||||
|
if (search == idMap.cend())
|
||||||
|
{
|
||||||
|
Log.report(logvisor::Warning, "unable to find id for bone '%s'", chan.boneName.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
extChanCount += std::max(zeus::PopCount(chan.attrMask), 2);
|
||||||
|
newAnim.bones.emplace_back(search->second, (chan.attrMask & 0x2) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
newAnim.frames.reserve(act.frames.size());
|
||||||
|
for (int32_t frame : act.frames)
|
||||||
|
newAnim.frames.push_back(frame);
|
||||||
|
|
||||||
|
newAnim.channels.reserve(extChanCount);
|
||||||
|
newAnim.chanKeys.reserve(extChanCount);
|
||||||
|
|
||||||
|
for (const BlenderAction::Channel& chan : act.channels)
|
||||||
|
{
|
||||||
|
auto search = idMap.find(chan.boneName);
|
||||||
|
if (search == idMap.cend())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
newAnim.channels.emplace_back();
|
||||||
|
DNAANIM::Channel& newChan = newAnim.channels.back();
|
||||||
|
newChan.type = DNAANIM::Channel::Type::Rotation;
|
||||||
|
newChan.id = search->second;
|
||||||
|
|
||||||
|
newAnim.chanKeys.emplace_back();
|
||||||
|
std::vector<DNAANIM::Value>& rotVals = newAnim.chanKeys.back();
|
||||||
|
rotVals.reserve(chan.keys.size());
|
||||||
|
for (const BlenderAction::Channel::Key& key : chan.keys)
|
||||||
|
{
|
||||||
|
rotVals.emplace_back(key.rotation.val.vec[0],
|
||||||
|
key.rotation.val.vec[1],
|
||||||
|
key.rotation.val.vec[2],
|
||||||
|
key.rotation.val.vec[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan.attrMask & 0x2)
|
||||||
|
{
|
||||||
|
newAnim.channels.emplace_back();
|
||||||
|
DNAANIM::Channel& newChan = newAnim.channels.back();
|
||||||
|
newChan.type = DNAANIM::Channel::Type::Translation;
|
||||||
|
newChan.id = search->second;
|
||||||
|
|
||||||
|
newAnim.chanKeys.emplace_back();
|
||||||
|
std::vector<DNAANIM::Value>& transVals = newAnim.chanKeys.back();
|
||||||
|
transVals.reserve(chan.keys.size());
|
||||||
|
for (const BlenderAction::Channel::Key& key : chan.keys)
|
||||||
|
{
|
||||||
|
transVals.emplace_back(key.position.val.vec[0],
|
||||||
|
key.position.val.vec[1],
|
||||||
|
key.position.val.vec[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newAnim.mainInterval = act.interval;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,6 +179,10 @@ struct ANIM : BigDNA
|
||||||
m_anim->sendANIMToBlender(os, rig);
|
m_anim->sendANIMToBlender(os, rig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using BlenderAction = hecl::BlenderConnection::DataStream::Actor::Action;
|
||||||
|
|
||||||
|
ANIM() = default;
|
||||||
|
ANIM(const BlenderAction& act, const std::unordered_map<std::string, atInt32>& idMap);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,36 +121,49 @@ struct CINF : BigDNA
|
||||||
CINF() = default;
|
CINF() = default;
|
||||||
using Armature = hecl::BlenderConnection::DataStream::Actor::Armature;
|
using Armature = hecl::BlenderConnection::DataStream::Actor::Armature;
|
||||||
|
|
||||||
int RecursiveAddArmatureBone(const Armature& armature, const Armature::Bone* bone, int parent, int& curId)
|
int RecursiveAddArmatureBone(const Armature& armature, const Armature::Bone* bone, int parent, int& curId,
|
||||||
|
std::unordered_map<std::string, atInt32>& idMap)
|
||||||
{
|
{
|
||||||
|
int selId;
|
||||||
|
auto search = idMap.find(bone->name);
|
||||||
|
if (search == idMap.end())
|
||||||
|
{
|
||||||
|
selId = curId++;
|
||||||
|
idMap.emplace(std::make_pair(bone->name, selId));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
selId = search->second;
|
||||||
|
|
||||||
bones.emplace_back();
|
bones.emplace_back();
|
||||||
names.emplace_back();
|
names.emplace_back();
|
||||||
Bone& boneOut = bones.back();
|
Bone& boneOut = bones.back();
|
||||||
Name& nameOut = names.back();
|
Name& nameOut = names.back();
|
||||||
nameOut.name = bone->name;
|
nameOut.name = bone->name;
|
||||||
nameOut.boneId = curId;
|
nameOut.boneId = selId;
|
||||||
boneOut.id = curId++;
|
boneOut.id = selId;
|
||||||
boneOut.parentId = parent;
|
boneOut.parentId = parent;
|
||||||
boneOut.origin = bone->origin;
|
boneOut.origin = bone->origin;
|
||||||
boneOut.linkedCount = bone->children.size();
|
boneOut.linkedCount = bone->children.size() + 1;
|
||||||
boneOut.linked.reserve(boneOut.linkedCount);
|
boneOut.linked.reserve(boneOut.linkedCount);
|
||||||
|
|
||||||
const Armature::Bone* child;
|
const Armature::Bone* child;
|
||||||
|
boneOut.linked.push_back(parent);
|
||||||
for (size_t i=0 ; (child = armature.getChild(bone, i)) ; ++i)
|
for (size_t i=0 ; (child = armature.getChild(bone, i)) ; ++i)
|
||||||
boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, curId));
|
boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, selId, idMap));
|
||||||
|
|
||||||
return boneOut.id;
|
return boneOut.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
CINF(const Armature& armature)
|
CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& idMap)
|
||||||
{
|
{
|
||||||
|
idMap.reserve(armature.bones.size());
|
||||||
bones.reserve(armature.bones.size());
|
bones.reserve(armature.bones.size());
|
||||||
names.reserve(armature.bones.size());
|
names.reserve(armature.bones.size());
|
||||||
|
|
||||||
const Armature::Bone* bone = armature.getRoot();
|
const Armature::Bone* bone = armature.getRoot();
|
||||||
int curId = 3;
|
int curId = 3;
|
||||||
if (bone)
|
if (bone)
|
||||||
RecursiveAddArmatureBone(armature, bone, 2, curId);
|
RecursiveAddArmatureBone(armature, bone, 2, curId, idMap);
|
||||||
|
|
||||||
boneCount = bones.size();
|
boneCount = bones.size();
|
||||||
nameCount = names.size();
|
nameCount = names.size();
|
||||||
|
|
|
@ -261,7 +261,7 @@ struct SpecMP1 : SpecBase
|
||||||
for (std::pair<const std::string, DNAMP1::PAKBridge*>& pair : m_orderedPaks)
|
for (std::pair<const std::string, DNAMP1::PAKBridge*>& pair : m_orderedPaks)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
const DNAMP1::PAK::Entry* ent = pair.second->getPAK().lookupEntry(UniqueID32("AF974083"));
|
const DNAMP1::PAK::Entry* ent = pair.second->getPAK().lookupEntry(UniqueID32("A4DFCAD6"));
|
||||||
if (ent)
|
if (ent)
|
||||||
{
|
{
|
||||||
DNAMP1::ANIM anim;
|
DNAMP1::ANIM anim;
|
||||||
|
@ -296,6 +296,8 @@ struct SpecMP1 : SpecBase
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process.waitUntilComplete();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -265,6 +265,8 @@ struct SpecMP2 : SpecBase
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process.waitUntilComplete();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -395,6 +395,8 @@ struct SpecMP3 : SpecBase
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process.waitUntilComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doMPTFE)
|
if (doMPTFE)
|
||||||
|
@ -455,6 +457,8 @@ struct SpecMP3 : SpecBase
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process.waitUntilComplete();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
||||||
for (const std::string& arm : armatureNames)
|
for (const std::string& arm : armatureNames)
|
||||||
{
|
{
|
||||||
hecl::SystemStringView sysStr(arm);
|
hecl::SystemStringView sysStr(arm);
|
||||||
hecl::ProjectPath subPath = path.ensureAuxInfo(sysStr.c_str());
|
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
|
||||||
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
||||||
if (pathTag)
|
if (pathTag)
|
||||||
{
|
{
|
||||||
|
@ -169,7 +169,7 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
||||||
for (const std::string& act : actionNames)
|
for (const std::string& act : actionNames)
|
||||||
{
|
{
|
||||||
hecl::SystemStringView sysStr(act);
|
hecl::SystemStringView sysStr(act);
|
||||||
hecl::ProjectPath subPath = path.ensureAuxInfo(sysStr.c_str());
|
hecl::ProjectPath subPath = path.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
|
||||||
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
SObjectTag pathTag = TagFromPath(subPath, m_backgroundBlender);
|
||||||
if (pathTag)
|
if (pathTag)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "Runtime/GuiSys/CRasterFont.hpp"
|
#include "Runtime/GuiSys/CRasterFont.hpp"
|
||||||
#include "Runtime/Graphics/CModel.hpp"
|
#include "Runtime/Graphics/CModel.hpp"
|
||||||
#include "Runtime/Graphics/CTexture.hpp"
|
#include "Runtime/Graphics/CTexture.hpp"
|
||||||
|
#include "Runtime/Character/CCharLayoutInfo.hpp"
|
||||||
|
|
||||||
#include "DataSpec/DNACommon/TXTR.hpp"
|
#include "DataSpec/DNACommon/TXTR.hpp"
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& client
|
||||||
m_factoryMgr.AddFactory(FOURCC('FRME'), FFactoryFunc(RGuiFrameFactoryInGame));
|
m_factoryMgr.AddFactory(FOURCC('FRME'), FFactoryFunc(RGuiFrameFactoryInGame));
|
||||||
m_factoryMgr.AddFactory(FOURCC('FONT'), FFactoryFunc(FRasterFontFactory));
|
m_factoryMgr.AddFactory(FOURCC('FONT'), FFactoryFunc(FRasterFontFactory));
|
||||||
m_factoryMgr.AddFactory(FOURCC('CMDL'), FMemFactoryFunc(FModelFactory));
|
m_factoryMgr.AddFactory(FOURCC('CMDL'), FMemFactoryFunc(FModelFactory));
|
||||||
|
m_factoryMgr.AddFactory(FOURCC('CINF'), FFactoryFunc(FCharLayoutInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj)
|
void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj)
|
||||||
|
@ -98,6 +100,11 @@ SObjectTag ProjectResourceFactoryMP1::TagFromPath(const hecl::ProjectPath& path,
|
||||||
resTag.type = SBIG('FONT');
|
resTag.type = SBIG('FONT');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(className, "urde::DNAMP1::EVNT"))
|
||||||
|
{
|
||||||
|
resTag.type = SBIG('EVNT');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "Runtime/Particle/CSwooshDescription.hpp"
|
#include "Runtime/Particle/CSwooshDescription.hpp"
|
||||||
#include "Runtime/Graphics/CModel.hpp"
|
#include "Runtime/Graphics/CModel.hpp"
|
||||||
#include "Runtime/Graphics/CGraphics.hpp"
|
#include "Runtime/Graphics/CGraphics.hpp"
|
||||||
#include "Runtime/Graphics/CSkinRules.hpp"
|
#include "Runtime/Character/CSkinRules.hpp"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
using YAMLNode = athena::io::YAMLNode;
|
using YAMLNode = athena::io::YAMLNode;
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include "CCharLayoutInfo.hpp"
|
||||||
|
#include "CToken.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
void CCharLayoutNode::Bone::read(CInputStream& in)
|
||||||
|
{
|
||||||
|
x0_parentId = CSegId(in);
|
||||||
|
x4_origin.readBig(in);
|
||||||
|
|
||||||
|
u32 chCount = in.readUint32Big();
|
||||||
|
x10_children.reserve(chCount);
|
||||||
|
for (u32 i=0 ; i<chCount ; ++i)
|
||||||
|
x10_children.emplace_back(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
CCharLayoutNode::CCharLayoutNode(CInputStream& in)
|
||||||
|
{
|
||||||
|
x0_boneCount = in.readUint32Big();
|
||||||
|
for (u32 i=0 ; i<x0_boneCount ; ++i)
|
||||||
|
{
|
||||||
|
u32 thisId = in.readUint32Big();
|
||||||
|
if (thisId >= 100)
|
||||||
|
{
|
||||||
|
Bone dummy;
|
||||||
|
dummy.read(in);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
x108_bones[i].read(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CCharLayoutInfo::CCharLayoutInfo(CInputStream& in)
|
||||||
|
: x0_node(std::make_shared<CCharLayoutNode>(in)),
|
||||||
|
x8_segIdList(in)
|
||||||
|
{
|
||||||
|
atUint32 mapCount = in.readUint32Big();
|
||||||
|
for (int i=0 ; i<mapCount ; ++i)
|
||||||
|
{
|
||||||
|
std::string key = in.readString();
|
||||||
|
x18_segIdMap.emplace(key, in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream& in, const CVParamTransfer&)
|
||||||
|
{
|
||||||
|
return TToken<CCharLayoutInfo>::GetIObjObjectFor(std::make_unique<CCharLayoutInfo>(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,13 +1,43 @@
|
||||||
#ifndef __PSHAG_CCHARLAYOUTINFO_HPP__
|
#ifndef __PSHAG_CCHARLAYOUTINFO_HPP__
|
||||||
#define __PSHAG_CCHARLAYOUTINFO_HPP__
|
#define __PSHAG_CCHARLAYOUTINFO_HPP__
|
||||||
|
|
||||||
|
#include "CFactoryMgr.hpp"
|
||||||
|
#include "IOStreams.hpp"
|
||||||
|
#include "CSegIdList.hpp"
|
||||||
|
#include "CSegId.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class CCharLayoutNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Bone
|
||||||
|
{
|
||||||
|
CSegId x0_parentId;
|
||||||
|
zeus::CVector3f x4_origin;
|
||||||
|
std::vector<CSegId> x10_children;
|
||||||
|
void read(CInputStream& in);
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
u8 x0_boneCount;
|
||||||
|
CSegId x8_ids[100];
|
||||||
|
Bone x108_bones[100];
|
||||||
|
public:
|
||||||
|
CCharLayoutNode(CInputStream& in);
|
||||||
|
};
|
||||||
|
|
||||||
class CCharLayoutInfo
|
class CCharLayoutInfo
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<CCharLayoutNode> x0_node;
|
||||||
|
CSegIdList x8_segIdList;
|
||||||
|
std::map<std::string, CSegId> x18_segIdMap;
|
||||||
|
public:
|
||||||
|
CCharLayoutInfo(CInputStream& in);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream&, const CVParamTransfer&);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __PSHAG_CCHARLAYOUTINFO_HPP__
|
#endif // __PSHAG_CCHARLAYOUTINFO_HPP__
|
||||||
|
|
|
@ -12,4 +12,8 @@ add_library(RuntimeCommonCharacter
|
||||||
CHierarchyPoseBuilder.hpp CHierarchyPoseBuilder.cpp
|
CHierarchyPoseBuilder.hpp CHierarchyPoseBuilder.cpp
|
||||||
CPoseAsTransforms.hpp CPoseAsTransforms.cpp
|
CPoseAsTransforms.hpp CPoseAsTransforms.cpp
|
||||||
CVirtualBone.hpp CVirtualBone.cpp
|
CVirtualBone.hpp CVirtualBone.cpp
|
||||||
|
CCharLayoutInfo.hpp CCharLayoutInfo.cpp
|
||||||
|
CSegIdList.hpp CSegIdList.cpp
|
||||||
|
CSegId.hpp CSegId.cpp
|
||||||
|
CSkinRules.hpp CSkinRules.cpp
|
||||||
CBodyState.hpp)
|
CBodyState.hpp)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef __PSHAG_CSEGID_HPP__
|
||||||
|
#define __PSHAG_CSEGID_HPP__
|
||||||
|
|
||||||
|
#include "RetroTypes.hpp"
|
||||||
|
#include "IOStreams.hpp"
|
||||||
|
#include "zeus/CVector3f.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
class CSegId
|
||||||
|
{
|
||||||
|
u8 x0_segId = 0xff;
|
||||||
|
public:
|
||||||
|
CSegId() = default;
|
||||||
|
CSegId(CInputStream& in) : x0_segId(in.readUint32Big()) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __PSHAG_CSEGID_HPP__
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "CSegIdList.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
CSegIdList::CSegIdList(CInputStream& in)
|
||||||
|
{
|
||||||
|
u32 count = in.readUint32Big();
|
||||||
|
x0_list.reserve(count);
|
||||||
|
for (u32 i=0 ; i<count ; ++i)
|
||||||
|
x0_list.emplace_back(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef __PSHAG_CSEGIDLIST_HPP__
|
||||||
|
#define __PSHAG_CSEGIDLIST_HPP__
|
||||||
|
|
||||||
|
#include "IOStreams.hpp"
|
||||||
|
#include "CSegId.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
class CSegIdList
|
||||||
|
{
|
||||||
|
std::vector<CSegId> x0_list;
|
||||||
|
public:
|
||||||
|
CSegIdList(CInputStream& in);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __PSHAG_CSEGIDLIST_HPP__
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include "CSkinRules.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
CSkinRules::CSkinRules(CInputStream& in)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,17 @@
|
||||||
#ifndef __PSHAG_CSKINRULES_HPP__
|
#ifndef __PSHAG_CSKINRULES_HPP__
|
||||||
#define __PSHAG_CSKINRULES_HPP__
|
#define __PSHAG_CSKINRULES_HPP__
|
||||||
|
|
||||||
|
#include "RetroTypes.hpp"
|
||||||
|
#include "CVirtualBone.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
class CSkinRules
|
class CSkinRules
|
||||||
{
|
{
|
||||||
|
std::vector<CVirtualBone> x0_bones;
|
||||||
|
public:
|
||||||
|
CSkinRules(CInputStream& in);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -20,6 +20,5 @@ add_library(RuntimeCommonGraphics
|
||||||
CVertexMorphEffect.hpp CVertexMorphEffect.cpp
|
CVertexMorphEffect.hpp CVertexMorphEffect.cpp
|
||||||
CMoviePlayer.hpp CMoviePlayer.cpp
|
CMoviePlayer.hpp CMoviePlayer.cpp
|
||||||
CGraphicsPalette.hpp CGraphicsPalette.cpp
|
CGraphicsPalette.hpp CGraphicsPalette.cpp
|
||||||
CSkinRules.hpp CSkinRules.cpp
|
|
||||||
CGraphics.hpp CGraphics.cpp
|
CGraphics.hpp CGraphics.cpp
|
||||||
${PLAT_SRCS})
|
${PLAT_SRCS})
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit 3ed5345c08fa0e93c5ab57099fc4714c41cf8457
|
Subproject commit d6b0f29fbce05f193822fbd4d05cd9b4d59d36f2
|
2
specter
2
specter
|
@ -1 +1 @@
|
||||||
Subproject commit dac460c4d531bd6e67ee76119d5203c3f3d4f48d
|
Subproject commit 5272e08fc7584dc45890707123a16eac2ed16b20
|
Loading…
Reference in New Issue