#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 "../DNAMP2/ANCS.hpp" namespace DataSpec::DNAMP3 { struct CHAR : BigDNA { using CINFType = CINF; using CSKRType = CSKR; using ANIMType = ANIM; AT_DECL_DNA_YAML Value<atUint16> version; struct CharacterInfo : BigDNA { AT_DECL_DNA_YAML String<-1> name; UniqueID64 cmdl; UniqueID64 cskr; Value<atUint32> overlayCount; struct Overlay : BigDNA { AT_DECL_DNA_YAML DNAFourCC type; UniqueID64 cmdl; UniqueID64 cskr; }; Vector<Overlay, AT_DNA_COUNT(overlayCount)> overlays; UniqueID64 cinf; UniqueID64 sand; using MP1CharacterInfo = DNAMP1::ANCS::CharacterSet::CharacterInfo; MP1CharacterInfo::PASDatabase pasDatabase; struct ParticleResData : BigDNA { AT_DECL_DNA_YAML Value<atUint32> partCount; Vector<UniqueID64, AT_DNA_COUNT(partCount)> part; Value<atUint32> swhcCount; Vector<UniqueID64, AT_DNA_COUNT(swhcCount)> swhc; Value<atUint32> unkCount; Vector<UniqueID64, AT_DNA_COUNT(unkCount)> unk; Value<atUint32> elscCount; Vector<UniqueID64, AT_DNA_COUNT(elscCount)> elsc; Value<atUint32> spscCount; Vector<UniqueID64, AT_DNA_COUNT(spscCount)> spsc; Value<atUint32> unk2Count; Vector<UniqueID64, AT_DNA_COUNT(unk2Count)> unk2; } partResData; } characterInfo; struct AnimationInfo : BigDNA { AT_DECL_DNA_YAML struct EVNT : BigDNA { AT_DECL_DNA_YAML Value<atUint32> eventIdx; String<-1> eventName; struct EventBase : BigDNA { AT_DECL_DNA_YAML String<-1> name1; Value<atUint16> unk0; String<-1> name2; Value<atUint16> type; Value<atUint32> unk1; Value<atUint32> unk2; Value<atUint32> unk3; Value<atUint32> unk4; Value<atUint8> unk5; Value<float> unk6; Value<atUint32> unk7; Value<atUint32> unk8; Value<atUint32> unk9; Value<atUint32> unk10; Value<atUint32> unk11; Value<atUint32> unk12; Value<atUint32> unk13; }; struct EffectEvent : EventBase { AT_DECL_DNA_YAML DNAFourCC effectType; UniqueID64 effectId; Value<float> scale; Value<atUint32> parentMode; }; Value<atUint32> effectCount; Vector<EffectEvent, AT_DNA_COUNT(effectCount)> effectEvents; struct SFXEvent : EventBase { AT_DECL_DNA_YAML Delete expl; UniqueID64 caudId; Value<atUint32> unk1_; Value<atUint32> unk2_; Value<atUint32> unk3_; std::vector<float> unk3Vals; Value<atUint32> extraType; Value<float> extraFloat; }; Value<atUint32> sfxCount; Vector<SFXEvent, AT_DNA_COUNT(sfxCount)> sfxEvents; }; Value<atUint32> evntCount; Vector<EVNT, AT_DNA_COUNT(evntCount)> evnts; 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(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID64>>& out) = 0; }; struct MetaAnimFactory : BigDNA { AT_DECL_DNA_YAML Delete expl; std::unique_ptr<IMetaAnim> m_anim; }; struct MetaAnimPrimitive : IMetaAnim { MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {} AT_DECL_DNA_YAMLV UniqueID64 animId; Value<atUint32> animIdx; String<-1> animName; Value<float> unk1; Value<atUint32> unk2; void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID64>>& out) override { out[animIdx] = {animName, animId, UniqueID64(), false}; } }; struct MetaAnimBlend : IMetaAnim { MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {} AT_DECL_DNA_YAMLV MetaAnimFactory animA; MetaAnimFactory animB; Value<float> unkFloat; Value<atUint8> unk; void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID64>>& out) override { animA.m_anim->gatherPrimitives(out); animB.m_anim->gatherPrimitives(out); } }; struct MetaAnimPhaseBlend : IMetaAnim { MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {} AT_DECL_DNA_YAMLV MetaAnimFactory animA; MetaAnimFactory animB; Value<float> unkFloat; Value<atUint8> unk; void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID64>>& out) override { animA.m_anim->gatherPrimitives(out); animB.m_anim->gatherPrimitives(out); } }; struct MetaAnimRandom : IMetaAnim { MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {} AT_DECL_DNA_YAMLV Value<atUint32> animCount; struct Child : BigDNA { AT_DECL_DNA_YAML MetaAnimFactory anim; Value<atUint32> probability; }; Vector<Child, AT_DNA_COUNT(animCount)> children; void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID64>>& out) override { for (const auto& child : children) child.anim.m_anim->gatherPrimitives(out); } }; struct MetaAnimSequence : IMetaAnim { MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {} AT_DECL_DNA_YAMLV Value<atUint32> animCount; Vector<MetaAnimFactory, AT_DNA_COUNT(animCount)> children; void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID64>>& out) override { for (const auto& child : children) child.m_anim->gatherPrimitives(out); } }; struct Animation : BigDNA { AT_DECL_DNA_YAML String<-1> name; MetaAnimFactory metaAnim; }; Value<atUint32> animationCount; Vector<Animation, AT_DNA_COUNT(animationCount)> animations; struct ActionAABB : BigDNA { AT_DECL_DNA_YAML UniqueID64 animId; Value<atVec3f> aabb[2]; }; Value<atUint32> animAABBCount; Vector<ActionAABB, AT_DNA_COUNT(animAABBCount)> animAABBs; Value<atUint8> unkByte; Value<atUint32> additiveMapCount; Vector<bool, AT_DNA_COUNT(additiveMapCount)> additiveMap; } animationInfo; struct HitboxSet : BigDNA { AT_DECL_DNA_YAML String<-1> name; Value<atUint32> hitboxCount; struct Hitbox : BigDNA { AT_DECL_DNA_YAML Value<atUint32> unk1; Value<atUint32> unk2; Value<atUint32> unk3; Value<atUint32> unk4; Value<atUint32> unk5; Value<float> unk6; Value<float> unk7; Value<float> unk8; Value<float> unk9; Value<float> unk10; Value<float> unk11; Value<float> unk12; Value<float> unk13; String<-1> boneName; Value<float> unk14; }; Vector<Hitbox, AT_DNA_COUNT(hitboxCount)> hitboxes; }; Value<atUint32> hitboxSetCount; Vector<HitboxSet, AT_DNA_COUNT(hitboxSetCount)> hitboxSets; void getCharacterResInfo(std::vector<DNAANCS::CharacterResInfo<UniqueID64>>& out) const { out.clear(); out.reserve(1); out.emplace_back(); DNAANCS::CharacterResInfo<UniqueID64>& chOut = out.back(); chOut.name = characterInfo.name; chOut.cmdl = characterInfo.cmdl; chOut.cskr = characterInfo.cskr; chOut.cinf = characterInfo.cinf; for (const CharacterInfo::Overlay& overlay : characterInfo.overlays) chOut.overlays.emplace_back(overlay.type.toString(), std::make_pair(overlay.cmdl, overlay.cskr)); } void getAnimationResInfo(PAKRouter<PAKBridge>* pakRouter, std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID64>>& out) const { out.clear(); for (const AnimationInfo::Animation& ai : animationInfo.animations) ai.metaAnim.m_anim->gatherPrimitives(out); for (auto& animRes : out) animRes.second.additive = animationInfo.additiveMap.at(animRes.first); } 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) { hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true); hecl::ProjectPath::Type yamlType = yamlPath.getPathType(); hecl::ProjectPath blendPath = outPath.getWithExtension(_SYS_STR(".blend"), true); hecl::ProjectPath::Type blendType = blendPath.getPathType(); if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) { CHAR aChar; aChar.read(rs); if (force || yamlType == hecl::ProjectPath::Type::None) { athena::io::FileWriter writer(yamlPath.getAbsolutePath()); athena::io::ToYAMLStream(aChar, writer); } if (force || blendType == hecl::ProjectPath::Type::None) { DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, CHAR, MaterialSet, DNACMDL::SurfaceHeader_3, 4>( btok, aChar, blendPath, pakRouter, entry, dataSpec, fileChanged, force); } } return true; } }; } // namespace DataSpec::DNAMP3