metaforce/DataSpec/DNAMP1/ANCS.hpp

429 lines
14 KiB
C++

#pragma once
#include <map>
#include "DataSpec/DNACommon/DNACommon.hpp"
#include "DataSpec/DNACommon/ANCS.hpp"
#include "CMDLMaterials.hpp"
#include "CINF.hpp"
#include "CSKR.hpp"
#include "ANIM.hpp"
#include "EVNT.hpp"
#include "athena/FileReader.hpp"
namespace DataSpec::DNAMP1 {
struct ANCS : BigDNA {
using CINFType = CINF;
using CSKRType = CSKR;
using ANIMType = ANIM;
AT_DECL_DNA_YAML
Value<atUint16> version;
struct CharacterSet : BigDNA {
AT_DECL_DNA_YAML
Value<atUint16> version;
Value<atUint32> characterCount;
struct CharacterInfo : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
atUint32 idx;
std::string name;
UniqueID32 cmdl;
UniqueID32 cskr;
UniqueID32 cinf;
struct Animation : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
String<-1> strA;
String<-1> strB;
};
std::vector<Animation> animations;
struct PASDatabase : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> magic;
Value<atUint32> animStateCount;
Value<atUint32> defaultState;
struct AnimState : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
atUint32 id;
struct ParmInfo : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
enum class DataType { Int32 = 0, UInt32 = 1, Float = 2, Bool = 3, Enum = 4 };
union Parm {
atInt32 int32;
atUint32 uint32;
float float32;
bool bool1;
Parm() : int32(0) {}
Parm(atInt32 val) : int32(val) {}
Parm(atUint32 val) : uint32(val) {}
Parm(float val) : float32(val) {}
Parm(bool val) : bool1(val) {}
};
atUint32 parmType;
atUint32 weightFunction;
float weight;
Parm range[2];
};
std::vector<ParmInfo> parmInfos;
struct AnimInfo {
atUint32 id;
std::vector<ParmInfo::Parm> parmVals;
};
std::vector<AnimInfo> animInfos;
};
Vector<AnimState, AT_DNA_COUNT(animStateCount)> animStates;
} pasDatabase;
struct ParticleResData {
std::vector<UniqueID32> part;
std::vector<UniqueID32> swhc;
std::vector<UniqueID32> unk;
std::vector<UniqueID32> elsc;
} partResData;
atUint32 unk1 = 0;
struct ActionAABB : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atVec3f> aabb[2];
};
std::vector<ActionAABB> animAABBs;
struct Effect : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> compCount;
struct EffectComponent : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
DNAFourCC type;
UniqueID32 id;
String<-1> locator;
Value<float> scale;
Value<atUint32> parentMode;
Value<atUint32> flags;
};
Vector<EffectComponent, AT_DNA_COUNT(compCount)> comps;
};
std::vector<Effect> effects;
UniqueID32Zero cmdlIce;
UniqueID32Zero cskrIce;
std::vector<atUint32> animIdxs;
};
Vector<CharacterInfo, AT_DNA_COUNT(characterCount)> characters;
} characterSet;
struct AnimationSet : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
struct MetaAnimPrimitive;
struct IMetaAnim : BigDNAVYaml {
Delete expl;
enum class Type { Primitive = 0, Blend = 1, PhaseBlend = 2, Random = 3, Sequence = 4 } m_type;
const char* m_typeStr;
IMetaAnim(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {}
virtual void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) = 0;
virtual bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) = 0;
};
struct MetaAnimFactory : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
std::unique_ptr<IMetaAnim> m_anim;
};
struct MetaAnimPrimitive : IMetaAnim {
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {}
UniqueID32 animId;
Value<atUint32> animIdx;
String<-1> animName;
Value<float> unk1;
Value<atUint32> unk2;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out);
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) { return func(*this); }
};
struct MetaAnimBlend : IMetaAnim {
MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory animA;
MetaAnimFactory animB;
Value<float> unkFloat;
Value<atUint8> unk;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
animA.m_anim->gatherPrimitives(pakRouter, out);
animB.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
if (!animA.m_anim->enumeratePrimitives(func))
return false;
if (!animB.m_anim->enumeratePrimitives(func))
return false;
return true;
}
};
struct MetaAnimPhaseBlend : IMetaAnim {
MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory animA;
MetaAnimFactory animB;
Value<float> unkFloat;
Value<atUint8> unk;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
animA.m_anim->gatherPrimitives(pakRouter, out);
animB.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
if (!animA.m_anim->enumeratePrimitives(func))
return false;
if (!animB.m_anim->enumeratePrimitives(func))
return false;
return true;
}
};
struct MetaAnimRandom : IMetaAnim {
MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atUint32> animCount;
struct Child : BigDNA {
AT_DECL_DNA
MetaAnimFactory anim;
Value<atUint32> probability;
};
Vector<Child, AT_DNA_COUNT(animCount)> children;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
for (const auto& child : children)
child.anim.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
for (auto& child : children)
if (!child.anim.m_anim->enumeratePrimitives(func))
return false;
return true;
}
};
struct MetaAnimSequence : IMetaAnim {
MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atUint32> animCount;
Vector<MetaAnimFactory, AT_DNA_COUNT(animCount)> children;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
for (const auto& child : children)
child.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
for (auto& child : children)
if (!child.m_anim->enumeratePrimitives(func))
return false;
return true;
}
};
struct Animation : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
MetaAnimFactory metaAnim;
};
std::vector<Animation> animations;
struct IMetaTrans : BigDNAVYaml {
Delete expl;
enum class Type {
MetaAnim = 0,
Trans = 1,
PhaseTrans = 2,
NoTrans = 3,
} m_type;
const char* m_typeStr;
IMetaTrans(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {}
virtual void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {}
virtual bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) { return true; }
};
struct MetaTransFactory : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
std::unique_ptr<IMetaTrans> m_trans;
};
struct MetaTransMetaAnim : IMetaTrans {
MetaTransMetaAnim() : IMetaTrans(Type::MetaAnim, "MetaAnim") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory anim;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
anim.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
return anim.m_anim->enumeratePrimitives(func);
}
};
struct MetaTransTrans : IMetaTrans {
MetaTransTrans() : IMetaTrans(Type::Trans, "Trans") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<float> transDurTime;
Value<atUint32> transDurTimeMode;
Value<bool> unk2;
Value<bool> runA;
Value<atUint32> flags;
};
struct MetaTransPhaseTrans : IMetaTrans {
MetaTransPhaseTrans() : IMetaTrans(Type::PhaseTrans, "PhaseTrans") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<float> transDurTime;
Value<atUint32> transDurTimeMode;
Value<bool> unk2;
Value<bool> runA;
Value<atUint32> flags;
};
struct Transition : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> unk;
Value<atUint32> animIdxA;
Value<atUint32> animIdxB;
MetaTransFactory metaTrans;
};
std::vector<Transition> transitions;
MetaTransFactory defaultTransition;
struct AdditiveAnimationInfo : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
Value<float> fadeInDur;
Value<float> fadeOutDur;
};
std::vector<AdditiveAnimationInfo> additiveAnims;
float additiveDefaultFadeInDur = 0.0;
float additiveDefaultFadeOutDur = 0.0;
struct HalfTransition : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
MetaTransFactory metaTrans;
};
std::vector<HalfTransition> halfTransitions;
struct AnimationResources : BigDNA {
AT_DECL_DNA_YAML
UniqueID32 animId;
UniqueID32 evntId;
};
std::vector<AnimationResources> animResources;
} animationSet;
void getCharacterResInfo(std::vector<DNAANCS::CharacterResInfo<UniqueID32>>& out) const {
out.clear();
out.reserve(characterSet.characters.size());
for (const CharacterSet::CharacterInfo& ci : characterSet.characters) {
out.emplace_back();
DNAANCS::CharacterResInfo<UniqueID32>& chOut = out.back();
chOut.name = ci.name;
chOut.cmdl = ci.cmdl;
chOut.cskr = ci.cskr;
chOut.cinf = ci.cinf;
if (ci.cmdlIce)
chOut.overlays.emplace_back("ICE", std::make_pair(ci.cmdlIce, ci.cskrIce));
}
}
void getAnimationResInfo(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) const {
out.clear();
for (const AnimationSet::Animation& ai : animationSet.animations)
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
anim->gatherPrimitives(pakRouter, out);
for (const AnimationSet::Transition& ti : animationSet.transitions)
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
trans->gatherPrimitives(pakRouter, out);
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
trans->gatherPrimitives(pakRouter, out);
}
void enumeratePrimitives(const std::function<bool(AnimationSet::MetaAnimPrimitive& prim)>& func) {
for (const AnimationSet::Animation& ai : animationSet.animations)
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
anim->enumeratePrimitives(func);
for (const AnimationSet::Transition& ti : animationSet.transitions)
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
trans->enumeratePrimitives(func);
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
trans->enumeratePrimitives(func);
}
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, int charIdx) const {
auto doCi = [&](const CharacterSet::CharacterInfo& ci) {
for (const auto& id : ci.partResData.part)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.swhc)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.unk)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.elsc)
g_curSpec->flattenDependencies(id, pathsOut);
};
if (charIdx < 0)
for (const CharacterSet::CharacterInfo& ci : characterSet.characters)
doCi(ci);
else if (charIdx < characterSet.characters.size())
doCi(characterSet.characters[charIdx]);
}
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor);
static bool CookCINF(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor);
static bool CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc);
static bool CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc);
static bool CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
hecl::blender::DataStream& ds, bool pc);
};
} // namespace DataSpec::DNAMP1