mirror of https://github.com/AxioDL/metaforce.git
Work on world cooking
This commit is contained in:
parent
2dad2e2051
commit
26eb9891c8
|
@ -2,6 +2,7 @@
|
|||
#include "../DNAMP1/DNAMP1.hpp"
|
||||
#include "../DNAMP2/DNAMP2.hpp"
|
||||
#include "../DNAMP3/DNAMP3.hpp"
|
||||
#include "zeus/CTransform.hpp"
|
||||
|
||||
namespace DataSpec
|
||||
{
|
||||
|
@ -286,6 +287,18 @@ bool ReadMAPAToBlender(hecl::BlenderConnection& conn,
|
|||
"bpy.context.scene.objects.link(obj)\n"
|
||||
"bm.free()\n";
|
||||
|
||||
const zeus::CMatrix4f* tmpMtx = pakRouter.lookupMAPATransform(entry.id);
|
||||
const zeus::CMatrix4f& mtx = tmpMtx ? *tmpMtx : zeus::CMatrix4f::skIdentityMatrix4f;
|
||||
os.format("mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n"
|
||||
"mtxd = mtx.decompose()\n"
|
||||
"obj.rotation_mode = 'QUATERNION'\n"
|
||||
"obj.location = mtxd[0]\n"
|
||||
"obj.rotation_quaternion = mtxd[1]\n"
|
||||
"obj.scale = mtxd[2]\n",
|
||||
mtx[0][0], mtx[1][0], mtx[2][0], mtx[3][0],
|
||||
mtx[0][1], mtx[1][1], mtx[2][1], mtx[3][1],
|
||||
mtx[0][2], mtx[1][2], mtx[2][2], mtx[3][2]);
|
||||
|
||||
/* World background */
|
||||
hecl::ProjectPath worldBlend(outPath.getParentPath().getParentPath(), "!world.blend");
|
||||
if (worldBlend.isFile())
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "DNACommon.hpp"
|
||||
#include "GX.hpp"
|
||||
|
||||
|
||||
namespace DataSpec
|
||||
{
|
||||
namespace DNAMAPA
|
||||
|
|
|
@ -202,6 +202,10 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
|
|||
athena::io::YAMLDocWriter catalogWriter(nullptr);
|
||||
|
||||
enterPAKBridge(bridge);
|
||||
|
||||
/* Add MAPA transforms to global map */
|
||||
bridge.addMAPATransforms(*this, m_mapaTransforms, m_overrideEntries);
|
||||
|
||||
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK();
|
||||
for (const auto& namedEntry : pak.m_nameEntries)
|
||||
{
|
||||
|
@ -224,7 +228,7 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
|
|||
/* Write catalog */
|
||||
intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get());
|
||||
const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first;
|
||||
hecl::SystemString catalogPath = hecl::ProjectPath(pakPath, "catalog.yaml").getAbsolutePath();
|
||||
hecl::SystemString catalogPath = hecl::ProjectPath(pakPath, "!catalog.yaml").getAbsolutePath();
|
||||
athena::io::FileWriter writer(catalogPath);
|
||||
catalogWriter.finish(&writer);
|
||||
}
|
||||
|
@ -274,6 +278,11 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
|
|||
{
|
||||
if (!entry)
|
||||
return hecl::ProjectPath();
|
||||
|
||||
auto overrideSearch = m_overrideEntries.find(entry->id);
|
||||
if (overrideSearch != m_overrideEntries.end())
|
||||
return overrideSearch->second;
|
||||
|
||||
const PAKType* pak = m_pak.get();
|
||||
intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get());
|
||||
if (!pak)
|
||||
|
@ -384,6 +393,16 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const
|
|||
{
|
||||
if (!entry)
|
||||
return hecl::ProjectPath();
|
||||
|
||||
auto overrideSearch = m_overrideEntries.find(entry->id);
|
||||
if (overrideSearch != m_overrideEntries.end())
|
||||
{
|
||||
return overrideSearch->second.getCookedPath(
|
||||
*m_dataSpec.overrideDataSpec(overrideSearch->second,
|
||||
m_dataSpec.getDataSpecEntry(),
|
||||
hecl::SharedBlenderToken));
|
||||
}
|
||||
|
||||
const PAKType* pak = m_pak.get();
|
||||
intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get());
|
||||
if (!pak)
|
||||
|
@ -636,6 +655,15 @@ const typename PAKRouter<BRIDGETYPE>::RigPair* PAKRouter<BRIDGETYPE>::lookupCMDL
|
|||
return &search->second;
|
||||
}
|
||||
|
||||
template <class BRIDGETYPE>
|
||||
const zeus::CMatrix4f* PAKRouter<BRIDGETYPE>::lookupMAPATransform(const IDType& id) const
|
||||
{
|
||||
auto search = m_mapaTransforms.find(id);
|
||||
if (search == m_mapaTransforms.end())
|
||||
return nullptr;
|
||||
return &search->second;
|
||||
}
|
||||
|
||||
template <class BRIDGETYPE>
|
||||
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerWorking(const IDType& areaId, int layerIdx) const
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "DNACommon.hpp"
|
||||
#include "boo/ThreadLocalPtr.hpp"
|
||||
#include <array>
|
||||
#include "zeus/CMatrix4f.hpp"
|
||||
|
||||
namespace DataSpec
|
||||
{
|
||||
|
@ -168,8 +169,10 @@ private:
|
|||
ThreadLocalPtr<const nod::Node> m_node;
|
||||
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, hecl::ProjectPath> m_overrideEntries;
|
||||
std::unordered_map<IDType, RigPair> m_cmdlRigs;
|
||||
std::unordered_map<IDType, std::pair<IDType, std::string>> m_cskrCinfToCharacter;
|
||||
std::unordered_map<IDType, zeus::CMatrix4f> m_mapaTransforms;
|
||||
|
||||
hecl::ProjectPath getCharacterWorking(const EntryType* entry) const;
|
||||
|
||||
|
@ -221,6 +224,7 @@ public:
|
|||
}
|
||||
|
||||
const RigPair* lookupCMDLRigPair(const IDType& id) const;
|
||||
const zeus::CMatrix4f* lookupMAPATransform(const IDType& mapaId) const;
|
||||
|
||||
hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx) const;
|
||||
hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx, bool& activeOut) const;
|
||||
|
|
|
@ -34,6 +34,7 @@ add_library(DNAMP1
|
|||
DNAMP1.hpp DNAMP1.cpp
|
||||
${liblist}
|
||||
PAK.cpp
|
||||
MLVL.cpp
|
||||
STRG.hpp STRG.cpp
|
||||
AGSC.cpp
|
||||
CSNG.cpp
|
||||
|
|
|
@ -147,13 +147,7 @@ void PAKBridge::build()
|
|||
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
|
||||
|
||||
/* Trim possible trailing whitespace */
|
||||
#if HECL_UCS2
|
||||
while (areaDeps.name.size() && iswspace(areaDeps.name.back()))
|
||||
areaDeps.name.pop_back();
|
||||
#else
|
||||
while (areaDeps.name.size() && isspace(areaDeps.name.back()))
|
||||
areaDeps.name.pop_back();
|
||||
#endif
|
||||
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
|
||||
}
|
||||
if (areaDeps.name.empty())
|
||||
{
|
||||
|
@ -273,6 +267,63 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
|||
}
|
||||
}
|
||||
|
||||
static const atVec4f BottomRow = {0.f, 0.f, 0.f, 1.f};
|
||||
|
||||
void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
|
||||
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const
|
||||
{
|
||||
for (const std::pair<UniqueID32, PAK::Entry*>& entry : m_pak.m_idMap)
|
||||
{
|
||||
if (entry.second->type == FOURCC('MLVL'))
|
||||
{
|
||||
MLVL mlvl;
|
||||
{
|
||||
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
|
||||
mlvl.read(rs);
|
||||
}
|
||||
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath();
|
||||
|
||||
if (mlvl.worldNameId)
|
||||
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));
|
||||
|
||||
for (const MLVL::Area& area : mlvl.areas)
|
||||
{
|
||||
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
|
||||
if (area.areaNameId)
|
||||
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _S("!name.yaml"));
|
||||
}
|
||||
|
||||
if (mlvl.worldMap)
|
||||
{
|
||||
const nod::Node* mapNode;
|
||||
const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode);
|
||||
if (mapEntry)
|
||||
{
|
||||
PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode);
|
||||
u32 magic = rs.readUint32Big();
|
||||
if (magic == 0xDEADF00D)
|
||||
{
|
||||
rs.readUint32Big();
|
||||
u32 count = rs.readUint32Big();
|
||||
for (u32 i=0 ; i<count && i<mlvl.areas.size() ; ++i)
|
||||
{
|
||||
MLVL::Area& areaData = mlvl.areas[i];
|
||||
UniqueID32 mapaId;
|
||||
mapaId.read(rs);
|
||||
addTo[mapaId] = zeus::CMatrix4f(
|
||||
areaData.transformMtx[0],
|
||||
areaData.transformMtx[1],
|
||||
areaData.transformMtx[2],
|
||||
BottomRow).transposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK& pak, const PAK::Entry& entry)
|
||||
{
|
||||
switch (entry.type)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "../DNACommon/DNACommon.hpp"
|
||||
#include "PAK.hpp"
|
||||
#include "zeus/CMatrix4f.hpp"
|
||||
|
||||
namespace DataSpec
|
||||
{
|
||||
|
@ -37,6 +38,10 @@ public:
|
|||
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo,
|
||||
std::unordered_map<UniqueID32, std::pair<UniqueID32, std::string>>& cskrCinfToAncs) const;
|
||||
|
||||
void addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
|
||||
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
#include "MLVL.hpp"
|
||||
#include "SCLY.hpp"
|
||||
|
||||
namespace DataSpec
|
||||
{
|
||||
namespace DNAMP1
|
||||
{
|
||||
|
||||
bool MLVL::Extract(const SpecBase& dataSpec,
|
||||
PAKEntryReadStream& rs,
|
||||
const hecl::ProjectPath& outPath,
|
||||
PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
bool force,
|
||||
hecl::BlenderToken& btok,
|
||||
std::function<void(const hecl::SystemChar*)> fileChanged)
|
||||
{
|
||||
MLVL mlvl;
|
||||
mlvl.read(rs);
|
||||
athena::io::FileWriter writer(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath());
|
||||
mlvl.toYAMLStream(writer, static_cast<YAMLWriteMemberFn>(&MLVL::writeMeta));
|
||||
hecl::BlenderConnection& conn = btok.getBlenderConnection();
|
||||
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter,
|
||||
entry, force, fileChanged);
|
||||
}
|
||||
|
||||
bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld)
|
||||
{
|
||||
MLVL mlvl = {};
|
||||
athena::io::FileReader reader(inPath.getWithExtension(_S(".yaml"), true).getAbsolutePath());
|
||||
mlvl.fromYAMLStream(reader, static_cast<YAMLReadMemberFn>(&MLVL::readMeta));
|
||||
|
||||
mlvl.magic = 0xDEAFBABE;
|
||||
mlvl.version = 0x11;
|
||||
mlvl.saveWorldId = inPath.ensureAuxInfo(_S(".SAVW"));
|
||||
|
||||
size_t areaIdx = 0;
|
||||
for (const World::Area& area : wld.areas)
|
||||
{
|
||||
if (area.path.getPathType() != hecl::ProjectPath::Type::Directory)
|
||||
continue;
|
||||
hecl::DirectoryEnumerator dEnum(area.path.getAbsolutePath(),
|
||||
hecl::DirectoryEnumerator::Mode::DirsSorted);
|
||||
bool areaInit = false;
|
||||
|
||||
for (const hecl::DirectoryEnumerator::Entry& e : dEnum)
|
||||
{
|
||||
hecl::SystemString layerName;
|
||||
hecl::SystemChar* endCh = nullptr;
|
||||
hecl::StrToUl(e.m_name.c_str(), &endCh, 0);
|
||||
if (!endCh)
|
||||
layerName = e.m_name;
|
||||
else
|
||||
layerName = hecl::StringUtils::TrimWhitespace(hecl::SystemString(endCh));
|
||||
|
||||
hecl::ProjectPath objectsPath(area.path, e.m_name + _S("/!objects.yaml"));
|
||||
if (objectsPath.isNone())
|
||||
continue;
|
||||
|
||||
SCLY::ScriptLayer layer;
|
||||
{
|
||||
athena::io::FileReader freader(objectsPath.getAbsolutePath());
|
||||
if (!freader.isOpen())
|
||||
continue;
|
||||
if (!BigYAML::ValidateFromYAMLStream<DNAMP1::SCLY::ScriptLayer>(freader))
|
||||
continue;
|
||||
|
||||
athena::io::YAMLDocReader reader;
|
||||
if (!reader.parse(&freader))
|
||||
continue;
|
||||
|
||||
layer.read(reader);
|
||||
}
|
||||
|
||||
hecl::ProjectPath defActivePath(area.path, e.m_name + _S("/!defaultactive"));
|
||||
bool active = defActivePath.isNone() ? false : true;
|
||||
|
||||
if (!areaInit)
|
||||
{
|
||||
mlvl.areas.emplace_back();
|
||||
MLVL::Area& areaOut = mlvl.areas.back();
|
||||
areaInit = true;
|
||||
}
|
||||
}
|
||||
++areaIdx;
|
||||
}
|
||||
mlvl.memRelayLinkCount = mlvl.memRelayLinks.size();
|
||||
mlvl.areaCount = mlvl.areas.size();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -108,8 +108,6 @@ struct MLVL : BigYAML
|
|||
|
||||
void readMeta(athena::io::YAMLDocReader& __dna_docin)
|
||||
{
|
||||
/* worldNameId */
|
||||
__dna_docin.enumerate("worldNameId", worldNameId);
|
||||
/* worldSkyboxId */
|
||||
__dna_docin.enumerate("worldSkyboxId", worldSkyboxId);
|
||||
/* audioGroupCount squelched */
|
||||
|
@ -119,8 +117,6 @@ struct MLVL : BigYAML
|
|||
|
||||
void writeMeta(athena::io::YAMLDocWriter& __dna_docout) const
|
||||
{
|
||||
/* worldNameId */
|
||||
__dna_docout.enumerate("worldNameId", worldNameId);
|
||||
/* worldSkyboxId */
|
||||
__dna_docout.enumerate("worldSkyboxId", worldSkyboxId);
|
||||
/* audioGroupCount squelched */
|
||||
|
@ -135,16 +131,13 @@ struct MLVL : BigYAML
|
|||
const PAK::Entry& entry,
|
||||
bool force,
|
||||
hecl::BlenderToken& btok,
|
||||
std::function<void(const hecl::SystemChar*)> fileChanged)
|
||||
{
|
||||
MLVL mlvl;
|
||||
mlvl.read(rs);
|
||||
athena::io::FileWriter writer(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath());
|
||||
mlvl.toYAMLStream(writer, static_cast<YAMLWriteMemFn>(&MLVL::writeMeta));
|
||||
hecl::BlenderConnection& conn = btok.getBlenderConnection();
|
||||
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter,
|
||||
entry, force, fileChanged);
|
||||
}
|
||||
std::function<void(const hecl::SystemChar*)> fileChanged);
|
||||
|
||||
using World = hecl::BlenderConnection::DataStream::World;
|
||||
|
||||
static bool Cook(const hecl::ProjectPath& outPath,
|
||||
const hecl::ProjectPath& inPath,
|
||||
const World& wld);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -262,7 +262,7 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
|
|||
false, false, true);
|
||||
for (const hecl::DirectoryEnumerator::Entry& ent : dEnum)
|
||||
{
|
||||
hecl::ProjectPath layerScriptPath(areaDirPath, ent.m_name + _S("/objects.yaml"));
|
||||
hecl::ProjectPath layerScriptPath(areaDirPath, ent.m_name + _S("/!objects.yaml"));
|
||||
if (layerScriptPath.isFile())
|
||||
layerScriptPaths.push_back(std::move(layerScriptPath));
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ void SCLY::exportToLayerDirectories(const PAK::Entry& entry, PAKRouter<PAKBridge
|
|||
fclose(hecl::Fopen(activePath.getAbsolutePath().c_str(), _S("wb")));
|
||||
}
|
||||
|
||||
hecl::ProjectPath yamlFile(layerPath, _S("objects.yaml"));
|
||||
hecl::ProjectPath yamlFile(layerPath, _S("!objects.yaml"));
|
||||
if (force || yamlFile.isNone())
|
||||
{
|
||||
athena::io::FileWriter writer(yamlFile.getAbsolutePath());
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "../DNACommon/FONT.hpp"
|
||||
#include "../DNACommon/DGRP.hpp"
|
||||
#include "../DNACommon/ATBL.hpp"
|
||||
#include "Runtime/GCNTypes.hpp"
|
||||
|
||||
namespace DataSpec
|
||||
{
|
||||
|
@ -121,13 +122,7 @@ void PAKBridge::build()
|
|||
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
|
||||
|
||||
/* Trim possible trailing whitespace */
|
||||
#if HECL_UCS2
|
||||
while (areaDeps.name.size() && iswspace(areaDeps.name.back()))
|
||||
areaDeps.name.pop_back();
|
||||
#else
|
||||
while (areaDeps.name.size() && isspace(areaDeps.name.back()))
|
||||
areaDeps.name.pop_back();
|
||||
#endif
|
||||
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
|
||||
}
|
||||
if (areaDeps.name.empty())
|
||||
{
|
||||
|
@ -209,6 +204,63 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
|||
}
|
||||
}
|
||||
|
||||
static const atVec4f BottomRow = {0.f, 0.f, 0.f, 1.f};
|
||||
|
||||
void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
|
||||
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const
|
||||
{
|
||||
for (const std::pair<UniqueID32, DNAMP1::PAK::Entry*>& entry : m_pak.m_idMap)
|
||||
{
|
||||
if (entry.second->type == FOURCC('MLVL'))
|
||||
{
|
||||
MLVL mlvl;
|
||||
{
|
||||
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
|
||||
mlvl.read(rs);
|
||||
}
|
||||
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath();
|
||||
|
||||
if (mlvl.worldNameId)
|
||||
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));
|
||||
|
||||
for (const MLVL::Area& area : mlvl.areas)
|
||||
{
|
||||
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
|
||||
if (area.areaNameId)
|
||||
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _S("!name.yaml"));
|
||||
}
|
||||
|
||||
if (mlvl.worldMap)
|
||||
{
|
||||
const nod::Node* mapNode;
|
||||
const DNAMP1::PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode);
|
||||
if (mapEntry)
|
||||
{
|
||||
PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode);
|
||||
u32 magic = rs.readUint32Big();
|
||||
if (magic == 0xDEADF00D)
|
||||
{
|
||||
rs.readUint32Big();
|
||||
u32 count = rs.readUint32Big();
|
||||
for (u32 i=0 ; i<count && i<mlvl.areas.size() ; ++i)
|
||||
{
|
||||
MLVL::Area& areaData = mlvl.areas[i];
|
||||
UniqueID32 mapaId;
|
||||
mapaId.read(rs);
|
||||
addTo[mapaId] = zeus::CMatrix4f(
|
||||
areaData.transformMtx[0],
|
||||
areaData.transformMtx[1],
|
||||
areaData.transformMtx[2],
|
||||
BottomRow).transposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const DNAMP1::PAK& pak, const DNAMP1::PAK::Entry& entry)
|
||||
{
|
||||
switch (entry.type)
|
||||
|
|
|
@ -38,6 +38,10 @@ public:
|
|||
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo,
|
||||
std::unordered_map<UniqueID32, std::pair<UniqueID32, std::string>>& cskrCinfToAncs) const;
|
||||
|
||||
void addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
|
||||
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "../DNACommon/FONT.hpp"
|
||||
#include "../DNACommon/FSM2.hpp"
|
||||
#include "../DNACommon/DGRP.hpp"
|
||||
#include "Runtime/GCNTypes.hpp"
|
||||
|
||||
namespace DataSpec
|
||||
{
|
||||
|
@ -127,13 +128,7 @@ void PAKBridge::build()
|
|||
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
|
||||
|
||||
/* Trim possible trailing whitespace */
|
||||
#if HECL_UCS2
|
||||
while (areaDeps.name.size() && iswspace(areaDeps.name.back()))
|
||||
areaDeps.name.pop_back();
|
||||
#else
|
||||
while (areaDeps.name.size() && isspace(areaDeps.name.back()))
|
||||
areaDeps.name.pop_back();
|
||||
#endif
|
||||
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
|
||||
}
|
||||
if (areaDeps.name.empty())
|
||||
{
|
||||
|
@ -218,6 +213,63 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
|||
}
|
||||
}
|
||||
|
||||
static const atVec4f BottomRow = {0.f, 0.f, 0.f, 1.f};
|
||||
|
||||
void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID64, zeus::CMatrix4f>& addTo,
|
||||
std::unordered_map<UniqueID64, hecl::ProjectPath>& pathOverrides) const
|
||||
{
|
||||
for (const std::pair<UniqueID64, PAK::Entry*>& entry : m_pak.m_idMap)
|
||||
{
|
||||
if (entry.second->type == FOURCC('MLVL'))
|
||||
{
|
||||
MLVL mlvl;
|
||||
{
|
||||
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
|
||||
mlvl.read(rs);
|
||||
}
|
||||
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath();
|
||||
|
||||
if (mlvl.worldNameId)
|
||||
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));
|
||||
|
||||
for (const MLVL::Area& area : mlvl.areas)
|
||||
{
|
||||
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
|
||||
if (area.areaNameId)
|
||||
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _S("!name.yaml"));
|
||||
}
|
||||
|
||||
if (mlvl.worldMap)
|
||||
{
|
||||
const nod::Node* mapNode;
|
||||
const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode);
|
||||
if (mapEntry)
|
||||
{
|
||||
PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode);
|
||||
u32 magic = rs.readUint32Big();
|
||||
if (magic == 0xDEADF00D)
|
||||
{
|
||||
rs.readUint32Big();
|
||||
u32 count = rs.readUint32Big();
|
||||
for (u32 i=0 ; i<count && i<mlvl.areas.size() ; ++i)
|
||||
{
|
||||
MLVL::Area& areaData = mlvl.areas[i];
|
||||
UniqueID64 mapaId;
|
||||
mapaId.read(rs);
|
||||
addTo[mapaId] = zeus::CMatrix4f(
|
||||
areaData.transformMtx[0],
|
||||
areaData.transformMtx[1],
|
||||
areaData.transformMtx[2],
|
||||
BottomRow).transposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK& pak, const PAK::Entry& entry)
|
||||
{
|
||||
switch (entry.type)
|
||||
|
|
|
@ -38,6 +38,10 @@ public:
|
|||
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID64, std::pair<UniqueID64, UniqueID64>>& addTo,
|
||||
std::unordered_map<UniqueID64, std::pair<UniqueID64, std::string>>& cskrCinfToChar) const;
|
||||
|
||||
void addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID64, zeus::CMatrix4f>& addTo,
|
||||
std::unordered_map<UniqueID64, hecl::ProjectPath>& pathOverrides) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::BlenderToken& btok)
|
|||
|
||||
const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::ProjectPath& path,
|
||||
const hecl::Database::DataSpecEntry* oldEntry,
|
||||
hecl::BlenderToken& btok)
|
||||
hecl::BlenderToken& btok) const
|
||||
{
|
||||
if (!checkPathPrefix(path))
|
||||
return nullptr;
|
||||
|
|
|
@ -20,7 +20,7 @@ struct SpecBase : hecl::Database::IDataSpec
|
|||
bool canCook(const hecl::ProjectPath& path, hecl::BlenderToken& btok);
|
||||
const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path,
|
||||
const hecl::Database::DataSpecEntry* oldEntry,
|
||||
hecl::BlenderToken& btok);
|
||||
hecl::BlenderToken& btok) const;
|
||||
void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath,
|
||||
bool fast, hecl::BlenderToken& btok, FCookProgress progress);
|
||||
|
||||
|
@ -46,7 +46,7 @@ struct SpecBase : hecl::Database::IDataSpec
|
|||
virtual const hecl::Database::DataSpecEntry* getOriginalSpec() const=0;
|
||||
|
||||
/* Basic path check (game directory matching) */
|
||||
virtual bool checkPathPrefix(const hecl::ProjectPath& path)=0;
|
||||
virtual bool checkPathPrefix(const hecl::ProjectPath& path) const=0;
|
||||
|
||||
/* Pre-cook handlers */
|
||||
virtual bool validateYAMLDNAType(athena::io::IStreamReader& fp) const=0;
|
||||
|
|
|
@ -324,7 +324,7 @@ struct SpecMP1 : SpecBase
|
|||
return m_pakRouter.getWorking(id);
|
||||
}
|
||||
|
||||
bool checkPathPrefix(const hecl::ProjectPath& path)
|
||||
bool checkPathPrefix(const hecl::ProjectPath& path) const
|
||||
{
|
||||
return path.getRelativePath().compare(0, 4, _S("MP1/")) == 0;
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ struct SpecMP1 : SpecBase
|
|||
FCookProgress progress)
|
||||
{
|
||||
BlendStream::World world = ds.compileWorld();
|
||||
|
||||
DNAMP1::MLVL::Cook(out, in, world);
|
||||
}
|
||||
|
||||
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
|
||||
|
|
|
@ -282,7 +282,7 @@ struct SpecMP2 : SpecBase
|
|||
return m_pakRouter.getWorking(id);
|
||||
}
|
||||
|
||||
bool checkPathPrefix(const hecl::ProjectPath& path)
|
||||
bool checkPathPrefix(const hecl::ProjectPath& path) const
|
||||
{
|
||||
return path.getRelativePath().compare(0, 4, _S("MP2/")) == 0;
|
||||
}
|
||||
|
|
|
@ -473,7 +473,7 @@ struct SpecMP3 : SpecBase
|
|||
return m_pakRouter.getWorking(id);
|
||||
}
|
||||
|
||||
bool checkPathPrefix(const hecl::ProjectPath& path)
|
||||
bool checkPathPrefix(const hecl::ProjectPath& path) const
|
||||
{
|
||||
return path.getRelativePath().compare(0, 4, _S("MP3/")) == 0;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveCatalogs(const hecl::Pr
|
|||
continue;
|
||||
|
||||
/* Read catalog.yaml for .pak directory if exists */
|
||||
if (level == 1 && !ent.m_name.compare(_S("catalog.yaml")))
|
||||
if (level == 1 && !ent.m_name.compare(_S("!catalog.yaml")))
|
||||
{
|
||||
ReadCatalog(path, nameWriter);
|
||||
continue;
|
||||
|
@ -228,6 +228,14 @@ bool ProjectResourceFactoryBase::AddFileToIndex(const hecl::ProjectPath& path,
|
|||
#if DUMP_CACHE_FILL
|
||||
DumpCacheAdd(pathTag, subPath);
|
||||
#endif
|
||||
|
||||
subPath = asGlob.ensureAuxInfo(_S(".SAVW"));
|
||||
pathTag = BuildTagFromPath(subPath, m_backgroundBlender);
|
||||
m_tagToPath[pathTag] = subPath;
|
||||
m_pathToTag[subPath.hash()] = pathTag;
|
||||
#if DUMP_CACHE_FILL
|
||||
DumpCacheAdd(pathTag, subPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Cache in-memory */
|
||||
|
@ -264,7 +272,7 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec
|
|||
continue;
|
||||
|
||||
/* Read catalog.yaml for .pak directory if exists */
|
||||
if (level == 1 && !ent.m_name.compare(_S("catalog.yaml")))
|
||||
if (level == 1 && !ent.m_name.compare(_S("!catalog.yaml")))
|
||||
{
|
||||
ReadCatalog(path, nameWriter);
|
||||
continue;
|
||||
|
|
|
@ -96,8 +96,12 @@ SObjectTag ProjectResourceFactoryMP1::BuildTagFromPath(const hecl::ProjectPath&
|
|||
case hecl::BlenderConnection::BlendType::World:
|
||||
{
|
||||
if (path.getAuxInfo().size())
|
||||
{
|
||||
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _S(".MAPW")))
|
||||
return {SBIG('MAPW'), path.hash().val32()};
|
||||
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _S(".SAVW")))
|
||||
return {SBIG('SAVW'), path.hash().val32()};
|
||||
}
|
||||
return {SBIG('MLVL'), path.hash().val32()};
|
||||
}
|
||||
case hecl::BlenderConnection::BlendType::MapArea:
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit b513ed1ded026067d9ba1ff6908783a0b678ba34
|
||||
Subproject commit 471385dd4a8cad60bd65211f7b17f118d961ef94
|
2
specter
2
specter
|
@ -1 +1 @@
|
|||
Subproject commit f6318521f9f28de34051f8e519f7ba8069501468
|
||||
Subproject commit b9877633b0774cd85557696228bfa8e7505ec153
|
Loading…
Reference in New Issue