AuxiliaryID32 implemented for sub-resources

This commit is contained in:
Jack Andersen 2016-04-05 15:44:07 -10:00
parent 5cd372592c
commit 28b9cd9e3f
19 changed files with 497 additions and 75 deletions

View File

@ -32,6 +32,20 @@ struct AnimationResInfo
bool additive; bool additive;
}; };
static void WriteOutAnimId(athena::io::YAMLDocWriter& __dna_docout,
const UniqueID32& ancsId,
const std::string& animName)
{
__dna_docout.enterSubRecord("animId");
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(ancsId);
if (path)
{
path = path.getWithExtension(_S(".blend"));
__dna_docout.writeString(nullptr, path.getRelativePathUTF8() + _S('|') + animName);
}
__dna_docout.leaveSubRecord();
}
template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion> template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion>
bool ReadANCSToBlender(hecl::BlenderConnection& conn, bool ReadANCSToBlender(hecl::BlenderConnection& conn,
const ANCSDNA& ancs, const ANCSDNA& ancs,

View File

@ -8,5 +8,6 @@ logvisor::Module LogDNACommon("urde::DNACommon");
SpecBase* g_curSpec = nullptr; SpecBase* g_curSpec = nullptr;
PAKRouterBase* g_PakRouter = nullptr; PAKRouterBase* g_PakRouter = nullptr;
hecl::Database::Project* UniqueIDBridge::s_Project = nullptr; hecl::Database::Project* UniqueIDBridge::s_Project = nullptr;
UniqueID32 UniqueID32::kInvalidId;
} }

View File

@ -116,8 +116,10 @@ public:
/** PAK 32-bit Unique ID */ /** PAK 32-bit Unique ID */
class UniqueID32 : public BigYAML class UniqueID32 : public BigYAML
{ {
protected:
uint32_t m_id = 0xffffffff; uint32_t m_id = 0xffffffff;
public: public:
static UniqueID32 kInvalidId;
Delete expl; Delete expl;
operator bool() const {return m_id != 0xffffffff && m_id != 0;} operator bool() const {return m_id != 0xffffffff && m_id != 0;}
void read(athena::io::IStreamReader& reader) void read(athena::io::IStreamReader& reader)
@ -176,6 +178,70 @@ public:
static constexpr size_t BinarySize() {return 4;} static constexpr size_t BinarySize() {return 4;}
}; };
class AuxiliaryID32 : public UniqueID32
{
const hecl::SystemChar* m_auxStr;
const hecl::SystemChar* m_addExtension;
UniqueID32 m_baseId;
public:
AuxiliaryID32(const hecl::SystemChar* auxStr,
const hecl::SystemChar* addExtension=nullptr)
: m_auxStr(auxStr), m_addExtension(addExtension) {}
AuxiliaryID32& operator=(const hecl::ProjectPath& path)
{
m_id = path.ensureAuxInfo(m_auxStr).hash().val32();
return *this;
}
AuxiliaryID32& operator=(const UniqueID32& id)
{
m_baseId = id;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
if (path)
{
if (m_addExtension)
path = path.getWithExtension(m_addExtension);
*this = path;
}
return *this;
}
void read(athena::io::IStreamReader& reader)
{
m_id = reader.readUint32Big();
m_baseId = *this;
}
void write(athena::io::IStreamWriter& writer) const
{
writer.writeUint32Big(m_id);
}
void read(athena::io::YAMLDocReader& reader)
{
hecl::ProjectPath readPath = UniqueIDBridge::MakePathFromString(reader.readString(nullptr));
*this = readPath.ensureAuxInfo(m_auxStr);
}
void write(athena::io::YAMLDocWriter& writer) const
{
if (!operator bool())
return;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path)
path = UniqueIDBridge::TranslatePakIdToPath(m_baseId);
if (!path)
return;
if (m_addExtension)
path = path.getWithExtension(m_addExtension);
hecl::SystemUTF8View ufx8AuxStr(m_auxStr);
writer.writeString(nullptr, path.getRelativePathUTF8() + '|' + ufx8AuxStr);
}
const UniqueID32& getBaseId() const {return m_baseId;}
};
/** PAK 64-bit Unique ID */ /** PAK 64-bit Unique ID */
class UniqueID64 : public BigYAML class UniqueID64 : public BigYAML
{ {

View File

@ -407,8 +407,8 @@ void ANCS::CharacterSet::CharacterInfo::write(athena::io::IStreamWriter& writer)
writer.writeString(name); writer.writeString(name);
cmdl.write(writer); cmdl.write(writer);
cskr.write(writer); cskr.UniqueID32::write(writer);
cinf.write(writer); cinf.UniqueID32::write(writer);
writer.writeUint32Big(animations.size()); writer.writeUint32Big(animations.size());
writer.enumerate(animations); writer.enumerate(animations);
@ -447,7 +447,7 @@ void ANCS::CharacterSet::CharacterInfo::write(athena::io::IStreamWriter& writer)
if (sectionCount > 3) if (sectionCount > 3)
{ {
cmdlOverlay.write(writer); cmdlOverlay.write(writer);
cskrOverlay.write(writer); cskrOverlay.UniqueID32::write(writer);
} }
if (sectionCount > 4) if (sectionCount > 4)
@ -648,23 +648,23 @@ void ANCS::AnimationSet::MetaAnimFactory::read(athena::io::IStreamReader& reader
switch (type) switch (type)
{ {
case IMetaAnim::Type::Primitive: case IMetaAnim::Type::Primitive:
m_anim.reset(new struct MetaAnimPrimitive); m_anim.reset(new struct MetaAnimPrimitive(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
break; break;
case IMetaAnim::Type::Blend: case IMetaAnim::Type::Blend:
m_anim.reset(new struct MetaAnimBlend); m_anim.reset(new struct MetaAnimBlend(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
break; break;
case IMetaAnim::Type::PhaseBlend: case IMetaAnim::Type::PhaseBlend:
m_anim.reset(new struct MetaAnimPhaseBlend); m_anim.reset(new struct MetaAnimPhaseBlend(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
break; break;
case IMetaAnim::Type::Random: case IMetaAnim::Type::Random:
m_anim.reset(new struct MetaAnimRandom); m_anim.reset(new struct MetaAnimRandom(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
break; break;
case IMetaAnim::Type::Sequence: case IMetaAnim::Type::Sequence:
m_anim.reset(new struct MetaAnimSequence); m_anim.reset(new struct MetaAnimSequence(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
break; break;
default: default:
@ -694,27 +694,27 @@ void ANCS::AnimationSet::MetaAnimFactory::read(athena::io::YAMLDocReader& reader
std::transform(type.begin(), type.end(), type.begin(), tolower); std::transform(type.begin(), type.end(), type.begin(), tolower);
if (!type.compare("primitive")) if (!type.compare("primitive"))
{ {
m_anim.reset(new struct MetaAnimPrimitive); m_anim.reset(new struct MetaAnimPrimitive(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
} }
else if (!type.compare("blend")) else if (!type.compare("blend"))
{ {
m_anim.reset(new struct MetaAnimBlend); m_anim.reset(new struct MetaAnimBlend(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
} }
else if (!type.compare("phaseblend")) else if (!type.compare("phaseblend"))
{ {
m_anim.reset(new struct MetaAnimPhaseBlend); m_anim.reset(new struct MetaAnimPhaseBlend(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
} }
else if (!type.compare("random")) else if (!type.compare("random"))
{ {
m_anim.reset(new struct MetaAnimRandom); m_anim.reset(new struct MetaAnimRandom(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
} }
else if (!type.compare("sequence")) else if (!type.compare("sequence"))
{ {
m_anim.reset(new struct MetaAnimSequence); m_anim.reset(new struct MetaAnimSequence(m_ancsId));
m_anim->read(reader); m_anim->read(reader);
} }
else else
@ -743,15 +743,15 @@ void ANCS::AnimationSet::MetaTransFactory::read(athena::io::IStreamReader& reade
switch (type) switch (type)
{ {
case IMetaTrans::Type::MetaAnim: case IMetaTrans::Type::MetaAnim:
m_trans.reset(new struct MetaTransMetaAnim); m_trans.reset(new struct MetaTransMetaAnim(m_ancsId));
m_trans->read(reader); m_trans->read(reader);
break; break;
case IMetaTrans::Type::Trans: case IMetaTrans::Type::Trans:
m_trans.reset(new struct MetaTransTrans); m_trans.reset(new struct MetaTransTrans(m_ancsId));
m_trans->read(reader); m_trans->read(reader);
break; break;
case IMetaTrans::Type::PhaseTrans: case IMetaTrans::Type::PhaseTrans:
m_trans.reset(new struct MetaTransPhaseTrans); m_trans.reset(new struct MetaTransPhaseTrans(m_ancsId));
m_trans->read(reader); m_trans->read(reader);
break; break;
case IMetaTrans::Type::NoTrans: case IMetaTrans::Type::NoTrans:
@ -785,17 +785,17 @@ void ANCS::AnimationSet::MetaTransFactory::read(athena::io::YAMLDocReader& reade
std::transform(type.begin(), type.end(), type.begin(), tolower); std::transform(type.begin(), type.end(), type.begin(), tolower);
if (!type.compare("metaanim")) if (!type.compare("metaanim"))
{ {
m_trans.reset(new struct MetaTransMetaAnim); m_trans.reset(new struct MetaTransMetaAnim(m_ancsId));
m_trans->read(reader); m_trans->read(reader);
} }
else if (!type.compare("trans")) else if (!type.compare("trans"))
{ {
m_trans.reset(new struct MetaTransTrans); m_trans.reset(new struct MetaTransTrans(m_ancsId));
m_trans->read(reader); m_trans->read(reader);
} }
else if (!type.compare("phasetrans")) else if (!type.compare("phasetrans"))
{ {
m_trans.reset(new struct MetaTransPhaseTrans); m_trans.reset(new struct MetaTransPhaseTrans(m_ancsId));
m_trans->read(reader); m_trans->read(reader);
} }
else else
@ -826,10 +826,23 @@ void ANCS::AnimationSet::read(athena::io::IStreamReader& reader)
atUint16 sectionCount = reader.readUint16Big(); atUint16 sectionCount = reader.readUint16Big();
atUint32 animationCount = reader.readUint32Big(); atUint32 animationCount = reader.readUint32Big();
reader.enumerate(animations, animationCount); animations.clear();
animations.reserve(animationCount);
for (size_t i=0 ; i<animationCount ; ++i)
{
animations.emplace_back(m_ancsId);
animations.back().read(reader);
}
atUint32 transitionCount = reader.readUint32Big(); atUint32 transitionCount = reader.readUint32Big();
reader.enumerate(transitions, transitionCount); transitions.clear();
transitions.reserve(transitionCount);
for (size_t i=0 ; i<transitionCount ; ++i)
{
transitions.emplace_back(m_ancsId);
transitions.back().read(reader);
}
defaultTransition.read(reader); defaultTransition.read(reader);
additiveAnims.clear(); additiveAnims.clear();
@ -845,7 +858,12 @@ void ANCS::AnimationSet::read(athena::io::IStreamReader& reader)
if (sectionCount > 2) if (sectionCount > 2)
{ {
atUint32 halfTransitionCount = reader.readUint32Big(); atUint32 halfTransitionCount = reader.readUint32Big();
reader.enumerate(halfTransitions, halfTransitionCount); halfTransitions.reserve(halfTransitionCount);
for (size_t i=0 ; i<halfTransitionCount ; ++i)
{
halfTransitions.emplace_back(m_ancsId);
halfTransitions.back().read(reader);
}
} }
animResources.clear(); animResources.clear();
@ -943,9 +961,36 @@ void ANCS::AnimationSet::read(athena::io::YAMLDocReader& reader)
{ {
atUint16 sectionCount = reader.readUint16("sectionCount"); atUint16 sectionCount = reader.readUint16("sectionCount");
reader.enumerate("animations", animations); size_t animationCount;
animations.clear();
if (reader.enterSubVector("animations", animationCount))
{
animations.reserve(animationCount);
for (size_t i=0 ; i<animationCount ; ++i)
{
animations.emplace_back(m_ancsId);
reader.enterSubRecord(nullptr);
animations.back().read(reader);
reader.leaveSubRecord();
}
reader.leaveSubVector();
}
size_t transitionCount;
transitions.clear();
if (reader.enterSubVector("transitions", transitionCount))
{
transitions.reserve(transitionCount);
for (size_t i=0 ; i<transitionCount ; ++i)
{
transitions.emplace_back(m_ancsId);
reader.enterSubRecord(nullptr);
transitions.back().read(reader);
reader.leaveSubRecord();
}
reader.leaveSubVector();
}
reader.enumerate("transitions", transitions);
reader.enumerate("defaultTransition", defaultTransition); reader.enumerate("defaultTransition", defaultTransition);
additiveAnims.clear(); additiveAnims.clear();
@ -959,14 +1004,28 @@ void ANCS::AnimationSet::read(athena::io::YAMLDocReader& reader)
halfTransitions.clear(); halfTransitions.clear();
if (sectionCount > 2) if (sectionCount > 2)
{ {
reader.enumerate("halfTransitions", halfTransitions); size_t halfTransitionCount;
if (reader.enterSubVector("halfTransitions", halfTransitionCount))
{
halfTransitions.reserve(halfTransitionCount);
for (size_t i=0 ; i<halfTransitionCount ; ++i)
{
halfTransitions.emplace_back(m_ancsId);
reader.enterSubRecord(nullptr);
halfTransitions.back().read(reader);
reader.leaveSubRecord();
}
reader.leaveSubVector();
}
} }
#if 0
animResources.clear(); animResources.clear();
if (sectionCount > 3) if (sectionCount > 3)
{ {
reader.enumerate("animResources", animResources); reader.enumerate("animResources", animResources);
} }
#endif
} }
void ANCS::AnimationSet::write(athena::io::YAMLDocWriter& writer) const void ANCS::AnimationSet::write(athena::io::YAMLDocWriter& writer) const
@ -1000,10 +1059,12 @@ void ANCS::AnimationSet::write(athena::io::YAMLDocWriter& writer) const
writer.enumerate("halfTransitions", halfTransitions); writer.enumerate("halfTransitions", halfTransitions);
} }
#if 0
if (sectionCount > 3) if (sectionCount > 3)
{ {
writer.enumerate("animResources", animResources); writer.enumerate("animResources", animResources);
} }
#endif
} }
const char* ANCS::AnimationSet::DNAType() const char* ANCS::AnimationSet::DNAType()

View File

@ -22,6 +22,8 @@ struct ANCS : BigYAML
using CSKRType = CSKR; using CSKRType = CSKR;
using ANIMType = ANIM; using ANIMType = ANIM;
ANCS(const UniqueID32& ancsId) : animationSet(ancsId) {}
DECL_YAML DECL_YAML
Value<atUint16> version; Value<atUint16> version;
@ -38,8 +40,8 @@ struct ANCS : BigYAML
atUint32 idx; atUint32 idx;
std::string name; std::string name;
UniqueID32 cmdl; UniqueID32 cmdl;
UniqueID32 cskr; AuxiliaryID32 cskr = _S("skin");
UniqueID32 cinf; AuxiliaryID32 cinf = {_S("layout"), _S(".blend")};
struct Animation : BigYAML struct Animation : BigYAML
{ {
@ -143,7 +145,7 @@ struct ANCS : BigYAML
std::vector<Effect> effects; std::vector<Effect> effects;
UniqueID32 cmdlOverlay; UniqueID32 cmdlOverlay;
UniqueID32 cskrOverlay; AuxiliaryID32 cskrOverlay = _S("skin");
std::vector<atUint32> animIdxs; std::vector<atUint32> animIdxs;
}; };
@ -154,6 +156,9 @@ struct ANCS : BigYAML
{ {
DECL_YAML DECL_YAML
Delete expl; Delete expl;
const UniqueID32& m_ancsId;
AnimationSet(const UniqueID32& ancsId)
: m_ancsId(ancsId), defaultTransition(ancsId) {}
struct IMetaAnim : BigYAML struct IMetaAnim : BigYAML
{ {
@ -168,26 +173,98 @@ struct ANCS : BigYAML
Sequence = 4 Sequence = 4
} m_type; } m_type;
const char* m_typeStr; const char* m_typeStr;
IMetaAnim(Type type, const char* typeStr) const UniqueID32& m_ancsId;
: m_type(type), m_typeStr(typeStr) {} IMetaAnim(Type type, const char* typeStr, const UniqueID32& ancsId)
: m_type(type), m_typeStr(typeStr), m_ancsId(ancsId) {}
virtual void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)=0; virtual void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)=0;
}; };
struct MetaAnimFactory : BigYAML struct MetaAnimFactory : BigYAML
{ {
DECL_YAML DECL_YAML
Delete expl; Delete expl;
const UniqueID32& m_ancsId;
std::unique_ptr<IMetaAnim> m_anim; std::unique_ptr<IMetaAnim> m_anim;
MetaAnimFactory(const UniqueID32& ancsId) : m_ancsId(ancsId) {}
}; };
struct MetaAnimPrimitive : IMetaAnim struct MetaAnimPrimitive : IMetaAnim
{ {
MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {} MetaAnimPrimitive(const UniqueID32& ancsId) : IMetaAnim(Type::Primitive, "Primitive", ancsId) {}
DECL_YAML
Delete _d;
UniqueID32 animId; UniqueID32 animId;
Value<atUint32> animIdx; Value<atUint32> animIdx;
String<-1> animName; String<-1> animName;
Value<float> unk1; Value<float> unk1;
Value<atUint32> unk2; Value<atUint32> unk2;
void read(athena::io::IStreamReader& __dna_reader)
{
/* animId */
animId.read(__dna_reader);
/* animIdx */
animIdx = __dna_reader.readUint32Big();
/* animName */
animName = __dna_reader.readString(-1);
/* unk1 */
unk1 = __dna_reader.readFloatBig();
/* unk2 */
unk2 = __dna_reader.readUint32Big();
}
void write(athena::io::IStreamWriter& __dna_writer) const
{
/* animId */
animId.write(__dna_writer);
/* animIdx */
__dna_writer.writeUint32Big(animIdx);
/* animName */
__dna_writer.writeString(animName, -1);
/* unk1 */
__dna_writer.writeFloatBig(unk1);
/* unk2 */
__dna_writer.writeUint32Big(unk2);
}
void read(athena::io::YAMLDocReader& __dna_docin)
{
/* animId */
__dna_docin.enumerate("animId", animId);
/* animIdx */
animIdx = __dna_docin.readUint32("animIdx");
/* animName */
animName = __dna_docin.readString("animName");
/* unk1 */
unk1 = __dna_docin.readFloat("unk1");
/* unk2 */
unk2 = __dna_docin.readUint32("unk2");
}
void write(athena::io::YAMLDocWriter& __dna_docout) const
{
/* animId */
DNAANCS::WriteOutAnimId(__dna_docout, m_ancsId, animName);
/* animIdx */
__dna_docout.writeUint32("animIdx", animIdx);
/* animName */
__dna_docout.writeString("animName", animName);
/* unk1 */
__dna_docout.writeFloat("unk1", unk1);
/* unk2 */
__dna_docout.writeUint32("unk2", unk2);
}
static const char* DNAType()
{
return "DataSpec::DNAMP1::ANCS::AnimationSet::MetaAnimPrimitive";
}
size_t binarySize(size_t __isz) const
{
__isz = animId.binarySize(__isz);
__isz += animName.size() + 1;
return __isz + 12;
}
void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{ {
out[animIdx] = {animName, animId, UniqueID32(), false}; out[animIdx] = {animName, animId, UniqueID32(), false};
@ -195,7 +272,8 @@ struct ANCS : BigYAML
}; };
struct MetaAnimBlend : IMetaAnim struct MetaAnimBlend : IMetaAnim
{ {
MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {} MetaAnimBlend(const UniqueID32& ancsId)
: IMetaAnim(Type::Blend, "Blend", ancsId), animA(ancsId), animB(ancsId) {}
DECL_YAML DECL_YAML
MetaAnimFactory animA; MetaAnimFactory animA;
MetaAnimFactory animB; MetaAnimFactory animB;
@ -210,7 +288,8 @@ struct ANCS : BigYAML
}; };
struct MetaAnimPhaseBlend : IMetaAnim struct MetaAnimPhaseBlend : IMetaAnim
{ {
MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {} MetaAnimPhaseBlend(const UniqueID32& ancsId)
: IMetaAnim(Type::PhaseBlend, "PhaseBlend", ancsId), animA(ancsId), animB(ancsId) {}
DECL_YAML DECL_YAML
MetaAnimFactory animA; MetaAnimFactory animA;
MetaAnimFactory animB; MetaAnimFactory animB;
@ -225,17 +304,77 @@ struct ANCS : BigYAML
}; };
struct MetaAnimRandom : IMetaAnim struct MetaAnimRandom : IMetaAnim
{ {
MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {} MetaAnimRandom(const UniqueID32& ancsId) : IMetaAnim(Type::Random, "Random", ancsId) {}
DECL_YAML Delete _d;
Value<atUint32> animCount; Value<atUint32> animCount;
struct Child : BigYAML struct Child : BigYAML
{ {
DECL_YAML DECL_YAML
MetaAnimFactory anim; MetaAnimFactory anim;
Value<atUint32> probability; Value<atUint32> probability;
Child(const UniqueID32& ancsId) : anim(ancsId) {}
}; };
Vector<Child, DNA_COUNT(animCount)> children; Vector<Child, DNA_COUNT(animCount)> children;
void read(athena::io::IStreamReader& __dna_reader)
{
/* animCount */
animCount = __dna_reader.readUint32Big();
/* children */
children.clear();
children.reserve(animCount);
for (size_t i=0 ; i<animCount ; ++i)
{
children.emplace_back(m_ancsId);
children.back().read(__dna_reader);
}
}
void write(athena::io::IStreamWriter& __dna_writer) const
{
/* animCount */
__dna_writer.writeUint32Big(animCount);
/* children */
__dna_writer.enumerate(children);
}
void read(athena::io::YAMLDocReader& __dna_docin)
{
/* animCount squelched */
/* children */
size_t childCount;
__dna_docin.enterSubVector("children", childCount);
animCount = childCount;
children.clear();
children.reserve(childCount);
for (size_t i=0 ; i<childCount ; ++i)
{
children.emplace_back(m_ancsId);
__dna_docin.enterSubRecord(nullptr);
children.back().read(__dna_docin);
__dna_docin.leaveSubRecord();
}
__dna_docin.leaveSubVector();
}
void write(athena::io::YAMLDocWriter& __dna_docout) const
{
/* animCount squelched */
/* children */
__dna_docout.enumerate("children", children);
}
static const char* DNAType()
{
return "DataSpec::DNAMP1::ANCS::AnimationSet::MetaAnimRandom";
}
size_t binarySize(size_t __isz) const
{
__isz = __EnumerateSize(__isz, children);
return __isz + 4;
}
void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{ {
for (const auto& child : children) for (const auto& child : children)
@ -244,11 +383,70 @@ struct ANCS : BigYAML
}; };
struct MetaAnimSequence : IMetaAnim struct MetaAnimSequence : IMetaAnim
{ {
MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {} MetaAnimSequence(const UniqueID32& ancsId) : IMetaAnim(Type::Sequence, "Sequence", ancsId) {}
DECL_YAML Delete _d;
Value<atUint32> animCount; Value<atUint32> animCount;
Vector<MetaAnimFactory, DNA_COUNT(animCount)> children; Vector<MetaAnimFactory, DNA_COUNT(animCount)> children;
void read(athena::io::IStreamReader& __dna_reader)
{
/* animCount */
animCount = __dna_reader.readUint32Big();
/* children */
children.clear();
children.reserve(animCount);
for (size_t i=0 ; i<animCount ; ++i)
{
children.emplace_back(m_ancsId);
children.back().read(__dna_reader);
}
}
void write(athena::io::IStreamWriter& __dna_writer) const
{
/* animCount */
__dna_writer.writeUint32Big(animCount);
/* children */
__dna_writer.enumerate(children);
}
void read(athena::io::YAMLDocReader& __dna_docin)
{
/* animCount squelched */
/* children */
size_t childCount;
__dna_docin.enterSubVector("children", childCount);
animCount = childCount;
children.clear();
children.reserve(childCount);
for (size_t i=0 ; i<childCount ; ++i)
{
children.emplace_back(m_ancsId);
__dna_docin.enterSubRecord(nullptr);
children.back().read(__dna_docin);
__dna_docin.leaveSubRecord();
}
__dna_docin.leaveSubVector();
}
void write(athena::io::YAMLDocWriter& __dna_docout) const
{
/* animCount squelched */
/* children */
__dna_docout.enumerate("children", children);
}
static const char* DNAType()
{
return "DataSpec::DNAMP1::ANCS::AnimationSet::MetaAnimSequence";
}
size_t binarySize(size_t __isz) const
{
__isz = __EnumerateSize(__isz, children);
return __isz + 4;
}
void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{ {
for (const auto& child : children) for (const auto& child : children)
@ -261,6 +459,7 @@ struct ANCS : BigYAML
DECL_YAML DECL_YAML
String<-1> name; String<-1> name;
MetaAnimFactory metaAnim; MetaAnimFactory metaAnim;
Animation(const UniqueID32& ancsId) : metaAnim(ancsId) {}
}; };
std::vector<Animation> animations; std::vector<Animation> animations;
@ -276,24 +475,29 @@ struct ANCS : BigYAML
NoTrans = 3, NoTrans = 3,
} m_type; } m_type;
const char* m_typeStr; const char* m_typeStr;
IMetaTrans(Type type, const char* typeStr) const UniqueID32& m_ancsId;
: m_type(type), m_typeStr(typeStr) {} IMetaTrans(Type type, const char* typeStr, const UniqueID32& ancsId)
: m_type(type), m_typeStr(typeStr), m_ancsId(ancsId) {}
}; };
struct MetaTransFactory : BigYAML struct MetaTransFactory : BigYAML
{ {
DECL_YAML DECL_YAML
Delete expl; Delete expl;
const UniqueID32& m_ancsId;
std::unique_ptr<IMetaTrans> m_trans; std::unique_ptr<IMetaTrans> m_trans;
MetaTransFactory(const UniqueID32& ancsId) : m_ancsId(ancsId) {}
}; };
struct MetaTransMetaAnim : IMetaTrans struct MetaTransMetaAnim : IMetaTrans
{ {
MetaTransMetaAnim() : IMetaTrans(Type::MetaAnim, "MetaAnim") {} MetaTransMetaAnim(const UniqueID32& ancsId)
: IMetaTrans(Type::MetaAnim, "MetaAnim", ancsId), anim(ancsId) {}
DECL_YAML DECL_YAML
MetaAnimFactory anim; MetaAnimFactory anim;
}; };
struct MetaTransTrans : IMetaTrans struct MetaTransTrans : IMetaTrans
{ {
MetaTransTrans() : IMetaTrans(Type::Trans, "Trans") {} MetaTransTrans(const UniqueID32& ancsId)
: IMetaTrans(Type::Trans, "Trans", ancsId) {}
DECL_YAML DECL_YAML
Value<float> time; Value<float> time;
Value<atUint32> unk1; Value<atUint32> unk1;
@ -303,7 +507,8 @@ struct ANCS : BigYAML
}; };
struct MetaTransPhaseTrans : IMetaTrans struct MetaTransPhaseTrans : IMetaTrans
{ {
MetaTransPhaseTrans() : IMetaTrans(Type::PhaseTrans, "PhaseTrans") {} MetaTransPhaseTrans(const UniqueID32& ancsId)
: IMetaTrans(Type::PhaseTrans, "PhaseTrans", ancsId) {}
DECL_YAML DECL_YAML
Value<float> time; Value<float> time;
Value<atUint32> unk1; Value<atUint32> unk1;
@ -319,6 +524,7 @@ struct ANCS : BigYAML
Value<atUint32> animIdxA; Value<atUint32> animIdxA;
Value<atUint32> animIdxB; Value<atUint32> animIdxB;
MetaTransFactory metaTrans; MetaTransFactory metaTrans;
Transition(const UniqueID32& ancsId) : metaTrans(ancsId) {}
}; };
std::vector<Transition> transitions; std::vector<Transition> transitions;
MetaTransFactory defaultTransition; MetaTransFactory defaultTransition;
@ -340,6 +546,7 @@ struct ANCS : BigYAML
DECL_YAML DECL_YAML
Value<atUint32> animIdx; Value<atUint32> animIdx;
MetaTransFactory metaTrans; MetaTransFactory metaTrans;
HalfTransition(const UniqueID32& ancsId) : metaTrans(ancsId) {}
}; };
std::vector<HalfTransition> halfTransitions; std::vector<HalfTransition> halfTransitions;
@ -388,6 +595,16 @@ struct ANCS : BigYAML
} }
} }
void fixupPaths(const UniqueID32& ancsId)
{
for (CharacterSet::CharacterInfo& character : characterSet.characters)
{
character.cskr = character.cmdl;
character.cinf = ancsId;
character.cskrOverlay = character.cmdlOverlay;
}
}
static bool Extract(const SpecBase& dataSpec, static bool Extract(const SpecBase& dataSpec,
PAKEntryReadStream& rs, PAKEntryReadStream& rs,
const hecl::ProjectPath& outPath, const hecl::ProjectPath& outPath,
@ -406,8 +623,9 @@ struct ANCS : BigYAML
yamlType == hecl::ProjectPath::Type::None || yamlType == hecl::ProjectPath::Type::None ||
blendType == hecl::ProjectPath::Type::None) blendType == hecl::ProjectPath::Type::None)
{ {
ANCS ancs; ANCS ancs(entry.id);
ancs.read(rs); ancs.read(rs);
ancs.fixupPaths(entry.id);
if (force || yamlType == hecl::ProjectPath::Type::None) if (force || yamlType == hecl::ProjectPath::Type::None)
{ {
@ -441,7 +659,7 @@ struct ANCS : BigYAML
if (!BigYAML::ValidateFromYAMLFile<ANCS>(yamlReader)) if (!BigYAML::ValidateFromYAMLFile<ANCS>(yamlReader))
Log.report(logvisor::Fatal, _S("'%s' is not urde::DNAMP1::ANCS type"), Log.report(logvisor::Fatal, _S("'%s' is not urde::DNAMP1::ANCS type"),
yamlPath.getRelativePath().c_str()); yamlPath.getRelativePath().c_str());
ANCS ancs; ANCS ancs(UniqueID32::kInvalidId);
ancs.read(yamlReader); ancs.read(yamlReader);

View File

@ -227,22 +227,22 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
if (entry.second->type == FOURCC('ANCS')) if (entry.second->type == FOURCC('ANCS'))
{ {
PAKEntryReadStream rs = entry.second->beginReadStream(m_node); PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
ANCS ancs; ANCS ancs(entry.first);
ancs.read(rs); ancs.read(rs);
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
{ {
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf); addTo[ci.cmdl] = std::make_pair(ci.cskr.getBaseId(), ci.cinf.getBaseId());
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl); PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl);
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr); PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr.getBaseId());
PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf); PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf.getBaseId());
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_model", entry.first.toUint32(), ci.name.c_str()); cmdlEnt->name = hecl::Format("ANCS_%08X_%s_model", entry.first.toUint32(), ci.name.c_str());
cskrEnt->name = hecl::Format("ANCS_%08X_%s_skin", entry.first.toUint32(), ci.name.c_str()); cskrEnt->name = hecl::Format("ANCS_%08X_%s_skin", entry.first.toUint32(), ci.name.c_str());
cinfEnt->name = hecl::Format("ANCS_%08X_%s_skel", entry.first.toUint32(), ci.name.c_str()); cinfEnt->name = hecl::Format("ANCS_%08X_%s_skel", entry.first.toUint32(), ci.name.c_str());
if (ci.cmdlOverlay && ci.cskrOverlay) if (ci.cmdlOverlay && ci.cskrOverlay)
{ {
addTo[ci.cmdlOverlay] = std::make_pair(ci.cskrOverlay, ci.cinf); addTo[ci.cmdlOverlay] = std::make_pair(ci.cskrOverlay.getBaseId(), ci.cinf.getBaseId());
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlOverlay); PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlOverlay);
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrOverlay); PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrOverlay.getBaseId());
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_overmodel", entry.first.toUint32(), ci.name.c_str()); cmdlEnt->name = hecl::Format("ANCS_%08X_%s_overmodel", entry.first.toUint32(), ci.name.c_str());
cskrEnt->name = hecl::Format("ANCS_%08X_%s_overskin", entry.first.toUint32(), ci.name.c_str()); cskrEnt->name = hecl::Format("ANCS_%08X_%s_overskin", entry.first.toUint32(), ci.name.c_str());
} }

View File

@ -12,12 +12,12 @@ UniqueID32 AnimationParameters::getCINF(PAKRouter<PAKBridge>& pakRouter) const
return UniqueID32(); return UniqueID32();
const nod::Node* node; const nod::Node* node;
const PAK::Entry* ancsEnt = pakRouter.lookupEntry(animationCharacterSet, &node); const PAK::Entry* ancsEnt = pakRouter.lookupEntry(animationCharacterSet, &node);
ANCS ancs; ANCS ancs(ancsEnt->id);
{ {
PAKEntryReadStream rs = ancsEnt->beginReadStream(*node); PAKEntryReadStream rs = ancsEnt->beginReadStream(*node);
ancs.read(rs); ancs.read(rs);
} }
return ancs.characterSet.characters.at(character).cinf; return ancs.characterSet.characters.at(character).cinf.getBaseId();
} }
} }

View File

@ -354,9 +354,9 @@ struct ActorParameters : BigYAML
LightParameters lightParameters; LightParameters lightParameters;
ScannableParameters scannableParameters; ScannableParameters scannableParameters;
UniqueID32 xrayModel; UniqueID32 xrayModel;
UniqueID32 xraySkin; AuxiliaryID32 xraySkin = _S("skin");
UniqueID32 thermalModel; UniqueID32 thermalModel;
UniqueID32 thermalSkin; AuxiliaryID32 thermalSkin = _S("skin");
Value<bool> unknown1; Value<bool> unknown1;
Value<float> unknown2; Value<float> unknown2;
Value<float> unknown3; Value<float> unknown3;

View File

@ -381,10 +381,23 @@ void ANCS::AnimationSet::read(athena::io::IStreamReader& reader)
atUint16 sectionCount = reader.readUint16Big(); atUint16 sectionCount = reader.readUint16Big();
atUint32 animationCount = reader.readUint32Big(); atUint32 animationCount = reader.readUint32Big();
reader.enumerate(animations, animationCount); animations.clear();
animations.reserve(animationCount);
for (atUint32 i=0 ; i<animationCount ; ++i)
{
animations.emplace_back(m_ancsId);
animations.back().read(reader);
}
atUint32 transitionCount = reader.readUint32Big(); atUint32 transitionCount = reader.readUint32Big();
reader.enumerate(transitions, transitionCount); transitions.clear();
transitions.reserve(transitionCount);
for (atUint32 i=0 ; i<transitionCount ; ++i)
{
transitions.emplace_back(m_ancsId);
transitions.back().read(reader);
}
defaultTransition.read(reader); defaultTransition.read(reader);
additiveAnims.clear(); additiveAnims.clear();
@ -400,7 +413,13 @@ void ANCS::AnimationSet::read(athena::io::IStreamReader& reader)
if (sectionCount > 2) if (sectionCount > 2)
{ {
atUint32 halfTransitionCount = reader.readUint32Big(); atUint32 halfTransitionCount = reader.readUint32Big();
reader.enumerate(halfTransitions, halfTransitionCount); halfTransitions.clear();
halfTransitions.reserve(halfTransitionCount);
for (atUint32 i=0 ; i<halfTransitionCount ; ++i)
{
halfTransitions.emplace_back(m_ancsId);
halfTransitions.back().read(reader);
}
} }
evnts.clear(); evnts.clear();
@ -498,9 +517,32 @@ void ANCS::AnimationSet::read(athena::io::YAMLDocReader& reader)
{ {
atUint16 sectionCount = reader.readUint16("sectionCount"); atUint16 sectionCount = reader.readUint16("sectionCount");
reader.enumerate("animations", animations); size_t animationCount;
reader.enterSubVector("animations", animationCount);
animations.clear();
animations.reserve(animationCount);
for (size_t i=0 ; i<animationCount ; ++i)
{
animations.emplace_back(m_ancsId);
reader.enterSubRecord(nullptr);
animations.back().read(reader);
reader.leaveSubRecord();
}
reader.leaveSubVector();
size_t transitionCount;
reader.enterSubVector("transitions", transitionCount);
transitions.clear();
transitions.reserve(transitionCount);
for (size_t i=0 ; i<transitionCount ; ++i)
{
transitions.emplace_back(m_ancsId);
reader.enterSubRecord(nullptr);
transitions.back().read(reader);
reader.leaveSubRecord();
}
reader.leaveSubVector();
reader.enumerate("transitions", transitions);
reader.enumerate("defaultTransition", defaultTransition); reader.enumerate("defaultTransition", defaultTransition);
additiveAnims.clear(); additiveAnims.clear();
@ -514,7 +556,17 @@ void ANCS::AnimationSet::read(athena::io::YAMLDocReader& reader)
halfTransitions.clear(); halfTransitions.clear();
if (sectionCount > 2) if (sectionCount > 2)
{ {
reader.enumerate("halfTransitions", halfTransitions); size_t halfTransitionCount;
reader.enterSubVector("halfTransitions", halfTransitionCount);
halfTransitions.reserve(halfTransitionCount);
for (size_t i=0 ; i<halfTransitionCount ; ++i)
{
halfTransitions.emplace_back(m_ancsId);
reader.enterSubRecord(nullptr);
halfTransitions.back().read(reader);
reader.leaveSubRecord();
}
reader.leaveSubVector();
} }
evnts.clear(); evnts.clear();

View File

@ -22,6 +22,8 @@ struct ANCS : BigYAML
using CSKRType = CSKR; using CSKRType = CSKR;
using ANIMType = ANIM; using ANIMType = ANIM;
ANCS(const UniqueID32& ancsId) : animationSet(ancsId) {}
DECL_YAML DECL_YAML
Value<atUint16> version; Value<atUint16> version;
@ -39,8 +41,8 @@ struct ANCS : BigYAML
atUint32 idx; atUint32 idx;
std::string name; std::string name;
UniqueID32 cmdl; UniqueID32 cmdl;
UniqueID32 cskr; AuxiliaryID32 cskr = _S("skin");
UniqueID32 cinf; AuxiliaryID32 cinf = {_S("layout"), _S("skin")};
struct Animation : BigYAML struct Animation : BigYAML
{ {
@ -86,7 +88,7 @@ struct ANCS : BigYAML
std::vector<Effect> effects; std::vector<Effect> effects;
UniqueID32 cmdlOverlay; UniqueID32 cmdlOverlay;
UniqueID32 cskrOverlay; AuxiliaryID32 cskrOverlay = _S("skin");
std::vector<atUint32> animIdxs; std::vector<atUint32> animIdxs;
@ -108,6 +110,9 @@ struct ANCS : BigYAML
{ {
DECL_YAML DECL_YAML
Delete expl; Delete expl;
const UniqueID32& m_ancsId;
AnimationSet(const UniqueID32& ancsId) : m_ancsId(ancsId), defaultTransition(ancsId) {}
using MP1AnimationSet = DNAMP1::ANCS::AnimationSet; using MP1AnimationSet = DNAMP1::ANCS::AnimationSet;
std::vector<MP1AnimationSet::Animation> animations; std::vector<MP1AnimationSet::Animation> animations;
@ -229,7 +234,7 @@ struct ANCS : BigYAML
yamlType == hecl::ProjectPath::Type::None || yamlType == hecl::ProjectPath::Type::None ||
blendType == hecl::ProjectPath::Type::None) blendType == hecl::ProjectPath::Type::None)
{ {
ANCS ancs; ANCS ancs(entry.id);
ancs.read(rs); ancs.read(rs);
if (force || yamlType == hecl::ProjectPath::Type::None) if (force || yamlType == hecl::ProjectPath::Type::None)

View File

@ -198,13 +198,13 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
if (entry.second->type == FOURCC('ANCS')) if (entry.second->type == FOURCC('ANCS'))
{ {
PAKEntryReadStream rs = entry.second->beginReadStream(m_node); PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
ANCS ancs; ANCS ancs(entry.first);
ancs.read(rs); ancs.read(rs);
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
{ {
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf); addTo[ci.cmdl] = std::make_pair(ci.cskr.getBaseId(), ci.cinf.getBaseId());
if (ci.cmdlOverlay) if (ci.cmdlOverlay)
addTo[ci.cmdlOverlay] = std::make_pair(ci.cskrOverlay, ci.cinf); addTo[ci.cmdlOverlay] = std::make_pair(ci.cskrOverlay.getBaseId(), ci.cinf.getBaseId());
} }
} }
} }

View File

@ -292,7 +292,10 @@ hecl::ProjectPath ProjectResourceFactoryBase::GetCookedPath(const hecl::ProjectP
spec = m_cookSpec->overrideDataSpec(working, m_pcSpec, hecl::SharedBlenderToken); spec = m_cookSpec->overrideDataSpec(working, m_pcSpec, hecl::SharedBlenderToken);
if (!spec) if (!spec)
return {}; return {};
return working.getCookedPath(*spec); if (working.getAuxInfo().size())
return working.getCookedPath(*spec).getWithExtension((_S('.') + working.getAuxInfo()).c_str());
else
return working.getCookedPath(*spec);
} }
bool ProjectResourceFactoryBase::SyncCook(const hecl::ProjectPath& working) bool ProjectResourceFactoryBase::SyncCook(const hecl::ProjectPath& working)

View File

@ -40,7 +40,7 @@ protected:
ProjectResourceFactoryBase& m_parent; ProjectResourceFactoryBase& m_parent;
SObjectTag x0_tag; SObjectTag x0_tag;
IDvdRequest* x8_dvdReq = nullptr; //IDvdRequest* x8_dvdReq = nullptr;
IObj** xc_targetPtr = nullptr; IObj** xc_targetPtr = nullptr;
std::unique_ptr<u8[]> x10_loadBuffer; std::unique_ptr<u8[]> x10_loadBuffer;
u32 x14_resSize = 0; u32 x14_resSize = 0;

View File

@ -11,6 +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 <cstdio> #include <cstdio>
using YAMLNode = athena::io::YAMLNode; using YAMLNode = athena::io::YAMLNode;
@ -20,6 +21,7 @@ namespace urde
void ViewManager::BuildTestPART(urde::IObjectStore& objStore) void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
{ {
TToken<CSkinRules>
m_modelTest = objStore.GetObj("MP1/SamusGun/CMDL_0EF58656.blend"); m_modelTest = objStore.GetObj("MP1/SamusGun/CMDL_0EF58656.blend");
//m_modelTest = objStore.GetObj("CMDL_GameCube"); //m_modelTest = objStore.GetObj("CMDL_GameCube");
m_modelTest.Lock(); m_modelTest.Lock();

View File

@ -11,5 +11,4 @@ add_library(RuntimeCommonCharacter
CTransitionDatabaseGame.hpp CTransitionDatabaseGame.hpp
CHierarchyPoseBuilder.hpp CHierarchyPoseBuilder.cpp CHierarchyPoseBuilder.hpp CHierarchyPoseBuilder.cpp
CPoseAsTransforms.hpp CPoseAsTransforms.cpp CPoseAsTransforms.hpp CPoseAsTransforms.cpp
CSkinRules.hpp CSkinRules.cpp
CVirtualBone.hpp CVirtualBone.cpp) CVirtualBone.hpp CVirtualBone.cpp)

View File

@ -20,5 +20,6 @@ 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

@ -1 +1 @@
Subproject commit 97a5fb2af2b16283af8c9bb619111a49d2869c7d Subproject commit de043503e5d2312ccc10876b0ac3d5ebb91bb768