2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-15 02:45:52 +00:00

Much more reliable CMDL with CINF/CSKR extract

This commit is contained in:
Jack Andersen 2015-09-05 19:34:30 -10:00
parent 4ede471d1e
commit cf7836fc9a
14 changed files with 151 additions and 82 deletions

View File

@ -26,46 +26,10 @@ bool ReadANCSToBlender(HECL::BlenderConnection& conn,
const HECL::ProjectPath& outPath, const HECL::ProjectPath& outPath,
PAKRouter& pakRouter, PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry, const typename PAKRouter::EntryType& entry,
const SpecBase& dataspec,
std::function<void(const HECL::SystemChar*)> fileChanged,
bool force=false) bool force=false)
{ {
/* Extract character CMDL/CSKR first */
std::vector<CharacterResInfo<typename PAKRouter::IDType>> chResInfo; std::vector<CharacterResInfo<typename PAKRouter::IDType>> chResInfo;
ancs.getCharacterResInfo(chResInfo); ancs.getCharacterResInfo(chResInfo);
for (const auto& info : chResInfo)
{
const NOD::DiscBase::IPartition::Node* node;
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node);
if (cmdlE)
{
HECL::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
if (force || cmdlPath.getPathType() == HECL::ProjectPath::PT_NONE)
{
if (!conn.createBlend(cmdlPath.getAbsolutePath()))
return false;
HECL::SystemStringView bestNameView(pakRouter.getBestEntryName(*cmdlE));
fileChanged(bestNameView.sys_str().c_str());
typename ANCSDNA::CSKRType cskr;
pakRouter.lookupAndReadDNA(info.cskr, cskr);
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(info.cinf, cinf);
using RIGPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>;
RIGPair rigPair(&cskr, &cinf);
PAKEntryReadStream rs = cmdlE->beginReadStream(*node);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RIGPair, CMDLVersion>
(conn, rs, pakRouter, *cmdlE, dataspec, &rigPair);
conn.saveBlend();
}
}
}
HECL::SystemStringView bestNameView(pakRouter.getBestEntryName(entry));
fileChanged(bestNameView.sys_str().c_str());
/* Establish ANCS blend */ /* Establish ANCS blend */
if (!conn.createBlend(outPath.getAbsolutePath())) if (!conn.createBlend(outPath.getAbsolutePath()))

View File

@ -310,7 +310,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
PAKRouter& pakRouter, PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry, const typename PAKRouter::EntryType& entry,
const SpecBase& dataspec, const SpecBase& dataspec,
const RIGPAIR* rp=nullptr) const RIGPAIR& rp)
{ {
Header head; Header head;
head.read(reader); head.read(reader);
@ -411,7 +411,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
"bm = bmesh.new()\n" "bm = bmesh.new()\n"
"\n", pakRouter.getBestEntryName(entry).c_str()); "\n", pakRouter.getBestEntryName(entry).c_str());
if (rp) if (rp.first)
os << "dvert_lay = bm.verts.layers.deform.verify()\n"; os << "dvert_lay = bm.verts.layers.deform.verify()\n";
/* Link master shader library */ /* Link master shader library */
@ -535,8 +535,8 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
atVec3f pos = reader.readVec3fBig(); atVec3f pos = reader.readVec3fBig();
os.format("vert = bm.verts.new((%f,%f,%f))\n", os.format("vert = bm.verts.new((%f,%f,%f))\n",
pos.vec[0], pos.vec[1], pos.vec[2]); pos.vec[0], pos.vec[1], pos.vec[2]);
if (rp) if (rp.first)
rp->first->weightVertex(os, *rp->second, i); rp.first->weightVertex(os, *rp.second, i);
} }
break; break;
} }
@ -832,8 +832,8 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
"bm.free()\n" "bm.free()\n"
"\n", head.matSetCount); "\n", head.matSetCount);
if (rp) if (rp.first)
rp->second->sendVertexGroupsToBlender(os); rp.second->sendVertexGroupsToBlender(os);
return true; return true;
} }

View File

@ -106,6 +106,7 @@ public:
using PAKType = typename BRIDGETYPE::PAKType; using PAKType = typename BRIDGETYPE::PAKType;
using IDType = typename PAKType::IDType; using IDType = typename PAKType::IDType;
using EntryType = typename PAKType::Entry; using EntryType = typename PAKType::Entry;
using RigPair = std::pair<IDType, IDType>;
private: private:
const SpecBase& m_dataSpec; const SpecBase& m_dataSpec;
const std::vector<BRIDGETYPE>* m_bridges = nullptr; const std::vector<BRIDGETYPE>* m_bridges = nullptr;
@ -119,6 +120,7 @@ private:
const NOD::DiscBase::IPartition::Node* m_node = nullptr; const NOD::DiscBase::IPartition::Node* m_node = nullptr;
std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_uniqueEntries; std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_uniqueEntries;
std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_sharedEntries; std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_sharedEntries;
std::unordered_map<IDType, RigPair> m_cmdlRigs;
public: public:
PAKRouter(const SpecBase& dataSpec, const HECL::ProjectPath& working, const HECL::ProjectPath& cooked) PAKRouter(const SpecBase& dataSpec, const HECL::ProjectPath& working, const HECL::ProjectPath& cooked)
: m_dataSpec(dataSpec), : m_dataSpec(dataSpec),
@ -147,7 +149,10 @@ public:
m_bridgePaths.emplace_back(std::make_pair(HECL::ProjectPath(m_gameWorking, baseName), m_bridgePaths.emplace_back(std::make_pair(HECL::ProjectPath(m_gameWorking, baseName),
HECL::ProjectPath(m_gameCooked, baseName))); HECL::ProjectPath(m_gameCooked, baseName)));
/* Index this PAK */
bridge.build(); bridge.build();
/* Add to global enntry lookup */
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); const typename BRIDGETYPE::PAKType& pak = bridge.getPAK();
for (const auto& entry : pak.m_idMap) for (const auto& entry : pak.m_idMap)
{ {
@ -163,6 +168,10 @@ public:
else else
m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, entry.second); m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, entry.second);
} }
/* Add RigPairs to global map */
bridge.addCMDLRigPairs(m_cmdlRigs);
progress(++count / bridgesSz); progress(++count / bridgesSz);
++bridgeIdx; ++bridgeIdx;
} }
@ -189,7 +198,7 @@ public:
LogDNACommon.report(LogVisor::FatalError, "PAKBridge provided to PAKRouter::enterPAKBridge() was not part of build()"); LogDNACommon.report(LogVisor::FatalError, "PAKBridge provided to PAKRouter::enterPAKBridge() was not part of build()");
} }
HECL::ProjectPath getWorking(const typename BRIDGETYPE::PAKType::Entry* entry, HECL::ProjectPath getWorking(const EntryType* entry,
const ResExtractor<BRIDGETYPE>& extractor) const const ResExtractor<BRIDGETYPE>& extractor) const
{ {
if (!m_pak) if (!m_pak)
@ -249,17 +258,17 @@ public:
return HECL::ProjectPath(); return HECL::ProjectPath();
} }
HECL::ProjectPath getWorking(const typename BRIDGETYPE::PAKType::Entry* entry) const HECL::ProjectPath getWorking(const EntryType* entry) const
{ {
return getWorking(entry, BRIDGETYPE::LookupExtractor(*entry)); return getWorking(entry, BRIDGETYPE::LookupExtractor(*entry));
} }
HECL::ProjectPath getWorking(const typename BRIDGETYPE::PAKType::IDType& id) const HECL::ProjectPath getWorking(const IDType& id) const
{ {
return getWorking(lookupEntry(id)); return getWorking(lookupEntry(id));
} }
HECL::ProjectPath getCooked(const typename BRIDGETYPE::PAKType::Entry* entry) const HECL::ProjectPath getCooked(const EntryType* entry) const
{ {
if (!m_pak) if (!m_pak)
LogDNACommon.report(LogVisor::FatalError, LogDNACommon.report(LogVisor::FatalError,
@ -282,13 +291,12 @@ public:
return HECL::ProjectPath(); return HECL::ProjectPath();
} }
HECL::ProjectPath getCooked(const typename BRIDGETYPE::PAKType::IDType& id) const HECL::ProjectPath getCooked(const IDType& id) const
{ {
return getCooked(lookupEntry(id)); return getCooked(lookupEntry(id));
} }
HECL::SystemString getResourceRelativePath(const typename BRIDGETYPE::PAKType::Entry& a, HECL::SystemString getResourceRelativePath(const EntryType& a, const IDType& b) const
const typename BRIDGETYPE::PAKType::IDType& b) const
{ {
if (!m_pak) if (!m_pak)
LogDNACommon.report(LogVisor::FatalError, LogDNACommon.report(LogVisor::FatalError,
@ -305,7 +313,7 @@ public:
return ret; return ret;
} }
std::string getBestEntryName(const typename BRIDGETYPE::PAKType::Entry& entry) const std::string getBestEntryName(const EntryType& entry) const
{ {
if (!m_pak) if (!m_pak)
LogDNACommon.report(LogVisor::FatalError, LogDNACommon.report(LogVisor::FatalError,
@ -313,7 +321,7 @@ public:
return m_pak->bestEntryName(entry); return m_pak->bestEntryName(entry);
} }
std::string getBestEntryName(const typename BRIDGETYPE::PAKType::IDType& entry) const std::string getBestEntryName(const IDType& entry) const
{ {
if (!m_pak) if (!m_pak)
LogDNACommon.report(LogVisor::FatalError, LogDNACommon.report(LogVisor::FatalError,
@ -379,7 +387,7 @@ public:
return true; return true;
} }
const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const typename BRIDGETYPE::PAKType::IDType& entry, const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry,
const NOD::DiscBase::IPartition::Node** nodeOut=nullptr) const const NOD::DiscBase::IPartition::Node** nodeOut=nullptr) const
{ {
if (!m_bridges) if (!m_bridges)
@ -387,7 +395,7 @@ public:
"PAKRouter::build() must be called before PAKRouter::lookupEntry()"); "PAKRouter::build() must be called before PAKRouter::lookupEntry()");
if (m_pak) if (m_pak)
{ {
const typename BRIDGETYPE::PAKType::Entry* ent = m_pak->lookupEntry(entry); const EntryType* ent = m_pak->lookupEntry(entry);
if (ent) if (ent)
{ {
if (nodeOut) if (nodeOut)
@ -397,8 +405,8 @@ public:
} }
for (const BRIDGETYPE& bridge : *m_bridges) for (const BRIDGETYPE& bridge : *m_bridges)
{ {
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); const PAKType& pak = bridge.getPAK();
const typename BRIDGETYPE::PAKType::Entry* ent = pak.lookupEntry(entry); const EntryType* ent = pak.lookupEntry(entry);
if (ent) if (ent)
{ {
if (nodeOut) if (nodeOut)
@ -413,16 +421,24 @@ public:
} }
template <typename DNA> template <typename DNA>
bool lookupAndReadDNA(const typename BRIDGETYPE::PAKType::IDType& id, DNA& out) bool lookupAndReadDNA(const IDType& id, DNA& out)
{ {
const NOD::DiscBase::IPartition::Node* node; const NOD::DiscBase::IPartition::Node* node;
const typename BRIDGETYPE::PAKType::Entry* entry = lookupEntry(id, &node); const EntryType* entry = lookupEntry(id, &node);
if (!entry) if (!entry)
return false; return false;
PAKEntryReadStream rs = entry->beginReadStream(*node); PAKEntryReadStream rs = entry->beginReadStream(*node);
out.read(rs); out.read(rs);
return true; return true;
} }
const RigPair* lookupCMDLRigPair(const IDType& id) const
{
auto search = m_cmdlRigs.find(id);
if (search == m_cmdlRigs.end())
return nullptr;
return &search->second;
}
}; };
} }

View File

@ -371,13 +371,13 @@ struct ANCS : BigYAML
ai.metaAnim.m_anim->gatherPrimitives(out); ai.metaAnim.m_anim->gatherPrimitives(out);
} }
static bool Extract(const SpecBase& dataSpec, static bool Extract(const SpecBase&,
PAKEntryReadStream& rs, PAKEntryReadStream& rs,
const HECL::ProjectPath& outPath, const HECL::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
std::function<void(const HECL::SystemChar*)> fileChanged) std::function<void(const HECL::SystemChar*)>)
{ {
HECL::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml")); HECL::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
HECL::ProjectPath::PathType yamlType = yamlPath.getPathType(); HECL::ProjectPath::PathType yamlType = yamlPath.getPathType();
@ -402,7 +402,7 @@ struct ANCS : BigYAML
{ {
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, 2> DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, 2>
(conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); (conn, ancs, blendPath, pakRouter, entry, force);
} }
} }

View File

@ -23,11 +23,25 @@ struct CMDL
bool force, bool force,
std::function<void(const HECL::SystemChar*)> fileChanged) std::function<void(const HECL::SystemChar*)> fileChanged)
{ {
/* Check for RigPair */
const PAKRouter<PAKBridge>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
CINF cinf;
CSKR cskr;
std::pair<CSKR*,CINF*> loadRp(nullptr, nullptr);
if (rp)
{
pakRouter.lookupAndReadDNA(rp->first, cskr);
pakRouter.lookupAndReadDNA(rp->second, cinf);
loadRp.first = &cskr;
loadRp.second = &cinf;
}
/* Do extract */
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
if (!conn.createBlend(outPath.getAbsolutePath())) if (!conn.createBlend(outPath.getAbsolutePath()))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, 2> DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, 2>
(conn, rs, pakRouter, entry, dataSpec); (conn, rs, pakRouter, entry, dataSpec, loadRp);
return conn.saveBlend(); return conn.saveBlend();
} }
}; };

View File

@ -190,6 +190,21 @@ void PAKBridge::build()
} }
} }
void PAKBridge::addCMDLRigPairs(std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo) const
{
for (const std::pair<UniqueID32, PAK::Entry*>& entry : m_pak.m_idMap)
{
if (entry.second->type == FOURCC('ANCS'))
{
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
ANCS ancs;
ancs.read(rs);
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
}
}
}
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry) ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
{ {
switch (entry.type) switch (entry.type)
@ -199,9 +214,9 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
case SBIG('TXTR'): case SBIG('TXTR'):
return {TXTR::Extract, nullptr, {_S(".png")}}; return {TXTR::Extract, nullptr, {_S(".png")}};
case SBIG('CMDL'): case SBIG('CMDL'):
return {nullptr, CMDL::Extract, {_S(".blend")}, 2}; return {nullptr, CMDL::Extract, {_S(".blend")}, 1};
case SBIG('ANCS'): case SBIG('ANCS'):
return {nullptr, ANCS::Extract, {_S(".yaml"), _S(".blend")}, 1}; return {nullptr, ANCS::Extract, {_S(".yaml"), _S(".blend")}, 2};
case SBIG('MLVL'): case SBIG('MLVL'):
return {MLVL::Extract, nullptr, {_S(".yaml")}}; return {MLVL::Extract, nullptr, {_S(".yaml")}};
} }

View File

@ -35,12 +35,14 @@ 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);
inline const std::string& getName() const {return m_node.getName();} const std::string& getName() const {return m_node.getName();}
inline const HECL::SystemString& getLevelString() const {return m_levelString;} const HECL::SystemString& getLevelString() const {return m_levelString;}
typedef PAK PAKType; using PAKType = PAK;
inline const PAKType& getPAK() const {return m_pak;} const PAKType& getPAK() const {return m_pak;}
inline const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;} const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;}
void addCMDLRigPairs(std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo) const;
}; };
} }

View File

@ -208,13 +208,13 @@ struct ANCS : BigYAML
ai.metaAnim.m_anim->gatherPrimitives(out); ai.metaAnim.m_anim->gatherPrimitives(out);
} }
static bool Extract(const SpecBase& dataSpec, static bool Extract(const SpecBase&,
PAKEntryReadStream& rs, PAKEntryReadStream& rs,
const HECL::ProjectPath& outPath, const HECL::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const DNAMP1::PAK::Entry& entry, const DNAMP1::PAK::Entry& entry,
bool force, bool force,
std::function<void(const HECL::SystemChar*)> fileChanged) std::function<void(const HECL::SystemChar*)>)
{ {
HECL::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml")); HECL::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
HECL::ProjectPath::PathType yamlType = yamlPath.getPathType(); HECL::ProjectPath::PathType yamlType = yamlPath.getPathType();
@ -239,7 +239,7 @@ struct ANCS : BigYAML
{ {
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, 4> DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, 4>
(conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); (conn, ancs, blendPath, pakRouter, entry, force);
} }
} }

View File

@ -20,14 +20,28 @@ struct CMDL
const HECL::ProjectPath& outPath, const HECL::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const DNAMP1::PAK::Entry& entry, const DNAMP1::PAK::Entry& entry,
bool force, bool,
std::function<void(const HECL::SystemChar*)> fileChanged) std::function<void(const HECL::SystemChar*)>)
{ {
/* Check for RigPair */
const PAKRouter<PAKBridge>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
CINF cinf;
CSKR cskr;
std::pair<CSKR*,CINF*> loadRp(nullptr, nullptr);
if (rp)
{
pakRouter.lookupAndReadDNA(rp->first, cskr);
pakRouter.lookupAndReadDNA(rp->second, cinf);
loadRp.first = &cskr;
loadRp.second = &cinf;
}
/* Do extract */
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
if (!conn.createBlend(outPath.getAbsolutePath())) if (!conn.createBlend(outPath.getAbsolutePath()))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, 4> DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, 4>
(conn, rs, pakRouter, entry, dataSpec); (conn, rs, pakRouter, entry, dataSpec, loadRp);
return conn.saveBlend(); return conn.saveBlend();
} }
}; };

View File

@ -197,6 +197,21 @@ void PAKBridge::build()
} }
} }
void PAKBridge::addCMDLRigPairs(std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo) const
{
for (const std::pair<UniqueID32, DNAMP1::PAK::Entry*>& entry : m_pak.m_idMap)
{
if (entry.second->type == FOURCC('ANCS'))
{
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
ANCS ancs;
ancs.read(rs);
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
}
}
}
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const DNAMP1::PAK::Entry& entry) ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const DNAMP1::PAK::Entry& entry)
{ {
switch (entry.type) switch (entry.type)
@ -206,9 +221,9 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const DNAMP1::PAK::Entry& ent
case SBIG('TXTR'): case SBIG('TXTR'):
return {TXTR::Extract, nullptr, {_S(".png")}}; return {TXTR::Extract, nullptr, {_S(".png")}};
case SBIG('CMDL'): case SBIG('CMDL'):
return {nullptr, CMDL::Extract, {_S(".blend")}, 2}; return {nullptr, CMDL::Extract, {_S(".blend")}, 1};
case SBIG('ANCS'): case SBIG('ANCS'):
return {nullptr, ANCS::Extract, {_S(".yaml"), _S(".blend")}, 1}; return {nullptr, ANCS::Extract, {_S(".yaml"), _S(".blend")}, 2};
} }
return {}; return {};
} }

View File

@ -35,12 +35,15 @@ 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);
inline const std::string& getName() const {return m_node.getName();} const std::string& getName() const {return m_node.getName();}
inline const HECL::SystemString& getLevelString() const {return m_levelString;} const HECL::SystemString& getLevelString() const {return m_levelString;}
typedef DNAMP1::PAK PAKType; using PAKType = DNAMP1::PAK;
inline const PAKType& getPAK() const {return m_pak;} const PAKType& getPAK() const {return m_pak;}
inline const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;}}; const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;}
void addCMDLRigPairs(std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo) const;
};
} }
} }

View File

@ -23,11 +23,25 @@ struct CMDL
bool force, bool force,
std::function<void(const HECL::SystemChar*)> fileChanged) std::function<void(const HECL::SystemChar*)> fileChanged)
{ {
/* Check for RigPair */
const PAKRouter<PAKBridge>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
CINF cinf;
CSKR cskr;
std::pair<CSKR*,CINF*> loadRp(nullptr, nullptr);
if (rp)
{
pakRouter.lookupAndReadDNA(rp->first, cskr);
pakRouter.lookupAndReadDNA(rp->second, cinf);
loadRp.first = &cskr;
loadRp.second = &cinf;
}
/* Do extract */
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
if (!conn.createBlend(outPath.getAbsolutePath())) if (!conn.createBlend(outPath.getAbsolutePath()))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, 5> DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, 5>
(conn, rs, pakRouter, entry, dataSpec); (conn, rs, pakRouter, entry, dataSpec, loadRp);
return conn.saveBlend(); return conn.saveBlend();
} }
}; };

View File

@ -53,6 +53,16 @@ void PAKBridge::build()
{ {
} }
void PAKBridge::addCMDLRigPairs(std::unordered_map<UniqueID64, std::pair<UniqueID64, UniqueID64>>& addTo) const
{
for (const std::pair<UniqueID64, PAK::Entry*>& entry : m_pak.m_idMap)
{
if (entry.second->type == FOURCC('CHAR'))
{
}
}
}
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry) ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
{ {
switch (entry.type) switch (entry.type)

View File

@ -28,6 +28,8 @@ public:
typedef PAK PAKType; typedef PAK PAKType;
inline const PAKType& getPAK() const {return m_pak;} inline const PAKType& getPAK() const {return m_pak;}
inline const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;} inline const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;}
void addCMDLRigPairs(std::unordered_map<UniqueID64, std::pair<UniqueID64, UniqueID64>>& addTo) const;
}; };
} }