Preparing for CHAR/ANIM implementation

This commit is contained in:
Jack Andersen 2015-09-23 14:59:36 -10:00
parent a5f6c2548b
commit 21d8b9dcd3
12 changed files with 636 additions and 9 deletions

View File

@ -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 */

View File

@ -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();
}
}; };
} }

View File

@ -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);

View File

@ -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);

View File

@ -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
DataSpec/DNAMP3/ANIM.cpp Normal file
View File

207
DataSpec/DNAMP3/ANIM.hpp Normal file
View File

@ -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
DataSpec/DNAMP3/CHAR.cpp Normal file
View File

363
DataSpec/DNAMP3/CHAR.hpp Normal file
View File

@ -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_

View File

@ -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"

View File

@ -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

View File

@ -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'):