2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-01 20:13:32 +00:00

New code style refactor

This commit is contained in:
Jack Andersen 2018-12-07 19:30:43 -10:00
parent 41ae32be31
commit 636c82a568
1451 changed files with 171430 additions and 203303 deletions

View File

@ -1,5 +1,5 @@
--- ---
IndentWidth: 4 BasedOnStyle: LLVM
ColumnLimit: 120 ColumnLimit: 120
UseTab: Never UseTab: Never
--- ---
@ -8,7 +8,6 @@ DerivePointerAlignment: false
PointerAlignment: Left PointerAlignment: Left
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false AlignConsecutiveAssignments: false
BreakBeforeBraces: Allman
IndentCaseLabels: false IndentCaseLabels: false
AllowShortBlocksOnASingleLine: true AllowShortBlocksOnASingleLine: true
AlignOperands: true AlignOperands: true
@ -24,6 +23,6 @@ NamespaceIndentation: None
BinPackArguments: true BinPackArguments: true
BinPackParameters: true BinPackParameters: true
SortIncludes: false SortIncludes: false
AccessModifierOffset: -4 AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 0 ConstructorInitializerIndentWidth: 0
ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerAllOnOneLineOrOnePerLine: true

1
.idea/vcs.xml generated
View File

@ -10,7 +10,6 @@
<mapping directory="$PROJECT_DIR$/discord-rpc" vcs="Git" /> <mapping directory="$PROJECT_DIR$/discord-rpc" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hecl" vcs="Git" /> <mapping directory="$PROJECT_DIR$/hecl" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hecl-gui" vcs="Git" /> <mapping directory="$PROJECT_DIR$/hecl-gui" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hecl-gui/quazip" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hecl/extern/athena" vcs="Git" /> <mapping directory="$PROJECT_DIR$/hecl/extern/athena" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hecl/extern/boo" vcs="Git" /> <mapping directory="$PROJECT_DIR$/hecl/extern/boo" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hecl/extern/boo/glslang" vcs="Git" /> <mapping directory="$PROJECT_DIR$/hecl/extern/boo/glslang" vcs="Git" />

View File

@ -6,79 +6,70 @@ extern "C" const size_t ASSET_NAME_MP32_SZ;
extern "C" const uint8_t ASSET_NAME_MP64[]; extern "C" const uint8_t ASSET_NAME_MP64[];
extern "C" const size_t ASSET_NAME_MP64_SZ; extern "C" const size_t ASSET_NAME_MP64_SZ;
namespace DataSpec::AssetNameMap namespace DataSpec::AssetNameMap {
{
logvisor::Module Log("AssetNameMap"); logvisor::Module Log("AssetNameMap");
struct SAsset struct SAsset {
{ std::string name;
std::string name; std::string directory;
std::string directory; hecl::FourCC type;
hecl::FourCC type; SAsset() = default;
SAsset() = default; SAsset(const hecl::FourCC& typeIn, athena::io::IStreamReader& in) : type(typeIn) {
SAsset(const hecl::FourCC& typeIn, athena::io::IStreamReader& in) uint32_t nameLen = in.readUint32Big();
: type(typeIn) name = in.readString(nameLen);
{ uint32_t dirLen = in.readUint32Big();
uint32_t nameLen = in.readUint32Big(); directory = in.readString(dirLen);
name = in.readString(nameLen); }
uint32_t dirLen = in.readUint32Big();
directory = in.readString(dirLen);
}
}; };
static std::unordered_map<uint64_t, SAsset> g_AssetNameMap; static std::unordered_map<uint64_t, SAsset> g_AssetNameMap;
static bool g_AssetNameMapInit = false; static bool g_AssetNameMapInit = false;
void LoadAssetMap(athena::io::MemoryReader& ar) void LoadAssetMap(athena::io::MemoryReader& ar) {
{ if (!ar.hasError()) {
if (!ar.hasError()) hecl::FourCC magic;
{ if (ar.length() >= 4)
hecl::FourCC magic; ar.readBytesToBuf(&magic, 4);
if (ar.length() >= 4) if (magic != FOURCC('AIDM'))
ar.readBytesToBuf(&magic, 4); Log.report(logvisor::Warning,
if (magic != FOURCC('AIDM')) _SYS_STR("Unable to load asset map; Assets will not have proper filenames for most files."));
Log.report(logvisor::Warning, _SYS_STR("Unable to load asset map; Assets will not have proper filenames for most files.")); else {
else uint32_t assetCount = ar.readUint32Big();
{ g_AssetNameMap.reserve(assetCount);
uint32_t assetCount = ar.readUint32Big(); for (uint32_t i = 0; i < assetCount; ++i) {
g_AssetNameMap.reserve(assetCount); hecl::FourCC type;
for (uint32_t i = 0 ; i<assetCount ; ++i) ar.readBytesToBuf(&type, 4);
{ uint64_t id = ar.readUint64Big();
hecl::FourCC type; g_AssetNameMap[id] = SAsset(type, ar);
ar.readBytesToBuf(&type, 4); }
uint64_t id = ar.readUint64Big();
g_AssetNameMap[id] = SAsset(type, ar);
}
}
} }
}
} }
void InitAssetNameMap() void InitAssetNameMap() {
{ if (g_AssetNameMapInit)
if (g_AssetNameMapInit) return;
return;
Log.report(logvisor::Info, "Initializing asset name database..."); Log.report(logvisor::Info, "Initializing asset name database...");
/* First load the 32bit map for MP1/2 */ /* First load the 32bit map for MP1/2 */
{ {
athena::io::MemoryReader ar(ASSET_NAME_MP32, ASSET_NAME_MP32_SZ); athena::io::MemoryReader ar(ASSET_NAME_MP32, ASSET_NAME_MP32_SZ);
LoadAssetMap(ar); LoadAssetMap(ar);
} }
/* Now load the 64bit map for MP3 */ /* Now load the 64bit map for MP3 */
{ {
athena::io::MemoryReader ar(ASSET_NAME_MP64, ASSET_NAME_MP64_SZ); athena::io::MemoryReader ar(ASSET_NAME_MP64, ASSET_NAME_MP64_SZ);
LoadAssetMap(ar); LoadAssetMap(ar);
} }
g_AssetNameMapInit = true; g_AssetNameMapInit = true;
} }
const std::string* TranslateIdToName(const UniqueID32& id) const std::string* TranslateIdToName(const UniqueID32& id) {
{ if (g_AssetNameMap.find(id.toUint64()) == g_AssetNameMap.end())
if (g_AssetNameMap.find(id.toUint64()) == g_AssetNameMap.end()) return nullptr;
return nullptr;
return &g_AssetNameMap[id.toUint64()].name; return &g_AssetNameMap[id.toUint64()].name;
} }
} } // namespace DataSpec::AssetNameMap

View File

@ -4,9 +4,8 @@
#include <string> #include <string>
#include "DNACommon/DNACommon.hpp" #include "DNACommon/DNACommon.hpp"
namespace DataSpec::AssetNameMap namespace DataSpec::AssetNameMap {
{
void InitAssetNameMap(); void InitAssetNameMap();
const std::string* TranslateIdToName(const UniqueID32&); const std::string* TranslateIdToName(const UniqueID32&);
const std::string* TranslateIdToName(const UniqueID64&); const std::string* TranslateIdToName(const UniqueID64&);
} } // namespace DataSpec::AssetNameMap

View File

@ -5,20 +5,18 @@
extern "C" uint8_t RETRO_MASTER_SHADER[]; extern "C" uint8_t RETRO_MASTER_SHADER[];
extern "C" size_t RETRO_MASTER_SHADER_SZ; extern "C" size_t RETRO_MASTER_SHADER_SZ;
namespace DataSpec::Blender namespace DataSpec::Blender {
{
bool BuildMasterShader(const hecl::ProjectPath& path) bool BuildMasterShader(const hecl::ProjectPath& path) {
{ hecl::blender::Connection& conn = hecl::blender::Connection::SharedConnection();
hecl::blender::Connection& conn = hecl::blender::Connection::SharedConnection(); if (!conn.createBlend(path, hecl::blender::BlendType::None))
if (!conn.createBlend(path, hecl::blender::BlendType::None)) return false;
return false; {
{ hecl::blender::PyOutStream os = conn.beginPythonOut(true);
hecl::blender::PyOutStream os = conn.beginPythonOut(true); os << RETRO_MASTER_SHADER;
os << RETRO_MASTER_SHADER; os << "make_master_shader_library()\n";
os << "make_master_shader_library()\n"; }
} return conn.saveBlend();
return conn.saveBlend();
} }
} } // namespace DataSpec::Blender

View File

@ -2,10 +2,8 @@
#include <hecl/hecl.hpp> #include <hecl/hecl.hpp>
namespace DataSpec::Blender namespace DataSpec::Blender {
{
bool BuildMasterShader(const hecl::ProjectPath& path); bool BuildMasterShader(const hecl::ProjectPath& path);
} }

View File

@ -7,302 +7,259 @@
#include "DataSpec/DNAMP3/CHAR.hpp" #include "DataSpec/DNAMP3/CHAR.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAANCS namespace DataSpec::DNAANCS {
{
template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion> template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion>
bool ReadANCSToBlender(hecl::blender::Connection& conn, bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, const hecl::ProjectPath& outPath,
const ANCSDNA& ancs, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged, bool force) {
PAKRouter& pakRouter, /* Extract character CMDL/CSKR first */
const typename PAKRouter::EntryType& entry, std::vector<CharacterResInfo<typename PAKRouter::IDType>> chResInfo;
const SpecBase& dataspec, ancs.getCharacterResInfo(chResInfo);
std::function<void(const hecl::SystemChar*)> fileChanged, for (const auto& info : chResInfo) {
bool force) const nod::Node* node;
{ const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node, true, false);
/* Extract character CMDL/CSKR first */ if (cmdlE) {
std::vector<CharacterResInfo<typename PAKRouter::IDType>> chResInfo; hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
ancs.getCharacterResInfo(chResInfo); if (force || cmdlPath.isNone()) {
for (const auto& info : chResInfo) cmdlPath.makeDirChain(false);
{ if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh))
const nod::Node* node; return false;
const typename PAKRouter::EntryType* cmdlE =
pakRouter.lookupEntry(info.cmdl, &node, true, false);
if (cmdlE)
{
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
if (force || cmdlPath.isNone())
{
cmdlPath.makeDirChain(false);
if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh))
return false;
std::string bestName = pakRouter.getBestEntryName(*cmdlE); std::string bestName = pakRouter.getBestEntryName(*cmdlE);
hecl::SystemStringConv bestNameView(bestName); hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str()); fileChanged(bestNameView.c_str());
typename ANCSDNA::CSKRType cskr; typename ANCSDNA::CSKRType cskr;
pakRouter.lookupAndReadDNA(info.cskr, cskr); pakRouter.lookupAndReadDNA(info.cskr, cskr);
typename ANCSDNA::CINFType cinf; typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(info.cinf, cinf); pakRouter.lookupAndReadDNA(info.cinf, cinf);
using RigPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>; using RigPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>;
RigPair rigPair(&cskr, &cinf); RigPair rigPair(&cskr, &cinf);
PAKEntryReadStream rs = cmdlE->beginReadStream(*node); PAKEntryReadStream rs = cmdlE->beginReadStream(*node);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion> DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>(
(conn, rs, pakRouter, *cmdlE, dataspec, rigPair); conn, rs, pakRouter, *cmdlE, dataspec, rigPair);
conn.saveBlend(); conn.saveBlend();
} }
}
}
/* Extract attachment CMDL/CSKRs first */
auto attRange = pakRouter.lookupCharacterAttachmentRigs(entry.id);
for (auto it = attRange.first; it != attRange.second; ++it) {
auto cmdlid = it->second.first.second;
const nod::Node* node;
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, &node, true, false);
if (cmdlE) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
if (force || cmdlPath.isNone()) {
cmdlPath.makeDirChain(false);
if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh))
return false;
std::string bestName = pakRouter.getBestEntryName(*cmdlE);
hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str());
const auto* rp = pakRouter.lookupCMDLRigPair(cmdlid);
typename ANCSDNA::CSKRType cskr;
pakRouter.lookupAndReadDNA(rp->first, cskr);
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(rp->second, 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, SurfaceHeader, CMDLVersion>(
conn, rs, pakRouter, *cmdlE, dataspec, rigPair);
conn.saveBlend();
}
}
}
std::string bestName = pakRouter.getBestEntryName(entry);
hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str());
/* Establish ANCS blend */
if (!conn.createBlend(outPath, hecl::blender::BlendType::Actor))
return false;
std::string firstName;
typename ANCSDNA::CINFType firstCinf;
{
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os.format(
"import bpy\n"
"from mathutils import Vector\n"
"bpy.context.scene.name = '%s'\n"
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n"
"\n"
"# Using 'Blender Game'\n"
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'LAMP' and ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"\n"
"actor_data = bpy.context.scene.hecl_sact_data\n"
"arm_obj = None\n",
pakRouter.getBestEntryName(entry).c_str());
std::unordered_set<typename PAKRouter::IDType> cinfsDone;
for (const auto& info : chResInfo) {
/* Provide data to add-on */
os.format(
"actor_subtype = actor_data.subtypes.add()\n"
"actor_subtype.name = '%s'\n\n",
info.name.c_str());
/* Build CINF if needed */
if (cinfsDone.find(info.cinf) == cinfsDone.end()) {
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(info.cinf, cinf);
cinf.sendCINFToBlender(os, info.cinf);
if (cinfsDone.empty()) {
firstName = ANCSDNA::CINFType::GetCINFArmatureName(info.cinf);
firstCinf = cinf;
} }
cinfsDone.insert(info.cinf);
} else
os.format("arm_obj = bpy.data.objects['CINF_%s']\n", info.cinf.toString().c_str());
os << "actor_subtype.linked_armature = arm_obj.name\n";
/* Link CMDL */
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, nullptr, true, false);
if (cmdlE) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).data(), true);
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.objects.link(obj)\n"
"obj.parent = arm_obj\n"
"obj.parent_type = 'ARMATURE'\n"
"actor_subtype.linked_mesh = obj.name\n\n";
}
/* Link overlays */
for (const auto& overlay : info.overlays) {
os << "overlay = actor_subtype.overlays.add()\n";
os.format("overlay.name = '%s'\n", overlay.first.c_str());
/* Link CMDL */
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(overlay.second.first, nullptr, true, false);
if (cmdlE) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).data(), true);
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.objects.link(obj)\n"
"obj.parent = arm_obj\n"
"obj.parent_type = 'ARMATURE'\n"
"overlay.linked_mesh = obj.name\n\n";
}
}
} }
/* Extract attachment CMDL/CSKRs first */ /* Link attachments */
auto attRange = pakRouter.lookupCharacterAttachmentRigs(entry.id); for (auto it = attRange.first; it != attRange.second; ++it) {
for (auto it = attRange.first; it != attRange.second; ++it) os << "attachment = actor_data.attachments.add()\n";
{ os.format("attachment.name = '%s'\n", it->second.second.c_str());
auto cmdlid = it->second.first.second;
const nod::Node* node; auto cinfid = it->second.first.first;
const typename PAKRouter::EntryType* cmdlE = auto cmdlid = it->second.first.second;
pakRouter.lookupEntry(cmdlid, &node, true, false);
if (cmdlE)
{
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
if (force || cmdlPath.isNone())
{
cmdlPath.makeDirChain(false);
if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh))
return false;
std::string bestName = pakRouter.getBestEntryName(*cmdlE); if (cinfid) {
hecl::SystemStringConv bestNameView(bestName); /* Build CINF if needed */
fileChanged(bestNameView.c_str()); if (cinfsDone.find(cinfid) == cinfsDone.end()) {
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(cinfid, cinf);
cinf.sendCINFToBlender(os, cinfid);
if (cinfsDone.empty()) {
firstName = ANCSDNA::CINFType::GetCINFArmatureName(cinfid);
firstCinf = cinf;
}
cinfsDone.insert(cinfid);
} else
os.format("arm_obj = bpy.data.objects['CINF_%s']\n", cinfid.toString().c_str());
os << "attachment.linked_armature = arm_obj.name\n";
}
const auto* rp = pakRouter.lookupCMDLRigPair(cmdlid); /* Link CMDL */
typename ANCSDNA::CSKRType cskr; const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, nullptr, true, false);
pakRouter.lookupAndReadDNA(rp->first, cskr); if (cmdlE) {
typename ANCSDNA::CINFType cinf; hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
pakRouter.lookupAndReadDNA(rp->second, cinf); os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).data(), true);
using RigPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>;
RigPair rigPair(&cskr, &cinf);
PAKEntryReadStream rs = cmdlE->beginReadStream(*node); /* Attach CMDL to CINF */
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion> os << "if obj.name not in bpy.context.scene.objects:\n"
(conn, rs, pakRouter, *cmdlE, dataspec, rigPair); " bpy.context.scene.objects.link(obj)\n"
"obj.parent = arm_obj\n"
conn.saveBlend(); "obj.parent_type = 'ARMATURE'\n"
} "attachment.linked_mesh = obj.name\n\n";
} }
} }
}
std::string bestName = pakRouter.getBestEntryName(entry); {
hecl::SystemStringConv bestNameView(bestName); hecl::blender::DataStream ds = conn.beginData();
fileChanged(bestNameView.c_str()); std::unordered_map<std::string, hecl::blender::Matrix3f> matrices = ds.getBoneMatrices(firstName);
ds.close();
DNAANIM::RigInverter<typename ANCSDNA::CINFType> inverter(firstCinf, matrices);
/* Establish ANCS blend */ hecl::blender::PyOutStream os = conn.beginPythonOut(true);
if (!conn.createBlend(outPath, hecl::blender::BlendType::Actor)) os << "import bpy\n"
return false; "actor_data = bpy.context.scene.hecl_sact_data\n";
std::string firstName; /* Get animation primitives */
typename ANCSDNA::CINFType firstCinf; std::map<atUint32, AnimationResInfo<typename PAKRouter::IDType>> animResInfo;
{ ancs.getAnimationResInfo(&pakRouter, animResInfo);
hecl::blender::PyOutStream os = conn.beginPythonOut(true); for (const auto& id : animResInfo) {
typename ANCSDNA::ANIMType anim;
if (pakRouter.lookupAndReadDNA(id.second.animId, anim, true)) {
os.format(
"act = bpy.data.actions.new('%s')\n"
"act.use_fake_user = True\n",
id.second.name.c_str());
anim.sendANIMToBlender(os, inverter, id.second.additive);
}
os.format("import bpy\n" os.format(
"from mathutils import Vector\n" "actor_action = actor_data.actions.add()\n"
"bpy.context.scene.name = '%s'\n" "actor_action.name = '%s'\n",
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n" id.second.name.c_str());
"\n"
"# Using 'Blender Game'\n"
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'LAMP' and ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"\n"
"actor_data = bpy.context.scene.hecl_sact_data\n"
"arm_obj = None\n",
pakRouter.getBestEntryName(entry).c_str());
std::unordered_set<typename PAKRouter::IDType> cinfsDone; /* Extract EVNT if present */
for (const auto& info : chResInfo) anim.extractEVNT(id.second, outPath, pakRouter, force);
{
/* Provide data to add-on */
os.format("actor_subtype = actor_data.subtypes.add()\n"
"actor_subtype.name = '%s'\n\n",
info.name.c_str());
/* Build CINF if needed */
if (cinfsDone.find(info.cinf) == cinfsDone.end())
{
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(info.cinf, cinf);
cinf.sendCINFToBlender(os, info.cinf);
if (cinfsDone.empty())
{
firstName = ANCSDNA::CINFType::GetCINFArmatureName(info.cinf);
firstCinf = cinf;
}
cinfsDone.insert(info.cinf);
}
else
os.format("arm_obj = bpy.data.objects['CINF_%s']\n", info.cinf.toString().c_str());
os << "actor_subtype.linked_armature = arm_obj.name\n";
/* Link CMDL */
const typename PAKRouter::EntryType* cmdlE =
pakRouter.lookupEntry(info.cmdl, nullptr, true, false);
if (cmdlE)
{
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(),
pakRouter.getBestEntryName(*cmdlE).data(), true);
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.objects.link(obj)\n"
"obj.parent = arm_obj\n"
"obj.parent_type = 'ARMATURE'\n"
"actor_subtype.linked_mesh = obj.name\n\n";
}
/* Link overlays */
for (const auto& overlay : info.overlays)
{
os << "overlay = actor_subtype.overlays.add()\n";
os.format("overlay.name = '%s'\n", overlay.first.c_str());
/* Link CMDL */
const typename PAKRouter::EntryType* cmdlE =
pakRouter.lookupEntry(overlay.second.first, nullptr, true, false);
if (cmdlE)
{
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(),
pakRouter.getBestEntryName(*cmdlE).data(), true);
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.objects.link(obj)\n"
"obj.parent = arm_obj\n"
"obj.parent_type = 'ARMATURE'\n"
"overlay.linked_mesh = obj.name\n\n";
}
}
}
/* Link attachments */
for (auto it = attRange.first; it != attRange.second; ++it)
{
os << "attachment = actor_data.attachments.add()\n";
os.format("attachment.name = '%s'\n", it->second.second.c_str());
auto cinfid = it->second.first.first;
auto cmdlid = it->second.first.second;
if (cinfid)
{
/* Build CINF if needed */
if (cinfsDone.find(cinfid) == cinfsDone.end())
{
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(cinfid, cinf);
cinf.sendCINFToBlender(os, cinfid);
if (cinfsDone.empty())
{
firstName = ANCSDNA::CINFType::GetCINFArmatureName(cinfid);
firstCinf = cinf;
}
cinfsDone.insert(cinfid);
}
else
os.format("arm_obj = bpy.data.objects['CINF_%s']\n", cinfid.toString().c_str());
os << "attachment.linked_armature = arm_obj.name\n";
}
/* Link CMDL */
const typename PAKRouter::EntryType* cmdlE =
pakRouter.lookupEntry(cmdlid, nullptr, true, false);
if (cmdlE)
{
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(),
pakRouter.getBestEntryName(*cmdlE).data(), true);
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.objects.link(obj)\n"
"obj.parent = arm_obj\n"
"obj.parent_type = 'ARMATURE'\n"
"attachment.linked_mesh = obj.name\n\n";
}
}
} }
}
{ conn.saveBlend();
hecl::blender::DataStream ds = conn.beginData(); return true;
std::unordered_map<std::string,
hecl::blender::Matrix3f> matrices = ds.getBoneMatrices(firstName);
ds.close();
DNAANIM::RigInverter<typename ANCSDNA::CINFType> inverter(firstCinf, matrices);
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os << "import bpy\n"
"actor_data = bpy.context.scene.hecl_sact_data\n";
/* Get animation primitives */
std::map<atUint32, AnimationResInfo<typename PAKRouter::IDType>> animResInfo;
ancs.getAnimationResInfo(&pakRouter, animResInfo);
for (const auto& id : animResInfo)
{
typename ANCSDNA::ANIMType anim;
if (pakRouter.lookupAndReadDNA(id.second.animId, anim, true))
{
os.format("act = bpy.data.actions.new('%s')\n"
"act.use_fake_user = True\n", id.second.name.c_str());
anim.sendANIMToBlender(os, inverter, id.second.additive);
}
os.format("actor_action = actor_data.actions.add()\n"
"actor_action.name = '%s'\n", id.second.name.c_str());
/* Extract EVNT if present */
anim.extractEVNT(id.second, outPath, pakRouter, force);
}
}
conn.saveBlend();
return true;
} }
template bool ReadANCSToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::ANCS, DNAMP1::MaterialSet, DNACMDL::SurfaceHeader_1, 2> template bool
(hecl::blender::Connection& conn, ReadANCSToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::ANCS, DNAMP1::MaterialSet, DNACMDL::SurfaceHeader_1, 2>(
const DNAMP1::ANCS& ancs, hecl::blender::Connection& conn, const DNAMP1::ANCS& ancs, const hecl::ProjectPath& outPath,
const hecl::ProjectPath& outPath, PAKRouter<DNAMP1::PAKBridge>& pakRouter, const typename PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
PAKRouter<DNAMP1::PAKBridge>& pakRouter, const SpecBase& dataspec, std::function<void(const hecl::SystemChar*)> fileChanged, bool force);
const typename PAKRouter<DNAMP1::PAKBridge>::EntryType& entry, template bool
const SpecBase& dataspec, ReadANCSToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::ANCS, DNAMP2::MaterialSet, DNACMDL::SurfaceHeader_2, 4>(
std::function<void(const hecl::SystemChar*)> fileChanged, hecl::blender::Connection& conn, const DNAMP2::ANCS& ancs, const hecl::ProjectPath& outPath,
bool force); PAKRouter<DNAMP2::PAKBridge>& pakRouter, const typename PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
template bool ReadANCSToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::ANCS, DNAMP2::MaterialSet, DNACMDL::SurfaceHeader_2, 4> const SpecBase& dataspec, std::function<void(const hecl::SystemChar*)> fileChanged, bool force);
(hecl::blender::Connection& conn, template bool
const DNAMP2::ANCS& ancs, ReadANCSToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::CHAR, DNAMP3::MaterialSet, DNACMDL::SurfaceHeader_3, 4>(
const hecl::ProjectPath& outPath, hecl::blender::Connection& conn, const DNAMP3::CHAR& ancs, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP2::PAKBridge>& pakRouter, PAKRouter<DNAMP3::PAKBridge>& pakRouter, const typename PAKRouter<DNAMP3::PAKBridge>::EntryType& entry,
const typename PAKRouter<DNAMP2::PAKBridge>::EntryType& entry, const SpecBase& dataspec, std::function<void(const hecl::SystemChar*)> fileChanged, bool force);
const SpecBase& dataspec,
std::function<void(const hecl::SystemChar*)> fileChanged,
bool force);
template bool ReadANCSToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::CHAR, DNAMP3::MaterialSet, DNACMDL::SurfaceHeader_3, 4>
(hecl::blender::Connection& conn,
const DNAMP3::CHAR& ancs,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP3::PAKBridge>& pakRouter,
const typename PAKRouter<DNAMP3::PAKBridge>::EntryType& entry,
const SpecBase& dataspec,
std::function<void(const hecl::SystemChar*)> fileChanged,
bool force);
} } // namespace DataSpec::DNAANCS

View File

@ -5,41 +5,32 @@
#include "CMDL.hpp" #include "CMDL.hpp"
#include "RigInverter.hpp" #include "RigInverter.hpp"
namespace DataSpec::DNAANCS namespace DataSpec::DNAANCS {
{
using Actor = hecl::blender::Actor; using Actor = hecl::blender::Actor;
using Armature = hecl::blender::Armature; using Armature = hecl::blender::Armature;
using Action = hecl::blender::Action; using Action = hecl::blender::Action;
template <typename IDTYPE> template <typename IDTYPE>
struct CharacterResInfo struct CharacterResInfo {
{ std::string name;
std::string name; IDTYPE cmdl;
IDTYPE cmdl; IDTYPE cskr;
IDTYPE cskr; IDTYPE cinf;
IDTYPE cinf; std::vector<std::pair<std::string, std::pair<IDTYPE, IDTYPE>>> overlays;
std::vector<std::pair<std::string, std::pair<IDTYPE, IDTYPE>>> overlays;
}; };
template <typename IDTYPE> template <typename IDTYPE>
struct AnimationResInfo struct AnimationResInfo {
{ std::string name;
std::string name; IDTYPE animId;
IDTYPE animId; IDTYPE evntId;
IDTYPE evntId; bool additive;
bool additive;
}; };
template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion> template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion>
bool ReadANCSToBlender(hecl::blender::Connection& conn, bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, const hecl::ProjectPath& outPath,
const ANCSDNA& ancs, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged, bool force = false);
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
const SpecBase& dataspec,
std::function<void(const hecl::SystemChar*)> fileChanged,
bool force=false);
}
} // namespace DataSpec::DNAANCS

View File

@ -3,529 +3,439 @@
#define DUMP_KEYS 0 #define DUMP_KEYS 0
namespace DataSpec::DNAANIM namespace DataSpec::DNAANIM {
{
size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels) size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels) {
{ size_t bitsPerKeyFrame = 0;
size_t bitsPerKeyFrame = 0; for (const Channel& chan : channels) {
for (const Channel& chan : channels) switch (chan.type) {
{ case Channel::Type::Rotation:
switch (chan.type) bitsPerKeyFrame += 1;
{ case Channel::Type::Translation:
case Channel::Type::Rotation: case Channel::Type::Scale:
bitsPerKeyFrame += 1; bitsPerKeyFrame += chan.q[0];
case Channel::Type::Translation: bitsPerKeyFrame += chan.q[1];
case Channel::Type::Scale: bitsPerKeyFrame += chan.q[2];
bitsPerKeyFrame += chan.q[0]; break;
bitsPerKeyFrame += chan.q[1]; case Channel::Type::KfHead:
bitsPerKeyFrame += chan.q[2]; bitsPerKeyFrame += 1;
break; break;
case Channel::Type::KfHead: case Channel::Type::RotationMP3:
bitsPerKeyFrame += 1; bitsPerKeyFrame += chan.q[0];
break; bitsPerKeyFrame += chan.q[1];
case Channel::Type::RotationMP3: bitsPerKeyFrame += chan.q[2];
bitsPerKeyFrame += chan.q[0]; bitsPerKeyFrame += chan.q[3];
bitsPerKeyFrame += chan.q[1]; break;
bitsPerKeyFrame += chan.q[2]; default:
bitsPerKeyFrame += chan.q[3]; break;
break;
default: break;
}
} }
return (bitsPerKeyFrame * keyFrameCount + 31) / 32 * 4; }
return (bitsPerKeyFrame * keyFrameCount + 31) / 32 * 4;
} }
static inline QuantizedRot QuantizeRotation(const Value& quat, atUint32 div) static inline QuantizedRot QuantizeRotation(const Value& quat, atUint32 div) {
{ float q = M_PIF / 2.0f / float(div);
float q = M_PIF / 2.0f / float(div); zeus::simd_floats f(quat.simd);
zeus::simd_floats f(quat.simd); return {{
return atInt32(std::asin(f[1]) / q),
{ atInt32(std::asin(f[2]) / q),
{ atInt32(std::asin(f[3]) / q),
atInt32(std::asin(f[1]) / q), },
atInt32(std::asin(f[2]) / q), (f[0] < 0.f)};
atInt32(std::asin(f[3]) / q),
},
(f[0] < 0.f)
};
} }
static inline Value DequantizeRotation(const QuantizedRot& v, atUint32 div) static inline Value DequantizeRotation(const QuantizedRot& v, atUint32 div) {
{ float q = M_PIF / 2.0f / float(div);
float q = M_PIF / 2.0f / float(div); athena::simd_floats f = {
athena::simd_floats f = { 0.0f,
0.0f, std::sin(v.v[0] * q),
std::sin(v.v[0] * q), std::sin(v.v[1] * q),
std::sin(v.v[1] * q), std::sin(v.v[2] * q),
std::sin(v.v[2] * q), };
}; f[0] = std::sqrt(std::max((1.0f - (f[1] * f[1] + f[2] * f[2] + f[3] * f[3])), 0.0f));
f[0] = std::sqrt(std::max((1.0f - f[0] = v.w ? -f[0] : f[0];
(f[1] * f[1] + Value retval;
f[2] * f[2] + retval.simd.copy_from(f);
f[3] * f[3])), 0.0f)); return retval;
f[0] = v.w ? -f[0] : f[0];
Value retval;
retval.simd.copy_from(f);
return retval;
} }
static inline Value DequantizeRotation_3(const QuantizedRot& v, atUint32 div) static inline Value DequantizeRotation_3(const QuantizedRot& v, atUint32 div) {
{ float q = 1.0f / float(div);
float q = 1.0f / float(div); athena::simd_floats f = {
athena::simd_floats f = { 0.0f,
0.0f, v.v[0] * q,
v.v[0] * q, v.v[1] * q,
v.v[1] * q, v.v[2] * q,
v.v[2] * q, };
}; f[0] = std::sqrt(std::max((1.0f - (f[1] * f[1] + f[2] * f[2] + f[3] * f[3])), 0.0f));
f[0] = std::sqrt(std::max((1.0f - f[0] = v.w ? -f[0] : f[0];
(f[1] * f[1] + Value retval;
f[2] * f[2] + retval.simd.copy_from(f);
f[3] * f[3])), 0.0f)); return retval;
f[0] = v.w ? -f[0] : f[0];
Value retval;
retval.simd.copy_from(f);
return retval;
} }
bool BitstreamReader::dequantizeBit(const atUint8* data) bool BitstreamReader::dequantizeBit(const atUint8* data) {
{ atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 byteCur = (m_bitCur / 32) * 4; atUint32 bitRem = m_bitCur % 32;
atUint32 bitRem = m_bitCur % 32;
/* Fill 32 bit buffer with region containing bits */ /* Fill 32 bit buffer with region containing bits */
/* Make them least significant */ /* Make them least significant */
atUint32 tempBuf = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem; atUint32 tempBuf = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem;
/* That's it */ /* That's it */
m_bitCur += 1; m_bitCur += 1;
return tempBuf & 0x1; return tempBuf & 0x1;
} }
atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 q) atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 q) {
{ atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 byteCur = (m_bitCur / 32) * 4; atUint32 bitRem = m_bitCur % 32;
atUint32 bitRem = m_bitCur % 32;
/* Fill 32 bit buffer with region containing bits */ /* Fill 32 bit buffer with region containing bits */
/* Make them least significant */ /* Make them least significant */
atUint32 tempBuf = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem; atUint32 tempBuf = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem;
/* If this shift underflows the value, buffer the next 32 bits */ /* If this shift underflows the value, buffer the next 32 bits */
/* And tack onto shifted buffer */ /* And tack onto shifted buffer */
if ((bitRem + q) > 32) if ((bitRem + q) > 32) {
{ atUint32 tempBuf2 = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur + 4));
atUint32 tempBuf2 = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur + 4)); tempBuf |= (tempBuf2 << (32 - bitRem));
tempBuf |= (tempBuf2 << (32 - bitRem)); }
/* Mask it */
atUint32 mask = (1 << q) - 1;
tempBuf &= mask;
/* Sign extend */
atUint32 sign = (tempBuf >> (q - 1)) & 0x1;
if (sign)
tempBuf |= ~0u << q;
/* Return delta value */
m_bitCur += q;
return atInt32(tempBuf);
}
std::vector<std::vector<Value>> BitstreamReader::read(const atUint8* data, size_t keyFrameCount,
const std::vector<Channel>& channels, atUint32 rotDiv,
float transMult, float scaleMult) {
m_bitCur = 0;
std::vector<std::vector<Value>> chanKeys;
std::vector<QuantizedValue> chanAccum;
chanKeys.reserve(channels.size());
chanAccum.reserve(channels.size());
for (const Channel& chan : channels) {
chanAccum.push_back(chan.i);
chanKeys.emplace_back();
std::vector<Value>& keys = chanKeys.back();
keys.reserve(keyFrameCount);
switch (chan.type) {
case Channel::Type::Rotation: {
QuantizedRot qr = {{chan.i[0], chan.i[1], chan.i[2]}, false};
keys.emplace_back(DequantizeRotation(qr, rotDiv));
break;
} }
case Channel::Type::Translation: {
/* Mask it */ keys.push_back({chan.i[0] * transMult, chan.i[1] * transMult, chan.i[2] * transMult});
atUint32 mask = (1 << q) - 1; break;
tempBuf &= mask;
/* Sign extend */
atUint32 sign = (tempBuf >> (q - 1)) & 0x1;
if (sign)
tempBuf |= ~0u << q;
/* Return delta value */
m_bitCur += q;
return atInt32(tempBuf);
}
std::vector<std::vector<Value>>
BitstreamReader::read(const atUint8* data,
size_t keyFrameCount,
const std::vector<Channel>& channels,
atUint32 rotDiv,
float transMult,
float scaleMult)
{
m_bitCur = 0;
std::vector<std::vector<Value>> chanKeys;
std::vector<QuantizedValue> chanAccum;
chanKeys.reserve(channels.size());
chanAccum.reserve(channels.size());
for (const Channel& chan : channels)
{
chanAccum.push_back(chan.i);
chanKeys.emplace_back();
std::vector<Value>& keys = chanKeys.back();
keys.reserve(keyFrameCount);
switch (chan.type)
{
case Channel::Type::Rotation:
{
QuantizedRot qr = {{chan.i[0], chan.i[1], chan.i[2]}, false};
keys.emplace_back(DequantizeRotation(qr, rotDiv));
break;
}
case Channel::Type::Translation:
{
keys.push_back({chan.i[0] * transMult, chan.i[1] * transMult, chan.i[2] * transMult});
break;
}
case Channel::Type::Scale:
{
keys.push_back({chan.i[0] * scaleMult, chan.i[1] * scaleMult, chan.i[2] * scaleMult});
break;
}
case Channel::Type::KfHead:
{
break;
}
case Channel::Type::RotationMP3:
{
QuantizedRot qr = {{chan.i[1], chan.i[2], chan.i[3]}, bool(chan.i[0] & 0x1)};
keys.emplace_back(DequantizeRotation_3(qr, rotDiv));
break;
}
default: break;
}
} }
case Channel::Type::Scale: {
for (size_t f=0 ; f<keyFrameCount ; ++f) keys.push_back({chan.i[0] * scaleMult, chan.i[1] * scaleMult, chan.i[2] * scaleMult});
{ break;
#if DUMP_KEYS
fprintf(stderr, "\nFRAME %" PRISize " %u %u\n", f, (m_bitCur / 32) * 4, m_bitCur % 32);
int lastId = -1;
#endif
auto kit = chanKeys.begin();
auto ait = chanAccum.begin();
for (const Channel& chan : channels)
{
#if DUMP_KEYS
if (chan.id != lastId)
{
lastId = chan.id;
fprintf(stderr, "\n");
}
#endif
QuantizedValue& p = *ait;
switch (chan.type)
{
case Channel::Type::Rotation:
{
bool wBit = dequantizeBit(data);
p[0] += dequantize(data, chan.q[0]);
p[1] += dequantize(data, chan.q[1]);
p[2] += dequantize(data, chan.q[2]);
QuantizedRot qr = {{p[0], p[1], p[2]}, wBit};
kit->emplace_back(DequantizeRotation(qr, rotDiv));
#if DUMP_KEYS
fprintf(stderr, "%d R: %d %d %d %d\t", chan.id, wBit, p[0], p[1], p[2]);
#endif
break;
}
case Channel::Type::Translation:
{
atInt32 val1 = dequantize(data, chan.q[0]);
p[0] += val1;
atInt32 val2 = dequantize(data, chan.q[1]);
p[1] += val2;
atInt32 val3 = dequantize(data, chan.q[2]);
p[2] += val3;
kit->push_back({p[0] * transMult, p[1] * transMult, p[2] * transMult});
#if DUMP_KEYS
fprintf(stderr, "%d T: %d %d %d\t", chan.id, p[0], p[1], p[2]);
#endif
break;
}
case Channel::Type::Scale:
{
p[0] += dequantize(data, chan.q[0]);
p[1] += dequantize(data, chan.q[1]);
p[2] += dequantize(data, chan.q[2]);
kit->push_back({p[0] * scaleMult, p[1] * scaleMult, p[2] * scaleMult});
#if DUMP_KEYS
fprintf(stderr, "%d S: %d %d %d\t", chan.id, p[0], p[1], p[2]);
#endif
break;
}
case Channel::Type::KfHead:
{
dequantizeBit(data);
break;
}
case Channel::Type::RotationMP3:
{
atInt32 val1 = dequantize(data, chan.q[0]);
p[0] += val1;
atInt32 val2 = dequantize(data, chan.q[1]);
p[1] += val2;
atInt32 val3 = dequantize(data, chan.q[2]);
p[2] += val3;
atInt32 val4 = dequantize(data, chan.q[3]);
p[3] += val4;
QuantizedRot qr = {{p[1], p[2], p[3]}, bool(p[0] & 0x1)};
kit->emplace_back(DequantizeRotation_3(qr, rotDiv));
break;
}
default: break;
}
++kit;
++ait;
}
#if DUMP_KEYS
fprintf(stderr, "\n");
#endif
} }
case Channel::Type::KfHead: {
return chanKeys; break;
}
void BitstreamWriter::quantizeBit(atUint8* data, bool val)
{
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
/* Fill 32 bit buffer with region containing bits */
/* Make them least significant */
*(atUint32*)(data + byteCur) =
hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (val << bitRem));
m_bitCur += 1;
}
void BitstreamWriter::quantize(atUint8* data, atUint8 q, atInt32 val)
{
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
atUint32 masked = val & ((1 << q) - 1);
/* Fill 32 bit buffer with region containing bits */
/* Make them least significant */
*(atUint32*)(data + byteCur) =
hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (masked << bitRem));
/* If this shift underflows the value, buffer the next 32 bits */
/* And tack onto shifted buffer */
if ((bitRem + q) > 32)
{
*(atUint32*)(data + byteCur + 4) =
hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur + 4)) | (masked >> (32 - bitRem)));
} }
case Channel::Type::RotationMP3: {
QuantizedRot qr = {{chan.i[1], chan.i[2], chan.i[3]}, bool(chan.i[0] & 0x1)};
keys.emplace_back(DequantizeRotation_3(qr, rotDiv));
break;
}
default:
break;
}
}
m_bitCur += q; for (size_t f = 0; f < keyFrameCount; ++f) {
} #if DUMP_KEYS
fprintf(stderr, "\nFRAME %" PRISize " %u %u\n", f, (m_bitCur / 32) * 4, m_bitCur % 32);
std::unique_ptr<atUint8[]> int lastId = -1;
BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys, #endif
size_t keyFrameCount, std::vector<Channel>& channels,
atUint32 quantRange,
atUint32& rotDivOut,
float& transMultOut,
float& scaleMultOut,
size_t& sizeOut)
{
m_bitCur = 0;
rotDivOut = quantRange; /* Normalized range of values */
float quantRangeF = float(quantRange);
/* Pre-pass to calculate translation multiplier */
float maxTransVal = 0.0f;
float maxScaleVal = 0.0f;
auto kit = chanKeys.begin(); auto kit = chanKeys.begin();
for (Channel& chan : channels) auto ait = chanAccum.begin();
{ for (const Channel& chan : channels) {
switch (chan.type) #if DUMP_KEYS
{ if (chan.id != lastId) {
case Channel::Type::Translation: lastId = chan.id;
{ fprintf(stderr, "\n");
for (auto it=kit->begin(); }
it != kit->end(); #endif
++it) QuantizedValue& p = *ait;
{ switch (chan.type) {
const Value* key = &*it; case Channel::Type::Rotation: {
zeus::simd_floats f(key->simd); bool wBit = dequantizeBit(data);
maxTransVal = std::max(maxTransVal, std::fabs(f[0])); p[0] += dequantize(data, chan.q[0]);
maxTransVal = std::max(maxTransVal, std::fabs(f[1])); p[1] += dequantize(data, chan.q[1]);
maxTransVal = std::max(maxTransVal, std::fabs(f[2])); p[2] += dequantize(data, chan.q[2]);
} QuantizedRot qr = {{p[0], p[1], p[2]}, wBit};
break; kit->emplace_back(DequantizeRotation(qr, rotDiv));
} #if DUMP_KEYS
case Channel::Type::Scale: fprintf(stderr, "%d R: %d %d %d %d\t", chan.id, wBit, p[0], p[1], p[2]);
{ #endif
for (auto it=kit->begin(); break;
it != kit->end(); }
++it) case Channel::Type::Translation: {
{ atInt32 val1 = dequantize(data, chan.q[0]);
const Value* key = &*it; p[0] += val1;
zeus::simd_floats f(key->simd); atInt32 val2 = dequantize(data, chan.q[1]);
maxScaleVal = std::max(maxScaleVal, std::fabs(f[0])); p[1] += val2;
maxScaleVal = std::max(maxScaleVal, std::fabs(f[1])); atInt32 val3 = dequantize(data, chan.q[2]);
maxScaleVal = std::max(maxScaleVal, std::fabs(f[2])); p[2] += val3;
} kit->push_back({p[0] * transMult, p[1] * transMult, p[2] * transMult});
break; #if DUMP_KEYS
} fprintf(stderr, "%d T: %d %d %d\t", chan.id, p[0], p[1], p[2]);
default: break; #endif
} break;
++kit; }
case Channel::Type::Scale: {
p[0] += dequantize(data, chan.q[0]);
p[1] += dequantize(data, chan.q[1]);
p[2] += dequantize(data, chan.q[2]);
kit->push_back({p[0] * scaleMult, p[1] * scaleMult, p[2] * scaleMult});
#if DUMP_KEYS
fprintf(stderr, "%d S: %d %d %d\t", chan.id, p[0], p[1], p[2]);
#endif
break;
}
case Channel::Type::KfHead: {
dequantizeBit(data);
break;
}
case Channel::Type::RotationMP3: {
atInt32 val1 = dequantize(data, chan.q[0]);
p[0] += val1;
atInt32 val2 = dequantize(data, chan.q[1]);
p[1] += val2;
atInt32 val3 = dequantize(data, chan.q[2]);
p[2] += val3;
atInt32 val4 = dequantize(data, chan.q[3]);
p[3] += val4;
QuantizedRot qr = {{p[1], p[2], p[3]}, bool(p[0] & 0x1)};
kit->emplace_back(DequantizeRotation_3(qr, rotDiv));
break;
}
default:
break;
}
++kit;
++ait;
} }
transMultOut = maxTransVal / quantRangeF; #if DUMP_KEYS
scaleMultOut = maxScaleVal / quantRangeF; fprintf(stderr, "\n");
#endif
}
/* Output channel inits */ return chanKeys;
std::vector<QuantizedValue> initVals;
initVals.reserve(channels.size());
kit = chanKeys.begin();
for (Channel& chan : channels)
{
chan.q[0] = 1;
chan.q[1] = 1;
chan.q[2] = 1;
switch (chan.type)
{
case Channel::Type::Rotation:
{
QuantizedRot qr = QuantizeRotation((*kit)[0], rotDivOut);
chan.i = qr.v;
initVals.push_back(chan.i);
break;
}
case Channel::Type::Translation:
{
zeus::simd_floats f((*kit)[0].simd);
chan.i = {atInt32(f[0] / transMultOut),
atInt32(f[1] / transMultOut),
atInt32(f[2] / transMultOut)};
initVals.push_back(chan.i);
break;
}
case Channel::Type::Scale:
{
zeus::simd_floats f((*kit)[0].simd);
chan.i = {atInt32(f[0] / scaleMultOut),
atInt32(f[1] / scaleMultOut),
atInt32(f[2] / scaleMultOut)};
initVals.push_back(chan.i);
break;
}
default: break;
}
++kit;
}
/* Pre-pass to analyze quantization factors for channels */
std::vector<QuantizedValue> lastVals = initVals;
kit = chanKeys.begin();
auto vit = lastVals.begin();
for (Channel& chan : channels)
{
QuantizedValue& last = *vit++;
switch (chan.type)
{
case Channel::Type::Rotation:
{
for (auto it=kit->begin() + 1;
it != kit->end();
++it)
{
QuantizedRot qrCur = QuantizeRotation(*it, rotDivOut);
chan.q[0] = std::max(chan.q[0], atUint8(qrCur.v.qFrom(last, 0)));
chan.q[1] = std::max(chan.q[1], atUint8(qrCur.v.qFrom(last, 1)));
chan.q[2] = std::max(chan.q[2], atUint8(qrCur.v.qFrom(last, 2)));
last = qrCur.v;
}
break;
}
case Channel::Type::Translation:
{
for (auto it=kit->begin() + 1;
it != kit->end();
++it)
{
zeus::simd_floats f(it->simd);
QuantizedValue cur = {atInt32(f[0] / transMultOut),
atInt32(f[1] / transMultOut),
atInt32(f[2] / transMultOut)};
chan.q[0] = std::max(chan.q[0], atUint8(cur.qFrom(last, 0)));
chan.q[1] = std::max(chan.q[1], atUint8(cur.qFrom(last, 1)));
chan.q[2] = std::max(chan.q[2], atUint8(cur.qFrom(last, 2)));
last = cur;
}
break;
}
case Channel::Type::Scale:
{
for (auto it=kit->begin() + 1;
it != kit->end();
++it)
{
zeus::simd_floats f(it->simd);
QuantizedValue cur = {atInt32(f[0] / scaleMultOut),
atInt32(f[1] / scaleMultOut),
atInt32(f[2] / scaleMultOut)};
chan.q[0] = std::max(chan.q[0], atUint8(cur.qFrom(last, 0)));
chan.q[1] = std::max(chan.q[1], atUint8(cur.qFrom(last, 1)));
chan.q[2] = std::max(chan.q[2], atUint8(cur.qFrom(last, 2)));
last = cur;
}
break;
}
default: break;
}
++kit;
}
/* Generate Bitstream */
sizeOut = ComputeBitstreamSize(keyFrameCount, channels);
std::unique_ptr<atUint8[]> newData(new atUint8[sizeOut]);
memset(newData.get(), 0, sizeOut);
lastVals = initVals;
for (size_t f=0 ; f<keyFrameCount ; ++f)
{
kit = chanKeys.begin();
vit = lastVals.begin();
for (const Channel& chan : channels)
{
const Value& val = (*kit++)[f+1];
QuantizedValue& last = *vit++;
switch (chan.type)
{
case Channel::Type::Rotation:
{
QuantizedRot qrCur = QuantizeRotation(val, rotDivOut);
quantizeBit(newData.get(), qrCur.w);
quantize(newData.get(), chan.q[0], qrCur.v[0] - last.v[0]);
quantize(newData.get(), chan.q[1], qrCur.v[1] - last.v[1]);
quantize(newData.get(), chan.q[2], qrCur.v[2] - last.v[2]);
last = qrCur.v;
break;
}
case Channel::Type::Translation:
{
zeus::simd_floats f(val.simd);
QuantizedValue cur = {atInt32(f[0] / transMultOut),
atInt32(f[1] / transMultOut),
atInt32(f[2] / transMultOut)};
quantize(newData.get(), chan.q[0], cur[0] - last[0]);
quantize(newData.get(), chan.q[1], cur[1] - last[1]);
quantize(newData.get(), chan.q[2], cur[2] - last[2]);
last = cur;
break;
}
case Channel::Type::Scale:
{
zeus::simd_floats f(val.simd);
QuantizedValue cur = {atInt32(f[0] / scaleMultOut),
atInt32(f[1] / scaleMultOut),
atInt32(f[2] / scaleMultOut)};
quantize(newData.get(), chan.q[0], cur[0] - last[0]);
quantize(newData.get(), chan.q[1], cur[1] - last[1]);
quantize(newData.get(), chan.q[2], cur[2] - last[2]);
last = cur;
break;
}
default: break;
}
}
}
return newData;
} }
void BitstreamWriter::quantizeBit(atUint8* data, bool val) {
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
/* Fill 32 bit buffer with region containing bits */
/* Make them least significant */
*(atUint32*)(data + byteCur) = hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (val << bitRem));
m_bitCur += 1;
} }
void BitstreamWriter::quantize(atUint8* data, atUint8 q, atInt32 val) {
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
atUint32 masked = val & ((1 << q) - 1);
/* Fill 32 bit buffer with region containing bits */
/* Make them least significant */
*(atUint32*)(data + byteCur) = hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (masked << bitRem));
/* If this shift underflows the value, buffer the next 32 bits */
/* And tack onto shifted buffer */
if ((bitRem + q) > 32) {
*(atUint32*)(data + byteCur + 4) =
hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur + 4)) | (masked >> (32 - bitRem)));
}
m_bitCur += q;
}
std::unique_ptr<atUint8[]> BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys, size_t keyFrameCount,
std::vector<Channel>& channels, atUint32 quantRange,
atUint32& rotDivOut, float& transMultOut, float& scaleMultOut,
size_t& sizeOut) {
m_bitCur = 0;
rotDivOut = quantRange; /* Normalized range of values */
float quantRangeF = float(quantRange);
/* Pre-pass to calculate translation multiplier */
float maxTransVal = 0.0f;
float maxScaleVal = 0.0f;
auto kit = chanKeys.begin();
for (Channel& chan : channels) {
switch (chan.type) {
case Channel::Type::Translation: {
for (auto it = kit->begin(); it != kit->end(); ++it) {
const Value* key = &*it;
zeus::simd_floats f(key->simd);
maxTransVal = std::max(maxTransVal, std::fabs(f[0]));
maxTransVal = std::max(maxTransVal, std::fabs(f[1]));
maxTransVal = std::max(maxTransVal, std::fabs(f[2]));
}
break;
}
case Channel::Type::Scale: {
for (auto it = kit->begin(); it != kit->end(); ++it) {
const Value* key = &*it;
zeus::simd_floats f(key->simd);
maxScaleVal = std::max(maxScaleVal, std::fabs(f[0]));
maxScaleVal = std::max(maxScaleVal, std::fabs(f[1]));
maxScaleVal = std::max(maxScaleVal, std::fabs(f[2]));
}
break;
}
default:
break;
}
++kit;
}
transMultOut = maxTransVal / quantRangeF;
scaleMultOut = maxScaleVal / quantRangeF;
/* Output channel inits */
std::vector<QuantizedValue> initVals;
initVals.reserve(channels.size());
kit = chanKeys.begin();
for (Channel& chan : channels) {
chan.q[0] = 1;
chan.q[1] = 1;
chan.q[2] = 1;
switch (chan.type) {
case Channel::Type::Rotation: {
QuantizedRot qr = QuantizeRotation((*kit)[0], rotDivOut);
chan.i = qr.v;
initVals.push_back(chan.i);
break;
}
case Channel::Type::Translation: {
zeus::simd_floats f((*kit)[0].simd);
chan.i = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)};
initVals.push_back(chan.i);
break;
}
case Channel::Type::Scale: {
zeus::simd_floats f((*kit)[0].simd);
chan.i = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)};
initVals.push_back(chan.i);
break;
}
default:
break;
}
++kit;
}
/* Pre-pass to analyze quantization factors for channels */
std::vector<QuantizedValue> lastVals = initVals;
kit = chanKeys.begin();
auto vit = lastVals.begin();
for (Channel& chan : channels) {
QuantizedValue& last = *vit++;
switch (chan.type) {
case Channel::Type::Rotation: {
for (auto it = kit->begin() + 1; it != kit->end(); ++it) {
QuantizedRot qrCur = QuantizeRotation(*it, rotDivOut);
chan.q[0] = std::max(chan.q[0], atUint8(qrCur.v.qFrom(last, 0)));
chan.q[1] = std::max(chan.q[1], atUint8(qrCur.v.qFrom(last, 1)));
chan.q[2] = std::max(chan.q[2], atUint8(qrCur.v.qFrom(last, 2)));
last = qrCur.v;
}
break;
}
case Channel::Type::Translation: {
for (auto it = kit->begin() + 1; it != kit->end(); ++it) {
zeus::simd_floats f(it->simd);
QuantizedValue cur = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)};
chan.q[0] = std::max(chan.q[0], atUint8(cur.qFrom(last, 0)));
chan.q[1] = std::max(chan.q[1], atUint8(cur.qFrom(last, 1)));
chan.q[2] = std::max(chan.q[2], atUint8(cur.qFrom(last, 2)));
last = cur;
}
break;
}
case Channel::Type::Scale: {
for (auto it = kit->begin() + 1; it != kit->end(); ++it) {
zeus::simd_floats f(it->simd);
QuantizedValue cur = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)};
chan.q[0] = std::max(chan.q[0], atUint8(cur.qFrom(last, 0)));
chan.q[1] = std::max(chan.q[1], atUint8(cur.qFrom(last, 1)));
chan.q[2] = std::max(chan.q[2], atUint8(cur.qFrom(last, 2)));
last = cur;
}
break;
}
default:
break;
}
++kit;
}
/* Generate Bitstream */
sizeOut = ComputeBitstreamSize(keyFrameCount, channels);
std::unique_ptr<atUint8[]> newData(new atUint8[sizeOut]);
memset(newData.get(), 0, sizeOut);
lastVals = initVals;
for (size_t f = 0; f < keyFrameCount; ++f) {
kit = chanKeys.begin();
vit = lastVals.begin();
for (const Channel& chan : channels) {
const Value& val = (*kit++)[f + 1];
QuantizedValue& last = *vit++;
switch (chan.type) {
case Channel::Type::Rotation: {
QuantizedRot qrCur = QuantizeRotation(val, rotDivOut);
quantizeBit(newData.get(), qrCur.w);
quantize(newData.get(), chan.q[0], qrCur.v[0] - last.v[0]);
quantize(newData.get(), chan.q[1], qrCur.v[1] - last.v[1]);
quantize(newData.get(), chan.q[2], qrCur.v[2] - last.v[2]);
last = qrCur.v;
break;
}
case Channel::Type::Translation: {
zeus::simd_floats f(val.simd);
QuantizedValue cur = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)};
quantize(newData.get(), chan.q[0], cur[0] - last[0]);
quantize(newData.get(), chan.q[1], cur[1] - last[1]);
quantize(newData.get(), chan.q[2], cur[2] - last[2]);
last = cur;
break;
}
case Channel::Type::Scale: {
zeus::simd_floats f(val.simd);
QuantizedValue cur = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)};
quantize(newData.get(), chan.q[0], cur[0] - last[0]);
quantize(newData.get(), chan.q[1], cur[1] - last[1]);
quantize(newData.get(), chan.q[2], cur[2] - last[2]);
last = cur;
break;
}
default:
break;
}
}
}
return newData;
}
} // namespace DataSpec::DNAANIM

View File

@ -3,87 +3,61 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
#include <cmath> #include <cmath>
namespace DataSpec::DNAANIM namespace DataSpec::DNAANIM {
{
struct Value struct Value {
{ athena::simd<float> simd;
athena::simd<float> simd; Value() = default;
Value() = default; Value(const athena::simd<float>& s) : simd(s) {}
Value(const athena::simd<float>& s) : simd(s) {} Value(const atVec3f& v) : simd(v.simd) {}
Value(const atVec3f& v) : simd(v.simd) {} Value(const atVec4f& v) : simd(v.simd) {}
Value(const atVec4f& v) : simd(v.simd) {} Value(float x, float y, float z) : simd(x, y, z, 0.f) {}
Value(float x, float y, float z) : simd(x, y, z, 0.f) {} Value(float w, float x, float y, float z) : simd(w, x, y, z) {}
Value(float w, float x, float y, float z) : simd(w, x, y, z) {}
}; };
struct QuantizedValue struct QuantizedValue {
{ atInt32 v[4];
atInt32 v[4]; atInt32& operator[](size_t idx) { return v[idx]; }
atInt32& operator[] (size_t idx) atInt32 operator[](size_t idx) const { return v[idx]; }
{return v[idx];}
atInt32 operator[] (size_t idx) const
{return v[idx];}
int qFrom(const QuantizedValue& other, size_t idx) const int qFrom(const QuantizedValue& other, size_t idx) const {
{ atInt32 delta = std::abs(v[idx] - other.v[idx]);
atInt32 delta = std::abs(v[idx] - other.v[idx]); if (delta == 0)
if (delta == 0) return 1;
return 1; return int(std::ceil(std::log2(delta))) + 1;
return int(std::ceil(std::log2(delta))) + 1; }
}
}; };
struct QuantizedRot struct QuantizedRot {
{ QuantizedValue v;
QuantizedValue v; bool w;
bool w;
}; };
struct Channel struct Channel {
{ enum class Type { Rotation, Translation, Scale, KfHead, RotationMP3 } type;
enum class Type atInt32 id = -1;
{ QuantizedValue i = {};
Rotation, atUint8 q[4] = {};
Translation,
Scale,
KfHead,
RotationMP3
} type;
atInt32 id = -1;
QuantizedValue i = {};
atUint8 q[4] = {};
}; };
size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels); size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels);
class BitstreamReader class BitstreamReader {
{ size_t m_bitCur;
size_t m_bitCur; atInt32 dequantize(const atUint8* data, atUint8 q);
atInt32 dequantize(const atUint8* data, atUint8 q); bool dequantizeBit(const atUint8* data);
bool dequantizeBit(const atUint8* data);
public: public:
std::vector<std::vector<Value>> std::vector<std::vector<Value>> read(const atUint8* data, size_t keyFrameCount, const std::vector<Channel>& channels,
read(const atUint8* data, atUint32 rotDiv, float transMult, float scaleMult);
size_t keyFrameCount,
const std::vector<Channel>& channels,
atUint32 rotDiv,
float transMult,
float scaleMult);
}; };
class BitstreamWriter class BitstreamWriter {
{ size_t m_bitCur;
size_t m_bitCur; void quantize(atUint8* data, atUint8 q, atInt32 val);
void quantize(atUint8* data, atUint8 q, atInt32 val); void quantizeBit(atUint8* data, bool val);
void quantizeBit(atUint8* data, bool val);
public: public:
std::unique_ptr<atUint8[]> std::unique_ptr<atUint8[]> write(const std::vector<std::vector<Value>>& chanKeys, size_t keyFrameCount,
write(const std::vector<std::vector<Value>>& chanKeys, std::vector<Channel>& channels, atUint32 quantRange, atUint32& rotDivOut,
size_t keyFrameCount, std::vector<Channel>& channels, float& transMultOut, float& scaleMultOut, size_t& sizeOut);
atUint32 quantRange,
atUint32& rotDivOut,
float& transMultOut,
float& scaleMultOut,
size_t& sizeOut);
}; };
} } // namespace DataSpec::DNAANIM

View File

@ -2,8 +2,7 @@
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
#include "../DNAMP1/PATH.hpp" #include "../DNAMP1/PATH.hpp"
namespace DataSpec namespace DataSpec {
{
logvisor::Module Log("AROTBuilder"); logvisor::Module Log("AROTBuilder");
#define AROT_MAX_LEVEL 10 #define AROT_MAX_LEVEL 10
@ -12,505 +11,419 @@ logvisor::Module Log("AROTBuilder");
#define COLLISION_MIN_NODE_TRIANGLES 8 #define COLLISION_MIN_NODE_TRIANGLES 8
#define PATH_MIN_NODE_REGIONS 16 #define PATH_MIN_NODE_REGIONS 16
static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i) static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i) {
{ zeus::CAABox pos, neg;
zeus::CAABox pos, neg; aabb.splitZ(neg, pos);
aabb.splitZ(neg, pos); if (i & 4) {
if (i & 4) zeus::CAABox(pos).splitY(neg, pos);
{ if (i & 2) {
zeus::CAABox(pos).splitY(neg, pos); zeus::CAABox(pos).splitX(neg, pos);
if (i & 2) if (i & 1)
{ return pos;
zeus::CAABox(pos).splitX(neg, pos); else
if (i & 1) return neg;
return pos; } else {
else zeus::CAABox(neg).splitX(neg, pos);
return neg; if (i & 1)
} return pos;
else else
{ return neg;
zeus::CAABox(neg).splitX(neg, pos);
if (i & 1)
return pos;
else
return neg;
}
} }
else } else {
{ zeus::CAABox(neg).splitY(neg, pos);
zeus::CAABox(neg).splitY(neg, pos); if (i & 2) {
if (i & 2) zeus::CAABox(pos).splitX(neg, pos);
{ if (i & 1)
zeus::CAABox(pos).splitX(neg, pos); return pos;
if (i & 1) else
return pos; return neg;
else } else {
return neg; zeus::CAABox(neg).splitX(neg, pos);
} if (i & 1)
else return pos;
{ else
zeus::CAABox(neg).splitX(neg, pos); return neg;
if (i & 1)
return pos;
else
return neg;
}
} }
}
} }
void AROTBuilder::Node::mergeSets(int a, int b) void AROTBuilder::Node::mergeSets(int a, int b) {
{ childNodes[a].childIndices.insert(childNodes[b].childIndices.cbegin(), childNodes[b].childIndices.cend());
childNodes[a].childIndices.insert(childNodes[b].childIndices.cbegin(), childNodes[b].childIndices.cend()); childNodes[b].childIndices = childNodes[a].childIndices;
childNodes[b].childIndices = childNodes[a].childIndices;
} }
bool AROTBuilder::Node::compareSets(int a, int b) const bool AROTBuilder::Node::compareSets(int a, int b) const {
{ return childNodes[a].childIndices != childNodes[b].childIndices;
return childNodes[a].childIndices != childNodes[b].childIndices;
} }
void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes, void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes,
const zeus::CAABox& curAABB, BspNodeType& typeOut) const zeus::CAABox& curAABB, BspNodeType& typeOut) {
{ /* Gather intersecting faces */
/* Gather intersecting faces */ for (int i = 0; i < triBoxes.size(); ++i)
for (int i=0 ; i<triBoxes.size() ; ++i) if (triBoxes[i].intersects(curAABB))
if (triBoxes[i].intersects(curAABB)) childIndices.insert(i);
childIndices.insert(i);
zeus::CVector3f extents = curAABB.extents(); zeus::CVector3f extents = curAABB.extents();
/* Return early if empty, triangle intersection below performance threshold, or at max level */ /* Return early if empty, triangle intersection below performance threshold, or at max level */
if (childIndices.empty()) if (childIndices.empty()) {
{ typeOut = BspNodeType::Invalid;
typeOut = BspNodeType::Invalid; return;
return; } else if (childIndices.size() < minChildren || level == AROT_MAX_LEVEL ||
} std::max(extents.x(), std::max(extents.y(), extents.z())) < AROT_MIN_SUBDIV) {
else if (childIndices.size() < minChildren || level == AROT_MAX_LEVEL || typeOut = BspNodeType::Leaf;
std::max(extents.x(), std::max(extents.y(), extents.z())) < AROT_MIN_SUBDIV) return;
{ }
typeOut = BspNodeType::Leaf;
return;
}
/* Subdivide */ /* Subdivide */
typeOut = BspNodeType::Branch; typeOut = BspNodeType::Branch;
childNodes.resize(8); childNodes.resize(8);
for (int i=0 ; i<8 ; ++i) for (int i = 0; i < 8; ++i) {
{ BspNodeType chType;
BspNodeType chType; childNodes[i].addChild(level + 1, minChildren, triBoxes, SplitAABB(curAABB, i), chType);
childNodes[i].addChild(level + 1, minChildren, triBoxes, SplitAABB(curAABB, i), chType); flags |= int(chType) << (i * 2);
flags |= int(chType) << (i * 2); }
}
/* Unsubdivide minimum axis dimensions */ /* Unsubdivide minimum axis dimensions */
if (extents.x() < AROT_MIN_SUBDIV) if (extents.x() < AROT_MIN_SUBDIV) {
{ mergeSets(0, 1);
mergeSets(0, 1); mergeSets(4, 5);
mergeSets(4, 5); mergeSets(2, 3);
mergeSets(2, 3); mergeSets(6, 7);
mergeSets(6, 7); }
} if (extents.y() < AROT_MIN_SUBDIV) {
if (extents.y() < AROT_MIN_SUBDIV) mergeSets(0, 2);
{ mergeSets(1, 3);
mergeSets(0, 2); mergeSets(4, 6);
mergeSets(1, 3); mergeSets(5, 7);
mergeSets(4, 6); }
mergeSets(5, 7); if (extents.z() < AROT_MIN_SUBDIV) {
} mergeSets(0, 4);
if (extents.z() < AROT_MIN_SUBDIV) mergeSets(1, 5);
{ mergeSets(2, 6);
mergeSets(0, 4); mergeSets(3, 7);
mergeSets(1, 5); }
mergeSets(2, 6);
mergeSets(3, 7);
}
/* Unsubdivide */ /* Unsubdivide */
compSubdivs = 0; compSubdivs = 0;
if (compareSets(0, 1) || if (compareSets(0, 1) || compareSets(4, 5) || compareSets(2, 3) || compareSets(6, 7))
compareSets(4, 5) || compSubdivs |= 0x1;
compareSets(2, 3) || if (compareSets(0, 2) || compareSets(1, 3) || compareSets(4, 6) || compareSets(5, 7))
compareSets(6, 7)) compSubdivs |= 0x2;
compSubdivs |= 0x1; if (compareSets(0, 4) || compareSets(1, 5) || compareSets(2, 6) || compareSets(3, 7))
if (compareSets(0, 2) || compSubdivs |= 0x4;
compareSets(1, 3) ||
compareSets(4, 6) ||
compareSets(5, 7))
compSubdivs |= 0x2;
if (compareSets(0, 4) ||
compareSets(1, 5) ||
compareSets(2, 6) ||
compareSets(3, 7))
compSubdivs |= 0x4;
if (!compSubdivs) if (!compSubdivs) {
{ typeOut = BspNodeType::Leaf;
typeOut = BspNodeType::Leaf; childNodes = std::vector<Node>();
childNodes = std::vector<Node>(); flags = 0;
flags = 0; }
}
} }
size_t AROTBuilder::BitmapPool::addIndices(const std::set<int>& indices) size_t AROTBuilder::BitmapPool::addIndices(const std::set<int>& indices) {
{ for (size_t i = 0; i < m_pool.size(); ++i)
for (size_t i=0 ; i<m_pool.size() ; ++i) if (m_pool[i] == indices)
if (m_pool[i] == indices) return i;
return i; m_pool.push_back(indices);
m_pool.push_back(indices); return m_pool.size() - 1;
return m_pool.size() - 1;
} }
static const uint32_t AROTChildCounts[] = { 0, 2, 2, 4, 2, 4, 4, 8 }; static const uint32_t AROTChildCounts[] = {0, 2, 2, 4, 2, 4, 4, 8};
void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff) void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff) {
{ sz += 1;
sz += 1; poolIdx = bmpPool.addIndices(childIndices);
poolIdx = bmpPool.addIndices(childIndices); if (poolIdx > 65535)
if (poolIdx > 65535) Log.report(logvisor::Fatal, "AROT bitmap exceeds 16-bit node addressing; area too complex");
Log.report(logvisor::Fatal, "AROT bitmap exceeds 16-bit node addressing; area too complex");
uint32_t childCount = AROTChildCounts[compSubdivs]; uint32_t childCount = AROTChildCounts[compSubdivs];
nodeOff = curOff; nodeOff = curOff;
nodeSz = childCount * 2 + 4; nodeSz = childCount * 2 + 4;
curOff += nodeSz; curOff += nodeSz;
if (childNodes.size()) if (childNodes.size()) {
{ for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) {
for (int k=0 ; k < 1 + ((compSubdivs & 0x4) != 0) ; ++k) for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) {
{ for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) {
for (int j=0 ; j < 1 + ((compSubdivs & 0x2) != 0) ; ++j) int idx = k * 4 + j * 2 + i;
{ childNodes[idx].nodeCount(sz, idxRefs, bmpPool, curOff);
for (int i=0 ; i < 1 + ((compSubdivs & 0x1) != 0) ; ++i)
{
int idx = k*4 + j*2 + i;
childNodes[idx].nodeCount(sz, idxRefs, bmpPool, curOff);
}
}
} }
idxRefs += childCount; }
} }
idxRefs += childCount;
}
} }
void AROTBuilder::Node::writeIndirectionTable(athena::io::MemoryWriter& w) void AROTBuilder::Node::writeIndirectionTable(athena::io::MemoryWriter& w) {
{ w.writeUint32Big(nodeOff);
w.writeUint32Big(nodeOff); if (childNodes.size()) {
if (childNodes.size()) for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) {
{ for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) {
for (int k=0 ; k < 1 + ((compSubdivs & 0x4) != 0) ; ++k) for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) {
{ int idx = k * 4 + j * 2 + i;
for (int j=0 ; j < 1 + ((compSubdivs & 0x2) != 0) ; ++j) childNodes[idx].writeIndirectionTable(w);
{
for (int i=0 ; i < 1 + ((compSubdivs & 0x1) != 0) ; ++i)
{
int idx = k*4 + j*2 + i;
childNodes[idx].writeIndirectionTable(w);
}
}
} }
}
} }
}
} }
void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx) void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx) {
{ w.writeUint16Big(poolIdx);
w.writeUint16Big(poolIdx); w.writeUint16Big(compSubdivs);
w.writeUint16Big(compSubdivs);
if (childNodes.size()) if (childNodes.size()) {
{ int curIdx = nodeIdx + 1;
int curIdx = nodeIdx + 1; if (curIdx > 65535)
if (curIdx > 65535) Log.report(logvisor::Fatal, "AROT node exceeds 16-bit node addressing; area too complex");
Log.report(logvisor::Fatal, "AROT node exceeds 16-bit node addressing; area too complex");
int childIndices[8]; int childIndices[8];
for (int k=0 ; k < 1 + ((compSubdivs & 0x4) != 0) ; ++k) for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) {
{ for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) {
for (int j=0 ; j < 1 + ((compSubdivs & 0x2) != 0) ; ++j) for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) {
{ int idx = k * 4 + j * 2 + i;
for (int i=0 ; i < 1 + ((compSubdivs & 0x1) != 0) ; ++i) w.writeUint16Big(curIdx);
{ childIndices[idx] = curIdx;
int idx = k*4 + j*2 + i; childNodes[idx].advanceIndex(curIdx);
w.writeUint16Big(curIdx);
childIndices[idx] = curIdx;
childNodes[idx].advanceIndex(curIdx);
}
}
}
for (int k=0 ; k < 1 + ((compSubdivs & 0x4) != 0) ; ++k)
{
for (int j=0 ; j < 1 + ((compSubdivs & 0x2) != 0) ; ++j)
{
for (int i=0 ; i < 1 + ((compSubdivs & 0x1) != 0) ; ++i)
{
int idx = k*4 + j*2 + i;
childNodes[idx].writeNodes(w, childIndices[idx]);
}
}
} }
}
} }
for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) {
for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) {
for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) {
int idx = k * 4 + j * 2 + i;
childNodes[idx].writeNodes(w, childIndices[idx]);
}
}
}
}
} }
void AROTBuilder::Node::advanceIndex(int& nodeIdx) void AROTBuilder::Node::advanceIndex(int& nodeIdx) {
{ ++nodeIdx;
++nodeIdx; if (childNodes.size()) {
if (childNodes.size()) for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) {
{ for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) {
for (int k=0 ; k < 1 + ((compSubdivs & 0x4) != 0) ; ++k) for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) {
{ int idx = k * 4 + j * 2 + i;
for (int j=0 ; j < 1 + ((compSubdivs & 0x2) != 0) ; ++j) childNodes[idx].advanceIndex(nodeIdx);
{
for (int i=0 ; i < 1 + ((compSubdivs & 0x1) != 0) ; ++i)
{
int idx = k*4 + j*2 + i;
childNodes[idx].advanceIndex(nodeIdx);
}
}
} }
}
} }
}
} }
void AROTBuilder::Node::colSize(size_t& totalSz) void AROTBuilder::Node::colSize(size_t& totalSz) {
{ if (childIndices.size()) {
if (childIndices.size()) nodeOff = totalSz;
{ if (childNodes.empty()) {
nodeOff = totalSz; totalSz += 26 + childIndices.size() * 2;
if (childNodes.empty()) } else {
{ totalSz += 36;
totalSz += 26 + childIndices.size() * 2; for (int i = 0; i < 8; ++i)
} childNodes[i].colSize(totalSz);
else
{
totalSz += 36;
for (int i=0 ; i<8 ; ++i)
childNodes[i].colSize(totalSz);
}
} }
}
} }
void AROTBuilder::Node::writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB) void AROTBuilder::Node::writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB) {
{ if (childIndices.size()) {
if (childIndices.size()) if (childNodes.empty()) {
{ float* aabbOut = reinterpret_cast<float*>(ptr);
if (childNodes.empty()) aabbOut[0] = hecl::SBig(curAABB.min[0]);
{ aabbOut[1] = hecl::SBig(curAABB.min[1]);
float* aabbOut = reinterpret_cast<float*>(ptr); aabbOut[2] = hecl::SBig(curAABB.min[2]);
aabbOut[0] = hecl::SBig(curAABB.min[0]); aabbOut[3] = hecl::SBig(curAABB.max[0]);
aabbOut[1] = hecl::SBig(curAABB.min[1]); aabbOut[4] = hecl::SBig(curAABB.max[1]);
aabbOut[2] = hecl::SBig(curAABB.min[2]); aabbOut[5] = hecl::SBig(curAABB.max[2]);
aabbOut[3] = hecl::SBig(curAABB.max[0]); athena::io::MemoryWriter w(ptr + 24, INT32_MAX);
aabbOut[4] = hecl::SBig(curAABB.max[1]); w.writeUint16Big(childIndices.size());
aabbOut[5] = hecl::SBig(curAABB.max[2]); for (int idx : childIndices)
athena::io::MemoryWriter w(ptr + 24, INT32_MAX); w.writeUint16Big(idx);
w.writeUint16Big(childIndices.size()); ptr += 26 + childIndices.size() * 2;
for (int idx : childIndices) } else {
w.writeUint16Big(idx); uint16_t* pflags = reinterpret_cast<uint16_t*>(ptr);
ptr += 26 + childIndices.size() * 2; uint32_t* offsets = reinterpret_cast<uint32_t*>(ptr + 4);
} memset(pflags, 0, sizeof(uint32_t) * 9);
else for (int i = 0; i < 8; ++i) {
{ const Node& chNode = childNodes[i];
uint16_t* pflags = reinterpret_cast<uint16_t*>(ptr); BspNodeType type = BspNodeType((flags >> (i * 2)) & 0x3);
uint32_t* offsets = reinterpret_cast<uint32_t*>(ptr + 4); if (type != BspNodeType::Invalid)
memset(pflags, 0, sizeof(uint32_t) * 9); offsets[i] = hecl::SBig(uint32_t(chNode.nodeOff - nodeOff - 36));
for (int i=0 ; i<8 ; ++i) }
{
const Node& chNode = childNodes[i];
BspNodeType type = BspNodeType((flags >> (i * 2)) & 0x3);
if (type != BspNodeType::Invalid)
offsets[i] = hecl::SBig(uint32_t(chNode.nodeOff - nodeOff - 36));
}
*pflags = hecl::SBig(flags); *pflags = hecl::SBig(flags);
ptr += 36; ptr += 36;
for (int i=0 ; i<8 ; ++i) for (int i = 0; i < 8; ++i)
childNodes[i].writeColNodes(ptr, SplitAABB(curAABB, i)); childNodes[i].writeColNodes(ptr, SplitAABB(curAABB, i));
}
} }
}
} }
void AROTBuilder::Node::pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount) void AROTBuilder::Node::pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount) {
{ ++nodeCount;
++nodeCount; if (childNodes.empty()) {
if (childNodes.empty()) lookupCount += childIndices.size();
{ } else {
lookupCount += childIndices.size(); for (int i = 0; i < 8; ++i)
} childNodes[i].pathCountNodesAndLookups(nodeCount, lookupCount);
else }
{
for (int i=0 ; i<8 ; ++i)
childNodes[i].pathCountNodesAndLookups(nodeCount, lookupCount);
}
} }
void AROTBuilder::Node::pathWrite(DNAMP1::PATH& path, const zeus::CAABox& curAABB) void AROTBuilder::Node::pathWrite(DNAMP1::PATH& path, const zeus::CAABox& curAABB) {
{ if (childNodes.empty()) {
if (childNodes.empty()) path.octree.emplace_back();
{ DNAMP1::PATH::OctreeNode& n = path.octree.back();
path.octree.emplace_back(); n.isLeaf = 1;
DNAMP1::PATH::OctreeNode& n = path.octree.back(); n.aabb[0] = curAABB.min;
n.isLeaf = 1; n.aabb[1] = curAABB.max;
n.aabb[0] = curAABB.min; n.centroid = curAABB.center();
n.aabb[1] = curAABB.max; for (int i = 0; i < 8; ++i)
n.centroid = curAABB.center(); n.children[i] = 0xffffffff;
for (int i=0 ; i<8 ; ++i) n.regionCount = childIndices.size();
n.children[i] = 0xffffffff; n.regionStart = path.octreeRegionLookup.size();
n.regionCount = childIndices.size(); for (int r : childIndices)
n.regionStart = path.octreeRegionLookup.size(); path.octreeRegionLookup.push_back(r);
for (int r : childIndices) } else {
path.octreeRegionLookup.push_back(r); atUint32 children[8];
for (int i = 0; i < 8; ++i) {
/* Head recursion (first node will be a leaf) */
children[i] = path.octree.size();
childNodes[i].pathWrite(path, SplitAABB(curAABB, i));
} }
else
{
atUint32 children[8];
for (int i=0 ; i<8 ; ++i)
{
/* Head recursion (first node will be a leaf) */
children[i] = path.octree.size();
childNodes[i].pathWrite(path, SplitAABB(curAABB, i));
}
path.octree.emplace_back(); path.octree.emplace_back();
DNAMP1::PATH::OctreeNode& n = path.octree.back(); DNAMP1::PATH::OctreeNode& n = path.octree.back();
n.isLeaf = 0; n.isLeaf = 0;
n.aabb[0] = curAABB.min; n.aabb[0] = curAABB.min;
n.aabb[1] = curAABB.max; n.aabb[1] = curAABB.max;
n.centroid = curAABB.center(); n.centroid = curAABB.center();
for (int i=0 ; i<8 ; ++i) for (int i = 0; i < 8; ++i)
n.children[i] = children[i]; n.children[i] = children[i];
n.regionCount = 0; n.regionCount = 0;
n.regionStart = 0; n.regionStart = 0;
} }
} }
void AROTBuilder::build(std::vector<std::vector<uint8_t>>& secs, const zeus::CAABox& fullAabb, void AROTBuilder::build(std::vector<std::vector<uint8_t>>& secs, const zeus::CAABox& fullAabb,
const std::vector<zeus::CAABox>& meshAabbs, const std::vector<DNACMDL::Mesh>& meshes) const std::vector<zeus::CAABox>& meshAabbs, const std::vector<DNACMDL::Mesh>& meshes) {
{ /* Recursively split */
/* Recursively split */ BspNodeType rootType;
BspNodeType rootType; rootNode.addChild(0, AROT_MIN_MODELS, meshAabbs, fullAabb, rootType);
rootNode.addChild(0, AROT_MIN_MODELS, meshAabbs, fullAabb, rootType);
/* Calculate indexing metrics */ /* Calculate indexing metrics */
size_t totalNodeCount = 0; size_t totalNodeCount = 0;
size_t idxRefCount = 0; size_t idxRefCount = 0;
size_t curOff = 0; size_t curOff = 0;
rootNode.nodeCount(totalNodeCount, idxRefCount, bmpPool, curOff); rootNode.nodeCount(totalNodeCount, idxRefCount, bmpPool, curOff);
size_t bmpWordCount = ROUND_UP_32(meshes.size()) / 32; size_t bmpWordCount = ROUND_UP_32(meshes.size()) / 32;
size_t arotSz = 64 + bmpWordCount * bmpPool.m_pool.size() * 4 + totalNodeCount * 8 + idxRefCount * 2; size_t arotSz = 64 + bmpWordCount * bmpPool.m_pool.size() * 4 + totalNodeCount * 8 + idxRefCount * 2;
/* Write header */ /* Write header */
secs.emplace_back(arotSz, 0); secs.emplace_back(arotSz, 0);
athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); athena::io::MemoryWriter w(secs.back().data(), secs.back().size());
w.writeUint32Big('AROT'); w.writeUint32Big('AROT');
w.writeUint32Big(1); w.writeUint32Big(1);
w.writeUint32Big(bmpPool.m_pool.size()); w.writeUint32Big(bmpPool.m_pool.size());
w.writeUint32Big(meshes.size()); w.writeUint32Big(meshes.size());
w.writeUint32Big(totalNodeCount); w.writeUint32Big(totalNodeCount);
w.writeVec3fBig(fullAabb.min); w.writeVec3fBig(fullAabb.min);
w.writeVec3fBig(fullAabb.max); w.writeVec3fBig(fullAabb.max);
w.seekAlign32(); w.seekAlign32();
/* Write bitmap */ /* Write bitmap */
std::vector<uint32_t> bmpWords; std::vector<uint32_t> bmpWords;
bmpWords.reserve(bmpWordCount); bmpWords.reserve(bmpWordCount);
for (const std::set<int>& bmp : bmpPool.m_pool) for (const std::set<int>& bmp : bmpPool.m_pool) {
{ bmpWords.clear();
bmpWords.clear(); bmpWords.resize(bmpWordCount);
bmpWords.resize(bmpWordCount);
auto bmpIt = bmp.cbegin(); auto bmpIt = bmp.cbegin();
if (bmpIt != bmp.cend()) if (bmpIt != bmp.cend()) {
{ int curIdx = 0;
int curIdx = 0; for (int w = 0; w < bmpWordCount; ++w) {
for (int w=0 ; w<bmpWordCount ; ++w) for (int b = 0; b < 32; ++b) {
{ if (*bmpIt == curIdx) {
for (int b=0 ; b<32 ; ++b) bmpWords[w] |= 1 << b;
{ ++bmpIt;
if (*bmpIt == curIdx) if (bmpIt == bmp.cend())
{ break;
bmpWords[w] |= 1 << b; }
++bmpIt; ++curIdx;
if (bmpIt == bmp.cend())
break;
}
++curIdx;
}
if (bmpIt == bmp.cend())
break;
}
} }
if (bmpIt == bmp.cend())
for (uint32_t word : bmpWords) break;
w.writeUint32Big(word); }
} }
/* Write the rest */ for (uint32_t word : bmpWords)
rootNode.writeIndirectionTable(w); w.writeUint32Big(word);
rootNode.writeNodes(w, 0); }
/* Write the rest */
rootNode.writeIndirectionTable(w);
rootNode.writeNodes(w, 0);
} }
std::pair<std::unique_ptr<uint8_t[]>, uint32_t> AROTBuilder::buildCol(const ColMesh& mesh, BspNodeType& rootOut) std::pair<std::unique_ptr<uint8_t[]>, uint32_t> AROTBuilder::buildCol(const ColMesh& mesh, BspNodeType& rootOut) {
{ /* Accumulate total AABB */
/* Accumulate total AABB */ zeus::CAABox fullAABB;
zeus::CAABox fullAABB; for (const auto& vert : mesh.verts)
for (const auto& vert : mesh.verts) fullAABB.accumulateBounds(zeus::CVector3f(vert));
fullAABB.accumulateBounds(zeus::CVector3f(vert));
/* Predetermine triangle AABBs */ /* Predetermine triangle AABBs */
std::vector<zeus::CAABox> triBoxes; std::vector<zeus::CAABox> triBoxes;
triBoxes.reserve(mesh.trianges.size()); triBoxes.reserve(mesh.trianges.size());
for (const ColMesh::Triangle& tri : mesh.trianges) for (const ColMesh::Triangle& tri : mesh.trianges) {
{ triBoxes.emplace_back();
triBoxes.emplace_back(); zeus::CAABox& aabb = triBoxes.back();
zeus::CAABox& aabb = triBoxes.back(); for (int e = 0; e < 3; ++e) {
for (int e=0 ; e<3 ; ++e) const ColMesh::Edge& edge = mesh.edges[tri.edges[e]];
{ for (int v = 0; v < 2; ++v) {
const ColMesh::Edge& edge = mesh.edges[tri.edges[e]]; const auto& vert = mesh.verts[edge.verts[v]];
for (int v=0 ; v<2 ; ++v) aabb.accumulateBounds(zeus::CVector3f(vert));
{ }
const auto& vert = mesh.verts[edge.verts[v]];
aabb.accumulateBounds(zeus::CVector3f(vert));
}
}
} }
}
/* Recursively split */ /* Recursively split */
rootNode.addChild(0, COLLISION_MIN_NODE_TRIANGLES, triBoxes, fullAABB, rootOut); rootNode.addChild(0, COLLISION_MIN_NODE_TRIANGLES, triBoxes, fullAABB, rootOut);
/* Calculate offsets and write out */ /* Calculate offsets and write out */
size_t totalSize = 0; size_t totalSize = 0;
rootNode.colSize(totalSize); rootNode.colSize(totalSize);
std::unique_ptr<uint8_t[]> ret(new uint8_t[totalSize]); std::unique_ptr<uint8_t[]> ret(new uint8_t[totalSize]);
uint8_t* ptr = ret.get(); uint8_t* ptr = ret.get();
rootNode.writeColNodes(ptr, fullAABB); rootNode.writeColNodes(ptr, fullAABB);
return {std::move(ret), totalSize}; return {std::move(ret), totalSize};
} }
void AROTBuilder::buildPath(DNAMP1::PATH& path) void AROTBuilder::buildPath(DNAMP1::PATH& path) {
{ /* Accumulate total AABB and gather region boxes */
/* Accumulate total AABB and gather region boxes */ std::vector<zeus::CAABox> regionBoxes;
std::vector<zeus::CAABox> regionBoxes; regionBoxes.reserve(path.regions.size());
regionBoxes.reserve(path.regions.size()); zeus::CAABox fullAABB;
zeus::CAABox fullAABB; for (const DNAMP1::PATH::Region& r : path.regions) {
for (const DNAMP1::PATH::Region& r : path.regions) regionBoxes.emplace_back(r.aabb[0], r.aabb[1]);
{ fullAABB.accumulateBounds(regionBoxes.back());
regionBoxes.emplace_back(r.aabb[0], r.aabb[1]); }
fullAABB.accumulateBounds(regionBoxes.back());
}
/* Recursively split */ /* Recursively split */
BspNodeType dontCare; BspNodeType dontCare;
rootNode.addChild(0, PATH_MIN_NODE_REGIONS, regionBoxes, fullAABB, dontCare); rootNode.addChild(0, PATH_MIN_NODE_REGIONS, regionBoxes, fullAABB, dontCare);
/* Write out */ /* Write out */
size_t nodeCount = 0; size_t nodeCount = 0;
size_t lookupCount = 0; size_t lookupCount = 0;
rootNode.pathCountNodesAndLookups(nodeCount, lookupCount); rootNode.pathCountNodesAndLookups(nodeCount, lookupCount);
path.octreeNodeCount = nodeCount; path.octreeNodeCount = nodeCount;
path.octree.reserve(nodeCount); path.octree.reserve(nodeCount);
path.octreeRegionLookupCount = lookupCount; path.octreeRegionLookupCount = lookupCount;
path.octreeRegionLookup.reserve(lookupCount); path.octreeRegionLookup.reserve(lookupCount);
rootNode.pathWrite(path, fullAABB); rootNode.pathWrite(path, fullAABB);
} }
} } // namespace DataSpec

View File

@ -6,55 +6,49 @@
#include "CMDL.hpp" #include "CMDL.hpp"
#include <set> #include <set>
namespace DataSpec namespace DataSpec {
{ namespace DNAMP1 {
namespace DNAMP1
{
struct PATH; struct PATH;
} }
struct AROTBuilder struct AROTBuilder {
{ using ColMesh = hecl::blender::ColMesh;
using ColMesh = hecl::blender::ColMesh;
struct BitmapPool struct BitmapPool {
{ std::vector<std::set<int>> m_pool;
std::vector<std::set<int>> m_pool; size_t addIndices(const std::set<int>& indices);
size_t addIndices(const std::set<int>& indices); } bmpPool;
} bmpPool;
struct Node struct Node {
{ std::vector<Node> childNodes;
std::vector<Node> childNodes; std::set<int> childIndices;
std::set<int> childIndices; size_t poolIdx = 0;
size_t poolIdx = 0; uint16_t flags = 0;
uint16_t flags = 0; uint16_t compSubdivs = 0;
uint16_t compSubdivs = 0;
size_t nodeOff = 0; size_t nodeOff = 0;
size_t nodeSz = 4; size_t nodeSz = 4;
void addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes, void addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes, const zeus::CAABox& curAABB,
const zeus::CAABox& curAABB, BspNodeType& typeOut); BspNodeType& typeOut);
void mergeSets(int a, int b); void mergeSets(int a, int b);
bool compareSets(int a, int b) const; bool compareSets(int a, int b) const;
void nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff); void nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff);
void writeIndirectionTable(athena::io::MemoryWriter& w); void writeIndirectionTable(athena::io::MemoryWriter& w);
void writeNodes(athena::io::MemoryWriter& w, int nodeIdx); void writeNodes(athena::io::MemoryWriter& w, int nodeIdx);
void advanceIndex(int& nodeIdx); void advanceIndex(int& nodeIdx);
void colSize(size_t& totalSz); void colSize(size_t& totalSz);
void writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB); void writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB);
void pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount); void pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount);
void pathWrite(DNAMP1::PATH& path, const zeus::CAABox& curAABB); void pathWrite(DNAMP1::PATH& path, const zeus::CAABox& curAABB);
} rootNode; } rootNode;
void build(std::vector<std::vector<uint8_t>>& secs, const zeus::CAABox& fullAabb, void build(std::vector<std::vector<uint8_t>>& secs, const zeus::CAABox& fullAabb,
const std::vector<zeus::CAABox>& meshAabbs, const std::vector<DNACMDL::Mesh>& meshes); const std::vector<zeus::CAABox>& meshAabbs, const std::vector<DNACMDL::Mesh>& meshes);
std::pair<std::unique_ptr<uint8_t[]>, uint32_t> buildCol(const ColMesh& mesh, BspNodeType& rootOut); std::pair<std::unique_ptr<uint8_t[]>, uint32_t> buildCol(const ColMesh& mesh, BspNodeType& rootOut);
void buildPath(DNAMP1::PATH& path); void buildPath(DNAMP1::PATH& path);
}; };
} } // namespace DataSpec

View File

@ -1,61 +1,55 @@
#include "ATBL.hpp" #include "ATBL.hpp"
namespace DataSpec::DNAAudio namespace DataSpec::DNAAudio {
{
bool ATBL::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) bool ATBL::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ uint32_t idxCount = rs.readUint32Big();
uint32_t idxCount = rs.readUint32Big(); athena::io::YAMLDocWriter w("ATBL");
athena::io::YAMLDocWriter w("ATBL"); for (uint32_t i = 0; i < idxCount; ++i) {
for (uint32_t i=0 ; i<idxCount ; ++i) uint16_t idx = rs.readUint16Big();
{ if (idx == 0xffff)
uint16_t idx = rs.readUint16Big(); continue;
if (idx == 0xffff) char iStr[16];
continue; snprintf(iStr, 16, "0x%04X", int(i));
char iStr[16]; w.writeUint16(iStr, idx);
snprintf(iStr, 16, "0x%04X", int(i)); }
w.writeUint16(iStr, idx);
}
athena::io::FileWriter fw(outPath.getAbsolutePath()); athena::io::FileWriter fw(outPath.getAbsolutePath());
w.finish(&fw); w.finish(&fw);
return true; return true;
} }
bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
{ athena::io::FileReader r(inPath.getAbsolutePath());
athena::io::FileReader r(inPath.getAbsolutePath()); if (r.hasError())
if (r.hasError()) return false;
return false;
athena::io::YAMLDocReader dr; athena::io::YAMLDocReader dr;
if (!dr.parse(&r)) if (!dr.parse(&r))
return false; return false;
unsigned long maxI = 0; unsigned long maxI = 0;
for (const auto& pair : dr.getRootNode()->m_mapChildren) for (const auto& pair : dr.getRootNode()->m_mapChildren) {
{ unsigned long i = strtoul(pair.first.c_str(), nullptr, 0);
unsigned long i = strtoul(pair.first.c_str(), nullptr, 0); maxI = std::max(maxI, i);
maxI = std::max(maxI, i); }
}
std::vector<uint16_t> vecOut; std::vector<uint16_t> vecOut;
vecOut.resize(maxI + 1, 0xffff); vecOut.resize(maxI + 1, 0xffff);
for (const auto& pair : dr.getRootNode()->m_mapChildren) for (const auto& pair : dr.getRootNode()->m_mapChildren) {
{ unsigned long i = strtoul(pair.first.c_str(), nullptr, 0);
unsigned long i = strtoul(pair.first.c_str(), nullptr, 0); vecOut[i] = hecl::SBig(uint16_t(strtoul(pair.second->m_scalarString.c_str(), nullptr, 0)));
vecOut[i] = hecl::SBig(uint16_t(strtoul(pair.second->m_scalarString.c_str(), nullptr, 0))); }
}
athena::io::FileWriter w(outPath.getAbsolutePath()); athena::io::FileWriter w(outPath.getAbsolutePath());
if (w.hasError()) if (w.hasError())
return false; return false;
w.writeUint32Big(uint32_t(vecOut.size())); w.writeUint32Big(uint32_t(vecOut.size()));
w.writeBytes(vecOut.data(), vecOut.size() * 2); w.writeBytes(vecOut.data(), vecOut.size() * 2);
return true; return true;
} }
} } // namespace DataSpec::DNAAudio

View File

@ -3,15 +3,12 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
#include "PAK.hpp" #include "PAK.hpp"
namespace DataSpec::DNAAudio namespace DataSpec::DNAAudio {
{
class ATBL class ATBL {
{
public: public:
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
}; };
} } // namespace DataSpec::DNAAudio

View File

@ -4,163 +4,156 @@
#include "zeus/CTransform.hpp" #include "zeus/CTransform.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec namespace DataSpec {
{
template<class BabeDeadLight> template <class BabeDeadLight>
void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLight& light, unsigned s, unsigned l) {
const BabeDeadLight& light, unsigned s, unsigned l) switch (light.lightType) {
{ case BabeDeadLight::LightType::LocalAmbient:
switch (light.lightType) case BabeDeadLight::LightType::LocalAmbient2:
{ os.format(
case BabeDeadLight::LightType::LocalAmbient: "bg_node.inputs[0].default_value = (%f,%f,%f,1.0)\n"
case BabeDeadLight::LightType::LocalAmbient2: "bg_node.inputs[1].default_value = %f\n",
os.format("bg_node.inputs[0].default_value = (%f,%f,%f,1.0)\n" light.color.simd[0], light.color.simd[1], light.color.simd[2], light.q / 8.f);
"bg_node.inputs[1].default_value = %f\n", return;
light.color.simd[0], light.color.simd[1], light.color.simd[2], case BabeDeadLight::LightType::Directional:
light.q / 8.f); os.format(
return; "lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SUN')\n"
case BabeDeadLight::LightType::Directional: "lamp.color = (%f,%f,%f)\n"
os.format("lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SUN')\n" "lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
"lamp.color = (%f,%f,%f)\n" "lamp_obj.rotation_mode = 'QUATERNION'\n"
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n" "lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector((%f,%f,%f)))\n"
"lamp_obj.rotation_mode = 'QUATERNION'\n" "lamp.shadow_method = '%s'\n"
"lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector((%f,%f,%f)))\n" "\n",
"lamp.shadow_method = '%s'\n" s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], light.direction.simd[0],
"\n", s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], light.direction.simd[1], light.direction.simd[2], light.castShadows ? "RAY_SHADOW" : "NOSHADOW");
light.direction.simd[0], light.direction.simd[1], light.direction.simd[2], return;
light.castShadows ? "RAY_SHADOW" : "NOSHADOW"); case BabeDeadLight::LightType::Custom:
return; os.format(
case BabeDeadLight::LightType::Custom: "lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'POINT')\n"
os.format("lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'POINT')\n" "lamp.color = (%f,%f,%f)\n"
"lamp.color = (%f,%f,%f)\n" "lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n" "lamp.shadow_soft_size = 1.0\n"
"lamp.shadow_soft_size = 1.0\n" "lamp.shadow_method = '%s'\n"
"lamp.shadow_method = '%s'\n" "\n",
"\n", s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2],
light.castShadows ? "RAY_SHADOW" : "NOSHADOW"); light.castShadows ? "RAY_SHADOW" : "NOSHADOW");
break; break;
case BabeDeadLight::LightType::Spot: case BabeDeadLight::LightType::Spot:
case BabeDeadLight::LightType::Spot2: case BabeDeadLight::LightType::Spot2:
os.format("lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SPOT')\n" os.format(
"lamp.color = (%f,%f,%f)\n" "lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SPOT')\n"
"lamp.spot_size = %.6g\n" "lamp.color = (%f,%f,%f)\n"
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n" "lamp.spot_size = %.6g\n"
"lamp_obj.rotation_mode = 'QUATERNION'\n" "lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
"lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector((%f,%f,%f)))\n" "lamp_obj.rotation_mode = 'QUATERNION'\n"
"lamp.shadow_soft_size = 0.5\n" "lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector((%f,%f,%f)))\n"
"lamp.shadow_method = '%s'\n" "lamp.shadow_soft_size = 0.5\n"
"\n", s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], "lamp.shadow_method = '%s'\n"
zeus::degToRad(light.spotCutoff), "\n",
light.direction.simd[0], light.direction.simd[1], light.direction.simd[2], s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], zeus::degToRad(light.spotCutoff),
light.castShadows ? "RAY_SHADOW" : "NOSHADOW"); light.direction.simd[0], light.direction.simd[1], light.direction.simd[2],
break; light.castShadows ? "RAY_SHADOW" : "NOSHADOW");
default: return; break;
} default:
return;
}
os.format("lamp.retro_layer = %u\n" os.format(
"lamp.retro_origtype = %u\n" "lamp.retro_layer = %u\n"
"lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n" "lamp.retro_origtype = %u\n"
"lamp.constant_coefficient = 0\n" "lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n"
"lamp.use_nodes = True\n" "lamp.constant_coefficient = 0\n"
"falloff_node = lamp.node_tree.nodes.new('ShaderNodeLightFalloff')\n" "lamp.use_nodes = True\n"
"lamp.energy = 0.0\n" "falloff_node = lamp.node_tree.nodes.new('ShaderNodeLightFalloff')\n"
"falloff_node.inputs[0].default_value = %f\n" "lamp.energy = 0.0\n"
"hue_sat_node = lamp.node_tree.nodes.new('ShaderNodeHueSaturation')\n" "falloff_node.inputs[0].default_value = %f\n"
"hue_sat_node.inputs[1].default_value = 1.25\n" "hue_sat_node = lamp.node_tree.nodes.new('ShaderNodeHueSaturation')\n"
"hue_sat_node.inputs[4].default_value = (%f,%f,%f,1.0)\n" "hue_sat_node.inputs[1].default_value = 1.25\n"
"lamp.node_tree.links.new(hue_sat_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[0])\n" "hue_sat_node.inputs[4].default_value = (%f,%f,%f,1.0)\n"
"lamp_obj.location = (%f,%f,%f)\n" "lamp.node_tree.links.new(hue_sat_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[0])\n"
"bpy.context.scene.objects.link(lamp_obj)\n" "lamp_obj.location = (%f,%f,%f)\n"
"\n", s, light.lightType, light.q / 8.f, "bpy.context.scene.objects.link(lamp_obj)\n"
light.color.simd[0], light.color.simd[1], light.color.simd[2], "\n",
light.position.simd[0], light.position.simd[1], light.position.simd[2]); s, light.lightType, light.q / 8.f, light.color.simd[0], light.color.simd[1], light.color.simd[2],
light.position.simd[0], light.position.simd[1], light.position.simd[2]);
switch (light.falloff) switch (light.falloff) {
{ case BabeDeadLight::Falloff::Constant:
case BabeDeadLight::Falloff::Constant: os << "falloff_node.inputs[0].default_value *= 150.0\n"
os << "falloff_node.inputs[0].default_value *= 150.0\n" "lamp.node_tree.links.new(falloff_node.outputs[2], lamp.node_tree.nodes['Emission'].inputs[1])\n";
"lamp.node_tree.links.new(falloff_node.outputs[2], lamp.node_tree.nodes['Emission'].inputs[1])\n"; if (light.q > FLT_EPSILON)
if (light.q > FLT_EPSILON) os.format("lamp.constant_coefficient = 2.0 / %f\n", light.q);
os.format("lamp.constant_coefficient = 2.0 / %f\n", light.q); break;
break; case BabeDeadLight::Falloff::Linear:
case BabeDeadLight::Falloff::Linear: os << "lamp.node_tree.links.new(falloff_node.outputs[1], lamp.node_tree.nodes['Emission'].inputs[1])\n";
os << "lamp.node_tree.links.new(falloff_node.outputs[1], lamp.node_tree.nodes['Emission'].inputs[1])\n"; if (light.q > FLT_EPSILON)
if (light.q > FLT_EPSILON) os.format("lamp.linear_coefficient = 250 / %f\n", light.q);
os.format("lamp.linear_coefficient = 250 / %f\n", light.q); break;
break; case BabeDeadLight::Falloff::Quadratic:
case BabeDeadLight::Falloff::Quadratic: os << "lamp.node_tree.links.new(falloff_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[1])\n";
os << "lamp.node_tree.links.new(falloff_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[1])\n"; if (light.q > FLT_EPSILON)
if (light.q > FLT_EPSILON) os.format("lamp.quadratic_coefficient = 25000 / %f\n", light.q);
os.format("lamp.quadratic_coefficient = 25000 / %f\n", light.q); break;
break; default:
default: break; break;
} }
} }
template void ReadBabeDeadLightToBlender<DNAMP1::MREA::BabeDeadLight> template void ReadBabeDeadLightToBlender<DNAMP1::MREA::BabeDeadLight>(hecl::blender::PyOutStream& os,
(hecl::blender::PyOutStream& os, const DNAMP1::MREA::BabeDeadLight& light, unsigned s, unsigned l); const DNAMP1::MREA::BabeDeadLight& light,
template void ReadBabeDeadLightToBlender<DNAMP3::MREA::BabeDeadLight> unsigned s, unsigned l);
(hecl::blender::PyOutStream& os, const DNAMP3::MREA::BabeDeadLight& light, unsigned s, unsigned l); template void ReadBabeDeadLightToBlender<DNAMP3::MREA::BabeDeadLight>(hecl::blender::PyOutStream& os,
const DNAMP3::MREA::BabeDeadLight& light,
unsigned s, unsigned l);
template<class BabeDeadLight> template <class BabeDeadLight>
void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender::Light& lightIn) void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender::Light& lightIn) {
{ using InterType = hecl::blender::Light::Type;
using InterType = hecl::blender::Light::Type; switch (lightIn.type) {
switch (lightIn.type) case InterType::Ambient:
{ lightOut.lightType = BabeDeadLight::LightType::LocalAmbient;
case InterType::Ambient: break;
lightOut.lightType = BabeDeadLight::LightType::LocalAmbient; case InterType::Directional:
break; lightOut.lightType = BabeDeadLight::LightType::Directional;
case InterType::Directional: break;
lightOut.lightType = BabeDeadLight::LightType::Directional; case InterType::Custom:
break; default:
case InterType::Custom: lightOut.lightType = BabeDeadLight::LightType::Custom;
default: break;
lightOut.lightType = BabeDeadLight::LightType::Custom; case InterType::Spot:
break; lightOut.lightType = BabeDeadLight::LightType::Spot;
case InterType::Spot: break;
lightOut.lightType = BabeDeadLight::LightType::Spot; }
break;
}
if (lightIn.type == InterType::Ambient) if (lightIn.type == InterType::Ambient) {
{ lightOut.falloff = BabeDeadLight::Falloff::Constant;
lightOut.falloff = BabeDeadLight::Falloff::Constant; lightOut.q = lightIn.energy * 8.f;
lightOut.q = lightIn.energy * 8.f; } else if (lightIn.linear > lightIn.constant && lightIn.linear > lightIn.quadratic) {
} lightOut.falloff = BabeDeadLight::Falloff::Linear;
else if (lightIn.linear > lightIn.constant && lightOut.q = 250.f / lightIn.linear;
lightIn.linear > lightIn.quadratic) } else if (lightIn.quadratic > lightIn.constant && lightIn.quadratic > lightIn.linear) {
{ lightOut.falloff = BabeDeadLight::Falloff::Quadratic;
lightOut.falloff = BabeDeadLight::Falloff::Linear; lightOut.q = 25000.f / lightIn.quadratic;
lightOut.q = 250.f / lightIn.linear; } else {
} lightOut.falloff = BabeDeadLight::Falloff::Constant;
else if (lightIn.quadratic > lightIn.constant && lightOut.q = 2.f / lightIn.constant;
lightIn.quadratic > lightIn.linear) }
{
lightOut.falloff = BabeDeadLight::Falloff::Quadratic;
lightOut.q = 25000.f / lightIn.quadratic;
}
else
{
lightOut.falloff = BabeDeadLight::Falloff::Constant;
lightOut.q = 2.f / lightIn.constant;
}
lightOut.color = lightIn.color; lightOut.color = lightIn.color;
lightOut.spotCutoff = zeus::radToDeg(lightIn.spotCutoff); lightOut.spotCutoff = zeus::radToDeg(lightIn.spotCutoff);
lightOut.castShadows = lightIn.shadow; lightOut.castShadows = lightIn.shadow;
lightOut.position.simd[0] = lightIn.sceneXf[0].simd[3]; lightOut.position.simd[0] = lightIn.sceneXf[0].simd[3];
lightOut.position.simd[1] = lightIn.sceneXf[1].simd[3]; lightOut.position.simd[1] = lightIn.sceneXf[1].simd[3];
lightOut.position.simd[2] = lightIn.sceneXf[2].simd[3]; lightOut.position.simd[2] = lightIn.sceneXf[2].simd[3];
zeus::CTransform lightXf(&lightIn.sceneXf[0]); zeus::CTransform lightXf(&lightIn.sceneXf[0]);
lightOut.direction = (lightXf.basis.transposed() * zeus::CVector3f(0.f, 0.f, -1.f)).normalized(); lightOut.direction = (lightXf.basis.transposed() * zeus::CVector3f(0.f, 0.f, -1.f)).normalized();
} }
template void WriteBabeDeadLightFromBlender<DNAMP1::MREA::BabeDeadLight> template void WriteBabeDeadLightFromBlender<DNAMP1::MREA::BabeDeadLight>(DNAMP1::MREA::BabeDeadLight& lightOut,
(DNAMP1::MREA::BabeDeadLight& lightOut, const hecl::blender::Light& lightIn); const hecl::blender::Light& lightIn);
template void WriteBabeDeadLightFromBlender<DNAMP3::MREA::BabeDeadLight> template void WriteBabeDeadLightFromBlender<DNAMP3::MREA::BabeDeadLight>(DNAMP3::MREA::BabeDeadLight& lightOut,
(DNAMP3::MREA::BabeDeadLight& lightOut, const hecl::blender::Light& lightIn); const hecl::blender::Light& lightIn);
} } // namespace DataSpec

View File

@ -4,15 +4,12 @@
#include "hecl/hecl.hpp" #include "hecl/hecl.hpp"
#include <cfloat> #include <cfloat>
namespace DataSpec namespace DataSpec {
{
template<class BabeDeadLight> template <class BabeDeadLight>
void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLight& light, unsigned s, unsigned l);
const BabeDeadLight& light, unsigned s, unsigned l);
template<class BabeDeadLight> template <class BabeDeadLight>
void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender::Light& lightIn); void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender::Light& lightIn);
} } // namespace DataSpec

File diff suppressed because it is too large Load Diff

View File

@ -8,165 +8,144 @@
#include "TXTR.hpp" #include "TXTR.hpp"
#include "zeus/CAABox.hpp" #include "zeus/CAABox.hpp"
namespace DataSpec::DNACMDL namespace DataSpec::DNACMDL {
{
using Mesh = hecl::blender::Mesh; using Mesh = hecl::blender::Mesh;
using Material = hecl::blender::Material; using Material = hecl::blender::Material;
struct Header : BigDNA struct Header : BigDNA {
{ AT_DECL_DNA
Value<atUint32> magic;
Value<atUint32> version;
struct Flags : BigDNA {
AT_DECL_DNA AT_DECL_DNA
Value<atUint32> magic; Value<atUint32> flags = 0;
Value<atUint32> version; bool skinned() const { return (flags & 0x1) != 0; }
struct Flags : BigDNA void setSkinned(bool val) {
{ flags &= ~0x1;
AT_DECL_DNA flags |= val;
Value<atUint32> flags = 0; }
bool skinned() const {return (flags & 0x1) != 0;} bool shortNormals() const { return (flags & 0x2) != 0; }
void setSkinned(bool val) {flags &= ~0x1; flags |= val;} void setShortNormals(bool val) {
bool shortNormals() const {return (flags & 0x2) != 0;} flags &= ~0x2;
void setShortNormals(bool val) {flags &= ~0x2; flags |= val << 1;} flags |= val << 1;
bool shortUVs() const {return (flags & 0x4) != 0;} }
void setShortUVs(bool val) {flags &= ~0x4; flags |= val << 2;} bool shortUVs() const { return (flags & 0x4) != 0; }
} flags; void setShortUVs(bool val) {
Value<atVec3f> aabbMin; flags &= ~0x4;
Value<atVec3f> aabbMax; flags |= val << 2;
Value<atUint32> secCount; }
Value<atUint32> matSetCount; } flags;
Vector<atUint32, AT_DNA_COUNT(secCount)> secSizes; Value<atVec3f> aabbMin;
Align<32> align; Value<atVec3f> aabbMax;
Value<atUint32> secCount;
Value<atUint32> matSetCount;
Vector<atUint32, AT_DNA_COUNT(secCount)> secSizes;
Align<32> align;
}; };
struct SurfaceHeader_1 : BigDNA struct SurfaceHeader_1 : BigDNA {
{ AT_DECL_EXPLICIT_DNA
AT_DECL_EXPLICIT_DNA Value<atVec3f> centroid;
Value<atVec3f> centroid; Value<atUint32> matIdx = 0;
Value<atUint32> matIdx = 0; Value<atUint32> dlSize = 0;
Value<atUint32> dlSize = 0; Value<atUint32> idxStart = 0; /* Actually used by game to stash CCubeModel pointer */
Value<atUint32> idxStart = 0; /* Actually used by game to stash CCubeModel pointer */ Value<atUint32> idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */
Value<atUint32> idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ Value<atUint32> aabbSz = 0;
Value<atUint32> aabbSz = 0; Value<atVec3f> reflectionNormal;
Value<atVec3f> reflectionNormal; Value<atVec3f> aabb[2];
Value<atVec3f> aabb[2]; Align<32> align;
Align<32> align;
static constexpr bool UseMatrixSkinning() {return false;} static constexpr bool UseMatrixSkinning() { return false; }
static constexpr atInt16 skinMatrixBankIdx() {return -1;} static constexpr atInt16 skinMatrixBankIdx() { return -1; }
}; };
struct SurfaceHeader_2 : BigDNA struct SurfaceHeader_2 : BigDNA {
{ AT_DECL_EXPLICIT_DNA
AT_DECL_EXPLICIT_DNA Value<atVec3f> centroid;
Value<atVec3f> centroid; Value<atUint32> matIdx = 0;
Value<atUint32> matIdx = 0; Value<atUint32> dlSize = 0;
Value<atUint32> dlSize = 0; Value<atUint32> idxStart = 0; /* Actually used by game to stash CCubeModel pointer */
Value<atUint32> idxStart = 0; /* Actually used by game to stash CCubeModel pointer */ Value<atUint32> idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */
Value<atUint32> idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ Value<atUint32> aabbSz = 0;
Value<atUint32> aabbSz = 0; Value<atVec3f> reflectionNormal;
Value<atVec3f> reflectionNormal; Value<atInt16> skinMtxBankIdx;
Value<atInt16> skinMtxBankIdx; Value<atUint16> surfaceGroup;
Value<atUint16> surfaceGroup; Value<atVec3f> aabb[2];
Value<atVec3f> aabb[2]; Align<32> align;
Align<32> align;
static constexpr bool UseMatrixSkinning() {return false;} static constexpr bool UseMatrixSkinning() { return false; }
atInt16 skinMatrixBankIdx() const {return skinMtxBankIdx;} atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; }
}; };
struct SurfaceHeader_3 : BigDNA struct SurfaceHeader_3 : BigDNA {
{ AT_DECL_EXPLICIT_DNA
AT_DECL_EXPLICIT_DNA Value<atVec3f> centroid;
Value<atVec3f> centroid; Value<atUint32> matIdx = 0;
Value<atUint32> matIdx = 0; Value<atUint32> dlSize = 0;
Value<atUint32> dlSize = 0; Value<atUint32> idxStart = 0; /* Actually used by game to stash CCubeModel pointer */
Value<atUint32> idxStart = 0; /* Actually used by game to stash CCubeModel pointer */ Value<atUint32> idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */
Value<atUint32> idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ Value<atUint32> aabbSz = 0;
Value<atUint32> aabbSz = 0; Value<atVec3f> reflectionNormal;
Value<atVec3f> reflectionNormal; Value<atInt16> skinMtxBankIdx;
Value<atInt16> skinMtxBankIdx; Value<atUint16> surfaceGroup;
Value<atUint16> surfaceGroup; Value<atVec3f> aabb[2];
Value<atVec3f> aabb[2]; Value<atUint8> unk3;
Value<atUint8> unk3; Align<32> align;
Align<32> align;
static constexpr bool UseMatrixSkinning() {return true;} static constexpr bool UseMatrixSkinning() { return true; }
atInt16 skinMatrixBankIdx() const {return skinMtxBankIdx;} atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; }
}; };
struct VertexAttributes struct VertexAttributes {
{ GX::AttrType pos = GX::NONE;
GX::AttrType pos = GX::NONE; GX::AttrType norm = GX::NONE;
GX::AttrType norm = GX::NONE; GX::AttrType color0 = GX::NONE;
GX::AttrType color0 = GX::NONE; GX::AttrType color1 = GX::NONE;
GX::AttrType color1 = GX::NONE; unsigned uvCount = 0;
unsigned uvCount = 0; GX::AttrType uvs[7] = {GX::NONE};
GX::AttrType uvs[7] = {GX::NONE}; GX::AttrType pnMtxIdx = GX::NONE;
GX::AttrType pnMtxIdx = GX::NONE; unsigned texMtxIdxCount = 0;
unsigned texMtxIdxCount = 0; GX::AttrType texMtxIdx[7] = {GX::NONE};
GX::AttrType texMtxIdx[7] = {GX::NONE}; bool shortUVs;
bool shortUVs;
}; };
template <class MaterialSet> template <class MaterialSet>
void GetVertexAttributes(const MaterialSet& matSet, void GetVertexAttributes(const MaterialSet& matSet, std::vector<VertexAttributes>& attributesOut);
std::vector<VertexAttributes>& attributesOut);
template <class PAKRouter, class MaterialSet> template <class PAKRouter, class MaterialSet>
void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter,
const MaterialSet& matSet, const typename PAKRouter::EntryType& entry, unsigned setIdx);
const PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
unsigned setIdx);
template <class PAKRouter, class MaterialSet> template <class PAKRouter, class MaterialSet>
void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os, void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter,
const MaterialSet& matSet, const typename PAKRouter::EntryType& entry, unsigned setIdx);
const PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
unsigned setIdx);
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath,
const hecl::ProjectPath& masterShaderPath,
bool solidShading); bool solidShading);
void FinishBlenderMesh(hecl::blender::PyOutStream& os, void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx);
unsigned matSetCount, int meshIdx);
template <class PAKRouter, class MaterialSet, class RigPair, class SurfaceHeader> template <class PAKRouter, class MaterialSet, class RigPair, class SurfaceHeader>
atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader,
athena::io::IStreamReader& reader, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const RigPair& rp,
PAKRouter& pakRouter, bool shortNormals, bool shortUVs, std::vector<VertexAttributes>& vertAttribs,
const typename PAKRouter::EntryType& entry, int meshIdx, atUint32 secCount, atUint32 matSetCount, const atUint32* secSizes,
const RigPair& rp, atUint32 surfaceCount = 0);
bool shortNormals,
bool shortUVs,
std::vector<VertexAttributes>& vertAttribs,
int meshIdx,
atUint32 secCount,
atUint32 matSetCount,
const atUint32* secSizes,
atUint32 surfaceCount=0);
template <class PAKRouter, class MaterialSet, class RigPair, class SurfaceHeader, atUint32 Version> template <class PAKRouter, class MaterialSet, class RigPair, class SurfaceHeader, atUint32 Version>
bool ReadCMDLToBlender(hecl::blender::Connection& conn, bool ReadCMDLToBlender(hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter,
athena::io::IStreamReader& reader, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, const RigPair& rp);
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
const SpecBase& dataspec,
const RigPair& rp);
template <class PAKRouter, class MaterialSet> template <class PAKRouter, class MaterialSet>
void NameCMDL(athena::io::IStreamReader& reader, void NameCMDL(athena::io::IStreamReader& reader, PAKRouter& pakRouter, typename PAKRouter::EntryType& entry,
PAKRouter& pakRouter,
typename PAKRouter::EntryType& entry,
const SpecBase& dataspec); const SpecBase& dataspec);
template <class MaterialSet, class SurfaceHeader, atUint32 Version> template <class MaterialSet, class SurfaceHeader, atUint32 Version>
bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh); bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
template <class MaterialSet, class SurfaceHeader, atUint32 Version> template <class MaterialSet, class SurfaceHeader, atUint32 Version>
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh,
const Mesh& mesh, hecl::blender::PoolSkinIndex& poolSkinIndex); hecl::blender::PoolSkinIndex& poolSkinIndex);
template <class MaterialSet, class SurfaceHeader, class MeshHeader> template <class MaterialSet, class SurfaceHeader, class MeshHeader>
bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath, bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath,
@ -176,5 +155,4 @@ template <class MaterialSet, class SurfaceHeader, class MeshHeader>
bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath, bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath,
const std::vector<Mesh>& meshes, zeus::CAABox& fullAABB, std::vector<zeus::CAABox>& meshAABBs); const std::vector<Mesh>& meshes, zeus::CAABox& fullAABB, std::vector<zeus::CAABox>& meshAABBs);
} } // namespace DataSpec::DNACMDL

View File

@ -1,341 +1,268 @@
#include "CRSC.hpp" #include "CRSC.hpp"
namespace DataSpec::DNAParticle namespace DataSpec::DNAParticle {
{ static const std::vector<FourCC> GeneratorTypes = {
static const std::vector<FourCC> GeneratorTypes = SBIG('NODP'), SBIG('DEFS'), SBIG('CRTS'), SBIG('MTLS'), SBIG('GRAS'), SBIG('ICEE'), SBIG('GOOO'), SBIG('WODS'),
{ SBIG('WATR'), SBIG('1MUD'), SBIG('1LAV'), SBIG('1SAN'), SBIG('1PRJ'), SBIG('DCHR'), SBIG('DCHS'), SBIG('DCSH'),
SBIG('NODP'),SBIG('DEFS'),SBIG('CRTS'),SBIG('MTLS'), SBIG('DENM'), SBIG('DESP'), SBIG('DESH'), SBIG('BTLE'), SBIG('WASP'), SBIG('TALP'), SBIG('PTGM'), SBIG('SPIR'),
SBIG('GRAS'),SBIG('ICEE'),SBIG('GOOO'),SBIG('WODS'), SBIG('FPIR'), SBIG('FFLE'), SBIG('PARA'), SBIG('BMON'), SBIG('BFLR'), SBIG('PBOS'), SBIG('IBOS'), SBIG('1SVA'),
SBIG('WATR'),SBIG('1MUD'),SBIG('1LAV'),SBIG('1SAN'), SBIG('1RPR'), SBIG('1MTR'), SBIG('1PDS'), SBIG('1FLB'), SBIG('1DRN'), SBIG('1MRE'), SBIG('CHOZ'), SBIG('JZAP'),
SBIG('1PRJ'),SBIG('DCHR'),SBIG('DCHS'),SBIG('DCSH'), SBIG('1ISE'), SBIG('1BSE'), SBIG('1ATB'), SBIG('1ATA'), SBIG('BTSP'), SBIG('WWSP'), SBIG('TASP'), SBIG('TGSP'),
SBIG('DENM'),SBIG('DESP'),SBIG('DESH'),SBIG('BTLE'), SBIG('SPSP'), SBIG('FPSP'), SBIG('FFSP'), SBIG('PSSP'), SBIG('BMSP'), SBIG('BFSP'), SBIG('PBSP'), SBIG('IBSP'),
SBIG('WASP'),SBIG('TALP'),SBIG('PTGM'),SBIG('SPIR'), SBIG('2SVA'), SBIG('2RPR'), SBIG('2MTR'), SBIG('2PDS'), SBIG('2FLB'), SBIG('2DRN'), SBIG('2MRE'), SBIG('CHSP'),
SBIG('FPIR'),SBIG('FFLE'),SBIG('PARA'),SBIG('BMON'), SBIG('JZSP'), SBIG('3ISE'), SBIG('3BSE'), SBIG('3ATB'), SBIG('3ATA'), SBIG('BTSH'), SBIG('WWSH'), SBIG('TASH'),
SBIG('BFLR'),SBIG('PBOS'),SBIG('IBOS'),SBIG('1SVA'), SBIG('TGSH'), SBIG('SPSH'), SBIG('FPSH'), SBIG('FFSH'), SBIG('PSSH'), SBIG('BMSH'), SBIG('BFSH'), SBIG('PBSH'),
SBIG('1RPR'),SBIG('1MTR'),SBIG('1PDS'),SBIG('1FLB'), SBIG('IBSH'), SBIG('3SVA'), SBIG('3RPR'), SBIG('3MTR'), SBIG('3PDS'), SBIG('3FLB'), SBIG('3DRN'), SBIG('3MRE'),
SBIG('1DRN'),SBIG('1MRE'),SBIG('CHOZ'),SBIG('JZAP'), SBIG('CHSH'), SBIG('JZSH'), SBIG('5ISE'), SBIG('5BSE'), SBIG('5ATB'), SBIG('5ATA')};
SBIG('1ISE'),SBIG('1BSE'),SBIG('1ATB'),SBIG('1ATA'),
SBIG('BTSP'),SBIG('WWSP'),SBIG('TASP'),SBIG('TGSP'), static const std::vector<FourCC> SFXTypes = {
SBIG('SPSP'),SBIG('FPSP'),SBIG('FFSP'),SBIG('PSSP'), SBIG('DSFX'), SBIG('CSFX'), SBIG('MSFX'), SBIG('GRFX'), SBIG('NSFX'), SBIG('DSFX'), SBIG('CSFX'), SBIG('MSFX'),
SBIG('BMSP'),SBIG('BFSP'),SBIG('PBSP'),SBIG('IBSP'), SBIG('GRFX'), SBIG('ICFX'), SBIG('GOFX'), SBIG('WSFX'), SBIG('WTFX'), SBIG('2MUD'), SBIG('2LAV'), SBIG('2SAN'),
SBIG('2SVA'),SBIG('2RPR'),SBIG('2MTR'),SBIG('2PDS'), SBIG('2PRJ'), SBIG('DCFX'), SBIG('DSFX'), SBIG('DSHX'), SBIG('DEFX'), SBIG('ESFX'), SBIG('SHFX'), SBIG('BEFX'),
SBIG('2FLB'),SBIG('2DRN'),SBIG('2MRE'),SBIG('CHSP'), SBIG('WWFX'), SBIG('TAFX'), SBIG('GTFX'), SBIG('SPFX'), SBIG('FPFX'), SBIG('FFFX'), SBIG('PAFX'), SBIG('BMFX'),
SBIG('JZSP'),SBIG('3ISE'),SBIG('3BSE'),SBIG('3ATB'), SBIG('BFFX'), SBIG('PBFX'), SBIG('IBFX'), SBIG('4SVA'), SBIG('4RPR'), SBIG('4MTR'), SBIG('4PDS'), SBIG('4FLB'),
SBIG('3ATA'),SBIG('BTSH'),SBIG('WWSH'),SBIG('TASH'), SBIG('4DRN'), SBIG('4MRE'), SBIG('CZFX'), SBIG('JZAS'), SBIG('2ISE'), SBIG('2BSE'), SBIG('2ATB'), SBIG('2ATA'),
SBIG('TGSH'),SBIG('SPSH'),SBIG('FPSH'),SBIG('FFSH'), SBIG('BSFX'), SBIG('WSFX'), SBIG('TSFX'), SBIG('GSFX'), SBIG('SSFX'), SBIG('FSFX'), SBIG('SFFX'), SBIG('PSFX'),
SBIG('PSSH'),SBIG('BMSH'),SBIG('BFSH'),SBIG('PBSH'), SBIG('MSFX'), SBIG('SBFX'), SBIG('PBSX'), SBIG('IBSX'), SBIG('5SVA'), SBIG('5RPR'), SBIG('5MTR'), SBIG('5PDS'),
SBIG('IBSH'),SBIG('3SVA'),SBIG('3RPR'),SBIG('3MTR'), SBIG('5FLB'), SBIG('5DRN'), SBIG('5MRE'), SBIG('CSFX'), SBIG('JZPS'), SBIG('4ISE'), SBIG('4BSE'), SBIG('4ATB'),
SBIG('3PDS'),SBIG('3FLB'),SBIG('3DRN'),SBIG('3MRE'), SBIG('4ATA'), SBIG('BHFX'), SBIG('WHFX'), SBIG('THFX'), SBIG('GHFX'), SBIG('SHFX'), SBIG('FHFX'), SBIG('HFFX'),
SBIG('CHSH'),SBIG('JZSH'),SBIG('5ISE'),SBIG('5BSE'), SBIG('PHFX'), SBIG('MHFX'), SBIG('HBFX'), SBIG('PBHX'), SBIG('IBHX'), SBIG('6SVA'), SBIG('6RPR'), SBIG('6MTR'),
SBIG('5ATB'),SBIG('5ATA') SBIG('6PDS'), SBIG('6FLB'), SBIG('6DRN'), SBIG('6MRE'), SBIG('CHFX'), SBIG('JZHS'), SBIG('6ISE'), SBIG('6BSE'),
SBIG('6ATB'), SBIG('6ATA'),
}; };
static const std::vector<FourCC> SFXTypes = static const std::vector<FourCC> DecalTypes = {SBIG('NCDL'), SBIG('DDCL'), SBIG('CODL'), SBIG('MEDL'), SBIG('GRDL'),
{ SBIG('ICDL'), SBIG('GODL'), SBIG('WODL'), SBIG('WTDL'), SBIG('3MUD'),
SBIG('DSFX'),SBIG('CSFX'),SBIG('MSFX'),SBIG('GRFX'), SBIG('3LAV'), SBIG('3SAN'), SBIG('CHDL'), SBIG('ENDL')};
SBIG('NSFX'),SBIG('DSFX'),SBIG('CSFX'),SBIG('MSFX'),
SBIG('GRFX'),SBIG('ICFX'),SBIG('GOFX'),SBIG('WSFX'),
SBIG('WTFX'),SBIG('2MUD'),SBIG('2LAV'),SBIG('2SAN'),
SBIG('2PRJ'),SBIG('DCFX'),SBIG('DSFX'),SBIG('DSHX'),
SBIG('DEFX'),SBIG('ESFX'),SBIG('SHFX'),SBIG('BEFX'),
SBIG('WWFX'),SBIG('TAFX'),SBIG('GTFX'),SBIG('SPFX'),
SBIG('FPFX'),SBIG('FFFX'),SBIG('PAFX'),SBIG('BMFX'),
SBIG('BFFX'),SBIG('PBFX'),SBIG('IBFX'),SBIG('4SVA'),
SBIG('4RPR'),SBIG('4MTR'),SBIG('4PDS'),SBIG('4FLB'),
SBIG('4DRN'),SBIG('4MRE'),SBIG('CZFX'),SBIG('JZAS'),
SBIG('2ISE'),SBIG('2BSE'),SBIG('2ATB'),SBIG('2ATA'),
SBIG('BSFX'),SBIG('WSFX'),SBIG('TSFX'),SBIG('GSFX'),
SBIG('SSFX'),SBIG('FSFX'),SBIG('SFFX'),SBIG('PSFX'),
SBIG('MSFX'),SBIG('SBFX'),SBIG('PBSX'),SBIG('IBSX'),
SBIG('5SVA'),SBIG('5RPR'),SBIG('5MTR'),SBIG('5PDS'),
SBIG('5FLB'),SBIG('5DRN'),SBIG('5MRE'),SBIG('CSFX'),
SBIG('JZPS'),SBIG('4ISE'),SBIG('4BSE'),SBIG('4ATB'),
SBIG('4ATA'),SBIG('BHFX'),SBIG('WHFX'),SBIG('THFX'),
SBIG('GHFX'),SBIG('SHFX'),SBIG('FHFX'),SBIG('HFFX'),
SBIG('PHFX'),SBIG('MHFX'),SBIG('HBFX'),SBIG('PBHX'),
SBIG('IBHX'),SBIG('6SVA'),SBIG('6RPR'),SBIG('6MTR'),
SBIG('6PDS'),SBIG('6FLB'),SBIG('6DRN'),SBIG('6MRE'),
SBIG('CHFX'),SBIG('JZHS'),SBIG('6ISE'),SBIG('6BSE'),
SBIG('6ATB'),SBIG('6ATA'),
};
static const std::vector<FourCC> DecalTypes =
{
SBIG('NCDL'),SBIG('DDCL'),SBIG('CODL'),SBIG('MEDL'),
SBIG('GRDL'),SBIG('ICDL'),SBIG('GODL'),SBIG('WODL'),
SBIG('WTDL'),SBIG('3MUD'),SBIG('3LAV'),SBIG('3SAN'),
SBIG('CHDL'),SBIG('ENDL')
};
template <> template <>
const char* CRSM<UniqueID32>::DNAType() { return "CRSM<UniqueID32>"; } const char* CRSM<UniqueID32>::DNAType() {
return "CRSM<UniqueID32>";
}
template <> template <>
const char* CRSM<UniqueID64>::DNAType() { return "CRSM<UniqueID64>"; } const char* CRSM<UniqueID64>::DNAType() {
return "CRSM<UniqueID64>";
template <class IDType>
void CRSM<IDType>::_read(athena::io::YAMLDocReader& r)
{
for (const auto& elem : r.getCurNode()->m_mapChildren)
{
if (elem.first.size() < 4)
{
LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str());
continue;
}
if (auto rec = r.enterSubRecord(elem.first.c_str()))
{
FourCC clsId(elem.first.c_str());
auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (gen != GeneratorTypes.end())
{
x0_generators[clsId].read(r);
continue;
}
auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (sfx != SFXTypes.end())
{
x10_sfx[clsId] = r.readInt32(clsId.toString().c_str());
continue;
}
auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (decal != DecalTypes.end())
{
x20_decals[clsId].read(r);
continue;
}
if (clsId == SBIG('RNGE'))
x30_RNGE = r.readFloat(nullptr);
else if (clsId == SBIG('FOFF'))
x34_FOFF = r.readFloat(nullptr);
}
}
} }
template <class IDType> template <class IDType>
void CRSM<IDType>::_write(athena::io::YAMLDocWriter& w) const void CRSM<IDType>::_read(athena::io::YAMLDocReader& r) {
{ for (const auto& elem : r.getCurNode()->m_mapChildren) {
for (const auto& pair : x0_generators) if (elem.first.size() < 4) {
if (pair.second) LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str());
if (auto rec = w.enterSubRecord(pair.first.toString().c_str())) continue;
pair.second.write(w); }
for (const auto& pair : x10_sfx) if (auto rec = r.enterSubRecord(elem.first.c_str())) {
if (pair.second != ~0) FourCC clsId(elem.first.c_str());
w.writeUint32(pair.first.toString().c_str(), pair.second); auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; });
if (gen != GeneratorTypes.end()) {
x0_generators[clsId].read(r);
continue;
}
for (const auto& pair : x20_decals) auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(),
if (pair.second) [&clsId](const FourCC& other) -> bool { return clsId == other; });
if (auto rec = w.enterSubRecord(pair.first.toString().c_str())) if (sfx != SFXTypes.end()) {
pair.second.write(w); x10_sfx[clsId] = r.readInt32(clsId.toString().c_str());
continue;
}
if (x30_RNGE != 50.f) auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(),
w.writeFloat("RNGE", x30_RNGE); [&clsId](const FourCC& other) -> bool { return clsId == other; });
if (x34_FOFF != 0.2f) if (decal != DecalTypes.end()) {
w.writeFloat("FOFF", x34_FOFF); x20_decals[clsId].read(r);
continue;
}
if (clsId == SBIG('RNGE'))
x30_RNGE = r.readFloat(nullptr);
else if (clsId == SBIG('FOFF'))
x34_FOFF = r.readFloat(nullptr);
}
}
} }
template <class IDType> template <class IDType>
void CRSM<IDType>::_binarySize(size_t& __isz) const void CRSM<IDType>::_write(athena::io::YAMLDocWriter& w) const {
{ for (const auto& pair : x0_generators)
__isz += 4; if (pair.second)
for (const auto& pair : x0_generators) if (auto rec = w.enterSubRecord(pair.first.toString().c_str()))
{ pair.second.write(w);
if (pair.second)
{
__isz += 4;
pair.second.binarySize(__isz);
}
}
for (const auto& pair : x10_sfx)
{
if (pair.second != ~0)
__isz += 12;
}
for (const auto& pair : x20_decals) for (const auto& pair : x10_sfx)
{ if (pair.second != ~0)
if (pair.second) w.writeUint32(pair.first.toString().c_str(), pair.second);
{
__isz += 4;
pair.second.binarySize(__isz);
}
}
if (x30_RNGE != 50.f) for (const auto& pair : x20_decals)
__isz += 12; if (pair.second)
if (x34_FOFF != 0.2f) if (auto rec = w.enterSubRecord(pair.first.toString().c_str()))
__isz += 12; pair.second.write(w);
if (x30_RNGE != 50.f)
w.writeFloat("RNGE", x30_RNGE);
if (x34_FOFF != 0.2f)
w.writeFloat("FOFF", x34_FOFF);
} }
template <class IDType> template <class IDType>
void CRSM<IDType>::_read(athena::io::IStreamReader &r) void CRSM<IDType>::_binarySize(size_t& __isz) const {
{ __isz += 4;
uint32_t clsId; for (const auto& pair : x0_generators) {
if (pair.second) {
__isz += 4;
pair.second.binarySize(__isz);
}
}
for (const auto& pair : x10_sfx) {
if (pair.second != ~0)
__isz += 12;
}
for (const auto& pair : x20_decals) {
if (pair.second) {
__isz += 4;
pair.second.binarySize(__isz);
}
}
if (x30_RNGE != 50.f)
__isz += 12;
if (x34_FOFF != 0.2f)
__isz += 12;
}
template <class IDType>
void CRSM<IDType>::_read(athena::io::IStreamReader& r) {
uint32_t clsId;
r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('CRSM')) {
LogModule.report(logvisor::Warning, "non CRSM provided to CRSM parser");
return;
}
while (clsId != SBIG('_END')) {
r.readBytesToBuf(&clsId, 4); r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('CRSM')) auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(),
{ [&clsId](const FourCC& other) -> bool { return clsId == other; });
LogModule.report(logvisor::Warning, "non CRSM provided to CRSM parser"); if (gen != GeneratorTypes.end()) {
return; x0_generators[clsId].read(r);
continue;
} }
while (clsId != SBIG('_END')) auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(),
{ [&clsId](const FourCC& other) -> bool { return clsId == other; });
r.readBytesToBuf(&clsId, 4); if (sfx != SFXTypes.end()) {
auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(), [&clsId](const FourCC& other) -> bool{ uint32_t fcc;
return clsId == other; r.readBytesToBuf(&fcc, 4);
}); if (fcc != SBIG('NONE'))
if (gen != GeneratorTypes.end()) x10_sfx[clsId] = r.readInt32Big();
{ else
x0_generators[clsId].read(r); x10_sfx[clsId] = ~0;
continue; continue;
}
auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (sfx != SFXTypes.end())
{
uint32_t fcc;
r.readBytesToBuf(&fcc, 4);
if (fcc != SBIG('NONE'))
x10_sfx[clsId] = r.readInt32Big();
else
x10_sfx[clsId] = ~0;
continue;
}
auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (decal != DecalTypes.end())
{
x20_decals[clsId].read(r);
continue;
}
if (clsId == SBIG('RNGE'))
{
r.readUint32();
x30_RNGE = r.readFloatBig();
continue;
}
if (clsId == SBIG('FOFF'))
{
r.readUint32();
x34_FOFF = r.readFloatBig();
continue;
}
if (clsId != SBIG('_END'))
LogModule.report(logvisor::Fatal, "Unknown CRSM class %.4s @%" PRIi64, &clsId, r.position());
} }
auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; });
if (decal != DecalTypes.end()) {
x20_decals[clsId].read(r);
continue;
}
if (clsId == SBIG('RNGE')) {
r.readUint32();
x30_RNGE = r.readFloatBig();
continue;
}
if (clsId == SBIG('FOFF')) {
r.readUint32();
x34_FOFF = r.readFloatBig();
continue;
}
if (clsId != SBIG('_END'))
LogModule.report(logvisor::Fatal, "Unknown CRSM class %.4s @%" PRIi64, &clsId, r.position());
}
} }
template <class IDType> template <class IDType>
void CRSM<IDType>::_write(athena::io::IStreamWriter& w) const void CRSM<IDType>::_write(athena::io::IStreamWriter& w) const {
{ w.writeBytes("CRSM", 4);
w.writeBytes("CRSM", 4); for (const auto& pair : x0_generators) {
for (const auto& pair : x0_generators) w.writeBytes(pair.first.getChars(), 4);
{ pair.second.write(w);
w.writeBytes(pair.first.getChars(), 4); }
pair.second.write(w);
}
for (const auto& pair : x10_sfx) for (const auto& pair : x10_sfx) {
{ w.writeBytes(pair.first.getChars(), 4);
w.writeBytes(pair.first.getChars(), 4); if (pair.second != ~0) {
if (pair.second != ~0) w.writeBytes("CNST", 4);
{ w.writeUint32Big(pair.second);
w.writeBytes("CNST", 4); } else {
w.writeUint32Big(pair.second); w.writeBytes("NONE", 4);
}
else
{
w.writeBytes("NONE", 4);
}
} }
}
for (const auto& pair : x20_decals) for (const auto& pair : x20_decals) {
{ w.writeBytes(pair.first.getChars(), 4);
w.writeBytes(pair.first.getChars(), 4); pair.second.write(w);
pair.second.write(w); }
}
if (x30_RNGE != 50.f) if (x30_RNGE != 50.f) {
{ w.writeBytes("RNGECNST", 8);
w.writeBytes("RNGECNST", 8); w.writeFloatBig(x30_RNGE);
w.writeFloatBig(x30_RNGE); }
} if (x34_FOFF != 0.2f) {
if (x34_FOFF != 0.2f) w.writeBytes("FOFFCNST", 8);
{ w.writeFloatBig(x34_FOFF);
w.writeBytes("FOFFCNST", 8); }
w.writeFloatBig(x34_FOFF); w.writeBytes("_END", 4);
}
w.writeBytes("_END", 4);
} }
AT_SUBSPECIALIZE_DNA_YAML(CRSM<UniqueID32>) AT_SUBSPECIALIZE_DNA_YAML(CRSM<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(CRSM<UniqueID64>) AT_SUBSPECIALIZE_DNA_YAML(CRSM<UniqueID64>)
template <class IDType> template <class IDType>
void CRSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const void CRSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
{ for (const auto& p : x0_generators)
for (const auto& p : x0_generators) g_curSpec->flattenDependencies(p.second.id, pathsOut);
g_curSpec->flattenDependencies(p.second.id, pathsOut); for (const auto& p : x20_decals)
for (const auto& p : x20_decals) g_curSpec->flattenDependencies(p.second.id, pathsOut);
g_curSpec->flattenDependencies(p.second.id, pathsOut);
} }
template <class IDType> template <class IDType>
CRSM<IDType>::CRSM() CRSM<IDType>::CRSM() : x30_RNGE(50.f), x34_FOFF(0.2f) {
: x30_RNGE(50.f), for (const auto& sfx : SFXTypes)
x34_FOFF(0.2f) x10_sfx[sfx] = ~0;
{
for (const auto& sfx : SFXTypes)
x10_sfx[sfx] = ~0;
} }
template struct CRSM<UniqueID32>; template struct CRSM<UniqueID32>;
template struct CRSM<UniqueID64>; template struct CRSM<UniqueID64>;
template <class IDType> template <class IDType>
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::FileWriter writer(outPath.getAbsolutePath()); if (writer.isOpen()) {
if (writer.isOpen()) CRSM<IDType> crsm;
{ crsm.read(rs);
CRSM<IDType> crsm; athena::io::ToYAMLStream(crsm, writer);
crsm.read(rs); return true;
athena::io::ToYAMLStream(crsm, writer); }
return true; return false;
}
return false;
} }
template bool ExtractCRSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractCRSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractCRSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractCRSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath) bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); if (w.hasError())
if (w.hasError()) return false;
return false; crsm.write(w);
crsm.write(w); int64_t rem = w.position() % 32;
int64_t rem = w.position() % 32; if (rem)
if (rem) for (int64_t i = 0; i < 32 - rem; ++i)
for (int64_t i=0 ; i<32-rem ; ++i) w.writeUByte(0xff);
w.writeUByte(0xff); return true;
return true;
} }
template bool WriteCRSM<UniqueID32>(const CRSM<UniqueID32>& crsm, const hecl::ProjectPath& outPath); template bool WriteCRSM<UniqueID32>(const CRSM<UniqueID32>& crsm, const hecl::ProjectPath& outPath);
template bool WriteCRSM<UniqueID64>(const CRSM<UniqueID64>& crsm, const hecl::ProjectPath& outPath); template bool WriteCRSM<UniqueID64>(const CRSM<UniqueID64>& crsm, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAParticle

View File

@ -5,26 +5,24 @@
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
#include "optional.hpp" #include "optional.hpp"
namespace DataSpec::DNAParticle namespace DataSpec::DNAParticle {
{
template <class IDType> template <class IDType>
struct CRSM : BigDNA struct CRSM : BigDNA {
{ AT_DECL_EXPLICIT_DNA_YAML
AT_DECL_EXPLICIT_DNA_YAML AT_SUBDECL_DNA
AT_SUBDECL_DNA std::unordered_map<FourCC, ChildResourceFactory<IDType>> x0_generators;
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x0_generators; std::unordered_map<FourCC, uint32_t> x10_sfx;
std::unordered_map<FourCC, uint32_t> x10_sfx; std::unordered_map<FourCC, ChildResourceFactory<IDType>> x20_decals;
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x20_decals; float x30_RNGE;
float x30_RNGE; float x34_FOFF;
float x34_FOFF;
CRSM(); CRSM();
void gatherDependencies(std::vector<hecl::ProjectPath>&) const; void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
}; };
template <class IDType> template <class IDType>
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath); bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAParticle

View File

@ -3,39 +3,35 @@
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
#include "DGRP.hpp" #include "DGRP.hpp"
namespace DataSpec::DNADGRP namespace DataSpec::DNADGRP {
{
template <class IDType> template <class IDType>
bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::FileWriter writer(outPath.getAbsolutePath()); if (writer.isOpen()) {
if (writer.isOpen()) DGRP<IDType> dgrp;
{ dgrp.read(rs);
DGRP<IDType> dgrp; athena::io::ToYAMLStream(dgrp, writer);
dgrp.read(rs); return true;
athena::io::ToYAMLStream(dgrp, writer); }
return true; return false;
}
return false;
} }
template bool ExtractDGRP<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractDGRP<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractDGRP<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractDGRP<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath) bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); if (w.hasError())
if (w.hasError()) return false;
return false; dgrp.write(w);
dgrp.write(w); int64_t rem = w.position() % 32;
int64_t rem = w.position() % 32; if (rem)
if (rem) for (int64_t i = 0; i < 32 - rem; ++i)
for (int64_t i=0 ; i<32-rem ; ++i) w.writeUByte(0xff);
w.writeUByte(0xff); return true;
return true;
} }
template bool WriteDGRP<UniqueID32>(const DGRP<UniqueID32>& dgrp, const hecl::ProjectPath& outPath); template bool WriteDGRP<UniqueID32>(const DGRP<UniqueID32>& dgrp, const hecl::ProjectPath& outPath);
template bool WriteDGRP<UniqueID64>(const DGRP<UniqueID64>& dgrp, const hecl::ProjectPath& outPath); template bool WriteDGRP<UniqueID64>(const DGRP<UniqueID64>& dgrp, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNADGRP

View File

@ -3,41 +3,36 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
#include "PAK.hpp" #include "PAK.hpp"
namespace DataSpec::DNADGRP namespace DataSpec::DNADGRP {
{
template <class IDType> template <class IDType>
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) DGRP : BigDNA struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) DGRP : BigDNA {
{ AT_DECL_DNA_YAML
Value<atUint32> dependCount;
struct ObjectTag : BigDNA {
AT_DECL_DNA_YAML AT_DECL_DNA_YAML
Value<atUint32> dependCount; DNAFourCC type;
struct ObjectTag : BigDNA Value<IDType> id;
{
AT_DECL_DNA_YAML
DNAFourCC type;
Value<IDType> id;
bool validate() const bool validate() const {
{ if (!id.operator bool())
if (!id.operator bool()) return false;
return false; hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id); return path && !path.isNone();
return path && !path.isNone();
}
};
Vector<ObjectTag, AT_DNA_COUNT(dependCount)> depends;
void validateDeps()
{
std::vector<ObjectTag> newDeps;
newDeps.reserve(depends.size());
for (const ObjectTag& tag : depends)
if (tag.validate())
newDeps.push_back(tag);
depends = std::move(newDeps);
dependCount = atUint32(depends.size());
} }
};
Vector<ObjectTag, AT_DNA_COUNT(dependCount)> depends;
void validateDeps() {
std::vector<ObjectTag> newDeps;
newDeps.reserve(depends.size());
for (const ObjectTag& tag : depends)
if (tag.validate())
newDeps.push_back(tag);
depends = std::move(newDeps);
dependCount = atUint32(depends.size());
}
}; };
template <class IDType> template <class IDType>
@ -45,5 +40,4 @@ bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath); bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNADGRP

View File

@ -2,8 +2,7 @@
#include "PAK.hpp" #include "PAK.hpp"
#include "boo/ThreadLocalPtr.hpp" #include "boo/ThreadLocalPtr.hpp"
namespace DataSpec namespace DataSpec {
{
logvisor::Module LogDNACommon("urde::DNACommon"); logvisor::Module LogDNACommon("urde::DNACommon");
ThreadLocalPtr<SpecBase> g_curSpec; ThreadLocalPtr<SpecBase> g_curSpec;
@ -16,305 +15,270 @@ ThreadLocalPtr<IDRestorer<UniqueID128>> UniqueIDBridge::s_restorer128;
UniqueID32 UniqueID32::kInvalidId; UniqueID32 UniqueID32::kInvalidId;
template <class IDType> template <class IDType>
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool silenceWarnings) hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool silenceWarnings) {
{ /* Try PAKRouter first (only available at extract) */
/* Try PAKRouter first (only available at extract) */ PAKRouterBase* pakRouter = g_PakRouter.get();
PAKRouterBase* pakRouter = g_PakRouter.get(); if (pakRouter) {
if (pakRouter) hecl::ProjectPath path = pakRouter->getWorking(id, silenceWarnings);
{ if (path)
hecl::ProjectPath path = pakRouter->getWorking(id, silenceWarnings); return path;
if (path) }
return path;
}
/* Try project cache second (populated with paths read from YAML resources) */ /* Try project cache second (populated with paths read from YAML resources) */
hecl::Database::Project* project = s_Project.get(); hecl::Database::Project* project = s_Project.get();
if (!project) if (!project) {
{ if (pakRouter) {
if (pakRouter) if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id)
{ LogDNACommon.report(logvisor::Warning, "unable to translate %s to path", id.toString().c_str());
if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id) return {};
LogDNACommon.report(logvisor::Warning,
"unable to translate %s to path", id.toString().c_str());
return {};
}
LogDNACommon.report(logvisor::Fatal,
"g_PakRouter or s_Project must be set to non-null before "
"calling UniqueIDBridge::TranslatePakIdToPath");
return {};
} }
LogDNACommon.report(logvisor::Fatal,
"g_PakRouter or s_Project must be set to non-null before "
"calling UniqueIDBridge::TranslatePakIdToPath");
return {};
}
const hecl::ProjectPath* search = project->lookupBridgePath(id.toUint64()); const hecl::ProjectPath* search = project->lookupBridgePath(id.toUint64());
if (!search) if (!search) {
{ if (IDRestorer<IDType>* restorer = GetIDRestorer<IDType>())
if (IDRestorer<IDType>* restorer = GetIDRestorer<IDType>()) if (IDType newId = restorer->originalToNew(id))
if (IDType newId = restorer->originalToNew(id)) if (const hecl::ProjectPath* newSearch = project->lookupBridgePath(newId.toUint64()))
if (const hecl::ProjectPath* newSearch = project->lookupBridgePath(newId.toUint64())) return *newSearch;
return *newSearch; if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id)
if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id) LogDNACommon.report(logvisor::Warning, "unable to translate %s to path", id.toString().c_str());
LogDNACommon.report(logvisor::Warning, return {};
"unable to translate %s to path", id.toString().c_str()); }
return {}; return *search;
}
return *search;
} }
template template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID32& id, bool silenceWarnings);
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID32& id, bool silenceWarnings); template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID64& id, bool silenceWarnings);
template template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID128& id, bool silenceWarnings);
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID64& id, bool silenceWarnings);
template
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID128& id, bool silenceWarnings);
template <class IDType> template <class IDType>
hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str) hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str) {
{ if (str.empty())
if (str.empty()) return {};
return {}; hecl::Database::Project* project = s_Project.get();
hecl::Database::Project* project = s_Project.get(); if (!project)
if (!project) LogDNACommon.report(logvisor::Fatal, "UniqueIDBridge::setGlobalProject must be called before MakePathFromString");
LogDNACommon.report(logvisor::Fatal, hecl::ProjectPath path = hecl::ProjectPath(*project, str);
"UniqueIDBridge::setGlobalProject must be called before MakePathFromString"); project->addBridgePathToCache(IDType(path).toUint64(), path);
hecl::ProjectPath path = hecl::ProjectPath(*project, str); return path;
project->addBridgePathToCache(IDType(path).toUint64(), path);
return path;
} }
template template hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID32>(std::string_view str);
hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID32>(std::string_view str); template hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID64>(std::string_view str);
template
hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID64>(std::string_view str);
template <class IDType> template <class IDType>
void UniqueIDBridge::TransformOldHashToNewHash(IDType& id) void UniqueIDBridge::TransformOldHashToNewHash(IDType& id) {
{ id = TranslatePakIdToPath(id);
id = TranslatePakIdToPath(id);
} }
template template void UniqueIDBridge::TransformOldHashToNewHash(UniqueID32& id);
void UniqueIDBridge::TransformOldHashToNewHash(UniqueID32& id); template void UniqueIDBridge::TransformOldHashToNewHash(UniqueID64& id);
template
void UniqueIDBridge::TransformOldHashToNewHash(UniqueID64& id);
void UniqueIDBridge::SetThreadProject(hecl::Database::Project& project) void UniqueIDBridge::SetThreadProject(hecl::Database::Project& project) { s_Project.reset(&project); }
{
s_Project.reset(&project);
}
/** PAK 32-bit Unique ID */ /** PAK 32-bit Unique ID */
void UniqueID32::assign(uint32_t id, bool noOriginal) void UniqueID32::assign(uint32_t id, bool noOriginal) {
{ m_id = id ? id : 0xffffffff;
m_id = id ? id : 0xffffffff; if (!noOriginal)
if (!noOriginal) if (IDRestorer<UniqueID32>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID32>())
if (IDRestorer<UniqueID32>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID32>()) if (UniqueID32 origId = restorer->newToOriginal(*this))
if (UniqueID32 origId = restorer->newToOriginal(*this)) *this = origId;
*this = origId;
} }
template <> template <>
void UniqueID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) void UniqueID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
{assign(reader.readUint32Big());} assign(reader.readUint32Big());
template <>
void UniqueID32::Enumerate<BigDNA::Write>(typename Write::StreamT& writer)
{writer.writeUint32Big(m_id);}
template <>
void UniqueID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
{
*this = UniqueIDBridge::MakePathFromString<UniqueID32>(reader.readString(nullptr));
} }
template <> template <>
void UniqueID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) void UniqueID32::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
{ writer.writeUint32Big(m_id);
if (!operator bool())
return;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path)
return;
writer.writeString(nullptr, path.getAuxInfo().size() ?
(std::string(path.getRelativePathUTF8()) + '|' + path.getAuxInfoUTF8().data()) :
path.getRelativePathUTF8());
} }
template <> template <>
void UniqueID32::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) void UniqueID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
{s += 4;} *this = UniqueIDBridge::MakePathFromString<UniqueID32>(reader.readString(nullptr));
}
template <>
void UniqueID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
if (!operator bool())
return;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path)
return;
writer.writeString(nullptr, path.getAuxInfo().size()
? (std::string(path.getRelativePathUTF8()) + '|' + path.getAuxInfoUTF8().data())
: path.getRelativePathUTF8());
}
template <>
void UniqueID32::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
s += 4;
}
std::string UniqueID32::toString() const std::string UniqueID32::toString() const {
{ char buf[9];
char buf[9]; snprintf(buf, 9, "%08X", m_id);
snprintf(buf, 9, "%08X", m_id); return std::string(buf);
return std::string(buf);
} }
template <> template <>
void UniqueID32Zero::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) void UniqueID32Zero::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
{UniqueID32::Enumerate<BigDNA::Read>(reader);} UniqueID32::Enumerate<BigDNA::Read>(reader);
}
template <> template <>
void UniqueID32Zero::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) void UniqueID32Zero::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
{writer.writeUint32Big(*this ? m_id : 0);} writer.writeUint32Big(*this ? m_id : 0);
}
template <> template <>
void UniqueID32Zero::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) void UniqueID32Zero::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
{UniqueID32::Enumerate<BigDNA::ReadYaml>(reader);} UniqueID32::Enumerate<BigDNA::ReadYaml>(reader);
}
template <> template <>
void UniqueID32Zero::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) void UniqueID32Zero::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
{UniqueID32::Enumerate<BigDNA::WriteYaml>(writer);} UniqueID32::Enumerate<BigDNA::WriteYaml>(writer);
}
template <> template <>
void UniqueID32Zero::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) void UniqueID32Zero::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
{UniqueID32::Enumerate<BigDNA::BinarySize>(s);} UniqueID32::Enumerate<BigDNA::BinarySize>(s);
AuxiliaryID32& AuxiliaryID32::operator=(const hecl::ProjectPath& path)
{
assign(path.ensureAuxInfo(m_auxStr).hash().val32());
return *this;
} }
AuxiliaryID32& AuxiliaryID32::operator=(const UniqueID32& id) AuxiliaryID32& AuxiliaryID32::operator=(const hecl::ProjectPath& path) {
{ assign(path.ensureAuxInfo(m_auxStr).hash().val32());
m_baseId = id; return *this;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
if (path)
{
if (m_addExtension)
path = path.getWithExtension(m_addExtension);
*this = path;
}
return *this;
} }
template <> AuxiliaryID32& AuxiliaryID32::operator=(const UniqueID32& id) {
void AuxiliaryID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) m_baseId = id;
{ hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
assign(reader.readUint32Big()); if (path) {
m_baseId = *this;
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::Write>(typename Write::StreamT& writer)
{
writer.writeUint32Big(m_id);
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
{
hecl::ProjectPath readPath = UniqueIDBridge::MakePathFromString<UniqueID32>(reader.readString(nullptr));
*this = readPath.ensureAuxInfo(m_auxStr);
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer)
{
if (!operator bool())
return;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath<UniqueID32>(*this, true);
if (!path)
path = UniqueIDBridge::TranslatePakIdToPath(m_baseId);
if (!path)
return;
if (m_addExtension) if (m_addExtension)
path = path.getWithExtension(m_addExtension); path = path.getWithExtension(m_addExtension);
hecl::SystemUTF8Conv ufx8AuxStr(m_auxStr); *this = path;
writer.writeString(nullptr, std::string(path.getRelativePathUTF8()) + '|' + ufx8AuxStr); }
return *this;
} }
template <>
void AuxiliaryID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
assign(reader.readUint32Big());
m_baseId = *this;
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint32Big(m_id);
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
hecl::ProjectPath readPath = UniqueIDBridge::MakePathFromString<UniqueID32>(reader.readString(nullptr));
*this = readPath.ensureAuxInfo(m_auxStr);
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
if (!operator bool())
return;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath<UniqueID32>(*this, true);
if (!path)
path = UniqueIDBridge::TranslatePakIdToPath(m_baseId);
if (!path)
return;
if (m_addExtension)
path = path.getWithExtension(m_addExtension);
hecl::SystemUTF8Conv ufx8AuxStr(m_auxStr);
writer.writeString(nullptr, std::string(path.getRelativePathUTF8()) + '|' + ufx8AuxStr);
}
/** PAK 64-bit Unique ID */ /** PAK 64-bit Unique ID */
void UniqueID64::assign(uint64_t id, bool noOriginal) void UniqueID64::assign(uint64_t id, bool noOriginal) {
{ m_id = id ? id : 0xffffffffffffffff;
m_id = id ? id : 0xffffffffffffffff; if (!noOriginal)
if (!noOriginal) if (IDRestorer<UniqueID64>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID64>())
if (IDRestorer<UniqueID64>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID64>()) if (UniqueID64 origId = restorer->newToOriginal(*this))
if (UniqueID64 origId = restorer->newToOriginal(*this)) *this = origId;
*this = origId;
} }
template <> template <>
void UniqueID64::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) void UniqueID64::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
{assign(reader.readUint64Big());} assign(reader.readUint64Big());
template <>
void UniqueID64::Enumerate<BigDNA::Write>(typename Write::StreamT& writer)
{writer.writeUint64Big(m_id);}
template <>
void UniqueID64::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
{
*this = UniqueIDBridge::MakePathFromString<UniqueID64>(reader.readString(nullptr));
} }
template <> template <>
void UniqueID64::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) void UniqueID64::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
{ writer.writeUint64Big(m_id);
if (!operator bool())
return;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path)
return;
writer.writeString(nullptr, path.getAuxInfo().size() ?
(std::string(path.getRelativePathUTF8()) + '|' + path.getAuxInfoUTF8().data()) :
path.getRelativePathUTF8());
} }
template <> template <>
void UniqueID64::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) void UniqueID64::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
{s += 8;} *this = UniqueIDBridge::MakePathFromString<UniqueID64>(reader.readString(nullptr));
}
template <>
void UniqueID64::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
if (!operator bool())
return;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path)
return;
writer.writeString(nullptr, path.getAuxInfo().size()
? (std::string(path.getRelativePathUTF8()) + '|' + path.getAuxInfoUTF8().data())
: path.getRelativePathUTF8());
}
template <>
void UniqueID64::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
s += 8;
}
std::string UniqueID64::toString() const std::string UniqueID64::toString() const {
{ char buf[17];
char buf[17]; snprintf(buf, 17, "%016" PRIX64, m_id);
snprintf(buf, 17, "%016" PRIX64, m_id); return std::string(buf);
return std::string(buf);
} }
/** PAK 128-bit Unique ID */ /** PAK 128-bit Unique ID */
template <> template <>
void UniqueID128::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) void UniqueID128::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
{ m_id.id[0] = reader.readUint64Big();
m_id.id[0] = reader.readUint64Big(); m_id.id[1] = reader.readUint64Big();
m_id.id[1] = reader.readUint64Big();
} }
template <> template <>
void UniqueID128::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) void UniqueID128::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
{ writer.writeUint64Big(m_id.id[0]);
writer.writeUint64Big(m_id.id[0]); writer.writeUint64Big(m_id.id[1]);
writer.writeUint64Big(m_id.id[1]);
} }
template <> template <>
void UniqueID128::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) void UniqueID128::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
{ *this = UniqueIDBridge::MakePathFromString<UniqueID128>(reader.readString(nullptr));
*this = UniqueIDBridge::MakePathFromString<UniqueID128>(reader.readString(nullptr));
} }
template <> template <>
void UniqueID128::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) void UniqueID128::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
{ if (!operator bool())
if (!operator bool()) return;
return; hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); if (!path)
if (!path) return;
return; writer.writeString(nullptr, path.getAuxInfo().size()
writer.writeString(nullptr, path.getAuxInfo().size() ? ? (std::string(path.getRelativePathUTF8()) + '|' + path.getAuxInfoUTF8().data())
(std::string(path.getRelativePathUTF8()) + '|' + path.getAuxInfoUTF8().data()) : : path.getRelativePathUTF8());
path.getRelativePathUTF8());
} }
template <> template <>
void UniqueID128::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) void UniqueID128::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
{s += 16;} s += 16;
std::string UniqueID128::toString() const
{
char buf[33];
snprintf(buf, 33, "%016" PRIX64 "%016" PRIX64, m_id.id[0], m_id.id[1]);
return std::string(buf);
} }
std::string UniqueID128::toString() const {
char buf[33];
snprintf(buf, 33, "%016" PRIX64 "%016" PRIX64, m_id.id[0], m_id.id[1]);
return std::string(buf);
}
/** Word Bitmap reader/writer */ /** Word Bitmap reader/writer */
void WordBitmap::read(athena::io::IStreamReader& reader, size_t bitCount) void WordBitmap::read(athena::io::IStreamReader& reader, size_t bitCount) {
{ m_bitCount = bitCount;
m_bitCount = bitCount; size_t wordCount = (bitCount + 31) / 32;
size_t wordCount = (bitCount + 31) / 32; m_words.clear();
m_words.clear(); m_words.reserve(wordCount);
m_words.reserve(wordCount); for (size_t w = 0; w < wordCount; ++w)
for (size_t w=0 ; w<wordCount ; ++w) m_words.push_back(reader.readUint32Big());
m_words.push_back(reader.readUint32Big());
} }
void WordBitmap::write(athena::io::IStreamWriter& writer) const void WordBitmap::write(athena::io::IStreamWriter& writer) const {
{ for (atUint32 word : m_words)
for (atUint32 word : m_words) writer.writeUint32Big(word);
writer.writeUint32Big(word);
}
void WordBitmap::binarySize(size_t& __isz) const
{
__isz += m_words.size() * 4;
} }
void WordBitmap::binarySize(size_t& __isz) const { __isz += m_words.size() * 4; }
} } // namespace DataSpec

View File

@ -8,8 +8,7 @@
#include "boo/ThreadLocalPtr.hpp" #include "boo/ThreadLocalPtr.hpp"
#include "zeus/CColor.hpp" #include "zeus/CColor.hpp"
namespace DataSpec namespace DataSpec {
{
struct SpecBase; struct SpecBase;
extern logvisor::Module LogDNACommon; extern logvisor::Module LogDNACommon;
@ -25,43 +24,46 @@ typedef athena::io::DNAVYaml<athena::Big> BigDNAVYaml;
/** FourCC with DNA read/write */ /** FourCC with DNA read/write */
using DNAFourCC = hecl::DNAFourCC; using DNAFourCC = hecl::DNAFourCC;
class DNAColor final : public BigDNA, public zeus::CColor class DNAColor final : public BigDNA, public zeus::CColor {
{
public: public:
DNAColor() = default; DNAColor() = default;
DNAColor(const zeus::CColor& color) : zeus::CColor(color) {} DNAColor(const zeus::CColor& color) : zeus::CColor(color) {}
AT_DECL_EXPLICIT_DNA_YAML AT_DECL_EXPLICIT_DNA_YAML
}; };
template <> inline void DNAColor::Enumerate<BigDNA::Read>(typename Read::StreamT& _r) template <>
{ zeus::CColor::readRGBABig(_r); } inline void DNAColor::Enumerate<BigDNA::Read>(typename Read::StreamT& _r) {
template <> inline void DNAColor::Enumerate<BigDNA::Write>(typename Write::StreamT& _w) zeus::CColor::readRGBABig(_r);
{ zeus::CColor::writeRGBABig(_w); }
template <> inline void DNAColor::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& _r)
{
size_t count;
if (auto v = _r.enterSubVector(nullptr, count))
{
zeus::simd_floats f;
f[0] = (count >= 1) ? _r.readFloat(nullptr) : 0.f;
f[1] = (count >= 2) ? _r.readFloat(nullptr) : 0.f;
f[2] = (count >= 3) ? _r.readFloat(nullptr) : 0.f;
f[3] = (count >= 4) ? _r.readFloat(nullptr) : 0.f;
mSimd.copy_from(f);
}
} }
template <> inline void DNAColor::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& _w) template <>
{ inline void DNAColor::Enumerate<BigDNA::Write>(typename Write::StreamT& _w) {
if (auto v = _w.enterSubVector(nullptr)) zeus::CColor::writeRGBABig(_w);
{ }
zeus::simd_floats f(mSimd); template <>
_w.writeFloat(nullptr, f[0]); inline void DNAColor::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& _r) {
_w.writeFloat(nullptr, f[1]); size_t count;
_w.writeFloat(nullptr, f[2]); if (auto v = _r.enterSubVector(nullptr, count)) {
_w.writeFloat(nullptr, f[3]); zeus::simd_floats f;
} f[0] = (count >= 1) ? _r.readFloat(nullptr) : 0.f;
f[1] = (count >= 2) ? _r.readFloat(nullptr) : 0.f;
f[2] = (count >= 3) ? _r.readFloat(nullptr) : 0.f;
f[3] = (count >= 4) ? _r.readFloat(nullptr) : 0.f;
mSimd.copy_from(f);
}
}
template <>
inline void DNAColor::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& _w) {
if (auto v = _w.enterSubVector(nullptr)) {
zeus::simd_floats f(mSimd);
_w.writeFloat(nullptr, f[0]);
_w.writeFloat(nullptr, f[1]);
_w.writeFloat(nullptr, f[2]);
_w.writeFloat(nullptr, f[3]);
}
}
template <>
inline void DNAColor::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& _s) {
_s += 16;
} }
template <> inline void DNAColor::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& _s)
{ _s += 16; }
using FourCC = hecl::FourCC; using FourCC = hecl::FourCC;
class UniqueID32; class UniqueID32;
@ -69,277 +71,266 @@ class UniqueID64;
class UniqueID128; class UniqueID128;
/** Common virtual interface for runtime ambiguity resolution */ /** Common virtual interface for runtime ambiguity resolution */
class PAKRouterBase class PAKRouterBase {
{
protected: protected:
const SpecBase& m_dataSpec; const SpecBase& m_dataSpec;
public: public:
PAKRouterBase(const SpecBase& dataSpec) : m_dataSpec(dataSpec) {} PAKRouterBase(const SpecBase& dataSpec) : m_dataSpec(dataSpec) {}
hecl::Database::Project& getProject() const {return m_dataSpec.getProject();} hecl::Database::Project& getProject() const { return m_dataSpec.getProject(); }
virtual hecl::ProjectPath getWorking(const UniqueID32&, bool silenceWarnings=false) const virtual hecl::ProjectPath getWorking(const UniqueID32&, bool silenceWarnings = false) const {
{ LogDNACommon.report(logvisor::Fatal, "PAKRouter IDType mismatch; expected UniqueID32 specialization");
LogDNACommon.report(logvisor::Fatal, return hecl::ProjectPath();
"PAKRouter IDType mismatch; expected UniqueID32 specialization"); }
return hecl::ProjectPath(); virtual hecl::ProjectPath getWorking(const UniqueID64&, bool silenceWarnings = false) const {
} LogDNACommon.report(logvisor::Fatal, "PAKRouter IDType mismatch; expected UniqueID64 specialization");
virtual hecl::ProjectPath getWorking(const UniqueID64&, bool silenceWarnings=false) const return hecl::ProjectPath();
{ }
LogDNACommon.report(logvisor::Fatal, virtual hecl::ProjectPath getWorking(const UniqueID128&, bool silenceWarnings = false) const {
"PAKRouter IDType mismatch; expected UniqueID64 specialization"); LogDNACommon.report(logvisor::Fatal, "PAKRouter IDType mismatch; expected UniqueID128 specialization");
return hecl::ProjectPath(); return hecl::ProjectPath();
} }
virtual hecl::ProjectPath getWorking(const UniqueID128&, bool silenceWarnings=false) const
{
LogDNACommon.report(logvisor::Fatal,
"PAKRouter IDType mismatch; expected UniqueID128 specialization");
return hecl::ProjectPath();
}
}; };
/** Globally-accessed manager allowing UniqueID* classes to directly /** Globally-accessed manager allowing UniqueID* classes to directly
* lookup destination paths of resources */ * lookup destination paths of resources */
class UniqueIDBridge class UniqueIDBridge {
{ friend class UniqueID32;
friend class UniqueID32; friend class UniqueID64;
friend class UniqueID64;
static ThreadLocalPtr<hecl::Database::Project> s_Project;
static ThreadLocalPtr<IDRestorer<UniqueID32>> s_restorer32;
static ThreadLocalPtr<IDRestorer<UniqueID64>> s_restorer64;
static ThreadLocalPtr<IDRestorer<UniqueID128>> s_restorer128;
static ThreadLocalPtr<hecl::Database::Project> s_Project;
static ThreadLocalPtr<IDRestorer<UniqueID32>> s_restorer32;
static ThreadLocalPtr<IDRestorer<UniqueID64>> s_restorer64;
static ThreadLocalPtr<IDRestorer<UniqueID128>> s_restorer128;
public: public:
template <class IDType> template <class IDType>
static hecl::ProjectPath TranslatePakIdToPath(const IDType& id, bool silenceWarnings=false); static hecl::ProjectPath TranslatePakIdToPath(const IDType& id, bool silenceWarnings = false);
template <class IDType> template <class IDType>
static hecl::ProjectPath MakePathFromString(std::string_view str); static hecl::ProjectPath MakePathFromString(std::string_view str);
template <class IDType> template <class IDType>
static void TransformOldHashToNewHash(IDType& id); static void TransformOldHashToNewHash(IDType& id);
static void SetThreadProject(hecl::Database::Project& project); static void SetThreadProject(hecl::Database::Project& project);
template <class IDType> template <class IDType>
static IDRestorer<IDType>* GetIDRestorer(); static IDRestorer<IDType>* GetIDRestorer();
template <class IDType> template <class IDType>
static void SetIDRestorer(IDRestorer<IDType>* restorer); static void SetIDRestorer(IDRestorer<IDType>* restorer);
}; };
template <> template <>
inline IDRestorer<UniqueID32>* UniqueIDBridge::GetIDRestorer<UniqueID32>() inline IDRestorer<UniqueID32>* UniqueIDBridge::GetIDRestorer<UniqueID32>() {
{ return s_restorer32.get();
return s_restorer32.get();
} }
template <> template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID32>(IDRestorer<UniqueID32>* restorer) inline void UniqueIDBridge::SetIDRestorer<UniqueID32>(IDRestorer<UniqueID32>* restorer) {
{ s_restorer32.reset(restorer);
s_restorer32.reset(restorer);
} }
template <> template <>
inline IDRestorer<UniqueID64>* UniqueIDBridge::GetIDRestorer<UniqueID64>() inline IDRestorer<UniqueID64>* UniqueIDBridge::GetIDRestorer<UniqueID64>() {
{ return s_restorer64.get();
return s_restorer64.get();
} }
template <> template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID64>(IDRestorer<UniqueID64>* restorer) inline void UniqueIDBridge::SetIDRestorer<UniqueID64>(IDRestorer<UniqueID64>* restorer) {
{ s_restorer64.reset(restorer);
s_restorer64.reset(restorer);
} }
template <> template <>
inline IDRestorer<UniqueID128>* UniqueIDBridge::GetIDRestorer<UniqueID128>() inline IDRestorer<UniqueID128>* UniqueIDBridge::GetIDRestorer<UniqueID128>() {
{ return s_restorer128.get();
return s_restorer128.get();
} }
template <> template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID128>(IDRestorer<UniqueID128>* restorer) inline void UniqueIDBridge::SetIDRestorer<UniqueID128>(IDRestorer<UniqueID128>* restorer) {
{ s_restorer128.reset(restorer);
s_restorer128.reset(restorer);
} }
/** PAK 32-bit Unique ID */ /** PAK 32-bit Unique ID */
class UniqueID32 : public BigDNA class UniqueID32 : public BigDNA {
{
protected: protected:
uint32_t m_id = 0xffffffff; uint32_t m_id = 0xffffffff;
public: public:
using value_type = uint32_t; using value_type = uint32_t;
static UniqueID32 kInvalidId; static UniqueID32 kInvalidId;
AT_DECL_EXPLICIT_DNA_YAML AT_DECL_EXPLICIT_DNA_YAML
operator bool() const {return m_id != 0xffffffff && m_id != 0;} operator bool() const { return m_id != 0xffffffff && m_id != 0; }
void assign(uint32_t id, bool noOriginal = false); void assign(uint32_t id, bool noOriginal = false);
UniqueID32& operator=(const hecl::ProjectPath& path) UniqueID32& operator=(const hecl::ProjectPath& path) {
{assign(path.hash().val32()); return *this;} assign(path.hash().val32());
return *this;
}
bool operator!=(const UniqueID32& other) const {return m_id != other.m_id;} bool operator!=(const UniqueID32& other) const { return m_id != other.m_id; }
bool operator==(const UniqueID32& other) const {return m_id == other.m_id;} bool operator==(const UniqueID32& other) const { return m_id == other.m_id; }
bool operator<(const UniqueID32& other) const {return m_id < other.m_id;} bool operator<(const UniqueID32& other) const { return m_id < other.m_id; }
uint32_t toUint32() const {return m_id;} uint32_t toUint32() const { return m_id; }
uint64_t toUint64() const {return m_id;} uint64_t toUint64() const { return m_id; }
std::string toString() const; std::string toString() const;
void clear() {m_id = 0xffffffff;} void clear() { m_id = 0xffffffff; }
UniqueID32() = default; UniqueID32() = default;
UniqueID32(uint32_t idin, bool noOriginal = false) {assign(idin, noOriginal);} UniqueID32(uint32_t idin, bool noOriginal = false) { assign(idin, noOriginal); }
UniqueID32(athena::io::IStreamReader& reader) {read(reader);} UniqueID32(athena::io::IStreamReader& reader) { read(reader); }
UniqueID32(const hecl::ProjectPath& path) {*this = path;} UniqueID32(const hecl::ProjectPath& path) { *this = path; }
UniqueID32(const char* hexStr) UniqueID32(const char* hexStr) {
{ char copy[9];
char copy[9]; strncpy(copy, hexStr, 8);
strncpy(copy, hexStr, 8); copy[8] = '\0';
copy[8] = '\0'; assign(strtoul(copy, nullptr, 16));
assign(strtoul(copy, nullptr, 16)); }
} UniqueID32(const wchar_t* hexStr) {
UniqueID32(const wchar_t* hexStr) wchar_t copy[9];
{ wcsncpy(copy, hexStr, 8);
wchar_t copy[9]; copy[8] = L'\0';
wcsncpy(copy, hexStr, 8); assign(wcstoul(copy, nullptr, 16));
copy[8] = L'\0'; }
assign(wcstoul(copy, nullptr, 16));
}
static constexpr size_t BinarySize() {return 4;} static constexpr size_t BinarySize() { return 4; }
}; };
/** PAK 32-bit Unique ID - writes zero when invalid */ /** PAK 32-bit Unique ID - writes zero when invalid */
class UniqueID32Zero : public UniqueID32 class UniqueID32Zero : public UniqueID32 {
{
public: public:
AT_DECL_DNA_YAML AT_DECL_DNA_YAML
Delete __d2; Delete __d2;
using UniqueID32::UniqueID32; using UniqueID32::UniqueID32;
}; };
class AuxiliaryID32 : public UniqueID32 class AuxiliaryID32 : public UniqueID32 {
{ const hecl::SystemChar* m_auxStr;
const hecl::SystemChar* m_auxStr; const hecl::SystemChar* m_addExtension;
const hecl::SystemChar* m_addExtension; UniqueID32 m_baseId;
UniqueID32 m_baseId;
public:
AT_DECL_DNA
Delete __d2;
AuxiliaryID32(const hecl::SystemChar* auxStr,
const hecl::SystemChar* addExtension=nullptr)
: m_auxStr(auxStr), m_addExtension(addExtension) {}
AuxiliaryID32& operator=(const hecl::ProjectPath& path); public:
AuxiliaryID32& operator=(const UniqueID32& id); AT_DECL_DNA
const UniqueID32& getBaseId() const {return m_baseId;} Delete __d2;
AuxiliaryID32(const hecl::SystemChar* auxStr, const hecl::SystemChar* addExtension = nullptr)
: m_auxStr(auxStr), m_addExtension(addExtension) {}
AuxiliaryID32& operator=(const hecl::ProjectPath& path);
AuxiliaryID32& operator=(const UniqueID32& id);
const UniqueID32& getBaseId() const { return m_baseId; }
}; };
/** PAK 64-bit Unique ID */ /** PAK 64-bit Unique ID */
class UniqueID64 : public BigDNA class UniqueID64 : public BigDNA {
{ uint64_t m_id = 0xffffffffffffffff;
uint64_t m_id = 0xffffffffffffffff;
public: public:
using value_type = uint64_t; using value_type = uint64_t;
AT_DECL_EXPLICIT_DNA_YAML AT_DECL_EXPLICIT_DNA_YAML
operator bool() const {return m_id != 0xffffffffffffffff && m_id != 0;} operator bool() const { return m_id != 0xffffffffffffffff && m_id != 0; }
void assign(uint64_t id, bool noOriginal = false); void assign(uint64_t id, bool noOriginal = false);
UniqueID64& operator=(const hecl::ProjectPath& path) UniqueID64& operator=(const hecl::ProjectPath& path) {
{assign(path.hash().val64()); return *this;} assign(path.hash().val64());
return *this;
}
bool operator!=(const UniqueID64& other) const {return m_id != other.m_id;} bool operator!=(const UniqueID64& other) const { return m_id != other.m_id; }
bool operator==(const UniqueID64& other) const {return m_id == other.m_id;} bool operator==(const UniqueID64& other) const { return m_id == other.m_id; }
bool operator<(const UniqueID64& other) const {return m_id < other.m_id;} bool operator<(const UniqueID64& other) const { return m_id < other.m_id; }
uint64_t toUint64() const {return m_id;} uint64_t toUint64() const { return m_id; }
std::string toString() const; std::string toString() const;
void clear() {m_id = 0xffffffffffffffff;} void clear() { m_id = 0xffffffffffffffff; }
UniqueID64() = default; UniqueID64() = default;
UniqueID64(uint64_t idin, bool noOriginal = false) {assign(idin, noOriginal);} UniqueID64(uint64_t idin, bool noOriginal = false) { assign(idin, noOriginal); }
UniqueID64(athena::io::IStreamReader& reader) {read(reader);} UniqueID64(athena::io::IStreamReader& reader) { read(reader); }
UniqueID64(const hecl::ProjectPath& path) {*this = path;} UniqueID64(const hecl::ProjectPath& path) { *this = path; }
UniqueID64(const char* hexStr) UniqueID64(const char* hexStr) {
{ char copy[17];
char copy[17]; strncpy(copy, hexStr, 16);
strncpy(copy, hexStr, 16); copy[16] = '\0';
copy[16] = '\0';
#if _WIN32 #if _WIN32
assign(_strtoui64(copy, nullptr, 16)); assign(_strtoui64(copy, nullptr, 16));
#else #else
assign(strtouq(copy, nullptr, 16)); assign(strtouq(copy, nullptr, 16));
#endif #endif
} }
UniqueID64(const wchar_t* hexStr) UniqueID64(const wchar_t* hexStr) {
{ wchar_t copy[17];
wchar_t copy[17]; wcsncpy(copy, hexStr, 16);
wcsncpy(copy, hexStr, 16); copy[16] = L'\0';
copy[16] = L'\0';
#if _WIN32 #if _WIN32
assign(_wcstoui64(copy, nullptr, 16)); assign(_wcstoui64(copy, nullptr, 16));
#else #else
assign(wcstoull(copy, nullptr, 16)); assign(wcstoull(copy, nullptr, 16));
#endif #endif
} }
static constexpr size_t BinarySize() {return 8;} static constexpr size_t BinarySize() { return 8; }
}; };
/** PAK 128-bit Unique ID */ /** PAK 128-bit Unique ID */
class UniqueID128 : public BigDNA class UniqueID128 : public BigDNA {
{
public: public:
union Value union Value {
{ uint64_t id[2];
uint64_t id[2];
#if __SSE__ #if __SSE__
__m128i id128; __m128i id128;
#endif #endif
}; };
private: private:
Value m_id; Value m_id;
public: public:
using value_type = uint64_t; using value_type = uint64_t;
AT_DECL_EXPLICIT_DNA_YAML AT_DECL_EXPLICIT_DNA_YAML
UniqueID128() {m_id.id[0]=0xffffffffffffffff; m_id.id[1]=0xffffffffffffffff;} UniqueID128() {
UniqueID128(uint64_t idin, bool noOriginal = false) m_id.id[0] = 0xffffffffffffffff;
{ m_id.id[1] = 0xffffffffffffffff;
m_id.id[0] = idin; }
m_id.id[1] = 0; UniqueID128(uint64_t idin, bool noOriginal = false) {
} m_id.id[0] = idin;
operator bool() const m_id.id[1] = 0;
{return m_id.id[0] != 0xffffffffffffffff && m_id.id[0] != 0 && m_id.id[1] != 0xffffffffffffffff && m_id.id[1] != 0;} }
operator bool() const {
return m_id.id[0] != 0xffffffffffffffff && m_id.id[0] != 0 && m_id.id[1] != 0xffffffffffffffff && m_id.id[1] != 0;
}
UniqueID128& operator=(const hecl::ProjectPath& path) UniqueID128& operator=(const hecl::ProjectPath& path) {
{ m_id.id[0] = path.hash().val64();
m_id.id[0] = path.hash().val64(); m_id.id[1] = 0;
m_id.id[1] = 0; return *this;
return *this; }
} UniqueID128(const hecl::ProjectPath& path) { *this = path; }
UniqueID128(const hecl::ProjectPath& path) {*this = path;}
bool operator!=(const UniqueID128& other) const bool operator!=(const UniqueID128& other) const {
{
#if __SSE__ #if __SSE__
__m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128); __m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128);
int vmask = _mm_movemask_epi8(vcmp); int vmask = _mm_movemask_epi8(vcmp);
return vmask != 0xffff; return vmask != 0xffff;
#else #else
return (m_id.id[0] != other.m_id.id[0]) || (m_id.id[1] != other.m_id.id[1]); return (m_id.id[0] != other.m_id.id[0]) || (m_id.id[1] != other.m_id.id[1]);
#endif #endif
} }
bool operator==(const UniqueID128& other) const bool operator==(const UniqueID128& other) const {
{
#if __SSE__ #if __SSE__
__m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128); __m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128);
int vmask = _mm_movemask_epi8(vcmp); int vmask = _mm_movemask_epi8(vcmp);
return vmask == 0xffff; return vmask == 0xffff;
#else #else
return (m_id.id[0] == other.m_id.id[0]) && (m_id.id[1] == other.m_id.id[1]); return (m_id.id[0] == other.m_id.id[0]) && (m_id.id[1] == other.m_id.id[1]);
#endif #endif
} }
void clear() {m_id.id[0] = 0xffffffffffffffff; m_id.id[1] = 0xffffffffffffffff;} void clear() {
uint64_t toUint64() const {return m_id.id[0];} m_id.id[0] = 0xffffffffffffffff;
uint64_t toHighUint64() const {return m_id.id[0];} m_id.id[1] = 0xffffffffffffffff;
uint64_t toLowUint64() const {return m_id.id[1];} }
std::string toString() const; uint64_t toUint64() const { return m_id.id[0]; }
uint64_t toHighUint64() const { return m_id.id[0]; }
uint64_t toLowUint64() const { return m_id.id[1]; }
std::string toString() const;
static constexpr size_t BinarySize() {return 16;} static constexpr size_t BinarySize() { return 16; }
}; };
/** Casts ID type to its null-zero equivalent */ /** Casts ID type to its null-zero equivalent */
@ -347,63 +338,66 @@ template <class T>
using CastIDToZero = typename std::conditional_t<std::is_same_v<T, UniqueID32>, UniqueID32Zero, T>; using CastIDToZero = typename std::conditional_t<std::is_same_v<T, UniqueID32>, UniqueID32Zero, T>;
/** Word Bitmap reader/writer */ /** Word Bitmap reader/writer */
class WordBitmap class WordBitmap {
{ std::vector<atUint32> m_words;
std::vector<atUint32> m_words; size_t m_bitCount = 0;
size_t m_bitCount = 0;
public: public:
void read(athena::io::IStreamReader& reader, size_t bitCount); void read(athena::io::IStreamReader& reader, size_t bitCount);
void write(athena::io::IStreamWriter& writer) const; void write(athena::io::IStreamWriter& writer) const;
void reserve(size_t bitCount) { m_words.reserve((bitCount + 31) / 32); } void reserve(size_t bitCount) { m_words.reserve((bitCount + 31) / 32); }
void binarySize(size_t& __isz) const; void binarySize(size_t& __isz) const;
size_t getBitCount() const {return m_bitCount;} size_t getBitCount() const { return m_bitCount; }
bool getBit(size_t idx) const bool getBit(size_t idx) const {
{ size_t wordIdx = idx / 32;
size_t wordIdx = idx / 32; if (wordIdx >= m_words.size())
if (wordIdx >= m_words.size()) return false;
return false; size_t wordCur = idx % 32;
size_t wordCur = idx % 32; return (m_words[wordIdx] >> wordCur) & 0x1;
return (m_words[wordIdx] >> wordCur) & 0x1; }
} void setBit(size_t idx) {
void setBit(size_t idx) size_t wordIdx = idx / 32;
{ while (wordIdx >= m_words.size())
size_t wordIdx = idx / 32; m_words.push_back(0);
while (wordIdx >= m_words.size()) size_t wordCur = idx % 32;
m_words.push_back(0); m_words[wordIdx] |= (1 << wordCur);
size_t wordCur = idx % 32; m_bitCount = std::max(m_bitCount, idx + 1);
m_words[wordIdx] |= (1 << wordCur); }
m_bitCount = std::max(m_bitCount, idx + 1); void unsetBit(size_t idx) {
} size_t wordIdx = idx / 32;
void unsetBit(size_t idx) while (wordIdx >= m_words.size())
{ m_words.push_back(0);
size_t wordIdx = idx / 32; size_t wordCur = idx % 32;
while (wordIdx >= m_words.size()) m_words[wordIdx] &= ~(1 << wordCur);
m_words.push_back(0); m_bitCount = std::max(m_bitCount, idx + 1);
size_t wordCur = idx % 32; }
m_words[wordIdx] &= ~(1 << wordCur); void clear() {
m_bitCount = std::max(m_bitCount, idx + 1); m_words.clear();
} m_bitCount = 0;
void clear() { m_words.clear(); m_bitCount = 0; } }
class Iterator class Iterator {
{ friend class WordBitmap;
friend class WordBitmap; const WordBitmap& m_bmp;
const WordBitmap& m_bmp; size_t m_idx = 0;
size_t m_idx = 0; Iterator(const WordBitmap& bmp, size_t idx) : m_bmp(bmp), m_idx(idx) {}
Iterator(const WordBitmap& bmp, size_t idx) : m_bmp(bmp), m_idx(idx) {}
public:
using iterator_category = std::forward_iterator_tag;
using value_type = bool;
using difference_type = std::ptrdiff_t;
using pointer = bool*;
using reference = bool&;
Iterator& operator++() {++m_idx; return *this;} public:
bool operator*() {return m_bmp.getBit(m_idx);} using iterator_category = std::forward_iterator_tag;
bool operator!=(const Iterator& other) const {return m_idx != other.m_idx;} using value_type = bool;
}; using difference_type = std::ptrdiff_t;
Iterator begin() const {return Iterator(*this, 0);} using pointer = bool*;
Iterator end() const {return Iterator(*this, m_bitCount);} using reference = bool&;
Iterator& operator++() {
++m_idx;
return *this;
}
bool operator*() { return m_bmp.getBit(m_idx); }
bool operator!=(const Iterator& other) const { return m_idx != other.m_idx; }
};
Iterator begin() const { return Iterator(*this, 0); }
Iterator end() const { return Iterator(*this, m_bitCount); }
}; };
/** Resource cooker function */ /** Resource cooker function */
@ -411,60 +405,47 @@ typedef std::function<bool(const hecl::ProjectPath&, const hecl::ProjectPath&)>
/** Mappings of resources involved in extracting characters */ /** Mappings of resources involved in extracting characters */
template <class IDType> template <class IDType>
struct CharacterAssociations struct CharacterAssociations {
{ using RigPair = std::pair<IDType, IDType>;
using RigPair = std::pair<IDType, IDType>; /* CMDL -> (CSKR, CINF) */
/* CMDL -> (CSKR, CINF) */ std::unordered_map<IDType, RigPair> m_cmdlRigs;
std::unordered_map<IDType, RigPair> m_cmdlRigs; /* (CSKR, CINF) -> ANCS */
/* (CSKR, CINF) -> ANCS */ std::unordered_map<IDType, std::pair<IDType, std::string>> m_cskrCinfToCharacter;
std::unordered_map<IDType, std::pair<IDType, std::string>> m_cskrCinfToCharacter; /* ANCS -> (CINF, CMDL) */
/* ANCS -> (CINF, CMDL) */ std::unordered_multimap<IDType, std::pair<RigPair, std::string>> m_characterToAttachmentRigs;
std::unordered_multimap<IDType, std::pair<RigPair, std::string>> m_characterToAttachmentRigs; using MultimapIteratorPair =
using MultimapIteratorPair = std::pair< std::pair<typename std::unordered_multimap<IDType, std::pair<RigPair, std::string>>::const_iterator,
typename std::unordered_multimap<IDType, std::pair<RigPair, std::string>>::const_iterator, typename std::unordered_multimap<IDType, std::pair<RigPair, std::string>>::const_iterator>;
typename std::unordered_multimap<IDType, std::pair<RigPair, std::string>>::const_iterator>; void addAttachmentRig(IDType character, IDType cinf, IDType cmdl, const char* name) {
void addAttachmentRig(IDType character, IDType cinf, IDType cmdl, const char* name) auto range = m_characterToAttachmentRigs.equal_range(character);
{ for (auto it = range.first; it != range.second; ++it)
auto range = m_characterToAttachmentRigs.equal_range(character); if (it->second.second == name)
for (auto it = range.first; it != range.second; ++it) return;
if (it->second.second == name) m_characterToAttachmentRigs.insert(std::make_pair(character, std::make_pair(std::make_pair(cinf, cmdl), name)));
return; }
m_characterToAttachmentRigs.insert(
std::make_pair(character, std::make_pair(std::make_pair(cinf, cmdl), name)));
}
}; };
} } // namespace DataSpec
/* Hash template-specializations for UniqueID types */ /* Hash template-specializations for UniqueID types */
namespace std namespace std {
{ template <>
template<> struct hash<DataSpec::DNAFourCC> {
struct hash<DataSpec::DNAFourCC> size_t operator()(const DataSpec::DNAFourCC& fcc) const { return fcc.toUint32(); }
{
size_t operator()(const DataSpec::DNAFourCC& fcc) const
{return fcc.toUint32();}
}; };
template<> template <>
struct hash<DataSpec::UniqueID32> struct hash<DataSpec::UniqueID32> {
{ size_t operator()(const DataSpec::UniqueID32& id) const { return id.toUint32(); }
size_t operator()(const DataSpec::UniqueID32& id) const
{return id.toUint32();}
}; };
template<> template <>
struct hash<DataSpec::UniqueID64> struct hash<DataSpec::UniqueID64> {
{ size_t operator()(const DataSpec::UniqueID64& id) const { return id.toUint64(); }
size_t operator()(const DataSpec::UniqueID64& id) const
{return id.toUint64();}
}; };
template<> template <>
struct hash<DataSpec::UniqueID128> struct hash<DataSpec::UniqueID128> {
{ size_t operator()(const DataSpec::UniqueID128& id) const { return id.toHighUint64() ^ id.toLowUint64(); }
size_t operator()(const DataSpec::UniqueID128& id) const
{return id.toHighUint64() ^ id.toLowUint64();}
}; };
} } // namespace std

View File

@ -1,418 +1,377 @@
#include "DPSC.hpp" #include "DPSC.hpp"
namespace DataSpec::DNAParticle namespace DataSpec::DNAParticle {
{
template <> template <>
const char* DPSM<UniqueID32>::DNAType() { return "DPSM<UniqueID32>"; } const char* DPSM<UniqueID32>::DNAType() {
return "DPSM<UniqueID32>";
}
template <> template <>
const char* DPSM<UniqueID64>::DNAType() { return "DPSM<UniqueID64>"; } const char* DPSM<UniqueID64>::DNAType() {
return "DPSM<UniqueID64>";
template <class IDType>
void DPSM<IDType>::_read(athena::io::YAMLDocReader& r)
{
for (const auto& elem : r.getCurNode()->m_mapChildren)
{
if (elem.first.size() < 4)
{
LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str());
continue;
}
if (auto rec = r.enterSubRecord(elem.first.c_str()))
{
bool loadFirstDesc = false;
uint32_t clsId = *reinterpret_cast<const uint32_t*>(elem.first.c_str());
switch(clsId)
{
case SBIG('1SZE'):
case SBIG('1LFT'):
case SBIG('1ROT'):
case SBIG('1OFF'):
case SBIG('1CLR'):
case SBIG('1TEX'):
case SBIG('1ADD'):
loadFirstDesc = true;
case SBIG('2SZE'):
case SBIG('2LFT'):
case SBIG('2ROT'):
case SBIG('2OFF'):
case SBIG('2CLR'):
case SBIG('2TEX'):
case SBIG('2ADD'):
if (loadFirstDesc)
readQuadDecalInfo(r, clsId, x0_quad);
else
readQuadDecalInfo(r, clsId, x1c_quad);
break;
case SBIG('DMDL'):
x38_DMDL.read(r);
break;
case SBIG('DLFT'):
x48_DLFT.read(r);
break;
case SBIG('DMOP'):
x4c_DMOP.read(r);
break;
case SBIG('DMRT'):
x50_DMRT.read(r);
break;
case SBIG('DMSC'):
x54_DMSC.read(r);
break;
case SBIG('DMCL'):
x58_DMCL.read(r);
break;
case SBIG('DMAB'):
x5c_24_DMAB = r.readBool(nullptr);
break;
case SBIG('DMOO'):
x5c_25_DMOO = r.readBool(nullptr);
break;
}
}
}
} }
template <class IDType> template <class IDType>
void DPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const void DPSM<IDType>::_read(athena::io::YAMLDocReader& r) {
{ for (const auto& elem : r.getCurNode()->m_mapChildren) {
writeQuadDecalInfo(w, x0_quad, true); if (elem.first.size() < 4) {
writeQuadDecalInfo(w, x1c_quad, false); LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str());
continue;
}
if (x38_DMDL) if (auto rec = r.enterSubRecord(elem.first.c_str())) {
if (auto rec = w.enterSubRecord("DMDL")) bool loadFirstDesc = false;
x38_DMDL.write(w); uint32_t clsId = *reinterpret_cast<const uint32_t*>(elem.first.c_str());
if (x48_DLFT) switch (clsId) {
if (auto rec = w.enterSubRecord("DLFT")) case SBIG('1SZE'):
x48_DLFT.write(w); case SBIG('1LFT'):
if (x4c_DMOP) case SBIG('1ROT'):
if (auto rec = w.enterSubRecord("DMOP")) case SBIG('1OFF'):
x4c_DMOP.write(w); case SBIG('1CLR'):
if (x50_DMRT) case SBIG('1TEX'):
if (auto rec = w.enterSubRecord("DMRT")) case SBIG('1ADD'):
x50_DMRT.write(w); loadFirstDesc = true;
if (x54_DMSC) case SBIG('2SZE'):
if (auto rec = w.enterSubRecord("DMSC")) case SBIG('2LFT'):
x54_DMSC.write(w); case SBIG('2ROT'):
if (x58_DMCL) case SBIG('2OFF'):
if (auto rec = w.enterSubRecord("DMCL")) case SBIG('2CLR'):
x54_DMSC.write(w); case SBIG('2TEX'):
case SBIG('2ADD'):
if (loadFirstDesc)
readQuadDecalInfo(r, clsId, x0_quad);
else
readQuadDecalInfo(r, clsId, x1c_quad);
break;
case SBIG('DMDL'):
x38_DMDL.read(r);
break;
case SBIG('DLFT'):
x48_DLFT.read(r);
break;
case SBIG('DMOP'):
x4c_DMOP.read(r);
break;
case SBIG('DMRT'):
x50_DMRT.read(r);
break;
case SBIG('DMSC'):
x54_DMSC.read(r);
break;
case SBIG('DMCL'):
x58_DMCL.read(r);
break;
case SBIG('DMAB'):
x5c_24_DMAB = r.readBool(nullptr);
break;
case SBIG('DMOO'):
x5c_25_DMOO = r.readBool(nullptr);
break;
}
}
}
}
if (x5c_24_DMAB) template <class IDType>
w.writeBool("DMAB", x5c_24_DMAB); void DPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const {
if (x5c_25_DMOO) writeQuadDecalInfo(w, x0_quad, true);
w.writeBool("DMOO", x5c_25_DMOO); writeQuadDecalInfo(w, x1c_quad, false);
if (x38_DMDL)
if (auto rec = w.enterSubRecord("DMDL"))
x38_DMDL.write(w);
if (x48_DLFT)
if (auto rec = w.enterSubRecord("DLFT"))
x48_DLFT.write(w);
if (x4c_DMOP)
if (auto rec = w.enterSubRecord("DMOP"))
x4c_DMOP.write(w);
if (x50_DMRT)
if (auto rec = w.enterSubRecord("DMRT"))
x50_DMRT.write(w);
if (x54_DMSC)
if (auto rec = w.enterSubRecord("DMSC"))
x54_DMSC.write(w);
if (x58_DMCL)
if (auto rec = w.enterSubRecord("DMCL"))
x54_DMSC.write(w);
if (x5c_24_DMAB)
w.writeBool("DMAB", x5c_24_DMAB);
if (x5c_25_DMOO)
w.writeBool("DMOO", x5c_25_DMOO);
} }
template <class IDType> template <class IDType>
template <class Reader> template <class Reader>
void DPSM<IDType>::readQuadDecalInfo(Reader& r, uint32_t clsId, typename DPSM<IDType>::SQuadDescr& quad) void DPSM<IDType>::readQuadDecalInfo(Reader& r, uint32_t clsId, typename DPSM<IDType>::SQuadDescr& quad) {
{ switch (clsId) {
switch(clsId) case SBIG('1LFT'):
{ case SBIG('2LFT'):
case SBIG('1LFT'): quad.x0_LFT.read(r);
case SBIG('2LFT'):
quad.x0_LFT.read(r);
break; break;
case SBIG('1SZE'): case SBIG('1SZE'):
case SBIG('2SZE'): case SBIG('2SZE'):
quad.x4_SZE.read(r); quad.x4_SZE.read(r);
break; break;
case SBIG('1ROT'): case SBIG('1ROT'):
case SBIG('2ROT'): case SBIG('2ROT'):
quad.x8_ROT.read(r); quad.x8_ROT.read(r);
break; break;
case SBIG('1OFF'): case SBIG('1OFF'):
case SBIG('2OFF'): case SBIG('2OFF'):
quad.xc_OFF.read(r); quad.xc_OFF.read(r);
break; break;
case SBIG('1CLR'): case SBIG('1CLR'):
case SBIG('2CLR'): case SBIG('2CLR'):
quad.x10_CLR.read(r); quad.x10_CLR.read(r);
break; break;
case SBIG('1TEX'): case SBIG('1TEX'):
case SBIG('2TEX'): case SBIG('2TEX'):
quad.x14_TEX.read(r); quad.x14_TEX.read(r);
break; break;
case SBIG('1ADD'): case SBIG('1ADD'):
case SBIG('2ADD'): case SBIG('2ADD'):
quad.x18_ADD.read(r); quad.x18_ADD.read(r);
break; break;
} }
} }
template <class IDType> template <class IDType>
void DPSM<IDType>::writeQuadDecalInfo(athena::io::YAMLDocWriter& w, void DPSM<IDType>::writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const typename DPSM<IDType>::SQuadDescr& quad,
const typename DPSM<IDType>::SQuadDescr& quad, bool first) const bool first) const {
{ if (quad.x0_LFT)
if (quad.x0_LFT) if (auto rec = w.enterSubRecord((first ? "1LFT" : "2LFT")))
if (auto rec = w.enterSubRecord((first ? "1LFT" : "2LFT"))) quad.x0_LFT.write(w);
quad.x0_LFT.write(w); if (quad.x4_SZE)
if (quad.x4_SZE) if (auto rec = w.enterSubRecord((first ? "1SZE" : "2SZE")))
if (auto rec = w.enterSubRecord((first ? "1SZE" : "2SZE"))) quad.x4_SZE.write(w);
quad.x4_SZE.write(w); if (quad.x8_ROT)
if (quad.x8_ROT) if (auto rec = w.enterSubRecord((first ? "1ROT" : "2ROT")))
if (auto rec = w.enterSubRecord((first ? "1ROT" : "2ROT"))) quad.x8_ROT.write(w);
quad.x8_ROT.write(w); if (quad.xc_OFF)
if (quad.xc_OFF) if (auto rec = w.enterSubRecord((first ? "1OFF" : "2OFF")))
if (auto rec = w.enterSubRecord((first ? "1OFF" : "2OFF"))) quad.xc_OFF.write(w);
quad.xc_OFF.write(w); if (quad.x10_CLR)
if (quad.x10_CLR) if (auto rec = w.enterSubRecord((first ? "1CLR" : "2CLR")))
if (auto rec = w.enterSubRecord((first ? "1CLR" : "2CLR"))) quad.x10_CLR.write(w);
quad.x10_CLR.write(w); if (quad.x14_TEX)
if (quad.x14_TEX) if (auto rec = w.enterSubRecord((first ? "1TEX" : "2TEX")))
if (auto rec = w.enterSubRecord((first ? "1TEX" : "2TEX"))) quad.x14_TEX.write(w);
quad.x14_TEX.write(w); if (quad.x18_ADD)
if (quad.x18_ADD) if (auto rec = w.enterSubRecord((first ? "1ADD" : "2ADD")))
if (auto rec = w.enterSubRecord((first ? "1ADD" : "2ADD"))) quad.x18_ADD.write(w);
quad.x18_ADD.write(w);
} }
template <class IDType> template <class IDType>
void DPSM<IDType>::_binarySize(size_t& s) const void DPSM<IDType>::_binarySize(size_t& s) const {
{ s += 4;
getQuadDecalBinarySize(s, x0_quad);
getQuadDecalBinarySize(s, x1c_quad);
if (x38_DMDL) {
s += 4; s += 4;
getQuadDecalBinarySize(s, x0_quad); x38_DMDL.binarySize(s);
getQuadDecalBinarySize(s, x1c_quad); }
if (x38_DMDL) if (x48_DLFT) {
{ s += 4;
s += 4; x48_DLFT.binarySize(s);
x38_DMDL.binarySize(s); }
} if (x4c_DMOP) {
if (x48_DLFT) s += 4;
{ x4c_DMOP.binarySize(s);
s += 4; }
x48_DLFT.binarySize(s); if (x50_DMRT) {
} s += 4;
if (x4c_DMOP) x50_DMRT.binarySize(s);
{ }
s += 4; if (x54_DMSC) {
x4c_DMOP.binarySize(s); s += 4;
} x54_DMSC.binarySize(s);
if (x50_DMRT) }
{ if (x58_DMCL) {
s += 4; x58_DMCL.binarySize(s);
x50_DMRT.binarySize(s); }
} if (x5c_24_DMAB)
if (x54_DMSC) s += 9;
{ if (x5c_25_DMOO)
s += 4; s += 9;
x54_DMSC.binarySize(s);
}
if (x58_DMCL)
{
x58_DMCL.binarySize(s);
}
if (x5c_24_DMAB)
s += 9;
if (x5c_25_DMOO)
s += 9;
} }
template <class IDType> template <class IDType>
void DPSM<IDType>::getQuadDecalBinarySize(size_t& s, const typename DPSM<IDType>::SQuadDescr& quad) const void DPSM<IDType>::getQuadDecalBinarySize(size_t& s, const typename DPSM<IDType>::SQuadDescr& quad) const {
{ if (quad.x0_LFT) {
if (quad.x0_LFT) s += 4;
{ quad.x0_LFT.binarySize(s);
s += 4; }
quad.x0_LFT.binarySize(s); if (quad.x4_SZE) {
} s += 4;
if (quad.x4_SZE) quad.x4_SZE.binarySize(s);
{ }
s += 4; if (quad.x8_ROT) {
quad.x4_SZE.binarySize(s); s += 4;
} quad.x8_ROT.binarySize(s);
if (quad.x8_ROT) }
{ if (quad.xc_OFF) {
s += 4; s += 4;
quad.x8_ROT.binarySize(s); quad.xc_OFF.binarySize(s);
} }
if (quad.xc_OFF) if (quad.x10_CLR) {
{ s += 4;
s += 4; quad.x10_CLR.binarySize(s);
quad.xc_OFF.binarySize(s); }
} if (quad.x14_TEX) {
if (quad.x10_CLR) s += 4;
{ quad.x14_TEX.binarySize(s);
s += 4; }
quad.x10_CLR.binarySize(s); if (quad.x18_ADD) {
} s += 4;
if (quad.x14_TEX) quad.x18_ADD.binarySize(s);
{ }
s += 4;
quad.x14_TEX.binarySize(s);
}
if (quad.x18_ADD)
{
s += 4;
quad.x18_ADD.binarySize(s);
}
} }
template <class IDType> template <class IDType>
void DPSM<IDType>::_read(athena::io::IStreamReader& r) void DPSM<IDType>::_read(athena::io::IStreamReader& r) {
{ uint32_t clsId;
uint32_t clsId; r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('DPSM')) {
LogModule.report(logvisor::Warning, "non DPSM provided to DPSM parser");
return;
}
bool loadFirstDesc = false;
r.readBytesToBuf(&clsId, 4);
while (clsId != SBIG('_END')) {
switch (clsId) {
case SBIG('1SZE'):
case SBIG('1LFT'):
case SBIG('1ROT'):
case SBIG('1OFF'):
case SBIG('1CLR'):
case SBIG('1TEX'):
case SBIG('1ADD'):
loadFirstDesc = true;
case SBIG('2SZE'):
case SBIG('2LFT'):
case SBIG('2ROT'):
case SBIG('2OFF'):
case SBIG('2CLR'):
case SBIG('2TEX'):
case SBIG('2ADD'):
if (loadFirstDesc)
readQuadDecalInfo(r, clsId, x0_quad);
else
readQuadDecalInfo(r, clsId, x1c_quad);
break;
case SBIG('DMDL'):
x38_DMDL.read(r);
break;
case SBIG('DLFT'):
x48_DLFT.read(r);
break;
case SBIG('DMOP'):
x4c_DMOP.read(r);
break;
case SBIG('DMRT'):
x50_DMRT.read(r);
break;
case SBIG('DMSC'):
x54_DMSC.read(r);
break;
case SBIG('DMCL'):
x58_DMCL.read(r);
break;
case SBIG('DMAB'):
r.readUint32();
x5c_24_DMAB = r.readBool();
break;
case SBIG('DMOO'):
r.readUint32();
x5c_25_DMOO = r.readBool();
break;
default:
LogModule.report(logvisor::Fatal, "Unknown DPSM class %.4s @%" PRIi64, &clsId, r.position());
break;
}
r.readBytesToBuf(&clsId, 4); r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('DPSM')) }
{
LogModule.report(logvisor::Warning, "non DPSM provided to DPSM parser");
return;
}
bool loadFirstDesc = false;
r.readBytesToBuf(&clsId, 4);
while (clsId != SBIG('_END'))
{
switch(clsId)
{
case SBIG('1SZE'):
case SBIG('1LFT'):
case SBIG('1ROT'):
case SBIG('1OFF'):
case SBIG('1CLR'):
case SBIG('1TEX'):
case SBIG('1ADD'):
loadFirstDesc = true;
case SBIG('2SZE'):
case SBIG('2LFT'):
case SBIG('2ROT'):
case SBIG('2OFF'):
case SBIG('2CLR'):
case SBIG('2TEX'):
case SBIG('2ADD'):
if (loadFirstDesc)
readQuadDecalInfo(r, clsId, x0_quad);
else
readQuadDecalInfo(r, clsId, x1c_quad);
break;
case SBIG('DMDL'):
x38_DMDL.read(r);
break;
case SBIG('DLFT'):
x48_DLFT.read(r);
break;
case SBIG('DMOP'):
x4c_DMOP.read(r);
break;
case SBIG('DMRT'):
x50_DMRT.read(r);
break;
case SBIG('DMSC'):
x54_DMSC.read(r);
break;
case SBIG('DMCL'):
x58_DMCL.read(r);
break;
case SBIG('DMAB'):
r.readUint32();
x5c_24_DMAB = r.readBool();
break;
case SBIG('DMOO'):
r.readUint32();
x5c_25_DMOO = r.readBool();
break;
default:
LogModule.report(logvisor::Fatal, "Unknown DPSM class %.4s @%" PRIi64, &clsId, r.position());
break;
}
r.readBytesToBuf(&clsId, 4);
}
} }
template <class IDType> template <class IDType>
void DPSM<IDType>::_write(athena::io::IStreamWriter& w) const void DPSM<IDType>::_write(athena::io::IStreamWriter& w) const {
{ w.writeBytes("DPSM", 4);
w.writeBytes("DPSM", 4); writeQuadDecalInfo(w, x0_quad, true);
writeQuadDecalInfo(w, x0_quad, true); writeQuadDecalInfo(w, x1c_quad, false);
writeQuadDecalInfo(w, x1c_quad, false); if (x38_DMDL) {
if (x38_DMDL) w.writeBytes("DMDL", 4);
{ x38_DMDL.write(w);
w.writeBytes("DMDL", 4); }
x38_DMDL.write(w); if (x48_DLFT) {
} w.writeBytes("DLFT", 4);
if (x48_DLFT) x48_DLFT.write(w);
{ }
w.writeBytes("DLFT", 4); if (x4c_DMOP) {
x48_DLFT.write(w); w.writeBytes("DMOP", 4);
} x4c_DMOP.write(w);
if (x4c_DMOP) }
{ if (x50_DMRT) {
w.writeBytes("DMOP", 4); w.writeBytes("DMRT", 4);
x4c_DMOP.write(w); x50_DMRT.write(w);
} }
if (x50_DMRT) if (x54_DMSC) {
{ w.writeBytes("DMSC", 4);
w.writeBytes("DMRT", 4); x54_DMSC.write(w);
x50_DMRT.write(w); }
} if (x58_DMCL) {
if (x54_DMSC) w.writeBytes("DMCL", 4);
{ x58_DMCL.write(w);
w.writeBytes("DMSC", 4); }
x54_DMSC.write(w); if (x5c_24_DMAB)
} w.writeBytes("DMABCNST\x01", 9);
if (x58_DMCL) if (x5c_25_DMOO)
{ w.writeBytes("DMOOCNST\x01", 9);
w.writeBytes("DMCL", 4); w.writeBytes("_END", 4);
x58_DMCL.write(w);
}
if (x5c_24_DMAB)
w.writeBytes("DMABCNST\x01", 9);
if (x5c_25_DMOO)
w.writeBytes("DMOOCNST\x01", 9);
w.writeBytes("_END", 4);
} }
template <class IDType> template <class IDType>
void DPSM<IDType>::writeQuadDecalInfo(athena::io::IStreamWriter& w, void DPSM<IDType>::writeQuadDecalInfo(athena::io::IStreamWriter& w, const typename DPSM<IDType>::SQuadDescr& quad,
const typename DPSM<IDType>::SQuadDescr& quad, bool first) const bool first) const {
{ if (quad.x0_LFT) {
if (quad.x0_LFT) w.writeBytes((first ? "1LFT" : "2LFT"), 4);
{ quad.x0_LFT.write(w);
w.writeBytes((first ? "1LFT" : "2LFT"), 4); }
quad.x0_LFT.write(w); if (quad.x4_SZE) {
} w.writeBytes((first ? "1SZE" : "2SZE"), 4);
if (quad.x4_SZE) quad.x4_SZE.write(w);
{ }
w.writeBytes((first ? "1SZE" : "2SZE"), 4); if (quad.x8_ROT) {
quad.x4_SZE.write(w); w.writeBytes((first ? "1ROT" : "2ROT"), 4);
} quad.x8_ROT.write(w);
if (quad.x8_ROT) }
{ if (quad.xc_OFF) {
w.writeBytes((first ? "1ROT" : "2ROT"), 4); w.writeBytes((first ? "1OFF" : "2OFF"), 4);
quad.x8_ROT.write(w); quad.xc_OFF.write(w);
} }
if (quad.xc_OFF) if (quad.x10_CLR) {
{ w.writeBytes((first ? "1CLR" : "2CLR"), 4);
w.writeBytes((first ? "1OFF" : "2OFF"), 4); quad.x10_CLR.write(w);
quad.xc_OFF.write(w); }
} if (quad.x14_TEX) {
if (quad.x10_CLR) w.writeBytes((first ? "1TEX" : "2TEX"), 4);
{ quad.x14_TEX.write(w);
w.writeBytes((first ? "1CLR" : "2CLR"), 4); }
quad.x10_CLR.write(w); if (quad.x18_ADD) {
} w.writeBytes((first ? "1ADD" : "2ADD"), 4);
if (quad.x14_TEX) quad.x18_ADD.write(w);
{ }
w.writeBytes((first ? "1TEX" : "2TEX"), 4);
quad.x14_TEX.write(w);
}
if (quad.x18_ADD)
{
w.writeBytes((first ? "1ADD" : "2ADD"), 4);
quad.x18_ADD.write(w);
}
} }
template <class IDType> template <class IDType>
void DPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const void DPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
{ if (x0_quad.x14_TEX.m_elem)
if (x0_quad.x14_TEX.m_elem) x0_quad.x14_TEX.m_elem->gatherDependencies(pathsOut);
x0_quad.x14_TEX.m_elem->gatherDependencies(pathsOut); if (x1c_quad.x14_TEX.m_elem)
if (x1c_quad.x14_TEX.m_elem) x1c_quad.x14_TEX.m_elem->gatherDependencies(pathsOut);
x1c_quad.x14_TEX.m_elem->gatherDependencies(pathsOut); g_curSpec->flattenDependencies(x38_DMDL.id, pathsOut);
g_curSpec->flattenDependencies(x38_DMDL.id, pathsOut);
} }
AT_SUBSPECIALIZE_DNA_YAML(DPSM<UniqueID32>) AT_SUBSPECIALIZE_DNA_YAML(DPSM<UniqueID32>)
@ -421,36 +380,32 @@ template struct DPSM<UniqueID32>;
template struct DPSM<UniqueID64>; template struct DPSM<UniqueID64>;
template <class IDType> template <class IDType>
bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::FileWriter writer(outPath.getAbsolutePath()); if (writer.isOpen()) {
if (writer.isOpen()) DPSM<IDType> dpsm;
{ dpsm.read(rs);
DPSM<IDType> dpsm; athena::io::ToYAMLStream(dpsm, writer);
dpsm.read(rs); return true;
athena::io::ToYAMLStream(dpsm, writer); }
return true; return false;
}
return false;
} }
template bool ExtractDPSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractDPSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractDPSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractDPSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath) bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); if (w.hasError())
if (w.hasError()) return false;
return false; dpsm.write(w);
dpsm.write(w); int64_t rem = w.position() % 32;
int64_t rem = w.position() % 32; if (rem)
if (rem) for (int64_t i = 0; i < 32 - rem; ++i)
for (int64_t i=0 ; i<32-rem ; ++i) w.writeUByte(0xff);
w.writeUByte(0xff); return true;
return true;
} }
template bool WriteDPSM<UniqueID32>(const DPSM<UniqueID32>& dpsm, const hecl::ProjectPath& outPath); template bool WriteDPSM<UniqueID32>(const DPSM<UniqueID32>& dpsm, const hecl::ProjectPath& outPath);
template bool WriteDPSM<UniqueID64>(const DPSM<UniqueID64>& dpsm, const hecl::ProjectPath& outPath); template bool WriteDPSM<UniqueID64>(const DPSM<UniqueID64>& dpsm, const hecl::ProjectPath& outPath);
} // namespace DataSpec::DNAParticle
}

View File

@ -4,46 +4,45 @@
#include "PAK.hpp" #include "PAK.hpp"
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle namespace DataSpec::DNAParticle {
{
template <class IDType> template <class IDType>
struct DPSM : BigDNA struct DPSM : BigDNA {
{ AT_DECL_EXPLICIT_DNA_YAML
AT_DECL_EXPLICIT_DNA_YAML AT_SUBDECL_DNA
AT_SUBDECL_DNA
struct SQuadDescr struct SQuadDescr {
{ IntElementFactory x0_LFT;
IntElementFactory x0_LFT; RealElementFactory x4_SZE;
RealElementFactory x4_SZE; RealElementFactory x8_ROT;
RealElementFactory x8_ROT; VectorElementFactory xc_OFF;
VectorElementFactory xc_OFF; ColorElementFactory x10_CLR;
ColorElementFactory x10_CLR; UVElementFactory<IDType> x14_TEX;
UVElementFactory<IDType> x14_TEX; BoolHelper x18_ADD;
BoolHelper x18_ADD; };
SQuadDescr x0_quad;
SQuadDescr x1c_quad;
ChildResourceFactory<IDType> x38_DMDL;
IntElementFactory x48_DLFT;
VectorElementFactory x4c_DMOP;
VectorElementFactory x50_DMRT;
VectorElementFactory x54_DMSC;
ColorElementFactory x58_DMCL;
union {
struct {
bool x5c_24_DMAB : 1;
bool x5c_25_DMOO : 1;
}; };
uint8_t dummy;
};
template <class Reader>
void readQuadDecalInfo(Reader& r, uint32_t clsId, SQuadDescr& quad);
void writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const SQuadDescr& quad, bool first) const;
void getQuadDecalBinarySize(size_t& s, const SQuadDescr& desc) const;
void writeQuadDecalInfo(athena::io::IStreamWriter& w, const SQuadDescr& quad, bool first) const;
SQuadDescr x0_quad; void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
SQuadDescr x1c_quad;
ChildResourceFactory<IDType> x38_DMDL;
IntElementFactory x48_DLFT;
VectorElementFactory x4c_DMOP;
VectorElementFactory x50_DMRT;
VectorElementFactory x54_DMSC;
ColorElementFactory x58_DMCL;
union
{
struct { bool x5c_24_DMAB : 1; bool x5c_25_DMOO : 1;};
uint8_t dummy;
};
template <class Reader>
void readQuadDecalInfo(Reader& r, uint32_t clsId, SQuadDescr& quad);
void writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const SQuadDescr& quad, bool first) const;
void getQuadDecalBinarySize(size_t& s, const SQuadDescr& desc) const;
void writeQuadDecalInfo(athena::io::IStreamWriter& w, const SQuadDescr& quad, bool first) const;
void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
}; };
template <class IDType> template <class IDType>
@ -52,5 +51,4 @@ bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath); bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAParticle

View File

@ -6,260 +6,246 @@
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
#include <cinttypes> #include <cinttypes>
namespace DataSpec namespace DataSpec {
{
template<class DEAFBABE> template <class DEAFBABE>
void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln, atInt32 idx) void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln, atInt32 idx) {
{ os << "material_index = []\n"
os << "material_index = []\n" "col_bm = bmesh.new()\n";
"col_bm = bmesh.new()\n"; for (const atVec3f& vert : db.verts) {
for (const atVec3f& vert : db.verts) zeus::simd_floats f(vert.simd);
{ os.format("col_bm.verts.new((%f,%f,%f))\n", f[0], f[1], f[2]);
zeus::simd_floats f(vert.simd); }
os.format("col_bm.verts.new((%f,%f,%f))\n", f[0], f[1], f[2]);
os << "col_bm.verts.ensure_lookup_table()\n";
int triIdx = 0;
for (const typename DEAFBABE::Triangle& tri : db.triangleEdgeConnections) {
const typename DEAFBABE::Material& triMat = db.materials[db.triMats[triIdx++]];
const typename DEAFBABE::Edge& edge0 = db.edgeVertConnections[tri.edges[0]];
const typename DEAFBABE::Edge& edge1 = db.edgeVertConnections[tri.edges[1]];
const typename DEAFBABE::Edge& edge2 = db.edgeVertConnections[tri.edges[2]];
if (!edge0.verts[0] && !edge1.verts[0] && !edge2.verts[0])
break;
int vindices[3];
vindices[2] =
(edge1.verts[0] != edge0.verts[0] && edge1.verts[0] != edge0.verts[1]) ? edge1.verts[0] : edge1.verts[1];
if (triMat.flipFace()) {
vindices[0] = edge0.verts[1];
vindices[1] = edge0.verts[0];
} else {
vindices[0] = edge0.verts[0];
vindices[1] = edge0.verts[1];
} }
os << "col_bm.verts.ensure_lookup_table()\n"; os << "tri_verts = []\n";
os.format("tri_verts.append(col_bm.verts[%u])\n", vindices[0]);
os.format("tri_verts.append(col_bm.verts[%u])\n", vindices[1]);
os.format("tri_verts.append(col_bm.verts[%u])\n", vindices[2]);
int triIdx = 0; os.format(
for (const typename DEAFBABE::Triangle& tri : db.triangleEdgeConnections) "face = col_bm.faces.get(tri_verts)\n"
{ "if face is None:\n"
const typename DEAFBABE::Material& triMat = db.materials[db.triMats[triIdx++]]; " face = col_bm.faces.new(tri_verts)\n"
const typename DEAFBABE::Edge& edge0 = db.edgeVertConnections[tri.edges[0]]; "else:\n"
const typename DEAFBABE::Edge& edge1 = db.edgeVertConnections[tri.edges[1]]; " face = face.copy()\n"
const typename DEAFBABE::Edge& edge2 = db.edgeVertConnections[tri.edges[2]]; " for i in range(3):\n"
if (!edge0.verts[0] && !edge1.verts[0] && !edge2.verts[0]) " face.verts[i].co = tri_verts[i].co\n"
break; " col_bm.verts.ensure_lookup_table()\n"
"face.material_index = select_material(0x%016" PRIX64
")\n"
"face.smooth = False\n"
"\n",
atUint64(triMat.material));
}
int vindices[3]; db.insertNoClimb(os);
vindices[2] =
(edge1.verts[0] != edge0.verts[0] && edge1.verts[0] != edge0.verts[1]) ?
edge1.verts[0] : edge1.verts[1];
if (triMat.flipFace()) if (isDcln)
{ os.format("col_mesh = bpy.data.meshes.new('CMESH_%i')\n", idx);
vindices[0] = edge0.verts[1]; else
vindices[1] = edge0.verts[0]; os << "col_mesh = bpy.data.meshes.new('CMESH')\n";
}
else
{
vindices[0] = edge0.verts[0];
vindices[1] = edge0.verts[1];
}
os << "tri_verts = []\n"; os << "col_bm.to_mesh(col_mesh)\n"
os.format("tri_verts.append(col_bm.verts[%u])\n", vindices[0]); "col_mesh_obj = bpy.data.objects.new(col_mesh.name, col_mesh)\n"
os.format("tri_verts.append(col_bm.verts[%u])\n", vindices[1]); "\n"
os.format("tri_verts.append(col_bm.verts[%u])\n", vindices[2]); "for mat_name in material_index:\n"
" mat = material_dict[mat_name]\n"
" col_mesh.materials.append(mat)\n"
"\n"
"bpy.context.scene.objects.link(col_mesh_obj)\n"
"bpy.context.scene.objects.active = col_mesh_obj\n"
"bpy.ops.object.mode_set(mode='EDIT')\n"
"bpy.ops.mesh.tris_convert_to_quads()\n"
"bpy.ops.object.mode_set(mode='OBJECT')\n"
"bpy.context.scene.objects.active = None\n";
if (!isDcln)
os << "col_mesh_obj.layers[1] = True\n"
"col_mesh_obj.layers[0] = False\n";
os.format("face = col_bm.faces.get(tri_verts)\n" os << "col_mesh_obj.draw_type = 'SOLID'\n"
"if face is None:\n" "col_mesh_obj.game.physics_type = 'STATIC'\n"
" face = col_bm.faces.new(tri_verts)\n" "\n";
"else:\n"
" face = face.copy()\n"
" for i in range(3):\n"
" face.verts[i].co = tri_verts[i].co\n"
" col_bm.verts.ensure_lookup_table()\n"
"face.material_index = select_material(0x%016" PRIX64 ")\n"
"face.smooth = False\n"
"\n",
atUint64(triMat.material));
}
db.insertNoClimb(os);
if (isDcln)
os.format("col_mesh = bpy.data.meshes.new('CMESH_%i')\n", idx);
else
os << "col_mesh = bpy.data.meshes.new('CMESH')\n";
os << "col_bm.to_mesh(col_mesh)\n"
"col_mesh_obj = bpy.data.objects.new(col_mesh.name, col_mesh)\n"
"\n"
"for mat_name in material_index:\n"
" mat = material_dict[mat_name]\n"
" col_mesh.materials.append(mat)\n"
"\n"
"bpy.context.scene.objects.link(col_mesh_obj)\n"
"bpy.context.scene.objects.active = col_mesh_obj\n"
"bpy.ops.object.mode_set(mode='EDIT')\n"
"bpy.ops.mesh.tris_convert_to_quads()\n"
"bpy.ops.object.mode_set(mode='OBJECT')\n"
"bpy.context.scene.objects.active = None\n";
if (!isDcln)
os << "col_mesh_obj.layers[1] = True\n"
"col_mesh_obj.layers[0] = False\n";
os << "col_mesh_obj.draw_type = 'SOLID'\n"
"col_mesh_obj.game.physics_type = 'STATIC'\n"
"\n";
} }
template void DeafBabeSendToBlender<DNAMP1::DeafBabe>(hecl::blender::PyOutStream& os, const DNAMP1::DeafBabe& db, bool isDcln, atInt32 idx); template void DeafBabeSendToBlender<DNAMP1::DeafBabe>(hecl::blender::PyOutStream& os, const DNAMP1::DeafBabe& db,
template void DeafBabeSendToBlender<DNAMP2::DeafBabe>(hecl::blender::PyOutStream& os, const DNAMP2::DeafBabe& db, bool isDcln, atInt32 idx); bool isDcln, atInt32 idx);
template void DeafBabeSendToBlender<DNAMP1::DCLN::Collision>(hecl::blender::PyOutStream& os, const DNAMP1::DCLN::Collision& db, bool isDcln, atInt32 idx); template void DeafBabeSendToBlender<DNAMP2::DeafBabe>(hecl::blender::PyOutStream& os, const DNAMP2::DeafBabe& db,
bool isDcln, atInt32 idx);
template void DeafBabeSendToBlender<DNAMP1::DCLN::Collision>(hecl::blender::PyOutStream& os,
const DNAMP1::DCLN::Collision& db, bool isDcln,
atInt32 idx);
template<class DEAFBABE> template <class DEAFBABE>
static void PopulateAreaFields(DEAFBABE& db, static void PopulateAreaFields(
const hecl::blender::ColMesh& colMesh, DEAFBABE& db, const hecl::blender::ColMesh& colMesh, const zeus::CAABox& fullAABB,
const zeus::CAABox& fullAABB, std::enable_if_t<std::is_same<DEAFBABE, DNAMP1::DeafBabe>::value || std::is_same<DEAFBABE, DNAMP2::DeafBabe>::value,
std::enable_if_t<std::is_same<DEAFBABE, DNAMP1::DeafBabe>::value || int>* = 0) {
std::is_same<DEAFBABE, DNAMP2::DeafBabe>::value, int>* = 0) AROTBuilder builder;
{ auto octree = builder.buildCol(colMesh, db.rootNodeType);
AROTBuilder builder; static_cast<std::unique_ptr<atUint8[]>&>(db.bspTree) = std::move(octree.first);
auto octree = builder.buildCol(colMesh, db.rootNodeType); db.bspSize = octree.second;
static_cast<std::unique_ptr<atUint8[]>&>(db.bspTree) = std::move(octree.first);
db.bspSize = octree.second;
db.unk1 = 0x1000000; db.unk1 = 0x1000000;
size_t dbSize = 0; size_t dbSize = 0;
db.binarySize(dbSize); db.binarySize(dbSize);
db.length = dbSize - 8; db.length = dbSize - 8;
db.magic = 0xDEAFBABE; db.magic = 0xDEAFBABE;
db.version = 3; db.version = 3;
db.aabb[0] = fullAABB.min; db.aabb[0] = fullAABB.min;
db.aabb[1] = fullAABB.max; db.aabb[1] = fullAABB.max;
} }
template<class DEAFBABE> template <class DEAFBABE>
static void PopulateAreaFields(DEAFBABE& db, static void PopulateAreaFields(DEAFBABE& db, const hecl::blender::ColMesh& colMesh, const zeus::CAABox& fullAABB,
const hecl::blender::ColMesh& colMesh, std::enable_if_t<std::is_same<DEAFBABE, DNAMP1::DCLN::Collision>::value, int>* = 0) {
const zeus::CAABox& fullAABB, db.magic = 0xDEAFBABE;
std::enable_if_t<std::is_same<DEAFBABE, DNAMP1::DCLN::Collision>::value, int>* = 0) db.version = 2;
{ db.memSize = 0;
db.magic = 0xDEAFBABE;
db.version = 2;
db.memSize = 0;
} }
class MaterialPool class MaterialPool {
{ std::unordered_map<u64, int> m_materials;
std::unordered_map<u64, int> m_materials;
public: public:
template <class M, class V> template <class M, class V>
int AddOrLookup(const M& mat, V& vec) int AddOrLookup(const M& mat, V& vec) {
{ auto search = m_materials.find(mat.material);
auto search = m_materials.find(mat.material); if (search != m_materials.end())
if (search != m_materials.end()) return search->second;
return search->second; auto idx = int(vec.size());
auto idx = int(vec.size()); vec.push_back(mat);
vec.push_back(mat); m_materials[mat.material] = idx;
m_materials[mat.material] = idx; return idx;
return idx; }
}
}; };
template<class DEAFBABE> template <class DEAFBABE>
void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh) void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh) {
{ using BlendMat = hecl::blender::ColMesh::Material;
using BlendMat = hecl::blender::ColMesh::Material;
auto MakeMat = [](const BlendMat& mat, bool flipFace) -> typename DEAFBABE::Material auto MakeMat = [](const BlendMat& mat, bool flipFace) -> typename DEAFBABE::Material {
{ typename DEAFBABE::Material dbMat = {};
typename DEAFBABE::Material dbMat = {}; dbMat.setUnknown(mat.unknown);
dbMat.setUnknown(mat.unknown); dbMat.setSurfaceStone(mat.surfaceStone);
dbMat.setSurfaceStone(mat.surfaceStone); dbMat.setSurfaceMetal(mat.surfaceMetal);
dbMat.setSurfaceMetal(mat.surfaceMetal); dbMat.setSurfaceGrass(mat.surfaceGrass);
dbMat.setSurfaceGrass(mat.surfaceGrass); dbMat.setSurfaceIce(mat.surfaceIce);
dbMat.setSurfaceIce(mat.surfaceIce); dbMat.setPillar(mat.pillar);
dbMat.setPillar(mat.pillar); dbMat.setSurfaceMetalGrating(mat.surfaceMetalGrating);
dbMat.setSurfaceMetalGrating(mat.surfaceMetalGrating); dbMat.setSurfacePhazon(mat.surfacePhazon);
dbMat.setSurfacePhazon(mat.surfacePhazon); dbMat.setSurfaceDirt(mat.surfaceDirt);
dbMat.setSurfaceDirt(mat.surfaceDirt); dbMat.setSurfaceLava(mat.surfaceLava);
dbMat.setSurfaceLava(mat.surfaceLava); dbMat.setSurfaceSPMetal(mat.surfaceSPMetal);
dbMat.setSurfaceSPMetal(mat.surfaceSPMetal); dbMat.setSurfaceLavaStone(mat.surfaceLavaStone);
dbMat.setSurfaceLavaStone(mat.surfaceLavaStone); dbMat.setSurfaceSnow(mat.surfaceSnow);
dbMat.setSurfaceSnow(mat.surfaceSnow); dbMat.setSurfaceMudSlow(mat.surfaceMudSlow);
dbMat.setSurfaceMudSlow(mat.surfaceMudSlow); dbMat.setSurfaceFabric(mat.surfaceFabric);
dbMat.setSurfaceFabric(mat.surfaceFabric); dbMat.setHalfPipe(mat.halfPipe);
dbMat.setHalfPipe(mat.halfPipe); dbMat.setSurfaceMud(mat.surfaceMud);
dbMat.setSurfaceMud(mat.surfaceMud); dbMat.setSurfaceGlass(mat.surfaceGlass);
dbMat.setSurfaceGlass(mat.surfaceGlass); dbMat.setUnused3(mat.unused3);
dbMat.setUnused3(mat.unused3); dbMat.setUnused4(mat.unused4);
dbMat.setUnused4(mat.unused4); dbMat.setSurfaceShield(mat.surfaceShield);
dbMat.setSurfaceShield(mat.surfaceShield); dbMat.setSurfaceSand(mat.surfaceSand);
dbMat.setSurfaceSand(mat.surfaceSand); dbMat.setSurfaceMothOrSeedOrganics(mat.surfaceMothOrSeedOrganics);
dbMat.setSurfaceMothOrSeedOrganics(mat.surfaceMothOrSeedOrganics); dbMat.setSurfaceWeb(mat.surfaceWeb);
dbMat.setSurfaceWeb(mat.surfaceWeb); dbMat.setProjectilePassthrough(mat.projPassthrough);
dbMat.setProjectilePassthrough(mat.projPassthrough); dbMat.setSolid(mat.solid);
dbMat.setSolid(mat.solid); dbMat.setNoPlatformCollision(mat.noPlatformCollision);
dbMat.setNoPlatformCollision(mat.noPlatformCollision); dbMat.setCameraPassthrough(mat.camPassthrough);
dbMat.setCameraPassthrough(mat.camPassthrough); dbMat.setSurfaceWood(mat.surfaceWood);
dbMat.setSurfaceWood(mat.surfaceWood); dbMat.setSurfaceOrganic(mat.surfaceOrganic);
dbMat.setSurfaceOrganic(mat.surfaceOrganic); dbMat.setNoEdgeCollision(mat.noEdgeCollision);
dbMat.setNoEdgeCollision(mat.noEdgeCollision); dbMat.setSurfaceRubber(mat.surfaceRubber);
dbMat.setSurfaceRubber(mat.surfaceRubber); dbMat.setSeeThrough(mat.seeThrough);
dbMat.setSeeThrough(mat.seeThrough); dbMat.setScanPassthrough(mat.scanPassthrough);
dbMat.setScanPassthrough(mat.scanPassthrough); dbMat.setAiPassthrough(mat.aiPassthrough);
dbMat.setAiPassthrough(mat.aiPassthrough); dbMat.setCeiling(mat.ceiling);
dbMat.setCeiling(mat.ceiling); dbMat.setWall(mat.wall);
dbMat.setWall(mat.wall); dbMat.setFloor(mat.floor);
dbMat.setFloor(mat.floor); dbMat.setAiBlock(mat.aiBlock);
dbMat.setAiBlock(mat.aiBlock); dbMat.setJumpNotAllowed(mat.jumpNotAllowed);
dbMat.setJumpNotAllowed(mat.jumpNotAllowed); dbMat.setSpiderBall(mat.spiderBall);
dbMat.setSpiderBall(mat.spiderBall); dbMat.setScrewAttackWallJump(mat.screwAttackWallJump);
dbMat.setScrewAttackWallJump(mat.screwAttackWallJump); dbMat.setFlipFace(flipFace);
dbMat.setFlipFace(flipFace); return dbMat;
return dbMat; };
};
MaterialPool matPool; MaterialPool matPool;
db.materials.reserve(colMesh.materials.size() * 2); db.materials.reserve(colMesh.materials.size() * 2);
zeus::CAABox fullAABB; zeus::CAABox fullAABB;
db.verts.reserve(colMesh.verts.size()); db.verts.reserve(colMesh.verts.size());
db.vertMats.resize(colMesh.verts.size()); db.vertMats.resize(colMesh.verts.size());
for (const auto& vert : colMesh.verts) for (const auto& vert : colMesh.verts) {
{ fullAABB.accumulateBounds(zeus::CVector3f(vert));
fullAABB.accumulateBounds(zeus::CVector3f(vert)); db.verts.push_back(vert);
db.verts.push_back(vert); }
db.vertMatsCount = colMesh.verts.size();
db.vertCount = colMesh.verts.size();
db.edgeVertConnections.reserve(colMesh.edges.size());
db.edgeMats.resize(colMesh.edges.size());
for (const auto& edge : colMesh.edges) {
db.edgeVertConnections.emplace_back();
db.edgeVertConnections.back().verts[0] = edge.verts[0];
db.edgeVertConnections.back().verts[1] = edge.verts[1];
}
db.edgeMatsCount = colMesh.edges.size();
db.edgeVertsCount = colMesh.edges.size();
db.triMats.reserve(colMesh.trianges.size());
db.triangleEdgeConnections.reserve(colMesh.trianges.size());
for (const auto& tri : colMesh.trianges) {
int triMatIdx = matPool.AddOrLookup(MakeMat(colMesh.materials[tri.matIdx], tri.flip), db.materials);
db.triMats.push_back(triMatIdx);
db.triangleEdgeConnections.emplace_back();
db.triangleEdgeConnections.back().edges[0] = tri.edges[0];
db.triangleEdgeConnections.back().edges[1] = tri.edges[1];
db.triangleEdgeConnections.back().edges[2] = tri.edges[2];
for (int e = 0; e < 3; ++e) {
db.edgeMats[tri.edges[e]] = triMatIdx;
for (int v = 0; v < 2; ++v)
db.vertMats[colMesh.edges[e].verts[v]] = triMatIdx;
} }
db.vertMatsCount = colMesh.verts.size(); }
db.vertCount = colMesh.verts.size(); db.triMatsCount = colMesh.trianges.size();
db.triangleEdgesCount = colMesh.trianges.size() * 3;
db.edgeVertConnections.reserve(colMesh.edges.size()); db.materialCount = db.materials.size();
db.edgeMats.resize(colMesh.edges.size());
for (const auto& edge : colMesh.edges)
{
db.edgeVertConnections.emplace_back();
db.edgeVertConnections.back().verts[0] = edge.verts[0];
db.edgeVertConnections.back().verts[1] = edge.verts[1];
}
db.edgeMatsCount = colMesh.edges.size();
db.edgeVertsCount = colMesh.edges.size();
db.triMats.reserve(colMesh.trianges.size()); PopulateAreaFields(db, colMesh, fullAABB);
db.triangleEdgeConnections.reserve(colMesh.trianges.size());
for (const auto& tri : colMesh.trianges)
{
int triMatIdx = matPool.AddOrLookup(MakeMat(colMesh.materials[tri.matIdx], tri.flip), db.materials);
db.triMats.push_back(triMatIdx);
db.triangleEdgeConnections.emplace_back();
db.triangleEdgeConnections.back().edges[0] = tri.edges[0];
db.triangleEdgeConnections.back().edges[1] = tri.edges[1];
db.triangleEdgeConnections.back().edges[2] = tri.edges[2];
for (int e=0 ; e<3 ; ++e)
{
db.edgeMats[tri.edges[e]] = triMatIdx;
for (int v=0 ; v<2 ; ++v)
db.vertMats[colMesh.edges[e].verts[v]] = triMatIdx;
}
}
db.triMatsCount = colMesh.trianges.size();
db.triangleEdgesCount = colMesh.trianges.size() * 3;
db.materialCount = db.materials.size();
PopulateAreaFields(db, colMesh, fullAABB);
} }
template void DeafBabeBuildFromBlender<DNAMP1::DeafBabe>(DNAMP1::DeafBabe& db, const hecl::blender::ColMesh& colMesh); template void DeafBabeBuildFromBlender<DNAMP1::DeafBabe>(DNAMP1::DeafBabe& db, const hecl::blender::ColMesh& colMesh);
template void DeafBabeBuildFromBlender<DNAMP2::DeafBabe>(DNAMP2::DeafBabe& db, const hecl::blender::ColMesh& colMesh); template void DeafBabeBuildFromBlender<DNAMP2::DeafBabe>(DNAMP2::DeafBabe& db, const hecl::blender::ColMesh& colMesh);
template void DeafBabeBuildFromBlender<DNAMP1::DCLN::Collision>(DNAMP1::DCLN::Collision& db, const hecl::blender::ColMesh& colMesh); template void DeafBabeBuildFromBlender<DNAMP1::DCLN::Collision>(DNAMP1::DCLN::Collision& db,
const hecl::blender::ColMesh& colMesh);
} } // namespace DataSpec

View File

@ -2,21 +2,14 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
namespace DataSpec namespace DataSpec {
{
enum class BspNodeType : atUint32 enum class BspNodeType : atUint32 { Invalid, Branch, Leaf };
{
Invalid,
Branch,
Leaf
};
template<class DEAFBABE> template <class DEAFBABE>
void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln = false, atInt32 idx = -1); void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln = false, atInt32 idx = -1);
template<class DEAFBABE> template <class DEAFBABE>
void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh); void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh);
} } // namespace DataSpec

View File

@ -2,20 +2,17 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
namespace DataSpec::DNACommon namespace DataSpec::DNACommon {
{ struct EGMC : public BigDNA {
struct EGMC : public BigDNA AT_DECL_DNA
{ Value<atUint32> count;
struct Object : BigDNA {
AT_DECL_DNA AT_DECL_DNA
Value<atUint32> count; Value<atUint32> mesh;
Value<atUint32> instanceId;
};
struct Object : BigDNA Vector<Object, AT_DNA_COUNT(count)> objects;
{
AT_DECL_DNA
Value<atUint32> mesh;
Value<atUint32> instanceId;
};
Vector<Object, AT_DNA_COUNT(count)> objects;
}; };
} } // namespace DataSpec::DNACommon

View File

@ -1,502 +1,449 @@
#include "ELSC.hpp" #include "ELSC.hpp"
namespace DataSpec::DNAParticle namespace DataSpec::DNAParticle {
{
template <class IDType> template <class IDType>
void ELSM<IDType>::_read(athena::io::IStreamReader& r) void ELSM<IDType>::_read(athena::io::IStreamReader& r) {
{ uint32_t clsId;
uint32_t clsId; r.readBytesToBuf(&clsId, 4);
r.readBytesToBuf(&clsId, 4); if (clsId != SBIG('ELSM')) {
if (clsId != SBIG('ELSM')) LogModule.report(logvisor::Warning, "non ELSM provided to ELSM parser");
{ return;
LogModule.report(logvisor::Warning, "non ELSM provided to ELSM parser"); }
return;
}
r.readBytesToBuf(&clsId, 4); r.readBytesToBuf(&clsId, 4);
while (clsId != SBIG('_END')) while (clsId != SBIG('_END')) {
{ switch (clsId) {
switch(clsId) case SBIG('LIFE'):
{ x0_LIFE.read(r);
case SBIG('LIFE'): break;
x0_LIFE.read(r); case SBIG('SLIF'):
break; x4_SLIF.read(r);
case SBIG('SLIF'): break;
x4_SLIF.read(r); case SBIG('GRAT'):
break; x8_GRAT.read(r);
case SBIG('GRAT'): break;
x8_GRAT.read(r); case SBIG('SCNT'):
break; xc_SCNT.read(r);
case SBIG('SCNT'): break;
xc_SCNT.read(r); case SBIG('SSEG'):
break; x10_SSEG.read(r);
case SBIG('SSEG'): break;
x10_SSEG.read(r); case SBIG('COLR'):
break; x14_COLR.read(r);
case SBIG('COLR'): break;
x14_COLR.read(r); case SBIG('IEMT'):
break; x18_IEMT.read(r);
case SBIG('IEMT'): break;
x18_IEMT.read(r); case SBIG('FEMT'):
break; x1c_FEMT.read(r);
case SBIG('FEMT'): break;
x1c_FEMT.read(r); case SBIG('AMPL'):
break; x20_AMPL.read(r);
case SBIG('AMPL'): break;
x20_AMPL.read(r); case SBIG('AMPD'):
break; x24_AMPD.read(r);
case SBIG('AMPD'): break;
x24_AMPD.read(r); case SBIG('LWD1'):
break; x28_LWD1.read(r);
case SBIG('LWD1'): break;
x28_LWD1.read(r); case SBIG('LWD2'):
break; x2c_LWD2.read(r);
case SBIG('LWD2'): break;
x2c_LWD2.read(r); case SBIG('LWD3'):
break; x30_LWD3.read(r);
case SBIG('LWD3'): break;
x30_LWD3.read(r); case SBIG('LCL1'):
break; x34_LCL1.read(r);
case SBIG('LCL1'): break;
x34_LCL1.read(r); case SBIG('LCL2'):
break; x38_LCL2.read(r);
case SBIG('LCL2'): break;
x38_LCL2.read(r); case SBIG('LCL3'):
break; x3c_LCL3.read(r);
case SBIG('LCL3'): break;
x3c_LCL3.read(r); case SBIG('SSWH'):
break; x40_SSWH.read(r);
case SBIG('SSWH'): break;
x40_SSWH.read(r); case SBIG('GPSM'):
break; x50_GPSM.read(r);
case SBIG('GPSM'): break;
x50_GPSM.read(r); case SBIG('EPSM'):
break; x60_EPSM.read(r);
case SBIG('EPSM'): break;
x60_EPSM.read(r); case SBIG('ZERY'):
break; x70_ZERY.read(r);
case SBIG('ZERY'): break;
x70_ZERY.read(r); default:
break; LogModule.report(logvisor::Fatal, "Unknown ELSM class %.4s @%" PRIi64, &clsId, r.position());
default: break;
LogModule.report(logvisor::Fatal, "Unknown ELSM class %.4s @%" PRIi64, &clsId, r.position());
break;
}
r.readBytesToBuf(&clsId, 4);
} }
r.readBytesToBuf(&clsId, 4);
}
} }
template <class IDType> template <class IDType>
void ELSM<IDType>::_write(athena::io::IStreamWriter& w) const void ELSM<IDType>::_write(athena::io::IStreamWriter& w) const {
{ w.writeBytes((atInt8*)"ELSM", 4);
w.writeBytes((atInt8*)"ELSM", 4); if (x0_LIFE) {
if (x0_LIFE) w.writeBytes((atInt8*)"LIFE", 4);
{ x0_LIFE.write(w);
w.writeBytes((atInt8*)"LIFE", 4); }
x0_LIFE.write(w); if (x4_SLIF) {
} w.writeBytes((atInt8*)"SLIF", 4);
if (x4_SLIF) x4_SLIF.write(w);
{ }
w.writeBytes((atInt8*)"SLIF", 4); if (x8_GRAT) {
x4_SLIF.write(w); w.writeBytes((atInt8*)"GRAT", 4);
} x8_GRAT.write(w);
if (x8_GRAT) }
{ if (xc_SCNT) {
w.writeBytes((atInt8*)"GRAT", 4); w.writeBytes((atInt8*)"SCNT", 4);
x8_GRAT.write(w); xc_SCNT.write(w);
} }
if (xc_SCNT) if (x10_SSEG) {
{ w.writeBytes((atInt8*)"SSEG", 4);
w.writeBytes((atInt8*)"SCNT", 4); x10_SSEG.write(w);
xc_SCNT.write(w); }
} if (x14_COLR) {
if (x10_SSEG) w.writeBytes((atInt8*)"COLR", 4);
{ x14_COLR.write(w);
w.writeBytes((atInt8*)"SSEG", 4); }
x10_SSEG.write(w); if (x18_IEMT) {
} w.writeBytes((atInt8*)"IEMT", 4);
if (x14_COLR) x18_IEMT.write(w);
{ }
w.writeBytes((atInt8*)"COLR", 4); if (x1c_FEMT) {
x14_COLR.write(w); w.writeBytes((atInt8*)"FEMT", 4);
} x1c_FEMT.write(w);
if (x18_IEMT) }
{ if (x20_AMPL) {
w.writeBytes((atInt8*)"IEMT", 4); w.writeBytes((atInt8*)"AMPL", 4);
x18_IEMT.write(w); x20_AMPL.write(w);
} }
if (x1c_FEMT) if (x24_AMPD) {
{ w.writeBytes((atInt8*)"AMPD", 4);
w.writeBytes((atInt8*)"FEMT", 4); x24_AMPD.write(w);
x1c_FEMT.write(w); }
} if (x28_LWD1) {
if (x20_AMPL) w.writeBytes((atInt8*)"LWD1", 4);
{ x28_LWD1.write(w);
w.writeBytes((atInt8*)"AMPL", 4); }
x20_AMPL.write(w); if (x2c_LWD2) {
} w.writeBytes((atInt8*)"LWD2", 4);
if (x24_AMPD) x2c_LWD2.write(w);
{ }
w.writeBytes((atInt8*)"AMPD", 4); if (x30_LWD3) {
x24_AMPD.write(w); w.writeBytes((atInt8*)"LWD3", 4);
} x30_LWD3.write(w);
if (x28_LWD1) }
{ if (x34_LCL1) {
w.writeBytes((atInt8*)"LWD1", 4); w.writeBytes((atInt8*)"LCL1", 4);
x28_LWD1.write(w); x34_LCL1.write(w);
} }
if (x2c_LWD2) if (x38_LCL2) {
{ w.writeBytes((atInt8*)"LCL2", 4);
w.writeBytes((atInt8*)"LWD2", 4); x38_LCL2.write(w);
x2c_LWD2.write(w); }
} if (x3c_LCL3) {
if (x30_LWD3) w.writeBytes((atInt8*)"LCL3", 4);
{ x3c_LCL3.write(w);
w.writeBytes((atInt8*)"LWD3", 4); }
x30_LWD3.write(w); if (x40_SSWH) {
} w.writeBytes((atInt8*)"SSWH", 4);
if (x34_LCL1) x40_SSWH.write(w);
{ }
w.writeBytes((atInt8*)"LCL1", 4); if (x50_GPSM) {
x34_LCL1.write(w); w.writeBytes((atInt8*)"GPSM", 4);
} x50_GPSM.write(w);
if (x38_LCL2) }
{ if (x60_EPSM) {
w.writeBytes((atInt8*)"LCL2", 4); w.writeBytes((atInt8*)"EPSM", 4);
x38_LCL2.write(w); x60_EPSM.write(w);
} }
if (x3c_LCL3) if (x70_ZERY) {
{ w.writeBytes((atInt8*)"ZERY", 4);
w.writeBytes((atInt8*)"LCL3", 4); x70_ZERY.write(w);
x3c_LCL3.write(w); }
} w.writeBytes("_END", 4);
if (x40_SSWH)
{
w.writeBytes((atInt8*)"SSWH", 4);
x40_SSWH.write(w);
}
if (x50_GPSM)
{
w.writeBytes((atInt8*)"GPSM", 4);
x50_GPSM.write(w);
}
if (x60_EPSM)
{
w.writeBytes((atInt8*)"EPSM", 4);
x60_EPSM.write(w);
}
if (x70_ZERY)
{
w.writeBytes((atInt8*)"ZERY", 4);
x70_ZERY.write(w);
}
w.writeBytes("_END", 4);
} }
template <class IDType> template <class IDType>
void ELSM<IDType>::_binarySize(size_t& s) const void ELSM<IDType>::_binarySize(size_t& s) const {
{ s += 4;
if (x0_LIFE) {
s += 4; s += 4;
if (x0_LIFE) x0_LIFE.binarySize(s);
{ }
s += 4; if (x4_SLIF) {
x0_LIFE.binarySize(s); s += 4;
} x4_SLIF.binarySize(s);
if (x4_SLIF) }
{ if (x8_GRAT) {
s += 4; s += 4;
x4_SLIF.binarySize(s); x8_GRAT.binarySize(s);
} }
if (x8_GRAT) if (xc_SCNT) {
{ s += 4;
s += 4; xc_SCNT.binarySize(s);
x8_GRAT.binarySize(s); }
} if (x10_SSEG) {
if (xc_SCNT) s += 4;
{ x10_SSEG.binarySize(s);
s += 4; }
xc_SCNT.binarySize(s); if (x14_COLR) {
} s += 4;
if (x10_SSEG) x14_COLR.binarySize(s);
{ }
s += 4; if (x18_IEMT) {
x10_SSEG.binarySize(s); s += 4;
} x18_IEMT.binarySize(s);
if (x14_COLR) }
{ if (x1c_FEMT) {
s += 4; s += 4;
x14_COLR.binarySize(s); x1c_FEMT.binarySize(s);
} }
if (x18_IEMT) if (x20_AMPL) {
{ s += 4;
s += 4; x20_AMPL.binarySize(s);
x18_IEMT.binarySize(s); }
} if (x24_AMPD) {
if (x1c_FEMT) s += 4;
{ x24_AMPD.binarySize(s);
s += 4; }
x1c_FEMT.binarySize(s); if (x28_LWD1) {
} s += 4;
if (x20_AMPL) x28_LWD1.binarySize(s);
{ }
s += 4; if (x2c_LWD2) {
x20_AMPL.binarySize(s); s += 4;
} x2c_LWD2.binarySize(s);
if (x24_AMPD) }
{ if (x30_LWD3) {
s += 4; s += 4;
x24_AMPD.binarySize(s); x30_LWD3.binarySize(s);
} }
if (x28_LWD1) if (x34_LCL1) {
{ s += 4;
s += 4; x34_LCL1.binarySize(s);
x28_LWD1.binarySize(s); }
} if (x38_LCL2) {
if (x2c_LWD2) s += 4;
{ x38_LCL2.binarySize(s);
s += 4; }
x2c_LWD2.binarySize(s); if (x3c_LCL3) {
} s += 4;
if (x30_LWD3) x3c_LCL3.binarySize(s);
{ }
s += 4; if (x40_SSWH) {
x30_LWD3.binarySize(s); s += 4;
} x40_SSWH.binarySize(s);
if (x34_LCL1) }
{ if (x50_GPSM) {
s += 4; s += 4;
x34_LCL1.binarySize(s); x50_GPSM.binarySize(s);
} }
if (x38_LCL2) if (x60_EPSM) {
{ s += 4;
s += 4; x60_EPSM.binarySize(s);
x38_LCL2.binarySize(s); }
} if (x70_ZERY) {
if (x3c_LCL3) s += 4;
{ x70_ZERY.binarySize(s);
s += 4; }
x3c_LCL3.binarySize(s);
}
if (x40_SSWH)
{
s += 4;
x40_SSWH.binarySize(s);
}
if (x50_GPSM)
{
s += 4;
x50_GPSM.binarySize(s);
}
if (x60_EPSM)
{
s += 4;
x60_EPSM.binarySize(s);
}
if (x70_ZERY)
{
s += 4;
x70_ZERY.binarySize(s);
}
} }
template <class IDType> template <class IDType>
void ELSM<IDType>::_read(athena::io::YAMLDocReader& r) void ELSM<IDType>::_read(athena::io::YAMLDocReader& r) {
{ for (const auto& elem : r.getCurNode()->m_mapChildren) {
for (const auto& elem : r.getCurNode()->m_mapChildren) if (elem.first.size() < 4) {
{ LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str());
if (elem.first.size() < 4) continue;
{
LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str());
continue;
}
if (auto rec = r.enterSubRecord(elem.first.c_str()))
{
switch (*reinterpret_cast<const uint32_t*>(elem.first.data()))
{
case SBIG('LIFE'):
x0_LIFE.read(r);
break;
case SBIG('SLIF'):
x4_SLIF.read(r);
break;
case SBIG('GRAT'):
x8_GRAT.read(r);
break;
case SBIG('SCNT'):
xc_SCNT.read(r);
break;
case SBIG('SSEG'):
x10_SSEG.read(r);
break;
case SBIG('COLR'):
x14_COLR.read(r);
break;
case SBIG('IEMT'):
x18_IEMT.read(r);
break;
case SBIG('FEMT'):
x1c_FEMT.read(r);
break;
case SBIG('AMPL'):
x20_AMPL.read(r);
break;
case SBIG('AMPD'):
x24_AMPD.read(r);
break;
case SBIG('LWD1'):
x28_LWD1.read(r);
break;
case SBIG('LWD2'):
x2c_LWD2.read(r);
break;
case SBIG('LWD3'):
x30_LWD3.read(r);
break;
case SBIG('LCL1'):
x34_LCL1.read(r);
break;
case SBIG('LCL2'):
x38_LCL2.read(r);
break;
case SBIG('LCL3'):
x3c_LCL3.read(r);
break;
case SBIG('SSWH'):
x40_SSWH.read(r);
break;
case SBIG('GPSM'):
x50_GPSM.read(r);
break;
case SBIG('EPSM'):
x60_EPSM.read(r);
break;
case SBIG('ZERY'):
x70_ZERY.read(r);
break;
default:
break;
}
}
} }
if (auto rec = r.enterSubRecord(elem.first.c_str())) {
switch (*reinterpret_cast<const uint32_t*>(elem.first.data())) {
case SBIG('LIFE'):
x0_LIFE.read(r);
break;
case SBIG('SLIF'):
x4_SLIF.read(r);
break;
case SBIG('GRAT'):
x8_GRAT.read(r);
break;
case SBIG('SCNT'):
xc_SCNT.read(r);
break;
case SBIG('SSEG'):
x10_SSEG.read(r);
break;
case SBIG('COLR'):
x14_COLR.read(r);
break;
case SBIG('IEMT'):
x18_IEMT.read(r);
break;
case SBIG('FEMT'):
x1c_FEMT.read(r);
break;
case SBIG('AMPL'):
x20_AMPL.read(r);
break;
case SBIG('AMPD'):
x24_AMPD.read(r);
break;
case SBIG('LWD1'):
x28_LWD1.read(r);
break;
case SBIG('LWD2'):
x2c_LWD2.read(r);
break;
case SBIG('LWD3'):
x30_LWD3.read(r);
break;
case SBIG('LCL1'):
x34_LCL1.read(r);
break;
case SBIG('LCL2'):
x38_LCL2.read(r);
break;
case SBIG('LCL3'):
x3c_LCL3.read(r);
break;
case SBIG('SSWH'):
x40_SSWH.read(r);
break;
case SBIG('GPSM'):
x50_GPSM.read(r);
break;
case SBIG('EPSM'):
x60_EPSM.read(r);
break;
case SBIG('ZERY'):
x70_ZERY.read(r);
break;
default:
break;
}
}
}
} }
template <class IDType> template <class IDType>
void ELSM<IDType>::_write(athena::io::YAMLDocWriter& w) const void ELSM<IDType>::_write(athena::io::YAMLDocWriter& w) const {
{ if (x0_LIFE)
if (x0_LIFE) if (auto rec = w.enterSubRecord("LIFE"))
if (auto rec = w.enterSubRecord("LIFE")) x0_LIFE.write(w);
x0_LIFE.write(w); if (x4_SLIF)
if (x4_SLIF) if (auto rec = w.enterSubRecord("SLIF"))
if (auto rec = w.enterSubRecord("SLIF")) x4_SLIF.write(w);
x4_SLIF.write(w); if (x8_GRAT)
if (x8_GRAT) if (auto rec = w.enterSubRecord("GRAT"))
if (auto rec = w.enterSubRecord("GRAT")) x8_GRAT.write(w);
x8_GRAT.write(w); if (xc_SCNT)
if (xc_SCNT) if (auto rec = w.enterSubRecord("SCNT"))
if (auto rec = w.enterSubRecord("SCNT")) xc_SCNT.write(w);
xc_SCNT.write(w); if (x10_SSEG)
if (x10_SSEG) if (auto rec = w.enterSubRecord("SSEG"))
if (auto rec = w.enterSubRecord("SSEG")) x10_SSEG.write(w);
x10_SSEG.write(w); if (x14_COLR)
if (x14_COLR) if (auto rec = w.enterSubRecord("COLR"))
if (auto rec = w.enterSubRecord("COLR")) x14_COLR.write(w);
x14_COLR.write(w); if (x18_IEMT)
if (x18_IEMT) if (auto rec = w.enterSubRecord("IEMT"))
if (auto rec = w.enterSubRecord("IEMT")) x18_IEMT.write(w);
x18_IEMT.write(w); if (x1c_FEMT)
if (x1c_FEMT) if (auto rec = w.enterSubRecord("FEMT"))
if (auto rec = w.enterSubRecord("FEMT")) x1c_FEMT.write(w);
x1c_FEMT.write(w); if (x20_AMPL)
if (x20_AMPL) if (auto rec = w.enterSubRecord("AMPL"))
if (auto rec = w.enterSubRecord("AMPL")) x20_AMPL.write(w);
x20_AMPL.write(w); if (x24_AMPD)
if (x24_AMPD) if (auto rec = w.enterSubRecord("AMPD"))
if (auto rec = w.enterSubRecord("AMPD")) x24_AMPD.write(w);
x24_AMPD.write(w); if (x28_LWD1)
if (x28_LWD1) if (auto rec = w.enterSubRecord("LWD1"))
if (auto rec = w.enterSubRecord("LWD1")) x28_LWD1.write(w);
x28_LWD1.write(w); if (x2c_LWD2)
if (x2c_LWD2) if (auto rec = w.enterSubRecord("LWD2"))
if (auto rec = w.enterSubRecord("LWD2")) x2c_LWD2.write(w);
x2c_LWD2.write(w); if (x30_LWD3)
if (x30_LWD3) if (auto rec = w.enterSubRecord("LWD3"))
if (auto rec = w.enterSubRecord("LWD3")) x30_LWD3.write(w);
x30_LWD3.write(w); if (x34_LCL1)
if (x34_LCL1) if (auto rec = w.enterSubRecord("LCL1"))
if (auto rec = w.enterSubRecord("LCL1")) x34_LCL1.write(w);
x34_LCL1.write(w); if (x38_LCL2)
if (x38_LCL2) if (auto rec = w.enterSubRecord("LCL2"))
if (auto rec = w.enterSubRecord("LCL2")) x38_LCL2.write(w);
x38_LCL2.write(w); if (x3c_LCL3)
if (x3c_LCL3) if (auto rec = w.enterSubRecord("LCL3"))
if (auto rec = w.enterSubRecord("LCL3")) x3c_LCL3.write(w);
x3c_LCL3.write(w); if (x40_SSWH)
if (x40_SSWH) if (auto rec = w.enterSubRecord("SSWH"))
if (auto rec = w.enterSubRecord("SSWH")) x40_SSWH.write(w);
x40_SSWH.write(w); if (x50_GPSM)
if (x50_GPSM) if (auto rec = w.enterSubRecord("GPSM"))
if (auto rec = w.enterSubRecord("GPSM")) x50_GPSM.write(w);
x50_GPSM.write(w); if (x60_EPSM)
if (x60_EPSM) if (auto rec = w.enterSubRecord("EPSM"))
if (auto rec = w.enterSubRecord("EPSM")) x60_EPSM.write(w);
x60_EPSM.write(w); if (x70_ZERY)
if (x70_ZERY) if (auto rec = w.enterSubRecord("ZERY"))
if (auto rec = w.enterSubRecord("ZERY")) x70_ZERY.write(w);
x70_ZERY.write(w);
} }
AT_SUBSPECIALIZE_DNA_YAML(ELSM<UniqueID32>) AT_SUBSPECIALIZE_DNA_YAML(ELSM<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(ELSM<UniqueID64>) AT_SUBSPECIALIZE_DNA_YAML(ELSM<UniqueID64>)
template <> template <>
const char* ELSM<UniqueID32>::DNAType() { return "urde::ELSM<UniqueID32>"; } const char* ELSM<UniqueID32>::DNAType() {
return "urde::ELSM<UniqueID32>";
}
template <> template <>
const char* ELSM<UniqueID64>::DNAType() { return "urde::ELSM<UniqueID64>"; } const char* ELSM<UniqueID64>::DNAType() {
return "urde::ELSM<UniqueID64>";
}
template <class IDType> template <class IDType>
void ELSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const void ELSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
{ g_curSpec->flattenDependencies(x40_SSWH.id, pathsOut);
g_curSpec->flattenDependencies(x40_SSWH.id, pathsOut); g_curSpec->flattenDependencies(x50_GPSM.id, pathsOut);
g_curSpec->flattenDependencies(x50_GPSM.id, pathsOut); g_curSpec->flattenDependencies(x60_EPSM.id, pathsOut);
g_curSpec->flattenDependencies(x60_EPSM.id, pathsOut);
} }
template struct ELSM<UniqueID32>; template struct ELSM<UniqueID32>;
template struct ELSM<UniqueID64>; template struct ELSM<UniqueID64>;
template <class IDType> template <class IDType>
bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::FileWriter writer(outPath.getAbsolutePath()); if (writer.isOpen()) {
if (writer.isOpen()) ELSM<IDType> elsm;
{ elsm.read(rs);
ELSM<IDType> elsm; athena::io::ToYAMLStream(elsm, writer);
elsm.read(rs); return true;
athena::io::ToYAMLStream(elsm, writer); }
return true; return false;
}
return false;
} }
template bool ExtractELSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractELSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractELSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractELSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteELSM(const ELSM<IDType>& elsm, const hecl::ProjectPath& outPath) bool WriteELSM(const ELSM<IDType>& elsm, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); if (w.hasError())
if (w.hasError()) return false;
return false; elsm.write(w);
elsm.write(w); int64_t rem = w.position() % 32;
int64_t rem = w.position() % 32; if (rem)
if (rem) for (int64_t i = 0; i < 32 - rem; ++i)
for (int64_t i=0 ; i<32-rem ; ++i) w.writeUByte(0xff);
w.writeUByte(0xff); return true;
return true;
} }
template bool WriteELSM<UniqueID32>(const ELSM<UniqueID32>& gpsm, const hecl::ProjectPath& outPath); template bool WriteELSM<UniqueID32>(const ELSM<UniqueID32>& gpsm, const hecl::ProjectPath& outPath);
template bool WriteELSM<UniqueID64>(const ELSM<UniqueID64>& gpsm, const hecl::ProjectPath& outPath); template bool WriteELSM<UniqueID64>(const ELSM<UniqueID64>& gpsm, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAParticle

View File

@ -4,35 +4,33 @@
#include "PAK.hpp" #include "PAK.hpp"
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle namespace DataSpec::DNAParticle {
{
template <class IDType> template <class IDType>
struct ELSM : BigDNA struct ELSM : BigDNA {
{ AT_DECL_EXPLICIT_DNA_YAML
AT_DECL_EXPLICIT_DNA_YAML AT_SUBDECL_DNA
AT_SUBDECL_DNA IntElementFactory x0_LIFE;
IntElementFactory x0_LIFE; IntElementFactory x4_SLIF;
IntElementFactory x4_SLIF; RealElementFactory x8_GRAT;
RealElementFactory x8_GRAT; IntElementFactory xc_SCNT;
IntElementFactory xc_SCNT; IntElementFactory x10_SSEG;
IntElementFactory x10_SSEG; ColorElementFactory x14_COLR;
ColorElementFactory x14_COLR; EmitterElementFactory x18_IEMT;
EmitterElementFactory x18_IEMT; EmitterElementFactory x1c_FEMT;
EmitterElementFactory x1c_FEMT; RealElementFactory x20_AMPL;
RealElementFactory x20_AMPL; RealElementFactory x24_AMPD;
RealElementFactory x24_AMPD; RealElementFactory x28_LWD1;
RealElementFactory x28_LWD1; RealElementFactory x2c_LWD2;
RealElementFactory x2c_LWD2; RealElementFactory x30_LWD3;
RealElementFactory x30_LWD3; ColorElementFactory x34_LCL1;
ColorElementFactory x34_LCL1; ColorElementFactory x38_LCL2;
ColorElementFactory x38_LCL2; ColorElementFactory x3c_LCL3;
ColorElementFactory x3c_LCL3; ChildResourceFactory<IDType> x40_SSWH;
ChildResourceFactory<IDType> x40_SSWH; ChildResourceFactory<IDType> x50_GPSM;
ChildResourceFactory<IDType> x50_GPSM; ChildResourceFactory<IDType> x60_EPSM;
ChildResourceFactory<IDType> x60_EPSM; BoolHelper x70_ZERY;
BoolHelper x70_ZERY;
void gatherDependencies(std::vector<hecl::ProjectPath>&) const; void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
}; };
template <class IDType> template <class IDType>
@ -41,4 +39,4 @@ bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteELSM(const ELSM<IDType>& elsm, const hecl::ProjectPath& outPath); bool WriteELSM(const ELSM<IDType>& elsm, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAParticle

View File

@ -1,246 +1,231 @@
#include "FONT.hpp" #include "FONT.hpp"
namespace DataSpec::DNAFont namespace DataSpec::DNAFont {
{
logvisor::Module LogModule("urde::DNAFont"); logvisor::Module LogModule("urde::DNAFont");
template <class IDType> template <class IDType>
void FONT<IDType>::_read(athena::io::IStreamReader& __dna_reader) void FONT<IDType>::_read(athena::io::IStreamReader& __dna_reader) {
{ /* magic */
/* magic */ atUint32 magic;
atUint32 magic; __dna_reader.readBytesToBuf(&magic, 4);
__dna_reader.readBytesToBuf(&magic, 4); if (magic != SBIG('FONT')) {
if (magic != SBIG('FONT')) LogModule.report(logvisor::Fatal, "Invalid FONT magic '%s'", &magic);
{ return;
LogModule.report(logvisor::Fatal, "Invalid FONT magic '%s'", &magic); }
return; /* version */
} version = __dna_reader.readUint32Big();
/* version */ /* unknown1 */
version = __dna_reader.readUint32Big(); unknown1 = __dna_reader.readUint32Big();
/* unknown1 */ /* lineHeight */
unknown1 = __dna_reader.readUint32Big(); lineHeight = __dna_reader.readInt32Big();
/* lineHeight */ /* verticalOffset */
lineHeight = __dna_reader.readInt32Big(); verticalOffset = __dna_reader.readInt32Big();
/* verticalOffset */ /* lineMargin */
verticalOffset = __dna_reader.readInt32Big(); lineMargin = __dna_reader.readInt32Big();
/* lineMargin */ /* unknown2 */
lineMargin = __dna_reader.readInt32Big(); unknown2 = __dna_reader.readBool();
/* unknown2 */ /* unknown3 */
unknown2 = __dna_reader.readBool(); unknown3 = __dna_reader.readBool();
/* unknown3 */ /* unknown4 */
unknown3 = __dna_reader.readBool(); unknown4 = __dna_reader.readUint32Big();
/* unknown4 */ /* fontSize */
unknown4 = __dna_reader.readUint32Big(); fontSize = __dna_reader.readUint32Big();
/* fontSize */ /* name */
fontSize = __dna_reader.readUint32Big(); name = __dna_reader.readString(-1);
/* name */ /* textureId */
name = __dna_reader.readString(-1); textureId.read(__dna_reader);
/* textureId */ /* textureFormat */
textureId.read(__dna_reader); textureFormat = __dna_reader.readUint32Big();
/* textureFormat */ /* glyphCount */
textureFormat = __dna_reader.readUint32Big(); glyphCount = __dna_reader.readUint32Big();
/* glyphCount */ /* glyphs */
glyphCount = __dna_reader.readUint32Big(); for (atUint32 i = 0; i < glyphCount; i++) {
/* glyphs */ if (version < 4)
for (atUint32 i = 0; i < glyphCount; i++) glyphs.emplace_back(new GlyphMP1);
{ else
if (version < 4) glyphs.emplace_back(new GlyphMP2);
glyphs.emplace_back(new GlyphMP1); glyphs.back()->read(__dna_reader);
else }
glyphs.emplace_back(new GlyphMP2); /* kerningInfoCount */
glyphs.back()->read(__dna_reader); kerningInfoCount = __dna_reader.readUint32Big();
} /* kerningInfo */
/* kerningInfoCount */ __dna_reader.enumerate(kerningInfo, kerningInfoCount);
kerningInfoCount = __dna_reader.readUint32Big();
/* kerningInfo */
__dna_reader.enumerate(kerningInfo, kerningInfoCount);
} }
template <class IDType> template <class IDType>
void FONT<IDType>::_write(athena::io::IStreamWriter& __dna_writer) const void FONT<IDType>::_write(athena::io::IStreamWriter& __dna_writer) const {
{ /* magic */
/* magic */ __dna_writer.writeBytes((atInt8*)"FONT", 4);
__dna_writer.writeBytes((atInt8*)"FONT", 4); /* version */
/* version */ __dna_writer.writeUint32Big(version);
__dna_writer.writeUint32Big(version); /* unknown1 */
/* unknown1 */ __dna_writer.writeUint32Big(unknown1);
__dna_writer.writeUint32Big(unknown1); /* lineHeight */
/* lineHeight */ __dna_writer.writeInt32Big(lineHeight);
__dna_writer.writeInt32Big(lineHeight); /* verticalOffset */
/* verticalOffset */ __dna_writer.writeInt32Big(verticalOffset);
__dna_writer.writeInt32Big(verticalOffset); /* lineMargin */
/* lineMargin */ __dna_writer.writeInt32Big(lineMargin);
__dna_writer.writeInt32Big(lineMargin); /* unknown2 */
/* unknown2 */ __dna_writer.writeBool(unknown2);
__dna_writer.writeBool(unknown2); /* unknown3 */
/* unknown3 */ __dna_writer.writeBool(unknown3);
__dna_writer.writeBool(unknown3); /* unknown4 */
/* unknown4 */ __dna_writer.writeUint32Big(unknown4);
__dna_writer.writeUint32Big(unknown4); /* fontSize */
/* fontSize */ __dna_writer.writeUint32Big(fontSize);
__dna_writer.writeUint32Big(fontSize); /* name */
/* name */ __dna_writer.writeString(name, -1);
__dna_writer.writeString(name, -1); /* textureId */
/* textureId */ textureId.write(__dna_writer);
textureId.write(__dna_writer); /* textureFormat */
/* textureFormat */ __dna_writer.writeUint32Big(textureFormat);
__dna_writer.writeUint32Big(textureFormat); /* glyphCount */
/* glyphCount */ __dna_writer.writeUint32Big(glyphCount);
__dna_writer.writeUint32Big(glyphCount); /* glyphs */
/* glyphs */ for (const std::unique_ptr<IGlyph>& glyph : glyphs)
glyph->write(__dna_writer);
/* kerningInfoCount */
__dna_writer.writeUint32Big(kerningInfoCount);
/* kerningInfo */
__dna_writer.enumerate(kerningInfo);
}
template <class IDType>
void FONT<IDType>::_read(athena::io::YAMLDocReader& __dna_docin) {
/* version */
version = __dna_docin.readUint32("version");
/* unknown1 */
unknown1 = __dna_docin.readUint32("unknown1");
/* lineHeight */
lineHeight = __dna_docin.readInt32("lineHeight");
/* verticalOffset */
verticalOffset = __dna_docin.readInt32("verticalOffset");
/* lineMargin */
lineMargin = __dna_docin.readInt32("lineMargin");
/* unknown2 */
unknown2 = __dna_docin.readBool("unknown2");
/* unknown3 */
unknown3 = __dna_docin.readBool("unknown3");
/* unknown4 */
unknown4 = __dna_docin.readUint32("unknown4");
/* fontSize */
fontSize = __dna_docin.readUint32("fontSize");
/* name */
name = __dna_docin.readString("name");
/* textureId */
__dna_docin.enumerate("textureId", textureId);
/* textureFormat */
textureFormat = __dna_docin.readUint32("textureFormat");
/* glyphCount */
/* glyphs */
size_t count;
if (auto v = __dna_docin.enterSubVector("glyphs", count)) {
glyphCount = count;
for (atUint32 i = 0; i < glyphCount; i++) {
if (version < 4)
glyphs.emplace_back(new GlyphMP1);
else
glyphs.emplace_back(new GlyphMP2);
if (auto rec = __dna_docin.enterSubRecord(nullptr))
glyphs.back()->read(__dna_docin);
}
}
/* kerningInfoCount squelched */
/* kerningInfo */
kerningInfoCount = __dna_docin.enumerate("kerningInfo", kerningInfo);
}
template <class IDType>
void FONT<IDType>::_write(athena::io::YAMLDocWriter& __dna_docout) const {
/* version */
__dna_docout.writeUint32("version", version);
/* unknown1 */
__dna_docout.writeUint32("unknown1", unknown1);
/* lineHeight */
__dna_docout.writeInt32("lineHeight", lineHeight);
/* verticalOffset */
__dna_docout.writeInt32("verticalOffset", verticalOffset);
/* lineMargin */
__dna_docout.writeInt32("lineMargin", lineMargin);
/* unknown2 */
__dna_docout.writeBool("unknown2", unknown2);
/* unknown3 */
__dna_docout.writeBool("unknown3", unknown3);
/* unknown4 */
__dna_docout.writeUint32("unknown4", unknown4);
/* fontSize */
__dna_docout.writeUint32("fontSize", fontSize);
/* name */
__dna_docout.writeString("name", name);
/* textureId */
__dna_docout.enumerate("textureId", textureId);
/* textureFormat */
__dna_docout.writeUint32("textureFormat", textureFormat);
/* glyphCount squelched */
/* glyphs */
if (auto v = __dna_docout.enterSubVector("glyphs"))
for (const std::unique_ptr<IGlyph>& glyph : glyphs) for (const std::unique_ptr<IGlyph>& glyph : glyphs)
glyph->write(__dna_writer); if (auto rec = __dna_docout.enterSubRecord(nullptr))
/* kerningInfoCount */ glyph->write(__dna_docout);
__dna_writer.writeUint32Big(kerningInfoCount); /* kerningInfoCount squelched */
/* kerningInfo */ /* kerningInfo */
__dna_writer.enumerate(kerningInfo); __dna_docout.enumerate("kerningInfo", kerningInfo);
}
template <class IDType>
void FONT<IDType>::_read(athena::io::YAMLDocReader& __dna_docin)
{
/* version */
version = __dna_docin.readUint32("version");
/* unknown1 */
unknown1 = __dna_docin.readUint32("unknown1");
/* lineHeight */
lineHeight = __dna_docin.readInt32("lineHeight");
/* verticalOffset */
verticalOffset = __dna_docin.readInt32("verticalOffset");
/* lineMargin */
lineMargin = __dna_docin.readInt32("lineMargin");
/* unknown2 */
unknown2 = __dna_docin.readBool("unknown2");
/* unknown3 */
unknown3 = __dna_docin.readBool("unknown3");
/* unknown4 */
unknown4 = __dna_docin.readUint32("unknown4");
/* fontSize */
fontSize = __dna_docin.readUint32("fontSize");
/* name */
name = __dna_docin.readString("name");
/* textureId */
__dna_docin.enumerate("textureId", textureId);
/* textureFormat */
textureFormat = __dna_docin.readUint32("textureFormat");
/* glyphCount */
/* glyphs */
size_t count;
if (auto v = __dna_docin.enterSubVector("glyphs", count))
{
glyphCount = count;
for (atUint32 i = 0; i < glyphCount; i++)
{
if (version < 4)
glyphs.emplace_back(new GlyphMP1);
else
glyphs.emplace_back(new GlyphMP2);
if (auto rec = __dna_docin.enterSubRecord(nullptr))
glyphs.back()->read(__dna_docin);
}
}
/* kerningInfoCount squelched */
/* kerningInfo */
kerningInfoCount = __dna_docin.enumerate("kerningInfo", kerningInfo);
}
template <class IDType>
void FONT<IDType>::_write(athena::io::YAMLDocWriter& __dna_docout) const
{
/* version */
__dna_docout.writeUint32("version", version);
/* unknown1 */
__dna_docout.writeUint32("unknown1", unknown1);
/* lineHeight */
__dna_docout.writeInt32("lineHeight", lineHeight);
/* verticalOffset */
__dna_docout.writeInt32("verticalOffset", verticalOffset);
/* lineMargin */
__dna_docout.writeInt32("lineMargin", lineMargin);
/* unknown2 */
__dna_docout.writeBool("unknown2", unknown2);
/* unknown3 */
__dna_docout.writeBool("unknown3", unknown3);
/* unknown4 */
__dna_docout.writeUint32("unknown4", unknown4);
/* fontSize */
__dna_docout.writeUint32("fontSize", fontSize);
/* name */
__dna_docout.writeString("name", name);
/* textureId */
__dna_docout.enumerate("textureId", textureId);
/* textureFormat */
__dna_docout.writeUint32("textureFormat", textureFormat);
/* glyphCount squelched */
/* glyphs */
if (auto v = __dna_docout.enterSubVector("glyphs"))
for (const std::unique_ptr<IGlyph>& glyph : glyphs)
if (auto rec = __dna_docout.enterSubRecord(nullptr))
glyph->write(__dna_docout);
/* kerningInfoCount squelched */
/* kerningInfo */
__dna_docout.enumerate("kerningInfo", kerningInfo);
} }
template <> template <>
const char* FONT<UniqueID32>::DNAType() const char* FONT<UniqueID32>::DNAType() {
{ return "FONT<UniqueID32>";
return "FONT<UniqueID32>";
} }
template <> template <>
const char* FONT<UniqueID64>::DNAType() const char* FONT<UniqueID64>::DNAType() {
{ return "FONT<UniqueID64>";
return "FONT<UniqueID64>";
} }
template <class IDType> template <class IDType>
void FONT<IDType>::_binarySize(size_t& __isz) const void FONT<IDType>::_binarySize(size_t& __isz) const {
{ __isz += name.size() + 1;
__isz += name.size() + 1; textureId.binarySize(__isz);
textureId.binarySize(__isz); for (const std::unique_ptr<IGlyph>& glyph : glyphs)
for (const std::unique_ptr<IGlyph>& glyph : glyphs) glyph->binarySize(__isz);
glyph->binarySize(__isz); for (const KerningInfo& k : kerningInfo)
for (const KerningInfo& k : kerningInfo) k.binarySize(__isz);
k.binarySize(__isz); __isz += 46;
__isz += 46;
} }
AT_SUBSPECIALIZE_DNA_YAML(FONT<UniqueID32>) AT_SUBSPECIALIZE_DNA_YAML(FONT<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(FONT<UniqueID64>) AT_SUBSPECIALIZE_DNA_YAML(FONT<UniqueID64>)
template <class IDType> template <class IDType>
bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::FileWriter writer(outPath.getAbsolutePath()); if (writer.isOpen()) {
if (writer.isOpen()) FONT<IDType> font;
{ font.read(rs);
FONT<IDType> font; athena::io::ToYAMLStream(font, writer);
font.read(rs); return true;
athena::io::ToYAMLStream(font, writer); }
return true; return false;
}
return false;
} }
template bool ExtractFONT<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractFONT<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractFONT<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractFONT<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath) bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); if (w.hasError())
if (w.hasError()) return false;
return false; font.write(w);
font.write(w); int64_t rem = w.position() % 32;
int64_t rem = w.position() % 32; if (rem)
if (rem) for (int64_t i = 0; i < 32 - rem; ++i)
for (int64_t i=0 ; i<32-rem ; ++i) w.writeUByte(0xff);
w.writeUByte(0xff); return true;
return true;
} }
template bool WriteFONT<UniqueID32>(const FONT<UniqueID32>& font, const hecl::ProjectPath& outPath); template bool WriteFONT<UniqueID32>(const FONT<UniqueID32>& font, const hecl::ProjectPath& outPath);
template bool WriteFONT<UniqueID64>(const FONT<UniqueID64>& font, const hecl::ProjectPath& outPath); template bool WriteFONT<UniqueID64>(const FONT<UniqueID64>& font, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAFont

View File

@ -3,117 +3,109 @@
#include "PAK.hpp" #include "PAK.hpp"
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
namespace DataSpec::DNAFont namespace DataSpec::DNAFont {
{ struct GlyphRect : BigDNA {
struct GlyphRect : BigDNA AT_DECL_DNA_YAML
{ Value<float> left;
AT_DECL_DNA_YAML Value<float> top;
Value<float> left; Value<float> right;
Value<float> top; Value<float> bottom;
Value<float> right;
Value<float> bottom;
}; };
struct IGlyph : BigDNAVYaml struct IGlyph : BigDNAVYaml {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML Value<atUint16> m_character;
Value<atUint16> m_character; GlyphRect m_glyphRect;
GlyphRect m_glyphRect;
atUint16 character() const { return m_character; } atUint16 character() const { return m_character; }
float left() const { return m_glyphRect.left; } float left() const { return m_glyphRect.left; }
float top() const { return m_glyphRect.top; } float top() const { return m_glyphRect.top; }
float right() const { return m_glyphRect.right; } float right() const { return m_glyphRect.right; }
float bottom() const { return m_glyphRect.bottom; } float bottom() const { return m_glyphRect.bottom; }
GlyphRect rect() const { return m_glyphRect; } GlyphRect rect() const { return m_glyphRect; }
virtual atInt32 layer() const { return 0; } virtual atInt32 layer() const { return 0; }
virtual atInt32 leftPadding() const=0; virtual atInt32 leftPadding() const = 0;
virtual atInt32 advance() const =0; virtual atInt32 advance() const = 0;
virtual atInt32 rightPadding() const=0; virtual atInt32 rightPadding() const = 0;
virtual atInt32 width() const=0; virtual atInt32 width() const = 0;
virtual atInt32 height() const=0; virtual atInt32 height() const = 0;
virtual atInt32 baseline() const=0; virtual atInt32 baseline() const = 0;
virtual atInt32 kerningIndex() const =0; virtual atInt32 kerningIndex() const = 0;
}; };
struct GlyphMP1 : IGlyph struct GlyphMP1 : IGlyph {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML AT_DECL_DNAV
AT_DECL_DNAV Value<atInt32> m_leftPadding;
Value<atInt32> m_leftPadding; Value<atInt32> m_advance;
Value<atInt32> m_advance; Value<atInt32> m_rightPadding;
Value<atInt32> m_rightPadding; Value<atInt32> m_width;
Value<atInt32> m_width; Value<atInt32> m_height;
Value<atInt32> m_height; Value<atInt32> m_baseline;
Value<atInt32> m_baseline; Value<atInt32> m_kerningIndex;
Value<atInt32> m_kerningIndex;
atInt32 leftPadding() const { return m_leftPadding; } atInt32 leftPadding() const { return m_leftPadding; }
atInt32 advance() const { return m_advance; } atInt32 advance() const { return m_advance; }
atInt32 rightPadding() const { return m_rightPadding; } atInt32 rightPadding() const { return m_rightPadding; }
atInt32 width() const { return m_width; } atInt32 width() const { return m_width; }
atInt32 height() const { return m_height; } atInt32 height() const { return m_height; }
atInt32 baseline() const { return m_baseline; } atInt32 baseline() const { return m_baseline; }
atInt32 kerningIndex() const { return m_kerningIndex; } atInt32 kerningIndex() const { return m_kerningIndex; }
}; };
struct GlyphMP2 : IGlyph struct GlyphMP2 : IGlyph {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML AT_DECL_DNAV
AT_DECL_DNAV Value<atInt8> m_layer;
Value<atInt8> m_layer; Value<atInt8> m_leftPadding;
Value<atInt8> m_leftPadding; Value<atInt8> m_advance;
Value<atInt8> m_advance; Value<atInt8> m_rightPadding;
Value<atInt8> m_rightPadding; Value<atInt8> m_width;
Value<atInt8> m_width; Value<atInt8> m_height;
Value<atInt8> m_height; Value<atInt8> m_baseline;
Value<atInt8> m_baseline; Value<atInt16> m_kerningIndex;
Value<atInt16> m_kerningIndex;
atInt32 layer() const { return m_layer; } atInt32 layer() const { return m_layer; }
atInt32 leftPadding() const { return m_leftPadding; } atInt32 leftPadding() const { return m_leftPadding; }
atInt32 advance() const { return m_advance; } atInt32 advance() const { return m_advance; }
atInt32 rightPadding() const { return m_rightPadding; } atInt32 rightPadding() const { return m_rightPadding; }
atInt32 width() const { return m_width; } atInt32 width() const { return m_width; }
atInt32 height() const { return m_height; } atInt32 height() const { return m_height; }
atInt32 baseline() const { return m_baseline; } atInt32 baseline() const { return m_baseline; }
atInt32 kerningIndex() const { return m_kerningIndex; } atInt32 kerningIndex() const { return m_kerningIndex; }
}; };
struct KerningInfo : BigDNA struct KerningInfo : BigDNA {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML Value<atUint16> thisChar;
Value<atUint16> thisChar; Value<atUint16> nextChar;
Value<atUint16> nextChar; Value<atInt32> adjust;
Value<atInt32> adjust;
}; };
template <class IDType> template <class IDType>
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FONT : BigDNA struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FONT : BigDNA {
{ AT_DECL_EXPLICIT_DNA_YAML
AT_DECL_EXPLICIT_DNA_YAML AT_SUBDECL_DNA
AT_SUBDECL_DNA Value<atUint32> version;
Value<atUint32> version; Value<atUint32> unknown1;
Value<atUint32> unknown1; Value<atInt32> lineHeight;
Value<atInt32> lineHeight; Value<atInt32> verticalOffset;
Value<atInt32> verticalOffset; Value<atInt32> lineMargin;
Value<atInt32> lineMargin; Value<bool> unknown2;
Value<bool> unknown2; Value<bool> unknown3;
Value<bool> unknown3; Value<atUint32> unknown4;
Value<atUint32> unknown4; Value<atUint32> fontSize; // in points
Value<atUint32> fontSize; // in points String<-1> name;
String<-1> name; Value<IDType> textureId;
Value<IDType> textureId; Value<atUint32> textureFormat;
Value<atUint32> textureFormat; Value<atUint32> glyphCount;
Value<atUint32> glyphCount; std::vector<std::unique_ptr<IGlyph>> glyphs;
std::vector<std::unique_ptr<IGlyph>> glyphs; Value<atUint32> kerningInfoCount;
Value<atUint32> kerningInfoCount; Vector<KerningInfo, AT_DNA_COUNT(kerningInfoCount)> kerningInfo;
Vector<KerningInfo, AT_DNA_COUNT(kerningInfoCount)> kerningInfo;
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
{ g_curSpec->flattenDependencies(textureId, pathsOut);
g_curSpec->flattenDependencies(textureId, pathsOut); }
}
}; };
template <class IDType> template <class IDType>
@ -122,5 +114,4 @@ bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath); bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAFont

View File

@ -4,82 +4,75 @@
#include "FSM2.hpp" #include "FSM2.hpp"
namespace DataSpec::DNAFSM2 namespace DataSpec::DNAFSM2 {
{
logvisor::Module LogDNAFSM2("urde::DNAFSM2"); logvisor::Module LogDNAFSM2("urde::DNAFSM2");
template <class IDType> template <class IDType>
template <class Op> template <class Op>
void FSM2<IDType>::Enumerate(typename Op::StreamT& s) void FSM2<IDType>::Enumerate(typename Op::StreamT& s) {
{ Do<Op>({"header"}, header, s);
Do<Op>({"header"}, header, s); if (header.magic != SBIG('FSM2')) {
if (header.magic != SBIG('FSM2')) LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 magic '%.4s' expected 'FSM2'", header.magic.toString().c_str());
{ return;
LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 magic '%.4s' expected 'FSM2'", header.magic.toString().c_str()); }
return;
}
if (header.version == 1) if (header.version == 1) {
{ if (!detail)
if (!detail) detail.reset(new FSMV1);
detail.reset(new FSMV1); Do<Op>({"detail"}, static_cast<FSMV1&>(*detail), s);
Do<Op>({"detail"}, static_cast<FSMV1&>(*detail), s); } else if (header.version == 2) {
} if (!detail)
else if (header.version == 2) detail.reset(new FSMV2);
{ Do<Op>({"detail"}, static_cast<FSMV2&>(*detail), s);
if (!detail) } else {
detail.reset(new FSMV2); LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 version '%i'", header.version);
Do<Op>({"detail"}, static_cast<FSMV2&>(*detail), s); return;
} }
else
{
LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 version '%i'", header.version);
return;
}
} }
AT_SPECIALIZE_DNA(FSM2<UniqueID32>) AT_SPECIALIZE_DNA(FSM2<UniqueID32>)
AT_SPECIALIZE_DNA(FSM2<UniqueID64>) AT_SPECIALIZE_DNA(FSM2<UniqueID64>)
template <> template <>
const char* FSM2<UniqueID32>::DNAType() { return "urde::FSM2<UniqueID32>"; } const char* FSM2<UniqueID32>::DNAType() {
return "urde::FSM2<UniqueID32>";
}
template <> template <>
const char* FSM2<UniqueID64>::DNAType() { return "urde::FSM2<UniqueID64>"; } const char* FSM2<UniqueID64>::DNAType() {
return "urde::FSM2<UniqueID64>";
}
template struct FSM2<UniqueID32>; template struct FSM2<UniqueID32>;
template struct FSM2<UniqueID64>; template struct FSM2<UniqueID64>;
template <class IDType> template <class IDType>
bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::FileWriter writer(outPath.getAbsolutePath()); if (writer.isOpen()) {
if (writer.isOpen()) FSM2<IDType> fsm2;
{ fsm2.read(rs);
FSM2<IDType> fsm2; athena::io::ToYAMLStream(fsm2, writer);
fsm2.read(rs); return true;
athena::io::ToYAMLStream(fsm2, writer); }
return true; return false;
}
return false;
} }
template bool ExtractFSM2<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractFSM2<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractFSM2<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); template bool ExtractFSM2<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath) bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); if (w.hasError())
if (w.hasError()) return false;
return false; fsm2.write(w);
fsm2.write(w); int64_t rem = w.position() % 32;
int64_t rem = w.position() % 32; if (rem)
if (rem) for (int64_t i = 0; i < 32 - rem; ++i)
for (int64_t i=0 ; i<32-rem ; ++i) w.writeUByte(0xff);
w.writeUByte(0xff); return true;
return true;
} }
template bool WriteFSM2<UniqueID32>(const FSM2<UniqueID32>& fsm2, const hecl::ProjectPath& outPath); template bool WriteFSM2<UniqueID32>(const FSM2<UniqueID32>& fsm2, const hecl::ProjectPath& outPath);
template bool WriteFSM2<UniqueID64>(const FSM2<UniqueID64>& fsm2, const hecl::ProjectPath& outPath); template bool WriteFSM2<UniqueID64>(const FSM2<UniqueID64>& fsm2, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAFSM2

View File

@ -4,146 +4,131 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
namespace DataSpec::DNAFSM2 namespace DataSpec::DNAFSM2 {
{ struct IFSM : BigDNAVYaml {
struct IFSM : BigDNAVYaml Delete _d;
{
Delete _d;
}; };
template <class IDType> template <class IDType>
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : BigDNA struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : BigDNA {
{ struct Header : BigDNA {
struct Header : BigDNA AT_DECL_DNA_YAML
{ DNAFourCC magic = FOURCC('FSM2');
AT_DECL_DNA_YAML Value<atUint32> version;
DNAFourCC magic = FOURCC('FSM2'); } header;
Value<atUint32> version;
} header;
struct CommonStruct : BigDNA struct CommonStruct : BigDNA {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML String<-1> name;
String<-1> name; Value<atUint32> unknown;
Value<atUint32> unknown; };
struct FSMV1 : IFSM {
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atUint32> stateCount;
Value<atUint32> unknown1Count;
Value<atUint32> unknown2Count;
Value<atUint32> unknown3Count;
struct State : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknownCount;
Vector<CommonStruct, AT_DNA_COUNT(unknownCount)> unknown;
}; };
struct FSMV1 : IFSM struct Unknown1 : BigDNA {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML String<-1> name;
AT_DECL_DNAV Value<float> unknown1;
Value<atUint32> stateCount; Value<atUint32> unknown2Count;
Value<atUint32> unknown1Count; Vector<CommonStruct, AT_DNA_COUNT(unknown2Count)> unknown2;
Value<atUint32> unknown2Count; Value<atUint8> unknown3;
Value<atUint32> unknown3Count;
struct State : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknownCount;
Vector<CommonStruct, AT_DNA_COUNT(unknownCount)> unknown;
};
struct Unknown1 : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<float> unknown1;
Value<atUint32> unknown2Count;
Vector<CommonStruct, AT_DNA_COUNT(unknown2Count)> unknown2;
Value<atUint8> unknown3;
};
struct Unknown2 : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknownCount;
Vector<CommonStruct, AT_DNA_COUNT(unknownCount)> unknown;
};
struct Unknown3 : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknownCount;
Vector<CommonStruct, AT_DNA_COUNT(unknownCount)> unknown;
Value<IDType> fsmId;
};
Vector<State, AT_DNA_COUNT(stateCount)> states;
Vector<Unknown1, AT_DNA_COUNT(unknown1Count)> unknown1;
Vector<Unknown2, AT_DNA_COUNT(unknown2Count)> unknown2;
Vector<Unknown3, AT_DNA_COUNT(unknown3Count)> unknown3;
}; };
struct FSMV2 : IFSM struct Unknown2 : BigDNA {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML String<-1> name;
AT_DECL_DNAV Value<atUint32> unknownCount;
Value<atUint32> stateCount; Vector<CommonStruct, AT_DNA_COUNT(unknownCount)> unknown;
Value<atUint32> unknown1Count;
Value<atUint32> unknown2Count;
Value<atUint32> unknown3Count;
struct State : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> unknown2;
Value<atUint32> unknown3;
Value<atUint32> unknown4;
Value<atUint32> unknown5Count;
Vector<CommonStruct, AT_DNA_COUNT(unknown5Count)> unknown5;
};
struct Unknown1 : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> unknown2;
Value<atUint32> unknown3;
Value<atUint32> unknown4;
Value<float> unknown5;
Value<atUint32> unknown6Count;
Vector<CommonStruct, AT_DNA_COUNT(unknown6Count)> unknown6;
Value<atUint8> unknown7;
};
struct Unknown2 : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> unknown2;
Value<atUint32> unknown3;
Value<atUint32> unknown4;
Value<atUint32> unknown5Count;
Vector<CommonStruct, AT_DNA_COUNT(unknown5Count)> unknown5;
};
struct Unknown3 : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> unknown2;
Value<atUint32> unknown3;
Value<atUint32> unknown4;
Value<atUint32> unknown5Count;
Vector<CommonStruct, AT_DNA_COUNT(unknown5Count)> unknown5;
Value<IDType> fsmId;
};
Vector<State, AT_DNA_COUNT(stateCount)> states;
Vector<Unknown1, AT_DNA_COUNT(unknown1Count)> unknown1;
Vector<Unknown2, AT_DNA_COUNT(unknown2Count)> unknown2;
Vector<Unknown3, AT_DNA_COUNT(unknown3Count)> unknown3;
}; };
std::unique_ptr<IFSM> detail; struct Unknown3 : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknownCount;
Vector<CommonStruct, AT_DNA_COUNT(unknownCount)> unknown;
Value<IDType> fsmId;
};
Vector<State, AT_DNA_COUNT(stateCount)> states;
Vector<Unknown1, AT_DNA_COUNT(unknown1Count)> unknown1;
Vector<Unknown2, AT_DNA_COUNT(unknown2Count)> unknown2;
Vector<Unknown3, AT_DNA_COUNT(unknown3Count)> unknown3;
};
struct FSMV2 : IFSM {
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atUint32> stateCount;
Value<atUint32> unknown1Count;
Value<atUint32> unknown2Count;
Value<atUint32> unknown3Count;
struct State : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> unknown2;
Value<atUint32> unknown3;
Value<atUint32> unknown4;
Value<atUint32> unknown5Count;
Vector<CommonStruct, AT_DNA_COUNT(unknown5Count)> unknown5;
};
struct Unknown1 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> unknown2;
Value<atUint32> unknown3;
Value<atUint32> unknown4;
Value<float> unknown5;
Value<atUint32> unknown6Count;
Vector<CommonStruct, AT_DNA_COUNT(unknown6Count)> unknown6;
Value<atUint8> unknown7;
};
struct Unknown2 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> unknown2;
Value<atUint32> unknown3;
Value<atUint32> unknown4;
Value<atUint32> unknown5Count;
Vector<CommonStruct, AT_DNA_COUNT(unknown5Count)> unknown5;
};
struct Unknown3 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> unknown2;
Value<atUint32> unknown3;
Value<atUint32> unknown4;
Value<atUint32> unknown5Count;
Vector<CommonStruct, AT_DNA_COUNT(unknown5Count)> unknown5;
Value<IDType> fsmId;
};
Vector<State, AT_DNA_COUNT(stateCount)> states;
Vector<Unknown1, AT_DNA_COUNT(unknown1Count)> unknown1;
Vector<Unknown2, AT_DNA_COUNT(unknown2Count)> unknown2;
Vector<Unknown3, AT_DNA_COUNT(unknown3Count)> unknown3;
};
std::unique_ptr<IFSM> detail;
AT_DECL_EXPLICIT_DNA_YAML
}; };
template <class IDType> template <class IDType>
@ -151,4 +136,4 @@ bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath); bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAFSM2

View File

@ -2,4 +2,3 @@
#include "hecl/Backend/GX.hpp" #include "hecl/Backend/GX.hpp"
using GX = hecl::Backend::GX; using GX = hecl::Backend::GX;

View File

@ -9,487 +9,419 @@
#include "zeus/CAABox.hpp" #include "zeus/CAABox.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMAPA namespace DataSpec::DNAMAPA {
{
static logvisor::Module Log("DNAMAPA"); static logvisor::Module Log("DNAMAPA");
template <> template <>
void MAPA::Enumerate<BigDNA::Read>(typename Read::StreamT& __dna_reader) void MAPA::Enumerate<BigDNA::Read>(typename Read::StreamT& __dna_reader) {
{ /* magic */
/* magic */ magic = __dna_reader.readUint32Big();
magic = __dna_reader.readUint32Big(); if (magic != 0xDEADD00D) {
if (magic != 0xDEADD00D) LogDNACommon.report(logvisor::Error, "invalid MAPA magic");
{ return;
LogDNACommon.report(logvisor::Error, "invalid MAPA magic"); }
return; /* version */
} version = __dna_reader.readUint32Big();
/* version */ if (version == 2)
version = __dna_reader.readUint32Big(); header.reset(new HeaderMP1);
if (version == 2) else if (version == 3)
header.reset(new HeaderMP1); header.reset(new HeaderMP2);
else if (version == 3) else if (version == 5)
header.reset(new HeaderMP2); header.reset(new HeaderMP3);
else if (version == 5) else {
header.reset(new HeaderMP3); LogDNACommon.report(logvisor::Error, "invalid MAPA version");
return;
}
header->read(__dna_reader);
for (atUint32 i = 0; i < header->mappableObjectCount(); i++) {
std::unique_ptr<IMappableObject> mo = nullptr;
if (version != 5)
mo.reset(new MappableObjectMP1_2);
else else
{ mo.reset(new MappableObjectMP3);
LogDNACommon.report(logvisor::Error, "invalid MAPA version"); mo->read(__dna_reader);
return; mappableObjects.push_back(std::move(mo));
} }
header->read(__dna_reader); /* vertices */
__dna_reader.enumerateBig(vertices, header->vertexCount());
for (atUint32 i = 0; i < header->mappableObjectCount(); i++) /* surfaceHeaders */
{ __dna_reader.enumerate(surfaceHeaders, header->surfaceCount());
std::unique_ptr<IMappableObject> mo = nullptr; /* surfaces */
if (version != 5) __dna_reader.enumerate(surfaces, header->surfaceCount());
mo.reset(new MappableObjectMP1_2);
else
mo.reset(new MappableObjectMP3);
mo->read(__dna_reader);
mappableObjects.push_back(std::move(mo));
}
/* vertices */
__dna_reader.enumerateBig(vertices, header->vertexCount());
/* surfaceHeaders */
__dna_reader.enumerate(surfaceHeaders, header->surfaceCount());
/* surfaces */
__dna_reader.enumerate(surfaces, header->surfaceCount());
} }
template <> template <>
void MAPA::Enumerate<BigDNA::Write>(typename Write::StreamT& __dna_writer) void MAPA::Enumerate<BigDNA::Write>(typename Write::StreamT& __dna_writer) {
{ /* magic */
/* magic */ __dna_writer.writeUint32Big(magic);
__dna_writer.writeUint32Big(magic); /* version */
/* version */ __dna_writer.writeUint32Big(version);
__dna_writer.writeUint32Big(version); header->write(__dna_writer);
header->write(__dna_writer);
/* mappableObjects */ /* mappableObjects */
for (const std::unique_ptr<IMappableObject>& mo : mappableObjects) for (const std::unique_ptr<IMappableObject>& mo : mappableObjects)
mo->write(__dna_writer); mo->write(__dna_writer);
/* vertices */ /* vertices */
__dna_writer.enumerateBig(vertices); __dna_writer.enumerateBig(vertices);
/* surfaceHeaders */ /* surfaceHeaders */
__dna_writer.enumerate(surfaceHeaders); __dna_writer.enumerate(surfaceHeaders);
/* surfaces */ /* surfaces */
__dna_writer.enumerate(surfaces); __dna_writer.enumerate(surfaces);
} }
template <> template <>
void MAPA::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) void MAPA::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
{ header->binarySize(s);
header->binarySize(s);
for (const std::unique_ptr<IMappableObject>& mo : mappableObjects) for (const std::unique_ptr<IMappableObject>& mo : mappableObjects)
mo->binarySize(s); mo->binarySize(s);
s += vertices.size() * 12; s += vertices.size() * 12;
for (const SurfaceHeader& sh : surfaceHeaders) for (const SurfaceHeader& sh : surfaceHeaders)
sh.binarySize(s); sh.binarySize(s);
for (const Surface& su : surfaces) for (const Surface& su : surfaces)
su.binarySize(s); su.binarySize(s);
s += 8; s += 8;
} }
static const char* RetroMapVisModes[] = static const char* RetroMapVisModes[] = {"ALWAYS", "MAPSTATIONORVISIT", "VISIT", "NEVER"};
{
"ALWAYS",
"MAPSTATIONORVISIT",
"VISIT",
"NEVER"
};
static const char* RetroMapObjVisModes[] = static const char* RetroMapObjVisModes[] = {"ALWAYS", "MAPSTATIONORVISIT", "VISIT", "NEVER", "MAPSTATIONORVISIT2"};
{
"ALWAYS",
"MAPSTATIONORVISIT",
"VISIT",
"NEVER",
"MAPSTATIONORVISIT2"
};
template <typename PAKRouter> template <typename PAKRouter>
bool ReadMAPAToBlender(hecl::blender::Connection& conn, bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const hecl::ProjectPath& outPath,
const MAPA& mapa, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force) {
const hecl::ProjectPath& outPath, if (!force && outPath.isFile())
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
bool force)
{
if (!force && outPath.isFile())
return true;
if (!conn.createBlend(outPath, hecl::blender::BlendType::MapArea))
return false;
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os << "import bpy, bmesh\n"
"from mathutils import Matrix\n"
"\n"
"bpy.types.Object.retro_mappable_type = bpy.props.IntProperty(name='Retro: MAPA object type', default=-1)\n"
"bpy.types.Object.retro_mappable_sclyid = bpy.props.StringProperty(name='Retro: MAPA object SCLY ID')\n"
"bpy.types.Scene.retro_map_vis_mode = bpy.props.EnumProperty(items=[('ALWAYS', 'Always', 'Always Visible', 0),"
"('MAPSTATIONORVISIT', 'Map Station or Visit', 'Visible after Map Station or Visit', 1),"
"('VISIT', 'Visit', 'Visible after Visit', 2),"
"('NEVER', 'Never', 'Never Visible', 3)],"
"name='Retro: Map Visibility Mode')\n"
"bpy.types.Object.retro_mapobj_vis_mode = bpy.props.EnumProperty(items=[('ALWAYS', 'Always', 'Always Visible', 0),"
"('MAPSTATIONORVISIT', 'Map Station or Visit', 'Visible after Map Station or Visit', 1),"
"('VISIT', 'Visit', 'Visible after Door Visit', 2),"
"('NEVER', 'Never', 'Never Visible', 3),"
"('MAPSTATIONORVISIT2', 'Map Station or Visit 2', 'Visible after Map Station or Visit', 4)],"
"name='Retro: Map Object Visibility Mode')\n"
"\n"
"for ar in bpy.context.screen.areas:\n"
" for sp in ar.spaces:\n"
" if sp.type == 'VIEW_3D':\n"
" sp.viewport_shade = 'SOLID'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"\n"
"def add_triangle(bm, verts):\n"
" verts = [bm.verts[vi] for vi in verts]\n"
" face = bm.faces.get(verts)\n"
" if face:\n"
" face = face.copy()\n"
" bm.verts.ensure_lookup_table()\n"
" face.normal_flip()\n"
" else:\n"
" bm.faces.new(verts)\n"
"\n"
"def add_border(bm, verts):\n"
" verts = [bm.verts[vi] for vi in verts]\n"
" edge = bm.edges.get(verts)\n"
" if not edge:\n"
" edge = bm.edges.new(verts)\n"
" edge.seam = True\n"
"\n";
os.format("bpy.context.scene.name = 'MAPA_%s'\n"
"bpy.context.scene.retro_map_vis_mode = '%s'\n",
entry.id.toString().c_str(),
RetroMapVisModes[mapa.header->visMode()]);
/* Add empties representing MappableObjects */
int moIdx = 0;
for (const std::unique_ptr<MAPA::IMappableObject>& mo : mapa.mappableObjects)
{
if (mapa.version < 5)
{
const MAPA::MappableObjectMP1_2* moMP12 = static_cast<const MAPA::MappableObjectMP1_2*>(mo.get());
zeus::simd_floats mtxF[3];
for (int i = 0; i < 3; ++i)
moMP12->transformMtx[i].simd.copy_to(mtxF[i]);
os.format("obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
"bpy.context.scene.objects.link(obj)\n"
"obj.retro_mappable_type = %d\n"
"obj.retro_mapobj_vis_mode = '%s'\n"
"obj.retro_mappable_sclyid = '0x%08X'\n"
"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",
moIdx, moMP12->type, RetroMapObjVisModes[moMP12->visMode], moMP12->sclyId,
mtxF[0][0], mtxF[0][1], mtxF[0][2], mtxF[0][3],
mtxF[1][0], mtxF[1][1], mtxF[1][2], mtxF[1][3],
mtxF[2][0], mtxF[2][1], mtxF[2][2], mtxF[2][3]);
++moIdx;
continue;
}
else
{
const MAPA::MappableObjectMP3* moMP3 = static_cast<const MAPA::MappableObjectMP3*>(mo.get());
zeus::simd_floats mtxF[3];
for (int i = 0; i < 3; ++i)
moMP3->transformMtx[i].simd.copy_to(mtxF[i]);
os.format("obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
"bpy.context.scene.objects.link(obj)\n"
"obj.retro_mappable_type = %d\n"
"obj.retro_mapobj_vis_mode = '%s'\n"
"obj.retro_mappable_sclyid = '0x%08X'\n"
"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",
moIdx, moMP3->type, RetroMapObjVisModes[moMP3->visMode], moMP3->sclyId,
mtxF[0][0], mtxF[0][1], mtxF[0][2], mtxF[0][3],
mtxF[1][0], mtxF[1][1], mtxF[1][2], mtxF[1][3],
mtxF[2][0], mtxF[2][1], mtxF[2][2], mtxF[2][3]);
++moIdx;
continue;
}
}
os << "# Begin bmesh\n"
"bm = bmesh.new()\n"
"\n";
/* Read in verts */
for (const atVec3f& vert : mapa.vertices)
{
zeus::simd_floats f(vert.simd);
os.format("bm.verts.new((%f,%f,%f))\n", f[0], f[1], f[2]);
}
os << "bm.verts.ensure_lookup_table()\n";
/* Read in surfaces */
for (const typename MAPA::Surface& surf : mapa.surfaces)
{
for (const typename MAPA::Surface::Primitive& prim : surf.primitives)
{
auto iit = prim.indices.cbegin();
/* 3 Prim Verts to start */
int c = 0;
unsigned int primVerts[3] =
{
*iit++,
*iit++,
*iit++
};
if (GX::Primitive(prim.type) == GX::TRIANGLESTRIP)
{
atUint8 flip = 0;
for (size_t v=0 ; v<prim.indexCount-2 ; ++v)
{
if (flip)
{
os.format("add_triangle(bm, (%u,%u,%u))\n",
primVerts[c%3],
primVerts[(c+2)%3],
primVerts[(c+1)%3]);
}
else
{
os.format("add_triangle(bm, (%u,%u,%u))\n",
primVerts[c%3],
primVerts[(c+1)%3],
primVerts[(c+2)%3]);
}
flip ^= 1;
/* Break if done */
if (iit == prim.indices.cend())
break;
bool peek = (v >= prim.indexCount - 3);
/* Advance one prim vert */
if (peek)
primVerts[c%3] = *iit;
else
primVerts[c%3] = *iit++;
++c;
}
}
else if (GX::Primitive(prim.type) == GX::TRIANGLES)
{
for (size_t v=0 ; v<prim.indexCount ; v+=3)
{
os.format("add_triangle(bm, (%u,%u,%u))\n",
primVerts[0],
primVerts[1],
primVerts[2]);
/* Break if done */
if (v+3 >= prim.indexCount)
break;
/* Advance 3 Prim Verts */
for (int pv=0 ; pv<3 ; ++pv)
primVerts[pv] = *iit++;
}
}
}
for (const typename MAPA::Surface::Border& border : surf.borders)
{
auto iit = border.indices.cbegin();
for (size_t i=0 ; i<border.indexCount-1 ; ++i)
{
os.format("add_border(bm, (%u,%u))\n",
*iit, *(iit+1));
++iit;
}
}
}
os << "mesh = bpy.data.meshes.new('MAP')\n"
"mesh.show_edge_seams = True\n"
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
"bm.to_mesh(mesh)\n"
"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())
os.linkBackground("//../!world.blend", "World");
os.centerView();
os.close();
conn.saveBlend();
return true; return true;
if (!conn.createBlend(outPath, hecl::blender::BlendType::MapArea))
return false;
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os << "import bpy, bmesh\n"
"from mathutils import Matrix\n"
"\n"
"bpy.types.Object.retro_mappable_type = bpy.props.IntProperty(name='Retro: MAPA object type', default=-1)\n"
"bpy.types.Object.retro_mappable_sclyid = bpy.props.StringProperty(name='Retro: MAPA object SCLY ID')\n"
"bpy.types.Scene.retro_map_vis_mode = bpy.props.EnumProperty(items=[('ALWAYS', 'Always', 'Always Visible', 0),"
"('MAPSTATIONORVISIT', 'Map Station or Visit', 'Visible after Map Station or Visit', 1),"
"('VISIT', 'Visit', 'Visible after Visit', 2),"
"('NEVER', 'Never', 'Never Visible', 3)],"
"name='Retro: Map Visibility Mode')\n"
"bpy.types.Object.retro_mapobj_vis_mode = bpy.props.EnumProperty(items=[('ALWAYS', 'Always', 'Always Visible', "
"0),"
"('MAPSTATIONORVISIT', 'Map Station or Visit', 'Visible after Map Station or Visit', 1),"
"('VISIT', 'Visit', 'Visible after Door Visit', 2),"
"('NEVER', 'Never', 'Never Visible', 3),"
"('MAPSTATIONORVISIT2', 'Map Station or Visit 2', 'Visible after Map Station or Visit', 4)],"
"name='Retro: Map Object Visibility Mode')\n"
"\n"
"for ar in bpy.context.screen.areas:\n"
" for sp in ar.spaces:\n"
" if sp.type == 'VIEW_3D':\n"
" sp.viewport_shade = 'SOLID'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"\n"
"def add_triangle(bm, verts):\n"
" verts = [bm.verts[vi] for vi in verts]\n"
" face = bm.faces.get(verts)\n"
" if face:\n"
" face = face.copy()\n"
" bm.verts.ensure_lookup_table()\n"
" face.normal_flip()\n"
" else:\n"
" bm.faces.new(verts)\n"
"\n"
"def add_border(bm, verts):\n"
" verts = [bm.verts[vi] for vi in verts]\n"
" edge = bm.edges.get(verts)\n"
" if not edge:\n"
" edge = bm.edges.new(verts)\n"
" edge.seam = True\n"
"\n";
os.format(
"bpy.context.scene.name = 'MAPA_%s'\n"
"bpy.context.scene.retro_map_vis_mode = '%s'\n",
entry.id.toString().c_str(), RetroMapVisModes[mapa.header->visMode()]);
/* Add empties representing MappableObjects */
int moIdx = 0;
for (const std::unique_ptr<MAPA::IMappableObject>& mo : mapa.mappableObjects) {
if (mapa.version < 5) {
const MAPA::MappableObjectMP1_2* moMP12 = static_cast<const MAPA::MappableObjectMP1_2*>(mo.get());
zeus::simd_floats mtxF[3];
for (int i = 0; i < 3; ++i)
moMP12->transformMtx[i].simd.copy_to(mtxF[i]);
os.format(
"obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
"bpy.context.scene.objects.link(obj)\n"
"obj.retro_mappable_type = %d\n"
"obj.retro_mapobj_vis_mode = '%s'\n"
"obj.retro_mappable_sclyid = '0x%08X'\n"
"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",
moIdx, moMP12->type, RetroMapObjVisModes[moMP12->visMode], moMP12->sclyId, mtxF[0][0], mtxF[0][1], mtxF[0][2],
mtxF[0][3], mtxF[1][0], mtxF[1][1], mtxF[1][2], mtxF[1][3], mtxF[2][0], mtxF[2][1], mtxF[2][2], mtxF[2][3]);
++moIdx;
continue;
} else {
const MAPA::MappableObjectMP3* moMP3 = static_cast<const MAPA::MappableObjectMP3*>(mo.get());
zeus::simd_floats mtxF[3];
for (int i = 0; i < 3; ++i)
moMP3->transformMtx[i].simd.copy_to(mtxF[i]);
os.format(
"obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
"bpy.context.scene.objects.link(obj)\n"
"obj.retro_mappable_type = %d\n"
"obj.retro_mapobj_vis_mode = '%s'\n"
"obj.retro_mappable_sclyid = '0x%08X'\n"
"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",
moIdx, moMP3->type, RetroMapObjVisModes[moMP3->visMode], moMP3->sclyId, mtxF[0][0], mtxF[0][1], mtxF[0][2],
mtxF[0][3], mtxF[1][0], mtxF[1][1], mtxF[1][2], mtxF[1][3], mtxF[2][0], mtxF[2][1], mtxF[2][2], mtxF[2][3]);
++moIdx;
continue;
}
}
os << "# Begin bmesh\n"
"bm = bmesh.new()\n"
"\n";
/* Read in verts */
for (const atVec3f& vert : mapa.vertices) {
zeus::simd_floats f(vert.simd);
os.format("bm.verts.new((%f,%f,%f))\n", f[0], f[1], f[2]);
}
os << "bm.verts.ensure_lookup_table()\n";
/* Read in surfaces */
for (const typename MAPA::Surface& surf : mapa.surfaces) {
for (const typename MAPA::Surface::Primitive& prim : surf.primitives) {
auto iit = prim.indices.cbegin();
/* 3 Prim Verts to start */
int c = 0;
unsigned int primVerts[3] = {*iit++, *iit++, *iit++};
if (GX::Primitive(prim.type) == GX::TRIANGLESTRIP) {
atUint8 flip = 0;
for (size_t v = 0; v < prim.indexCount - 2; ++v) {
if (flip) {
os.format("add_triangle(bm, (%u,%u,%u))\n", primVerts[c % 3], primVerts[(c + 2) % 3],
primVerts[(c + 1) % 3]);
} else {
os.format("add_triangle(bm, (%u,%u,%u))\n", primVerts[c % 3], primVerts[(c + 1) % 3],
primVerts[(c + 2) % 3]);
}
flip ^= 1;
/* Break if done */
if (iit == prim.indices.cend())
break;
bool peek = (v >= prim.indexCount - 3);
/* Advance one prim vert */
if (peek)
primVerts[c % 3] = *iit;
else
primVerts[c % 3] = *iit++;
++c;
}
} else if (GX::Primitive(prim.type) == GX::TRIANGLES) {
for (size_t v = 0; v < prim.indexCount; v += 3) {
os.format("add_triangle(bm, (%u,%u,%u))\n", primVerts[0], primVerts[1], primVerts[2]);
/* Break if done */
if (v + 3 >= prim.indexCount)
break;
/* Advance 3 Prim Verts */
for (int pv = 0; pv < 3; ++pv)
primVerts[pv] = *iit++;
}
}
}
for (const typename MAPA::Surface::Border& border : surf.borders) {
auto iit = border.indices.cbegin();
for (size_t i = 0; i < border.indexCount - 1; ++i) {
os.format("add_border(bm, (%u,%u))\n", *iit, *(iit + 1));
++iit;
}
}
}
os << "mesh = bpy.data.meshes.new('MAP')\n"
"mesh.show_edge_seams = True\n"
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
"bm.to_mesh(mesh)\n"
"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())
os.linkBackground("//../!world.blend", "World");
os.centerView();
os.close();
conn.saveBlend();
return true;
} }
template bool ReadMAPAToBlender<PAKRouter<DNAMP1::PAKBridge>> template bool ReadMAPAToBlender<PAKRouter<DNAMP1::PAKBridge>>(hecl::blender::Connection& conn, const MAPA& mapa,
(hecl::blender::Connection& conn, const hecl::ProjectPath& outPath,
const MAPA& mapa, PAKRouter<DNAMP1::PAKBridge>& pakRouter,
const hecl::ProjectPath& outPath, const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
PAKRouter<DNAMP1::PAKBridge>& pakRouter, bool force);
const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
bool force);
template bool ReadMAPAToBlender<PAKRouter<DNAMP2::PAKBridge>> template bool ReadMAPAToBlender<PAKRouter<DNAMP2::PAKBridge>>(hecl::blender::Connection& conn, const MAPA& mapa,
(hecl::blender::Connection& conn, const hecl::ProjectPath& outPath,
const MAPA& mapa, PAKRouter<DNAMP2::PAKBridge>& pakRouter,
const hecl::ProjectPath& outPath, const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
PAKRouter<DNAMP2::PAKBridge>& pakRouter, bool force);
const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
bool force);
template bool ReadMAPAToBlender<PAKRouter<DNAMP3::PAKBridge>> template bool ReadMAPAToBlender<PAKRouter<DNAMP3::PAKBridge>>(hecl::blender::Connection& conn, const MAPA& mapa,
(hecl::blender::Connection& conn, const hecl::ProjectPath& outPath,
const MAPA& mapa, PAKRouter<DNAMP3::PAKBridge>& pakRouter,
const hecl::ProjectPath& outPath, const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry,
PAKRouter<DNAMP3::PAKBridge>& pakRouter, bool force);
const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry,
bool force);
template <typename MAPAType> template <typename MAPAType>
bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out) bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out) {
{ if (mapaIn.verts.size() >= 256) {
if (mapaIn.verts.size() >= 256) Log.report(logvisor::Error, _SYS_STR("MAPA %s vertex range exceeded [%d/%d]"), out.getRelativePath().data(),
{ mapaIn.verts.size(), 255);
Log.report(logvisor::Error, _SYS_STR("MAPA %s vertex range exceeded [%d/%d]"), return false;
out.getRelativePath().data(), mapaIn.verts.size(), 255); }
return false;
MAPAType mapa;
mapa.magic = 0xDEADD00D;
mapa.version = MAPAType::Version();
zeus::CAABox aabb;
for (const hecl::blender::Vector3f& vert : mapaIn.verts)
aabb.accumulateBounds(vert.val);
mapa.header = std::make_unique<typename MAPAType::Header>();
typename MAPAType::Header& header = static_cast<typename MAPAType::Header&>(*mapa.header);
header.unknown1 = 0;
header.mapVisMode = mapaIn.visType.val;
header.boundingBox[0] = aabb.min;
header.boundingBox[1] = aabb.max;
header.moCount = mapaIn.pois.size();
header.vtxCount = mapaIn.verts.size();
header.surfCount = mapaIn.surfaces.size();
mapa.mappableObjects.reserve(mapaIn.pois.size());
for (const hecl::blender::MapArea::POI& poi : mapaIn.pois) {
mapa.mappableObjects.push_back(std::make_unique<typename MAPAType::MappableObject>());
typename MAPAType::MappableObject& mobj =
static_cast<typename MAPAType::MappableObject&>(*mapa.mappableObjects.back());
mobj.type = MAPA::IMappableObject::Type(poi.type);
mobj.visMode = poi.visMode;
mobj.sclyId = poi.objid;
mobj.transformMtx[0] = poi.xf.val[0];
mobj.transformMtx[1] = poi.xf.val[1];
mobj.transformMtx[2] = poi.xf.val[2];
}
mapa.vertices.reserve(mapaIn.verts.size());
for (const hecl::blender::Vector3f& vert : mapaIn.verts)
mapa.vertices.push_back(vert.val);
size_t offsetCur = 0;
for (const auto& mo : mapa.mappableObjects)
mo->binarySize(offsetCur);
offsetCur += mapa.vertices.size() * 12;
offsetCur += mapaIn.surfaces.size() * 32;
mapa.surfaceHeaders.reserve(mapaIn.surfaces.size());
mapa.surfaces.reserve(mapaIn.surfaces.size());
for (const hecl::blender::MapArea::Surface& surfIn : mapaIn.surfaces) {
mapa.surfaceHeaders.emplace_back();
DNAMAPA::MAPA::SurfaceHeader& surfHead = mapa.surfaceHeaders.back();
mapa.surfaces.emplace_back();
DNAMAPA::MAPA::Surface& surf = mapa.surfaces.back();
surf.primitiveCount = 1;
surf.primitives.emplace_back();
DNAMAPA::MAPA::Surface::Primitive& prim = surf.primitives.back();
prim.type = GX::TRIANGLESTRIP;
prim.indexCount = surfIn.count;
prim.indices.reserve(surfIn.count);
auto itBegin = mapaIn.indices.begin() + surfIn.start.val;
auto itEnd = itBegin + surfIn.count;
for (auto it = itBegin; it != itEnd; ++it)
prim.indices.push_back(it->val);
surf.borderCount = surfIn.borders.size();
surf.borders.reserve(surfIn.borders.size());
for (const auto& borderIn : surfIn.borders) {
surf.borders.emplace_back();
DNAMAPA::MAPA::Surface::Border& border = surf.borders.back();
border.indexCount = borderIn.second.val;
border.indices.reserve(borderIn.second.val);
auto it2Begin = mapaIn.indices.begin() + borderIn.first.val;
auto it2End = it2Begin + borderIn.second.val;
for (auto it = it2Begin; it != it2End; ++it)
border.indices.push_back(it->val);
} }
MAPAType mapa; surfHead.normal = surfIn.normal.val;
mapa.magic = 0xDEADD00D; surfHead.centroid = surfIn.centerOfMass;
mapa.version = MAPAType::Version(); surfHead.polyOff = offsetCur;
offsetCur += 4;
prim.binarySize(offsetCur);
surfHead.edgeOff = offsetCur;
offsetCur += 4;
for (const auto& border : surf.borders)
border.binarySize(offsetCur);
}
zeus::CAABox aabb; athena::io::FileWriter f(out.getAbsolutePath());
for (const hecl::blender::Vector3f& vert : mapaIn.verts) mapa.write(f);
aabb.accumulateBounds(vert.val); int64_t rem = f.position() % 32;
if (rem)
mapa.header = std::make_unique<typename MAPAType::Header>(); for (int64_t i = 0; i < 32 - rem; ++i)
typename MAPAType::Header& header = static_cast<typename MAPAType::Header&>(*mapa.header); f.writeBytes((atInt8*)"\xff", 1);
header.unknown1 = 0; return true;
header.mapVisMode = mapaIn.visType.val;
header.boundingBox[0] = aabb.min;
header.boundingBox[1] = aabb.max;
header.moCount = mapaIn.pois.size();
header.vtxCount = mapaIn.verts.size();
header.surfCount = mapaIn.surfaces.size();
mapa.mappableObjects.reserve(mapaIn.pois.size());
for (const hecl::blender::MapArea::POI& poi : mapaIn.pois)
{
mapa.mappableObjects.push_back(std::make_unique<typename MAPAType::MappableObject>());
typename MAPAType::MappableObject& mobj =
static_cast<typename MAPAType::MappableObject&>(*mapa.mappableObjects.back());
mobj.type = MAPA::IMappableObject::Type(poi.type);
mobj.visMode = poi.visMode;
mobj.sclyId = poi.objid;
mobj.transformMtx[0] = poi.xf.val[0];
mobj.transformMtx[1] = poi.xf.val[1];
mobj.transformMtx[2] = poi.xf.val[2];
}
mapa.vertices.reserve(mapaIn.verts.size());
for (const hecl::blender::Vector3f& vert : mapaIn.verts)
mapa.vertices.push_back(vert.val);
size_t offsetCur = 0;
for (const auto& mo : mapa.mappableObjects)
mo->binarySize(offsetCur);
offsetCur += mapa.vertices.size() * 12;
offsetCur += mapaIn.surfaces.size() * 32;
mapa.surfaceHeaders.reserve(mapaIn.surfaces.size());
mapa.surfaces.reserve(mapaIn.surfaces.size());
for (const hecl::blender::MapArea::Surface& surfIn : mapaIn.surfaces)
{
mapa.surfaceHeaders.emplace_back();
DNAMAPA::MAPA::SurfaceHeader& surfHead = mapa.surfaceHeaders.back();
mapa.surfaces.emplace_back();
DNAMAPA::MAPA::Surface& surf = mapa.surfaces.back();
surf.primitiveCount = 1;
surf.primitives.emplace_back();
DNAMAPA::MAPA::Surface::Primitive& prim = surf.primitives.back();
prim.type = GX::TRIANGLESTRIP;
prim.indexCount = surfIn.count;
prim.indices.reserve(surfIn.count);
auto itBegin = mapaIn.indices.begin() + surfIn.start.val;
auto itEnd = itBegin + surfIn.count;
for (auto it = itBegin ; it != itEnd ; ++it)
prim.indices.push_back(it->val);
surf.borderCount = surfIn.borders.size();
surf.borders.reserve(surfIn.borders.size());
for (const auto& borderIn : surfIn.borders)
{
surf.borders.emplace_back();
DNAMAPA::MAPA::Surface::Border& border = surf.borders.back();
border.indexCount = borderIn.second.val;
border.indices.reserve(borderIn.second.val);
auto it2Begin = mapaIn.indices.begin() + borderIn.first.val;
auto it2End = it2Begin + borderIn.second.val;
for (auto it = it2Begin ; it != it2End ; ++it)
border.indices.push_back(it->val);
}
surfHead.normal = surfIn.normal.val;
surfHead.centroid = surfIn.centerOfMass;
surfHead.polyOff = offsetCur;
offsetCur += 4;
prim.binarySize(offsetCur);
surfHead.edgeOff = offsetCur;
offsetCur += 4;
for (const auto& border : surf.borders)
border.binarySize(offsetCur);
}
athena::io::FileWriter f(out.getAbsolutePath());
mapa.write(f);
int64_t rem = f.position() % 32;
if (rem)
for (int64_t i=0 ; i<32-rem ; ++i)
f.writeBytes((atInt8*)"\xff", 1);
return true;
} }
template bool Cook<DNAMP1::MAPA>(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); template bool Cook<DNAMP1::MAPA>(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out);
template bool Cook<DNAMP2::MAPA>(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); template bool Cook<DNAMP2::MAPA>(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out);
template bool Cook<DNAMP3::MAPA>(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); template bool Cook<DNAMP3::MAPA>(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out);
} } // namespace DataSpec::DNAMAPA

View File

@ -3,190 +3,169 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
#include "GX.hpp" #include "GX.hpp"
namespace DataSpec::DNAMAPA {
struct MAPA : BigDNA {
AT_DECL_EXPLICIT_DNA
Value<atUint32> magic;
Value<atUint32> version;
struct IMAPAHeader : BigDNAV {
Delete _d;
virtual atUint32 visMode() const = 0;
virtual atUint32 mappableObjectCount() const = 0;
virtual atUint32 vertexCount() const = 0;
virtual atUint32 surfaceCount() const = 0;
};
namespace DataSpec::DNAMAPA struct HeaderMP1 : IMAPAHeader {
{ AT_DECL_DNA
struct MAPA : BigDNA AT_DECL_DNAV
{ Value<atUint32> unknown1 = 0;
AT_DECL_EXPLICIT_DNA Value<atUint32> mapVisMode = 0;
Value<atUint32> magic; Value<atVec3f> boundingBox[2] = {};
Value<atUint32> version; Value<atUint32> moCount = 0;
struct IMAPAHeader : BigDNAV Value<atUint32> vtxCount = 0;
{ Value<atUint32> surfCount = 0;
Delete _d; atUint32 visMode() const { return mapVisMode; }
virtual atUint32 visMode() const=0; atUint32 mappableObjectCount() const { return moCount; }
virtual atUint32 mappableObjectCount() const=0; atUint32 vertexCount() const { return vtxCount; }
virtual atUint32 vertexCount() const=0; atUint32 surfaceCount() const { return surfCount; }
virtual atUint32 surfaceCount() const=0; };
struct HeaderMP2 : IMAPAHeader {
AT_DECL_DNA
AT_DECL_DNAV
Value<atUint32> unknown1 = 0;
Value<atUint32> mapVisMode = 0;
Value<atVec3f> boundingBox[2] = {};
Value<atUint32> unknown3 = 0;
Value<atUint32> unknown4 = 0;
Value<atUint32> unknown5 = 0;
Value<atUint32> moCount = 0;
Value<atUint32> vtxCount = 0;
Value<atUint32> surfCount = 0;
atUint32 visMode() const { return mapVisMode; }
atUint32 mappableObjectCount() const { return moCount; }
atUint32 vertexCount() const { return vtxCount; }
atUint32 surfaceCount() const { return surfCount; }
};
struct HeaderMP3 : IMAPAHeader {
AT_DECL_DNA
AT_DECL_DNAV
Value<atUint32> unknown1 = 0;
Value<atUint32> mapVisMode = 0;
Value<atVec3f> boundingBox[2] = {};
Value<atUint32> unknown3 = 0;
Value<atUint32> unknown4 = 0;
Value<atUint32> unknown5 = 0;
Value<atUint32> unknown6 = 0;
Value<atUint32> moCount = 0;
Value<atUint32> vtxCount = 0;
Value<atUint32> surfCount = 0;
Value<atUint32> internalNameLength = 0;
Value<atUint32> unknown7 = 0;
String<AT_DNA_COUNT(internalNameLength)> internalName;
atUint32 visMode() const { return mapVisMode; }
atUint32 mappableObjectCount() const { return moCount; }
atUint32 vertexCount() const { return vtxCount; }
atUint32 surfaceCount() const { return surfCount; }
};
std::unique_ptr<IMAPAHeader> header;
struct IMappableObject : BigDNAV {
Delete _d;
enum class Type : atUint32 {
BlueDoor = 0,
ShieldDoor = 1,
IceDoor = 2,
WaveDoor = 3,
PlasmaDoor = 4,
BigDoor1 = 5,
BigDoor2 = 6,
IceDoorCeiling = 7,
IceDoorFloor = 8,
WaveDoorCeiling = 9,
WaveDoorFloor = 10,
IceDoorFloor2 = 13,
WaveDoorFloor2 = 14,
DownArrowYellow = 27, /* Maintenance Tunnel */
UpArrowYellow = 28, /* Phazon Processing Center */
DownArrowGreen = 29, /* Elevator A */
UpArrowGreen = 30, /* Elite Control Access */
DownArrowRed = 31, /* Elevator B */
UpArrowRed = 32, /* Fungal Hall Access */
TransportLift = 33,
SaveStation = 34,
MissileStation = 37
}; };
};
struct HeaderMP1 : IMAPAHeader struct MappableObjectMP1_2 : IMappableObject {
{ AT_DECL_DNA
AT_DECL_DNA AT_DECL_DNAV
AT_DECL_DNAV Value<Type> type;
Value<atUint32> unknown1 = 0; Value<atUint32> visMode;
Value<atUint32> mapVisMode = 0; Value<atUint32> sclyId;
Value<atVec3f> boundingBox[2] = {}; Value<atInt32> seek1 = -1;
Value<atUint32> moCount = 0; Value<atVec4f> transformMtx[3];
Value<atUint32> vtxCount = 0; Value<atInt32> seek2[4] = {-1, -1, -1, -1};
Value<atUint32> surfCount = 0; };
atUint32 visMode() const { return mapVisMode; }
atUint32 mappableObjectCount() const { return moCount;} struct MappableObjectMP3 : IMappableObject {
atUint32 vertexCount() const { return vtxCount; } AT_DECL_DNA
atUint32 surfaceCount() const { return surfCount; } AT_DECL_DNAV
Value<Type> type;
Value<atUint32> visMode;
Value<atUint32> sclyId;
Buffer<AT_DNA_COUNT(0x10)> unknownHash;
Value<atInt32> seek1 = -1;
Value<atVec4f> transformMtx[3];
Value<atInt32> seek2[4] = {-1, -1, -1, -1};
};
std::vector<std::unique_ptr<IMappableObject>> mappableObjects;
Vector<atVec3f, AT_DNA_COUNT(header->vertexCount())> vertices;
struct SurfaceHeader : BigDNA {
AT_DECL_DNA
Value<atVec3f> normal;
Value<atVec3f> centroid;
Value<atUint32> polyOff;
Value<atUint32> edgeOff;
};
Vector<SurfaceHeader, AT_DNA_COUNT(header->surfaceCount())> surfaceHeaders;
struct Surface : BigDNA {
AT_DECL_DNA
Value<atUint32> primitiveCount;
struct Primitive : BigDNA {
AT_DECL_DNA
Value<atUint32> type;
Value<atUint32> indexCount;
Vector<atUint8, AT_DNA_COUNT(indexCount)> indices;
Align<4> align;
}; };
Vector<Primitive, AT_DNA_COUNT(primitiveCount)> primitives;
struct HeaderMP2 : IMAPAHeader Value<atUint32> borderCount;
{ struct Border : BigDNA {
AT_DECL_DNA AT_DECL_DNA
AT_DECL_DNAV Value<atUint32> indexCount;
Value<atUint32> unknown1 = 0; Vector<atUint8, AT_DNA_COUNT(indexCount)> indices;
Value<atUint32> mapVisMode = 0; Align<4> align;
Value<atVec3f> boundingBox[2] = {};
Value<atUint32> unknown3 = 0;
Value<atUint32> unknown4 = 0;
Value<atUint32> unknown5 = 0;
Value<atUint32> moCount = 0;
Value<atUint32> vtxCount = 0;
Value<atUint32> surfCount = 0;
atUint32 visMode() const { return mapVisMode; }
atUint32 mappableObjectCount() const { return moCount;}
atUint32 vertexCount() const { return vtxCount; }
atUint32 surfaceCount() const { return surfCount; }
}; };
Vector<Border, AT_DNA_COUNT(borderCount)> borders;
};
struct HeaderMP3 : IMAPAHeader Vector<Surface, AT_DNA_COUNT(header->surfaceCount())> surfaces;
{
AT_DECL_DNA
AT_DECL_DNAV
Value<atUint32> unknown1 = 0;
Value<atUint32> mapVisMode = 0;
Value<atVec3f> boundingBox[2] = {};
Value<atUint32> unknown3 = 0;
Value<atUint32> unknown4 = 0;
Value<atUint32> unknown5 = 0;
Value<atUint32> unknown6 = 0;
Value<atUint32> moCount = 0;
Value<atUint32> vtxCount = 0;
Value<atUint32> surfCount = 0;
Value<atUint32> internalNameLength = 0;
Value<atUint32> unknown7 = 0;
String<AT_DNA_COUNT(internalNameLength)> internalName;
atUint32 visMode() const { return mapVisMode; }
atUint32 mappableObjectCount() const { return moCount;}
atUint32 vertexCount() const { return vtxCount; }
atUint32 surfaceCount() const { return surfCount; }
};
std::unique_ptr<IMAPAHeader> header;
struct IMappableObject : BigDNAV
{
Delete _d;
enum class Type : atUint32
{
BlueDoor = 0,
ShieldDoor = 1,
IceDoor = 2,
WaveDoor = 3,
PlasmaDoor = 4,
BigDoor1 = 5,
BigDoor2 = 6,
IceDoorCeiling = 7,
IceDoorFloor = 8,
WaveDoorCeiling = 9,
WaveDoorFloor = 10,
IceDoorFloor2 = 13,
WaveDoorFloor2 = 14,
DownArrowYellow = 27, /* Maintenance Tunnel */
UpArrowYellow = 28, /* Phazon Processing Center */
DownArrowGreen = 29, /* Elevator A */
UpArrowGreen = 30, /* Elite Control Access */
DownArrowRed = 31, /* Elevator B */
UpArrowRed = 32, /* Fungal Hall Access */
TransportLift = 33,
SaveStation = 34,
MissileStation = 37
};
};
struct MappableObjectMP1_2 : IMappableObject
{
AT_DECL_DNA
AT_DECL_DNAV
Value<Type> type;
Value<atUint32> visMode;
Value<atUint32> sclyId;
Value<atInt32> seek1 = -1;
Value<atVec4f> transformMtx[3];
Value<atInt32> seek2[4] = {-1, -1, -1, -1};
};
struct MappableObjectMP3 : IMappableObject
{
AT_DECL_DNA
AT_DECL_DNAV
Value<Type> type;
Value<atUint32> visMode;
Value<atUint32> sclyId;
Buffer<AT_DNA_COUNT(0x10)> unknownHash;
Value<atInt32> seek1 = -1;
Value<atVec4f> transformMtx[3];
Value<atInt32> seek2[4] = {-1, -1, -1, -1};
};
std::vector<std::unique_ptr<IMappableObject>> mappableObjects;
Vector<atVec3f, AT_DNA_COUNT(header->vertexCount())> vertices;
struct SurfaceHeader : BigDNA
{
AT_DECL_DNA
Value<atVec3f> normal;
Value<atVec3f> centroid;
Value<atUint32> polyOff;
Value<atUint32> edgeOff;
};
Vector<SurfaceHeader, AT_DNA_COUNT(header->surfaceCount())> surfaceHeaders;
struct Surface : BigDNA
{
AT_DECL_DNA
Value<atUint32> primitiveCount;
struct Primitive : BigDNA
{
AT_DECL_DNA
Value<atUint32> type;
Value<atUint32> indexCount;
Vector<atUint8, AT_DNA_COUNT(indexCount)> indices;
Align<4> align;
};
Vector<Primitive, AT_DNA_COUNT(primitiveCount)> primitives;
Value<atUint32> borderCount;
struct Border : BigDNA
{
AT_DECL_DNA
Value<atUint32> indexCount;
Vector<atUint8, AT_DNA_COUNT(indexCount)> indices;
Align<4> align;
};
Vector<Border, AT_DNA_COUNT(borderCount)> borders;
};
Vector<Surface, AT_DNA_COUNT(header->surfaceCount())> surfaces;
}; };
template <typename PAKRouter> template <typename PAKRouter>
bool ReadMAPAToBlender(hecl::blender::Connection& conn, bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const hecl::ProjectPath& outPath,
const MAPA& mapa, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force);
const hecl::ProjectPath& outPath,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
bool force);
template <typename MAPAType> template <typename MAPAType>
bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out);
} } // namespace DataSpec::DNAMAPA

View File

@ -5,157 +5,139 @@
#include "zeus/CTransform.hpp" #include "zeus/CTransform.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMAPU namespace DataSpec::DNAMAPU {
{
template <typename PAKRouter> template <typename PAKRouter>
bool ReadMAPUToBlender(hecl::blender::Connection& conn, bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const hecl::ProjectPath& outPath,
const MAPU& mapu, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force) {
const hecl::ProjectPath& outPath, if (!force && outPath.isFile())
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
bool force)
{
if (!force && outPath.isFile())
return true;
if (!conn.createBlend(outPath, hecl::blender::BlendType::MapUniverse))
return false;
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os << "import bpy\n"
"from mathutils import Matrix\n"
"\n"
"# Clear Scene\n"
"bpy.context.scene.camera = None\n"
"for ob in bpy.data.objects:\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"\n"
"bpy.types.Object.retro_mapworld_color = bpy.props.FloatVectorProperty(name='Retro: MapWorld Color',"
" description='Sets map world color', subtype='COLOR', size=4, min=0.0, max=1.0)\n"
"bpy.types.Object.retro_mapworld_path = bpy.props.StringProperty(name='Retro: MapWorld Path',"
" description='Sets path to World root')\n"
"\n";
hecl::ProjectPath hexPath = pakRouter.getWorking(mapu.hexMapa);
os.linkBlend(hexPath.getAbsolutePathUTF8().data(),
pakRouter.getBestEntryName(mapu.hexMapa).data());
os << "hexMesh = bpy.data.objects['MAP'].data\n";
for (const MAPU::World& wld : mapu.worlds)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(wld.mlvl);
const MAPU::Transform& wldXf = wld.transform;
zeus::simd_floats wldXfF[3];
for (int i = 0; i < 3; ++i)
wldXf.xf[i].simd.copy_to(wldXfF[i]);
zeus::simd_floats hexColorF(wld.hexColor.mSimd);
os.format("wldObj = bpy.data.objects.new('%s', None)\n"
"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"
"wldObj.rotation_mode = 'QUATERNION'\n"
"wldObj.location = mtxd[0]\n"
"wldObj.rotation_quaternion = mtxd[1]\n"
"wldObj.scale = mtxd[2]\n"
"wldObj.retro_mapworld_color = (%f, %f, %f, %f)\n"
"wldObj.retro_mapworld_path = '''%s'''\n"
"bpy.context.scene.objects.link(wldObj)\n", wld.name.c_str(),
wldXfF[0][0], wldXfF[0][1], wldXfF[0][2], wldXfF[0][3],
wldXfF[1][0], wldXfF[1][1], wldXfF[1][2], wldXfF[1][3],
wldXfF[2][0], wldXfF[2][1], wldXfF[2][2], wldXfF[2][3],
hexColorF[0], hexColorF[1], hexColorF[2], hexColorF[3],
path.getParentPath().getRelativePathUTF8().data());
int idx = 0;
for (const MAPU::Transform& hexXf : wld.hexTransforms)
{
zeus::simd_floats hexXfF[3];
for (int i = 0; i < 3; ++i)
hexXf.xf[i].simd.copy_to(hexXfF[i]);
os.format("obj = bpy.data.objects.new('%s_%d', hexMesh)\n"
"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"
"bpy.context.scene.objects.link(obj)\n"
"obj.parent = wldObj\n",
wld.name.c_str(), idx++,
hexXfF[0][0], hexXfF[0][1], hexXfF[0][2], hexXfF[0][3],
hexXfF[1][0], hexXfF[1][1], hexXfF[1][2], hexXfF[1][3],
hexXfF[2][0], hexXfF[2][1], hexXfF[2][2], hexXfF[2][3]);
}
}
os << "for screen in bpy.data.screens:\n"
" for area in screen.areas:\n"
" for space in area.spaces:\n"
" if space.type == 'VIEW_3D':\n"
" space.viewport_shade = 'SOLID'\n"
" space.clip_end = 8000.0\n";
os.centerView();
os.close();
conn.saveBlend();
return true; return true;
}
template bool ReadMAPUToBlender<PAKRouter<DNAMP1::PAKBridge>> if (!conn.createBlend(outPath, hecl::blender::BlendType::MapUniverse))
(hecl::blender::Connection& conn, return false;
const MAPU& mapu, hecl::blender::PyOutStream os = conn.beginPythonOut(true);
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP1::PAKBridge>& pakRouter,
const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
bool force);
template bool ReadMAPUToBlender<PAKRouter<DNAMP2::PAKBridge>> os << "import bpy\n"
(hecl::blender::Connection& conn, "from mathutils import Matrix\n"
const MAPU& mapu, "\n"
const hecl::ProjectPath& outPath, "# Clear Scene\n"
PAKRouter<DNAMP2::PAKBridge>& pakRouter, "bpy.context.scene.camera = None\n"
const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry, "for ob in bpy.data.objects:\n"
bool force); " bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"\n"
"bpy.types.Object.retro_mapworld_color = bpy.props.FloatVectorProperty(name='Retro: MapWorld Color',"
" description='Sets map world color', subtype='COLOR', size=4, min=0.0, max=1.0)\n"
"bpy.types.Object.retro_mapworld_path = bpy.props.StringProperty(name='Retro: MapWorld Path',"
" description='Sets path to World root')\n"
"\n";
bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPath& out) hecl::ProjectPath hexPath = pakRouter.getWorking(mapu.hexMapa);
{ os.linkBlend(hexPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(mapu.hexMapa).data());
MAPU mapu; os << "hexMesh = bpy.data.objects['MAP'].data\n";
mapu.magic = 0xABCDEF01; for (const MAPU::World& wld : mapu.worlds) {
mapu.version = 1; hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(wld.mlvl);
mapu.hexMapa = mapuIn.hexagonPath; const MAPU::Transform& wldXf = wld.transform;
zeus::simd_floats wldXfF[3];
mapu.worldCount = mapuIn.worlds.size(); for (int i = 0; i < 3; ++i)
mapu.worlds.reserve(mapuIn.worlds.size()); wldXf.xf[i].simd.copy_to(wldXfF[i]);
for (const hecl::blender::MapUniverse::World& wld : mapuIn.worlds) zeus::simd_floats hexColorF(wld.hexColor.mSimd);
{ os.format(
mapu.worlds.emplace_back(); "wldObj = bpy.data.objects.new('%s', None)\n"
MAPU::World& wldOut = mapu.worlds.back(); "mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n"
wldOut.name = wld.name; "mtxd = mtx.decompose()\n"
wldOut.mlvl = hecl::ProjectPath(wld.worldPath, _SYS_STR("!world.*")); "wldObj.rotation_mode = 'QUATERNION'\n"
wldOut.transform.xf[0] = wld.xf.val[0]; "wldObj.location = mtxd[0]\n"
wldOut.transform.xf[1] = wld.xf.val[1]; "wldObj.rotation_quaternion = mtxd[1]\n"
wldOut.transform.xf[2] = wld.xf.val[2]; "wldObj.scale = mtxd[2]\n"
wldOut.hexCount = wld.hexagons.size(); "wldObj.retro_mapworld_color = (%f, %f, %f, %f)\n"
wldOut.hexTransforms.reserve(wld.hexagons.size()); "wldObj.retro_mapworld_path = '''%s'''\n"
for (const hecl::blender::Matrix4f& mtx : wld.hexagons) "bpy.context.scene.objects.link(wldObj)\n",
{ wld.name.c_str(), wldXfF[0][0], wldXfF[0][1], wldXfF[0][2], wldXfF[0][3], wldXfF[1][0], wldXfF[1][1],
wldOut.hexTransforms.emplace_back(); wldXfF[1][2], wldXfF[1][3], wldXfF[2][0], wldXfF[2][1], wldXfF[2][2], wldXfF[2][3], hexColorF[0], hexColorF[1],
MAPU::Transform& xf = wldOut.hexTransforms.back(); hexColorF[2], hexColorF[3], path.getParentPath().getRelativePathUTF8().data());
xf.xf[0] = mtx.val[0]; int idx = 0;
xf.xf[1] = mtx.val[1]; for (const MAPU::Transform& hexXf : wld.hexTransforms) {
xf.xf[2] = mtx.val[2]; zeus::simd_floats hexXfF[3];
} for (int i = 0; i < 3; ++i)
wldOut.hexColor = zeus::CColor(wld.color.val); hexXf.xf[i].simd.copy_to(hexXfF[i]);
os.format(
"obj = bpy.data.objects.new('%s_%d', hexMesh)\n"
"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"
"bpy.context.scene.objects.link(obj)\n"
"obj.parent = wldObj\n",
wld.name.c_str(), idx++, hexXfF[0][0], hexXfF[0][1], hexXfF[0][2], hexXfF[0][3], hexXfF[1][0], hexXfF[1][1],
hexXfF[1][2], hexXfF[1][3], hexXfF[2][0], hexXfF[2][1], hexXfF[2][2], hexXfF[2][3]);
} }
}
athena::io::FileWriter f(out.getAbsolutePath()); os << "for screen in bpy.data.screens:\n"
mapu.write(f); " for area in screen.areas:\n"
int64_t rem = f.position() % 32; " for space in area.spaces:\n"
if (rem) " if space.type == 'VIEW_3D':\n"
for (int64_t i=0 ; i<32-rem ; ++i) " space.viewport_shade = 'SOLID'\n"
f.writeBytes((atInt8*)"\xff", 1); " space.clip_end = 8000.0\n";
return true;
os.centerView();
os.close();
conn.saveBlend();
return true;
} }
template bool ReadMAPUToBlender<PAKRouter<DNAMP1::PAKBridge>>(hecl::blender::Connection& conn, const MAPU& mapu,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP1::PAKBridge>& pakRouter,
const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
bool force);
template bool ReadMAPUToBlender<PAKRouter<DNAMP2::PAKBridge>>(hecl::blender::Connection& conn, const MAPU& mapu,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP2::PAKBridge>& pakRouter,
const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
bool force);
bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPath& out) {
MAPU mapu;
mapu.magic = 0xABCDEF01;
mapu.version = 1;
mapu.hexMapa = mapuIn.hexagonPath;
mapu.worldCount = mapuIn.worlds.size();
mapu.worlds.reserve(mapuIn.worlds.size());
for (const hecl::blender::MapUniverse::World& wld : mapuIn.worlds) {
mapu.worlds.emplace_back();
MAPU::World& wldOut = mapu.worlds.back();
wldOut.name = wld.name;
wldOut.mlvl = hecl::ProjectPath(wld.worldPath, _SYS_STR("!world.*"));
wldOut.transform.xf[0] = wld.xf.val[0];
wldOut.transform.xf[1] = wld.xf.val[1];
wldOut.transform.xf[2] = wld.xf.val[2];
wldOut.hexCount = wld.hexagons.size();
wldOut.hexTransforms.reserve(wld.hexagons.size());
for (const hecl::blender::Matrix4f& mtx : wld.hexagons) {
wldOut.hexTransforms.emplace_back();
MAPU::Transform& xf = wldOut.hexTransforms.back();
xf.xf[0] = mtx.val[0];
xf.xf[1] = mtx.val[1];
xf.xf[2] = mtx.val[2];
}
wldOut.hexColor = zeus::CColor(wld.color.val);
}
athena::io::FileWriter f(out.getAbsolutePath());
mapu.write(f);
int64_t rem = f.position() % 32;
if (rem)
for (int64_t i = 0; i < 32 - rem; ++i)
f.writeBytes((atInt8*)"\xff", 1);
return true;
} }
} // namespace DataSpec::DNAMAPU

View File

@ -2,42 +2,33 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
namespace DataSpec::DNAMAPU namespace DataSpec::DNAMAPU {
{ struct MAPU : BigDNA {
struct MAPU : BigDNA AT_DECL_DNA
{ Value<uint32_t> magic;
Value<uint32_t> version;
UniqueID32 hexMapa;
Value<uint32_t> worldCount;
struct Transform : BigDNA {
AT_DECL_DNA AT_DECL_DNA
Value<uint32_t> magic; Value<atVec4f> xf[3];
Value<uint32_t> version; };
UniqueID32 hexMapa; struct World : BigDNA {
Value<uint32_t> worldCount; AT_DECL_DNA
struct Transform : BigDNA String<-1> name;
{ UniqueID32 mlvl;
AT_DECL_DNA Transform transform;
Value<atVec4f> xf[3]; Value<uint32_t> hexCount;
}; Vector<Transform, AT_DNA_COUNT(hexCount)> hexTransforms;
struct World : BigDNA DNAColor hexColor;
{ };
AT_DECL_DNA Vector<World, AT_DNA_COUNT(worldCount)> worlds;
String<-1> name;
UniqueID32 mlvl;
Transform transform;
Value<uint32_t> hexCount;
Vector<Transform, AT_DNA_COUNT(hexCount)> hexTransforms;
DNAColor hexColor;
};
Vector<World, AT_DNA_COUNT(worldCount)> worlds;
static bool Cook(const hecl::blender::MapUniverse& mapu, const hecl::ProjectPath& out); static bool Cook(const hecl::blender::MapUniverse& mapu, const hecl::ProjectPath& out);
}; };
template <typename PAKRouter> template <typename PAKRouter>
bool ReadMAPUToBlender(hecl::blender::Connection& conn, bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const hecl::ProjectPath& outPath,
const MAPU& mapu, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force);
const hecl::ProjectPath& outPath,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
bool force);
}
} // namespace DataSpec::DNAMAPU

View File

@ -4,130 +4,109 @@
#include "../DNAMP3/MLVL.hpp" #include "../DNAMP3/MLVL.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMLVL namespace DataSpec::DNAMLVL {
{
template <class PAKRouter, typename MLVL> template <class PAKRouter, typename MLVL>
bool ReadMLVLToBlender(hecl::blender::Connection& conn, bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath,
const MLVL& mlvl, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged) {
PAKRouter& pakRouter, hecl::ProjectPath blendPath = outPath.getWithExtension(_SYS_STR(".blend"), true);
const typename PAKRouter::EntryType& entry, if (!force && blendPath.isFile())
bool force,
std::function<void(const hecl::SystemChar*)> fileChanged)
{
hecl::ProjectPath blendPath = outPath.getWithExtension(_SYS_STR(".blend"), true);
if (!force && blendPath.isFile())
return true;
/* Create World Blend */
if (!conn.createBlend(blendPath, hecl::blender::BlendType::World))
return false;
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os.format("import bpy\n"
"import bmesh\n"
"from mathutils import Matrix\n"
"\n"
"bpy.context.scene.name = 'World'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n");
/* Insert area empties */
int areaIdx = 0;
for (const auto& area : mlvl.areas)
{
const typename PAKRouter::EntryType* mreaEntry = pakRouter.lookupEntry(area.areaMREAId);
hecl::SystemUTF8Conv areaDirName(*mreaEntry->unique.m_areaName);
os.AABBToBMesh(area.aabb[0], area.aabb[1]);
zeus::simd_floats xfMtxF[3];
for (int i = 0; i < 3; ++i)
area.transformMtx[i].simd.copy_to(xfMtxF[i]);
os.format("box_mesh = bpy.data.meshes.new('''%s''')\n"
"bm.to_mesh(box_mesh)\n"
"bm.free()\n"
"box = bpy.data.objects.new(box_mesh.name, box_mesh)\n"
"bpy.context.scene.objects.link(box)\n"
"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"
"box.rotation_mode = 'QUATERNION'\n"
"box.location = mtxd[0]\n"
"box.rotation_quaternion = mtxd[1]\n"
"box.scale = mtxd[2]\n",
areaDirName.str().data(),
xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], xfMtxF[0][3],
xfMtxF[1][0], xfMtxF[1][1], xfMtxF[1][2], xfMtxF[1][3],
xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], xfMtxF[2][3]);
/* Insert dock planes */
int dockIdx = 0;
for (const auto& dock : area.docks)
{
os << "bm = bmesh.new()\n";
zeus::CVector3f pvAvg;
for (const atVec3f& pv : dock.planeVerts)
pvAvg += pv;
pvAvg /= zeus::CVector3f(dock.planeVerts.size());
int idx = 0;
for (const atVec3f& pv : dock.planeVerts)
{
const zeus::CVector3f pvRel = zeus::CVector3f(pv) - pvAvg;
os.format("bm.verts.new((%f,%f,%f))\n"
"bm.verts.ensure_lookup_table()\n",
pvRel[0], pvRel[1], pvRel[2]);
if (idx)
os << "bm.edges.new((bm.verts[-2], bm.verts[-1]))\n";
++idx;
}
os << "bm.edges.new((bm.verts[-1], bm.verts[0]))\n";
os.format("dockMesh = bpy.data.meshes.new('DOCK_%02d_%02d')\n", areaIdx, dockIdx);
os << "dockObj = bpy.data.objects.new(dockMesh.name, dockMesh)\n"
"bpy.context.scene.objects.link(dockObj)\n"
"bm.to_mesh(dockMesh)\n"
"bm.free()\n"
"dockObj.parent = box\n";
os.format("dockObj.location = (%f,%f,%f)\n",
float(pvAvg[0]), float(pvAvg[1]), float(pvAvg[2]));
++dockIdx;
}
++areaIdx;
}
os.centerView();
os.close();
conn.saveBlend();
return true; return true;
/* Create World Blend */
if (!conn.createBlend(blendPath, hecl::blender::BlendType::World))
return false;
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os.format(
"import bpy\n"
"import bmesh\n"
"from mathutils import Matrix\n"
"\n"
"bpy.context.scene.name = 'World'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n");
/* Insert area empties */
int areaIdx = 0;
for (const auto& area : mlvl.areas) {
const typename PAKRouter::EntryType* mreaEntry = pakRouter.lookupEntry(area.areaMREAId);
hecl::SystemUTF8Conv areaDirName(*mreaEntry->unique.m_areaName);
os.AABBToBMesh(area.aabb[0], area.aabb[1]);
zeus::simd_floats xfMtxF[3];
for (int i = 0; i < 3; ++i)
area.transformMtx[i].simd.copy_to(xfMtxF[i]);
os.format(
"box_mesh = bpy.data.meshes.new('''%s''')\n"
"bm.to_mesh(box_mesh)\n"
"bm.free()\n"
"box = bpy.data.objects.new(box_mesh.name, box_mesh)\n"
"bpy.context.scene.objects.link(box)\n"
"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"
"box.rotation_mode = 'QUATERNION'\n"
"box.location = mtxd[0]\n"
"box.rotation_quaternion = mtxd[1]\n"
"box.scale = mtxd[2]\n",
areaDirName.str().data(), xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], xfMtxF[0][3], xfMtxF[1][0], xfMtxF[1][1],
xfMtxF[1][2], xfMtxF[1][3], xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], xfMtxF[2][3]);
/* Insert dock planes */
int dockIdx = 0;
for (const auto& dock : area.docks) {
os << "bm = bmesh.new()\n";
zeus::CVector3f pvAvg;
for (const atVec3f& pv : dock.planeVerts)
pvAvg += pv;
pvAvg /= zeus::CVector3f(dock.planeVerts.size());
int idx = 0;
for (const atVec3f& pv : dock.planeVerts) {
const zeus::CVector3f pvRel = zeus::CVector3f(pv) - pvAvg;
os.format(
"bm.verts.new((%f,%f,%f))\n"
"bm.verts.ensure_lookup_table()\n",
pvRel[0], pvRel[1], pvRel[2]);
if (idx)
os << "bm.edges.new((bm.verts[-2], bm.verts[-1]))\n";
++idx;
}
os << "bm.edges.new((bm.verts[-1], bm.verts[0]))\n";
os.format("dockMesh = bpy.data.meshes.new('DOCK_%02d_%02d')\n", areaIdx, dockIdx);
os << "dockObj = bpy.data.objects.new(dockMesh.name, dockMesh)\n"
"bpy.context.scene.objects.link(dockObj)\n"
"bm.to_mesh(dockMesh)\n"
"bm.free()\n"
"dockObj.parent = box\n";
os.format("dockObj.location = (%f,%f,%f)\n", float(pvAvg[0]), float(pvAvg[1]), float(pvAvg[2]));
++dockIdx;
}
++areaIdx;
}
os.centerView();
os.close();
conn.saveBlend();
return true;
} }
template bool ReadMLVLToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::MLVL> template bool ReadMLVLToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::MLVL>(
(hecl::blender::Connection& conn, hecl::blender::Connection& conn, const DNAMP1::MLVL& mlvl, const hecl::ProjectPath& outPath,
const DNAMP1::MLVL& mlvl, PAKRouter<DNAMP1::PAKBridge>& pakRouter, const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry, bool force,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged);
PAKRouter<DNAMP1::PAKBridge>& pakRouter,
const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
template bool ReadMLVLToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::MLVL> template bool ReadMLVLToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::MLVL>(
(hecl::blender::Connection& conn, hecl::blender::Connection& conn, const DNAMP2::MLVL& mlvl, const hecl::ProjectPath& outPath,
const DNAMP2::MLVL& mlvl, PAKRouter<DNAMP2::PAKBridge>& pakRouter, const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry, bool force,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged);
PAKRouter<DNAMP2::PAKBridge>& pakRouter,
const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
template bool ReadMLVLToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::MLVL> template bool ReadMLVLToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::MLVL>(
(hecl::blender::Connection& conn, hecl::blender::Connection& conn, const DNAMP3::MLVL& mlvl, const hecl::ProjectPath& outPath,
const DNAMP3::MLVL& mlvl, PAKRouter<DNAMP3::PAKBridge>& pakRouter, const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry, bool force,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged);
PAKRouter<DNAMP3::PAKBridge>& pakRouter,
const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry,
bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
} } // namespace DataSpec::DNAMLVL

View File

@ -3,17 +3,11 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
#include "zeus/CVector3f.hpp" #include "zeus/CVector3f.hpp"
namespace DataSpec::DNAMLVL namespace DataSpec::DNAMLVL {
{
template <class PAKRouter, typename MLVL> template <class PAKRouter, typename MLVL>
bool ReadMLVLToBlender(hecl::blender::Connection& conn, bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath,
const MLVL& mlvl, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force,
const hecl::ProjectPath& outPath,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
bool force,
std::function<void(const hecl::SystemChar*)> fileChanged); std::function<void(const hecl::SystemChar*)> fileChanged);
} }

View File

@ -5,86 +5,80 @@
#include "gmm/gmm.h" #include "gmm/gmm.h"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec namespace DataSpec {
{
using ColMesh = hecl::blender::ColMesh; using ColMesh = hecl::blender::ColMesh;
struct FittedOBB struct FittedOBB {
{ zeus::CTransform xf;
zeus::CTransform xf; zeus::CVector3f he;
zeus::CVector3f he;
}; };
static std::vector<int> MakeRootTriangleIndex(const ColMesh& mesh) static std::vector<int> MakeRootTriangleIndex(const ColMesh& mesh) {
{ std::vector<int> ret;
std::vector<int> ret; ret.reserve(mesh.trianges.size());
ret.reserve(mesh.trianges.size()); for (int i = 0; i < mesh.trianges.size(); ++i)
for (int i = 0; i < mesh.trianges.size(); ++i) ret.push_back(i);
ret.push_back(i); return ret;
return ret;
} }
static std::unordered_set<uint32_t> GetTriangleVerts(const ColMesh& mesh, int triIdx) static std::unordered_set<uint32_t> GetTriangleVerts(const ColMesh& mesh, int triIdx) {
{ const ColMesh::Triangle& T = mesh.trianges[triIdx];
const ColMesh::Triangle& T = mesh.trianges[triIdx]; std::unordered_set<uint32_t> verts;
std::unordered_set<uint32_t> verts; verts.insert(mesh.edges[T.edges[0]].verts[0]);
verts.insert(mesh.edges[T.edges[0]].verts[0]); verts.insert(mesh.edges[T.edges[0]].verts[1]);
verts.insert(mesh.edges[T.edges[0]].verts[1]); verts.insert(mesh.edges[T.edges[1]].verts[0]);
verts.insert(mesh.edges[T.edges[1]].verts[0]); verts.insert(mesh.edges[T.edges[1]].verts[1]);
verts.insert(mesh.edges[T.edges[1]].verts[1]); verts.insert(mesh.edges[T.edges[2]].verts[0]);
verts.insert(mesh.edges[T.edges[2]].verts[0]); verts.insert(mesh.edges[T.edges[2]].verts[1]);
verts.insert(mesh.edges[T.edges[2]].verts[1]); return verts;
return verts;
} }
// method to set the OBB parameters which produce a box oriented according to // method to set the OBB parameters which produce a box oriented according to
// the covariance matrix C, which just containts the points pnts // the covariance matrix C, which just containts the points pnts
static FittedOBB BuildFromCovarianceMatrix(gmm::dense_matrix<float>& C, static FittedOBB BuildFromCovarianceMatrix(gmm::dense_matrix<float>& C, const ColMesh& mesh,
const ColMesh& mesh, const std::vector<int>& index) const std::vector<int>& index) {
{ FittedOBB ret;
FittedOBB ret;
// extract the eigenvalues and eigenvectors from C // extract the eigenvalues and eigenvectors from C
gmm::dense_matrix<float> eigvec(3,3); gmm::dense_matrix<float> eigvec(3, 3);
std::vector<float> eigval(3); std::vector<float> eigval(3);
using namespace gmm; using namespace gmm;
using MAT1 = gmm::dense_matrix<float>; using MAT1 = gmm::dense_matrix<float>;
gmm::symmetric_qr_algorithm(C, eigval, eigvec, default_tol_for_qr); gmm::symmetric_qr_algorithm(C, eigval, eigvec, default_tol_for_qr);
// find the right, up and forward vectors from the eigenvectors // find the right, up and forward vectors from the eigenvectors
zeus::CVector3f r(eigvec(0,0), eigvec(1,0), eigvec(2,0)); zeus::CVector3f r(eigvec(0, 0), eigvec(1, 0), eigvec(2, 0));
zeus::CVector3f u(eigvec(0,1), eigvec(1,1), eigvec(2,1)); zeus::CVector3f u(eigvec(0, 1), eigvec(1, 1), eigvec(2, 1));
zeus::CVector3f f(eigvec(0,2), eigvec(1,2), eigvec(2,2)); zeus::CVector3f f(eigvec(0, 2), eigvec(1, 2), eigvec(2, 2));
r.normalize(); u.normalize(), f.normalize(); r.normalize();
u.normalize(), f.normalize();
// set the rotation matrix using the eigvenvectors // set the rotation matrix using the eigvenvectors
ret.xf.basis[0] = r; ret.xf.basis[0] = r;
ret.xf.basis[1] = u; ret.xf.basis[1] = u;
ret.xf.basis[2] = f; ret.xf.basis[2] = f;
// now build the bounding box extents in the rotated frame // now build the bounding box extents in the rotated frame
zeus::CVector3f minim(1e10f, 1e10f, 1e10f), maxim(-1e10f, -1e10f, -1e10f); zeus::CVector3f minim(1e10f, 1e10f, 1e10f), maxim(-1e10f, -1e10f, -1e10f);
for (int triIdx : index) for (int triIdx : index) {
{ std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, triIdx);
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, triIdx); for (uint32_t v : verts) {
for (uint32_t v : verts) const zeus::CVector3f& p = mesh.verts[v].val;
{ zeus::CVector3f p_prime(r.dot(p), u.dot(p), f.dot(p));
const zeus::CVector3f& p = mesh.verts[v].val; minim = zeus::min(minim, p_prime);
zeus::CVector3f p_prime(r.dot(p), u.dot(p), f.dot(p)); maxim = zeus::max(maxim, p_prime);
minim = zeus::min(minim, p_prime);
maxim = zeus::max(maxim, p_prime);
}
} }
}
// set the center of the OBB to be the average of the // set the center of the OBB to be the average of the
// minimum and maximum, and the extents be half of the // minimum and maximum, and the extents be half of the
// difference between the minimum and maximum // difference between the minimum and maximum
zeus::CVector3f center = (maxim + minim) * 0.5f; zeus::CVector3f center = (maxim + minim) * 0.5f;
ret.xf.origin = ret.xf.basis * center; ret.xf.origin = ret.xf.basis * center;
ret.he = (maxim - minim) * 0.5f; ret.he = (maxim - minim) * 0.5f;
return ret; return ret;
} }
// builds an OBB from triangles specified as an array of // builds an OBB from triangles specified as an array of
@ -93,166 +87,164 @@ static FittedOBB BuildFromCovarianceMatrix(gmm::dense_matrix<float>& C,
// method build_from_covariance_matrix() method to fit // method build_from_covariance_matrix() method to fit
// the box. ALL points will be fit in the box, regardless // the box. ALL points will be fit in the box, regardless
// of whether they are indexed by a triangle or not. // of whether they are indexed by a triangle or not.
static FittedOBB FitOBB(const ColMesh& mesh, const std::vector<int>& index) static FittedOBB FitOBB(const ColMesh& mesh, const std::vector<int>& index) {
{ float Ai, Am = 0.0;
float Ai, Am=0.0; zeus::CVector3f mu, mui;
zeus::CVector3f mu, mui; gmm::dense_matrix<float> C(3, 3);
gmm::dense_matrix<float> C(3,3); float cxx = 0.0, cxy = 0.0, cxz = 0.0, cyy = 0.0, cyz = 0.0, czz = 0.0;
float cxx=0.0, cxy=0.0, cxz=0.0, cyy=0.0, cyz=0.0, czz=0.0;
// loop over the triangles this time to find the // loop over the triangles this time to find the
// mean location // mean location
for (int i : index) for (int i : index) {
{ std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, i);
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, i); auto it = verts.begin();
auto it = verts.begin(); zeus::CVector3f p = mesh.verts[*it++].val;
zeus::CVector3f p = mesh.verts[*it++].val; zeus::CVector3f q = mesh.verts[*it++].val;
zeus::CVector3f q = mesh.verts[*it++].val; zeus::CVector3f r = mesh.verts[*it++].val;
zeus::CVector3f r = mesh.verts[*it++].val; mui = (p + q + r) / 3.f;
mui = (p+q+r)/3.f; Ai = (q - p).cross(r - p).magnitude() / 2.f;
Ai = (q-p).cross(r-p).magnitude() / 2.f; mu += mui * Ai;
mu += mui*Ai; Am += Ai;
Am += Ai;
// these bits set the c terms to Am*E[xx], Am*E[xy], Am*E[xz].... // these bits set the c terms to Am*E[xx], Am*E[xy], Am*E[xz]....
cxx += ( 9.0*mui.x()*mui.x() + p.x()*p.x() + q.x()*q.x() + r.x()*r.x() )*(Ai/12.0); cxx += (9.0 * mui.x() * mui.x() + p.x() * p.x() + q.x() * q.x() + r.x() * r.x()) * (Ai / 12.0);
cxy += ( 9.0*mui.x()*mui.y() + p.x()*p.y() + q.x()*q.y() + r.x()*r.y() )*(Ai/12.0); cxy += (9.0 * mui.x() * mui.y() + p.x() * p.y() + q.x() * q.y() + r.x() * r.y()) * (Ai / 12.0);
cxz += ( 9.0*mui.x()*mui.z() + p.x()*p.z() + q.x()*q.z() + r.x()*r.z() )*(Ai/12.0); cxz += (9.0 * mui.x() * mui.z() + p.x() * p.z() + q.x() * q.z() + r.x() * r.z()) * (Ai / 12.0);
cyy += ( 9.0*mui.y()*mui.y() + p.y()*p.y() + q.y()*q.y() + r.y()*r.y() )*(Ai/12.0); cyy += (9.0 * mui.y() * mui.y() + p.y() * p.y() + q.y() * q.y() + r.y() * r.y()) * (Ai / 12.0);
cyz += ( 9.0*mui.y()*mui.z() + p.y()*p.z() + q.y()*q.z() + r.y()*r.z() )*(Ai/12.0); cyz += (9.0 * mui.y() * mui.z() + p.y() * p.z() + q.y() * q.z() + r.y() * r.z()) * (Ai / 12.0);
} }
if (zeus::close_enough(Am, 0.f)) if (zeus::close_enough(Am, 0.f))
return {}; return {};
// divide out the Am fraction from the average position and // divide out the Am fraction from the average position and
// covariance terms // covariance terms
mu = mu / Am; mu = mu / Am;
cxx /= Am; cxy /= Am; cxz /= Am; cyy /= Am; cyz /= Am; czz /= Am; cxx /= Am;
cxy /= Am;
cxz /= Am;
cyy /= Am;
cyz /= Am;
czz /= Am;
// now subtract off the E[x]*E[x], E[x]*E[y], ... terms // now subtract off the E[x]*E[x], E[x]*E[y], ... terms
cxx -= mu.x()*mu.x(); cxy -= mu.x()*mu.y(); cxz -= mu.x()*mu.z(); cxx -= mu.x() * mu.x();
cyy -= mu.y()*mu.y(); cyz -= mu.y()*mu.z(); czz -= mu.z()*mu.z(); cxy -= mu.x() * mu.y();
cxz -= mu.x() * mu.z();
cyy -= mu.y() * mu.y();
cyz -= mu.y() * mu.z();
czz -= mu.z() * mu.z();
// now build the covariance matrix // now build the covariance matrix
C(0,0)=cxx; C(0,1)=cxy; C(0,2)=cxz; C(0, 0) = cxx;
C(1,0)=cxy; C(1,1)=cyy; C(1,2)=cyz; C(0, 1) = cxy;
C(2,0)=cxz; C(2,1)=cyz; C(2,2)=czz; C(0, 2) = cxz;
C(1, 0) = cxy;
C(1, 1) = cyy;
C(1, 2) = cyz;
C(2, 0) = cxz;
C(2, 1) = cyz;
C(2, 2) = czz;
// set the obb parameters from the covariance matrix // set the obb parameters from the covariance matrix
return BuildFromCovarianceMatrix(C, mesh, index); return BuildFromCovarianceMatrix(C, mesh, index);
} }
template <typename Node> template <typename Node>
static void MakeLeaf(const ColMesh& mesh, const std::vector<int>& index, Node& n) static void MakeLeaf(const ColMesh& mesh, const std::vector<int>& index, Node& n) {
{ n.left.reset();
n.left.reset(); n.right.reset();
n.right.reset(); n.isLeaf = true;
n.isLeaf = true; n.leafData = std::make_unique<typename Node::LeafData>();
n.leafData = std::make_unique<typename Node::LeafData>(); n.leafData->triangleIndexCount = atUint32(index.size());
n.leafData->triangleIndexCount = atUint32(index.size()); n.leafData->triangleIndices.reserve(n.leafData->triangleIndexCount);
n.leafData->triangleIndices.reserve(n.leafData->triangleIndexCount); for (int i : index)
for (int i : index) n.leafData->triangleIndices.push_back(i);
n.leafData->triangleIndices.push_back(i);
} }
template <typename Node> template <typename Node>
static std::unique_ptr<Node> RecursiveMakeNode(const ColMesh& mesh, const std::vector<int>& index) static std::unique_ptr<Node> RecursiveMakeNode(const ColMesh& mesh, const std::vector<int>& index) {
{ // calculate root OBB
// calculate root OBB FittedOBB obb = FitOBB(mesh, index);
FittedOBB obb = FitOBB(mesh, index);
// make results row-major and also invert the rotation basis // make results row-major and also invert the rotation basis
obb.xf.basis.transpose(); obb.xf.basis.transpose();
std::unique_ptr<Node> n = std::make_unique<Node>(); std::unique_ptr<Node> n = std::make_unique<Node>();
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i) {
{ n->xf[i] = zeus::CVector4f{obb.xf.basis[i]};
n->xf[i] = zeus::CVector4f{obb.xf.basis[i]}; n->xf[i].simd[3] = float(obb.xf.origin[i]);
n->xf[i].simd[3] = float(obb.xf.origin[i]); }
} n->halfExtent = obb.he;
n->halfExtent = obb.he;
// terminate branch when volume < 1.0
if (obb.he[0] * obb.he[1] * obb.he[2] < 1.f)
{
MakeLeaf(mesh, index, *n);
return n;
}
n->isLeaf = false;
std::vector<int> indexNeg[3];
std::vector<int> indexPos[3];
for (int c = 0; c < 3; ++c)
{
// subdivide negative side
indexNeg[c].reserve(index.size());
for (int i : index)
{
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, i);
for (uint32_t vtx : verts)
{
zeus::CVector3f v = mesh.verts[vtx].val;
v = obb.xf.basis * (v - obb.xf.origin);
if (v[c] < 0.f)
{
indexNeg[c].push_back(i);
break;
}
}
}
// subdivide positive side
indexPos[c].reserve(index.size());
for (int i : index)
{
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, i);
for (uint32_t vtx : verts)
{
zeus::CVector3f v = mesh.verts[vtx].val;
v = obb.xf.basis * (v - obb.xf.origin);
if (v[c] >= 0.f)
{
indexPos[c].push_back(i);
break;
}
}
}
}
size_t idxMin = index.size();
int minComp = -1;
for (int c = 0; c < 3; ++c)
{
size_t test = std::max(indexNeg[c].size(), indexPos[c].size());
if (test < idxMin && test < index.size() * 3 / 4)
{
minComp = c;
idxMin = test;
}
}
if (minComp == -1)
{
MakeLeaf(mesh, index, *n);
return n;
}
n->left = RecursiveMakeNode<Node>(mesh, indexNeg[minComp]);
n->right = RecursiveMakeNode<Node>(mesh, indexPos[minComp]);
// terminate branch when volume < 1.0
if (obb.he[0] * obb.he[1] * obb.he[2] < 1.f) {
MakeLeaf(mesh, index, *n);
return n; return n;
}
n->isLeaf = false;
std::vector<int> indexNeg[3];
std::vector<int> indexPos[3];
for (int c = 0; c < 3; ++c) {
// subdivide negative side
indexNeg[c].reserve(index.size());
for (int i : index) {
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, i);
for (uint32_t vtx : verts) {
zeus::CVector3f v = mesh.verts[vtx].val;
v = obb.xf.basis * (v - obb.xf.origin);
if (v[c] < 0.f) {
indexNeg[c].push_back(i);
break;
}
}
}
// subdivide positive side
indexPos[c].reserve(index.size());
for (int i : index) {
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, i);
for (uint32_t vtx : verts) {
zeus::CVector3f v = mesh.verts[vtx].val;
v = obb.xf.basis * (v - obb.xf.origin);
if (v[c] >= 0.f) {
indexPos[c].push_back(i);
break;
}
}
}
}
size_t idxMin = index.size();
int minComp = -1;
for (int c = 0; c < 3; ++c) {
size_t test = std::max(indexNeg[c].size(), indexPos[c].size());
if (test < idxMin && test < index.size() * 3 / 4) {
minComp = c;
idxMin = test;
}
}
if (minComp == -1) {
MakeLeaf(mesh, index, *n);
return n;
}
n->left = RecursiveMakeNode<Node>(mesh, indexNeg[minComp]);
n->right = RecursiveMakeNode<Node>(mesh, indexPos[minComp]);
return n;
} }
template <typename Node> template <typename Node>
std::unique_ptr<Node> OBBTreeBuilder::buildCol(const ColMesh& mesh) std::unique_ptr<Node> OBBTreeBuilder::buildCol(const ColMesh& mesh) {
{ std::vector<int> root = MakeRootTriangleIndex(mesh);
std::vector<int> root = MakeRootTriangleIndex(mesh); return RecursiveMakeNode<Node>(mesh, root);
return RecursiveMakeNode<Node>(mesh, root);
} }
template std::unique_ptr<DNAMP1::DCLN::Collision::Node> template std::unique_ptr<DNAMP1::DCLN::Collision::Node>
OBBTreeBuilder::buildCol<DNAMP1::DCLN::Collision::Node>(const ColMesh& mesh); OBBTreeBuilder::buildCol<DNAMP1::DCLN::Collision::Node>(const ColMesh& mesh);
} } // namespace DataSpec

View File

@ -2,15 +2,12 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
namespace DataSpec namespace DataSpec {
{
struct OBBTreeBuilder struct OBBTreeBuilder {
{ using ColMesh = hecl::blender::ColMesh;
using ColMesh = hecl::blender::ColMesh; template <typename Node>
template <typename Node> static std::unique_ptr<Node> buildCol(const ColMesh& mesh);
static std::unique_ptr<Node> buildCol(const ColMesh& mesh);
}; };
} } // namespace DataSpec

File diff suppressed because it is too large Load Diff

View File

@ -5,73 +5,61 @@
#include <array> #include <array>
#include "zeus/CMatrix4f.hpp" #include "zeus/CMatrix4f.hpp"
namespace DataSpec namespace DataSpec {
{
/** PAK entry stream reader */ /** PAK entry stream reader */
class PAKEntryReadStream : public athena::io::IStreamReader class PAKEntryReadStream : public athena::io::IStreamReader {
{ std::unique_ptr<atUint8[]> m_buf;
std::unique_ptr<atUint8[]> m_buf; atUint64 m_sz;
atUint64 m_sz; atUint64 m_pos;
atUint64 m_pos;
public: public:
PAKEntryReadStream() {} PAKEntryReadStream() {}
operator bool() const {return m_buf.operator bool();} operator bool() const { return m_buf.operator bool(); }
PAKEntryReadStream(const PAKEntryReadStream& other) = delete; PAKEntryReadStream(const PAKEntryReadStream& other) = delete;
PAKEntryReadStream(PAKEntryReadStream&& other) = default; PAKEntryReadStream(PAKEntryReadStream&& other) = default;
PAKEntryReadStream& operator=(const PAKEntryReadStream& other) = delete; PAKEntryReadStream& operator=(const PAKEntryReadStream& other) = delete;
PAKEntryReadStream& operator=(PAKEntryReadStream&& other) = default; PAKEntryReadStream& operator=(PAKEntryReadStream&& other) = default;
PAKEntryReadStream(std::unique_ptr<atUint8[]>&& buf, atUint64 sz, atUint64 pos) PAKEntryReadStream(std::unique_ptr<atUint8[]>&& buf, atUint64 sz, atUint64 pos)
: m_buf(std::move(buf)), m_sz(sz), m_pos(pos) : m_buf(std::move(buf)), m_sz(sz), m_pos(pos) {
{ if (m_pos >= m_sz)
if (m_pos >= m_sz) LogDNACommon.report(logvisor::Fatal, "PAK stream cursor overrun");
LogDNACommon.report(logvisor::Fatal, "PAK stream cursor overrun"); }
} void seek(atInt64 pos, athena::SeekOrigin origin) {
void seek(atInt64 pos, athena::SeekOrigin origin) if (origin == athena::Begin)
{ m_pos = pos;
if (origin == athena::Begin) else if (origin == athena::Current)
m_pos = pos; m_pos += pos;
else if (origin == athena::Current) else if (origin == athena::End)
m_pos += pos; m_pos = m_sz + pos;
else if (origin == athena::End) if (m_pos > m_sz)
m_pos = m_sz + pos; LogDNACommon.report(logvisor::Fatal, "PAK stream cursor overrun");
if (m_pos > m_sz) }
LogDNACommon.report(logvisor::Fatal, "PAK stream cursor overrun"); atUint64 position() const { return m_pos; }
} atUint64 length() const { return m_sz; }
atUint64 position() const {return m_pos;} const atUint8* data() const { return m_buf.get(); }
atUint64 length() const {return m_sz;} atUint64 readUBytesToBuf(void* buf, atUint64 len) {
const atUint8* data() const {return m_buf.get();} atUint64 bufEnd = m_pos + len;
atUint64 readUBytesToBuf(void* buf, atUint64 len) if (bufEnd > m_sz)
{ len -= bufEnd - m_sz;
atUint64 bufEnd = m_pos + len; memmove(buf, m_buf.get() + m_pos, len);
if (bufEnd > m_sz) m_pos += len;
len -= bufEnd - m_sz; return len;
memmove(buf, m_buf.get() + m_pos, len); }
m_pos += len;
return len;
}
}; };
struct UniqueResult struct UniqueResult {
{ enum class Type { NotFound, Pak, Level, Area, Layer } m_type = Type::NotFound;
enum class Type const hecl::SystemString* m_levelName = nullptr;
{ const hecl::SystemString* m_areaName = nullptr;
NotFound, const hecl::SystemString* m_layerName = nullptr;
Pak, UniqueResult() = default;
Level, UniqueResult(Type tp) : m_type(tp) {}
Area,
Layer
} m_type = Type::NotFound;
const hecl::SystemString* m_levelName = nullptr;
const hecl::SystemString* m_areaName = nullptr;
const hecl::SystemString* m_layerName = nullptr;
UniqueResult() = default;
UniqueResult(Type tp) : m_type(tp) {}
template <class PAKBRIDGE> template <class PAKBRIDGE>
void checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry); void checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry);
hecl::ProjectPath uniquePath(const hecl::ProjectPath& pakPath) const; hecl::ProjectPath uniquePath(const hecl::ProjectPath& pakPath) const;
}; };
template <class BRIDGETYPE> template <class BRIDGETYPE>
@ -79,161 +67,154 @@ class PAKRouter;
/** Resource extractor type */ /** Resource extractor type */
template <class PAKBRIDGE> template <class PAKBRIDGE>
struct ResExtractor struct ResExtractor {
{ std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func_a;
std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func_a; std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&,
std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&, const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&,
const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&, std::function<void(const hecl::SystemChar*)>)>
std::function<void(const hecl::SystemChar*)>)> func_b; func_b;
std::array<const hecl::SystemChar*, 6> fileExts = {}; std::array<const hecl::SystemChar*, 6> fileExts = {};
unsigned weight = 0; unsigned weight = 0;
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&, std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&, typename PAKBRIDGE::PAKType::Entry&)>
typename PAKBRIDGE::PAKType::Entry&)> func_name; func_name;
ResExtractor() = default; ResExtractor() = default;
ResExtractor(std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func, ResExtractor(std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func,
std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin=0, std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin = 0,
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&, std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&,
typename PAKBRIDGE::PAKType::Entry&)> nfunc={}) typename PAKBRIDGE::PAKType::Entry&)>
: func_a(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {} nfunc = {})
: func_a(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {}
ResExtractor(std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&, ResExtractor(std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&,
const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&, const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&,
std::function<void(const hecl::SystemChar*)>)> func, std::function<void(const hecl::SystemChar*)>)>
std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin=0, func,
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&, std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin = 0,
typename PAKBRIDGE::PAKType::Entry&)> nfunc={}) std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&,
: func_b(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {} typename PAKBRIDGE::PAKType::Entry&)>
nfunc = {})
: func_b(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {}
bool IsFullyExtracted(const hecl::ProjectPath& path) const bool IsFullyExtracted(const hecl::ProjectPath& path) const {
{ hecl::ProjectPath::Type tp = path.getPathType();
hecl::ProjectPath::Type tp = path.getPathType(); if (tp == hecl::ProjectPath::Type::None)
if (tp == hecl::ProjectPath::Type::None) return false;
return false; else if (tp == hecl::ProjectPath::Type::Glob) {
else if (tp == hecl::ProjectPath::Type::Glob) for (int i = 0; i < 6; ++i) {
{ if (!fileExts[i])
for (int i=0 ; i<6 ; ++i) break;
{ hecl::ProjectPath withExt = path.getWithExtension(fileExts[i], true);
if (!fileExts[i]) if (withExt.isNone())
break; return false;
hecl::ProjectPath withExt = path.getWithExtension(fileExts[i], true); }
if (withExt.isNone())
return false;
}
}
return true;
} }
return true;
}
}; };
/** Level hierarchy representation */ /** Level hierarchy representation */
template <class IDType> template <class IDType>
struct Level struct Level {
{ hecl::SystemString name;
struct Area {
hecl::SystemString name; hecl::SystemString name;
struct Area struct Layer {
{ hecl::SystemString name;
hecl::SystemString name; bool active;
struct Layer std::unordered_set<IDType> resources;
{
hecl::SystemString name;
bool active;
std::unordered_set<IDType> resources;
};
std::vector<Layer> layers;
std::unordered_set<IDType> resources;
}; };
std::unordered_map<IDType, Area> areas; std::vector<Layer> layers;
std::unordered_set<IDType> resources;
};
std::unordered_map<IDType, Area> areas;
}; };
/** PAKRouter (for detecting shared entry locations) */ /** PAKRouter (for detecting shared entry locations) */
template <class BRIDGETYPE> template <class BRIDGETYPE>
class PAKRouter : public PAKRouterBase class PAKRouter : public PAKRouterBase {
{
public: 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;
private: private:
const std::vector<BRIDGETYPE>* m_bridges = nullptr; const std::vector<BRIDGETYPE>* m_bridges = nullptr;
std::vector<std::pair<hecl::ProjectPath,hecl::ProjectPath>> m_bridgePaths; std::vector<std::pair<hecl::ProjectPath, hecl::ProjectPath>> m_bridgePaths;
ThreadLocalPtr<void> m_curBridgeIdx; ThreadLocalPtr<void> m_curBridgeIdx;
const hecl::ProjectPath& m_gameWorking; const hecl::ProjectPath& m_gameWorking;
const hecl::ProjectPath& m_gameCooked; const hecl::ProjectPath& m_gameCooked;
hecl::ProjectPath m_sharedWorking; hecl::ProjectPath m_sharedWorking;
hecl::ProjectPath m_sharedCooked; hecl::ProjectPath m_sharedCooked;
ThreadLocalPtr<const PAKType> m_pak; ThreadLocalPtr<const PAKType> m_pak;
ThreadLocalPtr<const nod::Node> m_node; ThreadLocalPtr<const nod::Node> m_node;
std::unordered_map<IDType, std::pair<size_t, const EntryType*>> m_uniqueEntries; std::unordered_map<IDType, std::pair<size_t, const EntryType*>> m_uniqueEntries;
std::unordered_map<IDType, std::pair<size_t, const EntryType*>> m_sharedEntries; std::unordered_map<IDType, std::pair<size_t, const EntryType*>> m_sharedEntries;
std::unordered_map<IDType, hecl::ProjectPath> m_overrideEntries; std::unordered_map<IDType, hecl::ProjectPath> m_overrideEntries;
CharacterAssociations<IDType> m_charAssoc; CharacterAssociations<IDType> m_charAssoc;
std::unordered_map<IDType, zeus::CMatrix4f> m_mapaTransforms; std::unordered_map<IDType, zeus::CMatrix4f> m_mapaTransforms;
hecl::ProjectPath getCharacterWorking(const EntryType* entry) const; hecl::ProjectPath getCharacterWorking(const EntryType* entry) const;
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)
: PAKRouterBase(dataSpec), : PAKRouterBase(dataSpec)
m_gameWorking(working), m_gameCooked(cooked), , m_gameWorking(working)
m_sharedWorking(working, "Shared"), m_sharedCooked(cooked, "Shared") {} , m_gameCooked(cooked)
, m_sharedWorking(working, "Shared")
, m_sharedCooked(cooked, "Shared") {}
void build(std::vector<BRIDGETYPE>& bridges, std::function<void(float)> progress); void build(std::vector<BRIDGETYPE>& bridges, std::function<void(float)> progress);
void enterPAKBridge(const BRIDGETYPE& pakBridge); void enterPAKBridge(const BRIDGETYPE& pakBridge);
using PAKRouterBase::getWorking; using PAKRouterBase::getWorking;
hecl::ProjectPath getWorking(const EntryType* entry, hecl::ProjectPath getWorking(const EntryType* entry, const ResExtractor<BRIDGETYPE>& extractor) const;
const ResExtractor<BRIDGETYPE>& extractor) const; hecl::ProjectPath getWorking(const EntryType* entry) const;
hecl::ProjectPath getWorking(const EntryType* entry) const; hecl::ProjectPath getWorking(const IDType& id, bool silenceWarnings = false) const;
hecl::ProjectPath getWorking(const IDType& id, bool silenceWarnings=false) const; hecl::ProjectPath getCooked(const EntryType* entry) const;
hecl::ProjectPath getCooked(const EntryType* entry) const; hecl::ProjectPath getCooked(const IDType& id, bool silenceWarnings = false) const;
hecl::ProjectPath getCooked(const IDType& id, bool silenceWarnings=false) const; bool isShared() const {
bool isShared() const const PAKType* pak = m_pak.get();
{ return pak ? !pak->m_noShare : false;
const PAKType* pak = m_pak.get(); }
return pak ? !pak->m_noShare : false;
}
hecl::SystemString getResourceRelativePath(const EntryType& a, const IDType& b) const; hecl::SystemString getResourceRelativePath(const EntryType& a, const IDType& b) const;
std::string getBestEntryName(const EntryType& entry, bool stdOverride=true) const; std::string getBestEntryName(const EntryType& entry, bool stdOverride = true) const;
std::string getBestEntryName(const IDType& entry, bool stdOverride=true) const; std::string getBestEntryName(const IDType& entry, bool stdOverride = true) const;
bool extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok, bool extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*, float)> progress); std::function<void(const hecl::SystemChar*, float)> progress);
const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry, const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry, const nod::Node** nodeOut = nullptr,
const nod::Node** nodeOut=nullptr, bool silenceWarnings = false, bool currentPAK = false) const;
bool silenceWarnings=false,
bool currentPAK=false) const;
template <typename DNA> template <typename DNA>
bool lookupAndReadDNA(const IDType& id, DNA& out, bool silenceWarnings=false) bool lookupAndReadDNA(const IDType& id, DNA& out, bool silenceWarnings = false) {
{ const nod::Node* node;
const nod::Node* node; const EntryType* entry = lookupEntry(id, &node, silenceWarnings);
const EntryType* entry = lookupEntry(id, &node, silenceWarnings); 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 typename CharacterAssociations<IDType>::RigPair* lookupCMDLRigPair(const IDType& id) const; const typename CharacterAssociations<IDType>::RigPair* lookupCMDLRigPair(const IDType& id) const;
const typename CharacterAssociations<IDType>::MultimapIteratorPair lookupCharacterAttachmentRigs(const IDType& id) const; const typename CharacterAssociations<IDType>::MultimapIteratorPair
const zeus::CMatrix4f* lookupMAPATransform(const IDType& mapaId) const; lookupCharacterAttachmentRigs(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) const;
hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx, bool& activeOut) const; hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx, bool& activeOut) const;
hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx) const; hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx) const;
hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const; hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const;
void enumerateResources(const std::function<bool(const EntryType*)>& func); void enumerateResources(const std::function<bool(const EntryType*)>& func);
bool mreaHasDupeResources(const IDType& id) const; bool mreaHasDupeResources(const IDType& id) const;
}; };
} } // namespace DataSpec

File diff suppressed because it is too large Load Diff

View File

@ -4,106 +4,109 @@
#include "PAK.hpp" #include "PAK.hpp"
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle namespace DataSpec::DNAParticle {
{
template <class IDType> template <class IDType>
struct GPSM : BigDNA struct GPSM : BigDNA {
{ AT_DECL_EXPLICIT_DNA_YAML
AT_DECL_EXPLICIT_DNA_YAML AT_SUBDECL_DNA
AT_SUBDECL_DNA VectorElementFactory x0_PSIV;
VectorElementFactory x0_PSIV; ModVectorElementFactory x4_PSVM;
ModVectorElementFactory x4_PSVM; VectorElementFactory x8_PSOV;
VectorElementFactory x8_PSOV; IntElementFactory xc_PSLT;
IntElementFactory xc_PSLT; IntElementFactory x10_PSWT;
IntElementFactory x10_PSWT; RealElementFactory x14_PSTS;
RealElementFactory x14_PSTS; VectorElementFactory x18_POFS;
VectorElementFactory x18_POFS; IntElementFactory x1c_SEED;
IntElementFactory x1c_SEED; RealElementFactory x20_LENG;
RealElementFactory x20_LENG; RealElementFactory x24_WIDT;
RealElementFactory x24_WIDT; IntElementFactory x28_MAXP;
IntElementFactory x28_MAXP; RealElementFactory x2c_GRTE;
RealElementFactory x2c_GRTE; ColorElementFactory x30_COLR;
ColorElementFactory x30_COLR; IntElementFactory x34_LTME;
IntElementFactory x34_LTME; VectorElementFactory x38_ILOC;
VectorElementFactory x38_ILOC; VectorElementFactory x3c_IVEC;
VectorElementFactory x3c_IVEC; EmitterElementFactory x40_EMTR;
EmitterElementFactory x40_EMTR; union {
union struct {
{ bool x44_28_SORT : 1;
struct bool x44_30_MBLR : 1;
{ bool x44_24_LINE : 1;
bool x44_28_SORT : 1; bool x44_30_MBLR : 1; bool x44_24_LINE : 1; bool x44_29_LIT_ : 1; bool x44_29_LIT_ : 1;
bool x44_26_AAPH : 1; bool x44_27_ZBUF : 1; bool x44_25_FXLL : 1; bool x44_31_PMAB : 1; bool x44_26_AAPH : 1;
bool x45_29_VMD4 : 1; bool x45_28_VMD3 : 1; bool x45_27_VMD2 : 1; bool x45_26_VMD1 : 1; bool x44_27_ZBUF : 1;
bool x45_31_OPTS : 1; bool x45_24_PMUS : 1; bool x45_25_PMOO : 1; bool x45_30_CIND : 1; bool x44_25_FXLL : 1;
}; bool x44_31_PMAB : 1;
uint16_t dummy1 = 0; bool x45_29_VMD4 : 1;
bool x45_28_VMD3 : 1;
bool x45_27_VMD2 : 1;
bool x45_26_VMD1 : 1;
bool x45_31_OPTS : 1;
bool x45_24_PMUS : 1;
bool x45_25_PMOO : 1;
bool x45_30_CIND : 1;
}; };
IntElementFactory x48_MBSP; uint16_t dummy1 = 0;
RealElementFactory x4c_SIZE; };
RealElementFactory x50_ROTA; IntElementFactory x48_MBSP;
UVElementFactory<IDType> x54_TEXR; RealElementFactory x4c_SIZE;
UVElementFactory<IDType> x58_TIND; RealElementFactory x50_ROTA;
ChildResourceFactory<IDType> x5c_PMDL; UVElementFactory<IDType> x54_TEXR;
VectorElementFactory x6c_PMOP; UVElementFactory<IDType> x58_TIND;
VectorElementFactory x70_PMRT; ChildResourceFactory<IDType> x5c_PMDL;
VectorElementFactory x74_PMSC; VectorElementFactory x6c_PMOP;
ColorElementFactory x78_PMCL; VectorElementFactory x70_PMRT;
ModVectorElementFactory x7c_VEL1; VectorElementFactory x74_PMSC;
ModVectorElementFactory x80_VEL2; ColorElementFactory x78_PMCL;
ModVectorElementFactory x84_VEL3; ModVectorElementFactory x7c_VEL1;
ModVectorElementFactory x88_VEL4; ModVectorElementFactory x80_VEL2;
ChildResourceFactory<IDType> x8c_ICTS; ModVectorElementFactory x84_VEL3;
IntElementFactory x9c_NCSY; ModVectorElementFactory x88_VEL4;
IntElementFactory xa0_CSSD; ChildResourceFactory<IDType> x8c_ICTS;
ChildResourceFactory<IDType> xa4_IDTS; IntElementFactory x9c_NCSY;
IntElementFactory xb4_NDSY; IntElementFactory xa0_CSSD;
ChildResourceFactory<IDType> xb8_IITS; ChildResourceFactory<IDType> xa4_IDTS;
IntElementFactory xc8_PISY; IntElementFactory xb4_NDSY;
IntElementFactory xcc_SISY; ChildResourceFactory<IDType> xb8_IITS;
SpawnSystemKeyframeData<IDType> xd0_KSSM; IntElementFactory xc8_PISY;
ChildResourceFactory<IDType> xd4_SSWH; IntElementFactory xcc_SISY;
IntElementFactory xe4_SSSD; SpawnSystemKeyframeData<IDType> xd0_KSSM;
VectorElementFactory xe8_SSPO; ChildResourceFactory<IDType> xd4_SSWH;
IntElementFactory xf8_SESD; IntElementFactory xe4_SSSD;
VectorElementFactory xfc_SEPO; VectorElementFactory xe8_SSPO;
ChildResourceFactory<IDType> xec_PMLC; IntElementFactory xf8_SESD;
IntElementFactory x100_LTYP; VectorElementFactory xfc_SEPO;
ColorElementFactory x104_LCLR; ChildResourceFactory<IDType> xec_PMLC;
RealElementFactory x108_LINT; IntElementFactory x100_LTYP;
VectorElementFactory x10c_LOFF; ColorElementFactory x104_LCLR;
VectorElementFactory x110_LDIR; RealElementFactory x108_LINT;
IntElementFactory x114_LFOT; VectorElementFactory x10c_LOFF;
RealElementFactory x118_LFOR; VectorElementFactory x110_LDIR;
RealElementFactory x11c_LSLA; IntElementFactory x114_LFOT;
RealElementFactory x118_LFOR;
RealElementFactory x11c_LSLA;
/* 0-00 additions */ /* 0-00 additions */
ChildResourceFactory<IDType> xd8_SELC; ChildResourceFactory<IDType> xd8_SELC;
union union {
{ struct {
struct bool x30_30_ORNT : 1;
{ bool x30_31_RSOP : 1;
bool x30_30_ORNT : 1;
bool x30_31_RSOP : 1;
};
uint16_t dummy2 = 0;
}; };
RealElementFactory x10c_ADV1; uint16_t dummy2 = 0;
RealElementFactory x110_ADV2; };
RealElementFactory x114_ADV3; RealElementFactory x10c_ADV1;
RealElementFactory x118_ADV4; RealElementFactory x110_ADV2;
RealElementFactory x11c_ADV5; RealElementFactory x114_ADV3;
RealElementFactory x120_ADV6; RealElementFactory x118_ADV4;
RealElementFactory x124_ADV7; RealElementFactory x11c_ADV5;
RealElementFactory x128_ADV8; RealElementFactory x120_ADV6;
RealElementFactory x124_ADV7;
RealElementFactory x128_ADV8;
GPSM() GPSM() { x45_25_PMOO = true; }
{
x45_25_PMOO = true;
}
void gatherDependencies(std::vector<hecl::ProjectPath>&) const; void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
}; };
template <class IDType> template <class IDType>
@ -112,5 +115,4 @@ bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteGPSM(const GPSM<IDType>& gpsm, const hecl::ProjectPath& outPath); bool WriteGPSM(const GPSM<IDType>& gpsm, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAParticle

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,177 +4,144 @@
#include "DataSpec/DNAMP3/CINF.hpp" #include "DataSpec/DNAMP3/CINF.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAANIM namespace DataSpec::DNAANIM {
{
template <class CINFType> template <class CINFType>
RigInverter<CINFType>::Bone::Bone(const CINFType& cinf, const typename CINFType::Bone& origBone) RigInverter<CINFType>::Bone::Bone(const CINFType& cinf, const typename CINFType::Bone& origBone)
: m_origBone(origBone) : m_origBone(origBone) {
{ atUint32 parentIdx = cinf.getInternalBoneIdxFromId(origBone.parentId);
atUint32 parentIdx = cinf.getInternalBoneIdxFromId(origBone.parentId); zeus::CVector3f boneOrigin(origBone.origin);
zeus::CVector3f boneOrigin(origBone.origin); zeus::CVector3f naturalTail = boneOrigin + zeus::CVector3f{0.f, 0.5f, 0.f};
zeus::CVector3f naturalTail = boneOrigin + zeus::CVector3f{0.f, 0.5f, 0.f}; if (parentIdx != -1) {
if (parentIdx != -1) const typename CINFType::Bone& pBone = cinf.bones[parentIdx];
{ m_parentDelta = boneOrigin - zeus::CVector3f(pBone.origin);
const typename CINFType::Bone& pBone = cinf.bones[parentIdx]; }
m_parentDelta = boneOrigin - zeus::CVector3f(pBone.origin);
size_t actualChildren = 0;
for (atUint32 chId : origBone.linked) {
if (chId == origBone.parentId)
continue;
atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId);
if (chIdx != -1)
++actualChildren;
}
const std::string* bName = cinf.getBoneNameFromId(origBone.id);
bool isLCTR = false;
if (bName)
isLCTR = bName->find("_LCTR") != std::string::npos;
if (parentIdx == -1) {
/* Root will always use +Y tail */
m_tail = naturalTail;
} else if (actualChildren) {
/* Position tail to average of children */
for (atUint32 chId : origBone.linked) {
if (chId == origBone.parentId)
continue;
atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId);
if (chIdx != -1) {
const typename CINFType::Bone& chBone = cinf.bones[chIdx];
m_tail += chBone.origin;
}
}
m_tail /= zeus::CVector3f(float(actualChildren));
if ((m_tail - boneOrigin).magSquared() < 0.001f)
m_tail = naturalTail;
else if (isLCTR)
m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * (m_tail - boneOrigin).magnitude();
} else if (parentIdx != -1) {
/* Extrapolate by delta with parent */
m_tail = boneOrigin + m_parentDelta;
float deltaMag = m_parentDelta.magnitude();
if (deltaMag < 0.001f) {
deltaMag = 0.5f;
m_tail = naturalTail;
} else if (deltaMag > 0.5f) {
/* Extreme bones capped to +0.5 value */
deltaMag = 0.5f;
m_tail = boneOrigin + m_parentDelta.normalized() * 0.5f;
} }
size_t actualChildren = 0; if (isLCTR)
for (atUint32 chId : origBone.linked) m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * deltaMag;
{ } else {
if (chId == origBone.parentId) /* Fallback to +Y tail */
continue; m_tail = naturalTail;
atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId); }
if (chIdx != -1)
++actualChildren;
}
const std::string* bName = cinf.getBoneNameFromId(origBone.id);
bool isLCTR = false;
if (bName)
isLCTR = bName->find("_LCTR") != std::string::npos;
if (parentIdx == -1)
{
/* Root will always use +Y tail */
m_tail = naturalTail;
}
else if (actualChildren)
{
/* Position tail to average of children */
for (atUint32 chId : origBone.linked)
{
if (chId == origBone.parentId)
continue;
atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId);
if (chIdx != -1)
{
const typename CINFType::Bone& chBone = cinf.bones[chIdx];
m_tail += chBone.origin;
}
}
m_tail /= zeus::CVector3f(float(actualChildren));
if ((m_tail - boneOrigin).magSquared() < 0.001f)
m_tail = naturalTail;
else if (isLCTR)
m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * (m_tail - boneOrigin).magnitude();
}
else if (parentIdx != -1)
{
/* Extrapolate by delta with parent */
m_tail = boneOrigin + m_parentDelta;
float deltaMag = m_parentDelta.magnitude();
if (deltaMag < 0.001f)
{
deltaMag = 0.5f;
m_tail = naturalTail;
}
else if (deltaMag > 0.5f)
{
/* Extreme bones capped to +0.5 value */
deltaMag = 0.5f;
m_tail = boneOrigin + m_parentDelta.normalized() * 0.5f;
}
if (isLCTR)
m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * deltaMag;
}
else
{
/* Fallback to +Y tail */
m_tail = naturalTail;
}
} }
template <class CINFType> template <class CINFType>
RigInverter<CINFType>::RigInverter(const CINFType& cinf) RigInverter<CINFType>::RigInverter(const CINFType& cinf) : m_cinf(cinf) {
: m_cinf(cinf) m_bones.reserve(cinf.bones.size());
{ for (const typename CINFType::Bone& b : cinf.bones)
m_bones.reserve(cinf.bones.size()); m_bones.emplace_back(cinf, b);
for (const typename CINFType::Bone& b : cinf.bones)
m_bones.emplace_back(cinf, b);
} }
template <class CINFType> template <class CINFType>
RigInverter<CINFType>::RigInverter(const CINFType& cinf, RigInverter<CINFType>::RigInverter(const CINFType& cinf,
const std::unordered_map<std::string, const std::unordered_map<std::string, hecl::blender::Matrix3f>& matrices)
hecl::blender::Matrix3f>& matrices) : m_cinf(cinf) {
: m_cinf(cinf) m_bones.reserve(cinf.bones.size());
{ for (const typename CINFType::Bone& b : cinf.bones) {
m_bones.reserve(cinf.bones.size()); m_bones.emplace_back(cinf, b);
for (const typename CINFType::Bone& b : cinf.bones)
{
m_bones.emplace_back(cinf, b);
const std::string* name = cinf.getBoneNameFromId(b.id); const std::string* name = cinf.getBoneNameFromId(b.id);
if (name) if (name) {
{ auto search = matrices.find(*name);
auto search = matrices.find(*name); if (search != matrices.cend()) {
if (search != matrices.cend()) zeus::CMatrix3f boneMtx(search->second[0], search->second[1], search->second[2]);
{ m_bones.back().m_inverter = boneMtx.transposed();
zeus::CMatrix3f boneMtx(search->second[0], m_bones.back().m_restorer = boneMtx;
search->second[1], }
search->second[2]);
m_bones.back().m_inverter = boneMtx.transposed();
m_bones.back().m_restorer = boneMtx;
}
}
} }
}
} }
template <class CINFType> template <class CINFType>
zeus::CQuaternion zeus::CQuaternion RigInverter<CINFType>::invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const {
RigInverter<CINFType>::invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const for (const Bone& b : m_bones)
{ if (b.m_origBone.id == boneId)
for (const Bone& b : m_bones) return b.m_restorer * zeus::CMatrix3f(origRot) * b.m_inverter;
if (b.m_origBone.id == boneId) return origRot;
return b.m_restorer * zeus::CMatrix3f(origRot) * b.m_inverter;
return origRot;
} }
template <class CINFType> template <class CINFType>
zeus::CVector3f zeus::CVector3f RigInverter<CINFType>::invertPosition(atUint32 boneId, const zeus::CVector3f& origPos,
RigInverter<CINFType>::invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const bool subDelta) const {
{ for (const Bone& b : m_bones)
for (const Bone& b : m_bones) if (b.m_origBone.id == boneId) {
if (b.m_origBone.id == boneId) zeus::CVector3f localPos = origPos;
{ if (subDelta)
zeus::CVector3f localPos = origPos; localPos -= b.m_parentDelta;
if (subDelta) return b.m_restorer * localPos;
localPos -= b.m_parentDelta; }
return b.m_restorer * localPos; return origPos;
}
return origPos;
} }
template <class CINFType> template <class CINFType>
zeus::CQuaternion zeus::CQuaternion RigInverter<CINFType>::restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const {
RigInverter<CINFType>::restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const for (const Bone& b : m_bones)
{ if (b.m_origBone.id == boneId)
for (const Bone& b : m_bones) return b.m_inverter * zeus::CMatrix3f(origRot) * b.m_restorer;
if (b.m_origBone.id == boneId) return origRot;
return b.m_inverter * zeus::CMatrix3f(origRot) * b.m_restorer;
return origRot;
} }
template <class CINFType> template <class CINFType>
zeus::CVector3f zeus::CVector3f RigInverter<CINFType>::restorePosition(atUint32 boneId, const zeus::CVector3f& origPos,
RigInverter<CINFType>::restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const bool subDelta) const {
{ for (const Bone& b : m_bones)
for (const Bone& b : m_bones) if (b.m_origBone.id == boneId) {
if (b.m_origBone.id == boneId) zeus::CVector3f localPos = b.m_inverter * origPos;
{ if (subDelta)
zeus::CVector3f localPos = b.m_inverter * origPos; localPos += b.m_parentDelta;
if (subDelta) return localPos;
localPos += b.m_parentDelta; }
return localPos; return origPos;
}
return origPos;
} }
template class RigInverter<DNAMP1::CINF>; template class RigInverter<DNAMP1::CINF>;
template class RigInverter<DNAMP2::CINF>; template class RigInverter<DNAMP2::CINF>;
template class RigInverter<DNAMP3::CINF>; template class RigInverter<DNAMP3::CINF>;
} } // namespace DataSpec::DNAANIM

View File

@ -5,40 +5,37 @@
#include "zeus/CQuaternion.hpp" #include "zeus/CQuaternion.hpp"
#include "hecl/hecl.hpp" #include "hecl/hecl.hpp"
namespace DataSpec::DNAANIM namespace DataSpec::DNAANIM {
{
/** One-shot process to invert CINF armature into connected rig, /** One-shot process to invert CINF armature into connected rig,
* inverting rotations/translations of ANIM data to match */ * inverting rotations/translations of ANIM data to match */
template <class CINFType> template <class CINFType>
class RigInverter class RigInverter {
{
public: public:
struct Bone struct Bone {
{ const typename CINFType::Bone& m_origBone;
const typename CINFType::Bone& m_origBone; zeus::CMatrix3f m_inverter;
zeus::CMatrix3f m_inverter; zeus::CMatrix3f m_restorer;
zeus::CMatrix3f m_restorer; zeus::CVector3f m_tail;
zeus::CVector3f m_tail; zeus::CVector3f m_parentDelta;
zeus::CVector3f m_parentDelta; Bone(const CINFType& cinf, const typename CINFType::Bone& origBone);
Bone(const CINFType& cinf, const typename CINFType::Bone& origBone); };
};
private: private:
const CINFType& m_cinf; const CINFType& m_cinf;
std::vector<Bone> m_bones; std::vector<Bone> m_bones;
public: public:
RigInverter(const CINFType& cinf); RigInverter(const CINFType& cinf);
RigInverter(const CINFType& cinf, RigInverter(const CINFType& cinf, const std::unordered_map<std::string, hecl::blender::Matrix3f>& matrices);
const std::unordered_map<std::string, hecl::blender::Matrix3f>& matrices); const CINFType& getCINF() const { return m_cinf; }
const CINFType& getCINF() const {return m_cinf;} const std::vector<Bone>& getBones() const { return m_bones; }
const std::vector<Bone>& getBones() const {return m_bones;}
zeus::CQuaternion invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const; zeus::CQuaternion invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const;
zeus::CVector3f invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const; zeus::CVector3f invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const;
zeus::CQuaternion restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const; zeus::CQuaternion restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const;
zeus::CVector3f restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const; zeus::CVector3f restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const;
}; };
} } // namespace DataSpec::DNAANIM

View File

@ -2,51 +2,37 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
#include "PAK.hpp" #include "PAK.hpp"
namespace DataSpec::SAVWCommon namespace DataSpec::SAVWCommon {
{ enum class EScanCategory { None, Data, Lore, Creature, Research, Artifact };
enum class EScanCategory
{ struct Header : BigDNA {
None, AT_DECL_DNA_YAML
Data, Value<atUint32> magic;
Lore, Value<atUint32> version;
Creature, Value<atUint32> areaCount;
Research,
Artifact
}; };
struct Header : BigDNA struct EnvironmentVariable : BigDNA {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML String<-1> name;
Value<atUint32> magic; Value<atUint32> unk1;
Value<atUint32> version; Value<atUint32> unk2;
Value<atUint32> areaCount; Value<atUint32> unk3;
}; };
struct EnvironmentVariable : BigDNA struct Layer : BigDNA {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML Value<atUint32> areaId;
String<-1> name; Value<atUint32> layer;
Value<atUint32> unk1;
Value<atUint32> unk2;
Value<atUint32> unk3;
};
struct Layer : BigDNA
{
AT_DECL_DNA_YAML
Value<atUint32> areaId;
Value<atUint32> layer;
}; };
template <class SAVW> template <class SAVW>
static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ SAVW savw;
SAVW savw; savw.read(rs);
savw.read(rs); athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::FileWriter writer(outPath.getAbsolutePath()); athena::io::ToYAMLStream(savw, writer);
athena::io::ToYAMLStream(savw, writer); return true;
return true;
}
} }
} // namespace DataSpec::SAVWCommon

View File

@ -3,46 +3,37 @@
#include "../DNAMP2/STRG.hpp" #include "../DNAMP2/STRG.hpp"
#include "../DNAMP3/STRG.hpp" #include "../DNAMP3/STRG.hpp"
namespace DataSpec namespace DataSpec {
{
void ISTRG::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const void ISTRG::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const { /* TODO: parse out resource tokens */ }
{
/* TODO: parse out resource tokens */
}
std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader) std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader) {
{ uint32_t magic = reader.readUint32Big();
uint32_t magic = reader.readUint32Big(); if (magic != 0x87654321) {
if (magic != 0x87654321) LogDNACommon.report(logvisor::Error, "invalid STRG magic");
{
LogDNACommon.report(logvisor::Error, "invalid STRG magic");
return std::unique_ptr<ISTRG>();
}
uint32_t version = reader.readUint32Big();
switch (version)
{
case 0:
{
DNAMP1::STRG* newStrg = new DNAMP1::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
case 1:
{
DNAMP2::STRG* newStrg = new DNAMP2::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
case 3:
{
DNAMP3::STRG* newStrg = new DNAMP3::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
default: break;
}
return std::unique_ptr<ISTRG>(); return std::unique_ptr<ISTRG>();
}
uint32_t version = reader.readUint32Big();
switch (version) {
case 0: {
DNAMP1::STRG* newStrg = new DNAMP1::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
case 1: {
DNAMP2::STRG* newStrg = new DNAMP2::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
case 3: {
DNAMP3::STRG* newStrg = new DNAMP3::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
default:
break;
}
return std::unique_ptr<ISTRG>();
} }
} } // namespace DataSpec

View File

@ -7,21 +7,18 @@
#include <athena/FileWriter.hpp> #include <athena/FileWriter.hpp>
#include "DNACommon.hpp" #include "DNACommon.hpp"
namespace DataSpec namespace DataSpec {
{ struct ISTRG : BigDNAVYaml {
struct ISTRG : BigDNAVYaml virtual ~ISTRG() = default;
{
virtual ~ISTRG() = default;
virtual size_t count() const=0; virtual size_t count() const = 0;
virtual std::string getUTF8(const FourCC& lang, size_t idx) const=0; virtual std::string getUTF8(const FourCC& lang, size_t idx) const = 0;
virtual std::u16string getUTF16(const FourCC& lang, size_t idx) const=0; virtual std::u16string getUTF16(const FourCC& lang, size_t idx) const = 0;
virtual hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const=0; virtual hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const = 0;
virtual int32_t lookupIdx(std::string_view name) const=0; virtual int32_t lookupIdx(std::string_view name) const = 0;
virtual void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const; virtual void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const;
}; };
std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader); std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader);
} } // namespace DataSpec

File diff suppressed because it is too large Load Diff

View File

@ -4,49 +4,50 @@
#include "PAK.hpp" #include "PAK.hpp"
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle namespace DataSpec::DNAParticle {
{
template <class IDType> template <class IDType>
struct SWSH : public BigDNA struct SWSH : public BigDNA {
{ AT_DECL_EXPLICIT_DNA_YAML
AT_DECL_EXPLICIT_DNA_YAML AT_SUBDECL_DNA
AT_SUBDECL_DNA
IntElementFactory x0_PSLT; IntElementFactory x0_PSLT;
RealElementFactory x4_TIME; RealElementFactory x4_TIME;
RealElementFactory x8_LRAD; RealElementFactory x8_LRAD;
RealElementFactory xc_RRAD; RealElementFactory xc_RRAD;
IntElementFactory x10_LENG; IntElementFactory x10_LENG;
ColorElementFactory x14_COLR; ColorElementFactory x14_COLR;
IntElementFactory x18_SIDE; IntElementFactory x18_SIDE;
RealElementFactory x1c_IROT; RealElementFactory x1c_IROT;
RealElementFactory x20_ROTM; RealElementFactory x20_ROTM;
VectorElementFactory x24_POFS; VectorElementFactory x24_POFS;
VectorElementFactory x28_IVEL; VectorElementFactory x28_IVEL;
VectorElementFactory x2c_NPOS; VectorElementFactory x2c_NPOS;
ModVectorElementFactory x30_VELM; ModVectorElementFactory x30_VELM;
ModVectorElementFactory x34_VLM2; ModVectorElementFactory x34_VLM2;
IntElementFactory x38_SPLN; IntElementFactory x38_SPLN;
UVElementFactory<IDType> x3c_TEXR; UVElementFactory<IDType> x3c_TEXR;
IntElementFactory x40_TSPN; IntElementFactory x40_TSPN;
union union {
{ struct {
struct bool x44_24_LLRD : 1;
{ bool x44_25_CROS : 1;
bool x44_24_LLRD : 1; bool x44_25_CROS : 1; bool x44_26_VLS1 : 1; bool x44_27_VLS2 : 1; bool x44_26_VLS1 : 1;
bool x44_28_SROT : 1; bool x44_29_WIRE : 1; bool x44_30_TEXW : 1; bool x44_31_AALP : 1; bool x44_27_VLS2 : 1;
bool x45_24_ZBUF : 1; bool x45_25_ORNT : 1; bool x45_26_CRND : 1; bool x44_28_SROT : 1;
}; bool x44_29_WIRE : 1;
uint16_t dummy = 0; bool x44_30_TEXW : 1;
bool x44_31_AALP : 1;
bool x45_24_ZBUF : 1;
bool x45_25_ORNT : 1;
bool x45_26_CRND : 1;
}; };
uint16_t dummy = 0;
};
SWSH() SWSH() { x44_25_CROS = true; }
{
x44_25_CROS = true;
}
void gatherDependencies(std::vector<hecl::ProjectPath>&) const; void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
}; };
template <class IDType> template <class IDType>
@ -54,4 +55,4 @@ bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteSWSH(const SWSH<IDType>& gpsm, const hecl::ProjectPath& outPath); bool WriteSWSH(const SWSH<IDType>& gpsm, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAParticle

File diff suppressed because it is too large Load Diff

View File

@ -2,16 +2,13 @@
#include "DNACommon.hpp" #include "DNACommon.hpp"
namespace DataSpec namespace DataSpec {
{
class PAKEntryReadStream; class PAKEntryReadStream;
struct TXTR struct TXTR {
{ static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); static bool CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
static bool CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
}; };
} } // namespace DataSpec

View File

@ -2,16 +2,12 @@
#include "DataSpec/DNACommon/DNACommon.hpp" #include "DataSpec/DNACommon/DNACommon.hpp"
namespace hecl namespace hecl {
{
class CVarManager; class CVarManager;
} }
namespace DataSpec namespace DataSpec {
{ struct ITweak : BigDNA {
struct ITweak : BigDNA
{
virtual void initCVars(hecl::CVarManager*) {} virtual void initCVars(hecl::CVarManager*) {}
}; };
} } // namespace DataSpec

View File

@ -2,66 +2,62 @@
#include "ITweak.hpp" #include "ITweak.hpp"
namespace DataSpec namespace DataSpec {
{ struct ITweakAutoMapper : public ITweak {
struct ITweakAutoMapper : public ITweak virtual bool GetShowOneMiniMapArea() const = 0;
{ virtual bool GetScaleMoveSpeedWithCamDist() const = 0;
virtual bool GetShowOneMiniMapArea() const=0; virtual float GetCamDist() const = 0;
virtual bool GetScaleMoveSpeedWithCamDist() const=0; virtual float GetMinCamDist() const = 0;
virtual float GetCamDist() const=0; virtual float GetMaxCamDist() const = 0;
virtual float GetMinCamDist() const=0; virtual float GetMinCamRotateX() const = 0;
virtual float GetMaxCamDist() const=0; virtual float GetMaxCamRotateX() const = 0;
virtual float GetMinCamRotateX() const=0; virtual float GetCamAngle() const = 0;
virtual float GetMaxCamRotateX() const=0; virtual const zeus::CColor& GetAutomapperWidgetColor() const = 0;
virtual float GetCamAngle() const=0; virtual float GetMiniCamDist() const = 0;
virtual const zeus::CColor& GetAutomapperWidgetColor() const=0; virtual float GetMiniCamXAngle() const = 0;
virtual float GetMiniCamDist() const=0; virtual float GetMiniCamAngle() const = 0;
virtual float GetMiniCamXAngle() const=0; virtual const zeus::CColor& GetAutomapperWidgetMiniColor() const = 0;
virtual float GetMiniCamAngle() const=0; virtual const zeus::CColor& GetSurfaceVisitedColor() const = 0;
virtual const zeus::CColor& GetAutomapperWidgetMiniColor() const=0; virtual const zeus::CColor& GetOutlineVisitedColor() const = 0;
virtual const zeus::CColor& GetSurfaceVisitedColor() const=0; virtual const zeus::CColor& GetSurfaceUnvisitedColor() const = 0;
virtual const zeus::CColor& GetOutlineVisitedColor() const=0; virtual const zeus::CColor& GetOutlineUnvisitedColor() const = 0;
virtual const zeus::CColor& GetSurfaceUnvisitedColor() const=0; virtual const zeus::CColor& GetSurfaceSelectVisitedColor() const = 0;
virtual const zeus::CColor& GetOutlineUnvisitedColor() const=0; virtual const zeus::CColor& GetOutlineSelectVisitedColor() const = 0;
virtual const zeus::CColor& GetSurfaceSelectVisitedColor() const=0; virtual float GetMapSurfaceNormColorLinear() const = 0;
virtual const zeus::CColor& GetOutlineSelectVisitedColor() const=0; virtual float GetMapSurfaceNormColorConstant() const = 0;
virtual float GetMapSurfaceNormColorLinear() const=0; virtual float GetOpenMapScreenTime() const = 0;
virtual float GetMapSurfaceNormColorConstant() const=0; virtual float GetCloseMapScreenTime() const = 0;
virtual float GetOpenMapScreenTime() const=0; virtual float GetHintPanTime() const = 0;
virtual float GetCloseMapScreenTime() const=0; virtual float GetCamZoomUnitsPerFrame() const = 0;
virtual float GetHintPanTime() const=0; virtual float GetCamRotateDegreesPerFrame() const = 0;
virtual float GetCamZoomUnitsPerFrame() const=0; virtual float GetBaseMapScreenCameraMoveSpeed() const = 0;
virtual float GetCamRotateDegreesPerFrame() const=0; virtual const zeus::CColor& GetSurfaceSelectUnvisitedColor() const = 0;
virtual float GetBaseMapScreenCameraMoveSpeed() const=0; virtual const zeus::CColor& GetOutlineSelectUnvisitedColor() const = 0;
virtual const zeus::CColor& GetSurfaceSelectUnvisitedColor() const=0; virtual float GetMiniAlphaSurfaceVisited() const = 0;
virtual const zeus::CColor& GetOutlineSelectUnvisitedColor() const=0; virtual float GetAlphaSurfaceVisited() const = 0;
virtual float GetMiniAlphaSurfaceVisited() const=0; virtual float GetMiniAlphaOutlineVisited() const = 0;
virtual float GetAlphaSurfaceVisited() const=0; virtual float GetAlphaOutlineVisited() const = 0;
virtual float GetMiniAlphaOutlineVisited() const=0; virtual float GetMiniAlphaSurfaceUnvisited() const = 0;
virtual float GetAlphaOutlineVisited() const=0; virtual float GetAlphaSurfaceUnvisited() const = 0;
virtual float GetMiniAlphaSurfaceUnvisited() const=0; virtual float GetMiniAlphaOutlineUnvisited() const = 0;
virtual float GetAlphaSurfaceUnvisited() const=0; virtual float GetAlphaOutlineUnvisited() const = 0;
virtual float GetMiniAlphaOutlineUnvisited() const=0; virtual const zeus::CVector3f& GetDoorCenter() const = 0;
virtual float GetAlphaOutlineUnvisited() const=0; virtual float GetMiniMapViewportWidth() const = 0;
virtual const zeus::CVector3f& GetDoorCenter() const=0; virtual float GetMiniMapViewportHeight() const = 0;
virtual float GetMiniMapViewportWidth() const=0; virtual float GetMiniMapCamDistScale() const = 0;
virtual float GetMiniMapViewportHeight() const=0; virtual float GetMapPlaneScaleX() const = 0;
virtual float GetMiniMapCamDistScale() const=0; virtual float GetMapPlaneScaleZ() const = 0;
virtual float GetMapPlaneScaleX() const=0; virtual float GetUniverseCamDist() const = 0;
virtual float GetMapPlaneScaleZ() const=0; virtual float GetMinUniverseCamDist() const = 0;
virtual float GetUniverseCamDist() const=0; virtual float GetMaxUniverseCamDist() const = 0;
virtual float GetMinUniverseCamDist() const=0; virtual float GetSwitchToFromUniverseTime() const = 0;
virtual float GetMaxUniverseCamDist() const=0; virtual float GetCamPanUnitsPerFrame() const = 0;
virtual float GetSwitchToFromUniverseTime() const=0; virtual float GetAutomapperScaleX() const = 0;
virtual float GetCamPanUnitsPerFrame() const=0; virtual float GetAutomapperScaleZ() const = 0;
virtual float GetAutomapperScaleX() const=0; virtual float GetCamVerticalOffset() const = 0;
virtual float GetAutomapperScaleZ() const=0; virtual const zeus::CColor& GetMiniMapSamusModColor() const = 0;
virtual float GetCamVerticalOffset() const=0; virtual const zeus::CColor& GetAreaFlashPulseColor() const = 0;
virtual const zeus::CColor& GetMiniMapSamusModColor() const=0; virtual const zeus::CColor& GetDoorColor(int idx) const = 0;
virtual const zeus::CColor& GetAreaFlashPulseColor() const=0; virtual const zeus::CColor& GetOpenDoorColor() const = 0;
virtual const zeus::CColor& GetDoorColor(int idx) const=0;
virtual const zeus::CColor& GetOpenDoorColor() const=0;
}; };
} } // namespace DataSpec

View File

@ -2,71 +2,68 @@
#include "ITweak.hpp" #include "ITweak.hpp"
namespace DataSpec namespace DataSpec {
{ struct ITweakBall : ITweak {
struct ITweakBall : ITweak virtual float GetMaxBallTranslationAcceleration(int s) const = 0;
{ virtual float GetBallTranslationFriction(int s) const = 0;
virtual float GetMaxBallTranslationAcceleration(int s) const=0; virtual float GetBallTranslationMaxSpeed(int s) const = 0;
virtual float GetBallTranslationFriction(int s) const=0; virtual float GetBallCameraElevation() const = 0;
virtual float GetBallTranslationMaxSpeed(int s) const=0; virtual float GetBallCameraAnglePerSecond() const = 0;
virtual float GetBallCameraElevation() const=0; virtual const zeus::CVector3f& GetBallCameraOffset() const = 0;
virtual float GetBallCameraAnglePerSecond() const=0; virtual float GetBallCameraMinSpeedDistance() const = 0;
virtual const zeus::CVector3f& GetBallCameraOffset() const=0; virtual float GetBallCameraMaxSpeedDistance() const = 0;
virtual float GetBallCameraMinSpeedDistance() const=0; virtual float GetBallCameraBackwardsDistance() const = 0;
virtual float GetBallCameraMaxSpeedDistance() const=0; virtual float GetBallCameraSpringConstant() const = 0;
virtual float GetBallCameraBackwardsDistance() const=0; virtual float GetBallCameraSpringMax() const = 0;
virtual float GetBallCameraSpringConstant() const=0; virtual float GetBallCameraSpringTardis() const = 0;
virtual float GetBallCameraSpringMax() const=0; virtual float GetBallCameraCentroidSpringConstant() const = 0;
virtual float GetBallCameraSpringTardis() const=0; virtual float GetBallCameraCentroidSpringMax() const = 0;
virtual float GetBallCameraCentroidSpringConstant() const=0; virtual float GetBallCameraCentroidSpringTardis() const = 0;
virtual float GetBallCameraCentroidSpringMax() const=0; virtual float GetBallCameraCentroidDistanceSpringConstant() const = 0;
virtual float GetBallCameraCentroidSpringTardis() const=0; virtual float GetBallCameraCentroidDistanceSpringMax() const = 0;
virtual float GetBallCameraCentroidDistanceSpringConstant() const=0; virtual float GetBallCameraCentroidDistanceSpringTardis() const = 0;
virtual float GetBallCameraCentroidDistanceSpringMax() const=0; virtual float GetBallCameraLookAtSpringConstant() const = 0;
virtual float GetBallCameraCentroidDistanceSpringTardis() const=0; virtual float GetBallCameraLookAtSpringMax() const = 0;
virtual float GetBallCameraLookAtSpringConstant() const=0; virtual float GetBallCameraLookAtSpringTardis() const = 0;
virtual float GetBallCameraLookAtSpringMax() const=0; virtual float GetBallForwardBrakingAcceleration(int s) const = 0;
virtual float GetBallCameraLookAtSpringTardis() const=0; virtual float GetBallGravity() const = 0;
virtual float GetBallForwardBrakingAcceleration(int s) const=0; virtual float GetBallWaterGravity() const = 0;
virtual float GetBallGravity() const=0; virtual float GetBallSlipFactor(int s) const = 0;
virtual float GetBallWaterGravity() const=0; virtual float GetConservativeDoorCameraDistance() const = 0;
virtual float GetBallSlipFactor(int s) const=0; virtual float GetBallCameraChaseElevation() const = 0;
virtual float GetConservativeDoorCameraDistance() const=0; virtual float GetBallCameraChaseDampenAngle() const = 0;
virtual float GetBallCameraChaseElevation() const=0; virtual float GetBallCameraChaseDistance() const = 0;
virtual float GetBallCameraChaseDampenAngle() const=0; virtual float GetBallCameraChaseYawSpeed() const = 0;
virtual float GetBallCameraChaseDistance() const=0; virtual float GetBallCameraChaseAnglePerSecond() const = 0;
virtual float GetBallCameraChaseYawSpeed() const=0; virtual const zeus::CVector3f& GetBallCameraChaseLookAtOffset() const = 0;
virtual float GetBallCameraChaseAnglePerSecond() const=0; virtual float GetBallCameraChaseSpringConstant() const = 0;
virtual const zeus::CVector3f& GetBallCameraChaseLookAtOffset() const=0; virtual float GetBallCameraChaseSpringMax() const = 0;
virtual float GetBallCameraChaseSpringConstant() const=0; virtual float GetBallCameraChaseSpringTardis() const = 0;
virtual float GetBallCameraChaseSpringMax() const=0; virtual float GetBallCameraBoostElevation() const = 0;
virtual float GetBallCameraChaseSpringTardis() const=0; virtual float GetBallCameraBoostDampenAngle() const = 0;
virtual float GetBallCameraBoostElevation() const=0; virtual float GetBallCameraBoostDistance() const = 0;
virtual float GetBallCameraBoostDampenAngle() const=0; virtual float GetBallCameraBoostYawSpeed() const = 0;
virtual float GetBallCameraBoostDistance() const=0; virtual float GetBallCameraBoostAnglePerSecond() const = 0;
virtual float GetBallCameraBoostYawSpeed() const=0; virtual const zeus::CVector3f& GetBallCameraBoostLookAtOffset() const = 0;
virtual float GetBallCameraBoostAnglePerSecond() const=0; virtual float GetBallCameraBoostSpringConstant() const = 0;
virtual const zeus::CVector3f& GetBallCameraBoostLookAtOffset() const=0; virtual float GetBallCameraBoostSpringMax() const = 0;
virtual float GetBallCameraBoostSpringConstant() const=0; virtual float GetBallCameraBoostSpringTardis() const = 0;
virtual float GetBallCameraBoostSpringMax() const=0; virtual float GetMinimumAlignmentSpeed() const = 0;
virtual float GetBallCameraBoostSpringTardis() const=0; virtual float GetTireness() const = 0;
virtual float GetMinimumAlignmentSpeed() const=0; virtual float GetMaxLeanAngle() const = 0;
virtual float GetTireness() const=0; virtual float GetTireToMarbleThresholdSpeed() const = 0;
virtual float GetMaxLeanAngle() const=0; virtual float GetMarbleToTireThresholdSpeed() const = 0;
virtual float GetTireToMarbleThresholdSpeed() const=0; virtual float GetForceToLeanGain() const = 0;
virtual float GetMarbleToTireThresholdSpeed() const=0; virtual float GetLeanTrackingGain() const = 0;
virtual float GetForceToLeanGain() const=0; virtual float GetBallCameraControlDistance() const = 0;
virtual float GetLeanTrackingGain() const=0; virtual float GetLeftStickDivisor() const = 0;
virtual float GetBallCameraControlDistance() const=0; virtual float GetRightStickDivisor() const = 0;
virtual float GetLeftStickDivisor() const=0; virtual float GetBallTouchRadius() const = 0;
virtual float GetRightStickDivisor() const=0; virtual float GetBoostBallDrainTime() const = 0;
virtual float GetBallTouchRadius() const=0; virtual float GetBoostBallMaxChargeTime() const = 0;
virtual float GetBoostBallDrainTime() const=0; virtual float GetBoostBallMinChargeTime() const = 0;
virtual float GetBoostBallMaxChargeTime() const=0; virtual float GetBoostBallMinRelativeSpeedForDamage() const = 0;
virtual float GetBoostBallMinChargeTime() const=0; virtual float GetBoostBallChargeTimeTable(int i) const = 0;
virtual float GetBoostBallMinRelativeSpeedForDamage() const=0; virtual float GetBoostBallIncrementalSpeedTable(int i) const = 0;
virtual float GetBoostBallChargeTimeTable(int i) const=0;
virtual float GetBoostBallIncrementalSpeedTable(int i) const=0;
}; };
} } // namespace DataSpec

View File

@ -2,28 +2,25 @@
#include "ITweak.hpp" #include "ITweak.hpp"
namespace DataSpec namespace DataSpec {
{
struct ITweakGame : ITweak struct ITweakGame : ITweak {
{ virtual std::string_view GetWorldPrefix() const = 0;
virtual std::string_view GetWorldPrefix() const = 0; virtual bool GetSplashScreensDisabled() const = 0;
virtual bool GetSplashScreensDisabled() const = 0; virtual float GetFirstPersonFOV() const = 0;
virtual float GetFirstPersonFOV() const = 0; virtual float GetPressStartDelay() const = 0;
virtual float GetPressStartDelay() const = 0; virtual float GetWavecapIntensityNormal() const = 0;
virtual float GetWavecapIntensityNormal() const = 0; virtual float GetWavecapIntensityPoison() const = 0;
virtual float GetWavecapIntensityPoison() const = 0; virtual float GetWavecapIntensityLava() const = 0;
virtual float GetWavecapIntensityLava() const = 0; virtual float GetRippleIntensityNormal() const = 0;
virtual float GetRippleIntensityNormal() const = 0; virtual float GetRippleIntensityPoison() const = 0;
virtual float GetRippleIntensityPoison() const = 0; virtual float GetRippleIntensityLava() const = 0;
virtual float GetRippleIntensityLava() const = 0; virtual float GetFluidEnvBumpScale() const = 0;
virtual float GetFluidEnvBumpScale() const = 0; virtual float GetWaterFogDistanceBase() const = 0;
virtual float GetWaterFogDistanceBase() const = 0; virtual float GetWaterFogDistanceRange() const = 0;
virtual float GetWaterFogDistanceRange() const = 0; virtual float GetGravityWaterFogDistanceBase() const = 0;
virtual float GetGravityWaterFogDistanceBase() const = 0; virtual float GetGravityWaterFogDistanceRange() const = 0;
virtual float GetGravityWaterFogDistanceRange() const = 0; virtual float GetHardModeDamageMultiplier() const = 0;
virtual float GetHardModeDamageMultiplier() const = 0; virtual float GetHardModeWeaponMultiplier() const = 0;
virtual float GetHardModeWeaponMultiplier() const = 0;
}; };
} } // namespace DataSpec

View File

@ -3,151 +3,134 @@
#include "ITweak.hpp" #include "ITweak.hpp"
#include "zeus/CVector2f.hpp" #include "zeus/CVector2f.hpp"
namespace DataSpec namespace DataSpec {
{
struct ITweakGui : ITweak struct ITweakGui : ITweak {
{ enum class EHudVisMode : atUint32 { Zero, One, Two, Three };
enum class EHudVisMode : atUint32
{
Zero,
One,
Two,
Three
};
enum class EHelmetVisMode : atUint32 enum class EHelmetVisMode : atUint32 { ReducedUpdate, NotVisible, Deco, HelmetDeco, GlowHelmetDeco, HelmetOnly };
{
ReducedUpdate,
NotVisible,
Deco,
HelmetDeco,
GlowHelmetDeco,
HelmetOnly
};
virtual float GetMapAlphaInterpolant() const=0; virtual float GetMapAlphaInterpolant() const = 0;
virtual float GetPauseBlurFactor() const=0; virtual float GetPauseBlurFactor() const = 0;
virtual float GetRadarXYRadius() const=0; virtual float GetRadarXYRadius() const = 0;
virtual float GetRadarZRadius() const=0; virtual float GetRadarZRadius() const = 0;
virtual float GetRadarZCloseRadius() const=0; virtual float GetRadarZCloseRadius() const = 0;
virtual float GetEnergyBarFilledSpeed() const=0; virtual float GetEnergyBarFilledSpeed() const = 0;
virtual float GetEnergyBarShadowSpeed() const=0; virtual float GetEnergyBarShadowSpeed() const = 0;
virtual float GetEnergyBarDrainDelay() const=0; virtual float GetEnergyBarDrainDelay() const = 0;
virtual bool GetEnergyBarAlwaysResetDelay() const=0; virtual bool GetEnergyBarAlwaysResetDelay() const = 0;
virtual float GetHudDamagePracticalsGainConstant() const=0; virtual float GetHudDamagePracticalsGainConstant() const = 0;
virtual float GetHudDamagePracticalsGainLinear() const=0; virtual float GetHudDamagePracticalsGainLinear() const = 0;
virtual float GetHudDamagePracticalsInitConstant() const=0; virtual float GetHudDamagePracticalsInitConstant() const = 0;
virtual float GetHudDamagePracticalsInitLinear() const=0; virtual float GetHudDamagePracticalsInitLinear() const = 0;
virtual float GetHudDamageLightSpotAngle() const=0; virtual float GetHudDamageLightSpotAngle() const = 0;
virtual float GetDamageLightAngleC() const=0; virtual float GetDamageLightAngleC() const = 0;
virtual float GetDamageLightAngleL() const=0; virtual float GetDamageLightAngleL() const = 0;
virtual float GetDamageLightAngleQ() const=0; virtual float GetDamageLightAngleQ() const = 0;
virtual atVec3f GetDamageLightPreTranslate() const=0; virtual atVec3f GetDamageLightPreTranslate() const = 0;
virtual atVec3f GetDamageLightCenterTranslate() const=0; virtual atVec3f GetDamageLightCenterTranslate() const = 0;
virtual float GetDamageLightXfXAngle() const=0; virtual float GetDamageLightXfXAngle() const = 0;
virtual float GetDamageLightXfZAngle() const=0; virtual float GetDamageLightXfZAngle() const = 0;
virtual float GetHudDecoShakeTranslateVelConstant() const=0; virtual float GetHudDecoShakeTranslateVelConstant() const = 0;
virtual float GetHudDecoShakeTranslateVelLinear() const=0; virtual float GetHudDecoShakeTranslateVelLinear() const = 0;
virtual float GetMaxDecoDamageShakeTranslate() const=0; virtual float GetMaxDecoDamageShakeTranslate() const = 0;
virtual float GetDecoDamageShakeDeceleration() const=0; virtual float GetDecoDamageShakeDeceleration() const = 0;
virtual float GetDecoShakeGainConstant() const=0; virtual float GetDecoShakeGainConstant() const = 0;
virtual float GetDecoShakeGainLinear() const=0; virtual float GetDecoShakeGainLinear() const = 0;
virtual float GetDecoShakeInitConstant() const=0; virtual float GetDecoShakeInitConstant() const = 0;
virtual float GetDecoShakeInitLinear() const=0; virtual float GetDecoShakeInitLinear() const = 0;
virtual float GetMaxDecoDamageShakeRotate() const=0; virtual float GetMaxDecoDamageShakeRotate() const = 0;
virtual atUint32 GetHudCamFovTweak() const=0; virtual atUint32 GetHudCamFovTweak() const = 0;
virtual atUint32 GetHudCamYTweak() const=0; virtual atUint32 GetHudCamYTweak() const = 0;
virtual atUint32 GetHudCamZTweak() const=0; virtual atUint32 GetHudCamZTweak() const = 0;
virtual float GetBeamVisorMenuAnimTime() const=0; virtual float GetBeamVisorMenuAnimTime() const = 0;
virtual float GetVisorBeamMenuItemActiveScale() const=0; virtual float GetVisorBeamMenuItemActiveScale() const = 0;
virtual float GetVisorBeamMenuItemInactiveScale() const=0; virtual float GetVisorBeamMenuItemInactiveScale() const = 0;
virtual float GetVisorBeamMenuItemTranslate() const=0; virtual float GetVisorBeamMenuItemTranslate() const = 0;
virtual float GetThreatRange() const=0; virtual float GetThreatRange() const = 0;
virtual float GetRadarScopeCoordRadius() const=0; virtual float GetRadarScopeCoordRadius() const = 0;
virtual float GetRadarPlayerPaintRadius() const=0; virtual float GetRadarPlayerPaintRadius() const = 0;
virtual float GetRadarEnemyPaintRadius() const=0; virtual float GetRadarEnemyPaintRadius() const = 0;
virtual float GetMissileArrowVisTime() const=0; virtual float GetMissileArrowVisTime() const = 0;
virtual EHudVisMode GetHudVisMode() const=0; virtual EHudVisMode GetHudVisMode() const = 0;
virtual EHelmetVisMode GetHelmetVisMode() const=0; virtual EHelmetVisMode GetHelmetVisMode() const = 0;
virtual atUint32 GetEnableAutoMapper() const=0; virtual atUint32 GetEnableAutoMapper() const = 0;
virtual atUint32 GetEnableTargetingManager() const=0; virtual atUint32 GetEnableTargetingManager() const = 0;
virtual atUint32 GetEnablePlayerVisor() const=0; virtual atUint32 GetEnablePlayerVisor() const = 0;
virtual float GetThreatWarningFraction() const=0; virtual float GetThreatWarningFraction() const = 0;
virtual float GetMissileWarningFraction() const=0; virtual float GetMissileWarningFraction() const = 0;
virtual float GetFreeLookFadeTime() const=0; virtual float GetFreeLookFadeTime() const = 0;
virtual float GetFreeLookSfxPitchScale() const=0; virtual float GetFreeLookSfxPitchScale() const = 0;
virtual bool GetNoAbsoluteFreeLookSfxPitch() const=0; virtual bool GetNoAbsoluteFreeLookSfxPitch() const = 0;
virtual float GetFaceReflectionOrthoWidth() const=0; virtual float GetFaceReflectionOrthoWidth() const = 0;
virtual float GetFaceReflectionOrthoHeight() const=0; virtual float GetFaceReflectionOrthoHeight() const = 0;
virtual float GetFaceReflectionDistance() const=0; virtual float GetFaceReflectionDistance() const = 0;
virtual float GetFaceReflectionHeight() const=0; virtual float GetFaceReflectionHeight() const = 0;
virtual float GetFaceReflectionAspect() const=0; virtual float GetFaceReflectionAspect() const = 0;
virtual float GetMissileWarningPulseTime() const=0; virtual float GetMissileWarningPulseTime() const = 0;
virtual float GetExplosionLightFalloffMultConstant() const=0; virtual float GetExplosionLightFalloffMultConstant() const = 0;
virtual float GetExplosionLightFalloffMultLinear() const=0; virtual float GetExplosionLightFalloffMultLinear() const = 0;
virtual float GetExplosionLightFalloffMultQuadratic() const=0; virtual float GetExplosionLightFalloffMultQuadratic() const = 0;
virtual float GetHudDamagePeakFactor() const=0; virtual float GetHudDamagePeakFactor() const = 0;
virtual float GetHudDamageFilterGainConstant() const=0; virtual float GetHudDamageFilterGainConstant() const = 0;
virtual float GetHudDamageFilterGainLinear() const=0; virtual float GetHudDamageFilterGainLinear() const = 0;
virtual float GetHudDamageFilterInitConstant() const=0; virtual float GetHudDamageFilterInitConstant() const = 0;
virtual float GetHudDamageFilterInitLinear() const=0; virtual float GetHudDamageFilterInitLinear() const = 0;
virtual float GetEnergyDrainModPeriod() const=0; virtual float GetEnergyDrainModPeriod() const = 0;
virtual bool GetEnergyDrainSinusoidalPulse() const=0; virtual bool GetEnergyDrainSinusoidalPulse() const = 0;
virtual bool GetEnergyDrainFilterAdditive() const=0; virtual bool GetEnergyDrainFilterAdditive() const = 0;
virtual float GetHudDamagePulseDuration() const=0; virtual float GetHudDamagePulseDuration() const = 0;
virtual float GetHudDamageColorGain() const=0; virtual float GetHudDamageColorGain() const = 0;
virtual float GetHudDecoShakeTranslateGain() const=0; virtual float GetHudDecoShakeTranslateGain() const = 0;
virtual float GetHudLagOffsetScale() const=0; virtual float GetHudLagOffsetScale() const = 0;
virtual float GetScanAppearanceDuration() const=0; virtual float GetScanAppearanceDuration() const = 0;
virtual float GetScanPaneFlashFactor() const=0; virtual float GetScanPaneFlashFactor() const = 0;
virtual float GetScanPaneFadeInTime() const=0; virtual float GetScanPaneFadeInTime() const = 0;
virtual float GetScanPaneFadeOutTime() const=0; virtual float GetScanPaneFadeOutTime() const = 0;
virtual float GetBallViewportYReduction() const=0; virtual float GetBallViewportYReduction() const = 0;
virtual float GetScanWindowIdleWidth() const=0; virtual float GetScanWindowIdleWidth() const = 0;
virtual float GetScanWindowIdleHeight() const=0; virtual float GetScanWindowIdleHeight() const = 0;
virtual float GetScanWindowActiveWidth() const=0; virtual float GetScanWindowActiveWidth() const = 0;
virtual float GetScanWindowActiveHeight() const=0; virtual float GetScanWindowActiveHeight() const = 0;
virtual float GetScanWindowMagnification() const=0; virtual float GetScanWindowMagnification() const = 0;
virtual float GetScanWindowScanningAspect() const=0; virtual float GetScanWindowScanningAspect() const = 0;
virtual float GetScanSpeed(int idx) const=0; virtual float GetScanSpeed(int idx) const = 0;
virtual float GetXrayBlurScaleLinear() const=0; virtual float GetXrayBlurScaleLinear() const = 0;
virtual float GetXrayBlurScaleQuadratic() const=0; virtual float GetXrayBlurScaleQuadratic() const = 0;
virtual float GetScanSidesAngle() const=0; virtual float GetScanSidesAngle() const = 0;
virtual float GetScanSidesXScale() const=0; virtual float GetScanSidesXScale() const = 0;
virtual float GetScanSidesPositionEnd() const=0; virtual float GetScanSidesPositionEnd() const = 0;
virtual float GetScanSidesDuration() const=0; virtual float GetScanSidesDuration() const = 0;
virtual float GetScanSidesStartTime() const=0; virtual float GetScanSidesStartTime() const = 0;
virtual float GetScanSidesEndTime() const=0; virtual float GetScanSidesEndTime() const = 0;
virtual float GetScanDataDotRadius() const=0; virtual float GetScanDataDotRadius() const = 0;
virtual float GetScanDataDotPosRandMagnitude() const=0; virtual float GetScanDataDotPosRandMagnitude() const = 0;
virtual float GetScanDataDotSeekDurationMin() const=0; virtual float GetScanDataDotSeekDurationMin() const = 0;
virtual float GetScanDataDotSeekDurationMax() const=0; virtual float GetScanDataDotSeekDurationMax() const = 0;
virtual float GetScanDataDotHoldDurationMin() const=0; virtual float GetScanDataDotHoldDurationMin() const = 0;
virtual float GetScanDataDotHoldDurationMax() const=0; virtual float GetScanDataDotHoldDurationMax() const = 0;
virtual float GetScanSidesPositionStart() const=0; virtual float GetScanSidesPositionStart() const = 0;
virtual bool GetShowAutomapperInMorphball() const=0; virtual bool GetShowAutomapperInMorphball() const = 0;
virtual bool GetLatchArticleText() const=0; virtual bool GetLatchArticleText() const = 0;
virtual float GetWorldTransManagerCharsPerSfx() const=0; virtual float GetWorldTransManagerCharsPerSfx() const = 0;
virtual atUint32 GetXRayFogMode() const=0; virtual atUint32 GetXRayFogMode() const = 0;
virtual float GetXRayFogNearZ() const=0; virtual float GetXRayFogNearZ() const = 0;
virtual float GetXRayFogFarZ() const=0; virtual float GetXRayFogFarZ() const = 0;
virtual const zeus::CColor& GetXRayFogColor() const=0; virtual const zeus::CColor& GetXRayFogColor() const = 0;
virtual float GetThermalVisorLevel() const=0; virtual float GetThermalVisorLevel() const = 0;
virtual const zeus::CColor& GetThermalVisorColor() const=0; virtual const zeus::CColor& GetThermalVisorColor() const = 0;
virtual const zeus::CColor& GetVisorHudLightAdd(int v) const=0; virtual const zeus::CColor& GetVisorHudLightAdd(int v) const = 0;
virtual const zeus::CColor& GetVisorHudLightMultiply(int v) const=0; virtual const zeus::CColor& GetVisorHudLightMultiply(int v) const = 0;
virtual const zeus::CColor& GetHudReflectivityLightColor() const=0; virtual const zeus::CColor& GetHudReflectivityLightColor() const = 0;
virtual float GetHudLightAttMulConstant() const=0; virtual float GetHudLightAttMulConstant() const = 0;
virtual float GetHudLightAttMulLinear() const=0; virtual float GetHudLightAttMulLinear() const = 0;
virtual float GetHudLightAttMulQuadratic() const=0; virtual float GetHudLightAttMulQuadratic() const = 0;
static float FaceReflectionDistanceDebugValueToActualValue(float v) { return 0.015f * v + 0.2f; } static float FaceReflectionDistanceDebugValueToActualValue(float v) { return 0.015f * v + 0.2f; }
static float FaceReflectionHeightDebugValueToActualValue(float v) { return 0.005f * v - 0.05f; } static float FaceReflectionHeightDebugValueToActualValue(float v) { return 0.005f * v - 0.05f; }
static float FaceReflectionAspectDebugValueToActualValue(float v) { return 0.05f * v + 1.f; } static float FaceReflectionAspectDebugValueToActualValue(float v) { return 0.05f * v + 1.f; }
static float FaceReflectionOrthoWidthDebugValueToActualValue(float v) { return 0.007f * v + 0.02f; } static float FaceReflectionOrthoWidthDebugValueToActualValue(float v) { return 0.007f * v + 0.02f; }
static float FaceReflectionOrthoHeightDebugValueToActualValue(float v) { return 0.007f * v + 0.02f; } static float FaceReflectionOrthoHeightDebugValueToActualValue(float v) { return 0.007f * v + 0.02f; }
}; };
} } // namespace DataSpec

View File

@ -2,106 +2,101 @@
#include "ITweak.hpp" #include "ITweak.hpp"
namespace DataSpec namespace DataSpec {
{ struct ITweakGuiColors : ITweak {
struct ITweakGuiColors : ITweak struct VisorEnergyInitColors {
{ const zeus::CColor& tankFilled;
struct VisorEnergyInitColors const zeus::CColor& tankEmpty;
{ const zeus::CColor& digitsFont;
const zeus::CColor& tankFilled; const zeus::CColor& digitsOutline;
const zeus::CColor& tankEmpty; };
const zeus::CColor& digitsFont;
const zeus::CColor& digitsOutline;
};
struct VisorEnergyBarColors struct VisorEnergyBarColors {
{ const zeus::CColor& filled;
const zeus::CColor& filled; const zeus::CColor& empty;
const zeus::CColor& empty; const zeus::CColor& shadow;
const zeus::CColor& shadow; };
};
virtual const zeus::CColor& GetPauseBlurFilterColor() const=0; virtual const zeus::CColor& GetPauseBlurFilterColor() const = 0;
virtual const zeus::CColor& GetRadarStuffColor() const=0; virtual const zeus::CColor& GetRadarStuffColor() const = 0;
virtual const zeus::CColor& GetRadarPlayerPaintColor() const=0; virtual const zeus::CColor& GetRadarPlayerPaintColor() const = 0;
virtual const zeus::CColor& GetRadarEnemyPaintColor() const=0; virtual const zeus::CColor& GetRadarEnemyPaintColor() const = 0;
virtual const zeus::CColor& GetHudMessageFill() const=0; virtual const zeus::CColor& GetHudMessageFill() const = 0;
virtual const zeus::CColor& GetHudMessageOutline() const=0; virtual const zeus::CColor& GetHudMessageOutline() const = 0;
virtual const zeus::CColor& GetHudFrameColor() const=0; virtual const zeus::CColor& GetHudFrameColor() const = 0;
virtual const zeus::CColor& GetMissileIconColorActive() const=0; virtual const zeus::CColor& GetMissileIconColorActive() const = 0;
virtual const zeus::CColor& GetVisorBeamMenuItemActive() const=0; virtual const zeus::CColor& GetVisorBeamMenuItemActive() const = 0;
virtual const zeus::CColor& GetVisorBeamMenuItemInactive() const=0; virtual const zeus::CColor& GetVisorBeamMenuItemInactive() const = 0;
virtual const zeus::CColor& GetEnergyBarFilledLowEnergy() const=0; virtual const zeus::CColor& GetEnergyBarFilledLowEnergy() const = 0;
virtual const zeus::CColor& GetEnergyBarShadowLowEnergy() const=0; virtual const zeus::CColor& GetEnergyBarShadowLowEnergy() const = 0;
virtual const zeus::CColor& GetEnergyBarEmptyLowEnergy() const=0; virtual const zeus::CColor& GetEnergyBarEmptyLowEnergy() const = 0;
virtual const zeus::CColor& GetHudDamageLightColor() const=0; virtual const zeus::CColor& GetHudDamageLightColor() const = 0;
virtual const zeus::CColor& GetVisorMenuTextFont() const=0; virtual const zeus::CColor& GetVisorMenuTextFont() const = 0;
virtual const zeus::CColor& GetVisorMenuTextOutline() const=0; virtual const zeus::CColor& GetVisorMenuTextOutline() const = 0;
virtual const zeus::CColor& GetBeamMenuTextFont() const=0; virtual const zeus::CColor& GetBeamMenuTextFont() const = 0;
virtual const zeus::CColor& GetBeamMenuTextOutline() const=0; virtual const zeus::CColor& GetBeamMenuTextOutline() const = 0;
virtual const zeus::CColor& GetEnergyWarningFont() const=0; virtual const zeus::CColor& GetEnergyWarningFont() const = 0;
virtual const zeus::CColor& GetThreatWarningFont() const=0; virtual const zeus::CColor& GetThreatWarningFont() const = 0;
virtual const zeus::CColor& GetMissileWarningFont() const=0; virtual const zeus::CColor& GetMissileWarningFont() const = 0;
virtual const zeus::CColor& GetThreatBarFilled() const=0; virtual const zeus::CColor& GetThreatBarFilled() const = 0;
virtual const zeus::CColor& GetThreatBarShadow() const=0; virtual const zeus::CColor& GetThreatBarShadow() const = 0;
virtual const zeus::CColor& GetThreatBarEmpty() const=0; virtual const zeus::CColor& GetThreatBarEmpty() const = 0;
virtual const zeus::CColor& GetMissileBarFilled() const=0; virtual const zeus::CColor& GetMissileBarFilled() const = 0;
virtual const zeus::CColor& GetMissileBarShadow() const=0; virtual const zeus::CColor& GetMissileBarShadow() const = 0;
virtual const zeus::CColor& GetMissileBarEmpty() const=0; virtual const zeus::CColor& GetMissileBarEmpty() const = 0;
virtual const zeus::CColor& GetThreatIconColor() const=0; virtual const zeus::CColor& GetThreatIconColor() const = 0;
virtual const zeus::CColor& GetTickDecoColor() const=0; virtual const zeus::CColor& GetTickDecoColor() const = 0;
virtual const zeus::CColor& GetHelmetLightColor() const=0; virtual const zeus::CColor& GetHelmetLightColor() const = 0;
virtual const zeus::CColor& GetThreatIconSafeColor() const=0; virtual const zeus::CColor& GetThreatIconSafeColor() const = 0;
virtual const zeus::CColor& GetMissileIconColorInactive() const=0; virtual const zeus::CColor& GetMissileIconColorInactive() const = 0;
virtual const zeus::CColor& GetMissileIconColorChargedCanAlt() const=0; virtual const zeus::CColor& GetMissileIconColorChargedCanAlt() const = 0;
virtual const zeus::CColor& GetMissileIconColorChargedNoAlt() const=0; virtual const zeus::CColor& GetMissileIconColorChargedNoAlt() const = 0;
virtual const zeus::CColor& GetMissileIconColorDepleteAlt() const=0; virtual const zeus::CColor& GetMissileIconColorDepleteAlt() const = 0;
virtual const zeus::CColor& GetVisorBeamMenuLozColor() const=0; virtual const zeus::CColor& GetVisorBeamMenuLozColor() const = 0;
virtual const zeus::CColor& GetEnergyWarningOutline() const=0; virtual const zeus::CColor& GetEnergyWarningOutline() const = 0;
virtual const zeus::CColor& GetThreatWarningOutline() const=0; virtual const zeus::CColor& GetThreatWarningOutline() const = 0;
virtual const zeus::CColor& GetMissileWarningOutline() const=0; virtual const zeus::CColor& GetMissileWarningOutline() const = 0;
virtual const zeus::CColor& GetDamageAmbientColor() const=0; virtual const zeus::CColor& GetDamageAmbientColor() const = 0;
virtual const zeus::CColor& GetScanFrameInactiveColor() const=0; virtual const zeus::CColor& GetScanFrameInactiveColor() const = 0;
virtual const zeus::CColor& GetScanFrameActiveColor() const=0; virtual const zeus::CColor& GetScanFrameActiveColor() const = 0;
virtual const zeus::CColor& GetScanFrameImpulseColor() const=0; virtual const zeus::CColor& GetScanFrameImpulseColor() const = 0;
virtual const zeus::CColor& GetScanVisorHudLightMultiply() const=0; virtual const zeus::CColor& GetScanVisorHudLightMultiply() const = 0;
virtual const zeus::CColor& GetScanVisorScreenDimColor() const=0; virtual const zeus::CColor& GetScanVisorScreenDimColor() const = 0;
virtual const zeus::CColor& GetThermalVisorHudLightMultiply() const=0; virtual const zeus::CColor& GetThermalVisorHudLightMultiply() const = 0;
virtual const zeus::CColor& GetEnergyDrainFilterColor() const=0; virtual const zeus::CColor& GetEnergyDrainFilterColor() const = 0;
virtual const zeus::CColor& GetDamageAmbientPulseColor() const=0; virtual const zeus::CColor& GetDamageAmbientPulseColor() const = 0;
virtual const zeus::CColor& GetEnergyBarFlashColor() const=0; virtual const zeus::CColor& GetEnergyBarFlashColor() const = 0;
virtual const zeus::CColor& GetXRayEnergyDecoColor() const=0; virtual const zeus::CColor& GetXRayEnergyDecoColor() const = 0;
virtual const zeus::CColor& GetScanDataDotColor() const=0; virtual const zeus::CColor& GetScanDataDotColor() const = 0;
virtual const zeus::CColor& GetPowerBombDigitAvailableFont() const=0; virtual const zeus::CColor& GetPowerBombDigitAvailableFont() const = 0;
virtual const zeus::CColor& GetPowerBombDigitAvailableOutline() const=0; virtual const zeus::CColor& GetPowerBombDigitAvailableOutline() const = 0;
virtual const zeus::CColor& GetBallBombFilledColor() const=0; virtual const zeus::CColor& GetBallBombFilledColor() const = 0;
virtual const zeus::CColor& GetBallBombEmptyColor() const=0; virtual const zeus::CColor& GetBallBombEmptyColor() const = 0;
virtual const zeus::CColor& GetPowerBombIconAvailableColor() const=0; virtual const zeus::CColor& GetPowerBombIconAvailableColor() const = 0;
virtual const zeus::CColor& GetBallBombEnergyColor() const=0; virtual const zeus::CColor& GetBallBombEnergyColor() const = 0;
virtual const zeus::CColor& GetBallBombDecoColor() const=0; virtual const zeus::CColor& GetBallBombDecoColor() const = 0;
virtual const zeus::CColor& GetPowerBombDigitDelpetedFont() const=0; virtual const zeus::CColor& GetPowerBombDigitDelpetedFont() const = 0;
virtual const zeus::CColor& GetPowerBombDigitDelpetedOutline() const=0; virtual const zeus::CColor& GetPowerBombDigitDelpetedOutline() const = 0;
virtual const zeus::CColor& GetPowerBombIconDepletedColor() const=0; virtual const zeus::CColor& GetPowerBombIconDepletedColor() const = 0;
virtual const zeus::CColor& GetScanDisplayImagePaneColor() const=0; virtual const zeus::CColor& GetScanDisplayImagePaneColor() const = 0;
virtual const zeus::CColor& GetThreatIconWarningColor() const=0; virtual const zeus::CColor& GetThreatIconWarningColor() const = 0;
virtual const zeus::CColor& GetHudCounterFill() const=0; virtual const zeus::CColor& GetHudCounterFill() const = 0;
virtual const zeus::CColor& GetHudCounterOutline() const=0; virtual const zeus::CColor& GetHudCounterOutline() const = 0;
virtual const zeus::CColor& GetScanIconCriticalColor() const=0; virtual const zeus::CColor& GetScanIconCriticalColor() const = 0;
virtual const zeus::CColor& GetScanIconCriticalDimColor() const=0; virtual const zeus::CColor& GetScanIconCriticalDimColor() const = 0;
virtual const zeus::CColor& GetScanIconNoncriticalColor() const=0; virtual const zeus::CColor& GetScanIconNoncriticalColor() const = 0;
virtual const zeus::CColor& GetScanIconNoncriticalDimColor() const=0; virtual const zeus::CColor& GetScanIconNoncriticalDimColor() const = 0;
virtual const zeus::CColor& GetScanReticuleColor() const=0; virtual const zeus::CColor& GetScanReticuleColor() const = 0;
virtual const zeus::CColor& GetThreatDigitsFont() const=0; virtual const zeus::CColor& GetThreatDigitsFont() const = 0;
virtual const zeus::CColor& GetThreatDigitsOutline() const=0; virtual const zeus::CColor& GetThreatDigitsOutline() const = 0;
virtual const zeus::CColor& GetMissileDigitsFont() const=0; virtual const zeus::CColor& GetMissileDigitsFont() const = 0;
virtual const zeus::CColor& GetMissileDigitsOutline() const=0; virtual const zeus::CColor& GetMissileDigitsOutline() const = 0;
virtual const zeus::CColor& GetThermalDecoColor() const=0; virtual const zeus::CColor& GetThermalDecoColor() const = 0;
virtual const zeus::CColor& GetThermalOutlinesColor() const=0; virtual const zeus::CColor& GetThermalOutlinesColor() const = 0;
virtual const zeus::CColor& GetThermalLockColor() const=0; virtual const zeus::CColor& GetThermalLockColor() const = 0;
virtual const zeus::CColor& GetPauseItemAmberColor() const=0; virtual const zeus::CColor& GetPauseItemAmberColor() const = 0;
virtual const zeus::CColor& GetPauseItemBlueColor() const=0; virtual const zeus::CColor& GetPauseItemBlueColor() const = 0;
virtual VisorEnergyInitColors GetVisorEnergyInitColors(int idx) const=0; virtual VisorEnergyInitColors GetVisorEnergyInitColors(int idx) const = 0;
virtual VisorEnergyBarColors GetVisorEnergyBarColors(int idx) const=0; virtual VisorEnergyBarColors GetVisorEnergyBarColors(int idx) const = 0;
}; };
} } // namespace DataSpec

View File

@ -4,137 +4,130 @@
#include "Runtime/IFactory.hpp" #include "Runtime/IFactory.hpp"
#include "Runtime/CPlayerState.hpp" #include "Runtime/CPlayerState.hpp"
namespace DataSpec namespace DataSpec {
{
struct ITweakGunRes : ITweak struct ITweakGunRes : ITweak {
{ using ResId = urde::CAssetId;
using ResId = urde::CAssetId; using EBeamId = urde::CPlayerState::EBeamId;
using EBeamId = urde::CPlayerState::EBeamId;
ResId x4_gunMotion; ResId x4_gunMotion;
ResId x8_grappleArm; ResId x8_grappleArm;
ResId xc_rightHand; ResId xc_rightHand;
ResId x10_powerBeam; ResId x10_powerBeam;
ResId x14_iceBeam; ResId x14_iceBeam;
ResId x18_waveBeam; ResId x18_waveBeam;
ResId x1c_plasmaBeam; ResId x1c_plasmaBeam;
ResId x20_phazonBeam; ResId x20_phazonBeam;
ResId x24_holoTransition; ResId x24_holoTransition;
ResId x28_bombSet; ResId x28_bombSet;
ResId x2c_bombExplode; ResId x2c_bombExplode;
ResId x30_powerBombExplode; ResId x30_powerBombExplode;
/* Power, Ice, Wave, Plasma, Phazon / Beam, Ball */ /* Power, Ice, Wave, Plasma, Phazon / Beam, Ball */
ResId x34_weapons[5][2]; ResId x34_weapons[5][2];
ResId x84_muzzle[5]; ResId x84_muzzle[5];
ResId x94_charge[5]; ResId x94_charge[5];
ResId xa4_auxMuzzle[5]; ResId xa4_auxMuzzle[5];
ResId xb4_grappleSegment; ResId xb4_grappleSegment;
ResId xb8_grappleClaw; ResId xb8_grappleClaw;
ResId xbc_grappleHit; ResId xbc_grappleHit;
ResId xc0_grappleMuzzle; ResId xc0_grappleMuzzle;
ResId xc4_grappleSwoosh; ResId xc4_grappleSwoosh;
ResId GetBeamModel(EBeamId beam) const ResId GetBeamModel(EBeamId beam) const {
{ auto b = int(beam);
auto b = int(beam); if (b < 0 || b > 4)
if (b < 0 || b > 4) b = 0;
b = 0; switch (EBeamId(b)) {
switch (EBeamId(b)) default:
{ case EBeamId::Power:
default: return x10_powerBeam;
case EBeamId::Power: case EBeamId::Ice:
return x10_powerBeam; return x14_iceBeam;
case EBeamId::Ice: case EBeamId::Wave:
return x14_iceBeam; return x18_waveBeam;
case EBeamId::Wave: case EBeamId::Plasma:
return x18_waveBeam; return x1c_plasmaBeam;
case EBeamId::Plasma: case EBeamId::Phazon:
return x1c_plasmaBeam; return x20_phazonBeam;
case EBeamId::Phazon:
return x20_phazonBeam;
}
} }
}
const ResId* GetWeaponPair(EBeamId beam) const const ResId* GetWeaponPair(EBeamId beam) const {
{ auto b = int(beam);
auto b = int(beam); if (b < 0 || b > 4)
if (b < 0 || b > 4) return x34_weapons[0];
return x34_weapons[0]; return x34_weapons[b];
return x34_weapons[b]; }
}
void ResolveResources(const urde::IFactory& factory) void ResolveResources(const urde::IFactory& factory) {
{ x4_gunMotion = factory.GetResourceIdByName(GetGunMotion().c_str())->id;
x4_gunMotion = factory.GetResourceIdByName(GetGunMotion().c_str())->id; x8_grappleArm = factory.GetResourceIdByName(GetGrappleArm().c_str())->id;
x8_grappleArm = factory.GetResourceIdByName(GetGrappleArm().c_str())->id; xc_rightHand = factory.GetResourceIdByName(GetRightHand().c_str())->id;
xc_rightHand = factory.GetResourceIdByName(GetRightHand().c_str())->id;
x10_powerBeam = factory.GetResourceIdByName(GetPowerBeam().c_str())->id; x10_powerBeam = factory.GetResourceIdByName(GetPowerBeam().c_str())->id;
x14_iceBeam = factory.GetResourceIdByName(GetIceBeam().c_str())->id; x14_iceBeam = factory.GetResourceIdByName(GetIceBeam().c_str())->id;
x18_waveBeam = factory.GetResourceIdByName(GetWaveBeam().c_str())->id; x18_waveBeam = factory.GetResourceIdByName(GetWaveBeam().c_str())->id;
x1c_plasmaBeam = factory.GetResourceIdByName(GetPlasmaBeam().c_str())->id; x1c_plasmaBeam = factory.GetResourceIdByName(GetPlasmaBeam().c_str())->id;
x20_phazonBeam = factory.GetResourceIdByName(GetPhazonBeam().c_str())->id; x20_phazonBeam = factory.GetResourceIdByName(GetPhazonBeam().c_str())->id;
x24_holoTransition = factory.GetResourceIdByName(GetHoloTransition().c_str())->id; x24_holoTransition = factory.GetResourceIdByName(GetHoloTransition().c_str())->id;
x28_bombSet = factory.GetResourceIdByName(GetBombSet().c_str())->id; x28_bombSet = factory.GetResourceIdByName(GetBombSet().c_str())->id;
x2c_bombExplode = factory.GetResourceIdByName(GetBombExplode().c_str())->id; x2c_bombExplode = factory.GetResourceIdByName(GetBombExplode().c_str())->id;
x30_powerBombExplode = factory.GetResourceIdByName(GetPowerBombExplode().c_str())->id; x30_powerBombExplode = factory.GetResourceIdByName(GetPowerBombExplode().c_str())->id;
for (int i=0 ; i<5 ; ++i) for (int i = 0; i < 5; ++i)
for (int j=0 ; j<2 ; ++j) for (int j = 0; j < 2; ++j)
x34_weapons[i][j] = factory.GetResourceIdByName(GetWeapon(i, j).c_str())->id; x34_weapons[i][j] = factory.GetResourceIdByName(GetWeapon(i, j).c_str())->id;
for (int i=0 ; i<5 ; ++i) for (int i = 0; i < 5; ++i)
x84_muzzle[i] = factory.GetResourceIdByName(GetMuzzleParticle(i).c_str())->id; x84_muzzle[i] = factory.GetResourceIdByName(GetMuzzleParticle(i).c_str())->id;
for (int i=0 ; i<5 ; ++i) for (int i = 0; i < 5; ++i)
x94_charge[i] = factory.GetResourceIdByName(GetChargeParticle(i).c_str())->id; x94_charge[i] = factory.GetResourceIdByName(GetChargeParticle(i).c_str())->id;
for (int i=0 ; i<5 ; ++i) for (int i = 0; i < 5; ++i)
xa4_auxMuzzle[i] = factory.GetResourceIdByName(GetAuxMuzzleParticle(i).c_str())->id; xa4_auxMuzzle[i] = factory.GetResourceIdByName(GetAuxMuzzleParticle(i).c_str())->id;
xb4_grappleSegment = factory.GetResourceIdByName(GetGrappleSegmentParticle().c_str())->id; xb4_grappleSegment = factory.GetResourceIdByName(GetGrappleSegmentParticle().c_str())->id;
xb8_grappleClaw = factory.GetResourceIdByName(GetGrappleClawParticle().c_str())->id; xb8_grappleClaw = factory.GetResourceIdByName(GetGrappleClawParticle().c_str())->id;
xbc_grappleHit = factory.GetResourceIdByName(GetGrappleHitParticle().c_str())->id; xbc_grappleHit = factory.GetResourceIdByName(GetGrappleHitParticle().c_str())->id;
xc0_grappleMuzzle = factory.GetResourceIdByName(GetGrappleMuzzleParticle().c_str())->id; xc0_grappleMuzzle = factory.GetResourceIdByName(GetGrappleMuzzleParticle().c_str())->id;
xc4_grappleSwoosh = factory.GetResourceIdByName(GetGrappleSwooshParticle().c_str())->id; xc4_grappleSwoosh = factory.GetResourceIdByName(GetGrappleSwooshParticle().c_str())->id;
} }
protected: protected:
virtual const std::string& GetGunMotion() const=0; virtual const std::string& GetGunMotion() const = 0;
virtual const std::string& GetGrappleArm() const=0; virtual const std::string& GetGrappleArm() const = 0;
virtual const std::string& GetRightHand() const=0; virtual const std::string& GetRightHand() const = 0;
virtual const std::string& GetPowerBeam() const=0; virtual const std::string& GetPowerBeam() const = 0;
virtual const std::string& GetIceBeam() const=0; virtual const std::string& GetIceBeam() const = 0;
virtual const std::string& GetWaveBeam() const=0; virtual const std::string& GetWaveBeam() const = 0;
virtual const std::string& GetPlasmaBeam() const=0; virtual const std::string& GetPlasmaBeam() const = 0;
virtual const std::string& GetPhazonBeam() const=0; virtual const std::string& GetPhazonBeam() const = 0;
virtual const std::string& GetHoloTransition() const=0; virtual const std::string& GetHoloTransition() const = 0;
virtual const std::string& GetBombSet() const=0; virtual const std::string& GetBombSet() const = 0;
virtual const std::string& GetBombExplode() const=0; virtual const std::string& GetBombExplode() const = 0;
virtual const std::string& GetPowerBombExplode() const=0; virtual const std::string& GetPowerBombExplode() const = 0;
virtual const std::string& GetWeapon(size_t idx, bool ball) const=0; virtual const std::string& GetWeapon(size_t idx, bool ball) const = 0;
virtual const std::string& GetMuzzleParticle(size_t idx) const=0; virtual const std::string& GetMuzzleParticle(size_t idx) const = 0;
virtual const std::string& GetChargeParticle(size_t idx) const=0; virtual const std::string& GetChargeParticle(size_t idx) const = 0;
virtual const std::string& GetAuxMuzzleParticle(size_t idx) const=0; virtual const std::string& GetAuxMuzzleParticle(size_t idx) const = 0;
virtual const std::string& GetGrappleSegmentParticle() const=0; virtual const std::string& GetGrappleSegmentParticle() const = 0;
virtual const std::string& GetGrappleClawParticle() const=0; virtual const std::string& GetGrappleClawParticle() const = 0;
virtual const std::string& GetGrappleHitParticle() const=0; virtual const std::string& GetGrappleHitParticle() const = 0;
virtual const std::string& GetGrappleMuzzleParticle() const=0; virtual const std::string& GetGrappleMuzzleParticle() const = 0;
virtual const std::string& GetGrappleSwooshParticle() const=0; virtual const std::string& GetGrappleSwooshParticle() const = 0;
}; };
} } // namespace DataSpec

View File

@ -2,12 +2,8 @@
#include "ITweak.hpp" #include "ITweak.hpp"
namespace DataSpec namespace DataSpec {
{
struct ITweakParticle : ITweak struct ITweakParticle : ITweak {};
{
};
}
} // namespace DataSpec

View File

@ -3,145 +3,142 @@
#include "ITweak.hpp" #include "ITweak.hpp"
#include "zeus/CAABox.hpp" #include "zeus/CAABox.hpp"
namespace DataSpec namespace DataSpec {
{
struct ITweakPlayer : ITweak struct ITweakPlayer : ITweak {
{ virtual float GetMaxTranslationalAcceleration(int s) const = 0;
virtual float GetMaxTranslationalAcceleration(int s) const=0; virtual float GetMaxRotationalAcceleration(int s) const = 0;
virtual float GetMaxRotationalAcceleration(int s) const=0; virtual float GetPlayerTranslationFriction(int s) const = 0;
virtual float GetPlayerTranslationFriction(int s) const=0; virtual float GetPlayerRotationFriction(int s) const = 0;
virtual float GetPlayerRotationFriction(int s) const=0; virtual float GetPlayerRotationMaxSpeed(int s) const = 0;
virtual float GetPlayerRotationMaxSpeed(int s) const=0; virtual float GetPlayerTranslationMaxSpeed(int s) const = 0;
virtual float GetPlayerTranslationMaxSpeed(int s) const=0; virtual float GetNormalGravAccel() const = 0;
virtual float GetNormalGravAccel() const=0; virtual float GetFluidGravAccel() const = 0;
virtual float GetFluidGravAccel() const=0; virtual float GetVerticalJumpAccel() const = 0;
virtual float GetVerticalJumpAccel() const=0; virtual float GetHorizontalJumpAccel() const = 0;
virtual float GetHorizontalJumpAccel() const=0; virtual float GetVerticalDoubleJumpAccel() const = 0;
virtual float GetVerticalDoubleJumpAccel() const=0; virtual float GetHorizontalDoubleJumpAccel() const = 0;
virtual float GetHorizontalDoubleJumpAccel() const=0; virtual float GetWaterJumpFactor() const = 0;
virtual float GetWaterJumpFactor() const=0; virtual float GetWaterBallJumpFactor() const = 0;
virtual float GetWaterBallJumpFactor() const=0; virtual float GetLavaJumpFactor() const = 0;
virtual float GetLavaJumpFactor() const=0; virtual float GetLavaBallJumpFactor() const = 0;
virtual float GetLavaBallJumpFactor() const=0; virtual float GetPhazonJumpFactor() const = 0;
virtual float GetPhazonJumpFactor() const=0; virtual float GetPhazonBallJumpFactor() const = 0;
virtual float GetPhazonBallJumpFactor() const=0; virtual float GetAllowedJumpTime() const = 0;
virtual float GetAllowedJumpTime() const=0; virtual float GetAllowedDoubleJumpTime() const = 0;
virtual float GetAllowedDoubleJumpTime() const=0; virtual float GetMinDoubleJumpWindow() const = 0;
virtual float GetMinDoubleJumpWindow() const=0; virtual float GetMaxDoubleJumpWindow() const = 0;
virtual float GetMaxDoubleJumpWindow() const=0; virtual float GetMinJumpTime() const = 0;
virtual float GetMinJumpTime() const=0; virtual float GetMinDoubleJumpTime() const = 0;
virtual float GetMinDoubleJumpTime() const=0; virtual float GetAllowedLedgeTime() const = 0;
virtual float GetAllowedLedgeTime() const=0; virtual float GetDoubleJumpImpulse() const = 0;
virtual float GetDoubleJumpImpulse() const=0; virtual float GetBackwardsForceMultiplier() const = 0;
virtual float GetBackwardsForceMultiplier() const=0; virtual float GetBombJumpRadius() const = 0;
virtual float GetBombJumpRadius() const=0; virtual float GetBombJumpHeight() const = 0;
virtual float GetBombJumpHeight() const=0; virtual float GetEyeOffset() const = 0;
virtual float GetEyeOffset() const=0; virtual float GetTurnSpeedMultiplier() const = 0;
virtual float GetTurnSpeedMultiplier() const=0; virtual float GetFreeLookTurnSpeedMultiplier() const = 0;
virtual float GetFreeLookTurnSpeedMultiplier() const=0; virtual float GetFreeLookSpeed() const = 0;
virtual float GetFreeLookSpeed() const=0; virtual float GetFreeLookSnapSpeed() const = 0;
virtual float GetFreeLookSnapSpeed() const=0; virtual float GetFreeLookCenteredThresholdAngle() const = 0;
virtual float GetFreeLookCenteredThresholdAngle() const=0; virtual float GetFreeLookCenteredTime() const = 0;
virtual float GetFreeLookCenteredTime() const=0; virtual float GetOrbitModeTimer() const = 0;
virtual float GetOrbitModeTimer() const=0; virtual float GetOrbitUpperAngle() const = 0;
virtual float GetOrbitUpperAngle() const=0; virtual float GetOrbitLowerAngle() const = 0;
virtual float GetOrbitLowerAngle() const=0; virtual float GetOrbitHorizAngle() const = 0;
virtual float GetOrbitHorizAngle() const=0; virtual float GetOrbitMaxTargetDistance() const = 0;
virtual float GetOrbitMaxTargetDistance() const=0; virtual float GetOrbitMaxLockDistance() const = 0;
virtual float GetOrbitMaxLockDistance() const=0; virtual float GetOrbitDistanceThreshold() const = 0;
virtual float GetOrbitDistanceThreshold() const=0; virtual uint32_t GetOrbitScreenBoxHalfExtentX(int zone) const = 0;
virtual uint32_t GetOrbitScreenBoxHalfExtentX(int zone) const=0; virtual uint32_t GetOrbitScreenBoxHalfExtentY(int zone) const = 0;
virtual uint32_t GetOrbitScreenBoxHalfExtentY(int zone) const=0; virtual uint32_t GetOrbitScreenBoxCenterX(int zone) const = 0;
virtual uint32_t GetOrbitScreenBoxCenterX(int zone) const=0; virtual uint32_t GetOrbitScreenBoxCenterY(int zone) const = 0;
virtual uint32_t GetOrbitScreenBoxCenterY(int zone) const=0; virtual uint32_t GetOrbitZoneIdealX(int zone) const = 0;
virtual uint32_t GetOrbitZoneIdealX(int zone) const=0; virtual uint32_t GetOrbitZoneIdealY(int zone) const = 0;
virtual uint32_t GetOrbitZoneIdealY(int zone) const=0; virtual float GetOrbitNearX() const = 0;
virtual float GetOrbitNearX() const=0; virtual float GetOrbitNearZ() const = 0;
virtual float GetOrbitNearZ() const=0; virtual float GetOrbitFixedOffsetZDiff() const = 0;
virtual float GetOrbitFixedOffsetZDiff() const=0; virtual float GetOrbitZRange() const = 0;
virtual float GetOrbitZRange() const=0; virtual bool GetDashEnabled() const = 0;
virtual bool GetDashEnabled() const=0; virtual bool GetDashOnButtonRelease() const = 0;
virtual bool GetDashOnButtonRelease() const=0; virtual float GetDashButtonHoldCancelTime() const = 0;
virtual float GetDashButtonHoldCancelTime() const=0; virtual float GetDashStrafeInputThreshold() const = 0;
virtual float GetDashStrafeInputThreshold() const=0; virtual float GetSidewaysDoubleJumpImpulse() const = 0;
virtual float GetSidewaysDoubleJumpImpulse() const=0; virtual float GetSidewaysVerticalDoubleJumpAccel() const = 0;
virtual float GetSidewaysVerticalDoubleJumpAccel() const=0; virtual float GetSidewaysHorizontalDoubleJumpAccel() const = 0;
virtual float GetSidewaysHorizontalDoubleJumpAccel() const=0; virtual float GetScanningRange() const = 0; // x218
virtual float GetScanningRange() const=0; // x218 virtual bool GetScanRetention() const = 0;
virtual bool GetScanRetention() const=0; virtual bool GetScanFreezesGame() const = 0; // x21c_25
virtual bool GetScanFreezesGame() const=0; // x21c_25 virtual bool GetOrbitWhileScanning() const = 0;
virtual bool GetOrbitWhileScanning() const=0; virtual bool GetFallingDoubleJump() const = 0;
virtual bool GetFallingDoubleJump() const=0; virtual bool GetImpulseDoubleJump() const = 0;
virtual bool GetImpulseDoubleJump() const=0; virtual bool GetFiringCancelsCameraPitch() const = 0;
virtual bool GetFiringCancelsCameraPitch() const=0; virtual bool GetAssistedAimingIgnoreHorizontal() const = 0;
virtual bool GetAssistedAimingIgnoreHorizontal() const=0; virtual bool GetAssistedAimingIgnoreVertical() const = 0;
virtual bool GetAssistedAimingIgnoreVertical() const=0; virtual float GetAimMaxDistance() const = 0;
virtual float GetAimMaxDistance() const=0; virtual float GetAimThresholdDistance() const = 0;
virtual float GetAimThresholdDistance() const=0; virtual float GetAimBoxWidth() const = 0;
virtual float GetAimBoxWidth() const=0; virtual float GetAimBoxHeight() const = 0;
virtual float GetAimBoxHeight() const=0; virtual float GetAimTargetTimer() const = 0;
virtual float GetAimTargetTimer() const=0; virtual float GetAimAssistHorizontalAngle() const = 0;
virtual float GetAimAssistHorizontalAngle() const=0; virtual float GetAimAssistVerticalAngle() const = 0;
virtual float GetAimAssistVerticalAngle() const=0; virtual float GetScanMaxTargetDistance() const = 0;
virtual float GetScanMaxTargetDistance() const=0; virtual float GetScanMaxLockDistance() const = 0;
virtual float GetScanMaxLockDistance() const=0; virtual bool GetMoveDuringFreeLook() const = 0;
virtual bool GetMoveDuringFreeLook() const=0; virtual bool GetHoldButtonsForFreeLook() const = 0;
virtual bool GetHoldButtonsForFreeLook() const=0; virtual bool GetTwoButtonsForFreeLook() const = 0;
virtual bool GetTwoButtonsForFreeLook() const=0; virtual bool GetAimWhenOrbitingPoint() const = 0;
virtual bool GetAimWhenOrbitingPoint() const=0; virtual bool GetStayInFreeLookWhileFiring() const = 0;
virtual bool GetStayInFreeLookWhileFiring() const=0; virtual bool GetOrbitFixedOffset() const = 0;
virtual bool GetOrbitFixedOffset() const=0; virtual bool GetGunButtonTogglesHolster() const = 0;
virtual bool GetGunButtonTogglesHolster() const=0; virtual bool GetGunNotFiringHolstersGun() const = 0;
virtual bool GetGunNotFiringHolstersGun() const=0; virtual float GetPlayerHeight() const = 0; // x26c
virtual float GetPlayerHeight() const=0; // x26c virtual float GetPlayerXYHalfExtent() const = 0; // x270
virtual float GetPlayerXYHalfExtent() const=0; // x270 virtual bool GetFreeLookTurnsPlayer() const = 0; // x228_24
virtual bool GetFreeLookTurnsPlayer() const=0; // x228_24 virtual float GetStepUpHeight() const = 0; // x274
virtual float GetStepUpHeight() const=0; // x274 virtual float GetStepDownHeight() const = 0; // x278
virtual float GetStepDownHeight() const=0; // x278 virtual float GetPlayerBallHalfExtent() const = 0; // x27c
virtual float GetPlayerBallHalfExtent() const=0; // x27c virtual float GetOrbitDistanceMax() const = 0;
virtual float GetOrbitDistanceMax() const=0; virtual float GetGrappleSwingLength() const = 0;
virtual float GetGrappleSwingLength() const=0; virtual float GetGrappleSwingPeriod() const = 0;
virtual float GetGrappleSwingPeriod() const=0; virtual float GetGrapplePullSpeedMin() const = 0;
virtual float GetGrapplePullSpeedMin() const=0; virtual float GetMaxGrappleLockedTurnAlignDistance() const = 0;
virtual float GetMaxGrappleLockedTurnAlignDistance() const=0; virtual float GetGrapplePullSpeedProportion() const = 0;
virtual float GetGrapplePullSpeedProportion() const=0; virtual float GetGrapplePullSpeedMax() const = 0;
virtual float GetGrapplePullSpeedMax() const=0; virtual float GetGrappleLookCenterSpeed() const = 0;
virtual float GetGrappleLookCenterSpeed() const=0; virtual float GetMaxGrappleTurnSpeed() const = 0;
virtual float GetMaxGrappleTurnSpeed() const=0; virtual float GetGrappleJumpForce() const = 0;
virtual float GetGrappleJumpForce() const=0; virtual float GetGrappleReleaseTime() const = 0;
virtual float GetGrappleReleaseTime() const=0; virtual uint32_t GetGrappleJumpMode() const = 0;
virtual uint32_t GetGrappleJumpMode() const=0; virtual bool GetOrbitReleaseBreaksGrapple() const = 0;
virtual bool GetOrbitReleaseBreaksGrapple() const=0; virtual bool GetInvertGrappleTurn() const = 0;
virtual bool GetInvertGrappleTurn() const=0; virtual float GetGrappleBeamSpeed() const = 0;
virtual float GetGrappleBeamSpeed() const=0; virtual float GetGrappleBeamXWaveAmplitude() const = 0;
virtual float GetGrappleBeamXWaveAmplitude() const=0; virtual float GetGrappleBeamZWaveAmplitude() const = 0;
virtual float GetGrappleBeamZWaveAmplitude() const=0; virtual float GetGrappleBeamAnglePhaseDelta() const = 0;
virtual float GetGrappleBeamAnglePhaseDelta() const=0; virtual float GetHorizontalFreeLookAngleVel() const = 0;
virtual float GetHorizontalFreeLookAngleVel() const=0; virtual float GetVerticalFreeLookAngleVel() const = 0; // x134
virtual float GetVerticalFreeLookAngleVel() const=0; // x134 virtual float GetOrbitCameraSpeed() const = 0; // x184
virtual float GetOrbitCameraSpeed() const=0; // x184 virtual float GetOrbitPreventionTime() const = 0;
virtual float GetOrbitPreventionTime() const=0; virtual float GetJumpCameraPitchDownStart() const = 0; // x288
virtual float GetJumpCameraPitchDownStart() const=0; // x288 virtual float GetJumpCameraPitchDownFull() const = 0; // x28c
virtual float GetJumpCameraPitchDownFull() const=0; // x28c virtual float GetJumpCameraPitchDownAngle() const = 0; // x290
virtual float GetJumpCameraPitchDownAngle() const=0; // x290 virtual float GetFallCameraPitchDownStart() const = 0; // x294
virtual float GetFallCameraPitchDownStart() const=0; // x294 virtual float GetFallCameraPitchDownFull() const = 0; // x298
virtual float GetFallCameraPitchDownFull() const=0; // x298 virtual float GetFallCameraPitchDownAngle() const = 0; // x29c
virtual float GetFallCameraPitchDownAngle() const=0; // x29c virtual float GetFirstPersonCameraSpeed() const = 0; // x280
virtual float GetFirstPersonCameraSpeed() const=0; // x280 virtual float GetGrappleCameraSpeed() const = 0; // x2b0
virtual float GetGrappleCameraSpeed() const=0; // x2b0 virtual float GetFreeLookDampenFactor() const = 0; // x14c
virtual float GetFreeLookDampenFactor() const=0; // x14c virtual float GetLeftLogicalThreshold() const = 0;
virtual float GetLeftLogicalThreshold() const=0; virtual float GetRightLogicalThreshold() const = 0;
virtual float GetRightLogicalThreshold() const=0; virtual float GetOrbitMinDistance(int type) const = 0;
virtual float GetOrbitMinDistance(int type) const=0; virtual float GetOrbitNormalDistance(int type) const = 0;
virtual float GetOrbitNormalDistance(int type) const=0; virtual float GetOrbitMaxDistance(int type) const = 0;
virtual float GetOrbitMaxDistance(int type) const=0; virtual float GetFrozenTimeout() const = 0;
virtual float GetFrozenTimeout() const=0; virtual uint32_t GetIceBreakJumpCount() const = 0;
virtual uint32_t GetIceBreakJumpCount() const=0; virtual float GetVariaDamageReduction() const = 0;
virtual float GetVariaDamageReduction() const=0; virtual float GetGravityDamageReduction() const = 0;
virtual float GetGravityDamageReduction() const=0; virtual float GetPhazonDamageReduction() const = 0;
virtual float GetPhazonDamageReduction() const=0;
}; };
} } // namespace DataSpec

View File

@ -2,13 +2,10 @@
#include "ITweak.hpp" #include "ITweak.hpp"
namespace DataSpec namespace DataSpec {
{
struct ITweakPlayerControl : ITweak struct ITweakPlayerControl : ITweak {
{ virtual atUint32 GetMapping(atUint32) const = 0;
virtual atUint32 GetMapping(atUint32) const=0;
}; };
} } // namespace DataSpec

View File

@ -3,72 +3,70 @@
#include "ITweak.hpp" #include "ITweak.hpp"
#include "zeus/CAABox.hpp" #include "zeus/CAABox.hpp"
namespace DataSpec namespace DataSpec {
{
/* Same as CDamageInfo */ /* Same as CDamageInfo */
struct SShotParam : BigDNA struct SShotParam : BigDNA {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML Value<atInt32> weaponType = -1;
Value<atInt32> weaponType = -1; bool charged : 1;
bool charged : 1; bool combo : 1;
bool combo : 1; bool instaKill : 1;
bool instaKill : 1; Value<float> damage = 0.f;
Value<float> damage = 0.f; Value<float> radiusDamage = 0.f;
Value<float> radiusDamage = 0.f; Value<float> radius = 0.f;
Value<float> radius = 0.f; Value<float> knockback = 0.f;
Value<float> knockback = 0.f; bool noImmunity : 1;
bool noImmunity : 1; SShotParam() {
SShotParam() { charged = false; combo = false; instaKill = false; noImmunity = false; } charged = false;
combo = false;
instaKill = false;
noImmunity = false;
}
}; };
struct SComboShotParam : SShotParam struct SComboShotParam : SShotParam {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML SComboShotParam() { combo = true; }
SComboShotParam() { combo = true; }
}; };
struct SChargedShotParam : SShotParam struct SChargedShotParam : SShotParam {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML SChargedShotParam() { charged = true; }
SChargedShotParam() { charged = true; }
}; };
struct SWeaponInfo : BigDNA struct SWeaponInfo : BigDNA {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML Value<float> x0_coolDown = 0.1f;
Value<float> x0_coolDown = 0.1f; SShotParam x4_normal;
SShotParam x4_normal; SChargedShotParam x20_charged;
SChargedShotParam x20_charged;
}; };
struct ITweakPlayerGun : ITweak struct ITweakPlayerGun : ITweak {
{ AT_DECL_DNA_YAML
AT_DECL_DNA_YAML virtual float GetUpLookAngle() const = 0;
virtual float GetUpLookAngle() const = 0; virtual float GetDownLookAngle() const = 0;
virtual float GetDownLookAngle() const = 0; virtual float GetVerticalSpread() const = 0;
virtual float GetVerticalSpread() const = 0; virtual float GetHorizontalSpread() const = 0;
virtual float GetHorizontalSpread() const = 0; virtual float GetHighVerticalSpread() const = 0;
virtual float GetHighVerticalSpread() const = 0; virtual float GetHighHorizontalSpread() const = 0;
virtual float GetHighHorizontalSpread() const = 0; virtual float GetLowVerticalSpread() const = 0;
virtual float GetLowVerticalSpread() const = 0; virtual float GetLowHorizontalSpread() const = 0;
virtual float GetLowHorizontalSpread() const = 0; virtual float GetAimVerticalSpeed() const = 0; // x24
virtual float GetAimVerticalSpeed() const = 0; // x24 virtual float GetAimHorizontalSpeed() const = 0; // x28
virtual float GetAimHorizontalSpeed() const = 0; // x28 virtual float GetBombFuseTime() const = 0; // x2c
virtual float GetBombFuseTime() const = 0; // x2c virtual float GetBombDropDelayTime() const = 0; // x30
virtual float GetBombDropDelayTime() const = 0; // x30 virtual float GetHoloHoldTime() const = 0; // x34
virtual float GetHoloHoldTime() const = 0; // x34 virtual float GetGunTransformTime() const = 0; // x38
virtual float GetGunTransformTime() const = 0; // x38 virtual float GetGunHolsterTime() const = 0;
virtual float GetGunHolsterTime() const = 0; virtual float GetGunNotFiringTime() const = 0;
virtual float GetGunNotFiringTime() const = 0; virtual float GetFixedVerticalAim() const = 0;
virtual float GetFixedVerticalAim() const = 0; virtual float GetGunExtendDistance() const = 0;
virtual float GetGunExtendDistance() const = 0; virtual const zeus::CVector3f& GetGunPosition() const = 0;
virtual const zeus::CVector3f& GetGunPosition() const = 0; virtual const zeus::CVector3f& GetGrapplingArmPosition() const = 0;
virtual const zeus::CVector3f& GetGrapplingArmPosition() const = 0; virtual float GetRichochetDamage(atUint32) const = 0;
virtual float GetRichochetDamage(atUint32) const = 0; virtual const SWeaponInfo& GetBeamInfo(atInt32 beam) const = 0;
virtual const SWeaponInfo& GetBeamInfo(atInt32 beam) const = 0; virtual const SComboShotParam& GetComboShotInfo(atInt32 beam) const = 0;
virtual const SComboShotParam& GetComboShotInfo(atInt32 beam) const = 0; virtual const SShotParam& GetBombInfo() const = 0;
virtual const SShotParam& GetBombInfo() const=0; virtual const SShotParam& GetPowerBombInfo() const = 0;
virtual const SShotParam& GetPowerBombInfo() const=0;
}; };
} } // namespace DataSpec

View File

@ -4,163 +4,155 @@
#include "Runtime/IFactory.hpp" #include "Runtime/IFactory.hpp"
#include "Runtime/CPlayerState.hpp" #include "Runtime/CPlayerState.hpp"
namespace DataSpec namespace DataSpec {
{
struct ITweakPlayerRes : ITweak struct ITweakPlayerRes : ITweak {
{ using ResId = urde::CAssetId;
using ResId = urde::CAssetId; using EBeamId = urde::CPlayerState::EBeamId;
using EBeamId = urde::CPlayerState::EBeamId;
ResId x4_saveStationIcon; ResId x4_saveStationIcon;
ResId x8_missileStationIcon; ResId x8_missileStationIcon;
ResId xc_elevatorIcon; ResId xc_elevatorIcon;
ResId x10_minesBreakFirstTopIcon; ResId x10_minesBreakFirstTopIcon;
ResId x14_minesBreakFirstBottomIcon; ResId x14_minesBreakFirstBottomIcon;
ResId x18_minesBreakSecondTopIcon; ResId x18_minesBreakSecondTopIcon;
ResId x1c_minesBreakSecondBottomIcon; ResId x1c_minesBreakSecondBottomIcon;
/* N, U, UL, L, DL, D, DR, R, UR */ /* N, U, UL, L, DL, D, DR, R, UR */
ResId x24_lStick[9]; ResId x24_lStick[9];
ResId x4c_cStick[9]; ResId x4c_cStick[9];
/* Out, In */ /* Out, In */
ResId x74_lTrigger[2]; ResId x74_lTrigger[2];
ResId x80_rTrigger[2]; ResId x80_rTrigger[2];
ResId x8c_startButton[2]; ResId x8c_startButton[2];
ResId x98_aButton[2]; ResId x98_aButton[2];
ResId xa4_bButton[2]; ResId xa4_bButton[2];
ResId xb0_xButton[2]; ResId xb0_xButton[2];
ResId xbc_yButton[2]; ResId xbc_yButton[2];
ResId xc4_ballTransitionsANCS; ResId xc4_ballTransitionsANCS;
/* Power, Ice, Wave, Plasma, Phazon */ /* Power, Ice, Wave, Plasma, Phazon */
ResId xc8_ballTransitions[5]; ResId xc8_ballTransitions[5];
ResId xc8_cineGun[5]; ResId xc8_cineGun[5];
float xf0_cinematicMoveOutofIntoPlayerDistance; float xf0_cinematicMoveOutofIntoPlayerDistance;
ResId GetBeamBallTransitionModel(EBeamId beam) const ResId GetBeamBallTransitionModel(EBeamId beam) const {
{ int b = int(beam);
int b = int(beam); if (b < 0 || b > 4)
if (b < 0 || b > 4) b = 0;
b = 0; switch (EBeamId(b)) {
switch (EBeamId(b)) case EBeamId::Power:
{ default:
case EBeamId::Power: return xc8_ballTransitions[0];
default: case EBeamId::Ice:
return xc8_ballTransitions[0]; return xc8_ballTransitions[1];
case EBeamId::Ice: case EBeamId::Wave:
return xc8_ballTransitions[1]; return xc8_ballTransitions[2];
case EBeamId::Wave: case EBeamId::Plasma:
return xc8_ballTransitions[2]; return xc8_ballTransitions[3];
case EBeamId::Plasma: case EBeamId::Phazon:
return xc8_ballTransitions[3]; return xc8_ballTransitions[4];
case EBeamId::Phazon:
return xc8_ballTransitions[4];
}
} }
}
ResId GetBeamCineModel(EBeamId beam) const ResId GetBeamCineModel(EBeamId beam) const {
{ int b = int(beam);
int b = int(beam); if (b < 0 || b > 4)
if (b < 0 || b > 4) b = 0;
b = 0; switch (EBeamId(b)) {
switch (EBeamId(b)) case EBeamId::Power:
{ default:
case EBeamId::Power: return xc8_cineGun[0];
default: case EBeamId::Ice:
return xc8_cineGun[0]; return xc8_cineGun[1];
case EBeamId::Ice: case EBeamId::Wave:
return xc8_cineGun[1]; return xc8_cineGun[2];
case EBeamId::Wave: case EBeamId::Plasma:
return xc8_cineGun[2]; return xc8_cineGun[3];
case EBeamId::Plasma: case EBeamId::Phazon:
return xc8_cineGun[3]; return xc8_cineGun[4];
case EBeamId::Phazon:
return xc8_cineGun[4];
}
} }
}
void ResolveResources(const urde::IFactory& factory) void ResolveResources(const urde::IFactory& factory) {
{ x4_saveStationIcon = factory.GetResourceIdByName(_GetSaveStationIcon().data())->id;
x4_saveStationIcon = factory.GetResourceIdByName(_GetSaveStationIcon().data())->id; x8_missileStationIcon = factory.GetResourceIdByName(_GetMissileStationIcon().data())->id;
x8_missileStationIcon = factory.GetResourceIdByName(_GetMissileStationIcon().data())->id; xc_elevatorIcon = factory.GetResourceIdByName(_GetElevatorIcon().data())->id;
xc_elevatorIcon = factory.GetResourceIdByName(_GetElevatorIcon().data())->id;
x10_minesBreakFirstTopIcon = factory.GetResourceIdByName(_GetMinesBreakFirstTopIcon().data())->id; x10_minesBreakFirstTopIcon = factory.GetResourceIdByName(_GetMinesBreakFirstTopIcon().data())->id;
x14_minesBreakFirstBottomIcon = factory.GetResourceIdByName(_GetMinesBreakFirstTopIcon().data())->id; x14_minesBreakFirstBottomIcon = factory.GetResourceIdByName(_GetMinesBreakFirstTopIcon().data())->id;
x18_minesBreakSecondTopIcon = factory.GetResourceIdByName(_GetMinesBreakFirstTopIcon().data())->id; x18_minesBreakSecondTopIcon = factory.GetResourceIdByName(_GetMinesBreakFirstTopIcon().data())->id;
x1c_minesBreakSecondBottomIcon = factory.GetResourceIdByName(_GetMinesBreakFirstTopIcon().data())->id; x1c_minesBreakSecondBottomIcon = factory.GetResourceIdByName(_GetMinesBreakFirstTopIcon().data())->id;
for (int i=0 ; i<9 ; ++i) for (int i = 0; i < 9; ++i)
x24_lStick[i] = factory.GetResourceIdByName(_GetLStick(i).data())->id; x24_lStick[i] = factory.GetResourceIdByName(_GetLStick(i).data())->id;
for (int i=0 ; i<9 ; ++i) for (int i = 0; i < 9; ++i)
x4c_cStick[i] = factory.GetResourceIdByName(_GetCStick(i).data())->id; x4c_cStick[i] = factory.GetResourceIdByName(_GetCStick(i).data())->id;
for (int i=0 ; i<2 ; ++i) for (int i = 0; i < 2; ++i)
x74_lTrigger[i] = factory.GetResourceIdByName(_GetLTrigger(i).data())->id; x74_lTrigger[i] = factory.GetResourceIdByName(_GetLTrigger(i).data())->id;
for (int i=0 ; i<2 ; ++i) for (int i = 0; i < 2; ++i)
x80_rTrigger[i] = factory.GetResourceIdByName(_GetRTrigger(i).data())->id; x80_rTrigger[i] = factory.GetResourceIdByName(_GetRTrigger(i).data())->id;
for (int i=0 ; i<2 ; ++i) for (int i = 0; i < 2; ++i)
x8c_startButton[i] = factory.GetResourceIdByName(_GetStartButton(i).data())->id; x8c_startButton[i] = factory.GetResourceIdByName(_GetStartButton(i).data())->id;
for (int i=0 ; i<2 ; ++i) for (int i = 0; i < 2; ++i)
x98_aButton[i] = factory.GetResourceIdByName(_GetAButton(i).data())->id; x98_aButton[i] = factory.GetResourceIdByName(_GetAButton(i).data())->id;
for (int i=0 ; i<2 ; ++i) for (int i = 0; i < 2; ++i)
xa4_bButton[i] = factory.GetResourceIdByName(_GetBButton(i).data())->id; xa4_bButton[i] = factory.GetResourceIdByName(_GetBButton(i).data())->id;
for (int i=0 ; i<2 ; ++i) for (int i = 0; i < 2; ++i)
xb0_xButton[i] = factory.GetResourceIdByName(_GetXButton(i).data())->id; xb0_xButton[i] = factory.GetResourceIdByName(_GetXButton(i).data())->id;
for (int i=0 ; i<2 ; ++i) for (int i = 0; i < 2; ++i)
xbc_yButton[i] = factory.GetResourceIdByName(_GetYButton(i).data())->id; xbc_yButton[i] = factory.GetResourceIdByName(_GetYButton(i).data())->id;
xc4_ballTransitionsANCS = factory.GetResourceIdByName(_GetBallTransitionsANCS().data())->id; xc4_ballTransitionsANCS = factory.GetResourceIdByName(_GetBallTransitionsANCS().data())->id;
for (int i=0 ; i<5 ; ++i) for (int i = 0; i < 5; ++i)
xc8_ballTransitions[i] = factory.GetResourceIdByName(_GetBallTransitionBeamRes(i).data())->id; xc8_ballTransitions[i] = factory.GetResourceIdByName(_GetBallTransitionBeamRes(i).data())->id;
for (int i=0 ; i<5 ; ++i) for (int i = 0; i < 5; ++i)
xc8_cineGun[i] = factory.GetResourceIdByName(_GetBeamCineModel(i).data())->id; xc8_cineGun[i] = factory.GetResourceIdByName(_GetBeamCineModel(i).data())->id;
xf0_cinematicMoveOutofIntoPlayerDistance = _GetCinematicMoveOutofIntoPlayerDistance(); xf0_cinematicMoveOutofIntoPlayerDistance = _GetCinematicMoveOutofIntoPlayerDistance();
} }
protected: protected:
virtual std::string_view _GetSaveStationIcon() const=0; virtual std::string_view _GetSaveStationIcon() const = 0;
virtual std::string_view _GetMissileStationIcon() const=0; virtual std::string_view _GetMissileStationIcon() const = 0;
virtual std::string_view _GetElevatorIcon() const=0; virtual std::string_view _GetElevatorIcon() const = 0;
virtual std::string_view _GetMinesBreakFirstTopIcon() const=0; virtual std::string_view _GetMinesBreakFirstTopIcon() const = 0;
virtual std::string_view _GetMinesBreakFirstBottomIcon() const=0; virtual std::string_view _GetMinesBreakFirstBottomIcon() const = 0;
virtual std::string_view _GetMinesBreakSecondTopIcon() const=0; virtual std::string_view _GetMinesBreakSecondTopIcon() const = 0;
virtual std::string_view _GetMinesBreakSecondBottomIcon() const=0; virtual std::string_view _GetMinesBreakSecondBottomIcon() const = 0;
virtual std::string_view _GetLStick(size_t idx) const=0; virtual std::string_view _GetLStick(size_t idx) const = 0;
virtual std::string_view _GetCStick(size_t idx) const=0; virtual std::string_view _GetCStick(size_t idx) const = 0;
virtual std::string_view _GetLTrigger(size_t idx) const=0; virtual std::string_view _GetLTrigger(size_t idx) const = 0;
virtual std::string_view _GetRTrigger(size_t idx) const=0; virtual std::string_view _GetRTrigger(size_t idx) const = 0;
virtual std::string_view _GetStartButton(size_t idx) const=0; virtual std::string_view _GetStartButton(size_t idx) const = 0;
virtual std::string_view _GetAButton(size_t idx) const=0; virtual std::string_view _GetAButton(size_t idx) const = 0;
virtual std::string_view _GetBButton(size_t idx) const=0; virtual std::string_view _GetBButton(size_t idx) const = 0;
virtual std::string_view _GetXButton(size_t idx) const=0; virtual std::string_view _GetXButton(size_t idx) const = 0;
virtual std::string_view _GetYButton(size_t idx) const=0; virtual std::string_view _GetYButton(size_t idx) const = 0;
virtual std::string_view _GetBallTransitionsANCS() const=0; virtual std::string_view _GetBallTransitionsANCS() const = 0;
virtual std::string_view _GetBallTransitionBeamRes(size_t idx) const=0; virtual std::string_view _GetBallTransitionBeamRes(size_t idx) const = 0;
virtual std::string_view _GetBeamCineModel(size_t idx) const=0; virtual std::string_view _GetBeamCineModel(size_t idx) const = 0;
virtual float _GetCinematicMoveOutofIntoPlayerDistance() const=0; virtual float _GetCinematicMoveOutofIntoPlayerDistance() const = 0;
}; };
} } // namespace DataSpec

View File

@ -2,17 +2,14 @@
#include "ITweak.hpp" #include "ITweak.hpp"
namespace DataSpec namespace DataSpec {
{
struct ITweakSlideShow : ITweak struct ITweakSlideShow : ITweak {
{ virtual std::string_view GetFont() const = 0;
virtual std::string_view GetFont() const=0; virtual const zeus::CColor& GetFontColor() const = 0;
virtual const zeus::CColor& GetFontColor() const=0; virtual const zeus::CColor& GetOutlineColor() const = 0;
virtual const zeus::CColor& GetOutlineColor() const=0; virtual float GetScanPercentInterval() const = 0;
virtual float GetScanPercentInterval() const=0; virtual float GetX54() const = 0;
virtual float GetX54() const=0;
}; };
} } // namespace DataSpec

View File

@ -1,98 +1,95 @@
#pragma once #pragma once
#include "ITweak.hpp" #include "ITweak.hpp"
namespace DataSpec namespace DataSpec {
{ struct ITweakTargeting : public ITweak {
struct ITweakTargeting : public ITweak virtual atUint32 GetTargetRadiusMode() const = 0;
{ virtual float GetCurrLockOnExitDuration() const = 0;
virtual atUint32 GetTargetRadiusMode() const=0; virtual float GetCurrLockOnEnterDuration() const = 0;
virtual float GetCurrLockOnExitDuration() const=0; virtual float GetCurrLockOnSwitchDuration() const = 0;
virtual float GetCurrLockOnEnterDuration() const=0; virtual float GetLockConfirmScale() const = 0;
virtual float GetCurrLockOnSwitchDuration() const=0; virtual float GetNextLockOnEnterDuration() const = 0;
virtual float GetLockConfirmScale() const=0; virtual float GetNextLockOnExitDuration() const = 0;
virtual float GetNextLockOnEnterDuration() const=0; virtual float GetNextLockOnSwitchDuration() const = 0;
virtual float GetNextLockOnExitDuration() const=0; virtual float GetSeekerScale() const = 0;
virtual float GetNextLockOnSwitchDuration() const=0; virtual float GetSeekerAngleSpeed() const = 0;
virtual float GetSeekerScale() const=0; virtual float GetXRayRetAngleSpeed() const = 0;
virtual float GetSeekerAngleSpeed() const=0; virtual float GetOrbitPointZOffset() const = 0;
virtual float GetXRayRetAngleSpeed() const=0; virtual float GetOrbitPointInTime() const = 0;
virtual float GetOrbitPointZOffset() const=0; virtual float GetOrbitPointOutTime() const = 0;
virtual float GetOrbitPointInTime() const=0; virtual const zeus::CColor& GetThermalReticuleColor() const = 0;
virtual float GetOrbitPointOutTime() const=0; virtual float GetTargetFlowerScale() const = 0;
virtual const zeus::CColor& GetThermalReticuleColor() const=0; virtual const zeus::CColor& GetTargetFlowerColor() const = 0;
virtual float GetTargetFlowerScale() const=0; virtual float GetMissileBracketDuration() const = 0;
virtual const zeus::CColor& GetTargetFlowerColor() const=0; virtual float GetMissileBracketScaleStart() const = 0;
virtual float GetMissileBracketDuration() const=0; virtual float GetMissileBracketScaleEnd() const = 0;
virtual float GetMissileBracketScaleStart() const=0; virtual float GetMissileBracketScaleDuration() const = 0;
virtual float GetMissileBracketScaleEnd() const=0; virtual const zeus::CColor& GetMissileBracketColor() const = 0;
virtual float GetMissileBracketScaleDuration() const=0; virtual float GetChargeGaugeOvershootOffset() const = 0;
virtual const zeus::CColor& GetMissileBracketColor() const=0; virtual float GetChargeGaugeOvershootDuration() const = 0;
virtual float GetChargeGaugeOvershootOffset() const=0; virtual float GetOuterBeamSquaresScale() const = 0;
virtual float GetChargeGaugeOvershootDuration() const=0; virtual const zeus::CColor& GetOuterBeamSquareColor() const = 0;
virtual float GetOuterBeamSquaresScale() const=0; virtual float GetLockonDuration() const = 0;
virtual const zeus::CColor& GetOuterBeamSquareColor() const=0; virtual float GetInnerBeamScale() const = 0;
virtual float GetLockonDuration() const=0; virtual const zeus::CColor& GetInnerBeamColorPower() const = 0;
virtual float GetInnerBeamScale() const=0; virtual const zeus::CColor& GetInnerBeamColorIce() const = 0;
virtual const zeus::CColor& GetInnerBeamColorPower() const=0; virtual const zeus::CColor& GetInnerBeamColorWave() const = 0;
virtual const zeus::CColor& GetInnerBeamColorIce() const=0; virtual const zeus::CColor& GetInnerBeamColorPlasma() const = 0;
virtual const zeus::CColor& GetInnerBeamColorWave() const=0; virtual const float* GetOuterBeamSquareAngles(int i) const = 0;
virtual const zeus::CColor& GetInnerBeamColorPlasma() const=0; virtual float GetChargeGaugeAngle(int i) const = 0;
virtual const float* GetOuterBeamSquareAngles(int i) const=0; virtual float GetChargeGaugeScale() const = 0;
virtual float GetChargeGaugeAngle(int i) const=0; virtual const zeus::CColor& GetChargeGaugeNonFullColor() const = 0;
virtual float GetChargeGaugeScale() const=0; virtual atUint32 GetChargeTickCount() const = 0;
virtual const zeus::CColor& GetChargeGaugeNonFullColor() const=0; virtual float GetChargeTickAnglePitch() const = 0;
virtual atUint32 GetChargeTickCount() const=0; virtual float GetLockFireScale() const = 0;
virtual float GetChargeTickAnglePitch() const=0; virtual float GetLockFireDuration() const = 0;
virtual float GetLockFireScale() const=0; virtual const zeus::CColor& GetLockFireColor() const = 0;
virtual float GetLockFireDuration() const=0; virtual float GetLockDaggerScaleStart() const = 0;
virtual const zeus::CColor& GetLockFireColor() const=0; virtual float GetLockDaggerScaleEnd() const = 0;
virtual float GetLockDaggerScaleStart() const=0; virtual const zeus::CColor& GetLockDaggerColor() const = 0;
virtual float GetLockDaggerScaleEnd() const=0; virtual float GetLockDaggerAngle0() const = 0;
virtual const zeus::CColor& GetLockDaggerColor() const=0; virtual float GetLockDaggerAngle1() const = 0;
virtual float GetLockDaggerAngle0() const=0; virtual float GetLockDaggerAngle2() const = 0;
virtual float GetLockDaggerAngle1() const=0; virtual const zeus::CColor& GetLockConfirmColor() const = 0;
virtual float GetLockDaggerAngle2() const=0; virtual const zeus::CColor& GetSeekerColor() const = 0;
virtual const zeus::CColor& GetLockConfirmColor() const=0; virtual float GetLockConfirmClampMin() const = 0;
virtual const zeus::CColor& GetSeekerColor() const=0; virtual float GetLockConfirmClampMax() const = 0;
virtual float GetLockConfirmClampMin() const=0; virtual float GetTargetFlowerClampMin() const = 0;
virtual float GetLockConfirmClampMax() const=0; virtual float GetTargetFlowerClampMax() const = 0;
virtual float GetTargetFlowerClampMin() const=0; virtual float GetSeekerClampMin() const = 0;
virtual float GetTargetFlowerClampMax() const=0; virtual float GetSeekerClampMax() const = 0;
virtual float GetSeekerClampMin() const=0; virtual float GetMissileBracketClampMin() const = 0;
virtual float GetSeekerClampMax() const=0; virtual float GetMissileBracketClampMax() const = 0;
virtual float GetMissileBracketClampMin() const=0; virtual float GetInnerBeamClampMin() const = 0;
virtual float GetMissileBracketClampMax() const=0; virtual float GetInnerBeamClampMax() const = 0;
virtual float GetInnerBeamClampMin() const=0; virtual float GetChargeGaugeClampMin() const = 0;
virtual float GetInnerBeamClampMax() const=0; virtual float GetChargeGaugeClampMax() const = 0;
virtual float GetChargeGaugeClampMin() const=0; virtual float GetLockFireClampMin() const = 0;
virtual float GetChargeGaugeClampMax() const=0; virtual float GetLockFireClampMax() const = 0;
virtual float GetLockFireClampMin() const=0; virtual float GetLockDaggerClampMin() const = 0;
virtual float GetLockFireClampMax() const=0; virtual float GetLockDaggerClampMax() const = 0;
virtual float GetLockDaggerClampMin() const=0; virtual float GetGrappleSelectScale() const = 0;
virtual float GetLockDaggerClampMax() const=0; virtual float GetGrappleScale() const = 0;
virtual float GetGrappleSelectScale() const=0; virtual float GetGrappleClampMin() const = 0;
virtual float GetGrappleScale() const=0; virtual float GetGrappleClampMax() const = 0;
virtual float GetGrappleClampMin() const=0; virtual const zeus::CColor& GetGrapplePointSelectColor() const = 0;
virtual float GetGrappleClampMax() const=0; virtual const zeus::CColor& GetGrapplePointColor() const = 0;
virtual const zeus::CColor& GetGrapplePointSelectColor() const=0; virtual const zeus::CColor& GetLockedGrapplePointSelectColor() const = 0;
virtual const zeus::CColor& GetGrapplePointColor() const=0; virtual float GetGrappleMinClampScale() const = 0;
virtual const zeus::CColor& GetLockedGrapplePointSelectColor() const=0; virtual const zeus::CColor& GetChargeGaugePulseColorHigh() const = 0;
virtual float GetGrappleMinClampScale() const=0; virtual float GetFullChargeFadeDuration() const = 0;
virtual const zeus::CColor& GetChargeGaugePulseColorHigh() const=0; virtual const zeus::CColor& GetOrbitPointColor() const = 0;
virtual float GetFullChargeFadeDuration() const=0; virtual const zeus::CColor& GetCrosshairsColor() const = 0;
virtual const zeus::CColor& GetOrbitPointColor() const=0; virtual float GetCrosshairsScaleDuration() const = 0;
virtual const zeus::CColor& GetCrosshairsColor() const=0; virtual bool DrawOrbitPoint() const = 0;
virtual float GetCrosshairsScaleDuration() const=0; virtual const zeus::CColor& GetChargeGaugePulseColorLow() const = 0;
virtual bool DrawOrbitPoint() const=0; virtual float GetChargeGaugePulsePeriod() const = 0;
virtual const zeus::CColor& GetChargeGaugePulseColorLow() const=0; virtual float GetReticuleClampMin() const = 0;
virtual float GetChargeGaugePulsePeriod() const=0; virtual float GetReticuleClampMax() const = 0;
virtual float GetReticuleClampMin() const=0; virtual const zeus::CColor& GetXRayRetRingColor() const = 0;
virtual float GetReticuleClampMax() const=0; virtual float GetReticuleScale() const = 0;
virtual const zeus::CColor& GetXRayRetRingColor() const=0; virtual float GetScanTargetClampMin() const = 0;
virtual float GetReticuleScale() const=0; virtual float GetScanTargetClampMax() const = 0;
virtual float GetScanTargetClampMin() const=0; virtual float GetAngularLagSpeed() const = 0;
virtual float GetScanTargetClampMax() const=0;
virtual float GetAngularLagSpeed() const=0;
}; };
} } // namespace DataSpec

View File

@ -2,36 +2,31 @@
#include "../PAK.hpp" #include "../PAK.hpp"
namespace DataSpec namespace DataSpec {
{
template <class T> template <class T>
bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath) bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); if (w.hasError())
if (w.hasError())
return false;
tweak.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i=0 ; i<32-rem ; ++i)
w.writeUByte(0xff);
return true;
}
template <class T>
bool ExtractTweak(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
T tweak;
tweak.read(rs);
athena::io::ToYAMLStream(tweak, writer);
return true;
}
return false; return false;
tweak.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i = 0; i < 32 - rem; ++i)
w.writeUByte(0xff);
return true;
} }
template <class T>
bool ExtractTweak(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen()) {
T tweak;
tweak.read(rs);
athena::io::ToYAMLStream(tweak, writer);
return true;
}
return false;
} }
} // namespace DataSpec

File diff suppressed because it is too large Load Diff

View File

@ -4,54 +4,53 @@
#include "PAK.hpp" #include "PAK.hpp"
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle namespace DataSpec::DNAParticle {
{
template <class IDType> template <class IDType>
struct WPSM : BigDNA struct WPSM : BigDNA {
{ AT_DECL_EXPLICIT_DNA_YAML
AT_DECL_EXPLICIT_DNA_YAML AT_SUBDECL_DNA
AT_SUBDECL_DNA VectorElementFactory x0_IORN;
VectorElementFactory x0_IORN; VectorElementFactory x4_IVEC;
VectorElementFactory x4_IVEC; VectorElementFactory x8_PSOV;
VectorElementFactory x8_PSOV; ModVectorElementFactory xc_PSVM;
ModVectorElementFactory xc_PSVM; BoolHelper x10_VMD2;
BoolHelper x10_VMD2; IntElementFactory x14_PSLT;
IntElementFactory x14_PSLT; VectorElementFactory x18_PSCL;
VectorElementFactory x18_PSCL; ColorElementFactory x1c_PCOL;
ColorElementFactory x1c_PCOL; VectorElementFactory x20_POFS;
VectorElementFactory x20_POFS; VectorElementFactory x24_OFST;
VectorElementFactory x24_OFST; BoolHelper x28_APSO;
BoolHelper x28_APSO; BoolHelper x29_HOMG;
BoolHelper x29_HOMG; BoolHelper x2a_AP11;
BoolHelper x2a_AP11; BoolHelper x2b_AP21;
BoolHelper x2b_AP21; BoolHelper x2c_AS11;
BoolHelper x2c_AS11; BoolHelper x2d_AS12;
BoolHelper x2d_AS12; BoolHelper x2e_AS13;
BoolHelper x2e_AS13; RealElementFactory x30_TRAT;
RealElementFactory x30_TRAT; ChildResourceFactory<IDType> x34_APSM;
ChildResourceFactory<IDType> x34_APSM; ChildResourceFactory<IDType> x44_APS2;
ChildResourceFactory<IDType> x44_APS2; ChildResourceFactory<IDType> x54_ASW1;
ChildResourceFactory<IDType> x54_ASW1; ChildResourceFactory<IDType> x64_ASW2;
ChildResourceFactory<IDType> x64_ASW2; ChildResourceFactory<IDType> x74_ASW3;
ChildResourceFactory<IDType> x74_ASW3; ChildResourceFactory<IDType> x84_OHEF;
ChildResourceFactory<IDType> x84_OHEF; ChildResourceFactory<IDType> x94_COLR;
ChildResourceFactory<IDType> x94_COLR; BoolHelper xa4_EWTR;
BoolHelper xa4_EWTR; BoolHelper xa5_LWTR;
BoolHelper xa5_LWTR; BoolHelper xa6_SWTR;
BoolHelper xa6_SWTR; uint32_t xa8_PJFX = ~0;
uint32_t xa8_PJFX = ~0; RealElementFactory xac_RNGE;
RealElementFactory xac_RNGE; RealElementFactory xb0_FOFF;
RealElementFactory xb0_FOFF; BoolHelper xunk_FC60;
BoolHelper xunk_FC60; BoolHelper xunk_SPS1;
BoolHelper xunk_SPS1; BoolHelper xunk_SPS2;
BoolHelper xunk_SPS2;
WPSM() WPSM() {
{ xa4_EWTR = true;
xa4_EWTR = true; xa5_LWTR = true; xa6_SWTR = true; xa5_LWTR = true;
} xa6_SWTR = true;
}
void gatherDependencies(std::vector<hecl::ProjectPath>&) const; void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
}; };
template <class IDType> template <class IDType>
@ -60,5 +59,4 @@ bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType> template <class IDType>
bool WriteWPSM(const WPSM<IDType>& wpsm, const hecl::ProjectPath& outPath); bool WriteWPSM(const WPSM<IDType>& wpsm, const hecl::ProjectPath& outPath);
} } // namespace DataSpec::DNAParticle

View File

@ -1,127 +1,104 @@
#include "AFSM.hpp" #include "AFSM.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
template <> template <>
void AFSM::State::Transition::Enumerate<BigDNA::Read>(typename Read::StreamT& r) void AFSM::State::Transition::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {
{ triggerCount = r.readUint32Big();
triggerCount = r.readUint32Big(); int i = 0;
int i = 0; r.enumerate<Trigger>(triggers, triggerCount, [&](athena::io::IStreamReader& in, Trigger& tr) {
r.enumerate<Trigger>(triggers, triggerCount, tr.first = i == 0;
[&](athena::io::IStreamReader& in, Trigger& tr){ tr.read(in);
tr.first = i == 0; i++;
tr.read(in); });
i++;
});
} }
template <> template <>
void AFSM::State::Transition::Enumerate<BigDNA::Write>(typename Write::StreamT& w) void AFSM::State::Transition::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
{ w.writeInt32Big(triggerCount);
w.writeInt32Big(triggerCount); w.enumerate(triggers);
w.enumerate(triggers);
} }
template <> template <>
void AFSM::State::Transition::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) void AFSM::State::Transition::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
{ int i = 0;
int i = 0; /* triggers */
/* triggers */ triggerCount = r.enumerate<Trigger>("triggers", triggers, [&](athena::io::YAMLDocReader& in, Trigger& tr) {
triggerCount = r.enumerate<Trigger>("triggers", triggers, tr.first = i == 0;
[&](athena::io::YAMLDocReader& in, Trigger& tr){ tr.read(in);
tr.first = i == 0; i++;
tr.read(in); });
i++;
});
} }
template <> template <>
void AFSM::State::Transition::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) void AFSM::State::Transition::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) {
{ /* triggers */
/* triggers */ w.enumerate("triggers", triggers);
w.enumerate("triggers", triggers);
} }
template <> template <>
void AFSM::State::Transition::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) void AFSM::State::Transition::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
{ s += 4;
s += 4; for (const Trigger& trig : triggers)
for (const Trigger& trig : triggers) trig.binarySize(s);
trig.binarySize(s);
} }
const char* AFSM::State::Transition::DNAType() const char* AFSM::State::Transition::DNAType() { return "urde::DNAMP1::AFSM::Transition"; }
{
return "urde::DNAMP1::AFSM::Transition"; template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::Read>(athena::io::IStreamReader& __dna_reader) {
/* name */
name = __dna_reader.readString(-1);
/* parameter */
parameter = __dna_reader.readFloatBig();
if (first) {
/* targetState */
targetState = __dna_reader.readUint32Big();
}
} }
template <> template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::Read>(athena::io::IStreamReader& __dna_reader) void AFSM::State::Transition::Trigger::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& __dna_writer) {
{ /* name */
/* name */ __dna_writer.writeString(name, -1);
name = __dna_reader.readString(-1); /* parameter */
/* parameter */ __dna_writer.writeFloatBig(parameter);
parameter = __dna_reader.readFloatBig(); if (first) {
if (first) /* targetState */
{ __dna_writer.writeUint32Big(targetState);
/* targetState */ }
targetState = __dna_reader.readUint32Big();
}
} }
template <> template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& __dna_writer) void AFSM::State::Transition::Trigger::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& __dna_docin) {
{ /* name */
/* name */ name = __dna_docin.readString("name");
__dna_writer.writeString(name, -1); /* parameter */
/* parameter */ parameter = __dna_docin.readFloat("parameter");
__dna_writer.writeFloatBig(parameter); if (first) {
if (first) /* targetState */
{ targetState = __dna_docin.readUint32("targetState");
/* targetState */ }
__dna_writer.writeUint32Big(targetState);
}
} }
template <> template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& __dna_docin) void AFSM::State::Transition::Trigger::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& __dna_docout) {
{ /* name */
/* name */ __dna_docout.writeString("name", name);
name = __dna_docin.readString("name"); /* parameter */
/* parameter */ __dna_docout.writeFloat("parameter", parameter);
parameter = __dna_docin.readFloat("parameter"); if (first) {
if (first) /* targetState */
{ __dna_docout.writeUint32("targetState", targetState);
/* targetState */ }
targetState = __dna_docin.readUint32("targetState");
}
} }
template <> template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& __dna_docout) void AFSM::State::Transition::Trigger::Enumerate<BigDNA::BinarySize>(size_t& __isz) {
{ __isz += name.size() + 1;
/* name */ __isz += (first ? 8 : 4);
__dna_docout.writeString("name", name);
/* parameter */
__dna_docout.writeFloat("parameter", parameter);
if (first)
{
/* targetState */
__dna_docout.writeUint32("targetState", targetState);
}
} }
template <> const char* AFSM::State::Transition::Trigger::DNAType() { return "urde::DNAMP1::AFSM::State::Transition::Trigger"; }
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::BinarySize>(size_t& __isz)
{
__isz += name.size() + 1;
__isz += (first ? 8 : 4);
}
const char* AFSM::State::Transition::Trigger::DNAType() } // namespace DataSpec::DNAMP1
{
return "urde::DNAMP1::AFSM::State::Transition::Trigger";
}
}

View File

@ -4,56 +4,48 @@
#include "DataSpec/DNACommon/DNACommon.hpp" #include "DataSpec/DNACommon/DNACommon.hpp"
#include "DNAMP1.hpp" #include "DNAMP1.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{ struct AFSM : public BigDNA {
struct AFSM : public BigDNA AT_DECL_DNA_YAML
{ Value<atUint32> stateCount;
Vector<String<-1>, AT_DNA_COUNT(stateCount)> stateNames;
Value<atUint32> triggerCount;
struct State : public BigDNA {
AT_DECL_DNA_YAML AT_DECL_DNA_YAML
Value<atUint32> stateCount; Value<atUint32> transitionCount;
Vector<String<-1>, AT_DNA_COUNT(stateCount)> stateNames; struct Transition : public BigDNA {
Value<atUint32> triggerCount; AT_DECL_EXPLICIT_DNA_YAML
Value<atUint32> triggerCount;
struct State : public BigDNA struct Trigger : public BigDNA {
{ AT_DECL_EXPLICIT_DNA_YAML
AT_DECL_DNA_YAML bool first = false;
Value<atUint32> transitionCount; String<-1> name;
struct Transition : public BigDNA Value<float> parameter;
{ Value<atUint32> targetState;
AT_DECL_EXPLICIT_DNA_YAML };
Value<atUint32> triggerCount; Vector<Trigger, AT_DNA_COUNT(triggerCount)> triggers;
struct Trigger : public BigDNA
{
AT_DECL_EXPLICIT_DNA_YAML
bool first = false;
String<-1> name;
Value<float> parameter;
Value<atUint32> targetState;
};
Vector<Trigger, AT_DNA_COUNT(triggerCount)> triggers;
};
Vector<Transition, AT_DNA_COUNT(transitionCount)> transitions;
}; };
Vector<State, AT_DNA_COUNT(stateCount)> states; Vector<Transition, AT_DNA_COUNT(transitionCount)> transitions;
};
Vector<State, AT_DNA_COUNT(stateCount)> states;
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ AFSM afsm;
AFSM afsm; afsm.read(rs);
afsm.read(rs); athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::FileWriter writer(outPath.getAbsolutePath()); athena::io::ToYAMLStream(afsm, writer);
athena::io::ToYAMLStream(afsm, writer); return true;
return true; }
}
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
{ AFSM afsm;
AFSM afsm; athena::io::FileReader reader(inPath.getAbsolutePath());
athena::io::FileReader reader(inPath.getAbsolutePath()); athena::io::FromYAMLStream(afsm, reader);
athena::io::FromYAMLStream(afsm, reader); athena::io::FileWriter ws(outPath.getAbsolutePath());
athena::io::FileWriter ws(outPath.getAbsolutePath()); afsm.write(ws);
afsm.write(ws); return true;
return true; }
}
}; };
} } // namespace DataSpec::DNAMP1

View File

@ -74,176 +74,170 @@ extern "C" const uint8_t Zoomer_H[];
extern "C" const uint8_t lumigek_H[]; extern "C" const uint8_t lumigek_H[];
extern "C" const uint8_t test_H[]; extern "C" const uint8_t test_H[];
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
using namespace std::literals; using namespace std::literals;
static const std::pair<std::string_view, const uint8_t*> Headers[] = static const std::pair<std::string_view, const uint8_t*> Headers[] = {{"Atomic"sv, Atomic_H},
{ {"BetaBeetle"sv, BetaBeetle_H},
{"Atomic"sv, Atomic_H}, {"Bird"sv, Bird_H},
{"BetaBeetle"sv, BetaBeetle_H}, {"BloodFlower"sv, BloodFlower_H},
{"Bird"sv, Bird_H}, {"Burrower"sv, Burrower_H},
{"BloodFlower"sv, BloodFlower_H}, {"ChozoGhost"sv, ChozoGhost_H},
{"Burrower"sv, Burrower_H}, {"ChubbWeed"sv, ChubbWeed_H},
{"ChozoGhost"sv, ChozoGhost_H}, {"CineBoots"sv, CineBoots_H},
{"ChubbWeed"sv, ChubbWeed_H}, {"CineGeneral"sv, CineGeneral_H},
{"CineBoots"sv, CineBoots_H}, {"CineGun"sv, CineGun_H},
{"CineGeneral"sv, CineGeneral_H}, {"CineMorphball"sv, CineMorphball_H},
{"CineGun"sv, CineGun_H}, {"CineSuit"sv, CineSuit_H},
{"CineMorphball"sv, CineMorphball_H}, {"CineVisor"sv, CineVisor_H},
{"CineSuit"sv, CineSuit_H}, {"Crater"sv, Crater_H},
{"CineVisor"sv, CineVisor_H}, {"Crystallite"sv, Crystallite_H},
{"Crater"sv, Crater_H}, {"Drones"sv, Drones_H},
{"Crystallite"sv, Crystallite_H}, {"EliteSpacePirate"sv, EliteSpacePirate_H},
{"Drones"sv, Drones_H}, {"FireFlea"sv, FireFlea_H},
{"EliteSpacePirate"sv, EliteSpacePirate_H}, {"Flaaghra"sv, Flaaghra_H},
{"FireFlea"sv, FireFlea_H}, {"FlickerBat"sv, FlickerBat_H},
{"Flaaghra"sv, Flaaghra_H}, {"FlyingPirate"sv, FlyingPirate_H},
{"FlickerBat"sv, FlickerBat_H}, {"FrontEnd"sv, FrontEnd_H},
{"FlyingPirate"sv, FlyingPirate_H}, {"GagantuanBeatle"sv, GagantuanBeatle_H},
{"FrontEnd"sv, FrontEnd_H}, {"Gnats"sv, Gnats_H},
{"GagantuanBeatle"sv, GagantuanBeatle_H}, {"Gryzbee"sv, Gryzbee_H},
{"Gnats"sv, Gnats_H}, {"IceCrack"sv, IceCrack_H},
{"Gryzbee"sv, Gryzbee_H}, {"IceWorld"sv, IceWorld_H},
{"IceCrack"sv, IceCrack_H}, {"InjuredPirates"sv, InjuredPirates_H},
{"IceWorld"sv, IceWorld_H}, {"IntroBoss"sv, IntroBoss_H},
{"InjuredPirates"sv, InjuredPirates_H}, {"IntroWorld"sv, IntroWorld_H},
{"IntroBoss"sv, IntroBoss_H}, {"JellyZap"sv, JellyZap_H},
{"IntroWorld"sv, IntroWorld_H}, {"LavaWorld"sv, LavaWorld_H},
{"JellyZap"sv, JellyZap_H}, {"Magdolite"sv, Magdolite_H},
{"LavaWorld"sv, LavaWorld_H}, {"Metaree"sv, Metaree_H},
{"Magdolite"sv, Magdolite_H}, {"MetroidPrime"sv, MetroidPrime_H},
{"Metaree"sv, Metaree_H}, {"Metroid"sv, Metroid_H},
{"MetroidPrime"sv, MetroidPrime_H}, {"MinesWorld"sv, MinesWorld_H},
{"Metroid"sv, Metroid_H}, {"MiscSamus"sv, MiscSamus_H},
{"MinesWorld"sv, MinesWorld_H}, {"Misc"sv, Misc_H},
{"MiscSamus"sv, MiscSamus_H}, {"OmegaPirate"sv, OmegaPirate_H},
{"Misc"sv, Misc_H}, {"OverWorld"sv, OverWorld_H},
{"OmegaPirate"sv, OmegaPirate_H}, {"Parasite"sv, Parasite_H},
{"OverWorld"sv, OverWorld_H}, {"PhazonGun"sv, PhazonGun_H},
{"Parasite"sv, Parasite_H}, {"Phazon"sv, Phazon_H},
{"PhazonGun"sv, PhazonGun_H}, {"PuddleSpore"sv, PuddleSpore_H},
{"Phazon"sv, Phazon_H}, {"PuddleToad"sv, PuddleToad_H},
{"PuddleSpore"sv, PuddleSpore_H}, {"Puffer"sv, Puffer_H},
{"PuddleToad"sv, PuddleToad_H}, {"ReactorDoor"sv, ReactorDoor_H},
{"Puffer"sv, Puffer_H}, {"Ridley"sv, Ridley_H},
{"ReactorDoor"sv, ReactorDoor_H}, {"Ripper"sv, Ripper_H},
{"Ridley"sv, Ridley_H}, {"RuinsWorld"sv, RuinsWorld_H},
{"Ripper"sv, Ripper_H}, {"SamusShip"sv, SamusShip_H},
{"RuinsWorld"sv, RuinsWorld_H}, {"Scarab"sv, Scarab_H},
{"SamusShip"sv, SamusShip_H}, {"Seedling"sv, Seedling_H},
{"Scarab"sv, Scarab_H}, {"SheeGoth"sv, SheeGoth_H},
{"Seedling"sv, Seedling_H}, {"SnakeWeed"sv, SnakeWeed_H},
{"SheeGoth"sv, SheeGoth_H}, {"Sova"sv, Sova_H},
{"SnakeWeed"sv, SnakeWeed_H}, {"SpacePirate"sv, SpacePirate_H},
{"Sova"sv, Sova_H}, {"SpankWeed"sv, SpankWeed_H},
{"SpacePirate"sv, SpacePirate_H}, {"Thardus"sv, Thardus_H},
{"SpankWeed"sv, SpankWeed_H}, {"TheEnd"sv, TheEnd_H},
{"Thardus"sv, Thardus_H}, {"Torobyte"sv, Torobyte_H},
{"TheEnd"sv, TheEnd_H}, {"Triclops"sv, Triclops_H},
{"Torobyte"sv, Torobyte_H}, {"Turret"sv, Turret_H},
{"Triclops"sv, Triclops_H}, {"UI"sv, UI_H},
{"Turret"sv, Turret_H}, {"WarWasp"sv, WarWasp_H},
{"UI"sv, UI_H}, {"Weapons"sv, Weapons_H},
{"WarWasp"sv, WarWasp_H}, {"ZZZ"sv, ZZZ_H},
{"Weapons"sv, Weapons_H}, {"Zoomer"sv, Zoomer_H},
{"ZZZ"sv, ZZZ_H}, {"lumigek"sv, lumigek_H},
{"Zoomer"sv, Zoomer_H}, {"test"sv, test_H}};
{"lumigek"sv, lumigek_H},
{"test"sv, test_H}
};
bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) {
{ dir.makeDirChain(true);
dir.makeDirChain(true);
Header head; Header head;
head.read(rs); head.read(rs);
uint32_t poolLen = rs.readUint32Big(); uint32_t poolLen = rs.readUint32Big();
auto pool = rs.readUBytes(poolLen); auto pool = rs.readUBytes(poolLen);
uint32_t projLen = rs.readUint32Big(); uint32_t projLen = rs.readUint32Big();
auto proj = rs.readUBytes(projLen); auto proj = rs.readUBytes(projLen);
uint32_t sampLen = rs.readUint32Big(); uint32_t sampLen = rs.readUint32Big();
auto samp = rs.readUBytes(sampLen); auto samp = rs.readUBytes(sampLen);
uint32_t sdirLen = rs.readUint32Big(); uint32_t sdirLen = rs.readUint32Big();
auto sdir = rs.readUBytes(sdirLen); auto sdir = rs.readUBytes(sdirLen);
amuse::AudioGroupData data(proj.get(), projLen, pool.get(), poolLen, amuse::AudioGroupData data(proj.get(), projLen, pool.get(), poolLen, sdir.get(), sdirLen, samp.get(), sampLen,
sdir.get(), sdirLen, samp.get(), sampLen, amuse::GCNDataTag{}); amuse::GCNDataTag{});
/* Load into amuse representation */ /* Load into amuse representation */
amuse::ProjectDatabase projDb; amuse::ProjectDatabase projDb;
projDb.setIdDatabases(); projDb.setIdDatabases();
amuse::AudioGroupDatabase group(data); amuse::AudioGroupDatabase group(data);
group.setGroupPath(dir.getAbsolutePath()); group.setGroupPath(dir.getAbsolutePath());
/* Extract samples */ /* Extract samples */
group.getSdir().extractAllCompressed(dir.getAbsolutePath(), data.getSamp()); group.getSdir().extractAllCompressed(dir.getAbsolutePath(), data.getSamp());
/* Import C headers */ /* Import C headers */
auto lastComp = dir.getLastComponentUTF8(); auto lastComp = dir.getLastComponentUTF8();
auto search = std::lower_bound(std::cbegin(Headers), std::cend(Headers), lastComp, auto search = std::lower_bound(std::cbegin(Headers), std::cend(Headers), lastComp,
[](const auto& a, const auto& b) { return a.first < b; }); [](const auto& a, const auto& b) { return a.first < b; });
if (search != std::cend(Headers) && search->first == lastComp) if (search != std::cend(Headers) && search->first == lastComp)
group.importCHeader((char*)search->second); group.importCHeader((char*)search->second);
/* Write out project/pool */ /* Write out project/pool */
{ {
auto projd = group.getProj().toYAML(); auto projd = group.getProj().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!project.yaml")).getAbsolutePath()); athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!project.yaml")).getAbsolutePath());
if (fo.hasError()) if (fo.hasError())
return false; return false;
fo.writeUBytes(projd.data(), projd.size()); fo.writeUBytes(projd.data(), projd.size());
} }
{ {
auto poold = group.getPool().toYAML(); auto poold = group.getPool().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!pool.yaml")).getAbsolutePath()); athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!pool.yaml")).getAbsolutePath());
if (fo.hasError()) if (fo.hasError())
return false; return false;
fo.writeUBytes(poold.data(), poold.size()); fo.writeUBytes(poold.data(), poold.size());
} }
return true; return true;
} }
bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath) bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath) {
{ athena::io::FileWriter w(outPath.getAbsolutePath());
athena::io::FileWriter w(outPath.getAbsolutePath()); if (w.hasError())
if (w.hasError()) return false;
return false;
Header head; Header head;
head.audioDir = "Audio/"sv; head.audioDir = "Audio/"sv;
head.groupName = dir.getLastComponentUTF8(); head.groupName = dir.getLastComponentUTF8();
head.write(w); head.write(w);
amuse::ProjectDatabase projDb; amuse::ProjectDatabase projDb;
projDb.setIdDatabases(); projDb.setIdDatabases();
amuse::AudioGroupDatabase group(dir.getAbsolutePath()); amuse::AudioGroupDatabase group(dir.getAbsolutePath());
auto proj = group.getProj().toGCNData(group.getPool(), group.getSdir()); auto proj = group.getProj().toGCNData(group.getPool(), group.getSdir());
auto pool = group.getPool().toData<athena::Big>(); auto pool = group.getPool().toData<athena::Big>();
auto sdirSamp = group.getSdir().toGCNData(group); auto sdirSamp = group.getSdir().toGCNData(group);
w.writeUint32Big(pool.size()); w.writeUint32Big(pool.size());
w.writeUBytes(pool.data(), pool.size()); w.writeUBytes(pool.data(), pool.size());
w.writeUint32Big(proj.size()); w.writeUint32Big(proj.size());
w.writeUBytes(proj.data(), proj.size()); w.writeUBytes(proj.data(), proj.size());
w.writeUint32Big(sdirSamp.second.size()); w.writeUint32Big(sdirSamp.second.size());
w.writeUBytes(sdirSamp.second.data(), sdirSamp.second.size()); w.writeUBytes(sdirSamp.second.data(), sdirSamp.second.size());
w.writeUint32Big(sdirSamp.first.size()); w.writeUint32Big(sdirSamp.first.size());
w.writeUBytes(sdirSamp.first.data(), sdirSamp.first.size()); w.writeUBytes(sdirSamp.first.data(), sdirSamp.first.size());
return true; return true;
} }
} } // namespace DataSpec::DNAMP1

View File

@ -3,21 +3,17 @@
#include "DataSpec/DNACommon/DNACommon.hpp" #include "DataSpec/DNACommon/DNACommon.hpp"
#include "DNAMP1.hpp" #include "DNAMP1.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
class AGSC class AGSC {
{
public: public:
struct Header : BigDNA struct Header : BigDNA {
{ AT_DECL_DNA
AT_DECL_DNA String<-1> audioDir;
String<-1> audioDir; String<-1> groupName;
String<-1> groupName; };
}; static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
}; };
} } // namespace DataSpec::DNAMP1

File diff suppressed because it is too large Load Diff

View File

@ -10,510 +10,419 @@
#include "EVNT.hpp" #include "EVNT.hpp"
#include "athena/FileReader.hpp" #include "athena/FileReader.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
struct ANCS : BigDNA struct ANCS : BigDNA {
{ using CINFType = CINF;
using CINFType = CINF; using CSKRType = CSKR;
using CSKRType = CSKR; using ANIMType = ANIM;
using ANIMType = ANIM;
AT_DECL_DNA_YAML
Value<atUint16> version;
struct CharacterSet : BigDNA {
AT_DECL_DNA_YAML AT_DECL_DNA_YAML
Value<atUint16> version; Value<atUint16> version;
Value<atUint32> characterCount;
struct CharacterInfo : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
struct CharacterSet : BigDNA atUint32 idx;
{ std::string name;
UniqueID32 cmdl;
UniqueID32 cskr;
UniqueID32 cinf;
struct Animation : BigDNA {
AT_DECL_DNA_YAML AT_DECL_DNA_YAML
Value<atUint16> version; Value<atUint32> animIdx;
Value<atUint32> characterCount; String<-1> strA;
struct CharacterInfo : BigDNA String<-1> strB;
{ };
AT_DECL_DNA_YAML std::vector<Animation> animations;
Delete expl;
atUint32 idx; struct PASDatabase : BigDNA {
std::string name;
UniqueID32 cmdl;
UniqueID32 cskr;
UniqueID32 cinf;
struct Animation : BigDNA
{
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
String<-1> strA;
String<-1> strB;
};
std::vector<Animation> animations;
struct PASDatabase : BigDNA
{
AT_DECL_DNA_YAML
Value<atUint32> magic;
Value<atUint32> animStateCount;
Value<atUint32> defaultState;
struct AnimState : BigDNA
{
AT_DECL_DNA_YAML
Delete expl;
atUint32 id;
struct ParmInfo : BigDNA
{
AT_DECL_DNA_YAML
Delete expl;
enum class DataType
{
Int32 = 0,
UInt32 = 1,
Float = 2,
Bool = 3,
Enum = 4
};
union Parm
{
atInt32 int32;
atUint32 uint32;
float float32;
bool bool1;
Parm() : int32(0) {}
Parm(atInt32 val) : int32(val) {}
Parm(atUint32 val) : uint32(val) {}
Parm(float val) : float32(val) {}
Parm(bool val) : bool1(val) {}
};
atUint32 parmType;
atUint32 weightFunction;
float weight;
Parm range[2];
};
std::vector<ParmInfo> parmInfos;
struct AnimInfo
{
atUint32 id;
std::vector<ParmInfo::Parm> parmVals;
};
std::vector<AnimInfo> animInfos;
};
Vector<AnimState, AT_DNA_COUNT(animStateCount)> animStates;
} pasDatabase;
struct ParticleResData
{
std::vector<UniqueID32> part;
std::vector<UniqueID32> swhc;
std::vector<UniqueID32> unk;
std::vector<UniqueID32> elsc;
} partResData;
atUint32 unk1 = 0;
struct ActionAABB : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atVec3f> aabb[2];
};
std::vector<ActionAABB> animAABBs;
struct Effect : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> compCount;
struct EffectComponent : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
DNAFourCC type;
UniqueID32 id;
String<-1> locator;
Value<float> scale;
Value<atUint32> parentMode;
Value<atUint32> flags;
};
Vector<EffectComponent, AT_DNA_COUNT(compCount)> comps;
};
std::vector<Effect> effects;
UniqueID32Zero cmdlIce;
UniqueID32Zero cskrIce;
std::vector<atUint32> animIdxs;
};
Vector<CharacterInfo, AT_DNA_COUNT(characterCount)> characters;
} characterSet;
struct AnimationSet : BigDNA
{
AT_DECL_DNA_YAML AT_DECL_DNA_YAML
Delete expl; Value<atUint32> magic;
Value<atUint32> animStateCount;
Value<atUint32> defaultState;
struct AnimState : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
atUint32 id;
struct MetaAnimPrimitive; struct ParmInfo : BigDNA {
struct IMetaAnim : BigDNAVYaml AT_DECL_DNA_YAML
{
Delete expl; Delete expl;
enum class Type enum class DataType { Int32 = 0, UInt32 = 1, Float = 2, Bool = 3, Enum = 4 };
{ union Parm {
Primitive = 0, atInt32 int32;
Blend = 1, atUint32 uint32;
PhaseBlend = 2, float float32;
Random = 3, bool bool1;
Sequence = 4 Parm() : int32(0) {}
} m_type; Parm(atInt32 val) : int32(val) {}
const char* m_typeStr; Parm(atUint32 val) : uint32(val) {}
IMetaAnim(Type type, const char* typeStr) Parm(float val) : float32(val) {}
: m_type(type), m_typeStr(typeStr) {} Parm(bool val) : bool1(val) {}
virtual void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)=0;
virtual bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)=0;
};
struct MetaAnimFactory : BigDNA
{
AT_DECL_EXPLICIT_DNA_YAML
std::unique_ptr<IMetaAnim> m_anim;
};
struct MetaAnimPrimitive : IMetaAnim
{
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {}
UniqueID32 animId;
Value<atUint32> animIdx;
String<-1> animName;
Value<float> unk1;
Value<atUint32> unk2;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out);
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
return func(*this);
}
};
struct MetaAnimBlend : IMetaAnim
{
MetaAnimBlend()
: IMetaAnim(Type::Blend, "Blend") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory animA;
MetaAnimFactory animB;
Value<float> unkFloat;
Value<atUint8> unk;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{
animA.m_anim->gatherPrimitives(pakRouter, out);
animB.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
if (!animA.m_anim->enumeratePrimitives(func))
return false;
if (!animB.m_anim->enumeratePrimitives(func))
return false;
return true;
}
};
struct MetaAnimPhaseBlend : IMetaAnim
{
MetaAnimPhaseBlend()
: IMetaAnim(Type::PhaseBlend, "PhaseBlend") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory animA;
MetaAnimFactory animB;
Value<float> unkFloat;
Value<atUint8> unk;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{
animA.m_anim->gatherPrimitives(pakRouter, out);
animB.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
if (!animA.m_anim->enumeratePrimitives(func))
return false;
if (!animB.m_anim->enumeratePrimitives(func))
return false;
return true;
}
};
struct MetaAnimRandom : IMetaAnim
{
MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atUint32> animCount;
struct Child : BigDNA
{
AT_DECL_DNA
MetaAnimFactory anim;
Value<atUint32> probability;
}; };
Vector<Child, AT_DNA_COUNT(animCount)> children;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter, atUint32 parmType;
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) atUint32 weightFunction;
{ float weight;
for (const auto& child : children) Parm range[2];
child.anim.m_anim->gatherPrimitives(pakRouter, out); };
} std::vector<ParmInfo> parmInfos;
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) struct AnimInfo {
{ atUint32 id;
for (auto& child : children) std::vector<ParmInfo::Parm> parmVals;
if (!child.anim.m_anim->enumeratePrimitives(func)) };
return false; std::vector<AnimInfo> animInfos;
return true;
}
}; };
struct MetaAnimSequence : IMetaAnim Vector<AnimState, AT_DNA_COUNT(animStateCount)> animStates;
{ } pasDatabase;
MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atUint32> animCount;
Vector<MetaAnimFactory, AT_DNA_COUNT(animCount)> children;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter, struct ParticleResData {
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) std::vector<UniqueID32> part;
{ std::vector<UniqueID32> swhc;
for (const auto& child : children) std::vector<UniqueID32> unk;
child.m_anim->gatherPrimitives(pakRouter, out); std::vector<UniqueID32> elsc;
} } partResData;
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) atUint32 unk1 = 0;
{
for (auto& child : children) struct ActionAABB : BigDNA {
if (!child.m_anim->enumeratePrimitives(func)) AT_DECL_DNA_YAML
return false; String<-1> name;
return true; Value<atVec3f> aabb[2];
} };
std::vector<ActionAABB> animAABBs;
struct Effect : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> compCount;
struct EffectComponent : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
DNAFourCC type;
UniqueID32 id;
String<-1> locator;
Value<float> scale;
Value<atUint32> parentMode;
Value<atUint32> flags;
}; };
Vector<EffectComponent, AT_DNA_COUNT(compCount)> comps;
};
std::vector<Effect> effects;
struct Animation : BigDNA UniqueID32Zero cmdlIce;
{ UniqueID32Zero cskrIce;
AT_DECL_DNA_YAML
String<-1> name;
MetaAnimFactory metaAnim;
};
std::vector<Animation> animations;
struct IMetaTrans : BigDNAVYaml std::vector<atUint32> animIdxs;
{ };
Delete expl; Vector<CharacterInfo, AT_DNA_COUNT(characterCount)> characters;
enum class Type } characterSet;
{
MetaAnim = 0,
Trans = 1,
PhaseTrans = 2,
NoTrans = 3,
} m_type;
const char* m_typeStr;
IMetaTrans(Type type, const char* typeStr)
: m_type(type), m_typeStr(typeStr) {}
virtual void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {}
virtual bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {return true;}
};
struct MetaTransFactory : BigDNA
{
AT_DECL_DNA_YAML
Delete expl;
std::unique_ptr<IMetaTrans> m_trans;
};
struct MetaTransMetaAnim : IMetaTrans
{
MetaTransMetaAnim()
: IMetaTrans(Type::MetaAnim, "MetaAnim") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory anim;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter, struct AnimationSet : BigDNA {
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) AT_DECL_DNA_YAML
{ Delete expl;
anim.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) struct MetaAnimPrimitive;
{ struct IMetaAnim : BigDNAVYaml {
return anim.m_anim->enumeratePrimitives(func); Delete expl;
} enum class Type { Primitive = 0, Blend = 1, PhaseBlend = 2, Random = 3, Sequence = 4 } m_type;
}; const char* m_typeStr;
struct MetaTransTrans : IMetaTrans IMetaAnim(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {}
{ virtual void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
MetaTransTrans() std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) = 0;
: IMetaTrans(Type::Trans, "Trans") {} virtual bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) = 0;
AT_DECL_DNA_YAML };
AT_DECL_DNAV struct MetaAnimFactory : BigDNA {
Value<float> transDurTime; AT_DECL_EXPLICIT_DNA_YAML
Value<atUint32> transDurTimeMode; std::unique_ptr<IMetaAnim> m_anim;
Value<bool> unk2; };
Value<bool> runA; struct MetaAnimPrimitive : IMetaAnim {
Value<atUint32> flags; AT_DECL_DNA_YAML
}; AT_DECL_DNAV
struct MetaTransPhaseTrans : IMetaTrans MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {}
{
MetaTransPhaseTrans()
: IMetaTrans(Type::PhaseTrans, "PhaseTrans") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<float> transDurTime;
Value<atUint32> transDurTimeMode;
Value<bool> unk2;
Value<bool> runA;
Value<atUint32> flags;
};
struct Transition : BigDNA UniqueID32 animId;
{ Value<atUint32> animIdx;
AT_DECL_DNA_YAML String<-1> animName;
Value<atUint32> unk; Value<float> unk1;
Value<atUint32> animIdxA; Value<atUint32> unk2;
Value<atUint32> animIdxB;
MetaTransFactory metaTrans;
};
std::vector<Transition> transitions;
MetaTransFactory defaultTransition;
struct AdditiveAnimationInfo : BigDNA void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
{ std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out);
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
Value<float> unk1;
Value<float> unk2;
};
std::vector<AdditiveAnimationInfo> additiveAnims;
float floatA = 0.0; bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) { return func(*this); }
float floatB = 0.0; };
struct MetaAnimBlend : IMetaAnim {
MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory animA;
MetaAnimFactory animB;
Value<float> unkFloat;
Value<atUint8> unk;
struct HalfTransition : BigDNA void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
{ std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
AT_DECL_DNA_YAML animA.m_anim->gatherPrimitives(pakRouter, out);
Value<atUint32> animIdx; animB.m_anim->gatherPrimitives(pakRouter, out);
MetaTransFactory metaTrans; }
};
std::vector<HalfTransition> halfTransitions;
struct AnimationResources : BigDNA bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
{ if (!animA.m_anim->enumeratePrimitives(func))
AT_DECL_DNA_YAML return false;
UniqueID32 animId; if (!animB.m_anim->enumeratePrimitives(func))
UniqueID32 evntId; return false;
}; return true;
std::vector<AnimationResources> animResources; }
} animationSet; };
struct MetaAnimPhaseBlend : IMetaAnim {
MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory animA;
MetaAnimFactory animB;
Value<float> unkFloat;
Value<atUint8> unk;
void getCharacterResInfo(std::vector<DNAANCS::CharacterResInfo<UniqueID32>>& out) const void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
{ std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
out.clear(); animA.m_anim->gatherPrimitives(pakRouter, out);
out.reserve(characterSet.characters.size()); animB.m_anim->gatherPrimitives(pakRouter, out);
for (const CharacterSet::CharacterInfo& ci : characterSet.characters) }
{
out.emplace_back();
DNAANCS::CharacterResInfo<UniqueID32>& chOut = out.back();
chOut.name = ci.name;
chOut.cmdl = ci.cmdl;
chOut.cskr = ci.cskr;
chOut.cinf = ci.cinf;
if (ci.cmdlIce) bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
chOut.overlays.emplace_back("ICE", std::make_pair(ci.cmdlIce, ci.cskrIce)); if (!animA.m_anim->enumeratePrimitives(func))
} return false;
if (!animB.m_anim->enumeratePrimitives(func))
return false;
return true;
}
};
struct MetaAnimRandom : IMetaAnim {
MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atUint32> animCount;
struct Child : BigDNA {
AT_DECL_DNA
MetaAnimFactory anim;
Value<atUint32> probability;
};
Vector<Child, AT_DNA_COUNT(animCount)> children;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
for (const auto& child : children)
child.anim.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
for (auto& child : children)
if (!child.anim.m_anim->enumeratePrimitives(func))
return false;
return true;
}
};
struct MetaAnimSequence : IMetaAnim {
MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atUint32> animCount;
Vector<MetaAnimFactory, AT_DNA_COUNT(animCount)> children;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
for (const auto& child : children)
child.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
for (auto& child : children)
if (!child.m_anim->enumeratePrimitives(func))
return false;
return true;
}
};
struct Animation : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
MetaAnimFactory metaAnim;
};
std::vector<Animation> animations;
struct IMetaTrans : BigDNAVYaml {
Delete expl;
enum class Type {
MetaAnim = 0,
Trans = 1,
PhaseTrans = 2,
NoTrans = 3,
} m_type;
const char* m_typeStr;
IMetaTrans(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {}
virtual void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {}
virtual bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) { return true; }
};
struct MetaTransFactory : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
std::unique_ptr<IMetaTrans> m_trans;
};
struct MetaTransMetaAnim : IMetaTrans {
MetaTransMetaAnim() : IMetaTrans(Type::MetaAnim, "MetaAnim") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory anim;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
anim.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
return anim.m_anim->enumeratePrimitives(func);
}
};
struct MetaTransTrans : IMetaTrans {
MetaTransTrans() : IMetaTrans(Type::Trans, "Trans") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<float> transDurTime;
Value<atUint32> transDurTimeMode;
Value<bool> unk2;
Value<bool> runA;
Value<atUint32> flags;
};
struct MetaTransPhaseTrans : IMetaTrans {
MetaTransPhaseTrans() : IMetaTrans(Type::PhaseTrans, "PhaseTrans") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<float> transDurTime;
Value<atUint32> transDurTimeMode;
Value<bool> unk2;
Value<bool> runA;
Value<atUint32> flags;
};
struct Transition : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> unk;
Value<atUint32> animIdxA;
Value<atUint32> animIdxB;
MetaTransFactory metaTrans;
};
std::vector<Transition> transitions;
MetaTransFactory defaultTransition;
struct AdditiveAnimationInfo : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
Value<float> unk1;
Value<float> unk2;
};
std::vector<AdditiveAnimationInfo> additiveAnims;
float floatA = 0.0;
float floatB = 0.0;
struct HalfTransition : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
MetaTransFactory metaTrans;
};
std::vector<HalfTransition> halfTransitions;
struct AnimationResources : BigDNA {
AT_DECL_DNA_YAML
UniqueID32 animId;
UniqueID32 evntId;
};
std::vector<AnimationResources> animResources;
} animationSet;
void getCharacterResInfo(std::vector<DNAANCS::CharacterResInfo<UniqueID32>>& out) const {
out.clear();
out.reserve(characterSet.characters.size());
for (const CharacterSet::CharacterInfo& ci : characterSet.characters) {
out.emplace_back();
DNAANCS::CharacterResInfo<UniqueID32>& chOut = out.back();
chOut.name = ci.name;
chOut.cmdl = ci.cmdl;
chOut.cskr = ci.cskr;
chOut.cinf = ci.cinf;
if (ci.cmdlIce)
chOut.overlays.emplace_back("ICE", std::make_pair(ci.cmdlIce, ci.cskrIce));
} }
}
void getAnimationResInfo(PAKRouter<PAKBridge>* pakRouter, void getAnimationResInfo(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) const std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) const {
{ out.clear();
out.clear(); for (const AnimationSet::Animation& ai : animationSet.animations)
for (const AnimationSet::Animation& ai : animationSet.animations) if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get()) anim->gatherPrimitives(pakRouter, out);
anim->gatherPrimitives(pakRouter, out); for (const AnimationSet::Transition& ti : animationSet.transitions)
for (const AnimationSet::Transition& ti : animationSet.transitions) if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get()) trans->gatherPrimitives(pakRouter, out);
trans->gatherPrimitives(pakRouter, out); if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get()) trans->gatherPrimitives(pakRouter, out);
trans->gatherPrimitives(pakRouter, out); }
}
void enumeratePrimitives(const std::function<bool(AnimationSet::MetaAnimPrimitive& prim)>& func) void enumeratePrimitives(const std::function<bool(AnimationSet::MetaAnimPrimitive& prim)>& func) {
{ for (const AnimationSet::Animation& ai : animationSet.animations)
for (const AnimationSet::Animation& ai : animationSet.animations) if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get()) anim->enumeratePrimitives(func);
anim->enumeratePrimitives(func); for (const AnimationSet::Transition& ti : animationSet.transitions)
for (const AnimationSet::Transition& ti : animationSet.transitions) if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get()) trans->enumeratePrimitives(func);
trans->enumeratePrimitives(func); if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get()) trans->enumeratePrimitives(func);
trans->enumeratePrimitives(func); }
}
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, int charIdx) const void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, int charIdx) const {
{ auto doCi = [&](const CharacterSet::CharacterInfo& ci) {
auto doCi = [&](const CharacterSet::CharacterInfo& ci) for (const auto& id : ci.partResData.part)
{ g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.part) for (const auto& id : ci.partResData.swhc)
g_curSpec->flattenDependencies(id, pathsOut); g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.swhc) for (const auto& id : ci.partResData.unk)
g_curSpec->flattenDependencies(id, pathsOut); g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.unk) for (const auto& id : ci.partResData.elsc)
g_curSpec->flattenDependencies(id, pathsOut); g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.elsc) };
g_curSpec->flattenDependencies(id, pathsOut); if (charIdx < 0)
}; for (const CharacterSet::CharacterInfo& ci : characterSet.characters)
if (charIdx < 0) doCi(ci);
for (const CharacterSet::CharacterInfo& ci : characterSet.characters) else if (charIdx < characterSet.characters.size())
doCi(ci); doCi(characterSet.characters[charIdx]);
else if (charIdx < characterSet.characters.size()) }
doCi(characterSet.characters[charIdx]);
}
static bool Extract(const SpecBase& dataSpec, static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKEntryReadStream& rs, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged);
PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry,
bool force,
hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath, static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor);
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor);
static bool CookCINF(const hecl::ProjectPath& outPath, static bool CookCINF(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor);
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor);
static bool CookCSKR(const hecl::ProjectPath& outPath, static bool CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const hecl::ProjectPath& inPath, const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc);
const DNAANCS::Actor& actor, static bool CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc); const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc);
static bool CookCSKRPC(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc);
static bool CookANIM(const hecl::ProjectPath& outPath, static bool CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const hecl::ProjectPath& inPath, hecl::blender::DataStream& ds, bool pc);
const DNAANCS::Actor& actor,
hecl::blender::DataStream& ds,
bool pc);
}; };
} } // namespace DataSpec::DNAMP1

File diff suppressed because it is too large Load Diff

View File

@ -7,240 +7,211 @@
#include "EVNT.hpp" #include "EVNT.hpp"
#include "DataSpec/DNACommon/ANCS.hpp" #include "DataSpec/DNACommon/ANCS.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
struct ANIM : BigDNA struct ANIM : BigDNA {
{ AT_DECL_EXPLICIT_DNA
static UniqueID32 GetEVNTId(athena::io::IStreamReader& r);
struct IANIM : BigDNAV {
Delete expl;
atUint32 m_version;
IANIM(atUint32 version) : m_version(version) {}
std::vector<std::pair<atUint32, bool>> bones;
std::vector<atUint32> frames;
std::vector<DNAANIM::Channel> channels;
std::vector<std::vector<DNAANIM::Value>> chanKeys;
float mainInterval = 0.0;
UniqueID32Zero evnt;
bool looping = false;
void sendANIMToBlender(hecl::blender::PyOutStream&, const DNAANIM::RigInverter<CINF>& rig) const;
};
struct ANIM0 : IANIM {
AT_DECL_EXPLICIT_DNA AT_DECL_EXPLICIT_DNA
AT_DECL_DNAV
ANIM0() : IANIM(0) {}
static UniqueID32 GetEVNTId(athena::io::IStreamReader& r); struct Header : BigDNA {
AT_DECL_DNA
Value<float> duration;
Value<atUint32> unk0;
Value<float> interval;
Value<atUint32> unk1;
Value<atUint32> keyCount;
Value<atUint32> unk2;
Value<atUint32> boneSlotCount;
};
};
struct IANIM : BigDNAV struct ANIM2 : IANIM {
{ AT_DECL_EXPLICIT_DNA
Delete expl; AT_DECL_DNAV
atUint32 m_version; ANIM2(bool pc) : IANIM(pc ? 3 : 2) {}
IANIM(atUint32 version) : m_version(version) {}
std::vector<std::pair<atUint32, bool>> bones; struct Header : BigDNA {
std::vector<atUint32> frames; AT_DECL_DNA
std::vector<DNAANIM::Channel> channels; Value<atUint32> scratchSize;
std::vector<std::vector<DNAANIM::Value>> chanKeys; UniqueID32Zero evnt;
float mainInterval = 0.0; Value<atUint32> unk0 = 1;
UniqueID32Zero evnt; Value<float> duration;
bool looping = false; Value<float> interval;
Value<atUint32> rootBoneId = 3;
void sendANIMToBlender(hecl::blender::PyOutStream&, const DNAANIM::RigInverter<CINF>& rig) const; Value<atUint32> looping = 0;
Value<atUint32> rotDiv;
Value<float> translationMult;
Value<atUint32> boneChannelCount;
Value<atUint32> unk3;
Value<atUint32> keyBitmapBitCount;
}; };
struct ANIM0 : IANIM struct ChannelDesc : BigDNA {
{ Delete expl;
AT_DECL_EXPLICIT_DNA Value<atUint32> id = 0;
AT_DECL_DNAV Value<atUint16> keyCount1 = 0;
ANIM0() : IANIM(0) {} Value<atInt16> initRX = 0;
Value<atUint8> qRX = 0;
Value<atInt16> initRY = 0;
Value<atUint8> qRY = 0;
Value<atInt16> initRZ = 0;
Value<atUint8> qRZ = 0;
Value<atUint16> keyCount2 = 0;
Value<atInt16> initTX = 0;
Value<atUint8> qTX = 0;
Value<atInt16> initTY = 0;
Value<atUint8> qTY = 0;
Value<atInt16> initTZ = 0;
Value<atUint8> qTZ = 0;
struct Header : BigDNA void read(athena::io::IStreamReader& reader) {
{ id = reader.readUint32Big();
AT_DECL_DNA keyCount1 = reader.readUint16Big();
Value<float> duration; initRX = reader.readInt16Big();
Value<atUint32> unk0; qRX = reader.readUByte();
Value<float> interval; initRY = reader.readInt16Big();
Value<atUint32> unk1; qRY = reader.readUByte();
Value<atUint32> keyCount; initRZ = reader.readInt16Big();
Value<atUint32> unk2; qRZ = reader.readUByte();
Value<atUint32> boneSlotCount; keyCount2 = reader.readUint16Big();
}; if (keyCount2) {
}; initTX = reader.readInt16Big();
qTX = reader.readUByte();
struct ANIM2 : IANIM initTY = reader.readInt16Big();
{ qTY = reader.readUByte();
AT_DECL_EXPLICIT_DNA initTZ = reader.readInt16Big();
AT_DECL_DNAV qTZ = reader.readUByte();
ANIM2(bool pc) : IANIM(pc ? 3 : 2) {}
struct Header : BigDNA
{
AT_DECL_DNA
Value<atUint32> scratchSize;
UniqueID32Zero evnt;
Value<atUint32> unk0 = 1;
Value<float> duration;
Value<float> interval;
Value<atUint32> rootBoneId = 3;
Value<atUint32> looping = 0;
Value<atUint32> rotDiv;
Value<float> translationMult;
Value<atUint32> boneChannelCount;
Value<atUint32> unk3;
Value<atUint32> keyBitmapBitCount;
};
struct ChannelDesc : BigDNA
{
Delete expl;
Value<atUint32> id = 0;
Value<atUint16> keyCount1 = 0;
Value<atInt16> initRX = 0;
Value<atUint8> qRX = 0;
Value<atInt16> initRY = 0;
Value<atUint8> qRY = 0;
Value<atInt16> initRZ = 0;
Value<atUint8> qRZ = 0;
Value<atUint16> keyCount2 = 0;
Value<atInt16> initTX = 0;
Value<atUint8> qTX = 0;
Value<atInt16> initTY = 0;
Value<atUint8> qTY = 0;
Value<atInt16> initTZ = 0;
Value<atUint8> qTZ = 0;
void read(athena::io::IStreamReader& reader)
{
id = reader.readUint32Big();
keyCount1 = reader.readUint16Big();
initRX = reader.readInt16Big();
qRX = reader.readUByte();
initRY = reader.readInt16Big();
qRY = reader.readUByte();
initRZ = reader.readInt16Big();
qRZ = reader.readUByte();
keyCount2 = reader.readUint16Big();
if (keyCount2)
{
initTX = reader.readInt16Big();
qTX = reader.readUByte();
initTY = reader.readInt16Big();
qTY = reader.readUByte();
initTZ = reader.readInt16Big();
qTZ = reader.readUByte();
}
}
void write(athena::io::IStreamWriter& writer) const
{
writer.writeUint32Big(id);
writer.writeUint16Big(keyCount1);
writer.writeInt16Big(initRX);
writer.writeUByte(qRX);
writer.writeInt16Big(initRY);
writer.writeUByte(qRY);
writer.writeInt16Big(initRZ);
writer.writeUByte(qRZ);
writer.writeUint16Big(keyCount2);
if (keyCount2)
{
writer.writeInt16Big(initTX);
writer.writeUByte(qTX);
writer.writeInt16Big(initTY);
writer.writeUByte(qTY);
writer.writeInt16Big(initTZ);
writer.writeUByte(qTZ);
}
}
void binarySize(size_t& __isz) const
{
__isz += 17;
if (keyCount2)
__isz += 9;
}
};
struct ChannelDescPC : BigDNA
{
Delete expl;
Value<atUint32> id = 0;
Value<atUint32> keyCount1 = 0;
Value<atUint32> QinitRX = 0;
Value<atUint32> QinitRY = 0;
Value<atUint32> QinitRZ = 0;
Value<atUint32> keyCount2 = 0;
Value<atUint32> QinitTX = 0;
Value<atUint32> QinitTY = 0;
Value<atUint32> QinitTZ = 0;
void read(athena::io::IStreamReader& reader)
{
id = reader.readUint32Big();
keyCount1 = reader.readUint32Big();
QinitRX = reader.readUint32Big();
QinitRY = reader.readUint32Big();
QinitRZ = reader.readUint32Big();
keyCount2 = reader.readUint32Big();
if (keyCount2)
{
QinitTX = reader.readUint32Big();
QinitTY = reader.readUint32Big();
QinitTZ = reader.readUint32Big();
}
}
void write(athena::io::IStreamWriter& writer) const
{
writer.writeUint32Big(id);
writer.writeUint32Big(keyCount1);
writer.writeUint32Big(QinitRX);
writer.writeUint32Big(QinitRY);
writer.writeUint32Big(QinitRZ);
writer.writeUint32Big(keyCount2);
if (keyCount2)
{
writer.writeUint32Big(QinitTX);
writer.writeUint32Big(QinitTY);
writer.writeUint32Big(QinitTZ);
}
}
void binarySize(size_t& __isz) const
{
__isz += 24;
if (keyCount2)
__isz += 12;
}
};
};
std::unique_ptr<IANIM> m_anim;
void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig, bool) const
{
m_anim->sendANIMToBlender(os, rig);
}
bool isLooping() const
{
if (!m_anim)
return false;
return m_anim->looping;
}
void extractEVNT(const DNAANCS::AnimationResInfo<UniqueID32>& animInfo,
const hecl::ProjectPath& outPath, PAKRouter<PAKBridge>& pakRouter, bool force) const
{
if (m_anim->evnt)
{
hecl::SystemStringConv sysStr(animInfo.name);
hecl::ProjectPath evntYamlPath = outPath.getWithExtension((hecl::SystemString(_SYS_STR(".")) +
sysStr.c_str() +
_SYS_STR(".evnt.yaml")).c_str(), true);
hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType();
if (force || evntYamlType == hecl::ProjectPath::Type::None)
{
EVNT evnt;
if (pakRouter.lookupAndReadDNA(m_anim->evnt, evnt, true))
{
athena::io::FileWriter writer(evntYamlPath.getAbsolutePath());
athena::io::ToYAMLStream(evnt, writer);
}
}
} }
}
void write(athena::io::IStreamWriter& writer) const {
writer.writeUint32Big(id);
writer.writeUint16Big(keyCount1);
writer.writeInt16Big(initRX);
writer.writeUByte(qRX);
writer.writeInt16Big(initRY);
writer.writeUByte(qRY);
writer.writeInt16Big(initRZ);
writer.writeUByte(qRZ);
writer.writeUint16Big(keyCount2);
if (keyCount2) {
writer.writeInt16Big(initTX);
writer.writeUByte(qTX);
writer.writeInt16Big(initTY);
writer.writeUByte(qTY);
writer.writeInt16Big(initTZ);
writer.writeUByte(qTZ);
}
}
void binarySize(size_t& __isz) const {
__isz += 17;
if (keyCount2)
__isz += 9;
}
};
struct ChannelDescPC : BigDNA {
Delete expl;
Value<atUint32> id = 0;
Value<atUint32> keyCount1 = 0;
Value<atUint32> QinitRX = 0;
Value<atUint32> QinitRY = 0;
Value<atUint32> QinitRZ = 0;
Value<atUint32> keyCount2 = 0;
Value<atUint32> QinitTX = 0;
Value<atUint32> QinitTY = 0;
Value<atUint32> QinitTZ = 0;
void read(athena::io::IStreamReader& reader) {
id = reader.readUint32Big();
keyCount1 = reader.readUint32Big();
QinitRX = reader.readUint32Big();
QinitRY = reader.readUint32Big();
QinitRZ = reader.readUint32Big();
keyCount2 = reader.readUint32Big();
if (keyCount2) {
QinitTX = reader.readUint32Big();
QinitTY = reader.readUint32Big();
QinitTZ = reader.readUint32Big();
}
}
void write(athena::io::IStreamWriter& writer) const {
writer.writeUint32Big(id);
writer.writeUint32Big(keyCount1);
writer.writeUint32Big(QinitRX);
writer.writeUint32Big(QinitRY);
writer.writeUint32Big(QinitRZ);
writer.writeUint32Big(keyCount2);
if (keyCount2) {
writer.writeUint32Big(QinitTX);
writer.writeUint32Big(QinitTY);
writer.writeUint32Big(QinitTZ);
}
}
void binarySize(size_t& __isz) const {
__isz += 24;
if (keyCount2)
__isz += 12;
}
};
};
std::unique_ptr<IANIM> m_anim;
void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig, bool) const {
m_anim->sendANIMToBlender(os, rig);
}
bool isLooping() const {
if (!m_anim)
return false;
return m_anim->looping;
}
void extractEVNT(const DNAANCS::AnimationResInfo<UniqueID32>& animInfo, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, bool force) const {
if (m_anim->evnt) {
hecl::SystemStringConv sysStr(animInfo.name);
hecl::ProjectPath evntYamlPath = outPath.getWithExtension(
(hecl::SystemString(_SYS_STR(".")) + sysStr.c_str() + _SYS_STR(".evnt.yaml")).c_str(), true);
hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType();
if (force || evntYamlType == hecl::ProjectPath::Type::None) {
EVNT evnt;
if (pakRouter.lookupAndReadDNA(m_anim->evnt, evnt, true)) {
athena::io::FileWriter writer(evntYamlPath.getAbsolutePath());
athena::io::ToYAMLStream(evnt, writer);
}
}
} }
}
using BlenderAction = hecl::blender::Action; using BlenderAction = hecl::blender::Action;
ANIM() = default; ANIM() = default;
ANIM(const BlenderAction& act, ANIM(const BlenderAction& act, const std::unordered_map<std::string, atInt32>& idMap,
const std::unordered_map<std::string, atInt32>& idMap, const DNAANIM::RigInverter<CINF>& rig, bool pc);
const DNAANIM::RigInverter<CINF>& rig,
bool pc);
}; };
} } // namespace DataSpec::DNAMP1

View File

@ -1,184 +1,160 @@
#include "CINF.hpp" #include "CINF.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const {
{ atUint32 idx = 0;
atUint32 idx = 0; for (const Bone& b : bones) {
for (const Bone& b : bones) if (b.id == id)
{ return idx;
if (b.id == id) ++idx;
return idx; }
++idx; return -1;
}
atUint32 CINF::getBoneIdxFromId(atUint32 id) const {
atUint32 idx = 0;
for (atUint32 bid : boneIds) {
if (bid == id)
return idx;
++idx;
}
return 0;
}
const std::string* CINF::getBoneNameFromId(atUint32 id) const {
for (const Name& name : names)
if (id == name.boneId)
return &name.name;
return nullptr;
}
void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const {
for (atUint32 bid : boneIds) {
for (const Name& name : names) {
if (name.boneId == bid) {
os.format("obj.vertex_groups.new('%s')\n", name.name.c_str());
break;
}
} }
return -1; }
} }
atUint32 CINF::getBoneIdxFromId(atUint32 id) const void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const {
{ DNAANIM::RigInverter<CINF> inverter(*this);
atUint32 idx = 0;
for (atUint32 bid : boneIds) os.format(
{ "arm = bpy.data.armatures.new('CINF_%08X')\n"
if (bid == id) "arm_obj = bpy.data.objects.new(arm.name, arm)\n"
return idx; "bpy.context.scene.objects.link(arm_obj)\n"
++idx; "bpy.context.scene.objects.active = arm_obj\n"
} "bpy.ops.object.mode_set(mode='EDIT')\n"
return 0; "arm_bone_table = {}\n",
cinfId.toUint32());
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones()) {
zeus::simd_floats originF(bone.m_origBone.origin.simd);
zeus::simd_floats tailF(bone.m_tail.mSimd);
os.format(
"bone = arm.edit_bones.new('%s')\n"
"bone.head = (%f,%f,%f)\n"
"bone.tail = (%f,%f,%f)\n"
"bone.use_inherit_scale = False\n"
"arm_bone_table[%u] = bone\n",
getBoneNameFromId(bone.m_origBone.id)->c_str(), originF[0], originF[1], originF[2], tailF[0], tailF[1],
tailF[2], bone.m_origBone.id);
}
for (const Bone& bone : bones)
if (bone.parentId != 2)
os.format("arm_bone_table[%u].parent = arm_bone_table[%u]\n", bone.id, bone.parentId);
os << "bpy.ops.object.mode_set(mode='OBJECT')\n";
const char* rotMode = os.getConnection().hasSLERP() ? "QUATERNION_SLERP" : "QUATERNION";
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
os.format("arm_obj.pose.bones['%s'].rotation_mode = '%s'\n", getBoneNameFromId(bone.m_origBone.id)->c_str(),
rotMode);
} }
const std::string* CINF::getBoneNameFromId(atUint32 id) const std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId) { return hecl::Format("CINF_%08X", cinfId.toUint32()); }
{
for (const Name& name : names)
if (id == name.boneId)
return &name.name;
return nullptr;
}
void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const
{
for (atUint32 bid : boneIds)
{
for (const Name& name : names)
{
if (name.boneId == bid)
{
os.format("obj.vertex_groups.new('%s')\n", name.name.c_str());
break;
}
}
}
}
void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const
{
DNAANIM::RigInverter<CINF> inverter(*this);
os.format("arm = bpy.data.armatures.new('CINF_%08X')\n"
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
"bpy.context.scene.objects.link(arm_obj)\n"
"bpy.context.scene.objects.active = arm_obj\n"
"bpy.ops.object.mode_set(mode='EDIT')\n"
"arm_bone_table = {}\n",
cinfId.toUint32());
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
{
zeus::simd_floats originF(bone.m_origBone.origin.simd);
zeus::simd_floats tailF(bone.m_tail.mSimd);
os.format("bone = arm.edit_bones.new('%s')\n"
"bone.head = (%f,%f,%f)\n"
"bone.tail = (%f,%f,%f)\n"
"bone.use_inherit_scale = False\n"
"arm_bone_table[%u] = bone\n",
getBoneNameFromId(bone.m_origBone.id)->c_str(),
originF[0], originF[1], originF[2],
tailF[0], tailF[1], tailF[2],
bone.m_origBone.id);
}
for (const Bone& bone : bones)
if (bone.parentId != 2)
os.format("arm_bone_table[%u].parent = arm_bone_table[%u]\n", bone.id, bone.parentId);
os << "bpy.ops.object.mode_set(mode='OBJECT')\n";
const char* rotMode = os.getConnection().hasSLERP() ? "QUATERNION_SLERP" : "QUATERNION";
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
os.format("arm_obj.pose.bones['%s'].rotation_mode = '%s'\n",
getBoneNameFromId(bone.m_origBone.id)->c_str(), rotMode);
}
std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId)
{
return hecl::Format("CINF_%08X", cinfId.toUint32());
}
int CINF::RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, int CINF::RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId,
std::unordered_map<std::string, atInt32>& idMap, std::map<std::string, int>& nameMap) std::unordered_map<std::string, atInt32>& idMap,
{ std::map<std::string, int>& nameMap) {
int selId; int selId;
auto search = idMap.find(bone->name); auto search = idMap.find(bone->name);
if (search == idMap.end()) if (search == idMap.end()) {
{ selId = curId++;
selId = curId++; idMap.emplace(std::make_pair(bone->name, selId));
idMap.emplace(std::make_pair(bone->name, selId)); } else
selId = search->second;
bones.emplace_back();
Bone& boneOut = bones.back();
nameMap[bone->name] = selId;
boneOut.id = selId;
boneOut.parentId = parent;
boneOut.origin = bone->origin;
boneOut.linkedCount = bone->children.size() + 1;
boneOut.linked.reserve(boneOut.linkedCount);
const BlenderBone* child;
boneOut.linked.push_back(parent);
for (size_t i = 0; (child = armature.getChild(bone, i)); ++i)
boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, curId, idMap, nameMap));
return boneOut.id;
}
CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& idMap) {
idMap.reserve(armature.bones.size());
bones.reserve(armature.bones.size());
std::map<std::string, int> nameMap;
const BlenderBone* bone = armature.getRoot();
if (bone) {
if (bone->children.size()) {
int curId = 4;
const BlenderBone* child;
for (size_t i = 0; (child = armature.getChild(bone, i)); ++i)
RecursiveAddArmatureBone(armature, child, 3, curId, idMap, nameMap);
} }
else
selId = search->second;
bones.emplace_back(); bones.emplace_back();
Bone& boneOut = bones.back(); Bone& boneOut = bones.back();
nameMap[bone->name] = selId; nameMap[bone->name] = 3;
boneOut.id = selId; boneOut.id = 3;
boneOut.parentId = parent; boneOut.parentId = 2;
boneOut.origin = bone->origin; boneOut.origin = bone->origin;
boneOut.linkedCount = bone->children.size() + 1; idMap.emplace(std::make_pair(bone->name, 3));
boneOut.linked.reserve(boneOut.linkedCount);
const BlenderBone* child; if (bone->children.size()) {
boneOut.linked.push_back(parent); boneOut.linkedCount = 2;
for (size_t i=0 ; (child = armature.getChild(bone, i)) ; ++i) boneOut.linked = {2, 4};
boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, curId, idMap, nameMap)); } else {
boneOut.linkedCount = 1;
return boneOut.id; boneOut.linked = {2};
}
CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& idMap)
{
idMap.reserve(armature.bones.size());
bones.reserve(armature.bones.size());
std::map<std::string, int> nameMap;
const BlenderBone* bone = armature.getRoot();
if (bone)
{
if (bone->children.size())
{
int curId = 4;
const BlenderBone* child;
for (size_t i=0 ; (child = armature.getChild(bone, i)) ; ++i)
RecursiveAddArmatureBone(armature, child, 3, curId, idMap, nameMap);
}
bones.emplace_back();
Bone& boneOut = bones.back();
nameMap[bone->name] = 3;
boneOut.id = 3;
boneOut.parentId = 2;
boneOut.origin = bone->origin;
idMap.emplace(std::make_pair(bone->name, 3));
if (bone->children.size())
{
boneOut.linkedCount = 2;
boneOut.linked = {2, 4};
}
else
{
boneOut.linkedCount = 1;
boneOut.linked = {2};
}
} }
}
boneCount = bones.size(); boneCount = bones.size();
names.reserve(nameMap.size()); names.reserve(nameMap.size());
nameCount = nameMap.size(); nameCount = nameMap.size();
for (const auto& name : nameMap) for (const auto& name : nameMap) {
{ names.emplace_back();
names.emplace_back(); Name& nameOut = names.back();
Name& nameOut = names.back(); nameOut.name = name.first;
nameOut.name = name.first; nameOut.boneId = name.second;
nameOut.boneId = name.second; }
}
boneIdCount = boneCount; boneIdCount = boneCount;
boneIds.reserve(boneIdCount); boneIds.reserve(boneIdCount);
for (auto it=bones.crbegin() ; it != bones.crend() ; ++it) for (auto it = bones.crbegin(); it != bones.crend(); ++it)
boneIds.push_back(it->id); boneIds.push_back(it->id);
} }
} } // namespace DataSpec::DNAMP1

View File

@ -3,52 +3,47 @@
#include "DataSpec/DNACommon/DNACommon.hpp" #include "DataSpec/DNACommon/DNACommon.hpp"
#include "DataSpec/DNACommon/RigInverter.hpp" #include "DataSpec/DNACommon/RigInverter.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
struct CINF : BigDNA struct CINF : BigDNA {
{ AT_DECL_DNA
Value<atUint32> boneCount;
struct Bone : BigDNA {
AT_DECL_DNA AT_DECL_DNA
Value<atUint32> boneCount; Value<atUint32> id;
struct Bone : BigDNA Value<atUint32> parentId;
{ Value<atVec3f> origin;
AT_DECL_DNA Value<atUint32> linkedCount;
Value<atUint32> id; Vector<atUint32, AT_DNA_COUNT(linkedCount)> linked;
Value<atUint32> parentId; };
Value<atVec3f> origin; Vector<Bone, AT_DNA_COUNT(boneCount)> bones;
Value<atUint32> linkedCount;
Vector<atUint32, AT_DNA_COUNT(linkedCount)> linked;
};
Vector<Bone, AT_DNA_COUNT(boneCount)> bones;
Value<atUint32> boneIdCount; Value<atUint32> boneIdCount;
Vector<atUint32, AT_DNA_COUNT(boneIdCount)> boneIds; Vector<atUint32, AT_DNA_COUNT(boneIdCount)> boneIds;
Value<atUint32> nameCount; Value<atUint32> nameCount;
struct Name : BigDNA struct Name : BigDNA {
{ AT_DECL_DNA
AT_DECL_DNA String<-1> name;
String<-1> name; Value<atUint32> boneId;
Value<atUint32> boneId; };
}; Vector<Name, AT_DNA_COUNT(nameCount)> names;
Vector<Name, AT_DNA_COUNT(nameCount)> names;
atUint32 getInternalBoneIdxFromId(atUint32 id) const; atUint32 getInternalBoneIdxFromId(atUint32 id) const;
atUint32 getBoneIdxFromId(atUint32 id) const; atUint32 getBoneIdxFromId(atUint32 id) const;
const std::string* getBoneNameFromId(atUint32 id) const; const std::string* getBoneNameFromId(atUint32 id) const;
void sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const; void sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const;
void sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const; void sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const;
static std::string GetCINFArmatureName(const UniqueID32& cinfId); static std::string GetCINFArmatureName(const UniqueID32& cinfId);
CINF() = default; CINF() = default;
using Armature = hecl::blender::Armature; using Armature = hecl::blender::Armature;
using BlenderBone = hecl::blender::Bone; using BlenderBone = hecl::blender::Bone;
int RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, int RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId,
std::unordered_map<std::string, atInt32>& idMap, std::map<std::string, int>& nameMap); std::unordered_map<std::string, atInt32>& idMap, std::map<std::string, int>& nameMap);
CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& idMap); CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& idMap);
}; };
} } // namespace DataSpec::DNAMP1

View File

@ -1,38 +1,30 @@
#include "CMDL.hpp" #include "CMDL.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
bool CMDL::Extract(const SpecBase& dataSpec, bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKEntryReadStream& rs, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged) {
PAKRouter<PAKBridge>& pakRouter, /* Check for RigPair */
const PAK::Entry& entry, const typename CharacterAssociations<UniqueID32>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
bool force, CINF cinf;
hecl::blender::Token& btok, CSKR cskr;
std::function<void(const hecl::SystemChar*)> fileChanged) std::pair<CSKR*, CINF*> loadRp(nullptr, nullptr);
{ if (rp) {
/* Check for RigPair */ pakRouter.lookupAndReadDNA(rp->first, cskr);
const typename CharacterAssociations<UniqueID32>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id); pakRouter.lookupAndReadDNA(rp->second, cinf);
CINF cinf; loadRp.first = &cskr;
CSKR cskr; loadRp.second = &cinf;
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 */ /* Do extract */
hecl::blender::Connection& conn = btok.getBlenderConnection(); hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_1, 2> DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*, CINF*>, DNACMDL::SurfaceHeader_1, 2>(
(conn, rs, pakRouter, entry, dataSpec, loadRp); conn, rs, pakRouter, entry, dataSpec, loadRp);
conn.saveBlend(); conn.saveBlend();
#if 0 #if 0
/* Cook and re-extract test */ /* Cook and re-extract test */
@ -50,98 +42,82 @@ bool CMDL::Extract(const SpecBase& dataSpec,
(conn, reader, pakRouter, entry, dataSpec, loadRp); (conn, reader, pakRouter, entry, dataSpec, loadRp);
return conn.saveBlend(); return conn.saveBlend();
#elif 0 #elif 0
/* HMDL cook test */ /* HMDL cook test */
hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true); hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true);
hecl::blender::Connection::DataStream ds = conn.beginData(); hecl::blender::Connection::DataStream ds = conn.beginData();
DNACMDL::Mesh mesh = ds.compileMesh(hecl::HMDLTopology::TriStrips, 16); DNACMDL::Mesh mesh = ds.compileMesh(hecl::HMDLTopology::TriStrips, 16);
ds.close(); ds.close();
DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_1, 2>(tempOut, outPath, mesh); DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_1, 2>(tempOut, outPath, mesh);
#endif #endif
return true; return true;
} }
bool CMDL::Cook(const hecl::ProjectPath& outPath, bool CMDL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh) {
const hecl::ProjectPath& inPath, if (!mesh.skins.empty()) {
const DNACMDL::Mesh& mesh) DNACMDL::Mesh skinMesh = mesh.getContiguousSkinningVersion();
{ if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, skinMesh))
if (!mesh.skins.empty()) return false;
{
DNACMDL::Mesh skinMesh = mesh.getContiguousSkinningVersion();
if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, skinMesh))
return false;
/* Output skinning intermediate */ /* Output skinning intermediate */
auto vertCountIt = skinMesh.contiguousSkinVertCounts.cbegin(); auto vertCountIt = skinMesh.contiguousSkinVertCounts.cbegin();
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath()); athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath());
writer.writeUint32Big(skinMesh.boneNames.size()); writer.writeUint32Big(skinMesh.boneNames.size());
for (const std::string& boneName : skinMesh.boneNames) for (const std::string& boneName : skinMesh.boneNames)
writer.writeString(boneName); writer.writeString(boneName);
writer.writeUint32Big(skinMesh.skins.size()); writer.writeUint32Big(skinMesh.skins.size());
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins) for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins) {
{ writer.writeUint32Big(skin.size());
writer.writeUint32Big(skin.size()); for (const DNACMDL::Mesh::SkinBind& bind : skin) {
for (const DNACMDL::Mesh::SkinBind& bind : skin) writer.writeUint32Big(bind.boneIdx);
{ writer.writeFloatBig(bind.weight);
writer.writeUint32Big(bind.boneIdx); }
writer.writeFloatBig(bind.weight); writer.writeUint32Big(*vertCountIt++);
}
writer.writeUint32Big(*vertCountIt++);
}
writer.writeUint32Big(skinMesh.pos.size());
writer.writeUint32Big(skinMesh.norm.size());
} }
else if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, mesh)) writer.writeUint32Big(skinMesh.pos.size());
return false; writer.writeUint32Big(skinMesh.norm.size());
return true; } else if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, mesh))
return false;
return true;
} }
bool CMDL::HMDLCook(const hecl::ProjectPath& outPath, bool CMDL::HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh) {
const hecl::ProjectPath& inPath, hecl::blender::PoolSkinIndex poolSkinIndex;
const DNACMDL::Mesh& mesh) if (mesh.skins.size()) {
{ if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(outPath, inPath, mesh, poolSkinIndex))
hecl::blender::PoolSkinIndex poolSkinIndex; return false;
if (mesh.skins.size())
{
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(
outPath, inPath, mesh, poolSkinIndex))
return false;
/* Output skinning intermediate */ /* Output skinning intermediate */
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath()); athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath());
writer.writeUint32Big(mesh.skinBanks.banks.size()); writer.writeUint32Big(mesh.skinBanks.banks.size());
for (const DNACMDL::Mesh::SkinBanks::Bank& sb : mesh.skinBanks.banks) for (const DNACMDL::Mesh::SkinBanks::Bank& sb : mesh.skinBanks.banks) {
{ writer.writeUint32Big(sb.m_boneIdxs.size());
writer.writeUint32Big(sb.m_boneIdxs.size()); for (uint32_t bind : sb.m_boneIdxs)
for (uint32_t bind : sb.m_boneIdxs) writer.writeUint32Big(bind);
writer.writeUint32Big(bind);
}
writer.writeUint32Big(mesh.boneNames.size());
for (const std::string& boneName : mesh.boneNames)
writer.writeString(boneName);
/* CVirtualBone structure just like original (for CPU skinning) */
writer.writeUint32Big(mesh.skins.size());
for (auto& s : mesh.skins)
{
writer.writeUint32Big(s.size());
for (auto& b : s)
{
writer.writeUint32Big(b.boneIdx);
writer.writeFloatBig(b.weight);
}
}
/* Write indirection table mapping pool verts to CVirtualBones */
writer.writeUint32Big(poolSkinIndex.m_poolSz);
for (uint32_t i=0 ; i<poolSkinIndex.m_poolSz ; ++i)
writer.writeUint32Big(poolSkinIndex.m_poolToSkinIndex[i]);
} }
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>( writer.writeUint32Big(mesh.boneNames.size());
outPath, inPath, mesh, poolSkinIndex)) for (const std::string& boneName : mesh.boneNames)
return false; writer.writeString(boneName);
return true;
/* CVirtualBone structure just like original (for CPU skinning) */
writer.writeUint32Big(mesh.skins.size());
for (auto& s : mesh.skins) {
writer.writeUint32Big(s.size());
for (auto& b : s) {
writer.writeUint32Big(b.boneIdx);
writer.writeFloatBig(b.weight);
}
}
/* Write indirection table mapping pool verts to CVirtualBones */
writer.writeUint32Big(poolSkinIndex.m_poolSz);
for (uint32_t i = 0; i < poolSkinIndex.m_poolSz; ++i)
writer.writeUint32Big(poolSkinIndex.m_poolToSkinIndex[i]);
} else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(outPath, inPath, mesh,
poolSkinIndex))
return false;
return true;
} }
} } // namespace DataSpec::DNAMP1

View File

@ -9,36 +9,21 @@
#include <athena/FileReader.hpp> #include <athena/FileReader.hpp>
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
struct CMDL struct CMDL {
{ static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
static bool Extract(const SpecBase& dataSpec, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
PAKEntryReadStream& rs, std::function<void(const hecl::SystemChar*)> fileChanged);
const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry,
bool force,
hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
static void Name(const SpecBase& dataSpec, static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter<PAKBridge>& pakRouter,
PAKEntryReadStream& rs, PAK::Entry& entry) {
PAKRouter<PAKBridge>& pakRouter, DNACMDL::NameCMDL<PAKRouter<PAKBridge>, MaterialSet>(rs, pakRouter, entry, dataSpec);
PAK::Entry& entry) }
{
DNACMDL::NameCMDL<PAKRouter<PAKBridge>, MaterialSet>(rs, pakRouter, entry, dataSpec);
}
static bool Cook(const hecl::ProjectPath& outPath, static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh);
const hecl::ProjectPath& inPath,
const DNACMDL::Mesh& mesh);
static bool HMDLCook(const hecl::ProjectPath& outPath, static bool HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh);
const hecl::ProjectPath& inPath,
const DNACMDL::Mesh& mesh);
}; };
} } // namespace DataSpec::DNAMP1

File diff suppressed because it is too large Load Diff

View File

@ -5,411 +5,551 @@
#include "DataSpec/DNACommon/CMDL.hpp" #include "DataSpec/DNACommon/CMDL.hpp"
#include "DNAMP1.hpp" #include "DNAMP1.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
struct MaterialSet : BigDNA struct MaterialSet : BigDNA {
{ static constexpr bool OneSection() { return false; }
static constexpr bool OneSection() {return false;}
AT_DECL_DNA
struct MaterialSetHead : BigDNA {
AT_DECL_DNA AT_DECL_DNA
struct MaterialSetHead : BigDNA Value<atUint32> textureCount = 0;
{ Vector<UniqueID32, AT_DNA_COUNT(textureCount)> textureIDs;
AT_DECL_DNA Value<atUint32> materialCount = 0;
Value<atUint32> textureCount = 0; Vector<atUint32, AT_DNA_COUNT(materialCount)> materialEndOffs;
Vector<UniqueID32, AT_DNA_COUNT(textureCount)> textureIDs;
Value<atUint32> materialCount = 0;
Vector<atUint32, AT_DNA_COUNT(materialCount)> materialEndOffs;
void addTexture(const UniqueID32& id) {textureIDs.push_back(id); ++textureCount;} void addTexture(const UniqueID32& id) {
void addMaterialEndOff(atUint32 off) {materialEndOffs.push_back(off); ++materialCount;} textureIDs.push_back(id);
++textureCount;
}
void addMaterialEndOff(atUint32 off) {
materialEndOffs.push_back(off);
++materialCount;
}
template <class PAKBRIDGE> template <class PAKBRIDGE>
void ensureTexturesExtracted(PAKRouter<PAKBRIDGE>& pakRouter) const void ensureTexturesExtracted(PAKRouter<PAKBRIDGE>& pakRouter) const {
{ for (const auto& id : textureIDs) {
for (const auto& id : textureIDs) const nod::Node* node;
{ const PAK::Entry* texEntry = pakRouter.lookupEntry(id, &node);
const nod::Node* node; if (!texEntry)
const PAK::Entry* texEntry = pakRouter.lookupEntry(id, &node); continue;
if (!texEntry) hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
continue; if (txtrPath.isNone()) {
hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); txtrPath.makeDirChain(false);
if (txtrPath.isNone()) PAKEntryReadStream rs = texEntry->beginReadStream(*node);
{ TXTR::Extract(rs, txtrPath);
txtrPath.makeDirChain(false);
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath);
}
}
} }
} head; }
}
} head;
struct Material : BigDNA struct Material : BigDNA {
{ AT_DECL_DNA
AT_DECL_DNA struct Flags : BigDNA {
struct Flags : BigDNA AT_DECL_DNA
{ Value<atUint32> flags = 0;
AT_DECL_DNA bool konstValuesEnabled() const { return (flags & 0x8) != 0; }
Value<atUint32> flags = 0; void setKonstValuesEnabled(bool enabled) {
bool konstValuesEnabled() const {return (flags & 0x8) != 0;} flags &= ~0x8;
void setKonstValuesEnabled(bool enabled) {flags &= ~0x8; flags |= atUint32(enabled) << 3;} flags |= atUint32(enabled) << 3;
bool depthSorting() const {return (flags & 0x10) != 0;} }
void setDepthSorting(bool enabled) {flags &= ~0x10; flags |= atUint32(enabled) << 4;} bool depthSorting() const { return (flags & 0x10) != 0; }
bool alphaTest() const {return (flags & 0x20) != 0;} void setDepthSorting(bool enabled) {
void setPunchthroughAlpha(bool enabled) {flags &= ~0x20; flags |= atUint32(enabled) << 5;} flags &= ~0x10;
bool samusReflection() const {return (flags & 0x40) != 0;} flags |= atUint32(enabled) << 4;
void setSamusReflection(bool enabled) {flags &= ~0x40; flags |= atUint32(enabled) << 6;} }
bool depthWrite() const {return (flags & 0x80) != 0;} bool alphaTest() const { return (flags & 0x20) != 0; }
void setDepthWrite(bool enabled) {flags &= ~0x80; flags |= atUint32(enabled) << 7;} void setPunchthroughAlpha(bool enabled) {
bool samusReflectionSurfaceEye() const {return (flags & 0x100) != 0;} flags &= ~0x20;
void setSamusReflectionSurfaceEye(bool enabled) {flags &= ~0x100; flags |= atUint32(enabled) << 8;} flags |= atUint32(enabled) << 5;
bool shadowOccluderMesh() const {return (flags & 0x200) != 0;} }
void setShadowOccluderMesh(bool enabled) {flags &= ~0x200; flags |= atUint32(enabled) << 9;} bool samusReflection() const { return (flags & 0x40) != 0; }
bool samusReflectionIndirectTexture() const {return (flags & 0x400) != 0;} void setSamusReflection(bool enabled) {
void setSamusReflectionIndirectTexture(bool enabled) {flags &= ~0x400; flags |= atUint32(enabled) << 10;} flags &= ~0x40;
bool lightmap() const {return (flags & 0x800) != 0;} flags |= atUint32(enabled) << 6;
void setLightmap(bool enabled) {flags &= ~0x800; flags |= atUint32(enabled) << 11;} }
bool lightmapUVArray() const {return (flags & 0x2000) != 0;} bool depthWrite() const { return (flags & 0x80) != 0; }
void setLightmapUVArray(bool enabled) {flags &= ~0x2000; flags |= atUint32(enabled) << 13;} void setDepthWrite(bool enabled) {
atUint16 textureSlots() const {return (flags >> 16) != 0;} flags &= ~0x80;
void setTextureSlots(atUint16 texslots) {flags &= ~0xffff0000; flags |= atUint32(texslots) << 16;} flags |= atUint32(enabled) << 7;
} flags; }
const Flags& getFlags() const {return flags;} bool samusReflectionSurfaceEye() const { return (flags & 0x100) != 0; }
void setSamusReflectionSurfaceEye(bool enabled) {
flags &= ~0x100;
flags |= atUint32(enabled) << 8;
}
bool shadowOccluderMesh() const { return (flags & 0x200) != 0; }
void setShadowOccluderMesh(bool enabled) {
flags &= ~0x200;
flags |= atUint32(enabled) << 9;
}
bool samusReflectionIndirectTexture() const { return (flags & 0x400) != 0; }
void setSamusReflectionIndirectTexture(bool enabled) {
flags &= ~0x400;
flags |= atUint32(enabled) << 10;
}
bool lightmap() const { return (flags & 0x800) != 0; }
void setLightmap(bool enabled) {
flags &= ~0x800;
flags |= atUint32(enabled) << 11;
}
bool lightmapUVArray() const { return (flags & 0x2000) != 0; }
void setLightmapUVArray(bool enabled) {
flags &= ~0x2000;
flags |= atUint32(enabled) << 13;
}
atUint16 textureSlots() const { return (flags >> 16) != 0; }
void setTextureSlots(atUint16 texslots) {
flags &= ~0xffff0000;
flags |= atUint32(texslots) << 16;
}
} flags;
const Flags& getFlags() const { return flags; }
Value<atUint32> textureCount = 0; Value<atUint32> textureCount = 0;
Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs; Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
struct VAFlags : BigDNA struct VAFlags : BigDNA {
{ AT_DECL_DNA
AT_DECL_DNA Value<atUint32> vaFlags = 0;
Value<atUint32> vaFlags = 0; GX::AttrType position() const { return GX::AttrType(vaFlags & 0x3); }
GX::AttrType position() const {return GX::AttrType(vaFlags & 0x3);} void setPosition(GX::AttrType val) {
void setPosition(GX::AttrType val) {vaFlags &= ~0x3; vaFlags |= atUint32(val);} vaFlags &= ~0x3;
GX::AttrType normal() const {return GX::AttrType(vaFlags >> 2 & 0x3);} vaFlags |= atUint32(val);
void setNormal(GX::AttrType val) {vaFlags &= ~0xC; vaFlags |= atUint32(val) << 2;} }
GX::AttrType color0() const {return GX::AttrType(vaFlags >> 4 & 0x3);} GX::AttrType normal() const { return GX::AttrType(vaFlags >> 2 & 0x3); }
void setColor0(GX::AttrType val) {vaFlags &= ~0x30; vaFlags |= atUint32(val) << 4;} void setNormal(GX::AttrType val) {
GX::AttrType color1() const {return GX::AttrType(vaFlags >> 6 & 0x3);} vaFlags &= ~0xC;
void setColor1(GX::AttrType val) {vaFlags &= ~0xC0; vaFlags |= atUint32(val) << 6;} vaFlags |= atUint32(val) << 2;
GX::AttrType tex0() const {return GX::AttrType(vaFlags >> 8 & 0x3);} }
void setTex0(GX::AttrType val) {vaFlags &= ~0x300; vaFlags |= atUint32(val) << 8;} GX::AttrType color0() const { return GX::AttrType(vaFlags >> 4 & 0x3); }
GX::AttrType tex1() const {return GX::AttrType(vaFlags >> 10 & 0x3);} void setColor0(GX::AttrType val) {
void setTex1(GX::AttrType val) {vaFlags &= ~0xC00; vaFlags |= atUint32(val) << 10;} vaFlags &= ~0x30;
GX::AttrType tex2() const {return GX::AttrType(vaFlags >> 12 & 0x3);} vaFlags |= atUint32(val) << 4;
void setTex2(GX::AttrType val) {vaFlags &= ~0x3000; vaFlags |= atUint32(val) << 12;} }
GX::AttrType tex3() const {return GX::AttrType(vaFlags >> 14 & 0x3);} GX::AttrType color1() const { return GX::AttrType(vaFlags >> 6 & 0x3); }
void setTex3(GX::AttrType val) {vaFlags &= ~0xC000; vaFlags |= atUint32(val) << 14;} void setColor1(GX::AttrType val) {
GX::AttrType tex4() const {return GX::AttrType(vaFlags >> 16 & 0x3);} vaFlags &= ~0xC0;
void setTex4(GX::AttrType val) {vaFlags &= ~0x30000; vaFlags |= atUint32(val) << 16;} vaFlags |= atUint32(val) << 6;
GX::AttrType tex5() const {return GX::AttrType(vaFlags >> 18 & 0x3);} }
void setTex5(GX::AttrType val) {vaFlags &= ~0xC0000; vaFlags |= atUint32(val) << 18;} GX::AttrType tex0() const { return GX::AttrType(vaFlags >> 8 & 0x3); }
GX::AttrType tex6() const {return GX::AttrType(vaFlags >> 20 & 0x3);} void setTex0(GX::AttrType val) {
void setTex6(GX::AttrType val) {vaFlags &= ~0x300000; vaFlags |= atUint32(val) << 20;} vaFlags &= ~0x300;
GX::AttrType pnMatIdx() const {return GX::AttrType(vaFlags >> 24 & 0x1);} vaFlags |= atUint32(val) << 8;
void setPnMatIdx(GX::AttrType val) {vaFlags &= ~0x1000000; vaFlags |= atUint32(val & 0x1) << 24;} }
GX::AttrType tex0MatIdx() const {return GX::AttrType(vaFlags >> 25 & 0x1);} GX::AttrType tex1() const { return GX::AttrType(vaFlags >> 10 & 0x3); }
void setTex0MatIdx(GX::AttrType val) {vaFlags &= ~0x2000000; vaFlags |= atUint32(val & 0x1) << 25;} void setTex1(GX::AttrType val) {
GX::AttrType tex1MatIdx() const {return GX::AttrType(vaFlags >> 26 & 0x1);} vaFlags &= ~0xC00;
void setTex1MatIdx(GX::AttrType val) {vaFlags &= ~0x4000000; vaFlags |= atUint32(val & 0x1) << 26;} vaFlags |= atUint32(val) << 10;
GX::AttrType tex2MatIdx() const {return GX::AttrType(vaFlags >> 27 & 0x1);} }
void setTex2MatIdx(GX::AttrType val) {vaFlags &= ~0x8000000; vaFlags |= atUint32(val & 0x1) << 27;} GX::AttrType tex2() const { return GX::AttrType(vaFlags >> 12 & 0x3); }
GX::AttrType tex3MatIdx() const {return GX::AttrType(vaFlags >> 28 & 0x1);} void setTex2(GX::AttrType val) {
void setTex3MatIdx(GX::AttrType val) {vaFlags &= ~0x10000000; vaFlags |= atUint32(val & 0x1) << 28;} vaFlags &= ~0x3000;
GX::AttrType tex4MatIdx() const {return GX::AttrType(vaFlags >> 29 & 0x1);} vaFlags |= atUint32(val) << 12;
void setTex4MatIdx(GX::AttrType val) {vaFlags &= ~0x20000000; vaFlags |= atUint32(val & 0x1) << 29;} }
GX::AttrType tex5MatIdx() const {return GX::AttrType(vaFlags >> 30 & 0x1);} GX::AttrType tex3() const { return GX::AttrType(vaFlags >> 14 & 0x3); }
void setTex5MatIdx(GX::AttrType val) {vaFlags &= ~0x40000000; vaFlags |= atUint32(val & 0x1) << 30;} void setTex3(GX::AttrType val) {
GX::AttrType tex6MatIdx() const {return GX::AttrType(vaFlags >> 31 & 0x1);} vaFlags &= ~0xC000;
void setTex6MatIdx(GX::AttrType val) {vaFlags &= ~0x80000000; vaFlags |= atUint32(val & 0x1) << 31;} vaFlags |= atUint32(val) << 14;
}
GX::AttrType tex4() const { return GX::AttrType(vaFlags >> 16 & 0x3); }
void setTex4(GX::AttrType val) {
vaFlags &= ~0x30000;
vaFlags |= atUint32(val) << 16;
}
GX::AttrType tex5() const { return GX::AttrType(vaFlags >> 18 & 0x3); }
void setTex5(GX::AttrType val) {
vaFlags &= ~0xC0000;
vaFlags |= atUint32(val) << 18;
}
GX::AttrType tex6() const { return GX::AttrType(vaFlags >> 20 & 0x3); }
void setTex6(GX::AttrType val) {
vaFlags &= ~0x300000;
vaFlags |= atUint32(val) << 20;
}
GX::AttrType pnMatIdx() const { return GX::AttrType(vaFlags >> 24 & 0x1); }
void setPnMatIdx(GX::AttrType val) {
vaFlags &= ~0x1000000;
vaFlags |= atUint32(val & 0x1) << 24;
}
GX::AttrType tex0MatIdx() const { return GX::AttrType(vaFlags >> 25 & 0x1); }
void setTex0MatIdx(GX::AttrType val) {
vaFlags &= ~0x2000000;
vaFlags |= atUint32(val & 0x1) << 25;
}
GX::AttrType tex1MatIdx() const { return GX::AttrType(vaFlags >> 26 & 0x1); }
void setTex1MatIdx(GX::AttrType val) {
vaFlags &= ~0x4000000;
vaFlags |= atUint32(val & 0x1) << 26;
}
GX::AttrType tex2MatIdx() const { return GX::AttrType(vaFlags >> 27 & 0x1); }
void setTex2MatIdx(GX::AttrType val) {
vaFlags &= ~0x8000000;
vaFlags |= atUint32(val & 0x1) << 27;
}
GX::AttrType tex3MatIdx() const { return GX::AttrType(vaFlags >> 28 & 0x1); }
void setTex3MatIdx(GX::AttrType val) {
vaFlags &= ~0x10000000;
vaFlags |= atUint32(val & 0x1) << 28;
}
GX::AttrType tex4MatIdx() const { return GX::AttrType(vaFlags >> 29 & 0x1); }
void setTex4MatIdx(GX::AttrType val) {
vaFlags &= ~0x20000000;
vaFlags |= atUint32(val & 0x1) << 29;
}
GX::AttrType tex5MatIdx() const { return GX::AttrType(vaFlags >> 30 & 0x1); }
void setTex5MatIdx(GX::AttrType val) {
vaFlags &= ~0x40000000;
vaFlags |= atUint32(val & 0x1) << 30;
}
GX::AttrType tex6MatIdx() const { return GX::AttrType(vaFlags >> 31 & 0x1); }
void setTex6MatIdx(GX::AttrType val) {
vaFlags &= ~0x80000000;
vaFlags |= atUint32(val & 0x1) << 31;
}
size_t vertDLSize() const size_t vertDLSize() const {
{ static size_t ATTR_SZ[] = {0, 1, 1, 2};
static size_t ATTR_SZ[] = {0,1,1,2}; size_t ret = 0;
size_t ret = 0; ret += ATTR_SZ[position()];
ret += ATTR_SZ[position()]; ret += ATTR_SZ[normal()];
ret += ATTR_SZ[normal()]; ret += ATTR_SZ[color0()];
ret += ATTR_SZ[color0()]; ret += ATTR_SZ[color1()];
ret += ATTR_SZ[color1()]; ret += ATTR_SZ[tex0()];
ret += ATTR_SZ[tex0()]; ret += ATTR_SZ[tex1()];
ret += ATTR_SZ[tex1()]; ret += ATTR_SZ[tex2()];
ret += ATTR_SZ[tex2()]; ret += ATTR_SZ[tex3()];
ret += ATTR_SZ[tex3()]; ret += ATTR_SZ[tex4()];
ret += ATTR_SZ[tex4()]; ret += ATTR_SZ[tex5()];
ret += ATTR_SZ[tex5()]; ret += ATTR_SZ[tex6()];
ret += ATTR_SZ[tex6()]; ret += ATTR_SZ[pnMatIdx()];
ret += ATTR_SZ[pnMatIdx()]; ret += ATTR_SZ[tex0MatIdx()];
ret += ATTR_SZ[tex0MatIdx()]; ret += ATTR_SZ[tex1MatIdx()];
ret += ATTR_SZ[tex1MatIdx()]; ret += ATTR_SZ[tex2MatIdx()];
ret += ATTR_SZ[tex2MatIdx()]; ret += ATTR_SZ[tex3MatIdx()];
ret += ATTR_SZ[tex3MatIdx()]; ret += ATTR_SZ[tex4MatIdx()];
ret += ATTR_SZ[tex4MatIdx()]; ret += ATTR_SZ[tex5MatIdx()];
ret += ATTR_SZ[tex5MatIdx()]; ret += ATTR_SZ[tex6MatIdx()];
ret += ATTR_SZ[tex6MatIdx()]; return ret;
return ret; }
} } vaFlags;
} vaFlags; const VAFlags& getVAFlags() const { return vaFlags; }
const VAFlags& getVAFlags() const {return vaFlags;} Value<atUint32> uniqueIdx;
Value<atUint32> uniqueIdx;
Vector<atUint32, AT_DNA_COUNT(flags.konstValuesEnabled())> konstCount; Vector<atUint32, AT_DNA_COUNT(flags.konstValuesEnabled())> konstCount;
Vector<GX::Color, AT_DNA_COUNT(flags.konstValuesEnabled() ? konstCount[0] : 0)> konstColors; Vector<GX::Color, AT_DNA_COUNT(flags.konstValuesEnabled() ? konstCount[0] : 0)> konstColors;
using BlendFactor = GX::BlendFactor; using BlendFactor = GX::BlendFactor;
Value<BlendFactor> blendDstFac; Value<BlendFactor> blendDstFac;
Value<BlendFactor> blendSrcFac; Value<BlendFactor> blendSrcFac;
Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot; Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
Value<atUint32> colorChannelCount = 0; Value<atUint32> colorChannelCount = 0;
struct ColorChannel : BigDNA struct ColorChannel : BigDNA {
{ AT_DECL_DNA
AT_DECL_DNA Value<atUint32> flags = 0;
Value<atUint32> flags = 0; bool lighting() const { return (flags & 0x1) != 0; }
bool lighting() const {return (flags & 0x1) != 0;} void setLighting(bool enabled) {
void setLighting(bool enabled) {flags &= ~0x1; flags |= atUint32(enabled);} flags &= ~0x1;
bool useAmbient() const {return (flags & 0x2) != 0;} flags |= atUint32(enabled);
void setUseAmbient(bool enabled) {flags &= ~0x2; flags |= atUint32(enabled) << 1;} }
bool useMaterial() const {return (flags & 0x4) != 0;} bool useAmbient() const { return (flags & 0x2) != 0; }
void setUseMaterial(bool enabled) {flags &= ~0x4; flags |= atUint32(enabled) << 2;} void setUseAmbient(bool enabled) {
atUint8 lightmask() const {return atUint8(flags >> 3 & 0xff);} flags &= ~0x2;
void setLightmask(atUint8 mask) {flags &= ~0x7f8; flags |= atUint32(mask) << 3;} flags |= atUint32(enabled) << 1;
GX::DiffuseFn diffuseFn() const {return GX::DiffuseFn(flags >> 11 & 0x3);} }
void setDiffuseFn(GX::DiffuseFn fn) {flags &= ~0x1800; flags |= atUint32(fn) << 11;} bool useMaterial() const { return (flags & 0x4) != 0; }
GX::AttnFn attenuationFn() const {return GX::AttnFn(flags >> 13 & 0x3);} void setUseMaterial(bool enabled) {
void setAttenuationFn(GX::AttnFn fn) {flags &= ~0x6000; flags |= atUint32(fn) << 13;} flags &= ~0x4;
}; flags |= atUint32(enabled) << 2;
Vector<ColorChannel, AT_DNA_COUNT(colorChannelCount)> colorChannels; }
atUint8 lightmask() const { return atUint8(flags >> 3 & 0xff); }
Value<atUint32> tevStageCount = 0; void setLightmask(atUint8 mask) {
struct TEVStage : BigDNA flags &= ~0x7f8;
{ flags |= atUint32(mask) << 3;
AT_DECL_DNA }
Value<atUint32> ciFlags = 0; GX::DiffuseFn diffuseFn() const { return GX::DiffuseFn(flags >> 11 & 0x3); }
Value<atUint32> aiFlags = 0; void setDiffuseFn(GX::DiffuseFn fn) {
Value<atUint32> ccFlags = 0; flags &= ~0x1800;
Value<atUint32> acFlags = 0; flags |= atUint32(fn) << 11;
Value<atUint8> pad = 0; }
Value<atUint8> kaInput = 0; GX::AttnFn attenuationFn() const { return GX::AttnFn(flags >> 13 & 0x3); }
Value<atUint8> kcInput = 0; void setAttenuationFn(GX::AttnFn fn) {
Value<atUint8> rascInput = 0; flags &= ~0x6000;
flags |= atUint32(fn) << 13;
GX::TevColorArg colorInA() const {return GX::TevColorArg(ciFlags & 0xf);} }
void setColorInA(GX::TevColorArg val) {ciFlags &= ~0x1f; ciFlags |= atUint32(val);}
GX::TevColorArg colorInB() const {return GX::TevColorArg(ciFlags >> 5 & 0xf);}
void setColorInB(GX::TevColorArg val) {ciFlags &= ~0x3e0; ciFlags |= atUint32(val) << 5;}
GX::TevColorArg colorInC() const {return GX::TevColorArg(ciFlags >> 10 & 0xf);}
void setColorInC(GX::TevColorArg val) {ciFlags &= ~0x7c00; ciFlags |= atUint32(val) << 10;}
GX::TevColorArg colorInD() const {return GX::TevColorArg(ciFlags >> 15 & 0xf);}
void setColorInD(GX::TevColorArg val) {ciFlags &= ~0xf8000; ciFlags |= atUint32(val) << 15;}
GX::TevAlphaArg alphaInA() const {return GX::TevAlphaArg(aiFlags & 0x7);}
void setAlphaInA(GX::TevAlphaArg val) {aiFlags &= ~0x1f; aiFlags |= atUint32(val);}
GX::TevAlphaArg alphaInB() const {return GX::TevAlphaArg(aiFlags >> 5 & 0x7);}
void setAlphaInB(GX::TevAlphaArg val) {aiFlags &= ~0x3e0; aiFlags |= atUint32(val) << 5;}
GX::TevAlphaArg alphaInC() const {return GX::TevAlphaArg(aiFlags >> 10 & 0x7);}
void setAlphaInC(GX::TevAlphaArg val) {aiFlags &= ~0x7c00; aiFlags |= atUint32(val) << 10;}
GX::TevAlphaArg alphaInD() const {return GX::TevAlphaArg(aiFlags >> 15 & 0x7);}
void setAlphaInD(GX::TevAlphaArg val) {aiFlags &= ~0xf8000; aiFlags |= atUint32(val) << 15;}
GX::TevOp colorOp() const {return GX::TevOp(ccFlags & 0xf);}
void setColorOp(GX::TevOp val) {ccFlags &= ~0x1; ccFlags |= atUint32(val);}
GX::TevBias colorOpBias() const {return GX::TevBias(ccFlags >> 4 & 0x3);}
void setColorOpBias(GX::TevBias val) {ccFlags &= ~0x30; ccFlags |= atUint32(val) << 4;}
GX::TevScale colorOpScale() const {return GX::TevScale(ccFlags >> 6 & 0x3);}
void setColorOpScale(GX::TevScale val) {ccFlags &= ~0xc0; ccFlags |= atUint32(val) << 6;}
bool colorOpClamp() const {return ccFlags >> 8 & 0x1;}
void setColorOpClamp(bool val) {ccFlags &= ~0x100; ccFlags |= atUint32(val) << 8;}
GX::TevRegID colorOpOutReg() const {return GX::TevRegID(ccFlags >> 9 & 0x3);}
void setColorOpOutReg(GX::TevRegID val) {ccFlags &= ~0x600; ccFlags |= atUint32(val) << 9;}
GX::TevOp alphaOp() const {return GX::TevOp(acFlags & 0xf);}
void setAlphaOp(GX::TevOp val) {acFlags &= ~0x1; acFlags |= atUint32(val);}
GX::TevBias alphaOpBias() const {return GX::TevBias(acFlags >> 4 & 0x3);}
void setAlphaOpBias(GX::TevBias val) {acFlags &= ~0x30; acFlags |= atUint32(val) << 4;}
GX::TevScale alphaOpScale() const {return GX::TevScale(acFlags >> 6 & 0x3);}
void setAlphaOpScale(GX::TevScale val) {acFlags &= ~0xc0; acFlags |= atUint32(val) << 6;}
bool alphaOpClamp() const {return acFlags >> 8 & 0x1;}
void setAlphaOpClamp(bool val) {acFlags &= ~0x100; acFlags |= atUint32(val) << 8;}
GX::TevRegID alphaOpOutReg() const {return GX::TevRegID(acFlags >> 9 & 0x3);}
void setAlphaOpOutReg(GX::TevRegID val) {acFlags &= ~0x600; acFlags |= atUint32(val) << 9;}
GX::TevKColorSel kColorIn() const {return GX::TevKColorSel(kcInput);}
void setKColorIn(GX::TevKColorSel val) {kcInput = val;}
GX::TevKAlphaSel kAlphaIn() const {return GX::TevKAlphaSel(kaInput);}
void setKAlphaIn(GX::TevKAlphaSel val) {kaInput = val;}
GX::ChannelID rasIn() const {return GX::ChannelID(rascInput);}
void setRASIn(GX::ChannelID id) {rascInput = id;}
};
Vector<TEVStage, AT_DNA_COUNT(tevStageCount)> tevStages;
struct TEVStageTexInfo : BigDNA
{
AT_DECL_DNA
Value<atUint16> pad = 0;
Value<atUint8> texSlot = 0xff;
Value<atUint8> tcgSlot = 0xff;
};
Vector<TEVStageTexInfo, AT_DNA_COUNT(tevStageCount)> tevStageTexInfo;
Value<atUint32> tcgCount = 0;
struct TexCoordGen : BigDNA
{
AT_DECL_DNA
Value<atUint32> flags = 0;
GX::TexGenType type() const {return GX::TexGenType(flags & 0xf);}
void setType(GX::TexGenType val) {flags &= ~0xf; flags |= atUint32(val);}
GX::TexGenSrc source() const {return GX::TexGenSrc(flags >> 4 & 0x1f);}
void setSource(GX::TexGenSrc val) {flags &= ~0x1f0; flags |= atUint32(val) << 4;}
GX::TexMtx mtx() const {return GX::TexMtx((flags >> 9 & 0x1f) + 30);}
void setMtx(GX::TexMtx val) {flags &= ~0x3e00; flags |= (atUint32(val)-30) << 9;}
bool normalize() const {return flags >> 14 & 0x1;}
void setNormalize(bool val) {flags &= ~0x4000; flags |= atUint32(val) << 14;}
GX::PTTexMtx postMtx() const {return GX::PTTexMtx((flags >> 15 & 0x3f) + 64);}
void setPostMtx(GX::PTTexMtx val) {flags &= ~0x1f8000; flags |= (atUint32(val)-64) << 15;}
};
Vector<TexCoordGen, AT_DNA_COUNT(tcgCount)> tcgs;
Value<atUint32> uvAnimsSize = 4;
Value<atUint32> uvAnimsCount = 0;
struct UVAnimation : BigDNA
{
AT_DECL_EXPLICIT_DNA
enum class Mode
{
MvInvNoTranslation,
MvInv,
Scroll,
Rotation,
HStrip,
VStrip,
Model,
CylinderEnvironment,
Eight
} mode;
float vals[9];
UVAnimation() = default;
UVAnimation(const std::string& gameFunction,
const std::vector<atVec4f>& gameArgs);
};
Vector<UVAnimation, AT_DNA_COUNT(uvAnimsCount)> uvAnims;
static void AddTexture(hecl::blender::PyOutStream& out,
GX::TexGenSrc type, int mtxIdx, uint32_t texIdx);
static void AddTextureAnim(hecl::blender::PyOutStream& out,
MaterialSet::Material::UVAnimation::Mode type,
unsigned idx, const float* vals);
static void AddKcolor(hecl::blender::PyOutStream& out,
const GX::Color& col, unsigned idx);
static void AddDynamicColor(hecl::blender::PyOutStream& out, unsigned idx);
static void AddDynamicAlpha(hecl::blender::PyOutStream& out, unsigned idx);
Material() = default;
Material(const hecl::Backend::GX& gx,
const std::unordered_map<std::string, int32_t>& iprops,
const std::vector<hecl::ProjectPath>& texPathsIn,
std::vector<hecl::ProjectPath>& texPathsOut,
int colorCount,
bool lightmapUVs,
bool matrixSkinning);
}; };
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials; Vector<ColorChannel, AT_DNA_COUNT(colorChannelCount)> colorChannels;
static void RegisterMaterialProps(hecl::blender::PyOutStream& out); Value<atUint32> tevStageCount = 0;
static void ConstructMaterial(hecl::blender::PyOutStream& out, struct TEVStage : BigDNA {
const MaterialSet::Material& material, AT_DECL_DNA
unsigned groupIdx, unsigned matIdx); Value<atUint32> ciFlags = 0;
Value<atUint32> aiFlags = 0;
Value<atUint32> ccFlags = 0;
Value<atUint32> acFlags = 0;
Value<atUint8> pad = 0;
Value<atUint8> kaInput = 0;
Value<atUint8> kcInput = 0;
Value<atUint8> rascInput = 0;
void readToBlender(hecl::blender::PyOutStream& os, GX::TevColorArg colorInA() const { return GX::TevColorArg(ciFlags & 0xf); }
const PAKRouter<PAKBridge>& pakRouter, void setColorInA(GX::TevColorArg val) {
const PAKRouter<PAKBridge>::EntryType& entry, ciFlags &= ~0x1f;
unsigned setIdx) ciFlags |= atUint32(val);
{ }
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx); GX::TevColorArg colorInB() const { return GX::TevColorArg(ciFlags >> 5 & 0xf); }
} void setColorInB(GX::TevColorArg val) {
ciFlags &= ~0x3e0;
ciFlags |= atUint32(val) << 5;
}
GX::TevColorArg colorInC() const { return GX::TevColorArg(ciFlags >> 10 & 0xf); }
void setColorInC(GX::TevColorArg val) {
ciFlags &= ~0x7c00;
ciFlags |= atUint32(val) << 10;
}
GX::TevColorArg colorInD() const { return GX::TevColorArg(ciFlags >> 15 & 0xf); }
void setColorInD(GX::TevColorArg val) {
ciFlags &= ~0xf8000;
ciFlags |= atUint32(val) << 15;
}
template <class PAKRouter> GX::TevAlphaArg alphaInA() const { return GX::TevAlphaArg(aiFlags & 0x7); }
void nameTextures(PAKRouter& pakRouter, const char* prefix, int setIdx) const void setAlphaInA(GX::TevAlphaArg val) {
{ aiFlags &= ~0x1f;
int matIdx = 0; aiFlags |= atUint32(val);
for (const Material& mat : materials) }
{ GX::TevAlphaArg alphaInB() const { return GX::TevAlphaArg(aiFlags >> 5 & 0x7); }
int stageIdx = 0; void setAlphaInB(GX::TevAlphaArg val) {
for (const Material::TEVStage& stage : mat.tevStages) aiFlags &= ~0x3e0;
{ aiFlags |= atUint32(val) << 5;
(void)stage; }
const Material::TEVStageTexInfo& texInfo = mat.tevStageTexInfo[stageIdx]; GX::TevAlphaArg alphaInC() const { return GX::TevAlphaArg(aiFlags >> 10 & 0x7); }
if (texInfo.texSlot == 0xff) void setAlphaInC(GX::TevAlphaArg val) {
{ aiFlags &= ~0x7c00;
++stageIdx; aiFlags |= atUint32(val) << 10;
continue; }
} GX::TevAlphaArg alphaInD() const { return GX::TevAlphaArg(aiFlags >> 15 & 0x7); }
const nod::Node* node; void setAlphaInD(GX::TevAlphaArg val) {
typename PAKRouter::EntryType* texEntry = (typename PAKRouter::EntryType*) aiFlags &= ~0xf8000;
pakRouter.lookupEntry(head.textureIDs[mat.textureIdxs[texInfo.texSlot]], &node); aiFlags |= atUint32(val) << 15;
if (texEntry->name.size()) }
{
if (texEntry->name.size() < 5 || texEntry->name.compare(0, 5, "mult_"))
texEntry->name = "mult_" + texEntry->name;
++stageIdx;
continue;
}
if (setIdx < 0)
texEntry->name = hecl::Format("%s_%d_%d", prefix, matIdx, stageIdx);
else
texEntry->name = hecl::Format("%s_%d_%d_%d", prefix, setIdx, matIdx, stageIdx);
if (mat.flags.lightmap() && stageIdx == 0) GX::TevOp colorOp() const { return GX::TevOp(ccFlags & 0xf); }
{ void setColorOp(GX::TevOp val) {
texEntry->name += "light"; ccFlags &= ~0x1;
++stageIdx; ccFlags |= atUint32(val);
continue; }
} GX::TevBias colorOpBias() const { return GX::TevBias(ccFlags >> 4 & 0x3); }
void setColorOpBias(GX::TevBias val) {
ccFlags &= ~0x30;
ccFlags |= atUint32(val) << 4;
}
GX::TevScale colorOpScale() const { return GX::TevScale(ccFlags >> 6 & 0x3); }
void setColorOpScale(GX::TevScale val) {
ccFlags &= ~0xc0;
ccFlags |= atUint32(val) << 6;
}
bool colorOpClamp() const { return ccFlags >> 8 & 0x1; }
void setColorOpClamp(bool val) {
ccFlags &= ~0x100;
ccFlags |= atUint32(val) << 8;
}
GX::TevRegID colorOpOutReg() const { return GX::TevRegID(ccFlags >> 9 & 0x3); }
void setColorOpOutReg(GX::TevRegID val) {
ccFlags &= ~0x600;
ccFlags |= atUint32(val) << 9;
}
++stageIdx; GX::TevOp alphaOp() const { return GX::TevOp(acFlags & 0xf); }
} void setAlphaOp(GX::TevOp val) {
++matIdx; acFlags &= ~0x1;
acFlags |= atUint32(val);
}
GX::TevBias alphaOpBias() const { return GX::TevBias(acFlags >> 4 & 0x3); }
void setAlphaOpBias(GX::TevBias val) {
acFlags &= ~0x30;
acFlags |= atUint32(val) << 4;
}
GX::TevScale alphaOpScale() const { return GX::TevScale(acFlags >> 6 & 0x3); }
void setAlphaOpScale(GX::TevScale val) {
acFlags &= ~0xc0;
acFlags |= atUint32(val) << 6;
}
bool alphaOpClamp() const { return acFlags >> 8 & 0x1; }
void setAlphaOpClamp(bool val) {
acFlags &= ~0x100;
acFlags |= atUint32(val) << 8;
}
GX::TevRegID alphaOpOutReg() const { return GX::TevRegID(acFlags >> 9 & 0x3); }
void setAlphaOpOutReg(GX::TevRegID val) {
acFlags &= ~0x600;
acFlags |= atUint32(val) << 9;
}
GX::TevKColorSel kColorIn() const { return GX::TevKColorSel(kcInput); }
void setKColorIn(GX::TevKColorSel val) { kcInput = val; }
GX::TevKAlphaSel kAlphaIn() const { return GX::TevKAlphaSel(kaInput); }
void setKAlphaIn(GX::TevKAlphaSel val) { kaInput = val; }
GX::ChannelID rasIn() const { return GX::ChannelID(rascInput); }
void setRASIn(GX::ChannelID id) { rascInput = id; }
};
Vector<TEVStage, AT_DNA_COUNT(tevStageCount)> tevStages;
struct TEVStageTexInfo : BigDNA {
AT_DECL_DNA
Value<atUint16> pad = 0;
Value<atUint8> texSlot = 0xff;
Value<atUint8> tcgSlot = 0xff;
};
Vector<TEVStageTexInfo, AT_DNA_COUNT(tevStageCount)> tevStageTexInfo;
Value<atUint32> tcgCount = 0;
struct TexCoordGen : BigDNA {
AT_DECL_DNA
Value<atUint32> flags = 0;
GX::TexGenType type() const { return GX::TexGenType(flags & 0xf); }
void setType(GX::TexGenType val) {
flags &= ~0xf;
flags |= atUint32(val);
}
GX::TexGenSrc source() const { return GX::TexGenSrc(flags >> 4 & 0x1f); }
void setSource(GX::TexGenSrc val) {
flags &= ~0x1f0;
flags |= atUint32(val) << 4;
}
GX::TexMtx mtx() const { return GX::TexMtx((flags >> 9 & 0x1f) + 30); }
void setMtx(GX::TexMtx val) {
flags &= ~0x3e00;
flags |= (atUint32(val) - 30) << 9;
}
bool normalize() const { return flags >> 14 & 0x1; }
void setNormalize(bool val) {
flags &= ~0x4000;
flags |= atUint32(val) << 14;
}
GX::PTTexMtx postMtx() const { return GX::PTTexMtx((flags >> 15 & 0x3f) + 64); }
void setPostMtx(GX::PTTexMtx val) {
flags &= ~0x1f8000;
flags |= (atUint32(val) - 64) << 15;
}
};
Vector<TexCoordGen, AT_DNA_COUNT(tcgCount)> tcgs;
Value<atUint32> uvAnimsSize = 4;
Value<atUint32> uvAnimsCount = 0;
struct UVAnimation : BigDNA {
AT_DECL_EXPLICIT_DNA
enum class Mode {
MvInvNoTranslation,
MvInv,
Scroll,
Rotation,
HStrip,
VStrip,
Model,
CylinderEnvironment,
Eight
} mode;
float vals[9];
UVAnimation() = default;
UVAnimation(const std::string& gameFunction, const std::vector<atVec4f>& gameArgs);
};
Vector<UVAnimation, AT_DNA_COUNT(uvAnimsCount)> uvAnims;
static void AddTexture(hecl::blender::PyOutStream& out, GX::TexGenSrc type, int mtxIdx, uint32_t texIdx);
static void AddTextureAnim(hecl::blender::PyOutStream& out, MaterialSet::Material::UVAnimation::Mode type,
unsigned idx, const float* vals);
static void AddKcolor(hecl::blender::PyOutStream& out, const GX::Color& col, unsigned idx);
static void AddDynamicColor(hecl::blender::PyOutStream& out, unsigned idx);
static void AddDynamicAlpha(hecl::blender::PyOutStream& out, unsigned idx);
Material() = default;
Material(const hecl::Backend::GX& gx, const std::unordered_map<std::string, int32_t>& iprops,
const std::vector<hecl::ProjectPath>& texPathsIn, std::vector<hecl::ProjectPath>& texPathsOut,
int colorCount, bool lightmapUVs, bool matrixSkinning);
};
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
static void RegisterMaterialProps(hecl::blender::PyOutStream& out);
static void ConstructMaterial(hecl::blender::PyOutStream& out, const MaterialSet::Material& material,
unsigned groupIdx, unsigned matIdx);
void readToBlender(hecl::blender::PyOutStream& os, const PAKRouter<PAKBridge>& pakRouter,
const PAKRouter<PAKBridge>::EntryType& entry, unsigned setIdx) {
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx);
}
template <class PAKRouter>
void nameTextures(PAKRouter& pakRouter, const char* prefix, int setIdx) const {
int matIdx = 0;
for (const Material& mat : materials) {
int stageIdx = 0;
for (const Material::TEVStage& stage : mat.tevStages) {
(void)stage;
const Material::TEVStageTexInfo& texInfo = mat.tevStageTexInfo[stageIdx];
if (texInfo.texSlot == 0xff) {
++stageIdx;
continue;
} }
} const nod::Node* node;
typename PAKRouter::EntryType* texEntry = (typename PAKRouter::EntryType*)pakRouter.lookupEntry(
head.textureIDs[mat.textureIdxs[texInfo.texSlot]], &node);
if (texEntry->name.size()) {
if (texEntry->name.size() < 5 || texEntry->name.compare(0, 5, "mult_"))
texEntry->name = "mult_" + texEntry->name;
++stageIdx;
continue;
}
if (setIdx < 0)
texEntry->name = hecl::Format("%s_%d_%d", prefix, matIdx, stageIdx);
else
texEntry->name = hecl::Format("%s_%d_%d_%d", prefix, setIdx, matIdx, stageIdx);
void ensureTexturesExtracted(PAKRouter<PAKBridge>& pakRouter) const if (mat.flags.lightmap() && stageIdx == 0) {
{ texEntry->name += "light";
head.ensureTexturesExtracted(pakRouter); ++stageIdx;
continue;
}
++stageIdx;
}
++matIdx;
} }
}
void ensureTexturesExtracted(PAKRouter<PAKBridge>& pakRouter) const { head.ensureTexturesExtracted(pakRouter); }
}; };
struct HMDLMaterialSet : BigDNA struct HMDLMaterialSet : BigDNA {
{ static constexpr bool OneSection() { return false; }
static constexpr bool OneSection() {return false;}
AT_DECL_DNA
MaterialSet::MaterialSetHead head;
struct Material : BigDNA {
AT_DECL_DNA AT_DECL_DNA
MaterialSet::MaterialSetHead head; MaterialSet::Material::Flags flags;
struct Material : BigDNA Value<atUint32> textureCount = 0;
{ Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
AT_DECL_DNA
MaterialSet::Material::Flags flags;
Value<atUint32> textureCount = 0; Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot; Value<atUint32> uvAnimsSize = 4;
Value<atUint32> uvAnimsCount = 0;
Vector<MaterialSet::Material::UVAnimation, AT_DNA_COUNT(uvAnimsCount)> uvAnims;
Value<atUint32> uvAnimsSize = 4; String<-1> heclSource;
Value<atUint32> uvAnimsCount = 0; hecl::Frontend::IR heclIr;
Vector<MaterialSet::Material::UVAnimation, AT_DNA_COUNT(uvAnimsCount)> uvAnims;
String<-1> heclSource; Material() = default;
hecl::Frontend::IR heclIr; Material(hecl::Frontend::Frontend& FE, const std::string& diagName, const hecl::blender::Material& mat,
const std::unordered_map<std::string, int32_t>& iprops, const std::vector<hecl::ProjectPath>& texPaths);
Material() = default; };
Material(hecl::Frontend::Frontend& FE, Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
const std::string& diagName,
const hecl::blender::Material& mat,
const std::unordered_map<std::string, int32_t>& iprops,
const std::vector<hecl::ProjectPath>& texPaths);
};
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
}; };
} } // namespace DataSpec::DNAMP1

View File

@ -1,21 +1,16 @@
#include "CSKR.hpp" #include "CSKR.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const {
{ atUint32 accum = 0;
atUint32 accum = 0; for (const SkinningRule& rule : skinningRules) {
for (const SkinningRule& rule : skinningRules) if (idx >= accum && idx < accum + rule.vertCount)
{ for (const SkinningRule::Weight& weight : rule.weights)
if (idx >= accum && idx < accum + rule.vertCount) os.format("vert[dvert_lay][%u] = %f\n", cinf.getBoneIdxFromId(weight.boneId), weight.weight);
for (const SkinningRule::Weight& weight : rule.weights) accum += rule.vertCount;
os.format("vert[dvert_lay][%u] = %f\n", }
cinf.getBoneIdxFromId(weight.boneId),
weight.weight);
accum += rule.vertCount;
}
} }
} } // namespace DataSpec::DNAMP1

View File

@ -3,35 +3,27 @@
#include "DataSpec/DNACommon/DNACommon.hpp" #include "DataSpec/DNACommon/DNACommon.hpp"
#include "CINF.hpp" #include "CINF.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
struct CSKR : BigDNA struct CSKR : BigDNA {
{ AT_DECL_DNA
Value<atUint32> skinningRuleCount;
struct SkinningRule : BigDNA {
AT_DECL_DNA AT_DECL_DNA
Value<atUint32> skinningRuleCount; Value<atUint32> weightCount;
struct SkinningRule : BigDNA struct Weight : BigDNA {
{ AT_DECL_DNA
AT_DECL_DNA Value<atUint32> boneId;
Value<atUint32> weightCount; Value<float> weight;
struct Weight : BigDNA
{
AT_DECL_DNA
Value<atUint32> boneId;
Value<float> weight;
};
Vector<Weight, AT_DNA_COUNT(weightCount)> weights;
Value<atUint32> vertCount;
}; };
Vector<SkinningRule, AT_DNA_COUNT(skinningRuleCount)> skinningRules; Vector<Weight, AT_DNA_COUNT(weightCount)> weights;
Value<atUint32> vertCount;
};
Vector<SkinningRule, AT_DNA_COUNT(skinningRuleCount)> skinningRules;
const atInt16* getMatrixBank(size_t) const const atInt16* getMatrixBank(size_t) const { return nullptr; }
{
return nullptr;
}
void weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const; void weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const;
}; };
} } // namespace DataSpec::DNAMP1

View File

@ -1,102 +1,99 @@
#include "CSNG.hpp" #include "CSNG.hpp"
#include "amuse/SongConverter.hpp" #include "amuse/SongConverter.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
{ hecl::ProjectPath midPath = outPath.getWithExtension(_SYS_STR(".mid"), true);
hecl::ProjectPath midPath = outPath.getWithExtension(_SYS_STR(".mid"), true); hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true);
hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true);
Header head;
head.read(rs);
{
athena::io::YAMLDocWriter dw("CSNG");
dw.writeUint32("midiSetupId", head.midiSetupId);
dw.writeUint32("songGroupId", head.songGroupId);
if (auto rec = dw.enterSubRecord("agscId"))
head.agscId.write(dw);
athena::io::FileWriter w(yamlPath.getAbsolutePath());
if (w.hasError())
return false;
dw.finish(&w);
}
{
auto sng = rs.readUBytes(head.sngLength);
int version;
bool isBig;
auto midi = amuse::SongConverter::SongToMIDI(sng.get(), version, isBig);
athena::io::FileWriter w(midPath.getAbsolutePath());
if (w.hasError())
return false;
w.writeUBytes(midi.data(), midi.size());
}
/* Update !songs.yaml for Amuse editor */
hecl::ProjectPath audGrp(outPath.getParentPath().getParentPath(), _SYS_STR("AudioGrp"));
audGrp.makeDirChain(true);
hecl::ProjectPath songsPath(audGrp, _SYS_STR("!songs.yaml"));
std::experimental::optional<athena::io::FileReader> r;
if (songsPath.isFile())
r.emplace(songsPath.getAbsolutePath());
athena::io::YAMLDocWriter ydw("amuse::Songs", r ? &*r : nullptr);
r = std::experimental::nullopt;
char id[16];
snprintf(id, 16, "%04X", head.midiSetupId);
ydw.writeString(id, hecl::Format("../MidiData/%s", midPath.getLastComponentUTF8().data()));
athena::io::FileWriter w(songsPath.getAbsolutePath());
ydw.finish(&w);
return true;
}
bool CSNG::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
hecl::ProjectPath midPath = inPath.getWithExtension(_SYS_STR(".mid"), true);
hecl::ProjectPath yamlPath = inPath.getWithExtension(_SYS_STR(".yaml"), true);
std::vector<uint8_t> sngData;
{
athena::io::FileReader midR(midPath.getAbsolutePath());
if (midR.hasError())
return false;
uint32_t midLen = midR.length();
std::vector<uint8_t> midData;
midData.resize(midLen);
midR.readUBytesToBuf(midData.data(), midLen);
sngData = amuse::SongConverter::MIDIToSong(midData, 1, true);
}
athena::io::FileWriter w(outPath.getAbsolutePath());
if (w.hasError())
return false;
{
athena::io::FileReader yamlR(yamlPath.getAbsolutePath());
if (yamlR.hasError())
return false;
athena::io::YAMLDocReader dr;
if (!dr.parse(&yamlR))
return false;
Header head; Header head;
head.read(rs); head.midiSetupId = dr.readUint32("midiSetupId");
head.songGroupId = dr.readUint32("songGroupId");
if (auto rec = dr.enterSubRecord("agscId"))
head.agscId.read(dr);
head.sngLength = sngData.size();
head.write(w);
}
{ w.writeUBytes(sngData.data(), sngData.size());
athena::io::YAMLDocWriter dw("CSNG");
dw.writeUint32("midiSetupId", head.midiSetupId);
dw.writeUint32("songGroupId", head.songGroupId);
if (auto rec = dw.enterSubRecord("agscId"))
head.agscId.write(dw);
athena::io::FileWriter w(yamlPath.getAbsolutePath()); return true;
if (w.hasError())
return false;
dw.finish(&w);
}
{
auto sng = rs.readUBytes(head.sngLength);
int version;
bool isBig;
auto midi = amuse::SongConverter::SongToMIDI(sng.get(), version, isBig);
athena::io::FileWriter w(midPath.getAbsolutePath());
if (w.hasError())
return false;
w.writeUBytes(midi.data(), midi.size());
}
/* Update !songs.yaml for Amuse editor */
hecl::ProjectPath audGrp(outPath.getParentPath().getParentPath(), _SYS_STR("AudioGrp"));
audGrp.makeDirChain(true);
hecl::ProjectPath songsPath(audGrp, _SYS_STR("!songs.yaml"));
std::experimental::optional<athena::io::FileReader> r;
if (songsPath.isFile())
r.emplace(songsPath.getAbsolutePath());
athena::io::YAMLDocWriter ydw("amuse::Songs", r ? &*r : nullptr);
r = std::experimental::nullopt;
char id[16];
snprintf(id, 16, "%04X", head.midiSetupId);
ydw.writeString(id, hecl::Format("../MidiData/%s", midPath.getLastComponentUTF8().data()));
athena::io::FileWriter w(songsPath.getAbsolutePath());
ydw.finish(&w);
return true;
} }
bool CSNG::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) } // namespace DataSpec::DNAMP1
{
hecl::ProjectPath midPath = inPath.getWithExtension(_SYS_STR(".mid"), true);
hecl::ProjectPath yamlPath = inPath.getWithExtension(_SYS_STR(".yaml"), true);
std::vector<uint8_t> sngData;
{
athena::io::FileReader midR(midPath.getAbsolutePath());
if (midR.hasError())
return false;
uint32_t midLen = midR.length();
std::vector<uint8_t> midData;
midData.resize(midLen);
midR.readUBytesToBuf(midData.data(), midLen);
sngData = amuse::SongConverter::MIDIToSong(midData, 1, true);
}
athena::io::FileWriter w(outPath.getAbsolutePath());
if (w.hasError())
return false;
{
athena::io::FileReader yamlR(yamlPath.getAbsolutePath());
if (yamlR.hasError())
return false;
athena::io::YAMLDocReader dr;
if (!dr.parse(&yamlR))
return false;
Header head;
head.midiSetupId = dr.readUint32("midiSetupId");
head.songGroupId = dr.readUint32("songGroupId");
if (auto rec = dr.enterSubRecord("agscId"))
head.agscId.read(dr);
head.sngLength = sngData.size();
head.write(w);
}
w.writeUBytes(sngData.data(), sngData.size());
return true;
}
}

View File

@ -3,24 +3,21 @@
#include "DataSpec/DNACommon/DNACommon.hpp" #include "DataSpec/DNACommon/DNACommon.hpp"
#include "DNAMP1.hpp" #include "DNAMP1.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
class CSNG {
struct Header : BigDNA {
AT_DECL_DNA
Value<atUint32> magic = 0x2;
Value<atUint32> midiSetupId;
Value<atUint32> songGroupId;
UniqueID32 agscId;
Value<atUint32> sngLength;
};
class CSNG
{
struct Header : BigDNA
{
AT_DECL_DNA
Value<atUint32> magic = 0x2;
Value<atUint32> midiSetupId;
Value<atUint32> songGroupId;
UniqueID32 agscId;
Value<atUint32> sngLength;
};
public: public:
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
}; };
} } // namespace DataSpec::DNAMP1

View File

@ -1,138 +1,121 @@
#include "DCLN.hpp" #include "DCLN.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
#if DCLN_DUMP_OBB #if DCLN_DUMP_OBB
void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const {
{ os.format(
os.format("obj = bpy.data.objects.new('%s', None)\n" "obj = bpy.data.objects.new('%s', None)\n"
"obj.empty_draw_type = 'CUBE'\n" "obj.empty_draw_type = 'CUBE'\n"
"bpy.context.scene.objects.link(obj)\n" "bpy.context.scene.objects.link(obj)\n"
"mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n" "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" "mtxd = mtx.decompose()\n"
"obj.rotation_mode = 'QUATERNION'\n" "obj.rotation_mode = 'QUATERNION'\n"
"obj.location = mtxd[0]\n" "obj.location = mtxd[0]\n"
"obj.rotation_quaternion = mtxd[1]\n" "obj.rotation_quaternion = mtxd[1]\n"
"obj.scale = (%f,%f,%f)\n", isLeaf ? "leaf" : "branch", "obj.scale = (%f,%f,%f)\n",
xf[0].vec[0], xf[0].vec[1], xf[0].vec[2], xf[0].vec[3], isLeaf ? "leaf" : "branch", xf[0].vec[0], xf[0].vec[1], xf[0].vec[2], xf[0].vec[3], xf[1].vec[0], xf[1].vec[1],
xf[1].vec[0], xf[1].vec[1], xf[1].vec[2], xf[1].vec[3], xf[1].vec[2], xf[1].vec[3], xf[2].vec[0], xf[2].vec[1], xf[2].vec[2], xf[2].vec[3], halfExtent.vec[0],
xf[2].vec[0], xf[2].vec[1], xf[2].vec[2], xf[2].vec[3], halfExtent.vec[1], halfExtent.vec[2]);
halfExtent.vec[0], halfExtent.vec[1], halfExtent.vec[2]); if (isLeaf)
if (isLeaf) os << "obj.show_name = True\n";
os << "obj.show_name = True\n"; if (!isLeaf) {
if (!isLeaf) left->sendToBlender(os);
{ right->sendToBlender(os);
left->sendToBlender(os); }
right->sendToBlender(os);
}
} }
#endif #endif
template <class Op> template <class Op>
void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) {
{ Do<Op>({"xf[0]"}, xf[0], s);
Do<Op>({"xf[0]"}, xf[0], s); Do<Op>({"xf[1]"}, xf[1], s);
Do<Op>({"xf[1]"}, xf[1], s); Do<Op>({"xf[2]"}, xf[2], s);
Do<Op>({"xf[2]"}, xf[2], s); Do<Op>({"halfExtent"}, halfExtent, s);
Do<Op>({"halfExtent"}, halfExtent, s); Do<Op>({"isLeaf"}, isLeaf, s);
Do<Op>({"isLeaf"}, isLeaf, s); if (isLeaf) {
if (isLeaf) if (!leafData)
{ leafData.reset(new LeafData);
if (!leafData) Do<Op>({"leafData"}, *leafData, s);
leafData.reset(new LeafData); } else {
Do<Op>({"leafData"}, *leafData, s); if (!left)
} left.reset(new Node);
else Do<Op>({"left"}, *left, s);
{ if (!right)
if (!left) right.reset(new Node);
left.reset(new Node); Do<Op>({"right"}, *right, s);
Do<Op>({"left"}, *left, s); }
if (!right)
right.reset(new Node);
Do<Op>({"right"}, *right, s);
}
} }
AT_SPECIALIZE_DNA(DCLN::Collision::Node) AT_SPECIALIZE_DNA(DCLN::Collision::Node)
void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName) void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName) {
{ /* Open Py Stream and read sections */
/* Open Py Stream and read sections */ hecl::blender::PyOutStream os = conn.beginPythonOut(true);
hecl::blender::PyOutStream os = conn.beginPythonOut(true); os.format(
os.format("import bpy\n" "import bpy\n"
"import bmesh\n" "import bmesh\n"
"from mathutils import Vector, Matrix\n" "from mathutils import Vector, Matrix\n"
"\n" "\n"
"bpy.context.scene.name = '%s'\n" "bpy.context.scene.name = '%s'\n"
"# Clear Scene\n" "# Clear Scene\n"
"for ob in bpy.data.objects:\n" "for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n" " if ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n" " bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n", " bpy.data.objects.remove(ob)\n",
entryName.data()); entryName.data());
DeafBabe::BlenderInit(os); DeafBabe::BlenderInit(os);
atInt32 idx = 0; atInt32 idx = 0;
for (const Collision& col : collision) for (const Collision& col : collision) {
{ DeafBabeSendToBlender(os, col, true, idx++);
DeafBabeSendToBlender(os, col, true, idx++);
#if DCLN_DUMP_OBB #if DCLN_DUMP_OBB
col.root.sendToBlender(os); col.root.sendToBlender(os);
#endif #endif
} }
os.centerView(); os.centerView();
os.close(); os.close();
} }
bool DCLN::Extract(const SpecBase& dataSpec, bool DCLN::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKEntryReadStream& rs, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged) {
PAKRouter<PAKBridge>& pakRouter, DCLN dcln;
const PAK::Entry& entry, dcln.read(rs);
bool force, hecl::blender::Connection& conn = btok.getBlenderConnection();
hecl::blender::Token& btok, if (!conn.createBlend(outPath, hecl::blender::BlendType::ColMesh))
std::function<void(const hecl::SystemChar*)> fileChanged) return false;
{
DCLN dcln;
dcln.read(rs);
hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::blender::BlendType::ColMesh))
return false;
dcln.sendToBlender(conn, pakRouter.getBestEntryName(entry, false)); dcln.sendToBlender(conn, pakRouter.getBestEntryName(entry, false));
return conn.saveBlend(); return conn.saveBlend();
} }
bool DCLN::Cook(const hecl::ProjectPath& outPath, bool DCLN::Cook(const hecl::ProjectPath& outPath, const std::vector<Mesh>& meshes) {
const std::vector<Mesh>& meshes) DCLN dcln;
{ dcln.colCount = atUint32(meshes.size());
DCLN dcln; for (const Mesh& mesh : meshes) {
dcln.colCount = atUint32(meshes.size()); dcln.collision.emplace_back();
for (const Mesh& mesh : meshes) Collision& colOut = dcln.collision.back();
{ DeafBabeBuildFromBlender(colOut, mesh);
dcln.collision.emplace_back(); colOut.root = std::move(*OBBTreeBuilder::buildCol<Collision::Node>(mesh));
Collision& colOut = dcln.collision.back(); colOut.memSize = atUint32(colOut.root.getMemoryUsage());
DeafBabeBuildFromBlender(colOut, mesh); }
colOut.root = std::move(*OBBTreeBuilder::buildCol<Collision::Node>(mesh));
colOut.memSize = atUint32(colOut.root.getMemoryUsage());
}
#if DCLN_DUMP_OBB #if DCLN_DUMP_OBB
hecl::blender::Connection& conn = hecl::blender::SharedBlenderToken.getBlenderConnection(); hecl::blender::Connection& conn = hecl::blender::SharedBlenderToken.getBlenderConnection();
conn.createBlend(outPath.getWithExtension(_SYS_STR(".blend")), hecl::blender::BlendType::ColMesh); conn.createBlend(outPath.getWithExtension(_SYS_STR(".blend")), hecl::blender::BlendType::ColMesh);
dcln.sendToBlender(conn, "BLAH"); dcln.sendToBlender(conn, "BLAH");
conn.saveBlend(); conn.saveBlend();
#endif #endif
athena::io::FileWriter w(outPath.getAbsolutePath()); athena::io::FileWriter w(outPath.getAbsolutePath());
dcln.write(w); dcln.write(w);
int64_t rem = w.position() % 32; int64_t rem = w.position() % 32;
if (rem) if (rem)
for (int64_t i=0 ; i<32-rem ; ++i) for (int64_t i = 0; i < 32 - rem; ++i)
w.writeUByte(0xff); w.writeUByte(0xff);
return true; return true;
} }
} } // namespace DataSpec::DNAMP1

View File

@ -9,103 +9,86 @@
#define DCLN_DUMP_OBB 0 #define DCLN_DUMP_OBB 0
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
struct DCLN : BigDNA struct DCLN : BigDNA {
{ using Mesh = hecl::blender::ColMesh;
using Mesh = hecl::blender::ColMesh;
AT_DECL_DNA
Value<atUint32> colCount;
struct Collision : BigDNA {
using Material = DeafBabe::Material;
using Edge = DeafBabe::Edge;
using Triangle = DeafBabe::Triangle;
AT_DECL_DNA AT_DECL_DNA
Value<atUint32> colCount; Value<atUint32> magic;
struct Collision : BigDNA Value<atUint32> version;
{ Value<atUint32> memSize;
using Material = DeafBabe::Material; Value<atUint32> materialCount;
using Edge = DeafBabe::Edge; Vector<Material, AT_DNA_COUNT(materialCount)> materials;
using Triangle = DeafBabe::Triangle; Value<atUint32> vertMatsCount;
Vector<atUint8, AT_DNA_COUNT(vertMatsCount)> vertMats;
Value<atUint32> edgeMatsCount;
Vector<atUint8, AT_DNA_COUNT(edgeMatsCount)> edgeMats;
Value<atUint32> triMatsCount;
Vector<atUint8, AT_DNA_COUNT(triMatsCount)> triMats;
Value<atUint32> edgeVertsCount;
Vector<Edge, AT_DNA_COUNT(edgeVertsCount)> edgeVertConnections;
Value<atUint32> triangleEdgesCount;
Vector<Triangle, AT_DNA_COUNT(triangleEdgesCount / 3)> triangleEdgeConnections;
Value<atUint32> vertCount;
Vector<atVec3f, AT_DNA_COUNT(vertCount)> verts;
struct Node : BigDNA {
AT_DECL_EXPLICIT_DNA
struct LeafData : BigDNA {
AT_DECL_DNA AT_DECL_DNA
Value<atUint32> magic; Value<atUint32> triangleIndexCount;
Value<atUint32> version; Vector<atUint16, AT_DNA_COUNT(triangleIndexCount)> triangleIndices;
Value<atUint32> memSize; size_t getMemoryUsage() const { return (((triangleIndices.size() * 2) + 16) + 3) & ~3; }
Value<atUint32> materialCount; };
Vector<Material, AT_DNA_COUNT(materialCount)> materials;
Value<atUint32> vertMatsCount;
Vector<atUint8, AT_DNA_COUNT(vertMatsCount)> vertMats;
Value<atUint32> edgeMatsCount;
Vector<atUint8, AT_DNA_COUNT(edgeMatsCount)> edgeMats;
Value<atUint32> triMatsCount;
Vector<atUint8, AT_DNA_COUNT(triMatsCount)> triMats;
Value<atUint32> edgeVertsCount;
Vector<Edge, AT_DNA_COUNT(edgeVertsCount)> edgeVertConnections;
Value<atUint32> triangleEdgesCount;
Vector<Triangle, AT_DNA_COUNT(triangleEdgesCount / 3)> triangleEdgeConnections;
Value<atUint32> vertCount;
Vector<atVec3f, AT_DNA_COUNT(vertCount)> verts;
struct Node : BigDNA Value<atVec4f> xf[3];
{ Value<atVec3f> halfExtent;
AT_DECL_EXPLICIT_DNA Value<bool> isLeaf;
std::unique_ptr<LeafData> leafData;
std::unique_ptr<Node> left;
std::unique_ptr<Node> right;
struct LeafData : BigDNA size_t getMemoryUsage() const {
{ size_t ret = 80;
AT_DECL_DNA if (isLeaf)
Value<atUint32> triangleIndexCount; ret += leafData->getMemoryUsage();
Vector<atUint16, AT_DNA_COUNT(triangleIndexCount)> triangleIndices; else {
size_t getMemoryUsage() const { return (((triangleIndices.size() * 2) + 16) + 3) & ~3; } ret += left->getMemoryUsage();
}; ret += right->getMemoryUsage();
Value<atVec4f> xf[3];
Value<atVec3f> halfExtent;
Value<bool> isLeaf;
std::unique_ptr<LeafData> leafData;
std::unique_ptr<Node> left;
std::unique_ptr<Node> right;
size_t getMemoryUsage() const
{
size_t ret = 80;
if (isLeaf)
ret += leafData->getMemoryUsage();
else
{
ret += left->getMemoryUsage();
ret += right->getMemoryUsage();
}
return (ret + 3) & ~3;
}
#if DCLN_DUMP_OBB
void sendToBlender(hecl::blender::PyOutStream& os) const;
#endif
};
Node root;
size_t getMemoryUsage()
{
return root.getMemoryUsage();
} }
/* Dummy MP2 member */ return (ret + 3) & ~3;
void insertNoClimb(hecl::blender::PyOutStream&) const {} }
#if DCLN_DUMP_OBB
void sendToBlender(hecl::blender::PyOutStream& os) const;
#endif
}; };
Node root;
size_t getMemoryUsage() { return root.getMemoryUsage(); }
/* Dummy MP2 member */
void insertNoClimb(hecl::blender::PyOutStream&) const {}
};
Vector<Collision, AT_DNA_COUNT(colCount)> collision; Vector<Collision, AT_DNA_COUNT(colCount)> collision;
void sendToBlender(hecl::blender::Connection& conn, std::string_view entryName); void sendToBlender(hecl::blender::Connection& conn, std::string_view entryName);
static bool Extract(const SpecBase& dataSpec, static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKEntryReadStream& rs, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
const hecl::ProjectPath& outPath, std::function<void(const hecl::SystemChar*)> fileChanged);
PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry,
bool force,
hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath, static bool Cook(const hecl::ProjectPath& outPath, const std::vector<Mesh>& meshes);
const std::vector<Mesh>& meshes);
}; };
} } // namespace DataSpec::DNAMP1

View File

@ -47,419 +47,373 @@
#include "MazeSeeds.hpp" #include "MazeSeeds.hpp"
#include "SnowForces.hpp" #include "SnowForces.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
logvisor::Module Log("urde::DNAMP1"); logvisor::Module Log("urde::DNAMP1");
static bool GetNoShare(std::string_view name) static bool GetNoShare(std::string_view name) {
{ std::string lowerName(name);
std::string lowerName(name); std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); if (!lowerName.compare(0, 7, "metroid"))
if (!lowerName.compare(0, 7, "metroid")) return false;
return false; return true;
return true;
} }
PAKBridge::PAKBridge(const nod::Node& node, bool doExtract) PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
: m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract) : m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract) {
{ nod::AthenaPartReadStream rs(node.beginReadStream());
nod::AthenaPartReadStream rs(node.beginReadStream()); m_pak.read(rs);
m_pak.read(rs);
/* Append Level String */ /* Append Level String */
for (auto& ent : m_pak.m_entries) for (auto& ent : m_pak.m_entries) {
{ PAK::Entry& entry = ent.second;
PAK::Entry& entry = ent.second; if (entry.type == FOURCC('MLVL')) {
if (entry.type == FOURCC('MLVL')) PAKEntryReadStream rs = entry.beginReadStream(m_node);
{ MLVL mlvl;
PAKEntryReadStream rs = entry.beginReadStream(m_node); mlvl.read(rs);
MLVL mlvl; PAK::Entry* nameEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldNameId);
mlvl.read(rs); if (nameEnt) {
PAK::Entry* nameEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldNameId); nameEnt->name = entry.name + "_name";
if (nameEnt) PAKEntryReadStream rs = nameEnt->beginReadStream(m_node);
{ STRG mlvlName;
nameEnt->name = entry.name + "_name"; mlvlName.read(rs);
PAKEntryReadStream rs = nameEnt->beginReadStream(m_node); if (m_levelString.size())
STRG mlvlName; m_levelString += _SYS_STR(", ");
mlvlName.read(rs); m_levelString += mlvlName.getSystemString(FOURCC('ENGL'), 0);
if (m_levelString.size()) }
m_levelString += _SYS_STR(", ");
m_levelString += mlvlName.getSystemString(FOURCC('ENGL'), 0);
}
}
} }
}
} }
static hecl::SystemString LayerName(std::string_view name) static hecl::SystemString LayerName(std::string_view name) {
{ hecl::SystemString ret(hecl::SystemStringConv(name).sys_str());
hecl::SystemString ret(hecl::SystemStringConv(name).sys_str()); for (auto& ch : ret)
for (auto& ch : ret) if (ch == _SYS_STR('/') || ch == _SYS_STR('\\'))
if (ch == _SYS_STR('/') || ch == _SYS_STR('\\')) ch = _SYS_STR('-');
ch = _SYS_STR('-'); return ret;
return ret;
} }
void PAKBridge::build() void PAKBridge::build() {
{ /* First pass: build per-area/per-layer dependency map */
/* First pass: build per-area/per-layer dependency map */ for (const auto& ent : m_pak.m_entries) {
for (const auto& ent : m_pak.m_entries) const PAK::Entry& entry = ent.second;
{ if (entry.type == FOURCC('MLVL')) {
const PAK::Entry& entry = ent.second; Level& level = m_levelDeps[entry.id];
if (entry.type == FOURCC('MLVL'))
{
Level& level = m_levelDeps[entry.id];
MLVL mlvl; MLVL mlvl;
{ {
PAKEntryReadStream rs = entry.beginReadStream(m_node); PAKEntryReadStream rs = entry.beginReadStream(m_node);
mlvl.read(rs); mlvl.read(rs);
} }
bool named; bool named;
std::string bestName = m_pak.bestEntryName(m_node, entry, named); std::string bestName = m_pak.bestEntryName(m_node, entry, named);
level.name = hecl::SystemStringConv(bestName).sys_str(); level.name = hecl::SystemStringConv(bestName).sys_str();
level.areas.reserve(mlvl.areaCount); level.areas.reserve(mlvl.areaCount);
unsigned layerIdx = 0; unsigned layerIdx = 0;
/* Make MAPW available to lookup MAPAs */ /* Make MAPW available to lookup MAPAs */
PAK::Entry* worldMapEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldMap); PAK::Entry* worldMapEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldMap);
std::vector<UniqueID32> mapw; std::vector<UniqueID32> mapw;
if (worldMapEnt) if (worldMapEnt) {
{ worldMapEnt->name = entry.name + "_mapw";
worldMapEnt->name = entry.name + "_mapw"; PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node);
PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node); rs.seek(8, athena::Current);
rs.seek(8, athena::Current); atUint32 areaCount = rs.readUint32Big();
atUint32 areaCount = rs.readUint32Big(); mapw.reserve(areaCount);
mapw.reserve(areaCount); for (atUint32 i = 0; i < areaCount; ++i)
for (atUint32 i=0 ; i<areaCount ; ++i) mapw.emplace_back(rs);
mapw.emplace_back(rs); }
}
PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId); PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId);
if (savwEnt) if (savwEnt)
savwEnt->name = entry.name + "_savw"; savwEnt->name = entry.name + "_savw";
PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId); PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId);
if (skyEnt) if (skyEnt)
skyEnt->name = entry.name + "_skybox"; skyEnt->name = entry.name + "_skybox";
/* Index areas */ /* Index areas */
unsigned ai = 0; unsigned ai = 0;
for (const MLVL::Area& area : mlvl.areas) for (const MLVL::Area& area : mlvl.areas) {
{ Level::Area& areaDeps = level.areas[area.areaMREAId];
Level::Area& areaDeps = level.areas[area.areaMREAId]; MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai];
MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai]; PAK::Entry* areaNameEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaNameId);
PAK::Entry* areaNameEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaNameId); if (areaNameEnt) {
if (areaNameEnt) STRG areaName;
{ {
STRG areaName; PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node);
{ areaName.read(rs);
PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node); }
areaName.read(rs); areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
} areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
}
if (areaDeps.name.empty())
{
std::string idStr = area.areaMREAId.toString();
areaDeps.name = hecl::SystemString(_SYS_STR("MREA_")) + hecl::SystemStringConv(idStr).c_str();
}
hecl::SystemChar num[16];
hecl::SNPrintf(num, 16, _SYS_STR("%02u "), ai);
areaDeps.name = num + areaDeps.name;
std::string lowerName(hecl::SystemUTF8Conv(areaDeps.name).str());
for (char& ch : lowerName)
{
ch = tolower(ch);
if (ch == ' ')
ch = '_';
}
if (areaNameEnt)
areaNameEnt->name = lowerName + "_name";
PAK::Entry* areaEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaMREAId);
if (areaEnt)
areaEnt->name = lowerName;
areaDeps.layers.reserve(area.depLayerCount-1);
unsigned r=0;
for (unsigned l=1 ; l<area.depLayerCount ; ++l)
{
areaDeps.layers.emplace_back();
Level::Area::Layer& layer = areaDeps.layers.back();
layer.name = LayerName(mlvl.layerNames[layerIdx++]);
layer.active = layerFlags.flags >> (l-1) & 0x1;
layer.name = hecl::StringUtils::TrimWhitespace(layer.name);
hecl::SNPrintf(num, 16, _SYS_STR("%02u "), l-1);
layer.name = num + layer.name;
layer.resources.reserve(area.depLayers[l] - r);
for (; r<area.depLayers[l] ; ++r)
layer.resources.emplace(area.deps[r].id);
}
areaDeps.resources.reserve(area.depCount - r + 2);
for (; r<area.depCount ; ++r)
areaDeps.resources.emplace(area.deps[r].id);
areaDeps.resources.emplace(area.areaMREAId);
if (mapw.size() > ai)
areaDeps.resources.emplace(mapw[ai]);
++ai;
}
} }
} if (areaDeps.name.empty()) {
std::string idStr = area.areaMREAId.toString();
areaDeps.name = hecl::SystemString(_SYS_STR("MREA_")) + hecl::SystemStringConv(idStr).c_str();
}
hecl::SystemChar num[16];
hecl::SNPrintf(num, 16, _SYS_STR("%02u "), ai);
areaDeps.name = num + areaDeps.name;
/* Second pass: cross-compare uniqueness */ std::string lowerName(hecl::SystemUTF8Conv(areaDeps.name).str());
for (auto& entry : m_pak.m_entries) for (char& ch : lowerName) {
{ ch = tolower(ch);
entry.second.unique.checkEntry(*this, entry.second); if (ch == ' ')
ch = '_';
}
if (areaNameEnt)
areaNameEnt->name = lowerName + "_name";
PAK::Entry* areaEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaMREAId);
if (areaEnt)
areaEnt->name = lowerName;
areaDeps.layers.reserve(area.depLayerCount - 1);
unsigned r = 0;
for (unsigned l = 1; l < area.depLayerCount; ++l) {
areaDeps.layers.emplace_back();
Level::Area::Layer& layer = areaDeps.layers.back();
layer.name = LayerName(mlvl.layerNames[layerIdx++]);
layer.active = layerFlags.flags >> (l - 1) & 0x1;
layer.name = hecl::StringUtils::TrimWhitespace(layer.name);
hecl::SNPrintf(num, 16, _SYS_STR("%02u "), l - 1);
layer.name = num + layer.name;
layer.resources.reserve(area.depLayers[l] - r);
for (; r < area.depLayers[l]; ++r)
layer.resources.emplace(area.deps[r].id);
}
areaDeps.resources.reserve(area.depCount - r + 2);
for (; r < area.depCount; ++r)
areaDeps.resources.emplace(area.deps[r].id);
areaDeps.resources.emplace(area.areaMREAId);
if (mapw.size() > ai)
areaDeps.resources.emplace(mapw[ai]);
++ai;
}
} }
}
/* Second pass: cross-compare uniqueness */
for (auto& entry : m_pak.m_entries) {
entry.second.unique.checkEntry(*this, entry.second);
}
} }
void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
{ for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) {
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) if (entry.second.type == FOURCC('ANCS')) {
{ PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
if (entry.second.type == FOURCC('ANCS')) ANCS ancs;
{ ancs.read(rs);
PAKEntryReadStream rs = entry.second.beginReadStream(m_node); for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) {
ANCS ancs; charAssoc.m_cmdlRigs[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
ancs.read(rs); charAssoc.m_cskrCinfToCharacter[ci.cskr] =
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) std::make_pair(entry.second.id, hecl::Format("%s.CSKR", ci.name.c_str()));
{ charAssoc.m_cskrCinfToCharacter[ci.cinf] =
charAssoc.m_cmdlRigs[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf); std::make_pair(entry.second.id, hecl::Format("CINF_%08X.CINF", ci.cinf.toUint32()));
charAssoc.m_cskrCinfToCharacter[ci.cskr] = PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl);
std::make_pair(entry.second.id, hecl::Format("%s.CSKR", ci.name.c_str())); PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr);
charAssoc.m_cskrCinfToCharacter[ci.cinf] = PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf);
std::make_pair(entry.second.id, hecl::Format("CINF_%08X.CINF", ci.cinf.toUint32())); cmdlEnt->name = hecl::Format("ANCS_%08X_%s_model", entry.first.toUint32(), ci.name.c_str());
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl); cskrEnt->name = hecl::Format("ANCS_%08X_%s_skin", entry.first.toUint32(), ci.name.c_str());
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr); cinfEnt->name = hecl::Format("ANCS_%08X_%s_skel", entry.first.toUint32(), ci.name.c_str());
PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf); if (ci.cmdlIce && ci.cskrIce) {
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_model", entry.first.toUint32(), ci.name.c_str()); charAssoc.m_cmdlRigs[ci.cmdlIce] = std::make_pair(ci.cskrIce, ci.cinf);
cskrEnt->name = hecl::Format("ANCS_%08X_%s_skin", entry.first.toUint32(), ci.name.c_str()); charAssoc.m_cskrCinfToCharacter[ci.cskrIce] =
cinfEnt->name = hecl::Format("ANCS_%08X_%s_skel", entry.first.toUint32(), ci.name.c_str()); std::make_pair(entry.second.id, hecl::Format("%s.ICE.CSKR", ci.name.c_str()));
if (ci.cmdlIce && ci.cskrIce) PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlIce);
{ PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrIce);
charAssoc.m_cmdlRigs[ci.cmdlIce] = std::make_pair(ci.cskrIce, ci.cinf); cmdlEnt->name = hecl::Format("ANCS_%08X_%s_icemodel", entry.first.toUint32(), ci.name.c_str());
charAssoc.m_cskrCinfToCharacter[ci.cskrIce] = cskrEnt->name = hecl::Format("ANCS_%08X_%s_iceskin", entry.first.toUint32(), ci.name.c_str());
std::make_pair(entry.second.id, hecl::Format("%s.ICE.CSKR", ci.name.c_str()));
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlIce);
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrIce);
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_icemodel", entry.first.toUint32(), ci.name.c_str());
cskrEnt->name = hecl::Format("ANCS_%08X_%s_iceskin", entry.first.toUint32(), ci.name.c_str());
}
}
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animInfo;
ancs.getAnimationResInfo(&pakRouter, animInfo);
for (auto& ae : animInfo)
{
PAK::Entry* animEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.animId);
animEnt->name = hecl::Format("ANCS_%08X_%s", entry.first.toUint32(), ae.second.name.c_str());
charAssoc.m_cskrCinfToCharacter[ae.second.animId] =
std::make_pair(entry.second.id, hecl::Format("%s.ANIM", ae.second.name.c_str()));
if (ae.second.evntId)
{
PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.evntId);
evntEnt->name = hecl::Format("ANCS_%08X_%s_evnt", entry.first.toUint32(), ae.second.name.c_str());
charAssoc.m_cskrCinfToCharacter[ae.second.evntId] =
std::make_pair(entry.second.id, hecl::Format("%s.evnt.yaml", ae.second.name.c_str()));
}
}
} }
else if (entry.second.type == FOURCC('MREA')) }
{ std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animInfo;
PAKEntryReadStream rs = entry.second.beginReadStream(m_node); ancs.getAnimationResInfo(&pakRouter, animInfo);
MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc); for (auto& ae : animInfo) {
PAK::Entry* animEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.animId);
animEnt->name = hecl::Format("ANCS_%08X_%s", entry.first.toUint32(), ae.second.name.c_str());
charAssoc.m_cskrCinfToCharacter[ae.second.animId] =
std::make_pair(entry.second.id, hecl::Format("%s.ANIM", ae.second.name.c_str()));
if (ae.second.evntId) {
PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.evntId);
evntEnt->name = hecl::Format("ANCS_%08X_%s_evnt", entry.first.toUint32(), ae.second.name.c_str());
charAssoc.m_cskrCinfToCharacter[ae.second.evntId] =
std::make_pair(entry.second.id, hecl::Format("%s.evnt.yaml", ae.second.name.c_str()));
} }
}
} else if (entry.second.type == FOURCC('MREA')) {
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc);
} }
}
} }
void PAKBridge::addPATHToMREA(PAKRouter<PAKBridge>& pakRouter, void PAKBridge::addPATHToMREA(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const {
{ for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) {
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) if (entry.second.type == FOURCC('MREA')) {
{ PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
if (entry.second.type == FOURCC('MREA')) UniqueID32 pathID = MREA::GetPATHId(rs);
{ if (pathID)
PAKEntryReadStream rs = entry.second.beginReadStream(m_node); pathToMrea[pathID] = entry.first;
UniqueID32 pathID = MREA::GetPATHId(rs);
if (pathID)
pathToMrea[pathID] = entry.first;
}
} }
}
} }
static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}}; static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}};
void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter, void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo, std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const {
{ for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) {
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) if (entry.second.type == FOURCC('MLVL')) {
{ MLVL mlvl;
if (entry.second.type == FOURCC('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, _SYS_STR("!name.yaml"));
for (const MLVL::Area& area : mlvl.areas) {
{ {
MLVL mlvl; /* Get PATH transform */
{ const nod::Node* areaNode;
PAKEntryReadStream rs = entry.second.beginReadStream(m_node); const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode);
mlvl.read(rs); PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode);
} UniqueID32 pathId = MREA::GetPATHId(rs);
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath(); if (pathId)
addTo[pathId] = zeus::CMatrix4f(area.transformMtx[0], area.transformMtx[1], area.transformMtx[2], BottomRow)
if (mlvl.worldNameId) .transposed();
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _SYS_STR("!name.yaml"));
for (const MLVL::Area& area : mlvl.areas)
{
{
/* Get PATH transform */
const nod::Node* areaNode;
const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode);
PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode);
UniqueID32 pathId = MREA::GetPATHId(rs);
if (pathId)
addTo[pathId] = zeus::CMatrix4f(
area.transformMtx[0],
area.transformMtx[1],
area.transformMtx[2],
BottomRow).transposed();
}
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
if (area.areaNameId)
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _SYS_STR("!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 nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry) hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
{ if (area.areaNameId)
switch (entry.type) pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _SYS_STR("!name.yaml"));
{ }
case SBIG('STRG'):
return {STRG::Extract, {_SYS_STR(".yaml")}}; if (mlvl.worldMap) {
case SBIG('SCAN'): const nod::Node* mapNode;
return {SCAN::Extract, {_SYS_STR(".yaml")}, 0, SCAN::Name}; const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode);
case SBIG('HINT'): if (mapEntry) {
return {HINT::Extract, {_SYS_STR(".yaml")}}; PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode);
case SBIG('SAVW'): u32 magic = rs.readUint32Big();
return {SAVWCommon::ExtractSAVW<SAVW>, {_SYS_STR(".yaml")}}; if (magic == 0xDEADF00D) {
case SBIG('TXTR'): rs.readUint32Big();
return {TXTR::Extract, {_SYS_STR(".png")}}; u32 count = rs.readUint32Big();
case SBIG('AFSM'): for (u32 i = 0; i < count && i < mlvl.areas.size(); ++i) {
return {AFSM::Extract, {_SYS_STR(".yaml")}}; MLVL::Area& areaData = mlvl.areas[i];
case SBIG('FRME'): UniqueID32 mapaId;
return {FRME::Extract, {_SYS_STR(".blend")}, 2}; mapaId.read(rs);
case SBIG('CMDL'): addTo[mapaId] = zeus::CMatrix4f(areaData.transformMtx[0], areaData.transformMtx[1],
return {CMDL::Extract, {_SYS_STR(".blend")}, 1, CMDL::Name}; areaData.transformMtx[2], BottomRow)
case SBIG('DCLN'): .transposed();
return {DCLN::Extract, {_SYS_STR(".blend")}}; }
case SBIG('ANCS'): }
return {ANCS::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 2};
case SBIG('MLVL'):
return {MLVL::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 3};
case SBIG('MREA'):
return {MREA::Extract, {_SYS_STR(".blend")}, 4, MREA::Name};
case SBIG('MAPA'):
return {MAPA::Extract, {_SYS_STR(".blend")}, 4};
case SBIG('MAPU'):
return {MAPU::Extract, {_SYS_STR(".blend")}, 5};
case SBIG('PATH'):
return {PATH::Extract, {_SYS_STR(".blend")}, 5};
case SBIG('PART'):
return {DNAParticle::ExtractGPSM<UniqueID32>, {_SYS_STR(".gpsm.yaml")}};
case SBIG('ELSC'):
return {DNAParticle::ExtractELSM<UniqueID32>, {_SYS_STR(".elsm.yaml")}};
case SBIG('SWHC'):
return {DNAParticle::ExtractSWSH<UniqueID32>, {_SYS_STR(".swsh.yaml")}};
case SBIG('CRSC'):
return {DNAParticle::ExtractCRSM<UniqueID32>, {_SYS_STR(".crsm.yaml")}};
case SBIG('WPSC'):
return {DNAParticle::ExtractWPSM<UniqueID32>, {_SYS_STR(".wpsm.yaml")}};
case SBIG('DPSC'):
return {DNAParticle::ExtractDPSM<UniqueID32>, {_SYS_STR(".dpsm.yaml")}};
case SBIG('FONT'):
return {DNAFont::ExtractFONT<UniqueID32>, {_SYS_STR(".yaml")}};
case SBIG('DGRP'):
return {DNADGRP::ExtractDGRP<UniqueID32>, {_SYS_STR(".yaml")}};
case SBIG('AGSC'):
return {AGSC::Extract, {}};
case SBIG('CSNG'):
return {CSNG::Extract, {_SYS_STR(".mid"), _SYS_STR(".yaml")}};
case SBIG('ATBL'):
return {DNAAudio::ATBL::Extract, {_SYS_STR(".yaml")}};
case SBIG('CTWK'):
case SBIG('DUMB'):
{
bool named;
std::string name = pak.bestEntryName(pakNode, entry, named);
if (named)
{
if (!name.compare("PlayerRes"))
return {ExtractTweak<CTweakPlayerRes>, {_SYS_STR(".yaml")}};
if (!name.compare("GunRes"))
return {ExtractTweak<CTweakGunRes>, {_SYS_STR(".yaml")}};
if (!name.compare("Player"))
return {ExtractTweak<CTweakPlayer>, {_SYS_STR(".yaml")}};
if (!name.compare("CameraBob"))
return {ExtractTweak<CTweakCameraBob>, {_SYS_STR(".yaml")}};
if (!name.compare("SlideShow"))
return {ExtractTweak<CTweakSlideShow>, {_SYS_STR(".yaml")}};
if (!name.compare("Game"))
return {ExtractTweak<CTweakGame>, {_SYS_STR(".yaml")}};
if (!name.compare("Targeting"))
return {ExtractTweak<CTweakTargeting>, {_SYS_STR(".yaml")}};
if (!name.compare("Gui"))
return {ExtractTweak<CTweakGui>, {_SYS_STR(".yaml")}};
if (!name.compare("AutoMapper"))
return {ExtractTweak<CTweakAutoMapper>, {_SYS_STR(".yaml")}};
if (!name.compare("PlayerControls") || !name.compare("PlayerControls2"))
return {ExtractTweak<CTweakPlayerControl>, {_SYS_STR(".yaml")}};
if (!name.compare("Ball"))
return {ExtractTweak<CTweakBall>, {_SYS_STR(".yaml")}};
if (!name.compare("Particle"))
return {ExtractTweak<CTweakParticle>, {_SYS_STR(".yaml")}};
if (!name.compare("GuiColors"))
return {ExtractTweak<CTweakGuiColors>, {_SYS_STR(".yaml")}};
if (!name.compare("PlayerGun"))
return {ExtractTweak<CTweakPlayerGun>, {_SYS_STR(".yaml")}};
if (!name.compare("DUMB_MazeSeeds"))
return {ExtractTweak<MazeSeeds>, {_SYS_STR(".yaml")}};
if (!name.compare("DUMB_SnowForces"))
return {ExtractTweak<SnowForces>, {_SYS_STR(".yaml")}};
} }
break; }
} }
} }
return {};
} }
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry) {
switch (entry.type) {
case SBIG('STRG'):
return {STRG::Extract, {_SYS_STR(".yaml")}};
case SBIG('SCAN'):
return {SCAN::Extract, {_SYS_STR(".yaml")}, 0, SCAN::Name};
case SBIG('HINT'):
return {HINT::Extract, {_SYS_STR(".yaml")}};
case SBIG('SAVW'):
return {SAVWCommon::ExtractSAVW<SAVW>, {_SYS_STR(".yaml")}};
case SBIG('TXTR'):
return {TXTR::Extract, {_SYS_STR(".png")}};
case SBIG('AFSM'):
return {AFSM::Extract, {_SYS_STR(".yaml")}};
case SBIG('FRME'):
return {FRME::Extract, {_SYS_STR(".blend")}, 2};
case SBIG('CMDL'):
return {CMDL::Extract, {_SYS_STR(".blend")}, 1, CMDL::Name};
case SBIG('DCLN'):
return {DCLN::Extract, {_SYS_STR(".blend")}};
case SBIG('ANCS'):
return {ANCS::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 2};
case SBIG('MLVL'):
return {MLVL::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 3};
case SBIG('MREA'):
return {MREA::Extract, {_SYS_STR(".blend")}, 4, MREA::Name};
case SBIG('MAPA'):
return {MAPA::Extract, {_SYS_STR(".blend")}, 4};
case SBIG('MAPU'):
return {MAPU::Extract, {_SYS_STR(".blend")}, 5};
case SBIG('PATH'):
return {PATH::Extract, {_SYS_STR(".blend")}, 5};
case SBIG('PART'):
return {DNAParticle::ExtractGPSM<UniqueID32>, {_SYS_STR(".gpsm.yaml")}};
case SBIG('ELSC'):
return {DNAParticle::ExtractELSM<UniqueID32>, {_SYS_STR(".elsm.yaml")}};
case SBIG('SWHC'):
return {DNAParticle::ExtractSWSH<UniqueID32>, {_SYS_STR(".swsh.yaml")}};
case SBIG('CRSC'):
return {DNAParticle::ExtractCRSM<UniqueID32>, {_SYS_STR(".crsm.yaml")}};
case SBIG('WPSC'):
return {DNAParticle::ExtractWPSM<UniqueID32>, {_SYS_STR(".wpsm.yaml")}};
case SBIG('DPSC'):
return {DNAParticle::ExtractDPSM<UniqueID32>, {_SYS_STR(".dpsm.yaml")}};
case SBIG('FONT'):
return {DNAFont::ExtractFONT<UniqueID32>, {_SYS_STR(".yaml")}};
case SBIG('DGRP'):
return {DNADGRP::ExtractDGRP<UniqueID32>, {_SYS_STR(".yaml")}};
case SBIG('AGSC'):
return {AGSC::Extract, {}};
case SBIG('CSNG'):
return {CSNG::Extract, {_SYS_STR(".mid"), _SYS_STR(".yaml")}};
case SBIG('ATBL'):
return {DNAAudio::ATBL::Extract, {_SYS_STR(".yaml")}};
case SBIG('CTWK'):
case SBIG('DUMB'): {
bool named;
std::string name = pak.bestEntryName(pakNode, entry, named);
if (named) {
if (!name.compare("PlayerRes"))
return {ExtractTweak<CTweakPlayerRes>, {_SYS_STR(".yaml")}};
if (!name.compare("GunRes"))
return {ExtractTweak<CTweakGunRes>, {_SYS_STR(".yaml")}};
if (!name.compare("Player"))
return {ExtractTweak<CTweakPlayer>, {_SYS_STR(".yaml")}};
if (!name.compare("CameraBob"))
return {ExtractTweak<CTweakCameraBob>, {_SYS_STR(".yaml")}};
if (!name.compare("SlideShow"))
return {ExtractTweak<CTweakSlideShow>, {_SYS_STR(".yaml")}};
if (!name.compare("Game"))
return {ExtractTweak<CTweakGame>, {_SYS_STR(".yaml")}};
if (!name.compare("Targeting"))
return {ExtractTweak<CTweakTargeting>, {_SYS_STR(".yaml")}};
if (!name.compare("Gui"))
return {ExtractTweak<CTweakGui>, {_SYS_STR(".yaml")}};
if (!name.compare("AutoMapper"))
return {ExtractTweak<CTweakAutoMapper>, {_SYS_STR(".yaml")}};
if (!name.compare("PlayerControls") || !name.compare("PlayerControls2"))
return {ExtractTweak<CTweakPlayerControl>, {_SYS_STR(".yaml")}};
if (!name.compare("Ball"))
return {ExtractTweak<CTweakBall>, {_SYS_STR(".yaml")}};
if (!name.compare("Particle"))
return {ExtractTweak<CTweakParticle>, {_SYS_STR(".yaml")}};
if (!name.compare("GuiColors"))
return {ExtractTweak<CTweakGuiColors>, {_SYS_STR(".yaml")}};
if (!name.compare("PlayerGun"))
return {ExtractTweak<CTweakPlayerGun>, {_SYS_STR(".yaml")}};
if (!name.compare("DUMB_MazeSeeds"))
return {ExtractTweak<MazeSeeds>, {_SYS_STR(".yaml")}};
if (!name.compare("DUMB_SnowForces"))
return {ExtractTweak<SnowForces>, {_SYS_STR(".yaml")}};
}
break;
}
}
return {};
} }
} // namespace DataSpec::DNAMP1

View File

@ -4,40 +4,36 @@
#include "PAK.hpp" #include "PAK.hpp"
#include "zeus/CMatrix4f.hpp" #include "zeus/CMatrix4f.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
extern logvisor::Module Log; extern logvisor::Module Log;
/* MP1-specific, one-shot PAK traversal/extraction class */ /* MP1-specific, one-shot PAK traversal/extraction class */
class PAKBridge class PAKBridge {
{ const nod::Node& m_node;
const nod::Node& m_node; PAK m_pak;
PAK m_pak;
public: public:
bool m_doExtract; bool m_doExtract;
using Level = DataSpec::Level<UniqueID32>; using Level = DataSpec::Level<UniqueID32>;
std::unordered_map<UniqueID32, Level> m_levelDeps; std::unordered_map<UniqueID32, Level> m_levelDeps;
hecl::SystemString m_levelString; hecl::SystemString m_levelString;
PAKBridge(const nod::Node& node, bool doExtract=true); PAKBridge(const nod::Node& node, bool doExtract = true);
void build(); void build();
static ResExtractor<PAKBridge> LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry); static ResExtractor<PAKBridge> LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry);
std::string_view getName() const {return m_node.getName();} std::string_view getName() const { return m_node.getName(); }
hecl::SystemStringView getLevelString() const {return m_levelString;} hecl::SystemStringView getLevelString() const { return m_levelString; }
using PAKType = PAK; using PAKType = PAK;
const PAKType& getPAK() const {return m_pak;} const PAKType& getPAK() const { return m_pak; }
const nod::Node& getNode() const {return m_node;} const nod::Node& getNode() const { return m_node; }
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const; void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const;
void addPATHToMREA(PAKRouter<PAKBridge>& pakRouter, void addPATHToMREA(PAKRouter<PAKBridge>& pakRouter, std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const;
std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const;
void addMAPATransforms(PAKRouter<PAKBridge>& pakRouter, void addMAPATransforms(PAKRouter<PAKBridge>& pakRouter, std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo, std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const;
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const;
}; };
} } // namespace DataSpec::DNAMP1

View File

@ -1,233 +1,232 @@
#include "DeafBabe.hpp" #include "DeafBabe.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) {
{ os << "TYPE_COLORS = {'NoSFX':(0.0, 0.0, 0.0),\n"
os << "TYPE_COLORS = {'NoSFX':(0.0, 0.0, 0.0),\n" " 'Stone':(1.0, 0.43, 0.15),\n"
" 'Stone':(1.0, 0.43, 0.15),\n" " 'Metal':(0.5, 0.5, 0.5),\n"
" 'Metal':(0.5, 0.5, 0.5),\n" " 'Grass':(0.0, 0.42, 0.01),"
" 'Grass':(0.0, 0.42, 0.01)," " 'Ice':(0.0, 0.1, 0.1),\n"
" 'Ice':(0.0, 0.1, 0.1),\n" " 'Metal Grating':(0.09, 0.09, 0.09),\n"
" 'Metal Grating':(0.09, 0.09, 0.09),\n" " 'Phazon':(0.24, 0.0, 0.21),\n"
" 'Phazon':(0.24, 0.0, 0.21),\n" " 'Dirt':(0.1, 0.07, 0.05),\n"
" 'Dirt':(0.1, 0.07, 0.05),\n" " 'Stone':(0.12, 0.12, 0.12),\n"
" 'Stone':(0.12, 0.12, 0.12),\n" " 'Lava':(0.8, 0.15, 0.0),\n"
" 'Lava':(0.8, 0.15, 0.0),\n" " 'Stone/Rock':(0.06, 0.05, 0.03),\n"
" 'Stone/Rock':(0.06, 0.05, 0.03),\n" " 'Snow':(0.9, 1.0, 1.0),\n"
" 'Snow':(0.9, 1.0, 1.0),\n" " 'Mud (Slow)':(0.12, 0.06, 0.02),\n"
" 'Mud (Slow)':(0.12, 0.06, 0.02),\n" " 'Mud':(0.12, 0.06, 0.02),\n"
" 'Mud':(0.12, 0.06, 0.02),\n" " 'Glass':(0.27, 0.38, 0.9),\n"
" 'Glass':(0.27, 0.38, 0.9),\n" " 'Shield':(1.0, 0.6, 0.0),\n"
" 'Shield':(1.0, 0.6, 0.0),\n" " 'Sand':(0.53, 0.44, 0.21),\n"
" 'Sand':(0.53, 0.44, 0.21),\n" " 'Wood':(0.30, 0.15, 0.03),\n"
" 'Wood':(0.30, 0.15, 0.03),\n" " 'Organic':(0.19, 0.45, 0.2)}\n"
" 'Organic':(0.19, 0.45, 0.2)}\n" "\n"
"\n" "# Diffuse Color Maker\n"
"# Diffuse Color Maker\n" "def make_color(index, mat_type, name):\n"
"def make_color(index, mat_type, name):\n" " new_mat = bpy.data.materials.new(name)\n"
" new_mat = bpy.data.materials.new(name)\n" " if mat_type in TYPE_COLORS:\n"
" if mat_type in TYPE_COLORS:\n" " new_mat.diffuse_color = TYPE_COLORS[mat_type]\n"
" new_mat.diffuse_color = TYPE_COLORS[mat_type]\n" " else:\n"
" else:\n" " new_mat.diffuse_color.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n"
" new_mat.diffuse_color.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n" " return new_mat\n"
" return new_mat\n" "\n"
"\n" "bpy.types.Material.retro_unknown = bpy.props.BoolProperty(name='Retro: Unknown (U)')\n"
"bpy.types.Material.retro_unknown = bpy.props.BoolProperty(name='Retro: Unknown (U)')\n" "bpy.types.Material.retro_surface_stone = bpy.props.BoolProperty(name='Retro Surface: Stone')\n"
"bpy.types.Material.retro_surface_stone = bpy.props.BoolProperty(name='Retro Surface: Stone')\n" "bpy.types.Material.retro_surface_metal = bpy.props.BoolProperty(name='Retro Surface: Metal')\n"
"bpy.types.Material.retro_surface_metal = bpy.props.BoolProperty(name='Retro Surface: Metal')\n" "bpy.types.Material.retro_surface_grass = bpy.props.BoolProperty(name='Retro Surface: Grass')\n"
"bpy.types.Material.retro_surface_grass = bpy.props.BoolProperty(name='Retro Surface: Grass')\n" "bpy.types.Material.retro_surface_ice = bpy.props.BoolProperty(name='Retro Surface: Ice')\n"
"bpy.types.Material.retro_surface_ice = bpy.props.BoolProperty(name='Retro Surface: Ice')\n" "bpy.types.Material.retro_pillar = bpy.props.BoolProperty(name='Retro Pillar (I)')\n"
"bpy.types.Material.retro_pillar = bpy.props.BoolProperty(name='Retro Pillar (I)')\n" "bpy.types.Material.retro_surface_metal_grating = bpy.props.BoolProperty(name='Retro Surface: Metal Grating')\n"
"bpy.types.Material.retro_surface_metal_grating = bpy.props.BoolProperty(name='Retro Surface: Metal Grating')\n" "bpy.types.Material.retro_surface_phazon = bpy.props.BoolProperty(name='Retro Surface: Phazon')\n"
"bpy.types.Material.retro_surface_phazon = bpy.props.BoolProperty(name='Retro Surface: Phazon')\n" "bpy.types.Material.retro_surface_dirt = bpy.props.BoolProperty(name='Retro Surface: Rock')\n"
"bpy.types.Material.retro_surface_dirt = bpy.props.BoolProperty(name='Retro Surface: Rock')\n" "bpy.types.Material.retro_surface_lava = bpy.props.BoolProperty(name='Retro Surface: Lava')\n"
"bpy.types.Material.retro_surface_lava = bpy.props.BoolProperty(name='Retro Surface: Lava')\n" "bpy.types.Material.retro_surface_lava_stone = bpy.props.BoolProperty(name='Retro Surface: Lava Stone')\n"
"bpy.types.Material.retro_surface_lava_stone = bpy.props.BoolProperty(name='Retro Surface: Lava Stone')\n" "bpy.types.Material.retro_surface_snow = bpy.props.BoolProperty(name='Retro Surface: Snow')\n"
"bpy.types.Material.retro_surface_snow = bpy.props.BoolProperty(name='Retro Surface: Snow')\n" "bpy.types.Material.retro_surface_mud_slow = bpy.props.BoolProperty(name='Retro Surface: Mud (Slow)')\n"
"bpy.types.Material.retro_surface_mud_slow = bpy.props.BoolProperty(name='Retro Surface: Mud (Slow)')\n" "bpy.types.Material.retro_half_pipe = bpy.props.BoolProperty(name='Retro: Half Pipe (H)')\n"
"bpy.types.Material.retro_half_pipe = bpy.props.BoolProperty(name='Retro: Half Pipe (H)')\n" "bpy.types.Material.retro_surface_mud = bpy.props.BoolProperty(name='Retro Surface: Mud')\n"
"bpy.types.Material.retro_surface_mud = bpy.props.BoolProperty(name='Retro Surface: Mud')\n" "bpy.types.Material.retro_surface_glass = bpy.props.BoolProperty(name='Retro Surface: Glass')\n"
"bpy.types.Material.retro_surface_glass = bpy.props.BoolProperty(name='Retro Surface: Glass')\n" "bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(name='Retro Surface: Shield')\n"
"bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(name='Retro Surface: Shield')\n" "bpy.types.Material.retro_surface_sand = bpy.props.BoolProperty(name='Retro Surface: Sand')\n"
"bpy.types.Material.retro_surface_sand = bpy.props.BoolProperty(name='Retro Surface: Sand')\n" "bpy.types.Material.retro_projectile_passthrough = bpy.props.BoolProperty(name='Retro: Projectile Passthrough "
"bpy.types.Material.retro_projectile_passthrough = bpy.props.BoolProperty(name='Retro: Projectile Passthrough (P)')\n" "(P)')\n"
"bpy.types.Material.retro_solid = bpy.props.BoolProperty(name='Retro: Solid (K)')\n" "bpy.types.Material.retro_solid = bpy.props.BoolProperty(name='Retro: Solid (K)')\n"
"bpy.types.Material.retro_no_platform_collision = bpy.props.BoolProperty(name='Retro: No Platform Collision')\n" "bpy.types.Material.retro_no_platform_collision = bpy.props.BoolProperty(name='Retro: No Platform Collision')\n"
"bpy.types.Material.retro_camera_passthrough = bpy.props.BoolProperty(name='Retro: Camera Passthrough (O)')\n" "bpy.types.Material.retro_camera_passthrough = bpy.props.BoolProperty(name='Retro: Camera Passthrough (O)')\n"
"bpy.types.Material.retro_surface_wood = bpy.props.BoolProperty(name='Retro Surface: Wood')\n" "bpy.types.Material.retro_surface_wood = bpy.props.BoolProperty(name='Retro Surface: Wood')\n"
"bpy.types.Material.retro_surface_organic = bpy.props.BoolProperty(name='Retro Surface: Organic')\n" "bpy.types.Material.retro_surface_organic = bpy.props.BoolProperty(name='Retro Surface: Organic')\n"
"bpy.types.Material.retro_no_edge_collision = bpy.props.BoolProperty(name='Retro: No Edge Collision')\n" "bpy.types.Material.retro_no_edge_collision = bpy.props.BoolProperty(name='Retro: No Edge Collision')\n"
"bpy.types.Material.retro_see_through = bpy.props.BoolProperty(name='Retro: See Through')\n" "bpy.types.Material.retro_see_through = bpy.props.BoolProperty(name='Retro: See Through')\n"
"bpy.types.Material.retro_scan_passthrough = bpy.props.BoolProperty(name='Retro: Scan Passthrough (S)')\n" "bpy.types.Material.retro_scan_passthrough = bpy.props.BoolProperty(name='Retro: Scan Passthrough (S)')\n"
"bpy.types.Material.retro_ai_passthrough = bpy.props.BoolProperty(name='Retro: AI Passthrough (A)')\n" "bpy.types.Material.retro_ai_passthrough = bpy.props.BoolProperty(name='Retro: AI Passthrough (A)')\n"
"bpy.types.Material.retro_ceiling = bpy.props.BoolProperty(name='Retro: Ceiling (C)')\n" "bpy.types.Material.retro_ceiling = bpy.props.BoolProperty(name='Retro: Ceiling (C)')\n"
"bpy.types.Material.retro_wall = bpy.props.BoolProperty(name='Retro: Wall (W)')\n" "bpy.types.Material.retro_wall = bpy.props.BoolProperty(name='Retro: Wall (W)')\n"
"bpy.types.Material.retro_floor = bpy.props.BoolProperty(name='Retro: Floor (F)')\n" "bpy.types.Material.retro_floor = bpy.props.BoolProperty(name='Retro: Floor (F)')\n"
"\n" "\n"
"material_dict = {}\n" "material_dict = {}\n"
"material_index = []\n" "material_index = []\n"
"def get_type_id(data):\n" "def get_type_id(data):\n"
"\n" "\n"
" ret = 0\n" " ret = 0\n"
" for i in range(1, 24):\n" " for i in range(1, 24):\n"
" if i == 5 or i == 13 or i in range(18, 22):\n" " if i == 5 or i == 13 or i in range(18, 22):\n"
" continue\n" " continue\n"
" if ((data >> i) & 1):\n" " if ((data >> i) & 1):\n"
" ret = i\n" " ret = i\n"
" return ret\n" " return ret\n"
"\n" "\n"
"def select_material(data):\n" "def select_material(data):\n"
"\n" "\n"
" type_id = get_type_id(data)\n" " type_id = get_type_id(data)\n"
" mat_type = str(type_id)\n" " mat_type = str(type_id)\n"
" if type_id == 0:\n" " if type_id == 0:\n"
" mat_type = 'NoSFX'\n" " mat_type = 'NoSFX'\n"
" if type_id == 1:\n" " if type_id == 1:\n"
" mat_type = 'Stone'\n" " mat_type = 'Stone'\n"
" elif type_id == 2:\n" " elif type_id == 2:\n"
" mat_type = 'Metal'\n" " mat_type = 'Metal'\n"
" elif type_id == 3:\n" " elif type_id == 3:\n"
" mat_type = 'Grass'\n" " mat_type = 'Grass'\n"
" elif type_id == 4:\n" " elif type_id == 4:\n"
" mat_type = 'Ice'\n" " mat_type = 'Ice'\n"
" elif type_id == 6:\n" " elif type_id == 6:\n"
" mat_type = 'Metal Grating'\n" " mat_type = 'Metal Grating'\n"
" elif type_id == 7:\n" " elif type_id == 7:\n"
" mat_type = 'Phazon'\n" " mat_type = 'Phazon'\n"
" elif type_id == 8:\n" " elif type_id == 8:\n"
" mat_type = 'Dirt'\n" " mat_type = 'Dirt'\n"
" elif type_id == 9:\n" " elif type_id == 9:\n"
" mat_type = 'Lava'\n" " mat_type = 'Lava'\n"
" elif type_id == 10:\n" " elif type_id == 10:\n"
" mat_type = 'Stone/Rock'\n" " mat_type = 'Stone/Rock'\n"
" elif type_id == 11:\n" " elif type_id == 11:\n"
" mat_type = 'Snow'\n" " mat_type = 'Snow'\n"
" elif type_id == 12:\n" " elif type_id == 12:\n"
" mat_type = 'Mud (Slow)'\n" " mat_type = 'Mud (Slow)'\n"
" elif type_id == 14:\n" " elif type_id == 14:\n"
" mat_type = 'Mud'\n" " mat_type = 'Mud'\n"
" elif type_id == 15:\n" " elif type_id == 15:\n"
" mat_type = 'Glass'\n" " mat_type = 'Glass'\n"
" elif type_id == 16:\n" " elif type_id == 16:\n"
" mat_type = 'Shield'\n" " mat_type = 'Shield'\n"
" elif type_id == 17:\n" " elif type_id == 17:\n"
" mat_type = 'Sand'\n" " mat_type = 'Sand'\n"
" elif type_id == 22:\n" " elif type_id == 22:\n"
" mat_type = 'Wood'\n" " mat_type = 'Wood'\n"
" elif type_id == 23:\n" " elif type_id == 23:\n"
" mat_type = 'Organic'\n" " mat_type = 'Organic'\n"
"\n" "\n"
" mat_flags = ''\n" " mat_flags = ''\n"
" if ((data >> 0) & 1):\n" " if ((data >> 0) & 1):\n"
" mat_flags += 'U'\n" " mat_flags += 'U'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 5) & 1):\n" " if ((data >> 5) & 1):\n"
" mat_flags += 'I'\n" " mat_flags += 'I'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 13) & 1):\n" " if ((data >> 13) & 1):\n"
" mat_flags += 'H'\n" " mat_flags += 'H'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 18) & 1):\n" " if ((data >> 18) & 1):\n"
" mat_flags += 'P'\n" " mat_flags += 'P'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 19) & 1):\n" " if ((data >> 19) & 1):\n"
" mat_flags += 'K'\n" " mat_flags += 'K'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 20) & 1):\n" " if ((data >> 20) & 1):\n"
" mat_flags += 'u'\n" " mat_flags += 'u'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 21) & 1):\n" " if ((data >> 21) & 1):\n"
" mat_flags += 'O'\n" " mat_flags += 'O'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 24) & 1):\n" " if ((data >> 24) & 1):\n"
" mat_flags += 'u'\n" " mat_flags += 'u'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 26) & 1):\n" " if ((data >> 26) & 1):\n"
" mat_flags += 'T'\n" " mat_flags += 'T'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 27) & 1):\n" " if ((data >> 27) & 1):\n"
" mat_flags += 'S'\n" " mat_flags += 'S'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 28) & 1):\n" " if ((data >> 28) & 1):\n"
" mat_flags += 'A'\n" " mat_flags += 'A'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 29) & 1):\n" " if ((data >> 29) & 1):\n"
" mat_flags += 'C'\n" " mat_flags += 'C'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 30) & 1):\n" " if ((data >> 30) & 1):\n"
" mat_flags += 'W'\n" " mat_flags += 'W'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
" if ((data >> 31) & 1):\n" " if ((data >> 31) & 1):\n"
" mat_flags += 'F'\n" " mat_flags += 'F'\n"
" else:\n" " else:\n"
" mat_flags += 'x'\n" " mat_flags += 'x'\n"
"\n" "\n"
" if len(mat_flags) > 0:\n" " if len(mat_flags) > 0:\n"
" mat_flags = ' ' + mat_flags\n" " mat_flags = ' ' + mat_flags\n"
"\n" "\n"
" mat_name = mat_type + mat_flags\n" " mat_name = mat_type + mat_flags\n"
"\n" "\n"
" if mat_name in material_index:\n" " if mat_name in material_index:\n"
" return material_index.index(mat_name)\n" " return material_index.index(mat_name)\n"
" elif mat_name in material_dict:\n" " elif mat_name in material_dict:\n"
" material_index.append(mat_name)\n" " material_index.append(mat_name)\n"
" return len(material_index)-1\n" " return len(material_index)-1\n"
" else:\n" " else:\n"
" mat = make_color(len(material_dict), mat_type, mat_name)\n" " mat = make_color(len(material_dict), mat_type, mat_name)\n"
" mat.diffuse_intensity = 1.0\n" " mat.diffuse_intensity = 1.0\n"
" mat.specular_intensity = 0.0\n" " mat.specular_intensity = 0.0\n"
" mat.retro_unknown = ((data >> 0) & 1)\n" " mat.retro_unknown = ((data >> 0) & 1)\n"
" mat.retro_surface_stone = ((data >> 1) & 1)\n" " mat.retro_surface_stone = ((data >> 1) & 1)\n"
" mat.retro_surface_metal = ((data >> 2) & 1)\n" " mat.retro_surface_metal = ((data >> 2) & 1)\n"
" mat.retro_surface_grass = ((data >> 3) & 1) \n" " mat.retro_surface_grass = ((data >> 3) & 1) \n"
" mat.retro_surface_ice = ((data >> 4) & 1)\n" " mat.retro_surface_ice = ((data >> 4) & 1)\n"
" mat.retro_pillar = ((data >> 5) & 1)\n" " mat.retro_pillar = ((data >> 5) & 1)\n"
" mat.retro_surface_metal_grating = ((data >> 6) & 1)\n" " mat.retro_surface_metal_grating = ((data >> 6) & 1)\n"
" mat.retro_surface_phazon = ((data >> 7) & 1)\n" " mat.retro_surface_phazon = ((data >> 7) & 1)\n"
" mat.retro_surface_dirt = ((data >> 8) & 1)\n" " mat.retro_surface_dirt = ((data >> 8) & 1)\n"
" mat.retro_surface_lava = ((data >> 9) & 1)\n" " mat.retro_surface_lava = ((data >> 9) & 1)\n"
" mat.retro_surface_lava_stone = ((data >> 10) & 1)\n" " mat.retro_surface_lava_stone = ((data >> 10) & 1)\n"
" mat.retro_surface_snow = ((data >> 11) & 1)\n" " mat.retro_surface_snow = ((data >> 11) & 1)\n"
" mat.retro_surface_mud_slow = ((data >> 12) & 1)\n" " mat.retro_surface_mud_slow = ((data >> 12) & 1)\n"
" mat.retro_half_pipe = ((data >> 13) & 1)\n" " mat.retro_half_pipe = ((data >> 13) & 1)\n"
" mat.retro_surface_mud = ((data >> 14) & 1)\n" " mat.retro_surface_mud = ((data >> 14) & 1)\n"
" mat.retro_surface_glass = ((data >> 15) & 1)\n" " mat.retro_surface_glass = ((data >> 15) & 1)\n"
" mat.retro_surface_shield = ((data >> 16) & 1)\n" " mat.retro_surface_shield = ((data >> 16) & 1)\n"
" mat.retro_surface_sand = ((data >> 17) & 1)\n" " mat.retro_surface_sand = ((data >> 17) & 1)\n"
" mat.retro_projectile_passthrough = ((data >> 18) & 1)\n" " mat.retro_projectile_passthrough = ((data >> 18) & 1)\n"
" mat.retro_solid = ((data >> 19) & 1)\n" " mat.retro_solid = ((data >> 19) & 1)\n"
" mat.retro_no_platform_collision = ((data >> 20) & 1)\n" " mat.retro_no_platform_collision = ((data >> 20) & 1)\n"
" mat.retro_camera_passthrough = ((data >> 21) & 1)\n" " mat.retro_camera_passthrough = ((data >> 21) & 1)\n"
" mat.retro_surface_wood = ((data >> 22) & 1)\n" " mat.retro_surface_wood = ((data >> 22) & 1)\n"
" mat.retro_surface_organic = ((data >> 23) & 1)\n" " mat.retro_surface_organic = ((data >> 23) & 1)\n"
" mat.retro_no_edge_collision = ((data >> 24) & 1)\n" " mat.retro_no_edge_collision = ((data >> 24) & 1)\n"
" mat.retro_see_through = ((data >> 26) & 1)\n" " mat.retro_see_through = ((data >> 26) & 1)\n"
" mat.retro_scan_passthrough = ((data >> 27) & 1)\n" " mat.retro_scan_passthrough = ((data >> 27) & 1)\n"
" mat.retro_ai_passthrough = ((data >> 28) & 1)\n" " mat.retro_ai_passthrough = ((data >> 28) & 1)\n"
" mat.retro_ceiling = ((data >> 29) & 1)\n" " mat.retro_ceiling = ((data >> 29) & 1)\n"
" mat.retro_wall= ((data >> 30) & 1)\n" " mat.retro_wall= ((data >> 30) & 1)\n"
" mat.retro_floor = ((data >> 31) & 1)\n" " mat.retro_floor = ((data >> 31) & 1)\n"
" material_dict[mat_name] = mat\n" " material_dict[mat_name] = mat\n"
" material_index.append(mat_name)\n" " material_index.append(mat_name)\n"
" return len(material_index)-1\n" " return len(material_index)-1\n"
"\n" "\n"
"\n"; "\n";
} }
} } // namespace DataSpec::DNAMP1

View File

@ -2,152 +2,239 @@
#include "DataSpec/DNACommon/DeafBabe.hpp" #include "DataSpec/DNACommon/DeafBabe.hpp"
namespace DataSpec::DNAMP1 namespace DataSpec::DNAMP1 {
{
struct DeafBabe : BigDNA struct DeafBabe : BigDNA {
{ AT_DECL_DNA
using BspNodeType = DataSpec::BspNodeType;
struct Material : BigDNA {
AT_DECL_DNA AT_DECL_DNA
using BspNodeType = DataSpec::BspNodeType; Value<atUint32> material = 0;
bool unknown() const { return material & 1; }
struct Material : BigDNA void setUnknown(bool v) {
{ material &= ~1;
AT_DECL_DNA material |= int(v);
Value<atUint32> material = 0;
bool unknown() const { return material & 1; }
void setUnknown(bool v) { material &= ~1; material |= int(v); }
bool surfaceStone() const { return (material >> 1) & 1; }
void setSurfaceStone(bool v) { material &= ~(1ull << 1); material |= (v << 1); }
bool surfaceMetal() const { return (material >> 2) & 1; }
void setSurfaceMetal(bool v) { material &= ~(1ull << 2); material |= (v << 2); }
bool surfaceGrass() const { return (material >> 3) & 1; }
void setSurfaceGrass(bool v) { material &= ~(1ull << 3); material |= (v << 3); }
bool surfaceIce() const { return (material >> 4) & 1; }
void setSurfaceIce(bool v) { material &= ~(1ull << 4); material |= (v << 4); }
bool pillar() const { return (material >> 5) & 1; }
void setPillar(bool v) { material &= ~(1ull << 5); material |= (v << 5); }
bool surfaceMetalGrating() const { return (material >> 6) & 1; }
void setSurfaceMetalGrating(bool v) { material &= ~(1ull << 6); material |= (v << 6); }
bool surfacePhazon() const { return (material >> 7) & 1; }
void setSurfacePhazon(bool v) { material &= ~(1ull << 7); material |= (v << 7); }
bool surfaceDirt() const { return (material >> 8) & 1; }
void setSurfaceDirt(bool v) { material &= ~(1ull << 8); material |= (v << 8); }
bool surfaceLava() const {return (material >> 9) & 1; }
void setSurfaceLava(bool v) { material &= ~(1ull << 9); material |= (v << 9); }
bool surfaceStoneRock() const { return (material >> 10) & 1; }
void setSurfaceLavaStone(bool v) { material &= ~(1ull << 10); material |= (v << 10); }
bool surfaceSnow() const { return (material >> 11) & 1; }
void setSurfaceSnow(bool v) { material &= ~(1ull << 11); material |= (v << 11); }
bool surfaceMudSlow() const { return (material >> 12) & 1; }
void setSurfaceMudSlow(bool v) { material &= ~(1ull << 12); material |= (v << 12); }
bool halfPipe() const { return (material >> 13) & 1; }
void setHalfPipe(bool v) { material &= ~(1ull << 13); material |= (v << 13); }
bool surfaceMud() const { return (material >> 14) & 1; }
void setSurfaceMud(bool v) { material &= ~(1ull << 14); material |= (v << 14); }
bool surfaceGlass() const { return (material >> 15) & 1; }
void setSurfaceGlass(bool v) { material &= ~(1ull << 15); material |= (v << 15); }
bool surfaceShield() const { return (material >> 16) & 1; }
void setSurfaceShield(bool v) { material &= ~(1ull << 16); material |= (v << 16); }
bool surfaceSand() const { return (material >> 17) & 1; }
void setSurfaceSand(bool v) { material &= ~(1ull << 17); material |= (v << 17); }
bool projectilePassthrough() const { return (material >> 18) & 1; }
void setProjectilePassthrough(bool v) { material &= ~(1ull << 18); material |= (v << 18); }
bool solid() const { return (material >> 19) & 1; }
void setSolid(bool v) { material &= ~(1ull << 19); material |= (v << 19); }
bool noPlatformCollision() const { return (material >> 20) & 1; }
void setNoPlatformCollision(bool v) { material &= ~(1ull << 20); material |= (v << 20); }
bool cameraPassthrough() const { return (material >> 21) & 1; }
void setCameraPassthrough(bool v) { material &= ~(1ull << 21); material |= (v << 21); }
bool surfaceWood() const { return (material >> 22) & 1; }
void setSurfaceWood(bool v) { material &= ~(1ull << 22); material |= (v << 22); }
bool surfaceOrganic() const { return (material >> 23) & 1; }
void setSurfaceOrganic(bool v) { material &= ~(1ull << 23); material |= (v << 23); }
bool noEdgeCollision() const { return (material >> 24) & 1; }
void setNoEdgeCollision(bool v) { material &= ~(1ull << 24); material |= (v << 24); }
bool flipFace() const { return (material >> 25) & 1; }
void setFlipFace(bool v) { material &= ~(1ull << 25); material |= (v << 25); }
bool seeThrough() const { return (material >> 26) & 1; }
void setSeeThrough(bool v) { material &= ~(1ull << 26); material |= (v << 26); }
bool scanPassthrough() const { return (material >> 27) & 1; }
void setScanPassthrough(bool v) { material &= ~(1ull << 27); material |= (v << 27); }
bool aiPassthrough() const { return (material >> 28) & 1; }
void setAiPassthrough(bool v) { material &= ~(1ull << 28); material |= (v << 28); }
bool ceiling() const { return (material >> 29) & 1; }
void setCeiling(bool v) { material &= ~(1ull << 29); material |= (v << 29); }
bool wall() const { return (material >> 30) & 1; }
void setWall(bool v) { material &= ~(1ull << 30); material |= (v << 30); }
bool floor() const { return (material >> 31) & 1; }
void setFloor(bool v) { material &= ~(1ull << 31); material |= (v << 31); }
/* Dummies for later games */
bool surfaceSPMetal() const { return false; }
void setSurfaceSPMetal(bool v) { }
bool surfaceFabric() const { return false; }
void setSurfaceFabric(bool v) { }
bool surfaceRubber() const { return false; }
void setSurfaceRubber(bool v) { }
bool surfaceMothOrSeedOrganics() const { return false; }
void setSurfaceMothOrSeedOrganics(bool v) { }
bool surfaceWeb() const { return false; }
void setSurfaceWeb(bool v) { }
bool unused3() const { return false; }
void setUnused3(bool v) {}
bool unused4() const { return false; }
void setUnused4(bool v) {}
bool aiBlock() const { return false; }
void setAiBlock(bool v) { }
bool jumpNotAllowed() const { return false; }
void setJumpNotAllowed(bool v) { }
bool spiderBall() const { return false; }
void setSpiderBall(bool v) { }
bool screwAttackWallJump() const { return false; }
void setScrewAttackWallJump(bool v) { }
};
struct Edge : BigDNA
{
AT_DECL_DNA
Value<atUint16> verts[2];
};
struct Triangle : BigDNA
{
AT_DECL_DNA
Value<atUint16> edges[3];
};
Value<atUint32> unk1;
Value<atUint32> length;
Value<atUint32> magic;
Value<atUint32> version;
Value<atVec3f> aabb[2];
Value<BspNodeType> rootNodeType;
Value<atUint32> bspSize;
Buffer<AT_DNA_COUNT(bspSize)> bspTree;
Value<atUint32> materialCount;
Vector<Material, AT_DNA_COUNT(materialCount)> materials;
Value<atUint32> vertMatsCount;
Vector<atUint8, AT_DNA_COUNT(vertMatsCount)> vertMats;
Value<atUint32> edgeMatsCount;
Vector<atUint8, AT_DNA_COUNT(edgeMatsCount)> edgeMats;
Value<atUint32> triMatsCount;
Vector<atUint8, AT_DNA_COUNT(triMatsCount)> triMats;
Value<atUint32> edgeVertsCount;
Vector<Edge, AT_DNA_COUNT(edgeVertsCount)> edgeVertConnections;
Value<atUint32> triangleEdgesCount;
Vector<Triangle, AT_DNA_COUNT(triangleEdgesCount / 3)> triangleEdgeConnections;
Value<atUint32> vertCount;
Vector<atVec3f, AT_DNA_COUNT(vertCount)> verts;
/* Dummy MP2 member */
void insertNoClimb(hecl::blender::PyOutStream&) const {}
static void BlenderInit(hecl::blender::PyOutStream& os);
void sendToBlender(hecl::blender::PyOutStream& os) const
{
DeafBabeSendToBlender(os, *this);
} }
bool surfaceStone() const { return (material >> 1) & 1; }
void setSurfaceStone(bool v) {
material &= ~(1ull << 1);
material |= (v << 1);
}
bool surfaceMetal() const { return (material >> 2) & 1; }
void setSurfaceMetal(bool v) {
material &= ~(1ull << 2);
material |= (v << 2);
}
bool surfaceGrass() const { return (material >> 3) & 1; }
void setSurfaceGrass(bool v) {
material &= ~(1ull << 3);
material |= (v << 3);
}
bool surfaceIce() const { return (material >> 4) & 1; }
void setSurfaceIce(bool v) {
material &= ~(1ull << 4);
material |= (v << 4);
}
bool pillar() const { return (material >> 5) & 1; }
void setPillar(bool v) {
material &= ~(1ull << 5);
material |= (v << 5);
}
bool surfaceMetalGrating() const { return (material >> 6) & 1; }
void setSurfaceMetalGrating(bool v) {
material &= ~(1ull << 6);
material |= (v << 6);
}
bool surfacePhazon() const { return (material >> 7) & 1; }
void setSurfacePhazon(bool v) {
material &= ~(1ull << 7);
material |= (v << 7);
}
bool surfaceDirt() const { return (material >> 8) & 1; }
void setSurfaceDirt(bool v) {
material &= ~(1ull << 8);
material |= (v << 8);
}
bool surfaceLava() const { return (material >> 9) & 1; }
void setSurfaceLava(bool v) {
material &= ~(1ull << 9);
material |= (v << 9);
}
bool surfaceStoneRock() const { return (material >> 10) & 1; }
void setSurfaceLavaStone(bool v) {
material &= ~(1ull << 10);
material |= (v << 10);
}
bool surfaceSnow() const { return (material >> 11) & 1; }
void setSurfaceSnow(bool v) {
material &= ~(1ull << 11);
material |= (v << 11);
}
bool surfaceMudSlow() const { return (material >> 12) & 1; }
void setSurfaceMudSlow(bool v) {
material &= ~(1ull << 12);
material |= (v << 12);
}
bool halfPipe() const { return (material >> 13) & 1; }
void setHalfPipe(bool v) {
material &= ~(1ull << 13);
material |= (v << 13);
}
bool surfaceMud() const { return (material >> 14) & 1; }
void setSurfaceMud(bool v) {
material &= ~(1ull << 14);
material |= (v << 14);
}
bool surfaceGlass() const { return (material >> 15) & 1; }
void setSurfaceGlass(bool v) {
material &= ~(1ull << 15);
material |= (v << 15);
}
bool surfaceShield() const { return (material >> 16) & 1; }
void setSurfaceShield(bool v) {
material &= ~(1ull << 16);
material |= (v << 16);
}
bool surfaceSand() const { return (material >> 17) & 1; }
void setSurfaceSand(bool v) {
material &= ~(1ull << 17);
material |= (v << 17);
}
bool projectilePassthrough() const { return (material >> 18) & 1; }
void setProjectilePassthrough(bool v) {
material &= ~(1ull << 18);
material |= (v << 18);
}
bool solid() const { return (material >> 19) & 1; }
void setSolid(bool v) {
material &= ~(1ull << 19);
material |= (v << 19);
}
bool noPlatformCollision() const { return (material >> 20) & 1; }
void setNoPlatformCollision(bool v) {
material &= ~(1ull << 20);
material |= (v << 20);
}
bool cameraPassthrough() const { return (material >> 21) & 1; }
void setCameraPassthrough(bool v) {
material &= ~(1ull << 21);
material |= (v << 21);
}
bool surfaceWood() const { return (material >> 22) & 1; }
void setSurfaceWood(bool v) {
material &= ~(1ull << 22);
material |= (v << 22);
}
bool surfaceOrganic() const { return (material >> 23) & 1; }
void setSurfaceOrganic(bool v) {
material &= ~(1ull << 23);
material |= (v << 23);
}
bool noEdgeCollision() const { return (material >> 24) & 1; }
void setNoEdgeCollision(bool v) {
material &= ~(1ull << 24);
material |= (v << 24);
}
bool flipFace() const { return (material >> 25) & 1; }
void setFlipFace(bool v) {
material &= ~(1ull << 25);
material |= (v << 25);
}
bool seeThrough() const { return (material >> 26) & 1; }
void setSeeThrough(bool v) {
material &= ~(1ull << 26);
material |= (v << 26);
}
bool scanPassthrough() const { return (material >> 27) & 1; }
void setScanPassthrough(bool v) {
material &= ~(1ull << 27);
material |= (v << 27);
}
bool aiPassthrough() const { return (material >> 28) & 1; }
void setAiPassthrough(bool v) {
material &= ~(1ull << 28);
material |= (v << 28);
}
bool ceiling() const { return (material >> 29) & 1; }
void setCeiling(bool v) {
material &= ~(1ull << 29);
material |= (v << 29);
}
bool wall() const { return (material >> 30) & 1; }
void setWall(bool v) {
material &= ~(1ull << 30);
material |= (v << 30);
}
bool floor() const { return (material >> 31) & 1; }
void setFloor(bool v) {
material &= ~(1ull << 31);
material |= (v << 31);
}
/* Dummies for later games */
bool surfaceSPMetal() const { return false; }
void setSurfaceSPMetal(bool v) {}
bool surfaceFabric() const { return false; }
void setSurfaceFabric(bool v) {}
bool surfaceRubber() const { return false; }
void setSurfaceRubber(bool v) {}
bool surfaceMothOrSeedOrganics() const { return false; }
void setSurfaceMothOrSeedOrganics(bool v) {}
bool surfaceWeb() const { return false; }
void setSurfaceWeb(bool v) {}
bool unused3() const { return false; }
void setUnused3(bool v) {}
bool unused4() const { return false; }
void setUnused4(bool v) {}
bool aiBlock() const { return false; }
void setAiBlock(bool v) {}
bool jumpNotAllowed() const { return false; }
void setJumpNotAllowed(bool v) {}
bool spiderBall() const { return false; }
void setSpiderBall(bool v) {}
bool screwAttackWallJump() const { return false; }
void setScrewAttackWallJump(bool v) {}
};
struct Edge : BigDNA {
AT_DECL_DNA
Value<atUint16> verts[2];
};
struct Triangle : BigDNA {
AT_DECL_DNA
Value<atUint16> edges[3];
};
Value<atUint32> unk1;
Value<atUint32> length;
Value<atUint32> magic;
Value<atUint32> version;
Value<atVec3f> aabb[2];
Value<BspNodeType> rootNodeType;
Value<atUint32> bspSize;
Buffer<AT_DNA_COUNT(bspSize)> bspTree;
Value<atUint32> materialCount;
Vector<Material, AT_DNA_COUNT(materialCount)> materials;
Value<atUint32> vertMatsCount;
Vector<atUint8, AT_DNA_COUNT(vertMatsCount)> vertMats;
Value<atUint32> edgeMatsCount;
Vector<atUint8, AT_DNA_COUNT(edgeMatsCount)> edgeMats;
Value<atUint32> triMatsCount;
Vector<atUint8, AT_DNA_COUNT(triMatsCount)> triMats;
Value<atUint32> edgeVertsCount;
Vector<Edge, AT_DNA_COUNT(edgeVertsCount)> edgeVertConnections;
Value<atUint32> triangleEdgesCount;
Vector<Triangle, AT_DNA_COUNT(triangleEdgesCount / 3)> triangleEdgeConnections;
Value<atUint32> vertCount;
Vector<atVec3f, AT_DNA_COUNT(vertCount)> verts;
/* Dummy MP2 member */
void insertNoClimb(hecl::blender::PyOutStream&) const {}
static void BlenderInit(hecl::blender::PyOutStream& os);
void sendToBlender(hecl::blender::PyOutStream& os) const { DeafBabeSendToBlender(os, *this); }
}; };
} } // namespace DataSpec::DNAMP1

Some files were not shown because too many files have changed in this diff Show More