mirror of https://github.com/AxioDL/metaforce.git
Preparing for CHAR/ANIM implementation
This commit is contained in:
parent
a5f6c2548b
commit
21d8b9dcd3
|
@ -107,7 +107,7 @@ bool ReadANCSToBlender(HECL::BlenderConnection& conn,
|
||||||
cinfsDone.insert(info.cinf);
|
cinfsDone.insert(info.cinf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
os.format("arm_obj = bpy.data.objects['CINF_%08X']\n", info.cinf.toUint32());
|
os.format("arm_obj = bpy.data.objects['CINF_%s']\n", info.cinf.toString().c_str());
|
||||||
os << "actor_subtype.linked_armature = arm_obj.name\n";
|
os << "actor_subtype.linked_armature = arm_obj.name\n";
|
||||||
|
|
||||||
/* Link CMDL */
|
/* Link CMDL */
|
||||||
|
|
|
@ -486,6 +486,52 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return &search->second;
|
return &search->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HECL::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx) const
|
||||||
|
{
|
||||||
|
if (!m_bridges)
|
||||||
|
LogDNACommon.report(LogVisor::FatalError,
|
||||||
|
"PAKRouter::build() must be called before PAKRouter::getAreaLayerWorking()");
|
||||||
|
auto bridgePathIt = m_bridgePaths.cbegin();
|
||||||
|
for (const BRIDGETYPE& bridge : *m_bridges)
|
||||||
|
{
|
||||||
|
for (const auto& level : bridge.m_levelDeps)
|
||||||
|
for (const auto& area : level.second.areas)
|
||||||
|
if (area.first == areaId)
|
||||||
|
{
|
||||||
|
HECL::ProjectPath levelPath(bridgePathIt->first, level.second.name);
|
||||||
|
HECL::ProjectPath areaPath(levelPath, area.second.name);
|
||||||
|
if (layerIdx < 0)
|
||||||
|
return areaPath;
|
||||||
|
return HECL::ProjectPath(areaPath, area.second.layers.at(layerIdx).name);
|
||||||
|
}
|
||||||
|
++bridgePathIt;
|
||||||
|
}
|
||||||
|
return HECL::ProjectPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
HECL::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx) const
|
||||||
|
{
|
||||||
|
if (!m_bridges)
|
||||||
|
LogDNACommon.report(LogVisor::FatalError,
|
||||||
|
"PAKRouter::build() must be called before PAKRouter::getAreaLayerCooked()");
|
||||||
|
auto bridgePathIt = m_bridgePaths.cbegin();
|
||||||
|
for (const BRIDGETYPE& bridge : *m_bridges)
|
||||||
|
{
|
||||||
|
for (const auto& level : bridge.m_levelDeps)
|
||||||
|
for (const auto& area : level.second.areas)
|
||||||
|
if (area.first == areaId)
|
||||||
|
{
|
||||||
|
HECL::ProjectPath levelPath(bridgePathIt->second, level.second.name);
|
||||||
|
HECL::ProjectPath areaPath(levelPath, area.second.name);
|
||||||
|
if (layerIdx < 0)
|
||||||
|
return areaPath;
|
||||||
|
return HECL::ProjectPath(areaPath, area.second.layers.at(layerIdx).name);
|
||||||
|
}
|
||||||
|
++bridgePathIt;
|
||||||
|
}
|
||||||
|
return HECL::ProjectPath();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ class PAKBridge
|
||||||
HECL::Database::Project& m_project;
|
HECL::Database::Project& m_project;
|
||||||
const NOD::DiscBase::IPartition::Node& m_node;
|
const NOD::DiscBase::IPartition::Node& m_node;
|
||||||
PAK m_pak;
|
PAK m_pak;
|
||||||
|
UniqueResult uniqueCheck(const PAK::Entry& entry);
|
||||||
|
public:
|
||||||
struct Level
|
struct Level
|
||||||
{
|
{
|
||||||
HECL::SystemString name;
|
HECL::SystemString name;
|
||||||
|
@ -35,8 +37,7 @@ class PAKBridge
|
||||||
};
|
};
|
||||||
std::unordered_map<UniqueID32, Level> m_levelDeps;
|
std::unordered_map<UniqueID32, Level> m_levelDeps;
|
||||||
HECL::SystemString m_levelString;
|
HECL::SystemString m_levelString;
|
||||||
UniqueResult uniqueCheck(const PAK::Entry& entry);
|
|
||||||
public:
|
|
||||||
PAKBridge(HECL::Database::Project& project, const NOD::DiscBase::IPartition::Node& node);
|
PAKBridge(HECL::Database::Project& project, const NOD::DiscBase::IPartition::Node& node);
|
||||||
void build();
|
void build();
|
||||||
static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry);
|
static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry);
|
||||||
|
|
|
@ -47,7 +47,7 @@ void DeafBabeSendToBlender(HECL::BlenderConnection::PyOutStream& os, const DEAFB
|
||||||
"face.material_index = select_material(0x%08X)\n"
|
"face.material_index = select_material(0x%08X)\n"
|
||||||
"face.smooth = False\n"
|
"face.smooth = False\n"
|
||||||
"\n",
|
"\n",
|
||||||
triMat.material);
|
atUint32(triMat.material));
|
||||||
}
|
}
|
||||||
|
|
||||||
db.insertNoClimb(os);
|
db.insertNoClimb(os);
|
||||||
|
|
|
@ -17,6 +17,8 @@ class PAKBridge
|
||||||
HECL::Database::Project& m_project;
|
HECL::Database::Project& m_project;
|
||||||
const NOD::DiscBase::IPartition::Node& m_node;
|
const NOD::DiscBase::IPartition::Node& m_node;
|
||||||
DNAMP1::PAK m_pak;
|
DNAMP1::PAK m_pak;
|
||||||
|
UniqueResult uniqueCheck(const DNAMP1::PAK::Entry& entry);
|
||||||
|
public:
|
||||||
struct Level
|
struct Level
|
||||||
{
|
{
|
||||||
HECL::SystemString name;
|
HECL::SystemString name;
|
||||||
|
@ -35,8 +37,7 @@ class PAKBridge
|
||||||
};
|
};
|
||||||
std::unordered_map<UniqueID32, Level> m_levelDeps;
|
std::unordered_map<UniqueID32, Level> m_levelDeps;
|
||||||
HECL::SystemString m_levelString;
|
HECL::SystemString m_levelString;
|
||||||
UniqueResult uniqueCheck(const DNAMP1::PAK::Entry& entry);
|
|
||||||
public:
|
|
||||||
PAKBridge(HECL::Database::Project& project, const NOD::DiscBase::IPartition::Node& node);
|
PAKBridge(HECL::Database::Project& project, const NOD::DiscBase::IPartition::Node& node);
|
||||||
void build();
|
void build();
|
||||||
static ResExtractor<PAKBridge> LookupExtractor(const DNAMP1::PAK::Entry& entry);
|
static ResExtractor<PAKBridge> LookupExtractor(const DNAMP1::PAK::Entry& entry);
|
||||||
|
|
|
@ -0,0 +1,207 @@
|
||||||
|
#ifndef _DNAMP3_ANIM_HPP_
|
||||||
|
#define _DNAMP3_ANIM_HPP_
|
||||||
|
|
||||||
|
#include "BlenderConnection.hpp"
|
||||||
|
#include "DNAMP3.hpp"
|
||||||
|
#include "../DNACommon/ANIM.hpp"
|
||||||
|
#include "CINF.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMP3
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ANIM : BigDNA
|
||||||
|
{
|
||||||
|
Delete expl;
|
||||||
|
|
||||||
|
struct IANIM : BigDNA
|
||||||
|
{
|
||||||
|
Delete expl;
|
||||||
|
atUint32 m_version;
|
||||||
|
IANIM(atUint32 version) : m_version(version) {}
|
||||||
|
|
||||||
|
std::vector<std::pair<atUint32, std::tuple<bool,bool,bool>>> bones;
|
||||||
|
std::vector<atUint32> frames;
|
||||||
|
std::vector<DNAANIM::Channel> channels;
|
||||||
|
std::vector<std::vector<DNAANIM::Value>> chanKeys;
|
||||||
|
float mainInterval = 0.0;
|
||||||
|
|
||||||
|
void sendANIMToBlender(HECL::BlenderConnection::PyOutStream&, const CINF&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ANIM0 : IANIM
|
||||||
|
{
|
||||||
|
DECL_EXPLICIT_DNA
|
||||||
|
ANIM0() : IANIM(0) {}
|
||||||
|
|
||||||
|
struct Header : BigDNA
|
||||||
|
{
|
||||||
|
DECL_DNA
|
||||||
|
Value<float> duration;
|
||||||
|
Value<atUint32> unk0;
|
||||||
|
Value<float> interval;
|
||||||
|
Value<atUint32> unk1;
|
||||||
|
Value<atUint32> keyCount;
|
||||||
|
Value<atUint32> unk2;
|
||||||
|
Value<atUint32> boneSlotCount;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ANIM2 : IANIM
|
||||||
|
{
|
||||||
|
DECL_EXPLICIT_DNA
|
||||||
|
ANIM2() : IANIM(2) {}
|
||||||
|
|
||||||
|
struct Header : BigDNA
|
||||||
|
{
|
||||||
|
DECL_DNA
|
||||||
|
Value<atUint32> scratchSize;
|
||||||
|
Value<atUint8> unk1;
|
||||||
|
Value<atUint8> unk2;
|
||||||
|
Value<float> duration;
|
||||||
|
Value<float> interval;
|
||||||
|
Value<atUint32> unk3;
|
||||||
|
Value<atUint32> unk4;
|
||||||
|
Value<atUint32> rotDiv;
|
||||||
|
Value<float> translationMult;
|
||||||
|
Value<atUint32> unk5;
|
||||||
|
Value<atUint32> boneChannelCount;
|
||||||
|
Value<atUint32> unk6;
|
||||||
|
Value<atUint32> keyBitmapBitCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChannelDesc : BigDNA
|
||||||
|
{
|
||||||
|
Delete expl;
|
||||||
|
Value<atUint8> id = 0;
|
||||||
|
Value<atUint16> keyCount1 = 0;
|
||||||
|
Value<atUint16> initRX = 0;
|
||||||
|
Value<atUint8> qRX = 0;
|
||||||
|
Value<atUint16> initRY = 0;
|
||||||
|
Value<atUint8> qRY = 0;
|
||||||
|
Value<atUint16> initRZ = 0;
|
||||||
|
Value<atUint8> qRZ = 0;
|
||||||
|
Value<atUint16> keyCount2 = 0;
|
||||||
|
Value<atUint16> initTX = 0;
|
||||||
|
Value<atUint8> qTX = 0;
|
||||||
|
Value<atUint16> initTY = 0;
|
||||||
|
Value<atUint8> qTY = 0;
|
||||||
|
Value<atUint16> initTZ = 0;
|
||||||
|
Value<atUint8> qTZ = 0;
|
||||||
|
Value<atUint16> keyCount3 = 0;
|
||||||
|
Value<atUint16> initSX = 0;
|
||||||
|
Value<atUint8> qSX = 0;
|
||||||
|
Value<atUint16> initSY = 0;
|
||||||
|
Value<atUint8> qSY = 0;
|
||||||
|
Value<atUint16> initSZ = 0;
|
||||||
|
Value<atUint8> qSZ = 0;
|
||||||
|
|
||||||
|
void read(Athena::io::IStreamReader& reader)
|
||||||
|
{
|
||||||
|
id = reader.readUByte();
|
||||||
|
keyCount1 = reader.readUint16Big();
|
||||||
|
if (keyCount1)
|
||||||
|
{
|
||||||
|
initRX = reader.readUint16Big();
|
||||||
|
qRX = reader.readUByte();
|
||||||
|
initRY = reader.readUint16Big();
|
||||||
|
qRY = reader.readUByte();
|
||||||
|
initRZ = reader.readUint16Big();
|
||||||
|
qRZ = reader.readUByte();
|
||||||
|
}
|
||||||
|
keyCount2 = reader.readUint16Big();
|
||||||
|
if (keyCount2)
|
||||||
|
{
|
||||||
|
initTX = reader.readUint16Big();
|
||||||
|
qTX = reader.readUByte();
|
||||||
|
initTY = reader.readUint16Big();
|
||||||
|
qTY = reader.readUByte();
|
||||||
|
initTZ = reader.readUint16Big();
|
||||||
|
qTZ = reader.readUByte();
|
||||||
|
}
|
||||||
|
keyCount3 = reader.readUint16Big();
|
||||||
|
if (keyCount3)
|
||||||
|
{
|
||||||
|
initSX = reader.readUint16Big();
|
||||||
|
qSX = reader.readUByte();
|
||||||
|
initSY = reader.readUint16Big();
|
||||||
|
qSY = reader.readUByte();
|
||||||
|
initSZ = reader.readUint16Big();
|
||||||
|
qSZ = reader.readUByte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
writer.writeUByte(id);
|
||||||
|
writer.writeUint16Big(keyCount1);
|
||||||
|
if (keyCount1)
|
||||||
|
{
|
||||||
|
writer.writeUint16Big(initRX);
|
||||||
|
writer.writeUByte(qRX);
|
||||||
|
writer.writeUint16Big(initRY);
|
||||||
|
writer.writeUByte(qRY);
|
||||||
|
writer.writeUint16Big(initRZ);
|
||||||
|
writer.writeUByte(qRZ);
|
||||||
|
}
|
||||||
|
writer.writeUint16Big(keyCount2);
|
||||||
|
if (keyCount2)
|
||||||
|
{
|
||||||
|
writer.writeUint16Big(initTX);
|
||||||
|
writer.writeUByte(qTX);
|
||||||
|
writer.writeUint16Big(initTY);
|
||||||
|
writer.writeUByte(qTY);
|
||||||
|
writer.writeUint16Big(initTZ);
|
||||||
|
writer.writeUByte(qTZ);
|
||||||
|
}
|
||||||
|
writer.writeUint16Big(keyCount3);
|
||||||
|
if (keyCount3)
|
||||||
|
{
|
||||||
|
writer.writeUint16Big(initSX);
|
||||||
|
writer.writeUByte(qSX);
|
||||||
|
writer.writeUint16Big(initSY);
|
||||||
|
writer.writeUByte(qSY);
|
||||||
|
writer.writeUint16Big(initSZ);
|
||||||
|
writer.writeUByte(qSZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<IANIM> m_anim;
|
||||||
|
void read(Athena::io::IStreamReader& reader)
|
||||||
|
{
|
||||||
|
atUint32 version = reader.readUint32Big();
|
||||||
|
switch (version)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
m_anim.reset(new struct ANIM0);
|
||||||
|
m_anim->read(reader);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
m_anim.reset(new struct ANIM2);
|
||||||
|
m_anim->read(reader);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.report(LogVisor::FatalError, "unrecognized ANIM version");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
writer.writeUint32Big(m_anim->m_version);
|
||||||
|
m_anim->write(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendANIMToBlender(HECL::BlenderConnection::PyOutStream& os, const CINF& cinf) const
|
||||||
|
{
|
||||||
|
m_anim->sendANIMToBlender(os, cinf);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _DNAMP3_ANIM_HPP_
|
|
@ -0,0 +1,363 @@
|
||||||
|
#ifndef _DNAMP3_CHAR_HPP_
|
||||||
|
#define _DNAMP3_CHAR_HPP_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include "../DNACommon/DNACommon.hpp"
|
||||||
|
#include "../DNACommon/ANCS.hpp"
|
||||||
|
#include "CMDLMaterials.hpp"
|
||||||
|
#include "BlenderConnection.hpp"
|
||||||
|
#include "CINF.hpp"
|
||||||
|
#include "CSKR.hpp"
|
||||||
|
#include "ANIM.hpp"
|
||||||
|
#include "../DNAMP2/ANCS.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMP3
|
||||||
|
{
|
||||||
|
|
||||||
|
struct CHAR : BigYAML
|
||||||
|
{
|
||||||
|
using CINFType = CINF;
|
||||||
|
using CSKRType = CSKR;
|
||||||
|
using ANIMType = ANIM;
|
||||||
|
|
||||||
|
DECL_YAML
|
||||||
|
Delete expl;
|
||||||
|
atUint16 version;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
UniqueID64 cmdl;
|
||||||
|
UniqueID64 cskr;
|
||||||
|
atUint32 unk1;
|
||||||
|
atUint32 unk2;
|
||||||
|
UniqueID64 cmdl2;
|
||||||
|
UniqueID64 cskr2;
|
||||||
|
UniqueID64 cinf;
|
||||||
|
UniqueID64 sand;
|
||||||
|
|
||||||
|
using MP1CharacterInfo = DNAMP1::ANCS::CharacterSet::CharacterInfo;
|
||||||
|
MP1CharacterInfo::PASDatabase pasDatabase;
|
||||||
|
|
||||||
|
struct ParticleResData
|
||||||
|
{
|
||||||
|
std::vector<UniqueID64> part;
|
||||||
|
std::vector<UniqueID64> swhc;
|
||||||
|
std::vector<UniqueID64> unk;
|
||||||
|
std::vector<UniqueID64> elsc;
|
||||||
|
std::vector<UniqueID64> spsc;
|
||||||
|
std::vector<UniqueID64> unk2;
|
||||||
|
} partResData;
|
||||||
|
|
||||||
|
struct AnimationSet : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
Delete expl;
|
||||||
|
|
||||||
|
struct IMetaAnim : BigYAML
|
||||||
|
{
|
||||||
|
Delete expl;
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
MAPrimitive = 0,
|
||||||
|
MABlend = 1,
|
||||||
|
MAPhaseBlend = 2,
|
||||||
|
MARandom = 3,
|
||||||
|
MASequence = 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, std::pair<std::string, UniqueID64>>& out)=0;
|
||||||
|
};
|
||||||
|
struct MetaAnimFactory : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
Delete expl;
|
||||||
|
std::unique_ptr<IMetaAnim> m_anim;
|
||||||
|
};
|
||||||
|
struct MetaAnimPrimitive : IMetaAnim
|
||||||
|
{
|
||||||
|
MetaAnimPrimitive() : IMetaAnim(MAPrimitive, "Primitive") {}
|
||||||
|
DECL_YAML
|
||||||
|
UniqueID64 animId;
|
||||||
|
Value<atUint32> animIdx;
|
||||||
|
String<-1> animName;
|
||||||
|
Value<float> unk1;
|
||||||
|
Value<atUint32> unk2;
|
||||||
|
|
||||||
|
void gatherPrimitives(std::map<atUint32, std::pair<std::string, UniqueID64>>& out)
|
||||||
|
{
|
||||||
|
out[animIdx] = std::make_pair(animName, animId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct MetaAnimBlend : IMetaAnim
|
||||||
|
{
|
||||||
|
MetaAnimBlend() : IMetaAnim(MABlend, "Blend") {}
|
||||||
|
DECL_YAML
|
||||||
|
MetaAnimFactory animA;
|
||||||
|
MetaAnimFactory animB;
|
||||||
|
Value<float> unkFloat;
|
||||||
|
Value<atUint8> unk;
|
||||||
|
|
||||||
|
void gatherPrimitives(std::map<atUint32, std::pair<std::string, UniqueID64>>& out)
|
||||||
|
{
|
||||||
|
animA.m_anim->gatherPrimitives(out);
|
||||||
|
animB.m_anim->gatherPrimitives(out);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct MetaAnimPhaseBlend : IMetaAnim
|
||||||
|
{
|
||||||
|
MetaAnimPhaseBlend() : IMetaAnim(MAPhaseBlend, "PhaseBlend") {}
|
||||||
|
DECL_YAML
|
||||||
|
MetaAnimFactory animA;
|
||||||
|
MetaAnimFactory animB;
|
||||||
|
Value<float> unkFloat;
|
||||||
|
Value<atUint8> unk;
|
||||||
|
|
||||||
|
void gatherPrimitives(std::map<atUint32, std::pair<std::string, UniqueID64>>& out)
|
||||||
|
{
|
||||||
|
animA.m_anim->gatherPrimitives(out);
|
||||||
|
animB.m_anim->gatherPrimitives(out);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct MetaAnimRandom : IMetaAnim
|
||||||
|
{
|
||||||
|
MetaAnimRandom() : IMetaAnim(MARandom, "Random") {}
|
||||||
|
DECL_YAML
|
||||||
|
Value<atUint32> animCount;
|
||||||
|
struct Child : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
MetaAnimFactory anim;
|
||||||
|
Value<atUint32> probability;
|
||||||
|
};
|
||||||
|
Vector<Child, DNA_COUNT(animCount)> children;
|
||||||
|
|
||||||
|
void gatherPrimitives(std::map<atUint32, std::pair<std::string, UniqueID64>>& out)
|
||||||
|
{
|
||||||
|
for (const auto& child : children)
|
||||||
|
child.anim.m_anim->gatherPrimitives(out);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct MetaAnimSequence : IMetaAnim
|
||||||
|
{
|
||||||
|
MetaAnimSequence() : IMetaAnim(MASequence, "Sequence") {}
|
||||||
|
DECL_YAML
|
||||||
|
Value<atUint32> animCount;
|
||||||
|
Vector<MetaAnimFactory, DNA_COUNT(animCount)> children;
|
||||||
|
|
||||||
|
void gatherPrimitives(std::map<atUint32, std::pair<std::string, UniqueID64>>& out)
|
||||||
|
{
|
||||||
|
for (const auto& child : children)
|
||||||
|
child.m_anim->gatherPrimitives(out);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Animation : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
String<-1> name;
|
||||||
|
MetaAnimFactory metaAnim;
|
||||||
|
};
|
||||||
|
std::vector<Animation> animations;
|
||||||
|
|
||||||
|
struct IMetaTrans : BigYAML
|
||||||
|
{
|
||||||
|
Delete expl;
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
MTMetaAnim = 0,
|
||||||
|
MTTrans = 1,
|
||||||
|
MTPhaseTrans = 2,
|
||||||
|
MTNoTrans = 3,
|
||||||
|
} m_type;
|
||||||
|
const char* m_typeStr;
|
||||||
|
IMetaTrans(Type type, const char* typeStr)
|
||||||
|
: m_type(type), m_typeStr(typeStr) {}
|
||||||
|
};
|
||||||
|
struct MetaTransFactory : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
Delete expl;
|
||||||
|
std::unique_ptr<IMetaTrans> m_trans;
|
||||||
|
};
|
||||||
|
struct MetaTransMetaAnim : IMetaTrans
|
||||||
|
{
|
||||||
|
MetaTransMetaAnim() : IMetaTrans(MTMetaAnim, "MetaAnim") {}
|
||||||
|
DECL_YAML
|
||||||
|
MetaAnimFactory anim;
|
||||||
|
};
|
||||||
|
struct MetaTransTrans : IMetaTrans
|
||||||
|
{
|
||||||
|
MetaTransTrans() : IMetaTrans(MTTrans, "Trans") {}
|
||||||
|
DECL_YAML
|
||||||
|
Value<float> time;
|
||||||
|
Value<atUint32> unk1;
|
||||||
|
Value<atUint8> unk2;
|
||||||
|
Value<atUint8> unk3;
|
||||||
|
Value<atUint32> unk4;
|
||||||
|
};
|
||||||
|
struct MetaTransPhaseTrans : IMetaTrans
|
||||||
|
{
|
||||||
|
MetaTransPhaseTrans() : IMetaTrans(MTPhaseTrans, "PhaseTrans") {}
|
||||||
|
DECL_YAML
|
||||||
|
Value<float> time;
|
||||||
|
Value<atUint32> unk1;
|
||||||
|
Value<atUint8> unk2;
|
||||||
|
Value<atUint8> unk3;
|
||||||
|
Value<atUint32> unk4;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Transition : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
Value<atUint32> unk;
|
||||||
|
Value<atUint32> animIdxA;
|
||||||
|
Value<atUint32> animIdxB;
|
||||||
|
MetaTransFactory metaTrans;
|
||||||
|
};
|
||||||
|
std::vector<Transition> transitions;
|
||||||
|
MetaTransFactory defaultTransition;
|
||||||
|
|
||||||
|
struct AdditiveAnimationInfo : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
Value<atUint32> animIdx;
|
||||||
|
Value<float> unk1;
|
||||||
|
Value<float> unk2;
|
||||||
|
};
|
||||||
|
std::vector<AdditiveAnimationInfo> additiveAnims;
|
||||||
|
|
||||||
|
float floatA = 0.0;
|
||||||
|
float floatB = 0.0;
|
||||||
|
|
||||||
|
struct HalfTransition : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
Value<atUint32> animIdx;
|
||||||
|
MetaTransFactory metaTrans;
|
||||||
|
};
|
||||||
|
std::vector<HalfTransition> halfTransitions;
|
||||||
|
|
||||||
|
struct AnimationResources : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
UniqueID64 animId;
|
||||||
|
UniqueID64 evntId;
|
||||||
|
};
|
||||||
|
std::vector<AnimationResources> animResources;
|
||||||
|
} animationSet;
|
||||||
|
|
||||||
|
struct ActionAABB : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
UniqueID64 animId;
|
||||||
|
Value<atVec3f> aabb[2];
|
||||||
|
};
|
||||||
|
std::vector<ActionAABB> animAABBs;
|
||||||
|
|
||||||
|
atUint32 unk3 = 0;
|
||||||
|
|
||||||
|
|
||||||
|
struct Effect : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
String<-1> name;
|
||||||
|
Value<atUint32> compCount;
|
||||||
|
struct EffectComponent : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
String<-1> name;
|
||||||
|
DNAFourCC type;
|
||||||
|
UniqueID32 id;
|
||||||
|
Value<atUint32> unkMP2;
|
||||||
|
Value<float> unk1;
|
||||||
|
Value<atUint32> unk2;
|
||||||
|
Value<atUint32> unk3;
|
||||||
|
};
|
||||||
|
Vector<EffectComponent, DNA_COUNT(compCount)> comps;
|
||||||
|
};
|
||||||
|
std::vector<Effect> effects;
|
||||||
|
|
||||||
|
UniqueID32 cmdlOverride;
|
||||||
|
UniqueID32 cskrOverride;
|
||||||
|
|
||||||
|
std::vector<atUint32> animIdxs;
|
||||||
|
|
||||||
|
atUint32 unk4;
|
||||||
|
atUint8 unk5;
|
||||||
|
|
||||||
|
struct Extents : BigYAML
|
||||||
|
{
|
||||||
|
DECL_YAML
|
||||||
|
Value<atUint32> animIdx;
|
||||||
|
Value<atVec3f> aabb[2];
|
||||||
|
};
|
||||||
|
std::vector<Extents> extents;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 = name;
|
||||||
|
chOut.cmdl = cmdl;
|
||||||
|
chOut.cskr = cskr;
|
||||||
|
chOut.cinf = cinf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getAnimationResInfo(std::map<atUint32, std::pair<std::string, UniqueID64>>& out) const
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
for (const AnimationSet::Animation& ai : animationSet.animations)
|
||||||
|
ai.metaAnim.m_anim->gatherPrimitives(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Extract(const SpecBase& dataSpec,
|
||||||
|
PAKEntryReadStream& rs,
|
||||||
|
const HECL::ProjectPath& outPath,
|
||||||
|
PAKRouter<PAKBridge>& pakRouter,
|
||||||
|
const PAK::Entry& entry,
|
||||||
|
bool force,
|
||||||
|
std::function<void(const HECL::SystemChar*)> fileChanged)
|
||||||
|
{
|
||||||
|
HECL::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
|
||||||
|
HECL::ProjectPath::PathType yamlType = yamlPath.getPathType();
|
||||||
|
HECL::ProjectPath blendPath = outPath.getWithExtension(_S(".blend"));
|
||||||
|
HECL::ProjectPath::PathType blendType = blendPath.getPathType();
|
||||||
|
|
||||||
|
if (force ||
|
||||||
|
yamlType == HECL::ProjectPath::PT_NONE ||
|
||||||
|
blendType == HECL::ProjectPath::PT_NONE)
|
||||||
|
{
|
||||||
|
CHAR aChar;
|
||||||
|
aChar.read(rs);
|
||||||
|
|
||||||
|
if (force || yamlType == HECL::ProjectPath::PT_NONE)
|
||||||
|
{
|
||||||
|
FILE* fp = HECL::Fopen(yamlPath.getAbsolutePath().c_str(), _S("wb"));
|
||||||
|
aChar.toYAMLFile(fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (force || blendType == HECL::ProjectPath::PT_NONE)
|
||||||
|
{
|
||||||
|
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
||||||
|
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, CHAR, MaterialSet, 4>
|
||||||
|
(conn, aChar, blendPath, pakRouter, entry, dataSpec, fileChanged, force);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _DNAMP3_CHAR_HPP_
|
|
@ -71,15 +71,15 @@ struct CINF : BigDNA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendCINFToBlender(HECL::BlenderConnection::PyOutStream& os, const UniqueID32& cinfId) const
|
void sendCINFToBlender(HECL::BlenderConnection::PyOutStream& os, const UniqueID64& cinfId) const
|
||||||
{
|
{
|
||||||
os.format("arm = bpy.data.armatures.new('CINF_%08X')\n"
|
os.format("arm = bpy.data.armatures.new('CINF_%016" PRIX64 "')\n"
|
||||||
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
||||||
"bpy.context.scene.objects.link(arm_obj)\n"
|
"bpy.context.scene.objects.link(arm_obj)\n"
|
||||||
"bpy.context.scene.objects.active = arm_obj\n"
|
"bpy.context.scene.objects.active = arm_obj\n"
|
||||||
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
||||||
"arm_bone_table = {}\n",
|
"arm_bone_table = {}\n",
|
||||||
cinfId.toUint32());
|
cinfId.toUint64());
|
||||||
|
|
||||||
for (const Bone& bone : bones)
|
for (const Bone& bone : bones)
|
||||||
os.format("bone = arm.edit_bones.new('%s')\n"
|
os.format("bone = arm.edit_bones.new('%s')\n"
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
make_dnalist(liblist
|
make_dnalist(liblist
|
||||||
PAK
|
PAK
|
||||||
MLVL
|
MLVL
|
||||||
|
ANIM
|
||||||
|
CHAR
|
||||||
CMDLMaterials
|
CMDLMaterials
|
||||||
CINF
|
CINF
|
||||||
CSKR
|
CSKR
|
||||||
|
@ -9,6 +11,8 @@ add_library(DNAMP3
|
||||||
DNAMP3.hpp DNAMP3.cpp
|
DNAMP3.hpp DNAMP3.cpp
|
||||||
${liblist}
|
${liblist}
|
||||||
PAK.cpp
|
PAK.cpp
|
||||||
|
ANIM.cpp
|
||||||
|
CHAR.cpp
|
||||||
CMDL.hpp
|
CMDL.hpp
|
||||||
CMDLMaterials.cpp
|
CMDLMaterials.cpp
|
||||||
STRG.hpp STRG.cpp
|
STRG.hpp STRG.cpp
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "STRG.hpp"
|
#include "STRG.hpp"
|
||||||
#include "MLVL.hpp"
|
#include "MLVL.hpp"
|
||||||
#include "CMDL.hpp"
|
#include "CMDL.hpp"
|
||||||
|
#include "CHAR.hpp"
|
||||||
#include "MREA.hpp"
|
#include "MREA.hpp"
|
||||||
#include "../DNACommon/TXTR.hpp"
|
#include "../DNACommon/TXTR.hpp"
|
||||||
|
|
||||||
|
@ -308,6 +309,10 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
||||||
return {TXTR::Extract, nullptr, {_S(".png")}};
|
return {TXTR::Extract, nullptr, {_S(".png")}};
|
||||||
case SBIG('CMDL'):
|
case SBIG('CMDL'):
|
||||||
return {nullptr, CMDL::Extract, {_S(".blend")}, 1};
|
return {nullptr, CMDL::Extract, {_S(".blend")}, 1};
|
||||||
|
#if 0
|
||||||
|
case SBIG('CHAR'):
|
||||||
|
return {nullptr, CHAR::Extract, {_S(".yaml"), _S(".blend")}, 2};
|
||||||
|
#endif
|
||||||
case SBIG('MREA'):
|
case SBIG('MREA'):
|
||||||
return {nullptr, MREA::Extract, {_S(".blend")}, 2};
|
return {nullptr, MREA::Extract, {_S(".blend")}, 2};
|
||||||
case SBIG('MLVL'):
|
case SBIG('MLVL'):
|
||||||
|
|
Loading…
Reference in New Issue