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
UseTab: Never
---
@ -8,7 +8,6 @@ DerivePointerAlignment: false
PointerAlignment: Left
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
BreakBeforeBraces: Allman
IndentCaseLabels: false
AllowShortBlocksOnASingleLine: true
AlignOperands: true
@ -24,6 +23,6 @@ NamespaceIndentation: None
BinPackArguments: true
BinPackParameters: true
SortIncludes: false
AccessModifierOffset: -4
AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 0
ConstructorInitializerAllOnOneLineOrOnePerLine: true

View File

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

View File

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

View File

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

View File

@ -7,302 +7,259 @@
#include "DataSpec/DNAMP3/CHAR.hpp"
#include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAANCS
{
namespace DataSpec::DNAANCS {
template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion>
bool ReadANCSToBlender(hecl::blender::Connection& conn,
const ANCSDNA& ancs,
const hecl::ProjectPath& outPath,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
const SpecBase& dataspec,
std::function<void(const hecl::SystemChar*)> fileChanged,
bool force)
{
/* Extract character CMDL/CSKR first */
std::vector<CharacterResInfo<typename PAKRouter::IDType>> chResInfo;
ancs.getCharacterResInfo(chResInfo);
for (const auto& info : chResInfo)
{
const nod::Node* node;
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;
bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, const hecl::ProjectPath& outPath,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec,
std::function<void(const hecl::SystemChar*)> fileChanged, bool force) {
/* Extract character CMDL/CSKR first */
std::vector<CharacterResInfo<typename PAKRouter::IDType>> chResInfo;
ancs.getCharacterResInfo(chResInfo);
for (const auto& info : chResInfo) {
const nod::Node* node;
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);
hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str());
std::string bestName = pakRouter.getBestEntryName(*cmdlE);
hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str());
typename ANCSDNA::CSKRType cskr;
pakRouter.lookupAndReadDNA(info.cskr, cskr);
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(info.cinf, cinf);
using RigPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>;
RigPair rigPair(&cskr, &cinf);
typename ANCSDNA::CSKRType cskr;
pakRouter.lookupAndReadDNA(info.cskr, cskr);
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(info.cinf, cinf);
using RigPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>;
RigPair rigPair(&cskr, &cinf);
PAKEntryReadStream rs = cmdlE->beginReadStream(*node);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>
(conn, rs, pakRouter, *cmdlE, dataspec, rigPair);
PAKEntryReadStream rs = cmdlE->beginReadStream(*node);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>(
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 */
auto attRange = pakRouter.lookupCharacterAttachmentRigs(entry.id);
for (auto it = attRange.first; it != attRange.second; ++it)
{
auto cmdlid = it->second.first.second;
/* 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());
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;
auto cinfid = it->second.first.first;
auto cmdlid = it->second.first.second;
std::string bestName = pakRouter.getBestEntryName(*cmdlE);
hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str());
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";
}
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);
/* 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);
PAKEntryReadStream rs = cmdlE->beginReadStream(*node);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>
(conn, rs, pakRouter, *cmdlE, dataspec, rigPair);
conn.saveBlend();
}
}
/* 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";
}
}
}
std::string bestName = pakRouter.getBestEntryName(entry);
hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str());
{
hecl::blender::DataStream ds = conn.beginData();
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 */
if (!conn.createBlend(outPath, hecl::blender::BlendType::Actor))
return false;
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os << "import bpy\n"
"actor_data = bpy.context.scene.hecl_sact_data\n";
std::string firstName;
typename ANCSDNA::CINFType firstCinf;
{
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
/* 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("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());
os.format(
"actor_action = actor_data.actions.add()\n"
"actor_action.name = '%s'\n",
id.second.name.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";
}
}
}
/* 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";
}
}
/* Extract EVNT if present */
anim.extractEVNT(id.second, outPath, pakRouter, force);
}
{
hecl::blender::DataStream ds = conn.beginData();
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;
}
conn.saveBlend();
return true;
}
template bool ReadANCSToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::ANCS, DNAMP1::MaterialSet, DNACMDL::SurfaceHeader_1, 2>
(hecl::blender::Connection& conn,
const DNAMP1::ANCS& ancs,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP1::PAKBridge>& pakRouter,
const typename PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
const SpecBase& dataspec,
std::function<void(const hecl::SystemChar*)> fileChanged,
bool force);
template bool ReadANCSToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::ANCS, DNAMP2::MaterialSet, DNACMDL::SurfaceHeader_2, 4>
(hecl::blender::Connection& conn,
const DNAMP2::ANCS& ancs,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP2::PAKBridge>& pakRouter,
const typename PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
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);
template bool
ReadANCSToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::ANCS, DNAMP1::MaterialSet, DNACMDL::SurfaceHeader_1, 2>(
hecl::blender::Connection& conn, const DNAMP1::ANCS& ancs, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP1::PAKBridge>& pakRouter, const typename PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
const SpecBase& dataspec, std::function<void(const hecl::SystemChar*)> fileChanged, bool force);
template bool
ReadANCSToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::ANCS, DNAMP2::MaterialSet, DNACMDL::SurfaceHeader_2, 4>(
hecl::blender::Connection& conn, const DNAMP2::ANCS& ancs, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP2::PAKBridge>& pakRouter, const typename PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
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 "RigInverter.hpp"
namespace DataSpec::DNAANCS
{
namespace DataSpec::DNAANCS {
using Actor = hecl::blender::Actor;
using Armature = hecl::blender::Armature;
using Action = hecl::blender::Action;
template <typename IDTYPE>
struct CharacterResInfo
{
std::string name;
IDTYPE cmdl;
IDTYPE cskr;
IDTYPE cinf;
std::vector<std::pair<std::string, std::pair<IDTYPE, IDTYPE>>> overlays;
struct CharacterResInfo {
std::string name;
IDTYPE cmdl;
IDTYPE cskr;
IDTYPE cinf;
std::vector<std::pair<std::string, std::pair<IDTYPE, IDTYPE>>> overlays;
};
template <typename IDTYPE>
struct AnimationResInfo
{
std::string name;
IDTYPE animId;
IDTYPE evntId;
bool additive;
struct AnimationResInfo {
std::string name;
IDTYPE animId;
IDTYPE evntId;
bool additive;
};
template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion>
bool ReadANCSToBlender(hecl::blender::Connection& conn,
const ANCSDNA& ancs,
const hecl::ProjectPath& outPath,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
const SpecBase& dataspec,
std::function<void(const hecl::SystemChar*)> fileChanged,
bool force=false);
}
bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, const hecl::ProjectPath& outPath,
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
namespace DataSpec::DNAANIM
{
namespace DataSpec::DNAANIM {
size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels)
{
size_t bitsPerKeyFrame = 0;
for (const Channel& chan : channels)
{
switch (chan.type)
{
case Channel::Type::Rotation:
bitsPerKeyFrame += 1;
case Channel::Type::Translation:
case Channel::Type::Scale:
bitsPerKeyFrame += chan.q[0];
bitsPerKeyFrame += chan.q[1];
bitsPerKeyFrame += chan.q[2];
break;
case Channel::Type::KfHead:
bitsPerKeyFrame += 1;
break;
case Channel::Type::RotationMP3:
bitsPerKeyFrame += chan.q[0];
bitsPerKeyFrame += chan.q[1];
bitsPerKeyFrame += chan.q[2];
bitsPerKeyFrame += chan.q[3];
break;
default: break;
}
size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels) {
size_t bitsPerKeyFrame = 0;
for (const Channel& chan : channels) {
switch (chan.type) {
case Channel::Type::Rotation:
bitsPerKeyFrame += 1;
case Channel::Type::Translation:
case Channel::Type::Scale:
bitsPerKeyFrame += chan.q[0];
bitsPerKeyFrame += chan.q[1];
bitsPerKeyFrame += chan.q[2];
break;
case Channel::Type::KfHead:
bitsPerKeyFrame += 1;
break;
case Channel::Type::RotationMP3:
bitsPerKeyFrame += chan.q[0];
bitsPerKeyFrame += chan.q[1];
bitsPerKeyFrame += chan.q[2];
bitsPerKeyFrame += chan.q[3];
break;
default:
break;
}
return (bitsPerKeyFrame * keyFrameCount + 31) / 32 * 4;
}
return (bitsPerKeyFrame * keyFrameCount + 31) / 32 * 4;
}
static inline QuantizedRot QuantizeRotation(const Value& quat, atUint32 div)
{
float q = M_PIF / 2.0f / float(div);
zeus::simd_floats f(quat.simd);
return
{
{
atInt32(std::asin(f[1]) / q),
atInt32(std::asin(f[2]) / q),
atInt32(std::asin(f[3]) / q),
},
(f[0] < 0.f)
};
static inline QuantizedRot QuantizeRotation(const Value& quat, atUint32 div) {
float q = M_PIF / 2.0f / float(div);
zeus::simd_floats f(quat.simd);
return {{
atInt32(std::asin(f[1]) / q),
atInt32(std::asin(f[2]) / q),
atInt32(std::asin(f[3]) / q),
},
(f[0] < 0.f)};
}
static inline Value DequantizeRotation(const QuantizedRot& v, atUint32 div)
{
float q = M_PIF / 2.0f / float(div);
athena::simd_floats f = {
0.0f,
std::sin(v.v[0] * q),
std::sin(v.v[1] * 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] = v.w ? -f[0] : f[0];
Value retval;
retval.simd.copy_from(f);
return retval;
static inline Value DequantizeRotation(const QuantizedRot& v, atUint32 div) {
float q = M_PIF / 2.0f / float(div);
athena::simd_floats f = {
0.0f,
std::sin(v.v[0] * q),
std::sin(v.v[1] * 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] = 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)
{
float q = 1.0f / float(div);
athena::simd_floats f = {
0.0f,
v.v[0] * q,
v.v[1] * 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] = 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) {
float q = 1.0f / float(div);
athena::simd_floats f = {
0.0f,
v.v[0] * q,
v.v[1] * 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] = v.w ? -f[0] : f[0];
Value retval;
retval.simd.copy_from(f);
return retval;
}
bool BitstreamReader::dequantizeBit(const atUint8* data)
{
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
bool BitstreamReader::dequantizeBit(const atUint8* data) {
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
/* Fill 32 bit buffer with region containing bits */
/* Make them least significant */
atUint32 tempBuf = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem;
/* Fill 32 bit buffer with region containing bits */
/* Make them least significant */
atUint32 tempBuf = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem;
/* That's it */
m_bitCur += 1;
return tempBuf & 0x1;
/* That's it */
m_bitCur += 1;
return tempBuf & 0x1;
}
atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 q)
{
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 q) {
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
/* Fill 32 bit buffer with region containing bits */
/* Make them least significant */
atUint32 tempBuf = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem;
/* Fill 32 bit buffer with region containing bits */
/* Make them least significant */
atUint32 tempBuf = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur)) >> bitRem;
/* If this shift underflows the value, buffer the next 32 bits */
/* And tack onto shifted buffer */
if ((bitRem + q) > 32)
{
atUint32 tempBuf2 = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur + 4));
tempBuf |= (tempBuf2 << (32 - bitRem));
/* If this shift underflows the value, buffer the next 32 bits */
/* And tack onto shifted buffer */
if ((bitRem + q) > 32) {
atUint32 tempBuf2 = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur + 4));
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;
}
/* 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:
{
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::Translation: {
keys.push_back({chan.i[0] * transMult, chan.i[1] * transMult, chan.i[2] * transMult});
break;
}
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);
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::Scale: {
keys.push_back({chan.i[0] * scaleMult, chan.i[1] * scaleMult, chan.i[2] * scaleMult});
break;
}
return chanKeys;
}
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::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;
}
}
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;
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);
int lastId = -1;
#endif
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;
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;
}
transMultOut = maxTransVal / quantRangeF;
scaleMultOut = maxScaleVal / quantRangeF;
#if DUMP_KEYS
fprintf(stderr, "\n");
#endif
}
/* 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;
return chanKeys;
}
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 <cmath>
namespace DataSpec::DNAANIM
{
namespace DataSpec::DNAANIM {
struct Value
{
athena::simd<float> simd;
Value() = default;
Value(const athena::simd<float>& s) : simd(s) {}
Value(const atVec3f& 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 w, float x, float y, float z) : simd(w, x, y, z) {}
struct Value {
athena::simd<float> simd;
Value() = default;
Value(const athena::simd<float>& s) : simd(s) {}
Value(const atVec3f& 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 w, float x, float y, float z) : simd(w, x, y, z) {}
};
struct QuantizedValue
{
atInt32 v[4];
atInt32& operator[] (size_t idx)
{return v[idx];}
atInt32 operator[] (size_t idx) const
{return v[idx];}
struct QuantizedValue {
atInt32 v[4];
atInt32& operator[](size_t idx) { return v[idx]; }
atInt32 operator[](size_t idx) const { return v[idx]; }
int qFrom(const QuantizedValue& other, size_t idx) const
{
atInt32 delta = std::abs(v[idx] - other.v[idx]);
if (delta == 0)
return 1;
return int(std::ceil(std::log2(delta))) + 1;
}
int qFrom(const QuantizedValue& other, size_t idx) const {
atInt32 delta = std::abs(v[idx] - other.v[idx]);
if (delta == 0)
return 1;
return int(std::ceil(std::log2(delta))) + 1;
}
};
struct QuantizedRot
{
QuantizedValue v;
bool w;
struct QuantizedRot {
QuantizedValue v;
bool w;
};
struct Channel
{
enum class Type
{
Rotation,
Translation,
Scale,
KfHead,
RotationMP3
} type;
atInt32 id = -1;
QuantizedValue i = {};
atUint8 q[4] = {};
struct Channel {
enum class Type { Rotation, Translation, Scale, KfHead, RotationMP3 } type;
atInt32 id = -1;
QuantizedValue i = {};
atUint8 q[4] = {};
};
size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels);
class BitstreamReader
{
size_t m_bitCur;
atInt32 dequantize(const atUint8* data, atUint8 q);
bool dequantizeBit(const atUint8* data);
class BitstreamReader {
size_t m_bitCur;
atInt32 dequantize(const atUint8* data, atUint8 q);
bool dequantizeBit(const atUint8* data);
public:
std::vector<std::vector<Value>>
read(const atUint8* data,
size_t keyFrameCount,
const std::vector<Channel>& channels,
atUint32 rotDiv,
float transMult,
float scaleMult);
std::vector<std::vector<Value>> read(const atUint8* data, size_t keyFrameCount, const std::vector<Channel>& channels,
atUint32 rotDiv, float transMult, float scaleMult);
};
class BitstreamWriter
{
size_t m_bitCur;
void quantize(atUint8* data, atUint8 q, atInt32 val);
void quantizeBit(atUint8* data, bool val);
class BitstreamWriter {
size_t m_bitCur;
void quantize(atUint8* data, atUint8 q, atInt32 val);
void quantizeBit(atUint8* data, bool val);
public:
std::unique_ptr<atUint8[]>
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);
std::unique_ptr<atUint8[]> 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);
};
}
} // namespace DataSpec::DNAANIM

View File

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

View File

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

View File

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

View File

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

View File

@ -4,15 +4,12 @@
#include "hecl/hecl.hpp"
#include <cfloat>
namespace DataSpec
{
namespace DataSpec {
template<class BabeDeadLight>
void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os,
const BabeDeadLight& light, unsigned s, unsigned l);
template <class BabeDeadLight>
void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLight& light, unsigned s, unsigned l);
template<class BabeDeadLight>
template <class BabeDeadLight>
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 "zeus/CAABox.hpp"
namespace DataSpec::DNACMDL
{
namespace DataSpec::DNACMDL {
using Mesh = hecl::blender::Mesh;
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
Value<atUint32> magic;
Value<atUint32> version;
struct Flags : BigDNA
{
AT_DECL_DNA
Value<atUint32> flags = 0;
bool skinned() const {return (flags & 0x1) != 0;}
void setSkinned(bool val) {flags &= ~0x1; flags |= val;}
bool shortNormals() const {return (flags & 0x2) != 0;}
void setShortNormals(bool val) {flags &= ~0x2; flags |= val << 1;}
bool shortUVs() const {return (flags & 0x4) != 0;}
void setShortUVs(bool val) {flags &= ~0x4; flags |= val << 2;}
} flags;
Value<atVec3f> aabbMin;
Value<atVec3f> aabbMax;
Value<atUint32> secCount;
Value<atUint32> matSetCount;
Vector<atUint32, AT_DNA_COUNT(secCount)> secSizes;
Align<32> align;
Value<atUint32> flags = 0;
bool skinned() const { return (flags & 0x1) != 0; }
void setSkinned(bool val) {
flags &= ~0x1;
flags |= val;
}
bool shortNormals() const { return (flags & 0x2) != 0; }
void setShortNormals(bool val) {
flags &= ~0x2;
flags |= val << 1;
}
bool shortUVs() const { return (flags & 0x4) != 0; }
void setShortUVs(bool val) {
flags &= ~0x4;
flags |= val << 2;
}
} flags;
Value<atVec3f> aabbMin;
Value<atVec3f> aabbMax;
Value<atUint32> secCount;
Value<atUint32> matSetCount;
Vector<atUint32, AT_DNA_COUNT(secCount)> secSizes;
Align<32> align;
};
struct SurfaceHeader_1 : BigDNA
{
AT_DECL_EXPLICIT_DNA
Value<atVec3f> centroid;
Value<atUint32> matIdx = 0;
Value<atUint32> dlSize = 0;
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> aabbSz = 0;
Value<atVec3f> reflectionNormal;
Value<atVec3f> aabb[2];
Align<32> align;
struct SurfaceHeader_1 : BigDNA {
AT_DECL_EXPLICIT_DNA
Value<atVec3f> centroid;
Value<atUint32> matIdx = 0;
Value<atUint32> dlSize = 0;
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> aabbSz = 0;
Value<atVec3f> reflectionNormal;
Value<atVec3f> aabb[2];
Align<32> align;
static constexpr bool UseMatrixSkinning() {return false;}
static constexpr atInt16 skinMatrixBankIdx() {return -1;}
static constexpr bool UseMatrixSkinning() { return false; }
static constexpr atInt16 skinMatrixBankIdx() { return -1; }
};
struct SurfaceHeader_2 : BigDNA
{
AT_DECL_EXPLICIT_DNA
Value<atVec3f> centroid;
Value<atUint32> matIdx = 0;
Value<atUint32> dlSize = 0;
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> aabbSz = 0;
Value<atVec3f> reflectionNormal;
Value<atInt16> skinMtxBankIdx;
Value<atUint16> surfaceGroup;
Value<atVec3f> aabb[2];
Align<32> align;
struct SurfaceHeader_2 : BigDNA {
AT_DECL_EXPLICIT_DNA
Value<atVec3f> centroid;
Value<atUint32> matIdx = 0;
Value<atUint32> dlSize = 0;
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> aabbSz = 0;
Value<atVec3f> reflectionNormal;
Value<atInt16> skinMtxBankIdx;
Value<atUint16> surfaceGroup;
Value<atVec3f> aabb[2];
Align<32> align;
static constexpr bool UseMatrixSkinning() {return false;}
atInt16 skinMatrixBankIdx() const {return skinMtxBankIdx;}
static constexpr bool UseMatrixSkinning() { return false; }
atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; }
};
struct SurfaceHeader_3 : BigDNA
{
AT_DECL_EXPLICIT_DNA
Value<atVec3f> centroid;
Value<atUint32> matIdx = 0;
Value<atUint32> dlSize = 0;
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> aabbSz = 0;
Value<atVec3f> reflectionNormal;
Value<atInt16> skinMtxBankIdx;
Value<atUint16> surfaceGroup;
Value<atVec3f> aabb[2];
Value<atUint8> unk3;
Align<32> align;
struct SurfaceHeader_3 : BigDNA {
AT_DECL_EXPLICIT_DNA
Value<atVec3f> centroid;
Value<atUint32> matIdx = 0;
Value<atUint32> dlSize = 0;
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> aabbSz = 0;
Value<atVec3f> reflectionNormal;
Value<atInt16> skinMtxBankIdx;
Value<atUint16> surfaceGroup;
Value<atVec3f> aabb[2];
Value<atUint8> unk3;
Align<32> align;
static constexpr bool UseMatrixSkinning() {return true;}
atInt16 skinMatrixBankIdx() const {return skinMtxBankIdx;}
static constexpr bool UseMatrixSkinning() { return true; }
atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; }
};
struct VertexAttributes
{
GX::AttrType pos = GX::NONE;
GX::AttrType norm = GX::NONE;
GX::AttrType color0 = GX::NONE;
GX::AttrType color1 = GX::NONE;
unsigned uvCount = 0;
GX::AttrType uvs[7] = {GX::NONE};
GX::AttrType pnMtxIdx = GX::NONE;
unsigned texMtxIdxCount = 0;
GX::AttrType texMtxIdx[7] = {GX::NONE};
bool shortUVs;
struct VertexAttributes {
GX::AttrType pos = GX::NONE;
GX::AttrType norm = GX::NONE;
GX::AttrType color0 = GX::NONE;
GX::AttrType color1 = GX::NONE;
unsigned uvCount = 0;
GX::AttrType uvs[7] = {GX::NONE};
GX::AttrType pnMtxIdx = GX::NONE;
unsigned texMtxIdxCount = 0;
GX::AttrType texMtxIdx[7] = {GX::NONE};
bool shortUVs;
};
template <class MaterialSet>
void GetVertexAttributes(const MaterialSet& matSet,
std::vector<VertexAttributes>& attributesOut);
void GetVertexAttributes(const MaterialSet& matSet, std::vector<VertexAttributes>& attributesOut);
template <class PAKRouter, class MaterialSet>
void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os,
const MaterialSet& matSet,
const PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
unsigned setIdx);
void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry, unsigned setIdx);
template <class PAKRouter, class MaterialSet>
void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os,
const MaterialSet& matSet,
const PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
unsigned setIdx);
void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry, unsigned setIdx);
void InitGeomBlenderContext(hecl::blender::PyOutStream& os,
const hecl::ProjectPath& masterShaderPath,
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath,
bool solidShading);
void FinishBlenderMesh(hecl::blender::PyOutStream& os,
unsigned matSetCount, int meshIdx);
void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx);
template <class PAKRouter, class MaterialSet, class RigPair, class SurfaceHeader>
atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os,
athena::io::IStreamReader& reader,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
const RigPair& rp,
bool shortNormals,
bool shortUVs,
std::vector<VertexAttributes>& vertAttribs,
int meshIdx,
atUint32 secCount,
atUint32 matSetCount,
const atUint32* secSizes,
atUint32 surfaceCount=0);
atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const RigPair& rp,
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>
bool ReadCMDLToBlender(hecl::blender::Connection& conn,
athena::io::IStreamReader& reader,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
const SpecBase& dataspec,
const RigPair& rp);
bool ReadCMDLToBlender(hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, const RigPair& rp);
template <class PAKRouter, class MaterialSet>
void NameCMDL(athena::io::IStreamReader& reader,
PAKRouter& pakRouter,
typename PAKRouter::EntryType& entry,
void NameCMDL(athena::io::IStreamReader& reader, PAKRouter& pakRouter, typename PAKRouter::EntryType& entry,
const SpecBase& dataspec);
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
const Mesh& mesh, hecl::blender::PoolSkinIndex& poolSkinIndex);
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh,
hecl::blender::PoolSkinIndex& poolSkinIndex);
template <class MaterialSet, class SurfaceHeader, class MeshHeader>
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,
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"
namespace DataSpec::DNAParticle
{
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('DENM'),SBIG('DESP'),SBIG('DESH'),SBIG('BTLE'),
SBIG('WASP'),SBIG('TALP'),SBIG('PTGM'),SBIG('SPIR'),
SBIG('FPIR'),SBIG('FFLE'),SBIG('PARA'),SBIG('BMON'),
SBIG('BFLR'),SBIG('PBOS'),SBIG('IBOS'),SBIG('1SVA'),
SBIG('1RPR'),SBIG('1MTR'),SBIG('1PDS'),SBIG('1FLB'),
SBIG('1DRN'),SBIG('1MRE'),SBIG('CHOZ'),SBIG('JZAP'),
SBIG('1ISE'),SBIG('1BSE'),SBIG('1ATB'),SBIG('1ATA'),
SBIG('BTSP'),SBIG('WWSP'),SBIG('TASP'),SBIG('TGSP'),
SBIG('SPSP'),SBIG('FPSP'),SBIG('FFSP'),SBIG('PSSP'),
SBIG('BMSP'),SBIG('BFSP'),SBIG('PBSP'),SBIG('IBSP'),
SBIG('2SVA'),SBIG('2RPR'),SBIG('2MTR'),SBIG('2PDS'),
SBIG('2FLB'),SBIG('2DRN'),SBIG('2MRE'),SBIG('CHSP'),
SBIG('JZSP'),SBIG('3ISE'),SBIG('3BSE'),SBIG('3ATB'),
SBIG('3ATA'),SBIG('BTSH'),SBIG('WWSH'),SBIG('TASH'),
SBIG('TGSH'),SBIG('SPSH'),SBIG('FPSH'),SBIG('FFSH'),
SBIG('PSSH'),SBIG('BMSH'),SBIG('BFSH'),SBIG('PBSH'),
SBIG('IBSH'),SBIG('3SVA'),SBIG('3RPR'),SBIG('3MTR'),
SBIG('3PDS'),SBIG('3FLB'),SBIG('3DRN'),SBIG('3MRE'),
SBIG('CHSH'),SBIG('JZSH'),SBIG('5ISE'),SBIG('5BSE'),
SBIG('5ATB'),SBIG('5ATA')
namespace DataSpec::DNAParticle {
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('DENM'), SBIG('DESP'), SBIG('DESH'), SBIG('BTLE'), SBIG('WASP'), SBIG('TALP'), SBIG('PTGM'), SBIG('SPIR'),
SBIG('FPIR'), SBIG('FFLE'), SBIG('PARA'), SBIG('BMON'), SBIG('BFLR'), SBIG('PBOS'), SBIG('IBOS'), SBIG('1SVA'),
SBIG('1RPR'), SBIG('1MTR'), SBIG('1PDS'), SBIG('1FLB'), SBIG('1DRN'), SBIG('1MRE'), SBIG('CHOZ'), SBIG('JZAP'),
SBIG('1ISE'), SBIG('1BSE'), SBIG('1ATB'), SBIG('1ATA'), SBIG('BTSP'), SBIG('WWSP'), SBIG('TASP'), SBIG('TGSP'),
SBIG('SPSP'), SBIG('FPSP'), SBIG('FFSP'), SBIG('PSSP'), SBIG('BMSP'), SBIG('BFSP'), SBIG('PBSP'), SBIG('IBSP'),
SBIG('2SVA'), SBIG('2RPR'), SBIG('2MTR'), SBIG('2PDS'), SBIG('2FLB'), SBIG('2DRN'), SBIG('2MRE'), SBIG('CHSP'),
SBIG('JZSP'), SBIG('3ISE'), SBIG('3BSE'), SBIG('3ATB'), SBIG('3ATA'), SBIG('BTSH'), SBIG('WWSH'), SBIG('TASH'),
SBIG('TGSH'), SBIG('SPSH'), SBIG('FPSH'), SBIG('FFSH'), SBIG('PSSH'), SBIG('BMSH'), SBIG('BFSH'), SBIG('PBSH'),
SBIG('IBSH'), SBIG('3SVA'), SBIG('3RPR'), SBIG('3MTR'), SBIG('3PDS'), SBIG('3FLB'), SBIG('3DRN'), SBIG('3MRE'),
SBIG('CHSH'), SBIG('JZSH'), SBIG('5ISE'), SBIG('5BSE'), SBIG('5ATB'), SBIG('5ATA')};
static const std::vector<FourCC> SFXTypes = {
SBIG('DSFX'), SBIG('CSFX'), SBIG('MSFX'), SBIG('GRFX'), 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> SFXTypes =
{
SBIG('DSFX'),SBIG('CSFX'),SBIG('MSFX'),SBIG('GRFX'),
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')
};
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 <>
const char* CRSM<UniqueID32>::DNAType() { return "CRSM<UniqueID32>"; }
const char* CRSM<UniqueID32>::DNAType() {
return "CRSM<UniqueID32>";
}
template <>
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);
}
}
const char* CRSM<UniqueID64>::DNAType() {
return "CRSM<UniqueID64>";
}
template <class IDType>
void CRSM<IDType>::_write(athena::io::YAMLDocWriter& w) const
{
for (const auto& pair : x0_generators)
if (pair.second)
if (auto rec = w.enterSubRecord(pair.first.toString().c_str()))
pair.second.write(w);
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;
}
for (const auto& pair : x10_sfx)
if (pair.second != ~0)
w.writeUint32(pair.first.toString().c_str(), pair.second);
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;
}
for (const auto& pair : x20_decals)
if (pair.second)
if (auto rec = w.enterSubRecord(pair.first.toString().c_str()))
pair.second.write(w);
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;
}
if (x30_RNGE != 50.f)
w.writeFloat("RNGE", x30_RNGE);
if (x34_FOFF != 0.2f)
w.writeFloat("FOFF", x34_FOFF);
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>
void CRSM<IDType>::_binarySize(size_t& __isz) const
{
__isz += 4;
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;
}
void CRSM<IDType>::_write(athena::io::YAMLDocWriter& w) const {
for (const auto& pair : x0_generators)
if (pair.second)
if (auto rec = w.enterSubRecord(pair.first.toString().c_str()))
pair.second.write(w);
for (const auto& pair : x20_decals)
{
if (pair.second)
{
__isz += 4;
pair.second.binarySize(__isz);
}
}
for (const auto& pair : x10_sfx)
if (pair.second != ~0)
w.writeUint32(pair.first.toString().c_str(), pair.second);
if (x30_RNGE != 50.f)
__isz += 12;
if (x34_FOFF != 0.2f)
__isz += 12;
for (const auto& pair : x20_decals)
if (pair.second)
if (auto rec = w.enterSubRecord(pair.first.toString().c_str()))
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>
void CRSM<IDType>::_read(athena::io::IStreamReader &r)
{
uint32_t clsId;
void CRSM<IDType>::_binarySize(size_t& __isz) const {
__isz += 4;
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);
if (clsId != SBIG('CRSM'))
{
LogModule.report(logvisor::Warning, "non CRSM provided to CRSM parser");
return;
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;
}
while (clsId != SBIG('_END'))
{
r.readBytesToBuf(&clsId, 4);
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())
{
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 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());
}
}
template <class IDType>
void CRSM<IDType>::_write(athena::io::IStreamWriter& w) const
{
w.writeBytes("CRSM", 4);
for (const auto& pair : x0_generators)
{
w.writeBytes(pair.first.getChars(), 4);
pair.second.write(w);
}
void CRSM<IDType>::_write(athena::io::IStreamWriter& w) const {
w.writeBytes("CRSM", 4);
for (const auto& pair : x0_generators) {
w.writeBytes(pair.first.getChars(), 4);
pair.second.write(w);
}
for (const auto& pair : x10_sfx)
{
w.writeBytes(pair.first.getChars(), 4);
if (pair.second != ~0)
{
w.writeBytes("CNST", 4);
w.writeUint32Big(pair.second);
}
else
{
w.writeBytes("NONE", 4);
}
for (const auto& pair : x10_sfx) {
w.writeBytes(pair.first.getChars(), 4);
if (pair.second != ~0) {
w.writeBytes("CNST", 4);
w.writeUint32Big(pair.second);
} else {
w.writeBytes("NONE", 4);
}
}
for (const auto& pair : x20_decals)
{
w.writeBytes(pair.first.getChars(), 4);
pair.second.write(w);
}
for (const auto& pair : x20_decals) {
w.writeBytes(pair.first.getChars(), 4);
pair.second.write(w);
}
if (x30_RNGE != 50.f)
{
w.writeBytes("RNGECNST", 8);
w.writeFloatBig(x30_RNGE);
}
if (x34_FOFF != 0.2f)
{
w.writeBytes("FOFFCNST", 8);
w.writeFloatBig(x34_FOFF);
}
w.writeBytes("_END", 4);
if (x30_RNGE != 50.f) {
w.writeBytes("RNGECNST", 8);
w.writeFloatBig(x30_RNGE);
}
if (x34_FOFF != 0.2f) {
w.writeBytes("FOFFCNST", 8);
w.writeFloatBig(x34_FOFF);
}
w.writeBytes("_END", 4);
}
AT_SUBSPECIALIZE_DNA_YAML(CRSM<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(CRSM<UniqueID64>)
template <class IDType>
void CRSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
for (const auto& p : x0_generators)
g_curSpec->flattenDependencies(p.second.id, pathsOut);
for (const auto& p : x20_decals)
g_curSpec->flattenDependencies(p.second.id, pathsOut);
void CRSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
for (const auto& p : x0_generators)
g_curSpec->flattenDependencies(p.second.id, pathsOut);
for (const auto& p : x20_decals)
g_curSpec->flattenDependencies(p.second.id, pathsOut);
}
template <class IDType>
CRSM<IDType>::CRSM()
: x30_RNGE(50.f),
x34_FOFF(0.2f)
{
for (const auto& sfx : SFXTypes)
x10_sfx[sfx] = ~0;
CRSM<IDType>::CRSM() : x30_RNGE(50.f), x34_FOFF(0.2f) {
for (const auto& sfx : SFXTypes)
x10_sfx[sfx] = ~0;
}
template struct CRSM<UniqueID32>;
template struct CRSM<UniqueID64>;
template <class IDType>
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
CRSM<IDType> crsm;
crsm.read(rs);
athena::io::ToYAMLStream(crsm, writer);
return true;
}
return false;
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen()) {
CRSM<IDType> crsm;
crsm.read(rs);
athena::io::ToYAMLStream(crsm, writer);
return true;
}
return false;
}
template bool ExtractCRSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractCRSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
crsm.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i=0 ; i<32-rem ; ++i)
w.writeUByte(0xff);
return true;
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
crsm.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 bool WriteCRSM<UniqueID32>(const CRSM<UniqueID32>& 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 "optional.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
struct CRSM : BigDNA
{
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x0_generators;
std::unordered_map<FourCC, uint32_t> x10_sfx;
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x20_decals;
float x30_RNGE;
float x34_FOFF;
struct CRSM : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x0_generators;
std::unordered_map<FourCC, uint32_t> x10_sfx;
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x20_decals;
float x30_RNGE;
float x34_FOFF;
CRSM();
CRSM();
void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
};
template <class IDType>
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAParticle

View File

@ -3,39 +3,35 @@
#include "athena/FileWriter.hpp"
#include "DGRP.hpp"
namespace DataSpec::DNADGRP
{
namespace DataSpec::DNADGRP {
template <class IDType>
bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
DGRP<IDType> dgrp;
dgrp.read(rs);
athena::io::ToYAMLStream(dgrp, writer);
return true;
}
return false;
bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen()) {
DGRP<IDType> dgrp;
dgrp.read(rs);
athena::io::ToYAMLStream(dgrp, writer);
return true;
}
return false;
}
template bool ExtractDGRP<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractDGRP<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
dgrp.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i=0 ; i<32-rem ; ++i)
w.writeUByte(0xff);
return true;
bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
dgrp.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 bool WriteDGRP<UniqueID32>(const DGRP<UniqueID32>& 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 "PAK.hpp"
namespace DataSpec::DNADGRP
{
namespace DataSpec::DNADGRP {
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
Value<atUint32> dependCount;
struct ObjectTag : BigDNA
{
AT_DECL_DNA_YAML
DNAFourCC type;
Value<IDType> id;
DNAFourCC type;
Value<IDType> id;
bool validate() const
{
if (!id.operator bool())
return false;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
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());
bool validate() const {
if (!id.operator bool())
return false;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
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());
}
};
template <class IDType>
@ -45,5 +40,4 @@ bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNADGRP

View File

@ -2,8 +2,7 @@
#include "PAK.hpp"
#include "boo/ThreadLocalPtr.hpp"
namespace DataSpec
{
namespace DataSpec {
logvisor::Module LogDNACommon("urde::DNACommon");
ThreadLocalPtr<SpecBase> g_curSpec;
@ -16,305 +15,270 @@ ThreadLocalPtr<IDRestorer<UniqueID128>> UniqueIDBridge::s_restorer128;
UniqueID32 UniqueID32::kInvalidId;
template <class IDType>
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool silenceWarnings)
{
/* Try PAKRouter first (only available at extract) */
PAKRouterBase* pakRouter = g_PakRouter.get();
if (pakRouter)
{
hecl::ProjectPath path = pakRouter->getWorking(id, silenceWarnings);
if (path)
return path;
}
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool silenceWarnings) {
/* Try PAKRouter first (only available at extract) */
PAKRouterBase* pakRouter = g_PakRouter.get();
if (pakRouter) {
hecl::ProjectPath path = pakRouter->getWorking(id, silenceWarnings);
if (path)
return path;
}
/* Try project cache second (populated with paths read from YAML resources) */
hecl::Database::Project* project = s_Project.get();
if (!project)
{
if (pakRouter)
{
if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id)
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 {};
/* Try project cache second (populated with paths read from YAML resources) */
hecl::Database::Project* project = s_Project.get();
if (!project) {
if (pakRouter) {
if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id)
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 {};
}
const hecl::ProjectPath* search = project->lookupBridgePath(id.toUint64());
if (!search)
{
if (IDRestorer<IDType>* restorer = GetIDRestorer<IDType>())
if (IDType newId = restorer->originalToNew(id))
if (const hecl::ProjectPath* newSearch = project->lookupBridgePath(newId.toUint64()))
return *newSearch;
if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id)
LogDNACommon.report(logvisor::Warning,
"unable to translate %s to path", id.toString().c_str());
return {};
}
return *search;
const hecl::ProjectPath* search = project->lookupBridgePath(id.toUint64());
if (!search) {
if (IDRestorer<IDType>* restorer = GetIDRestorer<IDType>())
if (IDType newId = restorer->originalToNew(id))
if (const hecl::ProjectPath* newSearch = project->lookupBridgePath(newId.toUint64()))
return *newSearch;
if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id)
LogDNACommon.report(logvisor::Warning, "unable to translate %s to path", id.toString().c_str());
return {};
}
return *search;
}
template
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID32& id, bool silenceWarnings);
template
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID64& id, bool silenceWarnings);
template
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID128& id, bool silenceWarnings);
template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID32& id, bool silenceWarnings);
template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID64& id, bool silenceWarnings);
template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID128& id, bool silenceWarnings);
template <class IDType>
hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str)
{
if (str.empty())
return {};
hecl::Database::Project* project = s_Project.get();
if (!project)
LogDNACommon.report(logvisor::Fatal,
"UniqueIDBridge::setGlobalProject must be called before MakePathFromString");
hecl::ProjectPath path = hecl::ProjectPath(*project, str);
project->addBridgePathToCache(IDType(path).toUint64(), path);
return path;
hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str) {
if (str.empty())
return {};
hecl::Database::Project* project = s_Project.get();
if (!project)
LogDNACommon.report(logvisor::Fatal, "UniqueIDBridge::setGlobalProject must be called before MakePathFromString");
hecl::ProjectPath path = hecl::ProjectPath(*project, str);
project->addBridgePathToCache(IDType(path).toUint64(), path);
return path;
}
template
hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID32>(std::string_view str);
template
hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID64>(std::string_view str);
template hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID32>(std::string_view str);
template hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID64>(std::string_view str);
template <class IDType>
void UniqueIDBridge::TransformOldHashToNewHash(IDType& id)
{
id = TranslatePakIdToPath(id);
void UniqueIDBridge::TransformOldHashToNewHash(IDType& id) {
id = TranslatePakIdToPath(id);
}
template
void UniqueIDBridge::TransformOldHashToNewHash(UniqueID32& id);
template
void UniqueIDBridge::TransformOldHashToNewHash(UniqueID64& id);
template void UniqueIDBridge::TransformOldHashToNewHash(UniqueID32& id);
template void UniqueIDBridge::TransformOldHashToNewHash(UniqueID64& id);
void UniqueIDBridge::SetThreadProject(hecl::Database::Project& project)
{
s_Project.reset(&project);
}
void UniqueIDBridge::SetThreadProject(hecl::Database::Project& project) { s_Project.reset(&project); }
/** PAK 32-bit Unique ID */
void UniqueID32::assign(uint32_t id, bool noOriginal)
{
m_id = id ? id : 0xffffffff;
if (!noOriginal)
if (IDRestorer<UniqueID32>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID32>())
if (UniqueID32 origId = restorer->newToOriginal(*this))
*this = origId;
void UniqueID32::assign(uint32_t id, bool noOriginal) {
m_id = id ? id : 0xffffffff;
if (!noOriginal)
if (IDRestorer<UniqueID32>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID32>())
if (UniqueID32 origId = restorer->newToOriginal(*this))
*this = origId;
}
template <>
void UniqueID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
{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));
void UniqueID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
assign(reader.readUint32Big());
}
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());
void UniqueID32::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint32Big(m_id);
}
template <>
void UniqueID32::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
{s += 4;}
void UniqueID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
*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
{
char buf[9];
snprintf(buf, 9, "%08X", m_id);
return std::string(buf);
std::string UniqueID32::toString() const {
char buf[9];
snprintf(buf, 9, "%08X", m_id);
return std::string(buf);
}
template <>
void UniqueID32Zero::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
{UniqueID32::Enumerate<BigDNA::Read>(reader);}
void UniqueID32Zero::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
UniqueID32::Enumerate<BigDNA::Read>(reader);
}
template <>
void UniqueID32Zero::Enumerate<BigDNA::Write>(typename Write::StreamT& writer)
{writer.writeUint32Big(*this ? m_id : 0);}
void UniqueID32Zero::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint32Big(*this ? m_id : 0);
}
template <>
void UniqueID32Zero::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
{UniqueID32::Enumerate<BigDNA::ReadYaml>(reader);}
void UniqueID32Zero::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
UniqueID32::Enumerate<BigDNA::ReadYaml>(reader);
}
template <>
void UniqueID32Zero::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer)
{UniqueID32::Enumerate<BigDNA::WriteYaml>(writer);}
void UniqueID32Zero::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
UniqueID32::Enumerate<BigDNA::WriteYaml>(writer);
}
template <>
void UniqueID32Zero::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
{UniqueID32::Enumerate<BigDNA::BinarySize>(s);}
AuxiliaryID32& AuxiliaryID32::operator=(const hecl::ProjectPath& path)
{
assign(path.ensureAuxInfo(m_auxStr).hash().val32());
return *this;
void UniqueID32Zero::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
UniqueID32::Enumerate<BigDNA::BinarySize>(s);
}
AuxiliaryID32& AuxiliaryID32::operator=(const UniqueID32& id)
{
m_baseId = id;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
if (path)
{
if (m_addExtension)
path = path.getWithExtension(m_addExtension);
*this = path;
}
return *this;
AuxiliaryID32& AuxiliaryID32::operator=(const hecl::ProjectPath& path) {
assign(path.ensureAuxInfo(m_auxStr).hash().val32());
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;
AuxiliaryID32& AuxiliaryID32::operator=(const UniqueID32& id) {
m_baseId = id;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
if (path) {
if (m_addExtension)
path = path.getWithExtension(m_addExtension);
hecl::SystemUTF8Conv ufx8AuxStr(m_auxStr);
writer.writeString(nullptr, std::string(path.getRelativePathUTF8()) + '|' + ufx8AuxStr);
path = path.getWithExtension(m_addExtension);
*this = path;
}
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 */
void UniqueID64::assign(uint64_t id, bool noOriginal)
{
m_id = id ? id : 0xffffffffffffffff;
if (!noOriginal)
if (IDRestorer<UniqueID64>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID64>())
if (UniqueID64 origId = restorer->newToOriginal(*this))
*this = origId;
void UniqueID64::assign(uint64_t id, bool noOriginal) {
m_id = id ? id : 0xffffffffffffffff;
if (!noOriginal)
if (IDRestorer<UniqueID64>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID64>())
if (UniqueID64 origId = restorer->newToOriginal(*this))
*this = origId;
}
template <>
void UniqueID64::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
{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));
void UniqueID64::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
assign(reader.readUint64Big());
}
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());
void UniqueID64::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint64Big(m_id);
}
template <>
void UniqueID64::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
{s += 8;}
void UniqueID64::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
*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
{
char buf[17];
snprintf(buf, 17, "%016" PRIX64, m_id);
return std::string(buf);
std::string UniqueID64::toString() const {
char buf[17];
snprintf(buf, 17, "%016" PRIX64, m_id);
return std::string(buf);
}
/** PAK 128-bit Unique ID */
template <>
void UniqueID128::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
{
m_id.id[0] = reader.readUint64Big();
m_id.id[1] = reader.readUint64Big();
void UniqueID128::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
m_id.id[0] = reader.readUint64Big();
m_id.id[1] = reader.readUint64Big();
}
template <>
void UniqueID128::Enumerate<BigDNA::Write>(typename Write::StreamT& writer)
{
writer.writeUint64Big(m_id.id[0]);
writer.writeUint64Big(m_id.id[1]);
void UniqueID128::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint64Big(m_id.id[0]);
writer.writeUint64Big(m_id.id[1]);
}
template <>
void UniqueID128::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
{
*this = UniqueIDBridge::MakePathFromString<UniqueID128>(reader.readString(nullptr));
void UniqueID128::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
*this = UniqueIDBridge::MakePathFromString<UniqueID128>(reader.readString(nullptr));
}
template <>
void UniqueID128::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());
void UniqueID128::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 UniqueID128::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
{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);
void UniqueID128::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
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);
}
/** Word Bitmap reader/writer */
void WordBitmap::read(athena::io::IStreamReader& reader, size_t bitCount)
{
m_bitCount = bitCount;
size_t wordCount = (bitCount + 31) / 32;
m_words.clear();
m_words.reserve(wordCount);
for (size_t w=0 ; w<wordCount ; ++w)
m_words.push_back(reader.readUint32Big());
void WordBitmap::read(athena::io::IStreamReader& reader, size_t bitCount) {
m_bitCount = bitCount;
size_t wordCount = (bitCount + 31) / 32;
m_words.clear();
m_words.reserve(wordCount);
for (size_t w = 0; w < wordCount; ++w)
m_words.push_back(reader.readUint32Big());
}
void WordBitmap::write(athena::io::IStreamWriter& writer) const
{
for (atUint32 word : m_words)
writer.writeUint32Big(word);
}
void WordBitmap::binarySize(size_t& __isz) const
{
__isz += m_words.size() * 4;
void WordBitmap::write(athena::io::IStreamWriter& writer) const {
for (atUint32 word : m_words)
writer.writeUint32Big(word);
}
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 "zeus/CColor.hpp"
namespace DataSpec
{
namespace DataSpec {
struct SpecBase;
extern logvisor::Module LogDNACommon;
@ -25,43 +24,46 @@ typedef athena::io::DNAVYaml<athena::Big> BigDNAVYaml;
/** FourCC with DNA read/write */
using DNAFourCC = hecl::DNAFourCC;
class DNAColor final : public BigDNA, public zeus::CColor
{
class DNAColor final : public BigDNA, public zeus::CColor {
public:
DNAColor() = default;
DNAColor(const zeus::CColor& color) : zeus::CColor(color) {}
AT_DECL_EXPLICIT_DNA_YAML
DNAColor() = default;
DNAColor(const zeus::CColor& color) : zeus::CColor(color) {}
AT_DECL_EXPLICIT_DNA_YAML
};
template <> inline void DNAColor::Enumerate<BigDNA::Read>(typename Read::StreamT& _r)
{ zeus::CColor::readRGBABig(_r); }
template <> inline void DNAColor::Enumerate<BigDNA::Write>(typename Write::StreamT& _w)
{ 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::Read>(typename Read::StreamT& _r) {
zeus::CColor::readRGBABig(_r);
}
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::Write>(typename Write::StreamT& _w) {
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) {
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;
class UniqueID32;
@ -69,277 +71,266 @@ class UniqueID64;
class UniqueID128;
/** Common virtual interface for runtime ambiguity resolution */
class PAKRouterBase
{
class PAKRouterBase {
protected:
const SpecBase& m_dataSpec;
const SpecBase& m_dataSpec;
public:
PAKRouterBase(const SpecBase& dataSpec) : m_dataSpec(dataSpec) {}
hecl::Database::Project& getProject() const {return m_dataSpec.getProject();}
virtual hecl::ProjectPath getWorking(const UniqueID32&, bool silenceWarnings=false) const
{
LogDNACommon.report(logvisor::Fatal,
"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");
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();
}
PAKRouterBase(const SpecBase& dataSpec) : m_dataSpec(dataSpec) {}
hecl::Database::Project& getProject() const { return m_dataSpec.getProject(); }
virtual hecl::ProjectPath getWorking(const UniqueID32&, bool silenceWarnings = false) const {
LogDNACommon.report(logvisor::Fatal, "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");
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
* lookup destination paths of resources */
class UniqueIDBridge
{
friend class UniqueID32;
friend class UniqueID64;
class UniqueIDBridge {
friend class UniqueID32;
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:
template <class IDType>
static hecl::ProjectPath TranslatePakIdToPath(const IDType& id, bool silenceWarnings=false);
template <class IDType>
static hecl::ProjectPath MakePathFromString(std::string_view str);
template <class IDType>
static void TransformOldHashToNewHash(IDType& id);
template <class IDType>
static hecl::ProjectPath TranslatePakIdToPath(const IDType& id, bool silenceWarnings = false);
template <class IDType>
static hecl::ProjectPath MakePathFromString(std::string_view str);
template <class IDType>
static void TransformOldHashToNewHash(IDType& id);
static void SetThreadProject(hecl::Database::Project& project);
static void SetThreadProject(hecl::Database::Project& project);
template <class IDType>
static IDRestorer<IDType>* GetIDRestorer();
template <class IDType>
static void SetIDRestorer(IDRestorer<IDType>* restorer);
template <class IDType>
static IDRestorer<IDType>* GetIDRestorer();
template <class IDType>
static void SetIDRestorer(IDRestorer<IDType>* restorer);
};
template <>
inline IDRestorer<UniqueID32>* UniqueIDBridge::GetIDRestorer<UniqueID32>()
{
return s_restorer32.get();
inline IDRestorer<UniqueID32>* UniqueIDBridge::GetIDRestorer<UniqueID32>() {
return s_restorer32.get();
}
template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID32>(IDRestorer<UniqueID32>* restorer)
{
s_restorer32.reset(restorer);
inline void UniqueIDBridge::SetIDRestorer<UniqueID32>(IDRestorer<UniqueID32>* restorer) {
s_restorer32.reset(restorer);
}
template <>
inline IDRestorer<UniqueID64>* UniqueIDBridge::GetIDRestorer<UniqueID64>()
{
return s_restorer64.get();
inline IDRestorer<UniqueID64>* UniqueIDBridge::GetIDRestorer<UniqueID64>() {
return s_restorer64.get();
}
template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID64>(IDRestorer<UniqueID64>* restorer)
{
s_restorer64.reset(restorer);
inline void UniqueIDBridge::SetIDRestorer<UniqueID64>(IDRestorer<UniqueID64>* restorer) {
s_restorer64.reset(restorer);
}
template <>
inline IDRestorer<UniqueID128>* UniqueIDBridge::GetIDRestorer<UniqueID128>()
{
return s_restorer128.get();
inline IDRestorer<UniqueID128>* UniqueIDBridge::GetIDRestorer<UniqueID128>() {
return s_restorer128.get();
}
template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID128>(IDRestorer<UniqueID128>* restorer)
{
s_restorer128.reset(restorer);
inline void UniqueIDBridge::SetIDRestorer<UniqueID128>(IDRestorer<UniqueID128>* restorer) {
s_restorer128.reset(restorer);
}
/** PAK 32-bit Unique ID */
class UniqueID32 : public BigDNA
{
class UniqueID32 : public BigDNA {
protected:
uint32_t m_id = 0xffffffff;
uint32_t m_id = 0xffffffff;
public:
using value_type = uint32_t;
static UniqueID32 kInvalidId;
AT_DECL_EXPLICIT_DNA_YAML
operator bool() const {return m_id != 0xffffffff && m_id != 0;}
void assign(uint32_t id, bool noOriginal = false);
using value_type = uint32_t;
static UniqueID32 kInvalidId;
AT_DECL_EXPLICIT_DNA_YAML
operator bool() const { return m_id != 0xffffffff && m_id != 0; }
void assign(uint32_t id, bool noOriginal = false);
UniqueID32& operator=(const hecl::ProjectPath& path)
{assign(path.hash().val32()); return *this;}
UniqueID32& operator=(const hecl::ProjectPath& path) {
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;}
uint32_t toUint32() const {return m_id;}
uint64_t toUint64() const {return m_id;}
std::string toString() const;
void clear() {m_id = 0xffffffff;}
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; }
uint64_t toUint64() const { return m_id; }
std::string toString() const;
void clear() { m_id = 0xffffffff; }
UniqueID32() = default;
UniqueID32(uint32_t idin, bool noOriginal = false) {assign(idin, noOriginal);}
UniqueID32(athena::io::IStreamReader& reader) {read(reader);}
UniqueID32(const hecl::ProjectPath& path) {*this = path;}
UniqueID32(const char* hexStr)
{
char copy[9];
strncpy(copy, hexStr, 8);
copy[8] = '\0';
assign(strtoul(copy, nullptr, 16));
}
UniqueID32(const wchar_t* hexStr)
{
wchar_t copy[9];
wcsncpy(copy, hexStr, 8);
copy[8] = L'\0';
assign(wcstoul(copy, nullptr, 16));
}
UniqueID32() = default;
UniqueID32(uint32_t idin, bool noOriginal = false) { assign(idin, noOriginal); }
UniqueID32(athena::io::IStreamReader& reader) { read(reader); }
UniqueID32(const hecl::ProjectPath& path) { *this = path; }
UniqueID32(const char* hexStr) {
char copy[9];
strncpy(copy, hexStr, 8);
copy[8] = '\0';
assign(strtoul(copy, nullptr, 16));
}
UniqueID32(const wchar_t* hexStr) {
wchar_t copy[9];
wcsncpy(copy, hexStr, 8);
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 */
class UniqueID32Zero : public UniqueID32
{
class UniqueID32Zero : public UniqueID32 {
public:
AT_DECL_DNA_YAML
Delete __d2;
using UniqueID32::UniqueID32;
AT_DECL_DNA_YAML
Delete __d2;
using UniqueID32::UniqueID32;
};
class AuxiliaryID32 : public UniqueID32
{
const hecl::SystemChar* m_auxStr;
const hecl::SystemChar* m_addExtension;
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) {}
class AuxiliaryID32 : public UniqueID32 {
const hecl::SystemChar* m_auxStr;
const hecl::SystemChar* m_addExtension;
UniqueID32 m_baseId;
AuxiliaryID32& operator=(const hecl::ProjectPath& path);
AuxiliaryID32& operator=(const UniqueID32& id);
const UniqueID32& getBaseId() const {return 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);
AuxiliaryID32& operator=(const UniqueID32& id);
const UniqueID32& getBaseId() const { return m_baseId; }
};
/** PAK 64-bit Unique ID */
class UniqueID64 : public BigDNA
{
uint64_t m_id = 0xffffffffffffffff;
class UniqueID64 : public BigDNA {
uint64_t m_id = 0xffffffffffffffff;
public:
using value_type = uint64_t;
AT_DECL_EXPLICIT_DNA_YAML
operator bool() const {return m_id != 0xffffffffffffffff && m_id != 0;}
void assign(uint64_t id, bool noOriginal = false);
using value_type = uint64_t;
AT_DECL_EXPLICIT_DNA_YAML
operator bool() const { return m_id != 0xffffffffffffffff && m_id != 0; }
void assign(uint64_t id, bool noOriginal = false);
UniqueID64& operator=(const hecl::ProjectPath& path)
{assign(path.hash().val64()); return *this;}
UniqueID64& operator=(const hecl::ProjectPath& path) {
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;}
uint64_t toUint64() const {return m_id;}
std::string toString() const;
void clear() {m_id = 0xffffffffffffffff;}
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; }
std::string toString() const;
void clear() { m_id = 0xffffffffffffffff; }
UniqueID64() = default;
UniqueID64(uint64_t idin, bool noOriginal = false) {assign(idin, noOriginal);}
UniqueID64(athena::io::IStreamReader& reader) {read(reader);}
UniqueID64(const hecl::ProjectPath& path) {*this = path;}
UniqueID64(const char* hexStr)
{
char copy[17];
strncpy(copy, hexStr, 16);
copy[16] = '\0';
UniqueID64() = default;
UniqueID64(uint64_t idin, bool noOriginal = false) { assign(idin, noOriginal); }
UniqueID64(athena::io::IStreamReader& reader) { read(reader); }
UniqueID64(const hecl::ProjectPath& path) { *this = path; }
UniqueID64(const char* hexStr) {
char copy[17];
strncpy(copy, hexStr, 16);
copy[16] = '\0';
#if _WIN32
assign(_strtoui64(copy, nullptr, 16));
assign(_strtoui64(copy, nullptr, 16));
#else
assign(strtouq(copy, nullptr, 16));
assign(strtouq(copy, nullptr, 16));
#endif
}
UniqueID64(const wchar_t* hexStr)
{
wchar_t copy[17];
wcsncpy(copy, hexStr, 16);
copy[16] = L'\0';
}
UniqueID64(const wchar_t* hexStr) {
wchar_t copy[17];
wcsncpy(copy, hexStr, 16);
copy[16] = L'\0';
#if _WIN32
assign(_wcstoui64(copy, nullptr, 16));
assign(_wcstoui64(copy, nullptr, 16));
#else
assign(wcstoull(copy, nullptr, 16));
assign(wcstoull(copy, nullptr, 16));
#endif
}
}
static constexpr size_t BinarySize() {return 8;}
static constexpr size_t BinarySize() { return 8; }
};
/** PAK 128-bit Unique ID */
class UniqueID128 : public BigDNA
{
class UniqueID128 : public BigDNA {
public:
union Value
{
uint64_t id[2];
union Value {
uint64_t id[2];
#if __SSE__
__m128i id128;
__m128i id128;
#endif
};
};
private:
Value m_id;
Value m_id;
public:
using value_type = uint64_t;
AT_DECL_EXPLICIT_DNA_YAML
UniqueID128() {m_id.id[0]=0xffffffffffffffff; m_id.id[1]=0xffffffffffffffff;}
UniqueID128(uint64_t idin, bool noOriginal = false)
{
m_id.id[0] = idin;
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;}
using value_type = uint64_t;
AT_DECL_EXPLICIT_DNA_YAML
UniqueID128() {
m_id.id[0] = 0xffffffffffffffff;
m_id.id[1] = 0xffffffffffffffff;
}
UniqueID128(uint64_t idin, bool noOriginal = false) {
m_id.id[0] = idin;
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)
{
m_id.id[0] = path.hash().val64();
m_id.id[1] = 0;
return *this;
}
UniqueID128(const hecl::ProjectPath& path) {*this = path;}
UniqueID128& operator=(const hecl::ProjectPath& path) {
m_id.id[0] = path.hash().val64();
m_id.id[1] = 0;
return *this;
}
UniqueID128(const hecl::ProjectPath& path) { *this = path; }
bool operator!=(const UniqueID128& other) const
{
bool operator!=(const UniqueID128& other) const {
#if __SSE__
__m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128);
int vmask = _mm_movemask_epi8(vcmp);
return vmask != 0xffff;
__m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128);
int vmask = _mm_movemask_epi8(vcmp);
return vmask != 0xffff;
#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
}
bool operator==(const UniqueID128& other) const
{
}
bool operator==(const UniqueID128& other) const {
#if __SSE__
__m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128);
int vmask = _mm_movemask_epi8(vcmp);
return vmask == 0xffff;
__m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128);
int vmask = _mm_movemask_epi8(vcmp);
return vmask == 0xffff;
#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
}
void clear() {m_id.id[0] = 0xffffffffffffffff; m_id.id[1] = 0xffffffffffffffff;}
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;
}
void clear() {
m_id.id[0] = 0xffffffffffffffff;
m_id.id[1] = 0xffffffffffffffff;
}
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 */
@ -347,63 +338,66 @@ template <class T>
using CastIDToZero = typename std::conditional_t<std::is_same_v<T, UniqueID32>, UniqueID32Zero, T>;
/** Word Bitmap reader/writer */
class WordBitmap
{
std::vector<atUint32> m_words;
size_t m_bitCount = 0;
class WordBitmap {
std::vector<atUint32> m_words;
size_t m_bitCount = 0;
public:
void read(athena::io::IStreamReader& reader, size_t bitCount);
void write(athena::io::IStreamWriter& writer) const;
void reserve(size_t bitCount) { m_words.reserve((bitCount + 31) / 32); }
void binarySize(size_t& __isz) const;
size_t getBitCount() const {return m_bitCount;}
bool getBit(size_t idx) const
{
size_t wordIdx = idx / 32;
if (wordIdx >= m_words.size())
return false;
size_t wordCur = idx % 32;
return (m_words[wordIdx] >> wordCur) & 0x1;
}
void setBit(size_t idx)
{
size_t wordIdx = idx / 32;
while (wordIdx >= m_words.size())
m_words.push_back(0);
size_t wordCur = idx % 32;
m_words[wordIdx] |= (1 << wordCur);
m_bitCount = std::max(m_bitCount, idx + 1);
}
void unsetBit(size_t idx)
{
size_t wordIdx = idx / 32;
while (wordIdx >= m_words.size())
m_words.push_back(0);
size_t wordCur = idx % 32;
m_words[wordIdx] &= ~(1 << wordCur);
m_bitCount = std::max(m_bitCount, idx + 1);
}
void clear() { m_words.clear(); m_bitCount = 0; }
void read(athena::io::IStreamReader& reader, size_t bitCount);
void write(athena::io::IStreamWriter& writer) const;
void reserve(size_t bitCount) { m_words.reserve((bitCount + 31) / 32); }
void binarySize(size_t& __isz) const;
size_t getBitCount() const { return m_bitCount; }
bool getBit(size_t idx) const {
size_t wordIdx = idx / 32;
if (wordIdx >= m_words.size())
return false;
size_t wordCur = idx % 32;
return (m_words[wordIdx] >> wordCur) & 0x1;
}
void setBit(size_t idx) {
size_t wordIdx = idx / 32;
while (wordIdx >= m_words.size())
m_words.push_back(0);
size_t wordCur = idx % 32;
m_words[wordIdx] |= (1 << wordCur);
m_bitCount = std::max(m_bitCount, idx + 1);
}
void unsetBit(size_t idx) {
size_t wordIdx = idx / 32;
while (wordIdx >= m_words.size())
m_words.push_back(0);
size_t wordCur = idx % 32;
m_words[wordIdx] &= ~(1 << wordCur);
m_bitCount = std::max(m_bitCount, idx + 1);
}
void clear() {
m_words.clear();
m_bitCount = 0;
}
class Iterator
{
friend class WordBitmap;
const WordBitmap& m_bmp;
size_t m_idx = 0;
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&;
class Iterator {
friend class WordBitmap;
const WordBitmap& m_bmp;
size_t m_idx = 0;
Iterator(const WordBitmap& bmp, size_t idx) : m_bmp(bmp), m_idx(idx) {}
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);}
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;
}
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 */
@ -411,60 +405,47 @@ typedef std::function<bool(const hecl::ProjectPath&, const hecl::ProjectPath&)>
/** Mappings of resources involved in extracting characters */
template <class IDType>
struct CharacterAssociations
{
using RigPair = std::pair<IDType, IDType>;
/* CMDL -> (CSKR, CINF) */
std::unordered_map<IDType, RigPair> m_cmdlRigs;
/* (CSKR, CINF) -> ANCS */
std::unordered_map<IDType, std::pair<IDType, std::string>> m_cskrCinfToCharacter;
/* ANCS -> (CINF, CMDL) */
std::unordered_multimap<IDType, std::pair<RigPair, std::string>> m_characterToAttachmentRigs;
using MultimapIteratorPair = 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>;
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)
if (it->second.second == name)
return;
m_characterToAttachmentRigs.insert(
std::make_pair(character, std::make_pair(std::make_pair(cinf, cmdl), name)));
}
struct CharacterAssociations {
using RigPair = std::pair<IDType, IDType>;
/* CMDL -> (CSKR, CINF) */
std::unordered_map<IDType, RigPair> m_cmdlRigs;
/* (CSKR, CINF) -> ANCS */
std::unordered_map<IDType, std::pair<IDType, std::string>> m_cskrCinfToCharacter;
/* ANCS -> (CINF, CMDL) */
std::unordered_multimap<IDType, std::pair<RigPair, std::string>> m_characterToAttachmentRigs;
using MultimapIteratorPair =
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>;
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)
if (it->second.second == 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 */
namespace std
{
template<>
struct hash<DataSpec::DNAFourCC>
{
size_t operator()(const DataSpec::DNAFourCC& fcc) const
{return fcc.toUint32();}
namespace std {
template <>
struct hash<DataSpec::DNAFourCC> {
size_t operator()(const DataSpec::DNAFourCC& fcc) const { return fcc.toUint32(); }
};
template<>
struct hash<DataSpec::UniqueID32>
{
size_t operator()(const DataSpec::UniqueID32& id) const
{return id.toUint32();}
template <>
struct hash<DataSpec::UniqueID32> {
size_t operator()(const DataSpec::UniqueID32& id) const { return id.toUint32(); }
};
template<>
struct hash<DataSpec::UniqueID64>
{
size_t operator()(const DataSpec::UniqueID64& id) const
{return id.toUint64();}
template <>
struct hash<DataSpec::UniqueID64> {
size_t operator()(const DataSpec::UniqueID64& id) const { return id.toUint64(); }
};
template<>
struct hash<DataSpec::UniqueID128>
{
size_t operator()(const DataSpec::UniqueID128& id) const
{return id.toHighUint64() ^ id.toLowUint64();}
template <>
struct hash<DataSpec::UniqueID128> {
size_t operator()(const DataSpec::UniqueID128& id) const { return id.toHighUint64() ^ id.toLowUint64(); }
};
}
} // namespace std

View File

@ -1,418 +1,377 @@
#include "DPSC.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <>
const char* DPSM<UniqueID32>::DNAType() { return "DPSM<UniqueID32>"; }
const char* DPSM<UniqueID32>::DNAType() {
return "DPSM<UniqueID32>";
}
template <>
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;
}
}
}
const char* DPSM<UniqueID64>::DNAType() {
return "DPSM<UniqueID64>";
}
template <class IDType>
void DPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const
{
writeQuadDecalInfo(w, x0_quad, true);
writeQuadDecalInfo(w, x1c_quad, false);
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 (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 (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;
}
}
}
}
if (x5c_24_DMAB)
w.writeBool("DMAB", x5c_24_DMAB);
if (x5c_25_DMOO)
w.writeBool("DMOO", x5c_25_DMOO);
template <class IDType>
void DPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const {
writeQuadDecalInfo(w, x0_quad, true);
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 Reader>
void DPSM<IDType>::readQuadDecalInfo(Reader& r, uint32_t clsId, typename DPSM<IDType>::SQuadDescr& quad)
{
switch(clsId)
{
case SBIG('1LFT'):
case SBIG('2LFT'):
quad.x0_LFT.read(r);
void DPSM<IDType>::readQuadDecalInfo(Reader& r, uint32_t clsId, typename DPSM<IDType>::SQuadDescr& quad) {
switch (clsId) {
case SBIG('1LFT'):
case SBIG('2LFT'):
quad.x0_LFT.read(r);
break;
case SBIG('1SZE'):
case SBIG('2SZE'):
quad.x4_SZE.read(r);
case SBIG('1SZE'):
case SBIG('2SZE'):
quad.x4_SZE.read(r);
break;
case SBIG('1ROT'):
case SBIG('2ROT'):
quad.x8_ROT.read(r);
case SBIG('1ROT'):
case SBIG('2ROT'):
quad.x8_ROT.read(r);
break;
case SBIG('1OFF'):
case SBIG('2OFF'):
quad.xc_OFF.read(r);
case SBIG('1OFF'):
case SBIG('2OFF'):
quad.xc_OFF.read(r);
break;
case SBIG('1CLR'):
case SBIG('2CLR'):
quad.x10_CLR.read(r);
case SBIG('1CLR'):
case SBIG('2CLR'):
quad.x10_CLR.read(r);
break;
case SBIG('1TEX'):
case SBIG('2TEX'):
quad.x14_TEX.read(r);
case SBIG('1TEX'):
case SBIG('2TEX'):
quad.x14_TEX.read(r);
break;
case SBIG('1ADD'):
case SBIG('2ADD'):
quad.x18_ADD.read(r);
case SBIG('1ADD'):
case SBIG('2ADD'):
quad.x18_ADD.read(r);
break;
}
}
}
template <class IDType>
void DPSM<IDType>::writeQuadDecalInfo(athena::io::YAMLDocWriter& w,
const typename DPSM<IDType>::SQuadDescr& quad, bool first) const
{
if (quad.x0_LFT)
if (auto rec = w.enterSubRecord((first ? "1LFT" : "2LFT")))
quad.x0_LFT.write(w);
if (quad.x4_SZE)
if (auto rec = w.enterSubRecord((first ? "1SZE" : "2SZE")))
quad.x4_SZE.write(w);
if (quad.x8_ROT)
if (auto rec = w.enterSubRecord((first ? "1ROT" : "2ROT")))
quad.x8_ROT.write(w);
if (quad.xc_OFF)
if (auto rec = w.enterSubRecord((first ? "1OFF" : "2OFF")))
quad.xc_OFF.write(w);
if (quad.x10_CLR)
if (auto rec = w.enterSubRecord((first ? "1CLR" : "2CLR")))
quad.x10_CLR.write(w);
if (quad.x14_TEX)
if (auto rec = w.enterSubRecord((first ? "1TEX" : "2TEX")))
quad.x14_TEX.write(w);
if (quad.x18_ADD)
if (auto rec = w.enterSubRecord((first ? "1ADD" : "2ADD")))
quad.x18_ADD.write(w);
void DPSM<IDType>::writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const typename DPSM<IDType>::SQuadDescr& quad,
bool first) const {
if (quad.x0_LFT)
if (auto rec = w.enterSubRecord((first ? "1LFT" : "2LFT")))
quad.x0_LFT.write(w);
if (quad.x4_SZE)
if (auto rec = w.enterSubRecord((first ? "1SZE" : "2SZE")))
quad.x4_SZE.write(w);
if (quad.x8_ROT)
if (auto rec = w.enterSubRecord((first ? "1ROT" : "2ROT")))
quad.x8_ROT.write(w);
if (quad.xc_OFF)
if (auto rec = w.enterSubRecord((first ? "1OFF" : "2OFF")))
quad.xc_OFF.write(w);
if (quad.x10_CLR)
if (auto rec = w.enterSubRecord((first ? "1CLR" : "2CLR")))
quad.x10_CLR.write(w);
if (quad.x14_TEX)
if (auto rec = w.enterSubRecord((first ? "1TEX" : "2TEX")))
quad.x14_TEX.write(w);
if (quad.x18_ADD)
if (auto rec = w.enterSubRecord((first ? "1ADD" : "2ADD")))
quad.x18_ADD.write(w);
}
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;
getQuadDecalBinarySize(s, x0_quad);
getQuadDecalBinarySize(s, x1c_quad);
if (x38_DMDL)
{
s += 4;
x38_DMDL.binarySize(s);
}
if (x48_DLFT)
{
s += 4;
x48_DLFT.binarySize(s);
}
if (x4c_DMOP)
{
s += 4;
x4c_DMOP.binarySize(s);
}
if (x50_DMRT)
{
s += 4;
x50_DMRT.binarySize(s);
}
if (x54_DMSC)
{
s += 4;
x54_DMSC.binarySize(s);
}
if (x58_DMCL)
{
x58_DMCL.binarySize(s);
}
if (x5c_24_DMAB)
s += 9;
if (x5c_25_DMOO)
s += 9;
x38_DMDL.binarySize(s);
}
if (x48_DLFT) {
s += 4;
x48_DLFT.binarySize(s);
}
if (x4c_DMOP) {
s += 4;
x4c_DMOP.binarySize(s);
}
if (x50_DMRT) {
s += 4;
x50_DMRT.binarySize(s);
}
if (x54_DMSC) {
s += 4;
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>
void DPSM<IDType>::getQuadDecalBinarySize(size_t& s, const typename DPSM<IDType>::SQuadDescr& quad) const
{
if (quad.x0_LFT)
{
s += 4;
quad.x0_LFT.binarySize(s);
}
if (quad.x4_SZE)
{
s += 4;
quad.x4_SZE.binarySize(s);
}
if (quad.x8_ROT)
{
s += 4;
quad.x8_ROT.binarySize(s);
}
if (quad.xc_OFF)
{
s += 4;
quad.xc_OFF.binarySize(s);
}
if (quad.x10_CLR)
{
s += 4;
quad.x10_CLR.binarySize(s);
}
if (quad.x14_TEX)
{
s += 4;
quad.x14_TEX.binarySize(s);
}
if (quad.x18_ADD)
{
s += 4;
quad.x18_ADD.binarySize(s);
}
void DPSM<IDType>::getQuadDecalBinarySize(size_t& s, const typename DPSM<IDType>::SQuadDescr& quad) const {
if (quad.x0_LFT) {
s += 4;
quad.x0_LFT.binarySize(s);
}
if (quad.x4_SZE) {
s += 4;
quad.x4_SZE.binarySize(s);
}
if (quad.x8_ROT) {
s += 4;
quad.x8_ROT.binarySize(s);
}
if (quad.xc_OFF) {
s += 4;
quad.xc_OFF.binarySize(s);
}
if (quad.x10_CLR) {
s += 4;
quad.x10_CLR.binarySize(s);
}
if (quad.x14_TEX) {
s += 4;
quad.x14_TEX.binarySize(s);
}
if (quad.x18_ADD) {
s += 4;
quad.x18_ADD.binarySize(s);
}
}
template <class IDType>
void DPSM<IDType>::_read(athena::io::IStreamReader& r)
{
uint32_t clsId;
void DPSM<IDType>::_read(athena::io::IStreamReader& r) {
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);
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>
void DPSM<IDType>::_write(athena::io::IStreamWriter& w) const
{
w.writeBytes("DPSM", 4);
writeQuadDecalInfo(w, x0_quad, true);
writeQuadDecalInfo(w, x1c_quad, false);
if (x38_DMDL)
{
w.writeBytes("DMDL", 4);
x38_DMDL.write(w);
}
if (x48_DLFT)
{
w.writeBytes("DLFT", 4);
x48_DLFT.write(w);
}
if (x4c_DMOP)
{
w.writeBytes("DMOP", 4);
x4c_DMOP.write(w);
}
if (x50_DMRT)
{
w.writeBytes("DMRT", 4);
x50_DMRT.write(w);
}
if (x54_DMSC)
{
w.writeBytes("DMSC", 4);
x54_DMSC.write(w);
}
if (x58_DMCL)
{
w.writeBytes("DMCL", 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);
void DPSM<IDType>::_write(athena::io::IStreamWriter& w) const {
w.writeBytes("DPSM", 4);
writeQuadDecalInfo(w, x0_quad, true);
writeQuadDecalInfo(w, x1c_quad, false);
if (x38_DMDL) {
w.writeBytes("DMDL", 4);
x38_DMDL.write(w);
}
if (x48_DLFT) {
w.writeBytes("DLFT", 4);
x48_DLFT.write(w);
}
if (x4c_DMOP) {
w.writeBytes("DMOP", 4);
x4c_DMOP.write(w);
}
if (x50_DMRT) {
w.writeBytes("DMRT", 4);
x50_DMRT.write(w);
}
if (x54_DMSC) {
w.writeBytes("DMSC", 4);
x54_DMSC.write(w);
}
if (x58_DMCL) {
w.writeBytes("DMCL", 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>
void DPSM<IDType>::writeQuadDecalInfo(athena::io::IStreamWriter& w,
const typename DPSM<IDType>::SQuadDescr& quad, bool first) const
{
if (quad.x0_LFT)
{
w.writeBytes((first ? "1LFT" : "2LFT"), 4);
quad.x0_LFT.write(w);
}
if (quad.x4_SZE)
{
w.writeBytes((first ? "1SZE" : "2SZE"), 4);
quad.x4_SZE.write(w);
}
if (quad.x8_ROT)
{
w.writeBytes((first ? "1ROT" : "2ROT"), 4);
quad.x8_ROT.write(w);
}
if (quad.xc_OFF)
{
w.writeBytes((first ? "1OFF" : "2OFF"), 4);
quad.xc_OFF.write(w);
}
if (quad.x10_CLR)
{
w.writeBytes((first ? "1CLR" : "2CLR"), 4);
quad.x10_CLR.write(w);
}
if (quad.x14_TEX)
{
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);
}
void DPSM<IDType>::writeQuadDecalInfo(athena::io::IStreamWriter& w, const typename DPSM<IDType>::SQuadDescr& quad,
bool first) const {
if (quad.x0_LFT) {
w.writeBytes((first ? "1LFT" : "2LFT"), 4);
quad.x0_LFT.write(w);
}
if (quad.x4_SZE) {
w.writeBytes((first ? "1SZE" : "2SZE"), 4);
quad.x4_SZE.write(w);
}
if (quad.x8_ROT) {
w.writeBytes((first ? "1ROT" : "2ROT"), 4);
quad.x8_ROT.write(w);
}
if (quad.xc_OFF) {
w.writeBytes((first ? "1OFF" : "2OFF"), 4);
quad.xc_OFF.write(w);
}
if (quad.x10_CLR) {
w.writeBytes((first ? "1CLR" : "2CLR"), 4);
quad.x10_CLR.write(w);
}
if (quad.x14_TEX) {
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>
void DPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
if (x0_quad.x14_TEX.m_elem)
x0_quad.x14_TEX.m_elem->gatherDependencies(pathsOut);
if (x1c_quad.x14_TEX.m_elem)
x1c_quad.x14_TEX.m_elem->gatherDependencies(pathsOut);
g_curSpec->flattenDependencies(x38_DMDL.id, pathsOut);
void DPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
if (x0_quad.x14_TEX.m_elem)
x0_quad.x14_TEX.m_elem->gatherDependencies(pathsOut);
if (x1c_quad.x14_TEX.m_elem)
x1c_quad.x14_TEX.m_elem->gatherDependencies(pathsOut);
g_curSpec->flattenDependencies(x38_DMDL.id, pathsOut);
}
AT_SUBSPECIALIZE_DNA_YAML(DPSM<UniqueID32>)
@ -421,36 +380,32 @@ template struct DPSM<UniqueID32>;
template struct DPSM<UniqueID64>;
template <class IDType>
bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
DPSM<IDType> dpsm;
dpsm.read(rs);
athena::io::ToYAMLStream(dpsm, writer);
return true;
}
return false;
bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen()) {
DPSM<IDType> dpsm;
dpsm.read(rs);
athena::io::ToYAMLStream(dpsm, writer);
return true;
}
return false;
}
template bool ExtractDPSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractDPSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
dpsm.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i=0 ; i<32-rem ; ++i)
w.writeUByte(0xff);
return true;
bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
dpsm.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 bool WriteDPSM<UniqueID32>(const DPSM<UniqueID32>& 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 "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
struct DPSM : BigDNA
{
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
struct DPSM : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
struct SQuadDescr
{
IntElementFactory x0_LFT;
RealElementFactory x4_SZE;
RealElementFactory x8_ROT;
VectorElementFactory xc_OFF;
ColorElementFactory x10_CLR;
UVElementFactory<IDType> x14_TEX;
BoolHelper x18_ADD;
struct SQuadDescr {
IntElementFactory x0_LFT;
RealElementFactory x4_SZE;
RealElementFactory x8_ROT;
VectorElementFactory xc_OFF;
ColorElementFactory x10_CLR;
UVElementFactory<IDType> x14_TEX;
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;
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;
void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
};
template <class IDType>
@ -52,5 +51,4 @@ bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
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 <cinttypes>
namespace DataSpec
{
namespace DataSpec {
template<class DEAFBABE>
void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln, atInt32 idx)
{
os << "material_index = []\n"
"col_bm = bmesh.new()\n";
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]);
template <class DEAFBABE>
void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln, atInt32 idx) {
os << "material_index = []\n"
"col_bm = bmesh.new()\n";
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]);
}
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;
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;
os.format(
"face = col_bm.faces.get(tri_verts)\n"
"if face is None:\n"
" face = col_bm.faces.new(tri_verts)\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));
}
int vindices[3];
vindices[2] =
(edge1.verts[0] != edge0.verts[0] && edge1.verts[0] != edge0.verts[1]) ?
edge1.verts[0] : edge1.verts[1];
db.insertNoClimb(os);
if (triMat.flipFace())
{
vindices[0] = edge0.verts[1];
vindices[1] = edge0.verts[0];
}
else
{
vindices[0] = edge0.verts[0];
vindices[1] = edge0.verts[1];
}
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 << "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]);
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.format("face = col_bm.faces.get(tri_verts)\n"
"if face is None:\n"
" face = col_bm.faces.new(tri_verts)\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";
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<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 void DeafBabeSendToBlender<DNAMP1::DeafBabe>(hecl::blender::PyOutStream& os, const DNAMP1::DeafBabe& 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>
static void PopulateAreaFields(DEAFBABE& db,
const hecl::blender::ColMesh& colMesh,
const zeus::CAABox& fullAABB,
std::enable_if_t<std::is_same<DEAFBABE, DNAMP1::DeafBabe>::value ||
std::is_same<DEAFBABE, DNAMP2::DeafBabe>::value, int>* = 0)
{
AROTBuilder builder;
auto octree = builder.buildCol(colMesh, db.rootNodeType);
static_cast<std::unique_ptr<atUint8[]>&>(db.bspTree) = std::move(octree.first);
db.bspSize = octree.second;
template <class DEAFBABE>
static void PopulateAreaFields(
DEAFBABE& db, const hecl::blender::ColMesh& colMesh, const zeus::CAABox& fullAABB,
std::enable_if_t<std::is_same<DEAFBABE, DNAMP1::DeafBabe>::value || std::is_same<DEAFBABE, DNAMP2::DeafBabe>::value,
int>* = 0) {
AROTBuilder builder;
auto octree = builder.buildCol(colMesh, db.rootNodeType);
static_cast<std::unique_ptr<atUint8[]>&>(db.bspTree) = std::move(octree.first);
db.bspSize = octree.second;
db.unk1 = 0x1000000;
size_t dbSize = 0;
db.binarySize(dbSize);
db.length = dbSize - 8;
db.magic = 0xDEAFBABE;
db.version = 3;
db.aabb[0] = fullAABB.min;
db.aabb[1] = fullAABB.max;
db.unk1 = 0x1000000;
size_t dbSize = 0;
db.binarySize(dbSize);
db.length = dbSize - 8;
db.magic = 0xDEAFBABE;
db.version = 3;
db.aabb[0] = fullAABB.min;
db.aabb[1] = fullAABB.max;
}
template<class DEAFBABE>
static void PopulateAreaFields(DEAFBABE& db,
const hecl::blender::ColMesh& colMesh,
const zeus::CAABox& fullAABB,
std::enable_if_t<std::is_same<DEAFBABE, DNAMP1::DCLN::Collision>::value, int>* = 0)
{
db.magic = 0xDEAFBABE;
db.version = 2;
db.memSize = 0;
template <class DEAFBABE>
static void PopulateAreaFields(DEAFBABE& db, const hecl::blender::ColMesh& colMesh, const zeus::CAABox& fullAABB,
std::enable_if_t<std::is_same<DEAFBABE, DNAMP1::DCLN::Collision>::value, int>* = 0) {
db.magic = 0xDEAFBABE;
db.version = 2;
db.memSize = 0;
}
class MaterialPool
{
std::unordered_map<u64, int> m_materials;
class MaterialPool {
std::unordered_map<u64, int> m_materials;
public:
template <class M, class V>
int AddOrLookup(const M& mat, V& vec)
{
auto search = m_materials.find(mat.material);
if (search != m_materials.end())
return search->second;
auto idx = int(vec.size());
vec.push_back(mat);
m_materials[mat.material] = idx;
return idx;
}
template <class M, class V>
int AddOrLookup(const M& mat, V& vec) {
auto search = m_materials.find(mat.material);
if (search != m_materials.end())
return search->second;
auto idx = int(vec.size());
vec.push_back(mat);
m_materials[mat.material] = idx;
return idx;
}
};
template<class DEAFBABE>
void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh)
{
using BlendMat = hecl::blender::ColMesh::Material;
template <class DEAFBABE>
void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh) {
using BlendMat = hecl::blender::ColMesh::Material;
auto MakeMat = [](const BlendMat& mat, bool flipFace) -> typename DEAFBABE::Material
{
typename DEAFBABE::Material dbMat = {};
dbMat.setUnknown(mat.unknown);
dbMat.setSurfaceStone(mat.surfaceStone);
dbMat.setSurfaceMetal(mat.surfaceMetal);
dbMat.setSurfaceGrass(mat.surfaceGrass);
dbMat.setSurfaceIce(mat.surfaceIce);
dbMat.setPillar(mat.pillar);
dbMat.setSurfaceMetalGrating(mat.surfaceMetalGrating);
dbMat.setSurfacePhazon(mat.surfacePhazon);
dbMat.setSurfaceDirt(mat.surfaceDirt);
dbMat.setSurfaceLava(mat.surfaceLava);
dbMat.setSurfaceSPMetal(mat.surfaceSPMetal);
dbMat.setSurfaceLavaStone(mat.surfaceLavaStone);
dbMat.setSurfaceSnow(mat.surfaceSnow);
dbMat.setSurfaceMudSlow(mat.surfaceMudSlow);
dbMat.setSurfaceFabric(mat.surfaceFabric);
dbMat.setHalfPipe(mat.halfPipe);
dbMat.setSurfaceMud(mat.surfaceMud);
dbMat.setSurfaceGlass(mat.surfaceGlass);
dbMat.setUnused3(mat.unused3);
dbMat.setUnused4(mat.unused4);
dbMat.setSurfaceShield(mat.surfaceShield);
dbMat.setSurfaceSand(mat.surfaceSand);
dbMat.setSurfaceMothOrSeedOrganics(mat.surfaceMothOrSeedOrganics);
dbMat.setSurfaceWeb(mat.surfaceWeb);
dbMat.setProjectilePassthrough(mat.projPassthrough);
dbMat.setSolid(mat.solid);
dbMat.setNoPlatformCollision(mat.noPlatformCollision);
dbMat.setCameraPassthrough(mat.camPassthrough);
dbMat.setSurfaceWood(mat.surfaceWood);
dbMat.setSurfaceOrganic(mat.surfaceOrganic);
dbMat.setNoEdgeCollision(mat.noEdgeCollision);
dbMat.setSurfaceRubber(mat.surfaceRubber);
dbMat.setSeeThrough(mat.seeThrough);
dbMat.setScanPassthrough(mat.scanPassthrough);
dbMat.setAiPassthrough(mat.aiPassthrough);
dbMat.setCeiling(mat.ceiling);
dbMat.setWall(mat.wall);
dbMat.setFloor(mat.floor);
dbMat.setAiBlock(mat.aiBlock);
dbMat.setJumpNotAllowed(mat.jumpNotAllowed);
dbMat.setSpiderBall(mat.spiderBall);
dbMat.setScrewAttackWallJump(mat.screwAttackWallJump);
dbMat.setFlipFace(flipFace);
return dbMat;
};
auto MakeMat = [](const BlendMat& mat, bool flipFace) -> typename DEAFBABE::Material {
typename DEAFBABE::Material dbMat = {};
dbMat.setUnknown(mat.unknown);
dbMat.setSurfaceStone(mat.surfaceStone);
dbMat.setSurfaceMetal(mat.surfaceMetal);
dbMat.setSurfaceGrass(mat.surfaceGrass);
dbMat.setSurfaceIce(mat.surfaceIce);
dbMat.setPillar(mat.pillar);
dbMat.setSurfaceMetalGrating(mat.surfaceMetalGrating);
dbMat.setSurfacePhazon(mat.surfacePhazon);
dbMat.setSurfaceDirt(mat.surfaceDirt);
dbMat.setSurfaceLava(mat.surfaceLava);
dbMat.setSurfaceSPMetal(mat.surfaceSPMetal);
dbMat.setSurfaceLavaStone(mat.surfaceLavaStone);
dbMat.setSurfaceSnow(mat.surfaceSnow);
dbMat.setSurfaceMudSlow(mat.surfaceMudSlow);
dbMat.setSurfaceFabric(mat.surfaceFabric);
dbMat.setHalfPipe(mat.halfPipe);
dbMat.setSurfaceMud(mat.surfaceMud);
dbMat.setSurfaceGlass(mat.surfaceGlass);
dbMat.setUnused3(mat.unused3);
dbMat.setUnused4(mat.unused4);
dbMat.setSurfaceShield(mat.surfaceShield);
dbMat.setSurfaceSand(mat.surfaceSand);
dbMat.setSurfaceMothOrSeedOrganics(mat.surfaceMothOrSeedOrganics);
dbMat.setSurfaceWeb(mat.surfaceWeb);
dbMat.setProjectilePassthrough(mat.projPassthrough);
dbMat.setSolid(mat.solid);
dbMat.setNoPlatformCollision(mat.noPlatformCollision);
dbMat.setCameraPassthrough(mat.camPassthrough);
dbMat.setSurfaceWood(mat.surfaceWood);
dbMat.setSurfaceOrganic(mat.surfaceOrganic);
dbMat.setNoEdgeCollision(mat.noEdgeCollision);
dbMat.setSurfaceRubber(mat.surfaceRubber);
dbMat.setSeeThrough(mat.seeThrough);
dbMat.setScanPassthrough(mat.scanPassthrough);
dbMat.setAiPassthrough(mat.aiPassthrough);
dbMat.setCeiling(mat.ceiling);
dbMat.setWall(mat.wall);
dbMat.setFloor(mat.floor);
dbMat.setAiBlock(mat.aiBlock);
dbMat.setJumpNotAllowed(mat.jumpNotAllowed);
dbMat.setSpiderBall(mat.spiderBall);
dbMat.setScrewAttackWallJump(mat.screwAttackWallJump);
dbMat.setFlipFace(flipFace);
return dbMat;
};
MaterialPool matPool;
db.materials.reserve(colMesh.materials.size() * 2);
MaterialPool matPool;
db.materials.reserve(colMesh.materials.size() * 2);
zeus::CAABox fullAABB;
zeus::CAABox fullAABB;
db.verts.reserve(colMesh.verts.size());
db.vertMats.resize(colMesh.verts.size());
for (const auto& vert : colMesh.verts)
{
fullAABB.accumulateBounds(zeus::CVector3f(vert));
db.verts.push_back(vert);
db.verts.reserve(colMesh.verts.size());
db.vertMats.resize(colMesh.verts.size());
for (const auto& vert : colMesh.verts) {
fullAABB.accumulateBounds(zeus::CVector3f(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.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.materialCount = db.materials.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.triMatsCount = colMesh.trianges.size();
db.triangleEdgesCount = colMesh.trianges.size() * 3;
db.materialCount = db.materials.size();
PopulateAreaFields(db, colMesh, fullAABB);
PopulateAreaFields(db, colMesh, fullAABB);
}
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<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"
namespace DataSpec
{
namespace DataSpec {
enum class BspNodeType : atUint32
{
Invalid,
Branch,
Leaf
};
enum class BspNodeType : atUint32 { Invalid, Branch, Leaf };
template<class DEAFBABE>
template <class DEAFBABE>
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);
}
} // namespace DataSpec

View File

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

View File

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

View File

@ -1,246 +1,231 @@
#include "FONT.hpp"
namespace DataSpec::DNAFont
{
namespace DataSpec::DNAFont {
logvisor::Module LogModule("urde::DNAFont");
template <class IDType>
void FONT<IDType>::_read(athena::io::IStreamReader& __dna_reader)
{
/* magic */
atUint32 magic;
__dna_reader.readBytesToBuf(&magic, 4);
if (magic != SBIG('FONT'))
{
LogModule.report(logvisor::Fatal, "Invalid FONT magic '%s'", &magic);
return;
}
/* version */
version = __dna_reader.readUint32Big();
/* unknown1 */
unknown1 = __dna_reader.readUint32Big();
/* lineHeight */
lineHeight = __dna_reader.readInt32Big();
/* verticalOffset */
verticalOffset = __dna_reader.readInt32Big();
/* lineMargin */
lineMargin = __dna_reader.readInt32Big();
/* unknown2 */
unknown2 = __dna_reader.readBool();
/* unknown3 */
unknown3 = __dna_reader.readBool();
/* unknown4 */
unknown4 = __dna_reader.readUint32Big();
/* fontSize */
fontSize = __dna_reader.readUint32Big();
/* name */
name = __dna_reader.readString(-1);
/* textureId */
textureId.read(__dna_reader);
/* textureFormat */
textureFormat = __dna_reader.readUint32Big();
/* glyphCount */
glyphCount = __dna_reader.readUint32Big();
/* glyphs */
for (atUint32 i = 0; i < glyphCount; i++)
{
if (version < 4)
glyphs.emplace_back(new GlyphMP1);
else
glyphs.emplace_back(new GlyphMP2);
glyphs.back()->read(__dna_reader);
}
/* kerningInfoCount */
kerningInfoCount = __dna_reader.readUint32Big();
/* kerningInfo */
__dna_reader.enumerate(kerningInfo, kerningInfoCount);
void FONT<IDType>::_read(athena::io::IStreamReader& __dna_reader) {
/* magic */
atUint32 magic;
__dna_reader.readBytesToBuf(&magic, 4);
if (magic != SBIG('FONT')) {
LogModule.report(logvisor::Fatal, "Invalid FONT magic '%s'", &magic);
return;
}
/* version */
version = __dna_reader.readUint32Big();
/* unknown1 */
unknown1 = __dna_reader.readUint32Big();
/* lineHeight */
lineHeight = __dna_reader.readInt32Big();
/* verticalOffset */
verticalOffset = __dna_reader.readInt32Big();
/* lineMargin */
lineMargin = __dna_reader.readInt32Big();
/* unknown2 */
unknown2 = __dna_reader.readBool();
/* unknown3 */
unknown3 = __dna_reader.readBool();
/* unknown4 */
unknown4 = __dna_reader.readUint32Big();
/* fontSize */
fontSize = __dna_reader.readUint32Big();
/* name */
name = __dna_reader.readString(-1);
/* textureId */
textureId.read(__dna_reader);
/* textureFormat */
textureFormat = __dna_reader.readUint32Big();
/* glyphCount */
glyphCount = __dna_reader.readUint32Big();
/* glyphs */
for (atUint32 i = 0; i < glyphCount; i++) {
if (version < 4)
glyphs.emplace_back(new GlyphMP1);
else
glyphs.emplace_back(new GlyphMP2);
glyphs.back()->read(__dna_reader);
}
/* kerningInfoCount */
kerningInfoCount = __dna_reader.readUint32Big();
/* kerningInfo */
__dna_reader.enumerate(kerningInfo, kerningInfoCount);
}
template <class IDType>
void FONT<IDType>::_write(athena::io::IStreamWriter& __dna_writer) const
{
/* magic */
__dna_writer.writeBytes((atInt8*)"FONT", 4);
/* version */
__dna_writer.writeUint32Big(version);
/* unknown1 */
__dna_writer.writeUint32Big(unknown1);
/* lineHeight */
__dna_writer.writeInt32Big(lineHeight);
/* verticalOffset */
__dna_writer.writeInt32Big(verticalOffset);
/* lineMargin */
__dna_writer.writeInt32Big(lineMargin);
/* unknown2 */
__dna_writer.writeBool(unknown2);
/* unknown3 */
__dna_writer.writeBool(unknown3);
/* unknown4 */
__dna_writer.writeUint32Big(unknown4);
/* fontSize */
__dna_writer.writeUint32Big(fontSize);
/* name */
__dna_writer.writeString(name, -1);
/* textureId */
textureId.write(__dna_writer);
/* textureFormat */
__dna_writer.writeUint32Big(textureFormat);
/* glyphCount */
__dna_writer.writeUint32Big(glyphCount);
/* glyphs */
void FONT<IDType>::_write(athena::io::IStreamWriter& __dna_writer) const {
/* magic */
__dna_writer.writeBytes((atInt8*)"FONT", 4);
/* version */
__dna_writer.writeUint32Big(version);
/* unknown1 */
__dna_writer.writeUint32Big(unknown1);
/* lineHeight */
__dna_writer.writeInt32Big(lineHeight);
/* verticalOffset */
__dna_writer.writeInt32Big(verticalOffset);
/* lineMargin */
__dna_writer.writeInt32Big(lineMargin);
/* unknown2 */
__dna_writer.writeBool(unknown2);
/* unknown3 */
__dna_writer.writeBool(unknown3);
/* unknown4 */
__dna_writer.writeUint32Big(unknown4);
/* fontSize */
__dna_writer.writeUint32Big(fontSize);
/* name */
__dna_writer.writeString(name, -1);
/* textureId */
textureId.write(__dna_writer);
/* textureFormat */
__dna_writer.writeUint32Big(textureFormat);
/* glyphCount */
__dna_writer.writeUint32Big(glyphCount);
/* 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)
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)
if (auto rec = __dna_docout.enterSubRecord(nullptr))
glyph->write(__dna_docout);
/* kerningInfoCount squelched */
/* kerningInfo */
__dna_docout.enumerate("kerningInfo", kerningInfo);
if (auto rec = __dna_docout.enterSubRecord(nullptr))
glyph->write(__dna_docout);
/* kerningInfoCount squelched */
/* kerningInfo */
__dna_docout.enumerate("kerningInfo", kerningInfo);
}
template <>
const char* FONT<UniqueID32>::DNAType()
{
return "FONT<UniqueID32>";
const char* FONT<UniqueID32>::DNAType() {
return "FONT<UniqueID32>";
}
template <>
const char* FONT<UniqueID64>::DNAType()
{
return "FONT<UniqueID64>";
const char* FONT<UniqueID64>::DNAType() {
return "FONT<UniqueID64>";
}
template <class IDType>
void FONT<IDType>::_binarySize(size_t& __isz) const
{
__isz += name.size() + 1;
textureId.binarySize(__isz);
for (const std::unique_ptr<IGlyph>& glyph : glyphs)
glyph->binarySize(__isz);
for (const KerningInfo& k : kerningInfo)
k.binarySize(__isz);
__isz += 46;
void FONT<IDType>::_binarySize(size_t& __isz) const {
__isz += name.size() + 1;
textureId.binarySize(__isz);
for (const std::unique_ptr<IGlyph>& glyph : glyphs)
glyph->binarySize(__isz);
for (const KerningInfo& k : kerningInfo)
k.binarySize(__isz);
__isz += 46;
}
AT_SUBSPECIALIZE_DNA_YAML(FONT<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(FONT<UniqueID64>)
template <class IDType>
bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
FONT<IDType> font;
font.read(rs);
athena::io::ToYAMLStream(font, writer);
return true;
}
return false;
bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen()) {
FONT<IDType> font;
font.read(rs);
athena::io::ToYAMLStream(font, writer);
return true;
}
return false;
}
template bool ExtractFONT<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractFONT<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
font.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i=0 ; i<32-rem ; ++i)
w.writeUByte(0xff);
return true;
bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
font.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 bool WriteFONT<UniqueID32>(const FONT<UniqueID32>& 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 "athena/FileWriter.hpp"
namespace DataSpec::DNAFont
{
struct GlyphRect : BigDNA
{
AT_DECL_DNA_YAML
Value<float> left;
Value<float> top;
Value<float> right;
Value<float> bottom;
namespace DataSpec::DNAFont {
struct GlyphRect : BigDNA {
AT_DECL_DNA_YAML
Value<float> left;
Value<float> top;
Value<float> right;
Value<float> bottom;
};
struct IGlyph : BigDNAVYaml
{
AT_DECL_DNA_YAML
Value<atUint16> m_character;
GlyphRect m_glyphRect;
struct IGlyph : BigDNAVYaml {
AT_DECL_DNA_YAML
Value<atUint16> m_character;
GlyphRect m_glyphRect;
atUint16 character() const { return m_character; }
float left() const { return m_glyphRect.left; }
float top() const { return m_glyphRect.top; }
float right() const { return m_glyphRect.right; }
float bottom() const { return m_glyphRect.bottom; }
GlyphRect rect() const { return m_glyphRect; }
atUint16 character() const { return m_character; }
float left() const { return m_glyphRect.left; }
float top() const { return m_glyphRect.top; }
float right() const { return m_glyphRect.right; }
float bottom() const { return m_glyphRect.bottom; }
GlyphRect rect() const { return m_glyphRect; }
virtual atInt32 layer() const { return 0; }
virtual atInt32 leftPadding() const=0;
virtual atInt32 advance() const =0;
virtual atInt32 rightPadding() const=0;
virtual atInt32 width() const=0;
virtual atInt32 height() const=0;
virtual atInt32 baseline() const=0;
virtual atInt32 kerningIndex() const =0;
virtual atInt32 layer() const { return 0; }
virtual atInt32 leftPadding() const = 0;
virtual atInt32 advance() const = 0;
virtual atInt32 rightPadding() const = 0;
virtual atInt32 width() const = 0;
virtual atInt32 height() const = 0;
virtual atInt32 baseline() const = 0;
virtual atInt32 kerningIndex() const = 0;
};
struct GlyphMP1 : IGlyph
{
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atInt32> m_leftPadding;
Value<atInt32> m_advance;
Value<atInt32> m_rightPadding;
Value<atInt32> m_width;
Value<atInt32> m_height;
Value<atInt32> m_baseline;
Value<atInt32> m_kerningIndex;
struct GlyphMP1 : IGlyph {
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atInt32> m_leftPadding;
Value<atInt32> m_advance;
Value<atInt32> m_rightPadding;
Value<atInt32> m_width;
Value<atInt32> m_height;
Value<atInt32> m_baseline;
Value<atInt32> m_kerningIndex;
atInt32 leftPadding() const { return m_leftPadding; }
atInt32 advance() const { return m_advance; }
atInt32 rightPadding() const { return m_rightPadding; }
atInt32 width() const { return m_width; }
atInt32 height() const { return m_height; }
atInt32 baseline() const { return m_baseline; }
atInt32 kerningIndex() const { return m_kerningIndex; }
atInt32 leftPadding() const { return m_leftPadding; }
atInt32 advance() const { return m_advance; }
atInt32 rightPadding() const { return m_rightPadding; }
atInt32 width() const { return m_width; }
atInt32 height() const { return m_height; }
atInt32 baseline() const { return m_baseline; }
atInt32 kerningIndex() const { return m_kerningIndex; }
};
struct GlyphMP2 : IGlyph
{
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atInt8> m_layer;
Value<atInt8> m_leftPadding;
Value<atInt8> m_advance;
Value<atInt8> m_rightPadding;
Value<atInt8> m_width;
Value<atInt8> m_height;
Value<atInt8> m_baseline;
Value<atInt16> m_kerningIndex;
struct GlyphMP2 : IGlyph {
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atInt8> m_layer;
Value<atInt8> m_leftPadding;
Value<atInt8> m_advance;
Value<atInt8> m_rightPadding;
Value<atInt8> m_width;
Value<atInt8> m_height;
Value<atInt8> m_baseline;
Value<atInt16> m_kerningIndex;
atInt32 layer() const { return m_layer; }
atInt32 leftPadding() const { return m_leftPadding; }
atInt32 advance() const { return m_advance; }
atInt32 rightPadding() const { return m_rightPadding; }
atInt32 width() const { return m_width; }
atInt32 height() const { return m_height; }
atInt32 baseline() const { return m_baseline; }
atInt32 kerningIndex() const { return m_kerningIndex; }
atInt32 layer() const { return m_layer; }
atInt32 leftPadding() const { return m_leftPadding; }
atInt32 advance() const { return m_advance; }
atInt32 rightPadding() const { return m_rightPadding; }
atInt32 width() const { return m_width; }
atInt32 height() const { return m_height; }
atInt32 baseline() const { return m_baseline; }
atInt32 kerningIndex() const { return m_kerningIndex; }
};
struct KerningInfo : BigDNA
{
AT_DECL_DNA_YAML
Value<atUint16> thisChar;
Value<atUint16> nextChar;
Value<atInt32> adjust;
struct KerningInfo : BigDNA {
AT_DECL_DNA_YAML
Value<atUint16> thisChar;
Value<atUint16> nextChar;
Value<atInt32> adjust;
};
template <class IDType>
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FONT : BigDNA
{
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
Value<atUint32> version;
Value<atUint32> unknown1;
Value<atInt32> lineHeight;
Value<atInt32> verticalOffset;
Value<atInt32> lineMargin;
Value<bool> unknown2;
Value<bool> unknown3;
Value<atUint32> unknown4;
Value<atUint32> fontSize; // in points
String<-1> name;
Value<IDType> textureId;
Value<atUint32> textureFormat;
Value<atUint32> glyphCount;
std::vector<std::unique_ptr<IGlyph>> glyphs;
Value<atUint32> kerningInfoCount;
Vector<KerningInfo, AT_DNA_COUNT(kerningInfoCount)> kerningInfo;
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FONT : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
Value<atUint32> version;
Value<atUint32> unknown1;
Value<atInt32> lineHeight;
Value<atInt32> verticalOffset;
Value<atInt32> lineMargin;
Value<bool> unknown2;
Value<bool> unknown3;
Value<atUint32> unknown4;
Value<atUint32> fontSize; // in points
String<-1> name;
Value<IDType> textureId;
Value<atUint32> textureFormat;
Value<atUint32> glyphCount;
std::vector<std::unique_ptr<IGlyph>> glyphs;
Value<atUint32> kerningInfoCount;
Vector<KerningInfo, AT_DNA_COUNT(kerningInfoCount)> kerningInfo;
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
g_curSpec->flattenDependencies(textureId, pathsOut);
}
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
g_curSpec->flattenDependencies(textureId, pathsOut);
}
};
template <class IDType>
@ -122,5 +114,4 @@ bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAFont

View File

@ -4,82 +4,75 @@
#include "FSM2.hpp"
namespace DataSpec::DNAFSM2
{
namespace DataSpec::DNAFSM2 {
logvisor::Module LogDNAFSM2("urde::DNAFSM2");
template <class IDType>
template <class Op>
void FSM2<IDType>::Enumerate(typename Op::StreamT& s)
{
Do<Op>({"header"}, header, s);
if (header.magic != SBIG('FSM2'))
{
LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 magic '%.4s' expected 'FSM2'", header.magic.toString().c_str());
return;
}
void FSM2<IDType>::Enumerate(typename Op::StreamT& s) {
Do<Op>({"header"}, header, s);
if (header.magic != SBIG('FSM2')) {
LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 magic '%.4s' expected 'FSM2'", header.magic.toString().c_str());
return;
}
if (header.version == 1)
{
if (!detail)
detail.reset(new FSMV1);
Do<Op>({"detail"}, static_cast<FSMV1&>(*detail), s);
}
else if (header.version == 2)
{
if (!detail)
detail.reset(new FSMV2);
Do<Op>({"detail"}, static_cast<FSMV2&>(*detail), s);
}
else
{
LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 version '%i'", header.version);
return;
}
if (header.version == 1) {
if (!detail)
detail.reset(new FSMV1);
Do<Op>({"detail"}, static_cast<FSMV1&>(*detail), s);
} else if (header.version == 2) {
if (!detail)
detail.reset(new FSMV2);
Do<Op>({"detail"}, static_cast<FSMV2&>(*detail), s);
} else {
LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 version '%i'", header.version);
return;
}
}
AT_SPECIALIZE_DNA(FSM2<UniqueID32>)
AT_SPECIALIZE_DNA(FSM2<UniqueID64>)
template <>
const char* FSM2<UniqueID32>::DNAType() { return "urde::FSM2<UniqueID32>"; }
const char* FSM2<UniqueID32>::DNAType() {
return "urde::FSM2<UniqueID32>";
}
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<UniqueID64>;
template <class IDType>
bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
FSM2<IDType> fsm2;
fsm2.read(rs);
athena::io::ToYAMLStream(fsm2, writer);
return true;
}
return false;
bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen()) {
FSM2<IDType> fsm2;
fsm2.read(rs);
athena::io::ToYAMLStream(fsm2, writer);
return true;
}
return false;
}
template bool ExtractFSM2<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractFSM2<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
fsm2.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i=0 ; i<32-rem ; ++i)
w.writeUByte(0xff);
return true;
bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
fsm2.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 bool WriteFSM2<UniqueID32>(const FSM2<UniqueID32>& 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 "athena/FileWriter.hpp"
namespace DataSpec::DNAFSM2
{
struct IFSM : BigDNAVYaml
{
Delete _d;
namespace DataSpec::DNAFSM2 {
struct IFSM : BigDNAVYaml {
Delete _d;
};
template <class IDType>
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : BigDNA
{
struct Header : BigDNA
{
AT_DECL_DNA_YAML
DNAFourCC magic = FOURCC('FSM2');
Value<atUint32> version;
} header;
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : BigDNA {
struct Header : BigDNA {
AT_DECL_DNA_YAML
DNAFourCC magic = FOURCC('FSM2');
Value<atUint32> version;
} header;
struct CommonStruct : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown;
struct CommonStruct : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
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
{
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 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 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 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;
struct Unknown2 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknownCount;
Vector<CommonStruct, AT_DNA_COUNT(unknownCount)> unknown;
};
std::unique_ptr<IFSM> detail;
AT_DECL_EXPLICIT_DNA_YAML
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 {
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>
@ -151,4 +136,4 @@ bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAFSM2

View File

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

View File

@ -9,487 +9,419 @@
#include "zeus/CAABox.hpp"
#include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMAPA
{
namespace DataSpec::DNAMAPA {
static logvisor::Module Log("DNAMAPA");
template <>
void MAPA::Enumerate<BigDNA::Read>(typename Read::StreamT& __dna_reader)
{
/* magic */
magic = __dna_reader.readUint32Big();
if (magic != 0xDEADD00D)
{
LogDNACommon.report(logvisor::Error, "invalid MAPA magic");
return;
}
/* version */
version = __dna_reader.readUint32Big();
if (version == 2)
header.reset(new HeaderMP1);
else if (version == 3)
header.reset(new HeaderMP2);
else if (version == 5)
header.reset(new HeaderMP3);
void MAPA::Enumerate<BigDNA::Read>(typename Read::StreamT& __dna_reader) {
/* magic */
magic = __dna_reader.readUint32Big();
if (magic != 0xDEADD00D) {
LogDNACommon.report(logvisor::Error, "invalid MAPA magic");
return;
}
/* version */
version = __dna_reader.readUint32Big();
if (version == 2)
header.reset(new HeaderMP1);
else if (version == 3)
header.reset(new HeaderMP2);
else if (version == 5)
header.reset(new HeaderMP3);
else {
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
{
LogDNACommon.report(logvisor::Error, "invalid MAPA version");
return;
}
mo.reset(new MappableObjectMP3);
mo->read(__dna_reader);
mappableObjects.push_back(std::move(mo));
}
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
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());
/* vertices */
__dna_reader.enumerateBig(vertices, header->vertexCount());
/* surfaceHeaders */
__dna_reader.enumerate(surfaceHeaders, header->surfaceCount());
/* surfaces */
__dna_reader.enumerate(surfaces, header->surfaceCount());
}
template <>
void MAPA::Enumerate<BigDNA::Write>(typename Write::StreamT& __dna_writer)
{
/* magic */
__dna_writer.writeUint32Big(magic);
/* version */
__dna_writer.writeUint32Big(version);
header->write(__dna_writer);
void MAPA::Enumerate<BigDNA::Write>(typename Write::StreamT& __dna_writer) {
/* magic */
__dna_writer.writeUint32Big(magic);
/* version */
__dna_writer.writeUint32Big(version);
header->write(__dna_writer);
/* mappableObjects */
for (const std::unique_ptr<IMappableObject>& mo : mappableObjects)
mo->write(__dna_writer);
/* vertices */
__dna_writer.enumerateBig(vertices);
/* surfaceHeaders */
__dna_writer.enumerate(surfaceHeaders);
/* surfaces */
__dna_writer.enumerate(surfaces);
/* mappableObjects */
for (const std::unique_ptr<IMappableObject>& mo : mappableObjects)
mo->write(__dna_writer);
/* vertices */
__dna_writer.enumerateBig(vertices);
/* surfaceHeaders */
__dna_writer.enumerate(surfaceHeaders);
/* surfaces */
__dna_writer.enumerate(surfaces);
}
template <>
void MAPA::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
{
header->binarySize(s);
void MAPA::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
header->binarySize(s);
for (const std::unique_ptr<IMappableObject>& mo : mappableObjects)
mo->binarySize(s);
for (const std::unique_ptr<IMappableObject>& mo : mappableObjects)
mo->binarySize(s);
s += vertices.size() * 12;
for (const SurfaceHeader& sh : surfaceHeaders)
sh.binarySize(s);
for (const Surface& su : surfaces)
su.binarySize(s);
s += 8;
s += vertices.size() * 12;
for (const SurfaceHeader& sh : surfaceHeaders)
sh.binarySize(s);
for (const Surface& su : surfaces)
su.binarySize(s);
s += 8;
}
static const char* RetroMapVisModes[] =
{
"ALWAYS",
"MAPSTATIONORVISIT",
"VISIT",
"NEVER"
};
static const char* RetroMapVisModes[] = {"ALWAYS", "MAPSTATIONORVISIT", "VISIT", "NEVER"};
static const char* RetroMapObjVisModes[] =
{
"ALWAYS",
"MAPSTATIONORVISIT",
"VISIT",
"NEVER",
"MAPSTATIONORVISIT2"
};
static const char* RetroMapObjVisModes[] = {"ALWAYS", "MAPSTATIONORVISIT", "VISIT", "NEVER", "MAPSTATIONORVISIT2"};
template <typename PAKRouter>
bool ReadMAPAToBlender(hecl::blender::Connection& conn,
const MAPA& mapa,
const hecl::ProjectPath& outPath,
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();
bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const hecl::ProjectPath& outPath,
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;
}
template bool ReadMAPAToBlender<PAKRouter<DNAMP1::PAKBridge>>
(hecl::blender::Connection& conn,
const MAPA& mapa,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP1::PAKBridge>& pakRouter,
const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
bool force);
template bool ReadMAPAToBlender<PAKRouter<DNAMP1::PAKBridge>>(hecl::blender::Connection& conn, const MAPA& mapa,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP1::PAKBridge>& pakRouter,
const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
bool force);
template bool ReadMAPAToBlender<PAKRouter<DNAMP2::PAKBridge>>
(hecl::blender::Connection& conn,
const MAPA& mapa,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP2::PAKBridge>& pakRouter,
const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
bool force);
template bool ReadMAPAToBlender<PAKRouter<DNAMP2::PAKBridge>>(hecl::blender::Connection& conn, const MAPA& mapa,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP2::PAKBridge>& pakRouter,
const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
bool force);
template bool ReadMAPAToBlender<PAKRouter<DNAMP3::PAKBridge>>
(hecl::blender::Connection& conn,
const MAPA& mapa,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP3::PAKBridge>& pakRouter,
const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry,
bool force);
template bool ReadMAPAToBlender<PAKRouter<DNAMP3::PAKBridge>>(hecl::blender::Connection& conn, const MAPA& mapa,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP3::PAKBridge>& pakRouter,
const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry,
bool force);
template <typename MAPAType>
bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out)
{
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);
return false;
bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out) {
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);
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;
mapa.magic = 0xDEADD00D;
mapa.version = MAPAType::Version();
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);
}
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);
}
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;
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<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);
}
} // namespace DataSpec::DNAMAPA

View File

@ -3,190 +3,169 @@
#include "DNACommon.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 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;
struct HeaderMP1 : IMAPAHeader {
AT_DECL_DNA
AT_DECL_DNAV
Value<atUint32> unknown1 = 0;
Value<atUint32> mapVisMode = 0;
Value<atVec3f> boundingBox[2] = {};
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 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
{
AT_DECL_DNA
AT_DECL_DNAV
Value<atUint32> unknown1 = 0;
Value<atUint32> mapVisMode = 0;
Value<atVec3f> boundingBox[2] = {};
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 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;
};
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; }
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;
};
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 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;
Vector<Surface, AT_DNA_COUNT(header->surfaceCount())> surfaces;
};
template <typename PAKRouter>
bool ReadMAPAToBlender(hecl::blender::Connection& conn,
const MAPA& mapa,
const hecl::ProjectPath& outPath,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
bool force);
bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const hecl::ProjectPath& outPath,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force);
template <typename MAPAType>
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 "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMAPU
{
namespace DataSpec::DNAMAPU {
template <typename PAKRouter>
bool ReadMAPUToBlender(hecl::blender::Connection& conn,
const MAPU& mapu,
const hecl::ProjectPath& outPath,
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();
bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const hecl::ProjectPath& outPath,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force) {
if (!force && outPath.isFile())
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);
if (!conn.createBlend(outPath, hecl::blender::BlendType::MapUniverse))
return false;
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
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);
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";
bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPath& out)
{
MAPU mapu;
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";
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);
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]);
}
}
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;
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;
}
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"
namespace DataSpec::DNAMAPU
{
struct MAPU : BigDNA
{
namespace DataSpec::DNAMAPU {
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
Value<uint32_t> magic;
Value<uint32_t> version;
UniqueID32 hexMapa;
Value<uint32_t> worldCount;
struct Transform : BigDNA
{
AT_DECL_DNA
Value<atVec4f> xf[3];
};
struct World : BigDNA
{
AT_DECL_DNA
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;
Value<atVec4f> xf[3];
};
struct World : BigDNA {
AT_DECL_DNA
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>
bool ReadMAPUToBlender(hecl::blender::Connection& conn,
const MAPU& mapu,
const hecl::ProjectPath& outPath,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
bool force);
}
bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, 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 "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMLVL
{
namespace DataSpec::DNAMLVL {
template <class PAKRouter, typename MLVL>
bool ReadMLVLToBlender(hecl::blender::Connection& conn,
const MLVL& mlvl,
const hecl::ProjectPath& outPath,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
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();
bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, 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;
}
template bool ReadMLVLToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::MLVL>
(hecl::blender::Connection& conn,
const DNAMP1::MLVL& mlvl,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP1::PAKBridge>& pakRouter,
const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
template bool ReadMLVLToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::MLVL>(
hecl::blender::Connection& conn, const DNAMP1::MLVL& mlvl, const hecl::ProjectPath& outPath,
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>
(hecl::blender::Connection& conn,
const DNAMP2::MLVL& mlvl,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP2::PAKBridge>& pakRouter,
const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
template bool ReadMLVLToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::MLVL>(
hecl::blender::Connection& conn, const DNAMP2::MLVL& mlvl, const hecl::ProjectPath& outPath,
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>
(hecl::blender::Connection& conn,
const DNAMP3::MLVL& mlvl,
const hecl::ProjectPath& outPath,
PAKRouter<DNAMP3::PAKBridge>& pakRouter,
const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry,
bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
template bool ReadMLVLToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::MLVL>(
hecl::blender::Connection& conn, const DNAMP3::MLVL& mlvl, const hecl::ProjectPath& outPath,
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 "zeus/CVector3f.hpp"
namespace DataSpec::DNAMLVL
{
namespace DataSpec::DNAMLVL {
template <class PAKRouter, typename MLVL>
bool ReadMLVLToBlender(hecl::blender::Connection& conn,
const MLVL& mlvl,
const hecl::ProjectPath& outPath,
PAKRouter& pakRouter,
const typename PAKRouter::EntryType& entry,
bool force,
bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
}

View File

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

View File

@ -2,15 +2,12 @@
#include "DNACommon.hpp"
namespace DataSpec
{
namespace DataSpec {
struct OBBTreeBuilder
{
using ColMesh = hecl::blender::ColMesh;
template <typename Node>
static std::unique_ptr<Node> buildCol(const ColMesh& mesh);
struct OBBTreeBuilder {
using ColMesh = hecl::blender::ColMesh;
template <typename Node>
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 "zeus/CMatrix4f.hpp"
namespace DataSpec
{
namespace DataSpec {
/** PAK entry stream reader */
class PAKEntryReadStream : public athena::io::IStreamReader
{
std::unique_ptr<atUint8[]> m_buf;
atUint64 m_sz;
atUint64 m_pos;
class PAKEntryReadStream : public athena::io::IStreamReader {
std::unique_ptr<atUint8[]> m_buf;
atUint64 m_sz;
atUint64 m_pos;
public:
PAKEntryReadStream() {}
operator bool() const {return m_buf.operator bool();}
PAKEntryReadStream(const PAKEntryReadStream& other) = delete;
PAKEntryReadStream(PAKEntryReadStream&& other) = default;
PAKEntryReadStream& operator=(const PAKEntryReadStream& other) = delete;
PAKEntryReadStream& operator=(PAKEntryReadStream&& other) = default;
PAKEntryReadStream(std::unique_ptr<atUint8[]>&& buf, atUint64 sz, atUint64 pos)
: m_buf(std::move(buf)), m_sz(sz), m_pos(pos)
{
if (m_pos >= m_sz)
LogDNACommon.report(logvisor::Fatal, "PAK stream cursor overrun");
}
void seek(atInt64 pos, athena::SeekOrigin origin)
{
if (origin == athena::Begin)
m_pos = pos;
else if (origin == athena::Current)
m_pos += pos;
else if (origin == athena::End)
m_pos = m_sz + pos;
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;}
const atUint8* data() const {return m_buf.get();}
atUint64 readUBytesToBuf(void* buf, atUint64 len)
{
atUint64 bufEnd = m_pos + len;
if (bufEnd > m_sz)
len -= bufEnd - m_sz;
memmove(buf, m_buf.get() + m_pos, len);
m_pos += len;
return len;
}
PAKEntryReadStream() {}
operator bool() const { return m_buf.operator bool(); }
PAKEntryReadStream(const PAKEntryReadStream& other) = delete;
PAKEntryReadStream(PAKEntryReadStream&& other) = default;
PAKEntryReadStream& operator=(const PAKEntryReadStream& other) = delete;
PAKEntryReadStream& operator=(PAKEntryReadStream&& other) = default;
PAKEntryReadStream(std::unique_ptr<atUint8[]>&& buf, atUint64 sz, atUint64 pos)
: m_buf(std::move(buf)), m_sz(sz), m_pos(pos) {
if (m_pos >= m_sz)
LogDNACommon.report(logvisor::Fatal, "PAK stream cursor overrun");
}
void seek(atInt64 pos, athena::SeekOrigin origin) {
if (origin == athena::Begin)
m_pos = pos;
else if (origin == athena::Current)
m_pos += pos;
else if (origin == athena::End)
m_pos = m_sz + pos;
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; }
const atUint8* data() const { return m_buf.get(); }
atUint64 readUBytesToBuf(void* buf, atUint64 len) {
atUint64 bufEnd = m_pos + len;
if (bufEnd > m_sz)
len -= bufEnd - m_sz;
memmove(buf, m_buf.get() + m_pos, len);
m_pos += len;
return len;
}
};
struct UniqueResult
{
enum class Type
{
NotFound,
Pak,
Level,
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) {}
struct UniqueResult {
enum class Type { NotFound, Pak, Level, 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>
void checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry);
template <class PAKBRIDGE>
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>
@ -79,161 +67,154 @@ class PAKRouter;
/** Resource extractor type */
template <class PAKBRIDGE>
struct ResExtractor
{
std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func_a;
std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&,
const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&,
std::function<void(const hecl::SystemChar*)>)> func_b;
std::array<const hecl::SystemChar*, 6> fileExts = {};
unsigned weight = 0;
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&,
typename PAKBRIDGE::PAKType::Entry&)> func_name;
struct ResExtractor {
std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func_a;
std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&,
const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&,
std::function<void(const hecl::SystemChar*)>)>
func_b;
std::array<const hecl::SystemChar*, 6> fileExts = {};
unsigned weight = 0;
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&, typename PAKBRIDGE::PAKType::Entry&)>
func_name;
ResExtractor() = default;
ResExtractor() = default;
ResExtractor(std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func,
std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin=0,
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&,
typename PAKBRIDGE::PAKType::Entry&)> nfunc={})
: func_a(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {}
ResExtractor(std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func,
std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin = 0,
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&,
typename PAKBRIDGE::PAKType::Entry&)>
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>&,
const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&,
std::function<void(const hecl::SystemChar*)>)> func,
std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin=0,
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&,
typename PAKBRIDGE::PAKType::Entry&)> nfunc={})
: func_b(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>&,
const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&,
std::function<void(const hecl::SystemChar*)>)>
func,
std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin = 0,
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&,
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
{
hecl::ProjectPath::Type tp = path.getPathType();
if (tp == hecl::ProjectPath::Type::None)
return false;
else if (tp == hecl::ProjectPath::Type::Glob)
{
for (int i=0 ; i<6 ; ++i)
{
if (!fileExts[i])
break;
hecl::ProjectPath withExt = path.getWithExtension(fileExts[i], true);
if (withExt.isNone())
return false;
}
}
return true;
bool IsFullyExtracted(const hecl::ProjectPath& path) const {
hecl::ProjectPath::Type tp = path.getPathType();
if (tp == hecl::ProjectPath::Type::None)
return false;
else if (tp == hecl::ProjectPath::Type::Glob) {
for (int i = 0; i < 6; ++i) {
if (!fileExts[i])
break;
hecl::ProjectPath withExt = path.getWithExtension(fileExts[i], true);
if (withExt.isNone())
return false;
}
}
return true;
}
};
/** Level hierarchy representation */
template <class IDType>
struct Level
{
struct Level {
hecl::SystemString name;
struct Area {
hecl::SystemString name;
struct Area
{
hecl::SystemString name;
struct Layer
{
hecl::SystemString name;
bool active;
std::unordered_set<IDType> resources;
};
std::vector<Layer> layers;
std::unordered_set<IDType> resources;
struct Layer {
hecl::SystemString name;
bool active;
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) */
template <class BRIDGETYPE>
class PAKRouter : public PAKRouterBase
{
class PAKRouter : public PAKRouterBase {
public:
using PAKType = typename BRIDGETYPE::PAKType;
using IDType = typename PAKType::IDType;
using EntryType = typename PAKType::Entry;
using PAKType = typename BRIDGETYPE::PAKType;
using IDType = typename PAKType::IDType;
using EntryType = typename PAKType::Entry;
private:
const std::vector<BRIDGETYPE>* m_bridges = nullptr;
std::vector<std::pair<hecl::ProjectPath,hecl::ProjectPath>> m_bridgePaths;
ThreadLocalPtr<void> m_curBridgeIdx;
const hecl::ProjectPath& m_gameWorking;
const hecl::ProjectPath& m_gameCooked;
hecl::ProjectPath m_sharedWorking;
hecl::ProjectPath m_sharedCooked;
ThreadLocalPtr<const PAKType> m_pak;
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_sharedEntries;
std::unordered_map<IDType, hecl::ProjectPath> m_overrideEntries;
CharacterAssociations<IDType> m_charAssoc;
std::unordered_map<IDType, zeus::CMatrix4f> m_mapaTransforms;
const std::vector<BRIDGETYPE>* m_bridges = nullptr;
std::vector<std::pair<hecl::ProjectPath, hecl::ProjectPath>> m_bridgePaths;
ThreadLocalPtr<void> m_curBridgeIdx;
const hecl::ProjectPath& m_gameWorking;
const hecl::ProjectPath& m_gameCooked;
hecl::ProjectPath m_sharedWorking;
hecl::ProjectPath m_sharedCooked;
ThreadLocalPtr<const PAKType> m_pak;
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_sharedEntries;
std::unordered_map<IDType, hecl::ProjectPath> m_overrideEntries;
CharacterAssociations<IDType> m_charAssoc;
std::unordered_map<IDType, zeus::CMatrix4f> m_mapaTransforms;
hecl::ProjectPath getCharacterWorking(const EntryType* entry) const;
hecl::ProjectPath getCharacterWorking(const EntryType* entry) const;
public:
PAKRouter(const SpecBase& dataSpec, const hecl::ProjectPath& working, const hecl::ProjectPath& cooked)
: PAKRouterBase(dataSpec),
m_gameWorking(working), m_gameCooked(cooked),
m_sharedWorking(working, "Shared"), m_sharedCooked(cooked, "Shared") {}
PAKRouter(const SpecBase& dataSpec, const hecl::ProjectPath& working, const hecl::ProjectPath& cooked)
: PAKRouterBase(dataSpec)
, m_gameWorking(working)
, 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;
hecl::ProjectPath getWorking(const EntryType* entry,
const ResExtractor<BRIDGETYPE>& extractor) const;
hecl::ProjectPath getWorking(const EntryType* entry) const;
hecl::ProjectPath getWorking(const IDType& id, bool silenceWarnings=false) const;
hecl::ProjectPath getCooked(const EntryType* entry) const;
hecl::ProjectPath getCooked(const IDType& id, bool silenceWarnings=false) const;
bool isShared() const
{
const PAKType* pak = m_pak.get();
return pak ? !pak->m_noShare : false;
}
using PAKRouterBase::getWorking;
hecl::ProjectPath getWorking(const EntryType* entry, const ResExtractor<BRIDGETYPE>& extractor) const;
hecl::ProjectPath getWorking(const EntryType* entry) const;
hecl::ProjectPath getWorking(const IDType& id, bool silenceWarnings = false) const;
hecl::ProjectPath getCooked(const EntryType* entry) const;
hecl::ProjectPath getCooked(const IDType& id, bool silenceWarnings = false) const;
bool isShared() const {
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 IDType& 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;
bool extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*, float)> progress);
bool extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*, float)> progress);
const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry,
const nod::Node** nodeOut=nullptr,
bool silenceWarnings=false,
bool currentPAK=false) const;
const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry, const nod::Node** nodeOut = nullptr,
bool silenceWarnings = false, bool currentPAK = false) const;
template <typename DNA>
bool lookupAndReadDNA(const IDType& id, DNA& out, bool silenceWarnings=false)
{
const nod::Node* node;
const EntryType* entry = lookupEntry(id, &node, silenceWarnings);
if (!entry)
return false;
PAKEntryReadStream rs = entry->beginReadStream(*node);
out.read(rs);
return true;
}
template <typename DNA>
bool lookupAndReadDNA(const IDType& id, DNA& out, bool silenceWarnings = false) {
const nod::Node* node;
const EntryType* entry = lookupEntry(id, &node, silenceWarnings);
if (!entry)
return false;
PAKEntryReadStream rs = entry->beginReadStream(*node);
out.read(rs);
return true;
}
const typename CharacterAssociations<IDType>::RigPair* lookupCMDLRigPair(const IDType& id) const;
const typename CharacterAssociations<IDType>::MultimapIteratorPair lookupCharacterAttachmentRigs(const IDType& id) const;
const zeus::CMatrix4f* lookupMAPATransform(const IDType& mapaId) const;
const typename CharacterAssociations<IDType>::RigPair* lookupCMDLRigPair(const IDType& id) const;
const typename CharacterAssociations<IDType>::MultimapIteratorPair
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, bool& activeOut) const;
hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx) const;
hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const;
hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx) 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, 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 "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
struct GPSM : BigDNA
{
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
VectorElementFactory x0_PSIV;
ModVectorElementFactory x4_PSVM;
VectorElementFactory x8_PSOV;
IntElementFactory xc_PSLT;
IntElementFactory x10_PSWT;
RealElementFactory x14_PSTS;
VectorElementFactory x18_POFS;
IntElementFactory x1c_SEED;
RealElementFactory x20_LENG;
RealElementFactory x24_WIDT;
IntElementFactory x28_MAXP;
RealElementFactory x2c_GRTE;
ColorElementFactory x30_COLR;
IntElementFactory x34_LTME;
VectorElementFactory x38_ILOC;
VectorElementFactory x3c_IVEC;
EmitterElementFactory x40_EMTR;
union
{
struct
{
bool x44_28_SORT : 1; bool x44_30_MBLR : 1; bool x44_24_LINE : 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 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;
};
uint16_t dummy1 = 0;
struct GPSM : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
VectorElementFactory x0_PSIV;
ModVectorElementFactory x4_PSVM;
VectorElementFactory x8_PSOV;
IntElementFactory xc_PSLT;
IntElementFactory x10_PSWT;
RealElementFactory x14_PSTS;
VectorElementFactory x18_POFS;
IntElementFactory x1c_SEED;
RealElementFactory x20_LENG;
RealElementFactory x24_WIDT;
IntElementFactory x28_MAXP;
RealElementFactory x2c_GRTE;
ColorElementFactory x30_COLR;
IntElementFactory x34_LTME;
VectorElementFactory x38_ILOC;
VectorElementFactory x3c_IVEC;
EmitterElementFactory x40_EMTR;
union {
struct {
bool x44_28_SORT : 1;
bool x44_30_MBLR : 1;
bool x44_24_LINE : 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 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;
RealElementFactory x4c_SIZE;
RealElementFactory x50_ROTA;
UVElementFactory<IDType> x54_TEXR;
UVElementFactory<IDType> x58_TIND;
ChildResourceFactory<IDType> x5c_PMDL;
VectorElementFactory x6c_PMOP;
VectorElementFactory x70_PMRT;
VectorElementFactory x74_PMSC;
ColorElementFactory x78_PMCL;
ModVectorElementFactory x7c_VEL1;
ModVectorElementFactory x80_VEL2;
ModVectorElementFactory x84_VEL3;
ModVectorElementFactory x88_VEL4;
ChildResourceFactory<IDType> x8c_ICTS;
IntElementFactory x9c_NCSY;
IntElementFactory xa0_CSSD;
ChildResourceFactory<IDType> xa4_IDTS;
IntElementFactory xb4_NDSY;
ChildResourceFactory<IDType> xb8_IITS;
IntElementFactory xc8_PISY;
IntElementFactory xcc_SISY;
SpawnSystemKeyframeData<IDType> xd0_KSSM;
ChildResourceFactory<IDType> xd4_SSWH;
IntElementFactory xe4_SSSD;
VectorElementFactory xe8_SSPO;
IntElementFactory xf8_SESD;
VectorElementFactory xfc_SEPO;
ChildResourceFactory<IDType> xec_PMLC;
IntElementFactory x100_LTYP;
ColorElementFactory x104_LCLR;
RealElementFactory x108_LINT;
VectorElementFactory x10c_LOFF;
VectorElementFactory x110_LDIR;
IntElementFactory x114_LFOT;
RealElementFactory x118_LFOR;
RealElementFactory x11c_LSLA;
uint16_t dummy1 = 0;
};
IntElementFactory x48_MBSP;
RealElementFactory x4c_SIZE;
RealElementFactory x50_ROTA;
UVElementFactory<IDType> x54_TEXR;
UVElementFactory<IDType> x58_TIND;
ChildResourceFactory<IDType> x5c_PMDL;
VectorElementFactory x6c_PMOP;
VectorElementFactory x70_PMRT;
VectorElementFactory x74_PMSC;
ColorElementFactory x78_PMCL;
ModVectorElementFactory x7c_VEL1;
ModVectorElementFactory x80_VEL2;
ModVectorElementFactory x84_VEL3;
ModVectorElementFactory x88_VEL4;
ChildResourceFactory<IDType> x8c_ICTS;
IntElementFactory x9c_NCSY;
IntElementFactory xa0_CSSD;
ChildResourceFactory<IDType> xa4_IDTS;
IntElementFactory xb4_NDSY;
ChildResourceFactory<IDType> xb8_IITS;
IntElementFactory xc8_PISY;
IntElementFactory xcc_SISY;
SpawnSystemKeyframeData<IDType> xd0_KSSM;
ChildResourceFactory<IDType> xd4_SSWH;
IntElementFactory xe4_SSSD;
VectorElementFactory xe8_SSPO;
IntElementFactory xf8_SESD;
VectorElementFactory xfc_SEPO;
ChildResourceFactory<IDType> xec_PMLC;
IntElementFactory x100_LTYP;
ColorElementFactory x104_LCLR;
RealElementFactory x108_LINT;
VectorElementFactory x10c_LOFF;
VectorElementFactory x110_LDIR;
IntElementFactory x114_LFOT;
RealElementFactory x118_LFOR;
RealElementFactory x11c_LSLA;
/* 0-00 additions */
ChildResourceFactory<IDType> xd8_SELC;
union
{
struct
{
bool x30_30_ORNT : 1;
bool x30_31_RSOP : 1;
};
uint16_t dummy2 = 0;
/* 0-00 additions */
ChildResourceFactory<IDType> xd8_SELC;
union {
struct {
bool x30_30_ORNT : 1;
bool x30_31_RSOP : 1;
};
RealElementFactory x10c_ADV1;
RealElementFactory x110_ADV2;
RealElementFactory x114_ADV3;
RealElementFactory x118_ADV4;
RealElementFactory x11c_ADV5;
RealElementFactory x120_ADV6;
RealElementFactory x124_ADV7;
RealElementFactory x128_ADV8;
uint16_t dummy2 = 0;
};
RealElementFactory x10c_ADV1;
RealElementFactory x110_ADV2;
RealElementFactory x114_ADV3;
RealElementFactory x118_ADV4;
RealElementFactory x11c_ADV5;
RealElementFactory x120_ADV6;
RealElementFactory x124_ADV7;
RealElementFactory x128_ADV8;
GPSM()
{
x45_25_PMOO = true;
}
GPSM() { x45_25_PMOO = true; }
void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
};
template <class IDType>
@ -112,5 +115,4 @@ bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
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 "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAANIM
{
namespace DataSpec::DNAANIM {
template <class CINFType>
RigInverter<CINFType>::Bone::Bone(const CINFType& cinf, const typename CINFType::Bone& origBone)
: m_origBone(origBone)
{
atUint32 parentIdx = cinf.getInternalBoneIdxFromId(origBone.parentId);
zeus::CVector3f boneOrigin(origBone.origin);
zeus::CVector3f naturalTail = boneOrigin + zeus::CVector3f{0.f, 0.5f, 0.f};
if (parentIdx != -1)
{
const typename CINFType::Bone& pBone = cinf.bones[parentIdx];
m_parentDelta = boneOrigin - zeus::CVector3f(pBone.origin);
: m_origBone(origBone) {
atUint32 parentIdx = cinf.getInternalBoneIdxFromId(origBone.parentId);
zeus::CVector3f boneOrigin(origBone.origin);
zeus::CVector3f naturalTail = boneOrigin + zeus::CVector3f{0.f, 0.5f, 0.f};
if (parentIdx != -1) {
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;
}
}
size_t actualChildren = 0;
for (atUint32 chId : origBone.linked)
{
if (chId == origBone.parentId)
continue;
atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId);
if (chIdx != -1)
++actualChildren;
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;
}
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;
}
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>
RigInverter<CINFType>::RigInverter(const CINFType& cinf)
: m_cinf(cinf)
{
m_bones.reserve(cinf.bones.size());
for (const typename CINFType::Bone& b : cinf.bones)
m_bones.emplace_back(cinf, b);
RigInverter<CINFType>::RigInverter(const CINFType& cinf) : m_cinf(cinf) {
m_bones.reserve(cinf.bones.size());
for (const typename CINFType::Bone& b : cinf.bones)
m_bones.emplace_back(cinf, b);
}
template <class CINFType>
RigInverter<CINFType>::RigInverter(const CINFType& cinf,
const std::unordered_map<std::string,
hecl::blender::Matrix3f>& matrices)
: m_cinf(cinf)
{
m_bones.reserve(cinf.bones.size());
for (const typename CINFType::Bone& b : cinf.bones)
{
m_bones.emplace_back(cinf, b);
const std::unordered_map<std::string, hecl::blender::Matrix3f>& matrices)
: m_cinf(cinf) {
m_bones.reserve(cinf.bones.size());
for (const typename CINFType::Bone& b : cinf.bones) {
m_bones.emplace_back(cinf, b);
const std::string* name = cinf.getBoneNameFromId(b.id);
if (name)
{
auto search = matrices.find(*name);
if (search != matrices.cend())
{
zeus::CMatrix3f boneMtx(search->second[0],
search->second[1],
search->second[2]);
m_bones.back().m_inverter = boneMtx.transposed();
m_bones.back().m_restorer = boneMtx;
}
}
const std::string* name = cinf.getBoneNameFromId(b.id);
if (name) {
auto search = matrices.find(*name);
if (search != matrices.cend()) {
zeus::CMatrix3f boneMtx(search->second[0], search->second[1], search->second[2]);
m_bones.back().m_inverter = boneMtx.transposed();
m_bones.back().m_restorer = boneMtx;
}
}
}
}
template <class CINFType>
zeus::CQuaternion
RigInverter<CINFType>::invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const
{
for (const Bone& b : m_bones)
if (b.m_origBone.id == boneId)
return b.m_restorer * zeus::CMatrix3f(origRot) * b.m_inverter;
return origRot;
}
template <class CINFType>
zeus::CVector3f
RigInverter<CINFType>::invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const
{
for (const Bone& b : m_bones)
if (b.m_origBone.id == boneId)
{
zeus::CVector3f localPos = origPos;
if (subDelta)
localPos -= b.m_parentDelta;
return b.m_restorer * localPos;
}
return origPos;
zeus::CQuaternion RigInverter<CINFType>::invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const {
for (const Bone& b : m_bones)
if (b.m_origBone.id == boneId)
return b.m_restorer * zeus::CMatrix3f(origRot) * b.m_inverter;
return origRot;
}
template <class CINFType>
zeus::CQuaternion
RigInverter<CINFType>::restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const
{
for (const Bone& b : m_bones)
if (b.m_origBone.id == boneId)
return b.m_inverter * zeus::CMatrix3f(origRot) * b.m_restorer;
return origRot;
zeus::CVector3f RigInverter<CINFType>::invertPosition(atUint32 boneId, const zeus::CVector3f& origPos,
bool subDelta) const {
for (const Bone& b : m_bones)
if (b.m_origBone.id == boneId) {
zeus::CVector3f localPos = origPos;
if (subDelta)
localPos -= b.m_parentDelta;
return b.m_restorer * localPos;
}
return origPos;
}
template <class CINFType>
zeus::CVector3f
RigInverter<CINFType>::restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const
{
for (const Bone& b : m_bones)
if (b.m_origBone.id == boneId)
{
zeus::CVector3f localPos = b.m_inverter * origPos;
if (subDelta)
localPos += b.m_parentDelta;
return localPos;
}
return origPos;
zeus::CQuaternion RigInverter<CINFType>::restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const {
for (const Bone& b : m_bones)
if (b.m_origBone.id == boneId)
return b.m_inverter * zeus::CMatrix3f(origRot) * b.m_restorer;
return origRot;
}
template <class CINFType>
zeus::CVector3f RigInverter<CINFType>::restorePosition(atUint32 boneId, const zeus::CVector3f& origPos,
bool subDelta) const {
for (const Bone& b : m_bones)
if (b.m_origBone.id == boneId) {
zeus::CVector3f localPos = b.m_inverter * origPos;
if (subDelta)
localPos += b.m_parentDelta;
return localPos;
}
return origPos;
}
template class RigInverter<DNAMP1::CINF>;
template class RigInverter<DNAMP2::CINF>;
template class RigInverter<DNAMP3::CINF>;
}
} // namespace DataSpec::DNAANIM

View File

@ -5,40 +5,37 @@
#include "zeus/CQuaternion.hpp"
#include "hecl/hecl.hpp"
namespace DataSpec::DNAANIM
{
namespace DataSpec::DNAANIM {
/** One-shot process to invert CINF armature into connected rig,
* inverting rotations/translations of ANIM data to match */
template <class CINFType>
class RigInverter
{
class RigInverter {
public:
struct Bone
{
const typename CINFType::Bone& m_origBone;
zeus::CMatrix3f m_inverter;
zeus::CMatrix3f m_restorer;
zeus::CVector3f m_tail;
zeus::CVector3f m_parentDelta;
Bone(const CINFType& cinf, const typename CINFType::Bone& origBone);
};
struct Bone {
const typename CINFType::Bone& m_origBone;
zeus::CMatrix3f m_inverter;
zeus::CMatrix3f m_restorer;
zeus::CVector3f m_tail;
zeus::CVector3f m_parentDelta;
Bone(const CINFType& cinf, const typename CINFType::Bone& origBone);
};
private:
const CINFType& m_cinf;
std::vector<Bone> m_bones;
const CINFType& m_cinf;
std::vector<Bone> m_bones;
public:
RigInverter(const CINFType& cinf);
RigInverter(const CINFType& cinf,
const std::unordered_map<std::string, hecl::blender::Matrix3f>& matrices);
const CINFType& getCINF() const {return m_cinf;}
const std::vector<Bone>& getBones() const {return m_bones;}
RigInverter(const CINFType& cinf);
RigInverter(const CINFType& cinf, const std::unordered_map<std::string, hecl::blender::Matrix3f>& matrices);
const CINFType& getCINF() const { return m_cinf; }
const std::vector<Bone>& getBones() const { return m_bones; }
zeus::CQuaternion invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const;
zeus::CVector3f invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const;
zeus::CQuaternion invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const;
zeus::CVector3f invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const;
zeus::CQuaternion restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const;
zeus::CVector3f restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const;
zeus::CQuaternion restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) 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 "PAK.hpp"
namespace DataSpec::SAVWCommon
{
enum class EScanCategory
{
None,
Data,
Lore,
Creature,
Research,
Artifact
namespace DataSpec::SAVWCommon {
enum class EScanCategory { None, Data, Lore, Creature, Research, Artifact };
struct Header : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> magic;
Value<atUint32> version;
Value<atUint32> areaCount;
};
struct Header : BigDNA
{
AT_DECL_DNA_YAML
Value<atUint32> magic;
Value<atUint32> version;
Value<atUint32> areaCount;
struct EnvironmentVariable : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unk1;
Value<atUint32> unk2;
Value<atUint32> unk3;
};
struct EnvironmentVariable : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unk1;
Value<atUint32> unk2;
Value<atUint32> unk3;
};
struct Layer : BigDNA
{
AT_DECL_DNA_YAML
Value<atUint32> areaId;
Value<atUint32> layer;
struct Layer : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> areaId;
Value<atUint32> layer;
};
template <class SAVW>
static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
SAVW savw;
savw.read(rs);
athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::ToYAMLStream(savw, writer);
return true;
}
static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
SAVW savw;
savw.read(rs);
athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::ToYAMLStream(savw, writer);
return true;
}
} // namespace DataSpec::SAVWCommon

View File

@ -3,46 +3,37 @@
#include "../DNAMP2/STRG.hpp"
#include "../DNAMP3/STRG.hpp"
namespace DataSpec
{
namespace DataSpec {
void ISTRG::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
/* TODO: parse out resource tokens */
}
void ISTRG::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const { /* TODO: parse out resource tokens */ }
std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader)
{
uint32_t magic = reader.readUint32Big();
if (magic != 0x87654321)
{
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;
}
std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader) {
uint32_t magic = reader.readUint32Big();
if (magic != 0x87654321) {
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>();
}
}
} // namespace DataSpec

View File

@ -7,21 +7,18 @@
#include <athena/FileWriter.hpp>
#include "DNACommon.hpp"
namespace DataSpec
{
struct ISTRG : BigDNAVYaml
{
virtual ~ISTRG() = default;
namespace DataSpec {
struct ISTRG : BigDNAVYaml {
virtual ~ISTRG() = default;
virtual size_t count() 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 hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const=0;
virtual int32_t lookupIdx(std::string_view name) const=0;
virtual size_t count() 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 hecl::SystemString getSystemString(const FourCC& lang, size_t idx) 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);
}
} // namespace DataSpec

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -2,66 +2,62 @@
#include "ITweak.hpp"
namespace DataSpec
{
struct ITweakAutoMapper : public ITweak
{
virtual bool GetShowOneMiniMapArea() const=0;
virtual bool GetScaleMoveSpeedWithCamDist() const=0;
virtual float GetCamDist() const=0;
virtual float GetMinCamDist() const=0;
virtual float GetMaxCamDist() const=0;
virtual float GetMinCamRotateX() const=0;
virtual float GetMaxCamRotateX() const=0;
virtual float GetCamAngle() const=0;
virtual const zeus::CColor& GetAutomapperWidgetColor() const=0;
virtual float GetMiniCamDist() const=0;
virtual float GetMiniCamXAngle() const=0;
virtual float GetMiniCamAngle() const=0;
virtual const zeus::CColor& GetAutomapperWidgetMiniColor() const=0;
virtual const zeus::CColor& GetSurfaceVisitedColor() const=0;
virtual const zeus::CColor& GetOutlineVisitedColor() const=0;
virtual const zeus::CColor& GetSurfaceUnvisitedColor() const=0;
virtual const zeus::CColor& GetOutlineUnvisitedColor() const=0;
virtual const zeus::CColor& GetSurfaceSelectVisitedColor() const=0;
virtual const zeus::CColor& GetOutlineSelectVisitedColor() const=0;
virtual float GetMapSurfaceNormColorLinear() const=0;
virtual float GetMapSurfaceNormColorConstant() const=0;
virtual float GetOpenMapScreenTime() const=0;
virtual float GetCloseMapScreenTime() const=0;
virtual float GetHintPanTime() const=0;
virtual float GetCamZoomUnitsPerFrame() const=0;
virtual float GetCamRotateDegreesPerFrame() const=0;
virtual float GetBaseMapScreenCameraMoveSpeed() const=0;
virtual const zeus::CColor& GetSurfaceSelectUnvisitedColor() const=0;
virtual const zeus::CColor& GetOutlineSelectUnvisitedColor() const=0;
virtual float GetMiniAlphaSurfaceVisited() const=0;
virtual float GetAlphaSurfaceVisited() const=0;
virtual float GetMiniAlphaOutlineVisited() const=0;
virtual float GetAlphaOutlineVisited() const=0;
virtual float GetMiniAlphaSurfaceUnvisited() const=0;
virtual float GetAlphaSurfaceUnvisited() const=0;
virtual float GetMiniAlphaOutlineUnvisited() const=0;
virtual float GetAlphaOutlineUnvisited() const=0;
virtual const zeus::CVector3f& GetDoorCenter() const=0;
virtual float GetMiniMapViewportWidth() const=0;
virtual float GetMiniMapViewportHeight() const=0;
virtual float GetMiniMapCamDistScale() const=0;
virtual float GetMapPlaneScaleX() const=0;
virtual float GetMapPlaneScaleZ() const=0;
virtual float GetUniverseCamDist() const=0;
virtual float GetMinUniverseCamDist() const=0;
virtual float GetMaxUniverseCamDist() const=0;
virtual float GetSwitchToFromUniverseTime() const=0;
virtual float GetCamPanUnitsPerFrame() const=0;
virtual float GetAutomapperScaleX() const=0;
virtual float GetAutomapperScaleZ() const=0;
virtual float GetCamVerticalOffset() const=0;
virtual const zeus::CColor& GetMiniMapSamusModColor() const=0;
virtual const zeus::CColor& GetAreaFlashPulseColor() const=0;
virtual const zeus::CColor& GetDoorColor(int idx) const=0;
virtual const zeus::CColor& GetOpenDoorColor() const=0;
namespace DataSpec {
struct ITweakAutoMapper : public ITweak {
virtual bool GetShowOneMiniMapArea() const = 0;
virtual bool GetScaleMoveSpeedWithCamDist() const = 0;
virtual float GetCamDist() const = 0;
virtual float GetMinCamDist() const = 0;
virtual float GetMaxCamDist() const = 0;
virtual float GetMinCamRotateX() const = 0;
virtual float GetMaxCamRotateX() const = 0;
virtual float GetCamAngle() const = 0;
virtual const zeus::CColor& GetAutomapperWidgetColor() const = 0;
virtual float GetMiniCamDist() const = 0;
virtual float GetMiniCamXAngle() const = 0;
virtual float GetMiniCamAngle() const = 0;
virtual const zeus::CColor& GetAutomapperWidgetMiniColor() const = 0;
virtual const zeus::CColor& GetSurfaceVisitedColor() const = 0;
virtual const zeus::CColor& GetOutlineVisitedColor() const = 0;
virtual const zeus::CColor& GetSurfaceUnvisitedColor() const = 0;
virtual const zeus::CColor& GetOutlineUnvisitedColor() const = 0;
virtual const zeus::CColor& GetSurfaceSelectVisitedColor() const = 0;
virtual const zeus::CColor& GetOutlineSelectVisitedColor() const = 0;
virtual float GetMapSurfaceNormColorLinear() const = 0;
virtual float GetMapSurfaceNormColorConstant() const = 0;
virtual float GetOpenMapScreenTime() const = 0;
virtual float GetCloseMapScreenTime() const = 0;
virtual float GetHintPanTime() const = 0;
virtual float GetCamZoomUnitsPerFrame() const = 0;
virtual float GetCamRotateDegreesPerFrame() const = 0;
virtual float GetBaseMapScreenCameraMoveSpeed() const = 0;
virtual const zeus::CColor& GetSurfaceSelectUnvisitedColor() const = 0;
virtual const zeus::CColor& GetOutlineSelectUnvisitedColor() const = 0;
virtual float GetMiniAlphaSurfaceVisited() const = 0;
virtual float GetAlphaSurfaceVisited() const = 0;
virtual float GetMiniAlphaOutlineVisited() const = 0;
virtual float GetAlphaOutlineVisited() const = 0;
virtual float GetMiniAlphaSurfaceUnvisited() const = 0;
virtual float GetAlphaSurfaceUnvisited() const = 0;
virtual float GetMiniAlphaOutlineUnvisited() const = 0;
virtual float GetAlphaOutlineUnvisited() const = 0;
virtual const zeus::CVector3f& GetDoorCenter() const = 0;
virtual float GetMiniMapViewportWidth() const = 0;
virtual float GetMiniMapViewportHeight() const = 0;
virtual float GetMiniMapCamDistScale() const = 0;
virtual float GetMapPlaneScaleX() const = 0;
virtual float GetMapPlaneScaleZ() const = 0;
virtual float GetUniverseCamDist() const = 0;
virtual float GetMinUniverseCamDist() const = 0;
virtual float GetMaxUniverseCamDist() const = 0;
virtual float GetSwitchToFromUniverseTime() const = 0;
virtual float GetCamPanUnitsPerFrame() const = 0;
virtual float GetAutomapperScaleX() const = 0;
virtual float GetAutomapperScaleZ() const = 0;
virtual float GetCamVerticalOffset() const = 0;
virtual const zeus::CColor& GetMiniMapSamusModColor() const = 0;
virtual const zeus::CColor& GetAreaFlashPulseColor() 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"
namespace DataSpec
{
struct ITweakBall : ITweak
{
virtual float GetMaxBallTranslationAcceleration(int s) const=0;
virtual float GetBallTranslationFriction(int s) const=0;
virtual float GetBallTranslationMaxSpeed(int s) const=0;
virtual float GetBallCameraElevation() const=0;
virtual float GetBallCameraAnglePerSecond() const=0;
virtual const zeus::CVector3f& GetBallCameraOffset() const=0;
virtual float GetBallCameraMinSpeedDistance() const=0;
virtual float GetBallCameraMaxSpeedDistance() const=0;
virtual float GetBallCameraBackwardsDistance() const=0;
virtual float GetBallCameraSpringConstant() const=0;
virtual float GetBallCameraSpringMax() const=0;
virtual float GetBallCameraSpringTardis() const=0;
virtual float GetBallCameraCentroidSpringConstant() const=0;
virtual float GetBallCameraCentroidSpringMax() const=0;
virtual float GetBallCameraCentroidSpringTardis() const=0;
virtual float GetBallCameraCentroidDistanceSpringConstant() const=0;
virtual float GetBallCameraCentroidDistanceSpringMax() const=0;
virtual float GetBallCameraCentroidDistanceSpringTardis() const=0;
virtual float GetBallCameraLookAtSpringConstant() const=0;
virtual float GetBallCameraLookAtSpringMax() const=0;
virtual float GetBallCameraLookAtSpringTardis() const=0;
virtual float GetBallForwardBrakingAcceleration(int s) const=0;
virtual float GetBallGravity() const=0;
virtual float GetBallWaterGravity() const=0;
virtual float GetBallSlipFactor(int s) const=0;
virtual float GetConservativeDoorCameraDistance() const=0;
virtual float GetBallCameraChaseElevation() const=0;
virtual float GetBallCameraChaseDampenAngle() const=0;
virtual float GetBallCameraChaseDistance() const=0;
virtual float GetBallCameraChaseYawSpeed() const=0;
virtual float GetBallCameraChaseAnglePerSecond() const=0;
virtual const zeus::CVector3f& GetBallCameraChaseLookAtOffset() const=0;
virtual float GetBallCameraChaseSpringConstant() const=0;
virtual float GetBallCameraChaseSpringMax() const=0;
virtual float GetBallCameraChaseSpringTardis() const=0;
virtual float GetBallCameraBoostElevation() const=0;
virtual float GetBallCameraBoostDampenAngle() const=0;
virtual float GetBallCameraBoostDistance() const=0;
virtual float GetBallCameraBoostYawSpeed() const=0;
virtual float GetBallCameraBoostAnglePerSecond() const=0;
virtual const zeus::CVector3f& GetBallCameraBoostLookAtOffset() const=0;
virtual float GetBallCameraBoostSpringConstant() const=0;
virtual float GetBallCameraBoostSpringMax() const=0;
virtual float GetBallCameraBoostSpringTardis() const=0;
virtual float GetMinimumAlignmentSpeed() const=0;
virtual float GetTireness() const=0;
virtual float GetMaxLeanAngle() const=0;
virtual float GetTireToMarbleThresholdSpeed() const=0;
virtual float GetMarbleToTireThresholdSpeed() const=0;
virtual float GetForceToLeanGain() const=0;
virtual float GetLeanTrackingGain() const=0;
virtual float GetBallCameraControlDistance() const=0;
virtual float GetLeftStickDivisor() const=0;
virtual float GetRightStickDivisor() const=0;
virtual float GetBallTouchRadius() const=0;
virtual float GetBoostBallDrainTime() const=0;
virtual float GetBoostBallMaxChargeTime() const=0;
virtual float GetBoostBallMinChargeTime() const=0;
virtual float GetBoostBallMinRelativeSpeedForDamage() const=0;
virtual float GetBoostBallChargeTimeTable(int i) const=0;
virtual float GetBoostBallIncrementalSpeedTable(int i) const=0;
namespace DataSpec {
struct ITweakBall : ITweak {
virtual float GetMaxBallTranslationAcceleration(int s) const = 0;
virtual float GetBallTranslationFriction(int s) const = 0;
virtual float GetBallTranslationMaxSpeed(int s) const = 0;
virtual float GetBallCameraElevation() const = 0;
virtual float GetBallCameraAnglePerSecond() const = 0;
virtual const zeus::CVector3f& GetBallCameraOffset() const = 0;
virtual float GetBallCameraMinSpeedDistance() const = 0;
virtual float GetBallCameraMaxSpeedDistance() const = 0;
virtual float GetBallCameraBackwardsDistance() const = 0;
virtual float GetBallCameraSpringConstant() const = 0;
virtual float GetBallCameraSpringMax() const = 0;
virtual float GetBallCameraSpringTardis() const = 0;
virtual float GetBallCameraCentroidSpringConstant() const = 0;
virtual float GetBallCameraCentroidSpringMax() const = 0;
virtual float GetBallCameraCentroidSpringTardis() const = 0;
virtual float GetBallCameraCentroidDistanceSpringConstant() const = 0;
virtual float GetBallCameraCentroidDistanceSpringMax() const = 0;
virtual float GetBallCameraCentroidDistanceSpringTardis() const = 0;
virtual float GetBallCameraLookAtSpringConstant() const = 0;
virtual float GetBallCameraLookAtSpringMax() const = 0;
virtual float GetBallCameraLookAtSpringTardis() const = 0;
virtual float GetBallForwardBrakingAcceleration(int s) const = 0;
virtual float GetBallGravity() const = 0;
virtual float GetBallWaterGravity() const = 0;
virtual float GetBallSlipFactor(int s) const = 0;
virtual float GetConservativeDoorCameraDistance() const = 0;
virtual float GetBallCameraChaseElevation() const = 0;
virtual float GetBallCameraChaseDampenAngle() const = 0;
virtual float GetBallCameraChaseDistance() const = 0;
virtual float GetBallCameraChaseYawSpeed() const = 0;
virtual float GetBallCameraChaseAnglePerSecond() const = 0;
virtual const zeus::CVector3f& GetBallCameraChaseLookAtOffset() const = 0;
virtual float GetBallCameraChaseSpringConstant() const = 0;
virtual float GetBallCameraChaseSpringMax() const = 0;
virtual float GetBallCameraChaseSpringTardis() const = 0;
virtual float GetBallCameraBoostElevation() const = 0;
virtual float GetBallCameraBoostDampenAngle() const = 0;
virtual float GetBallCameraBoostDistance() const = 0;
virtual float GetBallCameraBoostYawSpeed() const = 0;
virtual float GetBallCameraBoostAnglePerSecond() const = 0;
virtual const zeus::CVector3f& GetBallCameraBoostLookAtOffset() const = 0;
virtual float GetBallCameraBoostSpringConstant() const = 0;
virtual float GetBallCameraBoostSpringMax() const = 0;
virtual float GetBallCameraBoostSpringTardis() const = 0;
virtual float GetMinimumAlignmentSpeed() const = 0;
virtual float GetTireness() const = 0;
virtual float GetMaxLeanAngle() const = 0;
virtual float GetTireToMarbleThresholdSpeed() const = 0;
virtual float GetMarbleToTireThresholdSpeed() const = 0;
virtual float GetForceToLeanGain() const = 0;
virtual float GetLeanTrackingGain() const = 0;
virtual float GetBallCameraControlDistance() const = 0;
virtual float GetLeftStickDivisor() const = 0;
virtual float GetRightStickDivisor() const = 0;
virtual float GetBallTouchRadius() const = 0;
virtual float GetBoostBallDrainTime() const = 0;
virtual float GetBoostBallMaxChargeTime() const = 0;
virtual float GetBoostBallMinChargeTime() const = 0;
virtual float GetBoostBallMinRelativeSpeedForDamage() 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"
namespace DataSpec
{
namespace DataSpec {
struct ITweakGame : ITweak
{
virtual std::string_view GetWorldPrefix() const = 0;
virtual bool GetSplashScreensDisabled() const = 0;
virtual float GetFirstPersonFOV() const = 0;
virtual float GetPressStartDelay() const = 0;
virtual float GetWavecapIntensityNormal() const = 0;
virtual float GetWavecapIntensityPoison() const = 0;
virtual float GetWavecapIntensityLava() const = 0;
virtual float GetRippleIntensityNormal() const = 0;
virtual float GetRippleIntensityPoison() const = 0;
virtual float GetRippleIntensityLava() const = 0;
virtual float GetFluidEnvBumpScale() const = 0;
virtual float GetWaterFogDistanceBase() const = 0;
virtual float GetWaterFogDistanceRange() const = 0;
virtual float GetGravityWaterFogDistanceBase() const = 0;
virtual float GetGravityWaterFogDistanceRange() const = 0;
virtual float GetHardModeDamageMultiplier() const = 0;
virtual float GetHardModeWeaponMultiplier() const = 0;
struct ITweakGame : ITweak {
virtual std::string_view GetWorldPrefix() const = 0;
virtual bool GetSplashScreensDisabled() const = 0;
virtual float GetFirstPersonFOV() const = 0;
virtual float GetPressStartDelay() const = 0;
virtual float GetWavecapIntensityNormal() const = 0;
virtual float GetWavecapIntensityPoison() const = 0;
virtual float GetWavecapIntensityLava() const = 0;
virtual float GetRippleIntensityNormal() const = 0;
virtual float GetRippleIntensityPoison() const = 0;
virtual float GetRippleIntensityLava() const = 0;
virtual float GetFluidEnvBumpScale() const = 0;
virtual float GetWaterFogDistanceBase() const = 0;
virtual float GetWaterFogDistanceRange() const = 0;
virtual float GetGravityWaterFogDistanceBase() const = 0;
virtual float GetGravityWaterFogDistanceRange() const = 0;
virtual float GetHardModeDamageMultiplier() const = 0;
virtual float GetHardModeWeaponMultiplier() const = 0;
};
}
} // namespace DataSpec

View File

@ -3,151 +3,134 @@
#include "ITweak.hpp"
#include "zeus/CVector2f.hpp"
namespace DataSpec
{
namespace DataSpec {
struct ITweakGui : ITweak
{
enum class EHudVisMode : atUint32
{
Zero,
One,
Two,
Three
};
struct ITweakGui : ITweak {
enum class EHudVisMode : atUint32 { Zero, One, Two, Three };
enum class EHelmetVisMode : atUint32
{
ReducedUpdate,
NotVisible,
Deco,
HelmetDeco,
GlowHelmetDeco,
HelmetOnly
};
enum class EHelmetVisMode : atUint32 { ReducedUpdate, NotVisible, Deco, HelmetDeco, GlowHelmetDeco, HelmetOnly };
virtual float GetMapAlphaInterpolant() const=0;
virtual float GetPauseBlurFactor() const=0;
virtual float GetRadarXYRadius() const=0;
virtual float GetRadarZRadius() const=0;
virtual float GetRadarZCloseRadius() const=0;
virtual float GetEnergyBarFilledSpeed() const=0;
virtual float GetEnergyBarShadowSpeed() const=0;
virtual float GetEnergyBarDrainDelay() const=0;
virtual bool GetEnergyBarAlwaysResetDelay() const=0;
virtual float GetHudDamagePracticalsGainConstant() const=0;
virtual float GetHudDamagePracticalsGainLinear() const=0;
virtual float GetHudDamagePracticalsInitConstant() const=0;
virtual float GetHudDamagePracticalsInitLinear() const=0;
virtual float GetHudDamageLightSpotAngle() const=0;
virtual float GetDamageLightAngleC() const=0;
virtual float GetDamageLightAngleL() const=0;
virtual float GetDamageLightAngleQ() const=0;
virtual atVec3f GetDamageLightPreTranslate() const=0;
virtual atVec3f GetDamageLightCenterTranslate() const=0;
virtual float GetDamageLightXfXAngle() const=0;
virtual float GetDamageLightXfZAngle() const=0;
virtual float GetHudDecoShakeTranslateVelConstant() const=0;
virtual float GetHudDecoShakeTranslateVelLinear() const=0;
virtual float GetMaxDecoDamageShakeTranslate() const=0;
virtual float GetDecoDamageShakeDeceleration() const=0;
virtual float GetDecoShakeGainConstant() const=0;
virtual float GetDecoShakeGainLinear() const=0;
virtual float GetDecoShakeInitConstant() const=0;
virtual float GetDecoShakeInitLinear() const=0;
virtual float GetMaxDecoDamageShakeRotate() const=0;
virtual atUint32 GetHudCamFovTweak() const=0;
virtual atUint32 GetHudCamYTweak() const=0;
virtual atUint32 GetHudCamZTweak() const=0;
virtual float GetBeamVisorMenuAnimTime() const=0;
virtual float GetVisorBeamMenuItemActiveScale() const=0;
virtual float GetVisorBeamMenuItemInactiveScale() const=0;
virtual float GetVisorBeamMenuItemTranslate() const=0;
virtual float GetThreatRange() const=0;
virtual float GetRadarScopeCoordRadius() const=0;
virtual float GetRadarPlayerPaintRadius() const=0;
virtual float GetRadarEnemyPaintRadius() const=0;
virtual float GetMissileArrowVisTime() const=0;
virtual EHudVisMode GetHudVisMode() const=0;
virtual EHelmetVisMode GetHelmetVisMode() const=0;
virtual atUint32 GetEnableAutoMapper() const=0;
virtual atUint32 GetEnableTargetingManager() const=0;
virtual atUint32 GetEnablePlayerVisor() const=0;
virtual float GetThreatWarningFraction() const=0;
virtual float GetMissileWarningFraction() const=0;
virtual float GetFreeLookFadeTime() const=0;
virtual float GetFreeLookSfxPitchScale() const=0;
virtual bool GetNoAbsoluteFreeLookSfxPitch() const=0;
virtual float GetFaceReflectionOrthoWidth() const=0;
virtual float GetFaceReflectionOrthoHeight() const=0;
virtual float GetFaceReflectionDistance() const=0;
virtual float GetFaceReflectionHeight() const=0;
virtual float GetFaceReflectionAspect() const=0;
virtual float GetMissileWarningPulseTime() const=0;
virtual float GetExplosionLightFalloffMultConstant() const=0;
virtual float GetExplosionLightFalloffMultLinear() const=0;
virtual float GetExplosionLightFalloffMultQuadratic() const=0;
virtual float GetHudDamagePeakFactor() const=0;
virtual float GetHudDamageFilterGainConstant() const=0;
virtual float GetHudDamageFilterGainLinear() const=0;
virtual float GetHudDamageFilterInitConstant() const=0;
virtual float GetHudDamageFilterInitLinear() const=0;
virtual float GetEnergyDrainModPeriod() const=0;
virtual bool GetEnergyDrainSinusoidalPulse() const=0;
virtual bool GetEnergyDrainFilterAdditive() const=0;
virtual float GetHudDamagePulseDuration() const=0;
virtual float GetHudDamageColorGain() const=0;
virtual float GetHudDecoShakeTranslateGain() const=0;
virtual float GetHudLagOffsetScale() const=0;
virtual float GetScanAppearanceDuration() const=0;
virtual float GetScanPaneFlashFactor() const=0;
virtual float GetScanPaneFadeInTime() const=0;
virtual float GetScanPaneFadeOutTime() const=0;
virtual float GetBallViewportYReduction() const=0;
virtual float GetScanWindowIdleWidth() const=0;
virtual float GetScanWindowIdleHeight() const=0;
virtual float GetScanWindowActiveWidth() const=0;
virtual float GetScanWindowActiveHeight() const=0;
virtual float GetScanWindowMagnification() const=0;
virtual float GetScanWindowScanningAspect() const=0;
virtual float GetScanSpeed(int idx) const=0;
virtual float GetXrayBlurScaleLinear() const=0;
virtual float GetXrayBlurScaleQuadratic() const=0;
virtual float GetScanSidesAngle() const=0;
virtual float GetScanSidesXScale() const=0;
virtual float GetScanSidesPositionEnd() const=0;
virtual float GetScanSidesDuration() const=0;
virtual float GetScanSidesStartTime() const=0;
virtual float GetScanSidesEndTime() const=0;
virtual float GetScanDataDotRadius() const=0;
virtual float GetScanDataDotPosRandMagnitude() const=0;
virtual float GetScanDataDotSeekDurationMin() const=0;
virtual float GetScanDataDotSeekDurationMax() const=0;
virtual float GetScanDataDotHoldDurationMin() const=0;
virtual float GetScanDataDotHoldDurationMax() const=0;
virtual float GetScanSidesPositionStart() const=0;
virtual bool GetShowAutomapperInMorphball() const=0;
virtual bool GetLatchArticleText() const=0;
virtual float GetWorldTransManagerCharsPerSfx() const=0;
virtual atUint32 GetXRayFogMode() const=0;
virtual float GetXRayFogNearZ() const=0;
virtual float GetXRayFogFarZ() const=0;
virtual const zeus::CColor& GetXRayFogColor() const=0;
virtual float GetThermalVisorLevel() const=0;
virtual const zeus::CColor& GetThermalVisorColor() const=0;
virtual const zeus::CColor& GetVisorHudLightAdd(int v) const=0;
virtual const zeus::CColor& GetVisorHudLightMultiply(int v) const=0;
virtual const zeus::CColor& GetHudReflectivityLightColor() const=0;
virtual float GetHudLightAttMulConstant() const=0;
virtual float GetHudLightAttMulLinear() const=0;
virtual float GetHudLightAttMulQuadratic() const=0;
virtual float GetMapAlphaInterpolant() const = 0;
virtual float GetPauseBlurFactor() const = 0;
virtual float GetRadarXYRadius() const = 0;
virtual float GetRadarZRadius() const = 0;
virtual float GetRadarZCloseRadius() const = 0;
virtual float GetEnergyBarFilledSpeed() const = 0;
virtual float GetEnergyBarShadowSpeed() const = 0;
virtual float GetEnergyBarDrainDelay() const = 0;
virtual bool GetEnergyBarAlwaysResetDelay() const = 0;
virtual float GetHudDamagePracticalsGainConstant() const = 0;
virtual float GetHudDamagePracticalsGainLinear() const = 0;
virtual float GetHudDamagePracticalsInitConstant() const = 0;
virtual float GetHudDamagePracticalsInitLinear() const = 0;
virtual float GetHudDamageLightSpotAngle() const = 0;
virtual float GetDamageLightAngleC() const = 0;
virtual float GetDamageLightAngleL() const = 0;
virtual float GetDamageLightAngleQ() const = 0;
virtual atVec3f GetDamageLightPreTranslate() const = 0;
virtual atVec3f GetDamageLightCenterTranslate() const = 0;
virtual float GetDamageLightXfXAngle() const = 0;
virtual float GetDamageLightXfZAngle() const = 0;
virtual float GetHudDecoShakeTranslateVelConstant() const = 0;
virtual float GetHudDecoShakeTranslateVelLinear() const = 0;
virtual float GetMaxDecoDamageShakeTranslate() const = 0;
virtual float GetDecoDamageShakeDeceleration() const = 0;
virtual float GetDecoShakeGainConstant() const = 0;
virtual float GetDecoShakeGainLinear() const = 0;
virtual float GetDecoShakeInitConstant() const = 0;
virtual float GetDecoShakeInitLinear() const = 0;
virtual float GetMaxDecoDamageShakeRotate() const = 0;
virtual atUint32 GetHudCamFovTweak() const = 0;
virtual atUint32 GetHudCamYTweak() const = 0;
virtual atUint32 GetHudCamZTweak() const = 0;
virtual float GetBeamVisorMenuAnimTime() const = 0;
virtual float GetVisorBeamMenuItemActiveScale() const = 0;
virtual float GetVisorBeamMenuItemInactiveScale() const = 0;
virtual float GetVisorBeamMenuItemTranslate() const = 0;
virtual float GetThreatRange() const = 0;
virtual float GetRadarScopeCoordRadius() const = 0;
virtual float GetRadarPlayerPaintRadius() const = 0;
virtual float GetRadarEnemyPaintRadius() const = 0;
virtual float GetMissileArrowVisTime() const = 0;
virtual EHudVisMode GetHudVisMode() const = 0;
virtual EHelmetVisMode GetHelmetVisMode() const = 0;
virtual atUint32 GetEnableAutoMapper() const = 0;
virtual atUint32 GetEnableTargetingManager() const = 0;
virtual atUint32 GetEnablePlayerVisor() const = 0;
virtual float GetThreatWarningFraction() const = 0;
virtual float GetMissileWarningFraction() const = 0;
virtual float GetFreeLookFadeTime() const = 0;
virtual float GetFreeLookSfxPitchScale() const = 0;
virtual bool GetNoAbsoluteFreeLookSfxPitch() const = 0;
virtual float GetFaceReflectionOrthoWidth() const = 0;
virtual float GetFaceReflectionOrthoHeight() const = 0;
virtual float GetFaceReflectionDistance() const = 0;
virtual float GetFaceReflectionHeight() const = 0;
virtual float GetFaceReflectionAspect() const = 0;
virtual float GetMissileWarningPulseTime() const = 0;
virtual float GetExplosionLightFalloffMultConstant() const = 0;
virtual float GetExplosionLightFalloffMultLinear() const = 0;
virtual float GetExplosionLightFalloffMultQuadratic() const = 0;
virtual float GetHudDamagePeakFactor() const = 0;
virtual float GetHudDamageFilterGainConstant() const = 0;
virtual float GetHudDamageFilterGainLinear() const = 0;
virtual float GetHudDamageFilterInitConstant() const = 0;
virtual float GetHudDamageFilterInitLinear() const = 0;
virtual float GetEnergyDrainModPeriod() const = 0;
virtual bool GetEnergyDrainSinusoidalPulse() const = 0;
virtual bool GetEnergyDrainFilterAdditive() const = 0;
virtual float GetHudDamagePulseDuration() const = 0;
virtual float GetHudDamageColorGain() const = 0;
virtual float GetHudDecoShakeTranslateGain() const = 0;
virtual float GetHudLagOffsetScale() const = 0;
virtual float GetScanAppearanceDuration() const = 0;
virtual float GetScanPaneFlashFactor() const = 0;
virtual float GetScanPaneFadeInTime() const = 0;
virtual float GetScanPaneFadeOutTime() const = 0;
virtual float GetBallViewportYReduction() const = 0;
virtual float GetScanWindowIdleWidth() const = 0;
virtual float GetScanWindowIdleHeight() const = 0;
virtual float GetScanWindowActiveWidth() const = 0;
virtual float GetScanWindowActiveHeight() const = 0;
virtual float GetScanWindowMagnification() const = 0;
virtual float GetScanWindowScanningAspect() const = 0;
virtual float GetScanSpeed(int idx) const = 0;
virtual float GetXrayBlurScaleLinear() const = 0;
virtual float GetXrayBlurScaleQuadratic() const = 0;
virtual float GetScanSidesAngle() const = 0;
virtual float GetScanSidesXScale() const = 0;
virtual float GetScanSidesPositionEnd() const = 0;
virtual float GetScanSidesDuration() const = 0;
virtual float GetScanSidesStartTime() const = 0;
virtual float GetScanSidesEndTime() const = 0;
virtual float GetScanDataDotRadius() const = 0;
virtual float GetScanDataDotPosRandMagnitude() const = 0;
virtual float GetScanDataDotSeekDurationMin() const = 0;
virtual float GetScanDataDotSeekDurationMax() const = 0;
virtual float GetScanDataDotHoldDurationMin() const = 0;
virtual float GetScanDataDotHoldDurationMax() const = 0;
virtual float GetScanSidesPositionStart() const = 0;
virtual bool GetShowAutomapperInMorphball() const = 0;
virtual bool GetLatchArticleText() const = 0;
virtual float GetWorldTransManagerCharsPerSfx() const = 0;
virtual atUint32 GetXRayFogMode() const = 0;
virtual float GetXRayFogNearZ() const = 0;
virtual float GetXRayFogFarZ() const = 0;
virtual const zeus::CColor& GetXRayFogColor() const = 0;
virtual float GetThermalVisorLevel() const = 0;
virtual const zeus::CColor& GetThermalVisorColor() const = 0;
virtual const zeus::CColor& GetVisorHudLightAdd(int v) const = 0;
virtual const zeus::CColor& GetVisorHudLightMultiply(int v) const = 0;
virtual const zeus::CColor& GetHudReflectivityLightColor() const = 0;
virtual float GetHudLightAttMulConstant() const = 0;
virtual float GetHudLightAttMulLinear() const = 0;
virtual float GetHudLightAttMulQuadratic() const = 0;
static float FaceReflectionDistanceDebugValueToActualValue(float v) { return 0.015f * v + 0.2f; }
static float FaceReflectionHeightDebugValueToActualValue(float v) { return 0.005f * v - 0.05f; }
static float FaceReflectionAspectDebugValueToActualValue(float v) { return 0.05f * v + 1.f; }
static float FaceReflectionOrthoWidthDebugValueToActualValue(float v) { return 0.007f * v + 0.02f; }
static float FaceReflectionOrthoHeightDebugValueToActualValue(float v) { return 0.007f * v + 0.02f; }
static float FaceReflectionDistanceDebugValueToActualValue(float v) { return 0.015f * v + 0.2f; }
static float FaceReflectionHeightDebugValueToActualValue(float v) { return 0.005f * v - 0.05f; }
static float FaceReflectionAspectDebugValueToActualValue(float v) { return 0.05f * v + 1.f; }
static float FaceReflectionOrthoWidthDebugValueToActualValue(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"
namespace DataSpec
{
struct ITweakGuiColors : ITweak
{
struct VisorEnergyInitColors
{
const zeus::CColor& tankFilled;
const zeus::CColor& tankEmpty;
const zeus::CColor& digitsFont;
const zeus::CColor& digitsOutline;
};
namespace DataSpec {
struct ITweakGuiColors : ITweak {
struct VisorEnergyInitColors {
const zeus::CColor& tankFilled;
const zeus::CColor& tankEmpty;
const zeus::CColor& digitsFont;
const zeus::CColor& digitsOutline;
};
struct VisorEnergyBarColors
{
const zeus::CColor& filled;
const zeus::CColor& empty;
const zeus::CColor& shadow;
};
struct VisorEnergyBarColors {
const zeus::CColor& filled;
const zeus::CColor& empty;
const zeus::CColor& shadow;
};
virtual const zeus::CColor& GetPauseBlurFilterColor() const=0;
virtual const zeus::CColor& GetRadarStuffColor() const=0;
virtual const zeus::CColor& GetRadarPlayerPaintColor() const=0;
virtual const zeus::CColor& GetRadarEnemyPaintColor() const=0;
virtual const zeus::CColor& GetHudMessageFill() const=0;
virtual const zeus::CColor& GetHudMessageOutline() const=0;
virtual const zeus::CColor& GetHudFrameColor() const=0;
virtual const zeus::CColor& GetMissileIconColorActive() const=0;
virtual const zeus::CColor& GetVisorBeamMenuItemActive() const=0;
virtual const zeus::CColor& GetVisorBeamMenuItemInactive() const=0;
virtual const zeus::CColor& GetEnergyBarFilledLowEnergy() const=0;
virtual const zeus::CColor& GetEnergyBarShadowLowEnergy() const=0;
virtual const zeus::CColor& GetEnergyBarEmptyLowEnergy() const=0;
virtual const zeus::CColor& GetHudDamageLightColor() const=0;
virtual const zeus::CColor& GetVisorMenuTextFont() const=0;
virtual const zeus::CColor& GetVisorMenuTextOutline() const=0;
virtual const zeus::CColor& GetBeamMenuTextFont() const=0;
virtual const zeus::CColor& GetBeamMenuTextOutline() const=0;
virtual const zeus::CColor& GetEnergyWarningFont() const=0;
virtual const zeus::CColor& GetThreatWarningFont() const=0;
virtual const zeus::CColor& GetMissileWarningFont() const=0;
virtual const zeus::CColor& GetThreatBarFilled() const=0;
virtual const zeus::CColor& GetThreatBarShadow() const=0;
virtual const zeus::CColor& GetThreatBarEmpty() const=0;
virtual const zeus::CColor& GetMissileBarFilled() const=0;
virtual const zeus::CColor& GetMissileBarShadow() const=0;
virtual const zeus::CColor& GetMissileBarEmpty() const=0;
virtual const zeus::CColor& GetThreatIconColor() const=0;
virtual const zeus::CColor& GetTickDecoColor() const=0;
virtual const zeus::CColor& GetHelmetLightColor() const=0;
virtual const zeus::CColor& GetThreatIconSafeColor() const=0;
virtual const zeus::CColor& GetMissileIconColorInactive() const=0;
virtual const zeus::CColor& GetMissileIconColorChargedCanAlt() const=0;
virtual const zeus::CColor& GetMissileIconColorChargedNoAlt() const=0;
virtual const zeus::CColor& GetMissileIconColorDepleteAlt() const=0;
virtual const zeus::CColor& GetVisorBeamMenuLozColor() const=0;
virtual const zeus::CColor& GetEnergyWarningOutline() const=0;
virtual const zeus::CColor& GetThreatWarningOutline() const=0;
virtual const zeus::CColor& GetMissileWarningOutline() const=0;
virtual const zeus::CColor& GetDamageAmbientColor() const=0;
virtual const zeus::CColor& GetScanFrameInactiveColor() const=0;
virtual const zeus::CColor& GetScanFrameActiveColor() const=0;
virtual const zeus::CColor& GetScanFrameImpulseColor() const=0;
virtual const zeus::CColor& GetScanVisorHudLightMultiply() const=0;
virtual const zeus::CColor& GetScanVisorScreenDimColor() const=0;
virtual const zeus::CColor& GetThermalVisorHudLightMultiply() const=0;
virtual const zeus::CColor& GetEnergyDrainFilterColor() const=0;
virtual const zeus::CColor& GetDamageAmbientPulseColor() const=0;
virtual const zeus::CColor& GetEnergyBarFlashColor() const=0;
virtual const zeus::CColor& GetXRayEnergyDecoColor() const=0;
virtual const zeus::CColor& GetScanDataDotColor() const=0;
virtual const zeus::CColor& GetPowerBombDigitAvailableFont() const=0;
virtual const zeus::CColor& GetPowerBombDigitAvailableOutline() const=0;
virtual const zeus::CColor& GetBallBombFilledColor() const=0;
virtual const zeus::CColor& GetBallBombEmptyColor() const=0;
virtual const zeus::CColor& GetPowerBombIconAvailableColor() const=0;
virtual const zeus::CColor& GetBallBombEnergyColor() const=0;
virtual const zeus::CColor& GetBallBombDecoColor() const=0;
virtual const zeus::CColor& GetPowerBombDigitDelpetedFont() const=0;
virtual const zeus::CColor& GetPowerBombDigitDelpetedOutline() const=0;
virtual const zeus::CColor& GetPowerBombIconDepletedColor() const=0;
virtual const zeus::CColor& GetScanDisplayImagePaneColor() const=0;
virtual const zeus::CColor& GetThreatIconWarningColor() const=0;
virtual const zeus::CColor& GetHudCounterFill() const=0;
virtual const zeus::CColor& GetHudCounterOutline() const=0;
virtual const zeus::CColor& GetScanIconCriticalColor() const=0;
virtual const zeus::CColor& GetScanIconCriticalDimColor() const=0;
virtual const zeus::CColor& GetScanIconNoncriticalColor() const=0;
virtual const zeus::CColor& GetScanIconNoncriticalDimColor() const=0;
virtual const zeus::CColor& GetScanReticuleColor() const=0;
virtual const zeus::CColor& GetThreatDigitsFont() const=0;
virtual const zeus::CColor& GetThreatDigitsOutline() const=0;
virtual const zeus::CColor& GetMissileDigitsFont() const=0;
virtual const zeus::CColor& GetMissileDigitsOutline() const=0;
virtual const zeus::CColor& GetThermalDecoColor() const=0;
virtual const zeus::CColor& GetThermalOutlinesColor() const=0;
virtual const zeus::CColor& GetThermalLockColor() const=0;
virtual const zeus::CColor& GetPauseItemAmberColor() const=0;
virtual const zeus::CColor& GetPauseItemBlueColor() const=0;
virtual VisorEnergyInitColors GetVisorEnergyInitColors(int idx) const=0;
virtual VisorEnergyBarColors GetVisorEnergyBarColors(int idx) const=0;
virtual const zeus::CColor& GetPauseBlurFilterColor() const = 0;
virtual const zeus::CColor& GetRadarStuffColor() const = 0;
virtual const zeus::CColor& GetRadarPlayerPaintColor() const = 0;
virtual const zeus::CColor& GetRadarEnemyPaintColor() const = 0;
virtual const zeus::CColor& GetHudMessageFill() const = 0;
virtual const zeus::CColor& GetHudMessageOutline() const = 0;
virtual const zeus::CColor& GetHudFrameColor() const = 0;
virtual const zeus::CColor& GetMissileIconColorActive() const = 0;
virtual const zeus::CColor& GetVisorBeamMenuItemActive() const = 0;
virtual const zeus::CColor& GetVisorBeamMenuItemInactive() const = 0;
virtual const zeus::CColor& GetEnergyBarFilledLowEnergy() const = 0;
virtual const zeus::CColor& GetEnergyBarShadowLowEnergy() const = 0;
virtual const zeus::CColor& GetEnergyBarEmptyLowEnergy() const = 0;
virtual const zeus::CColor& GetHudDamageLightColor() const = 0;
virtual const zeus::CColor& GetVisorMenuTextFont() const = 0;
virtual const zeus::CColor& GetVisorMenuTextOutline() const = 0;
virtual const zeus::CColor& GetBeamMenuTextFont() const = 0;
virtual const zeus::CColor& GetBeamMenuTextOutline() const = 0;
virtual const zeus::CColor& GetEnergyWarningFont() const = 0;
virtual const zeus::CColor& GetThreatWarningFont() const = 0;
virtual const zeus::CColor& GetMissileWarningFont() const = 0;
virtual const zeus::CColor& GetThreatBarFilled() const = 0;
virtual const zeus::CColor& GetThreatBarShadow() const = 0;
virtual const zeus::CColor& GetThreatBarEmpty() const = 0;
virtual const zeus::CColor& GetMissileBarFilled() const = 0;
virtual const zeus::CColor& GetMissileBarShadow() const = 0;
virtual const zeus::CColor& GetMissileBarEmpty() const = 0;
virtual const zeus::CColor& GetThreatIconColor() const = 0;
virtual const zeus::CColor& GetTickDecoColor() const = 0;
virtual const zeus::CColor& GetHelmetLightColor() const = 0;
virtual const zeus::CColor& GetThreatIconSafeColor() const = 0;
virtual const zeus::CColor& GetMissileIconColorInactive() const = 0;
virtual const zeus::CColor& GetMissileIconColorChargedCanAlt() const = 0;
virtual const zeus::CColor& GetMissileIconColorChargedNoAlt() const = 0;
virtual const zeus::CColor& GetMissileIconColorDepleteAlt() const = 0;
virtual const zeus::CColor& GetVisorBeamMenuLozColor() const = 0;
virtual const zeus::CColor& GetEnergyWarningOutline() const = 0;
virtual const zeus::CColor& GetThreatWarningOutline() const = 0;
virtual const zeus::CColor& GetMissileWarningOutline() const = 0;
virtual const zeus::CColor& GetDamageAmbientColor() const = 0;
virtual const zeus::CColor& GetScanFrameInactiveColor() const = 0;
virtual const zeus::CColor& GetScanFrameActiveColor() const = 0;
virtual const zeus::CColor& GetScanFrameImpulseColor() const = 0;
virtual const zeus::CColor& GetScanVisorHudLightMultiply() const = 0;
virtual const zeus::CColor& GetScanVisorScreenDimColor() const = 0;
virtual const zeus::CColor& GetThermalVisorHudLightMultiply() const = 0;
virtual const zeus::CColor& GetEnergyDrainFilterColor() const = 0;
virtual const zeus::CColor& GetDamageAmbientPulseColor() const = 0;
virtual const zeus::CColor& GetEnergyBarFlashColor() const = 0;
virtual const zeus::CColor& GetXRayEnergyDecoColor() const = 0;
virtual const zeus::CColor& GetScanDataDotColor() const = 0;
virtual const zeus::CColor& GetPowerBombDigitAvailableFont() const = 0;
virtual const zeus::CColor& GetPowerBombDigitAvailableOutline() const = 0;
virtual const zeus::CColor& GetBallBombFilledColor() const = 0;
virtual const zeus::CColor& GetBallBombEmptyColor() const = 0;
virtual const zeus::CColor& GetPowerBombIconAvailableColor() const = 0;
virtual const zeus::CColor& GetBallBombEnergyColor() const = 0;
virtual const zeus::CColor& GetBallBombDecoColor() const = 0;
virtual const zeus::CColor& GetPowerBombDigitDelpetedFont() const = 0;
virtual const zeus::CColor& GetPowerBombDigitDelpetedOutline() const = 0;
virtual const zeus::CColor& GetPowerBombIconDepletedColor() const = 0;
virtual const zeus::CColor& GetScanDisplayImagePaneColor() const = 0;
virtual const zeus::CColor& GetThreatIconWarningColor() const = 0;
virtual const zeus::CColor& GetHudCounterFill() const = 0;
virtual const zeus::CColor& GetHudCounterOutline() const = 0;
virtual const zeus::CColor& GetScanIconCriticalColor() const = 0;
virtual const zeus::CColor& GetScanIconCriticalDimColor() const = 0;
virtual const zeus::CColor& GetScanIconNoncriticalColor() const = 0;
virtual const zeus::CColor& GetScanIconNoncriticalDimColor() const = 0;
virtual const zeus::CColor& GetScanReticuleColor() const = 0;
virtual const zeus::CColor& GetThreatDigitsFont() const = 0;
virtual const zeus::CColor& GetThreatDigitsOutline() const = 0;
virtual const zeus::CColor& GetMissileDigitsFont() const = 0;
virtual const zeus::CColor& GetMissileDigitsOutline() const = 0;
virtual const zeus::CColor& GetThermalDecoColor() const = 0;
virtual const zeus::CColor& GetThermalOutlinesColor() const = 0;
virtual const zeus::CColor& GetThermalLockColor() const = 0;
virtual const zeus::CColor& GetPauseItemAmberColor() const = 0;
virtual const zeus::CColor& GetPauseItemBlueColor() const = 0;
virtual VisorEnergyInitColors GetVisorEnergyInitColors(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/CPlayerState.hpp"
namespace DataSpec
{
namespace DataSpec {
struct ITweakGunRes : ITweak
{
using ResId = urde::CAssetId;
using EBeamId = urde::CPlayerState::EBeamId;
struct ITweakGunRes : ITweak {
using ResId = urde::CAssetId;
using EBeamId = urde::CPlayerState::EBeamId;
ResId x4_gunMotion;
ResId x8_grappleArm;
ResId xc_rightHand;
ResId x4_gunMotion;
ResId x8_grappleArm;
ResId xc_rightHand;
ResId x10_powerBeam;
ResId x14_iceBeam;
ResId x18_waveBeam;
ResId x1c_plasmaBeam;
ResId x20_phazonBeam;
ResId x10_powerBeam;
ResId x14_iceBeam;
ResId x18_waveBeam;
ResId x1c_plasmaBeam;
ResId x20_phazonBeam;
ResId x24_holoTransition;
ResId x24_holoTransition;
ResId x28_bombSet;
ResId x2c_bombExplode;
ResId x30_powerBombExplode;
ResId x28_bombSet;
ResId x2c_bombExplode;
ResId x30_powerBombExplode;
/* Power, Ice, Wave, Plasma, Phazon / Beam, Ball */
ResId x34_weapons[5][2];
ResId x84_muzzle[5];
ResId x94_charge[5];
ResId xa4_auxMuzzle[5];
/* Power, Ice, Wave, Plasma, Phazon / Beam, Ball */
ResId x34_weapons[5][2];
ResId x84_muzzle[5];
ResId x94_charge[5];
ResId xa4_auxMuzzle[5];
ResId xb4_grappleSegment;
ResId xb8_grappleClaw;
ResId xbc_grappleHit;
ResId xc0_grappleMuzzle;
ResId xc4_grappleSwoosh;
ResId xb4_grappleSegment;
ResId xb8_grappleClaw;
ResId xbc_grappleHit;
ResId xc0_grappleMuzzle;
ResId xc4_grappleSwoosh;
ResId GetBeamModel(EBeamId beam) const
{
auto b = int(beam);
if (b < 0 || b > 4)
b = 0;
switch (EBeamId(b))
{
default:
case EBeamId::Power:
return x10_powerBeam;
case EBeamId::Ice:
return x14_iceBeam;
case EBeamId::Wave:
return x18_waveBeam;
case EBeamId::Plasma:
return x1c_plasmaBeam;
case EBeamId::Phazon:
return x20_phazonBeam;
}
ResId GetBeamModel(EBeamId beam) const {
auto b = int(beam);
if (b < 0 || b > 4)
b = 0;
switch (EBeamId(b)) {
default:
case EBeamId::Power:
return x10_powerBeam;
case EBeamId::Ice:
return x14_iceBeam;
case EBeamId::Wave:
return x18_waveBeam;
case EBeamId::Plasma:
return x1c_plasmaBeam;
case EBeamId::Phazon:
return x20_phazonBeam;
}
}
const ResId* GetWeaponPair(EBeamId beam) const
{
auto b = int(beam);
if (b < 0 || b > 4)
return x34_weapons[0];
return x34_weapons[b];
}
const ResId* GetWeaponPair(EBeamId beam) const {
auto b = int(beam);
if (b < 0 || b > 4)
return x34_weapons[0];
return x34_weapons[b];
}
void ResolveResources(const urde::IFactory& factory)
{
x4_gunMotion = factory.GetResourceIdByName(GetGunMotion().c_str())->id;
x8_grappleArm = factory.GetResourceIdByName(GetGrappleArm().c_str())->id;
xc_rightHand = factory.GetResourceIdByName(GetRightHand().c_str())->id;
void ResolveResources(const urde::IFactory& factory) {
x4_gunMotion = factory.GetResourceIdByName(GetGunMotion().c_str())->id;
x8_grappleArm = factory.GetResourceIdByName(GetGrappleArm().c_str())->id;
xc_rightHand = factory.GetResourceIdByName(GetRightHand().c_str())->id;
x10_powerBeam = factory.GetResourceIdByName(GetPowerBeam().c_str())->id;
x14_iceBeam = factory.GetResourceIdByName(GetIceBeam().c_str())->id;
x18_waveBeam = factory.GetResourceIdByName(GetWaveBeam().c_str())->id;
x1c_plasmaBeam = factory.GetResourceIdByName(GetPlasmaBeam().c_str())->id;
x20_phazonBeam = factory.GetResourceIdByName(GetPhazonBeam().c_str())->id;
x10_powerBeam = factory.GetResourceIdByName(GetPowerBeam().c_str())->id;
x14_iceBeam = factory.GetResourceIdByName(GetIceBeam().c_str())->id;
x18_waveBeam = factory.GetResourceIdByName(GetWaveBeam().c_str())->id;
x1c_plasmaBeam = factory.GetResourceIdByName(GetPlasmaBeam().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;
x2c_bombExplode = factory.GetResourceIdByName(GetBombExplode().c_str())->id;
x30_powerBombExplode = factory.GetResourceIdByName(GetPowerBombExplode().c_str())->id;
x28_bombSet = factory.GetResourceIdByName(GetBombSet().c_str())->id;
x2c_bombExplode = factory.GetResourceIdByName(GetBombExplode().c_str())->id;
x30_powerBombExplode = factory.GetResourceIdByName(GetPowerBombExplode().c_str())->id;
for (int i=0 ; i<5 ; ++i)
for (int j=0 ; j<2 ; ++j)
x34_weapons[i][j] = factory.GetResourceIdByName(GetWeapon(i, j).c_str())->id;
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 2; ++j)
x34_weapons[i][j] = factory.GetResourceIdByName(GetWeapon(i, j).c_str())->id;
for (int i=0 ; i<5 ; ++i)
x84_muzzle[i] = factory.GetResourceIdByName(GetMuzzleParticle(i).c_str())->id;
for (int i = 0; i < 5; ++i)
x84_muzzle[i] = factory.GetResourceIdByName(GetMuzzleParticle(i).c_str())->id;
for (int i=0 ; i<5 ; ++i)
x94_charge[i] = factory.GetResourceIdByName(GetChargeParticle(i).c_str())->id;
for (int i = 0; i < 5; ++i)
x94_charge[i] = factory.GetResourceIdByName(GetChargeParticle(i).c_str())->id;
for (int i=0 ; i<5 ; ++i)
xa4_auxMuzzle[i] = factory.GetResourceIdByName(GetAuxMuzzleParticle(i).c_str())->id;
for (int i = 0; i < 5; ++i)
xa4_auxMuzzle[i] = factory.GetResourceIdByName(GetAuxMuzzleParticle(i).c_str())->id;
xb4_grappleSegment = factory.GetResourceIdByName(GetGrappleSegmentParticle().c_str())->id;
xb8_grappleClaw = factory.GetResourceIdByName(GetGrappleClawParticle().c_str())->id;
xbc_grappleHit = factory.GetResourceIdByName(GetGrappleHitParticle().c_str())->id;
xc0_grappleMuzzle = factory.GetResourceIdByName(GetGrappleMuzzleParticle().c_str())->id;
xc4_grappleSwoosh = factory.GetResourceIdByName(GetGrappleSwooshParticle().c_str())->id;
}
xb4_grappleSegment = factory.GetResourceIdByName(GetGrappleSegmentParticle().c_str())->id;
xb8_grappleClaw = factory.GetResourceIdByName(GetGrappleClawParticle().c_str())->id;
xbc_grappleHit = factory.GetResourceIdByName(GetGrappleHitParticle().c_str())->id;
xc0_grappleMuzzle = factory.GetResourceIdByName(GetGrappleMuzzleParticle().c_str())->id;
xc4_grappleSwoosh = factory.GetResourceIdByName(GetGrappleSwooshParticle().c_str())->id;
}
protected:
virtual const std::string& GetGunMotion() const=0;
virtual const std::string& GetGrappleArm() const=0;
virtual const std::string& GetRightHand() const=0;
virtual const std::string& GetGunMotion() const = 0;
virtual const std::string& GetGrappleArm() const = 0;
virtual const std::string& GetRightHand() const = 0;
virtual const std::string& GetPowerBeam() const=0;
virtual const std::string& GetIceBeam() const=0;
virtual const std::string& GetWaveBeam() const=0;
virtual const std::string& GetPlasmaBeam() const=0;
virtual const std::string& GetPhazonBeam() const=0;
virtual const std::string& GetPowerBeam() const = 0;
virtual const std::string& GetIceBeam() const = 0;
virtual const std::string& GetWaveBeam() const = 0;
virtual const std::string& GetPlasmaBeam() 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& GetBombExplode() const=0;
virtual const std::string& GetPowerBombExplode() const=0;
virtual const std::string& GetBombSet() const = 0;
virtual const std::string& GetBombExplode() 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& GetMuzzleParticle(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& GetWeapon(size_t idx, bool ball) 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& GetAuxMuzzleParticle(size_t idx) const = 0;
virtual const std::string& GetGrappleSegmentParticle() const=0;
virtual const std::string& GetGrappleClawParticle() const=0;
virtual const std::string& GetGrappleHitParticle() const=0;
virtual const std::string& GetGrappleMuzzleParticle() const=0;
virtual const std::string& GetGrappleSwooshParticle() const=0;
virtual const std::string& GetGrappleSegmentParticle() const = 0;
virtual const std::string& GetGrappleClawParticle() const = 0;
virtual const std::string& GetGrappleHitParticle() const = 0;
virtual const std::string& GetGrappleMuzzleParticle() const = 0;
virtual const std::string& GetGrappleSwooshParticle() const = 0;
};
}
} // namespace DataSpec

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,36 +2,31 @@
#include "../PAK.hpp"
namespace DataSpec
{
namespace DataSpec {
template <class T>
bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
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;
}
bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
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;
}
} // namespace DataSpec

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -4,56 +4,48 @@
#include "DataSpec/DNACommon/DNACommon.hpp"
#include "DNAMP1.hpp"
namespace DataSpec::DNAMP1
{
struct AFSM : public BigDNA
{
namespace DataSpec::DNAMP1 {
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
Value<atUint32> stateCount;
Vector<String<-1>, AT_DNA_COUNT(stateCount)> stateNames;
Value<atUint32> triggerCount;
Value<atUint32> transitionCount;
struct Transition : public BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
Value<atUint32> triggerCount;
struct State : public BigDNA
{
AT_DECL_DNA_YAML
Value<atUint32> transitionCount;
struct Transition : public BigDNA
{
AT_DECL_EXPLICIT_DNA_YAML
Value<atUint32> triggerCount;
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;
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<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)
{
AFSM afsm;
afsm.read(rs);
athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::ToYAMLStream(afsm, writer);
return true;
}
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
AFSM afsm;
afsm.read(rs);
athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::ToYAMLStream(afsm, writer);
return true;
}
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath)
{
AFSM afsm;
athena::io::FileReader reader(inPath.getAbsolutePath());
athena::io::FromYAMLStream(afsm, reader);
athena::io::FileWriter ws(outPath.getAbsolutePath());
afsm.write(ws);
return true;
}
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
AFSM afsm;
athena::io::FileReader reader(inPath.getAbsolutePath());
athena::io::FromYAMLStream(afsm, reader);
athena::io::FileWriter ws(outPath.getAbsolutePath());
afsm.write(ws);
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 test_H[];
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
using namespace std::literals;
static const std::pair<std::string_view, const uint8_t*> Headers[] =
{
{"Atomic"sv, Atomic_H},
{"BetaBeetle"sv, BetaBeetle_H},
{"Bird"sv, Bird_H},
{"BloodFlower"sv, BloodFlower_H},
{"Burrower"sv, Burrower_H},
{"ChozoGhost"sv, ChozoGhost_H},
{"ChubbWeed"sv, ChubbWeed_H},
{"CineBoots"sv, CineBoots_H},
{"CineGeneral"sv, CineGeneral_H},
{"CineGun"sv, CineGun_H},
{"CineMorphball"sv, CineMorphball_H},
{"CineSuit"sv, CineSuit_H},
{"CineVisor"sv, CineVisor_H},
{"Crater"sv, Crater_H},
{"Crystallite"sv, Crystallite_H},
{"Drones"sv, Drones_H},
{"EliteSpacePirate"sv, EliteSpacePirate_H},
{"FireFlea"sv, FireFlea_H},
{"Flaaghra"sv, Flaaghra_H},
{"FlickerBat"sv, FlickerBat_H},
{"FlyingPirate"sv, FlyingPirate_H},
{"FrontEnd"sv, FrontEnd_H},
{"GagantuanBeatle"sv, GagantuanBeatle_H},
{"Gnats"sv, Gnats_H},
{"Gryzbee"sv, Gryzbee_H},
{"IceCrack"sv, IceCrack_H},
{"IceWorld"sv, IceWorld_H},
{"InjuredPirates"sv, InjuredPirates_H},
{"IntroBoss"sv, IntroBoss_H},
{"IntroWorld"sv, IntroWorld_H},
{"JellyZap"sv, JellyZap_H},
{"LavaWorld"sv, LavaWorld_H},
{"Magdolite"sv, Magdolite_H},
{"Metaree"sv, Metaree_H},
{"MetroidPrime"sv, MetroidPrime_H},
{"Metroid"sv, Metroid_H},
{"MinesWorld"sv, MinesWorld_H},
{"MiscSamus"sv, MiscSamus_H},
{"Misc"sv, Misc_H},
{"OmegaPirate"sv, OmegaPirate_H},
{"OverWorld"sv, OverWorld_H},
{"Parasite"sv, Parasite_H},
{"PhazonGun"sv, PhazonGun_H},
{"Phazon"sv, Phazon_H},
{"PuddleSpore"sv, PuddleSpore_H},
{"PuddleToad"sv, PuddleToad_H},
{"Puffer"sv, Puffer_H},
{"ReactorDoor"sv, ReactorDoor_H},
{"Ridley"sv, Ridley_H},
{"Ripper"sv, Ripper_H},
{"RuinsWorld"sv, RuinsWorld_H},
{"SamusShip"sv, SamusShip_H},
{"Scarab"sv, Scarab_H},
{"Seedling"sv, Seedling_H},
{"SheeGoth"sv, SheeGoth_H},
{"SnakeWeed"sv, SnakeWeed_H},
{"Sova"sv, Sova_H},
{"SpacePirate"sv, SpacePirate_H},
{"SpankWeed"sv, SpankWeed_H},
{"Thardus"sv, Thardus_H},
{"TheEnd"sv, TheEnd_H},
{"Torobyte"sv, Torobyte_H},
{"Triclops"sv, Triclops_H},
{"Turret"sv, Turret_H},
{"UI"sv, UI_H},
{"WarWasp"sv, WarWasp_H},
{"Weapons"sv, Weapons_H},
{"ZZZ"sv, ZZZ_H},
{"Zoomer"sv, Zoomer_H},
{"lumigek"sv, lumigek_H},
{"test"sv, test_H}
};
static const std::pair<std::string_view, const uint8_t*> Headers[] = {{"Atomic"sv, Atomic_H},
{"BetaBeetle"sv, BetaBeetle_H},
{"Bird"sv, Bird_H},
{"BloodFlower"sv, BloodFlower_H},
{"Burrower"sv, Burrower_H},
{"ChozoGhost"sv, ChozoGhost_H},
{"ChubbWeed"sv, ChubbWeed_H},
{"CineBoots"sv, CineBoots_H},
{"CineGeneral"sv, CineGeneral_H},
{"CineGun"sv, CineGun_H},
{"CineMorphball"sv, CineMorphball_H},
{"CineSuit"sv, CineSuit_H},
{"CineVisor"sv, CineVisor_H},
{"Crater"sv, Crater_H},
{"Crystallite"sv, Crystallite_H},
{"Drones"sv, Drones_H},
{"EliteSpacePirate"sv, EliteSpacePirate_H},
{"FireFlea"sv, FireFlea_H},
{"Flaaghra"sv, Flaaghra_H},
{"FlickerBat"sv, FlickerBat_H},
{"FlyingPirate"sv, FlyingPirate_H},
{"FrontEnd"sv, FrontEnd_H},
{"GagantuanBeatle"sv, GagantuanBeatle_H},
{"Gnats"sv, Gnats_H},
{"Gryzbee"sv, Gryzbee_H},
{"IceCrack"sv, IceCrack_H},
{"IceWorld"sv, IceWorld_H},
{"InjuredPirates"sv, InjuredPirates_H},
{"IntroBoss"sv, IntroBoss_H},
{"IntroWorld"sv, IntroWorld_H},
{"JellyZap"sv, JellyZap_H},
{"LavaWorld"sv, LavaWorld_H},
{"Magdolite"sv, Magdolite_H},
{"Metaree"sv, Metaree_H},
{"MetroidPrime"sv, MetroidPrime_H},
{"Metroid"sv, Metroid_H},
{"MinesWorld"sv, MinesWorld_H},
{"MiscSamus"sv, MiscSamus_H},
{"Misc"sv, Misc_H},
{"OmegaPirate"sv, OmegaPirate_H},
{"OverWorld"sv, OverWorld_H},
{"Parasite"sv, Parasite_H},
{"PhazonGun"sv, PhazonGun_H},
{"Phazon"sv, Phazon_H},
{"PuddleSpore"sv, PuddleSpore_H},
{"PuddleToad"sv, PuddleToad_H},
{"Puffer"sv, Puffer_H},
{"ReactorDoor"sv, ReactorDoor_H},
{"Ridley"sv, Ridley_H},
{"Ripper"sv, Ripper_H},
{"RuinsWorld"sv, RuinsWorld_H},
{"SamusShip"sv, SamusShip_H},
{"Scarab"sv, Scarab_H},
{"Seedling"sv, Seedling_H},
{"SheeGoth"sv, SheeGoth_H},
{"SnakeWeed"sv, SnakeWeed_H},
{"Sova"sv, Sova_H},
{"SpacePirate"sv, SpacePirate_H},
{"SpankWeed"sv, SpankWeed_H},
{"Thardus"sv, Thardus_H},
{"TheEnd"sv, TheEnd_H},
{"Torobyte"sv, Torobyte_H},
{"Triclops"sv, Triclops_H},
{"Turret"sv, Turret_H},
{"UI"sv, UI_H},
{"WarWasp"sv, WarWasp_H},
{"Weapons"sv, Weapons_H},
{"ZZZ"sv, ZZZ_H},
{"Zoomer"sv, Zoomer_H},
{"lumigek"sv, lumigek_H},
{"test"sv, test_H}};
bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir)
{
dir.makeDirChain(true);
bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) {
dir.makeDirChain(true);
Header head;
head.read(rs);
Header head;
head.read(rs);
uint32_t poolLen = rs.readUint32Big();
auto pool = rs.readUBytes(poolLen);
uint32_t poolLen = rs.readUint32Big();
auto pool = rs.readUBytes(poolLen);
uint32_t projLen = rs.readUint32Big();
auto proj = rs.readUBytes(projLen);
uint32_t projLen = rs.readUint32Big();
auto proj = rs.readUBytes(projLen);
uint32_t sampLen = rs.readUint32Big();
auto samp = rs.readUBytes(sampLen);
uint32_t sampLen = rs.readUint32Big();
auto samp = rs.readUBytes(sampLen);
uint32_t sdirLen = rs.readUint32Big();
auto sdir = rs.readUBytes(sdirLen);
uint32_t sdirLen = rs.readUint32Big();
auto sdir = rs.readUBytes(sdirLen);
amuse::AudioGroupData data(proj.get(), projLen, pool.get(), poolLen,
sdir.get(), sdirLen, samp.get(), sampLen, amuse::GCNDataTag{});
amuse::AudioGroupData data(proj.get(), projLen, pool.get(), poolLen, sdir.get(), sdirLen, samp.get(), sampLen,
amuse::GCNDataTag{});
/* Load into amuse representation */
amuse::ProjectDatabase projDb;
projDb.setIdDatabases();
amuse::AudioGroupDatabase group(data);
group.setGroupPath(dir.getAbsolutePath());
/* Load into amuse representation */
amuse::ProjectDatabase projDb;
projDb.setIdDatabases();
amuse::AudioGroupDatabase group(data);
group.setGroupPath(dir.getAbsolutePath());
/* Extract samples */
group.getSdir().extractAllCompressed(dir.getAbsolutePath(), data.getSamp());
/* Extract samples */
group.getSdir().extractAllCompressed(dir.getAbsolutePath(), data.getSamp());
/* Import C headers */
auto lastComp = dir.getLastComponentUTF8();
auto search = std::lower_bound(std::cbegin(Headers), std::cend(Headers), lastComp,
[](const auto& a, const auto& b) { return a.first < b; });
if (search != std::cend(Headers) && search->first == lastComp)
group.importCHeader((char*)search->second);
/* Import C headers */
auto lastComp = dir.getLastComponentUTF8();
auto search = std::lower_bound(std::cbegin(Headers), std::cend(Headers), lastComp,
[](const auto& a, const auto& b) { return a.first < b; });
if (search != std::cend(Headers) && search->first == lastComp)
group.importCHeader((char*)search->second);
/* Write out project/pool */
{
auto projd = group.getProj().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!project.yaml")).getAbsolutePath());
if (fo.hasError())
return false;
fo.writeUBytes(projd.data(), projd.size());
}
/* Write out project/pool */
{
auto projd = group.getProj().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!project.yaml")).getAbsolutePath());
if (fo.hasError())
return false;
fo.writeUBytes(projd.data(), projd.size());
}
{
auto poold = group.getPool().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!pool.yaml")).getAbsolutePath());
if (fo.hasError())
return false;
fo.writeUBytes(poold.data(), poold.size());
}
{
auto poold = group.getPool().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!pool.yaml")).getAbsolutePath());
if (fo.hasError())
return false;
fo.writeUBytes(poold.data(), poold.size());
}
return true;
return true;
}
bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter w(outPath.getAbsolutePath());
if (w.hasError())
return false;
bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath());
if (w.hasError())
return false;
Header head;
head.audioDir = "Audio/"sv;
head.groupName = dir.getLastComponentUTF8();
head.write(w);
Header head;
head.audioDir = "Audio/"sv;
head.groupName = dir.getLastComponentUTF8();
head.write(w);
amuse::ProjectDatabase projDb;
projDb.setIdDatabases();
amuse::AudioGroupDatabase group(dir.getAbsolutePath());
amuse::ProjectDatabase projDb;
projDb.setIdDatabases();
amuse::AudioGroupDatabase group(dir.getAbsolutePath());
auto proj = group.getProj().toGCNData(group.getPool(), group.getSdir());
auto pool = group.getPool().toData<athena::Big>();
auto sdirSamp = group.getSdir().toGCNData(group);
auto proj = group.getProj().toGCNData(group.getPool(), group.getSdir());
auto pool = group.getPool().toData<athena::Big>();
auto sdirSamp = group.getSdir().toGCNData(group);
w.writeUint32Big(pool.size());
w.writeUBytes(pool.data(), pool.size());
w.writeUint32Big(pool.size());
w.writeUBytes(pool.data(), pool.size());
w.writeUint32Big(proj.size());
w.writeUBytes(proj.data(), proj.size());
w.writeUint32Big(proj.size());
w.writeUBytes(proj.data(), proj.size());
w.writeUint32Big(sdirSamp.second.size());
w.writeUBytes(sdirSamp.second.data(), sdirSamp.second.size());
w.writeUint32Big(sdirSamp.second.size());
w.writeUBytes(sdirSamp.second.data(), sdirSamp.second.size());
w.writeUint32Big(sdirSamp.first.size());
w.writeUBytes(sdirSamp.first.data(), sdirSamp.first.size());
w.writeUint32Big(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 "DNAMP1.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
class AGSC
{
class AGSC {
public:
struct Header : BigDNA
{
AT_DECL_DNA
String<-1> audioDir;
String<-1> groupName;
};
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
struct Header : BigDNA {
AT_DECL_DNA
String<-1> audioDir;
String<-1> groupName;
};
static bool Extract(PAKEntryReadStream& rs, 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 "athena/FileReader.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
struct ANCS : BigDNA
{
using CINFType = CINF;
using CSKRType = CSKR;
using ANIMType = ANIM;
struct ANCS : BigDNA {
using CINFType = CINF;
using CSKRType = CSKR;
using ANIMType = ANIM;
AT_DECL_DNA_YAML
Value<atUint16> version;
struct CharacterSet : BigDNA {
AT_DECL_DNA_YAML
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
Value<atUint16> version;
Value<atUint32> characterCount;
struct CharacterInfo : BigDNA
{
AT_DECL_DNA_YAML
Delete expl;
Value<atUint32> animIdx;
String<-1> strA;
String<-1> strB;
};
std::vector<Animation> animations;
atUint32 idx;
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
{
struct PASDatabase : BigDNA {
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 IMetaAnim : BigDNAVYaml
{
struct ParmInfo : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
enum class Type
{
Primitive = 0,
Blend = 1,
PhaseBlend = 2,
Random = 3,
Sequence = 4
} m_type;
const char* m_typeStr;
IMetaAnim(Type type, const char* typeStr)
: m_type(type), m_typeStr(typeStr) {}
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;
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) {}
};
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);
}
atUint32 parmType;
atUint32 weightFunction;
float weight;
Parm range[2];
};
std::vector<ParmInfo> parmInfos;
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 AnimInfo {
atUint32 id;
std::vector<ParmInfo::Parm> parmVals;
};
std::vector<AnimInfo> animInfos;
};
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;
Vector<AnimState, AT_DNA_COUNT(animStateCount)> animStates;
} pasDatabase;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{
for (const auto& child : children)
child.m_anim->gatherPrimitives(pakRouter, out);
}
struct ParticleResData {
std::vector<UniqueID32> part;
std::vector<UniqueID32> swhc;
std::vector<UniqueID32> unk;
std::vector<UniqueID32> elsc;
} partResData;
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
for (auto& child : children)
if (!child.m_anim->enumeratePrimitives(func))
return false;
return true;
}
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;
struct Animation : BigDNA
{
AT_DECL_DNA_YAML
String<-1> name;
MetaAnimFactory metaAnim;
};
std::vector<Animation> animations;
UniqueID32Zero cmdlIce;
UniqueID32Zero cskrIce;
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;
std::vector<atUint32> animIdxs;
};
Vector<CharacterInfo, AT_DNA_COUNT(characterCount)> characters;
} characterSet;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{
anim.m_anim->gatherPrimitives(pakRouter, out);
}
struct AnimationSet : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
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 MetaAnimPrimitive;
struct IMetaAnim : BigDNAVYaml {
Delete expl;
enum class Type { Primitive = 0, Blend = 1, PhaseBlend = 2, Random = 3, Sequence = 4 } m_type;
const char* m_typeStr;
IMetaAnim(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {}
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") {}
struct Transition : BigDNA
{
AT_DECL_DNA_YAML
Value<atUint32> unk;
Value<atUint32> animIdxA;
Value<atUint32> animIdxB;
MetaTransFactory metaTrans;
};
std::vector<Transition> transitions;
MetaTransFactory defaultTransition;
UniqueID32 animId;
Value<atUint32> animIdx;
String<-1> animName;
Value<float> unk1;
Value<atUint32> unk2;
struct AdditiveAnimationInfo : BigDNA
{
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
Value<float> unk1;
Value<float> unk2;
};
std::vector<AdditiveAnimationInfo> additiveAnims;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out);
float floatA = 0.0;
float floatB = 0.0;
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;
struct HalfTransition : BigDNA
{
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
MetaTransFactory metaTrans;
};
std::vector<HalfTransition> halfTransitions;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
animA.m_anim->gatherPrimitives(pakRouter, out);
animB.m_anim->gatherPrimitives(pakRouter, out);
}
struct AnimationResources : BigDNA
{
AT_DECL_DNA_YAML
UniqueID32 animId;
UniqueID32 evntId;
};
std::vector<AnimationResources> animResources;
} animationSet;
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 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;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
animA.m_anim->gatherPrimitives(pakRouter, out);
animB.m_anim->gatherPrimitives(pakRouter, out);
}
if (ci.cmdlIce)
chOut.overlays.emplace_back("ICE", std::make_pair(ci.cmdlIce, ci.cskrIce));
}
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,
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,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) const
{
out.clear();
for (const AnimationSet::Animation& ai : animationSet.animations)
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
anim->gatherPrimitives(pakRouter, out);
for (const AnimationSet::Transition& ti : animationSet.transitions)
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
trans->gatherPrimitives(pakRouter, out);
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
trans->gatherPrimitives(pakRouter, out);
}
void getAnimationResInfo(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) const {
out.clear();
for (const AnimationSet::Animation& ai : animationSet.animations)
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
anim->gatherPrimitives(pakRouter, out);
for (const AnimationSet::Transition& ti : animationSet.transitions)
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
trans->gatherPrimitives(pakRouter, out);
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
trans->gatherPrimitives(pakRouter, out);
}
void enumeratePrimitives(const std::function<bool(AnimationSet::MetaAnimPrimitive& prim)>& func)
{
for (const AnimationSet::Animation& ai : animationSet.animations)
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
anim->enumeratePrimitives(func);
for (const AnimationSet::Transition& ti : animationSet.transitions)
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
trans->enumeratePrimitives(func);
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
trans->enumeratePrimitives(func);
}
void enumeratePrimitives(const std::function<bool(AnimationSet::MetaAnimPrimitive& prim)>& func) {
for (const AnimationSet::Animation& ai : animationSet.animations)
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
anim->enumeratePrimitives(func);
for (const AnimationSet::Transition& ti : animationSet.transitions)
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
trans->enumeratePrimitives(func);
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
trans->enumeratePrimitives(func);
}
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, int charIdx) const
{
auto doCi = [&](const CharacterSet::CharacterInfo& ci)
{
for (const auto& id : ci.partResData.part)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.swhc)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.unk)
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)
doCi(ci);
else if (charIdx < characterSet.characters.size())
doCi(characterSet.characters[charIdx]);
}
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, int charIdx) const {
auto doCi = [&](const CharacterSet::CharacterInfo& ci) {
for (const auto& id : ci.partResData.part)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.swhc)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.unk)
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)
doCi(ci);
else if (charIdx < characterSet.characters.size())
doCi(characterSet.characters[charIdx]);
}
static bool Extract(const SpecBase& dataSpec,
PAKEntryReadStream& rs,
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 bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, 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 bool Cook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor);
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor);
static bool CookCINF(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor);
static bool CookCINF(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor);
static bool CookCSKR(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor,
static bool CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
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 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,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor,
hecl::blender::DataStream& ds,
bool pc);
static bool CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, 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 "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_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
{
Delete expl;
atUint32 m_version;
IANIM(atUint32 version) : m_version(version) {}
struct ANIM2 : IANIM {
AT_DECL_EXPLICIT_DNA
AT_DECL_DNAV
ANIM2(bool pc) : IANIM(pc ? 3 : 2) {}
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 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 ANIM0 : IANIM
{
AT_DECL_EXPLICIT_DNA
AT_DECL_DNAV
ANIM0() : IANIM(0) {}
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;
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 ANIM2 : IANIM
{
AT_DECL_EXPLICIT_DNA
AT_DECL_DNAV
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 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);
}
}
}
}
using BlenderAction = hecl::blender::Action;
using BlenderAction = hecl::blender::Action;
ANIM() = default;
ANIM(const BlenderAction& act,
const std::unordered_map<std::string, atInt32>& idMap,
const DNAANIM::RigInverter<CINF>& rig,
bool pc);
ANIM() = default;
ANIM(const BlenderAction& act, const std::unordered_map<std::string, atInt32>& idMap,
const DNAANIM::RigInverter<CINF>& rig, bool pc);
};
}
} // namespace DataSpec::DNAMP1

View File

@ -1,184 +1,160 @@
#include "CINF.hpp"
#include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const
{
atUint32 idx = 0;
for (const Bone& b : bones)
{
if (b.id == id)
return idx;
++idx;
atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const {
atUint32 idx = 0;
for (const Bone& b : bones) {
if (b.id == id)
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
{
atUint32 idx = 0;
for (atUint32 bid : boneIds)
{
if (bid == id)
return idx;
++idx;
}
return 0;
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);
}
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;
}
}
}
}
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());
}
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,
std::unordered_map<std::string, atInt32>& idMap, std::map<std::string, int>& nameMap)
{
int selId;
auto search = idMap.find(bone->name);
if (search == idMap.end())
{
selId = curId++;
idMap.emplace(std::make_pair(bone->name, selId));
std::unordered_map<std::string, atInt32>& idMap,
std::map<std::string, int>& nameMap) {
int selId;
auto search = idMap.find(bone->name);
if (search == idMap.end()) {
selId = curId++;
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();
Bone& boneOut = bones.back();
nameMap[bone->name] = selId;
boneOut.id = selId;
boneOut.parentId = parent;
nameMap[bone->name] = 3;
boneOut.id = 3;
boneOut.parentId = 2;
boneOut.origin = bone->origin;
boneOut.linkedCount = bone->children.size() + 1;
boneOut.linked.reserve(boneOut.linkedCount);
idMap.emplace(std::make_pair(bone->name, 3));
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);
}
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};
}
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());
nameCount = nameMap.size();
for (const auto& name : nameMap)
{
names.emplace_back();
Name& nameOut = names.back();
nameOut.name = name.first;
nameOut.boneId = name.second;
}
names.reserve(nameMap.size());
nameCount = nameMap.size();
for (const auto& name : nameMap) {
names.emplace_back();
Name& nameOut = names.back();
nameOut.name = name.first;
nameOut.boneId = name.second;
}
boneIdCount = boneCount;
boneIds.reserve(boneIdCount);
for (auto it=bones.crbegin() ; it != bones.crend() ; ++it)
boneIds.push_back(it->id);
boneIdCount = boneCount;
boneIds.reserve(boneIdCount);
for (auto it = bones.crbegin(); it != bones.crend(); ++it)
boneIds.push_back(it->id);
}
}
} // namespace DataSpec::DNAMP1

View File

@ -3,52 +3,47 @@
#include "DataSpec/DNACommon/DNACommon.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
Value<atUint32> boneCount;
struct Bone : BigDNA
{
AT_DECL_DNA
Value<atUint32> id;
Value<atUint32> parentId;
Value<atVec3f> origin;
Value<atUint32> linkedCount;
Vector<atUint32, AT_DNA_COUNT(linkedCount)> linked;
};
Vector<Bone, AT_DNA_COUNT(boneCount)> bones;
Value<atUint32> id;
Value<atUint32> parentId;
Value<atVec3f> origin;
Value<atUint32> linkedCount;
Vector<atUint32, AT_DNA_COUNT(linkedCount)> linked;
};
Vector<Bone, AT_DNA_COUNT(boneCount)> bones;
Value<atUint32> boneIdCount;
Vector<atUint32, AT_DNA_COUNT(boneIdCount)> boneIds;
Value<atUint32> boneIdCount;
Vector<atUint32, AT_DNA_COUNT(boneIdCount)> boneIds;
Value<atUint32> nameCount;
struct Name : BigDNA
{
AT_DECL_DNA
String<-1> name;
Value<atUint32> boneId;
};
Vector<Name, AT_DNA_COUNT(nameCount)> names;
Value<atUint32> nameCount;
struct Name : BigDNA {
AT_DECL_DNA
String<-1> name;
Value<atUint32> boneId;
};
Vector<Name, AT_DNA_COUNT(nameCount)> names;
atUint32 getInternalBoneIdxFromId(atUint32 id) const;
atUint32 getBoneIdxFromId(atUint32 id) const;
const std::string* getBoneNameFromId(atUint32 id) const;
void sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const;
void sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const;
static std::string GetCINFArmatureName(const UniqueID32& cinfId);
atUint32 getInternalBoneIdxFromId(atUint32 id) const;
atUint32 getBoneIdxFromId(atUint32 id) const;
const std::string* getBoneNameFromId(atUint32 id) const;
void sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const;
void sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const;
static std::string GetCINFArmatureName(const UniqueID32& cinfId);
CINF() = default;
using Armature = hecl::blender::Armature;
using BlenderBone = hecl::blender::Bone;
CINF() = default;
using Armature = hecl::blender::Armature;
using BlenderBone = hecl::blender::Bone;
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);
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);
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 "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
bool CMDL::Extract(const SpecBase& dataSpec,
PAKEntryReadStream& rs,
const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry,
bool force,
hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged)
{
/* Check for RigPair */
const typename CharacterAssociations<UniqueID32>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
CINF cinf;
CSKR cskr;
std::pair<CSKR*,CINF*> loadRp(nullptr, nullptr);
if (rp)
{
pakRouter.lookupAndReadDNA(rp->first, cskr);
pakRouter.lookupAndReadDNA(rp->second, cinf);
loadRp.first = &cskr;
loadRp.second = &cinf;
}
bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
/* Check for RigPair */
const typename CharacterAssociations<UniqueID32>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
CINF cinf;
CSKR cskr;
std::pair<CSKR*, CINF*> loadRp(nullptr, nullptr);
if (rp) {
pakRouter.lookupAndReadDNA(rp->first, cskr);
pakRouter.lookupAndReadDNA(rp->second, cinf);
loadRp.first = &cskr;
loadRp.second = &cinf;
}
/* Do extract */
hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh))
return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_1, 2>
(conn, rs, pakRouter, entry, dataSpec, loadRp);
conn.saveBlend();
/* Do extract */
hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh))
return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*, CINF*>, DNACMDL::SurfaceHeader_1, 2>(
conn, rs, pakRouter, entry, dataSpec, loadRp);
conn.saveBlend();
#if 0
/* Cook and re-extract test */
@ -50,98 +42,82 @@ bool CMDL::Extract(const SpecBase& dataSpec,
(conn, reader, pakRouter, entry, dataSpec, loadRp);
return conn.saveBlend();
#elif 0
/* HMDL cook test */
hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true);
hecl::blender::Connection::DataStream ds = conn.beginData();
DNACMDL::Mesh mesh = ds.compileMesh(hecl::HMDLTopology::TriStrips, 16);
ds.close();
DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_1, 2>(tempOut, outPath, mesh);
/* HMDL cook test */
hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true);
hecl::blender::Connection::DataStream ds = conn.beginData();
DNACMDL::Mesh mesh = ds.compileMesh(hecl::HMDLTopology::TriStrips, 16);
ds.close();
DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_1, 2>(tempOut, outPath, mesh);
#endif
return true;
return true;
}
bool CMDL::Cook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNACMDL::Mesh& mesh)
{
if (!mesh.skins.empty())
{
DNACMDL::Mesh skinMesh = mesh.getContiguousSkinningVersion();
if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, skinMesh))
return false;
bool CMDL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh) {
if (!mesh.skins.empty()) {
DNACMDL::Mesh skinMesh = mesh.getContiguousSkinningVersion();
if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, skinMesh))
return false;
/* Output skinning intermediate */
auto vertCountIt = skinMesh.contiguousSkinVertCounts.cbegin();
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath());
writer.writeUint32Big(skinMesh.boneNames.size());
for (const std::string& boneName : skinMesh.boneNames)
writer.writeString(boneName);
/* Output skinning intermediate */
auto vertCountIt = skinMesh.contiguousSkinVertCounts.cbegin();
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath());
writer.writeUint32Big(skinMesh.boneNames.size());
for (const std::string& boneName : skinMesh.boneNames)
writer.writeString(boneName);
writer.writeUint32Big(skinMesh.skins.size());
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins)
{
writer.writeUint32Big(skin.size());
for (const DNACMDL::Mesh::SkinBind& bind : skin)
{
writer.writeUint32Big(bind.boneIdx);
writer.writeFloatBig(bind.weight);
}
writer.writeUint32Big(*vertCountIt++);
}
writer.writeUint32Big(skinMesh.pos.size());
writer.writeUint32Big(skinMesh.norm.size());
writer.writeUint32Big(skinMesh.skins.size());
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins) {
writer.writeUint32Big(skin.size());
for (const DNACMDL::Mesh::SkinBind& bind : skin) {
writer.writeUint32Big(bind.boneIdx);
writer.writeFloatBig(bind.weight);
}
writer.writeUint32Big(*vertCountIt++);
}
else if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, mesh))
return false;
return true;
writer.writeUint32Big(skinMesh.pos.size());
writer.writeUint32Big(skinMesh.norm.size());
} else if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, mesh))
return false;
return true;
}
bool CMDL::HMDLCook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNACMDL::Mesh& mesh)
{
hecl::blender::PoolSkinIndex poolSkinIndex;
if (mesh.skins.size())
{
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(
outPath, inPath, mesh, poolSkinIndex))
return false;
bool CMDL::HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh) {
hecl::blender::PoolSkinIndex poolSkinIndex;
if (mesh.skins.size()) {
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(outPath, inPath, mesh, poolSkinIndex))
return false;
/* Output skinning intermediate */
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath());
writer.writeUint32Big(mesh.skinBanks.banks.size());
for (const DNACMDL::Mesh::SkinBanks::Bank& sb : mesh.skinBanks.banks)
{
writer.writeUint32Big(sb.m_boneIdxs.size());
for (uint32_t bind : sb.m_boneIdxs)
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]);
/* Output skinning intermediate */
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath());
writer.writeUint32Big(mesh.skinBanks.banks.size());
for (const DNACMDL::Mesh::SkinBanks::Bank& sb : mesh.skinBanks.banks) {
writer.writeUint32Big(sb.m_boneIdxs.size());
for (uint32_t bind : sb.m_boneIdxs)
writer.writeUint32Big(bind);
}
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(
outPath, inPath, mesh, poolSkinIndex))
return false;
return true;
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>(outPath, inPath, mesh,
poolSkinIndex))
return false;
return true;
}
}
} // namespace DataSpec::DNAMP1

View File

@ -9,36 +9,21 @@
#include <athena/FileReader.hpp>
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
struct CMDL
{
static bool Extract(const SpecBase& dataSpec,
PAKEntryReadStream& rs,
const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry,
bool force,
hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
struct CMDL {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, 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,
PAKEntryReadStream& rs,
PAKRouter<PAKBridge>& pakRouter,
PAK::Entry& entry)
{
DNACMDL::NameCMDL<PAKRouter<PAKBridge>, MaterialSet>(rs, pakRouter, entry, dataSpec);
}
static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter<PAKBridge>& pakRouter,
PAK::Entry& entry) {
DNACMDL::NameCMDL<PAKRouter<PAKBridge>, MaterialSet>(rs, pakRouter, entry, dataSpec);
}
static bool Cook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNACMDL::Mesh& mesh);
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh);
static bool HMDLCook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNACMDL::Mesh& mesh);
static bool HMDLCook(const hecl::ProjectPath& outPath, 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 "DNAMP1.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
struct MaterialSet : BigDNA
{
static constexpr bool OneSection() {return false;}
struct MaterialSet : BigDNA {
static constexpr bool OneSection() { return false; }
AT_DECL_DNA
struct MaterialSetHead : BigDNA {
AT_DECL_DNA
struct MaterialSetHead : BigDNA
{
AT_DECL_DNA
Value<atUint32> textureCount = 0;
Vector<UniqueID32, AT_DNA_COUNT(textureCount)> textureIDs;
Value<atUint32> materialCount = 0;
Vector<atUint32, AT_DNA_COUNT(materialCount)> materialEndOffs;
Value<atUint32> textureCount = 0;
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 addMaterialEndOff(atUint32 off) {materialEndOffs.push_back(off); ++materialCount;}
void addTexture(const UniqueID32& id) {
textureIDs.push_back(id);
++textureCount;
}
void addMaterialEndOff(atUint32 off) {
materialEndOffs.push_back(off);
++materialCount;
}
template <class PAKBRIDGE>
void ensureTexturesExtracted(PAKRouter<PAKBRIDGE>& pakRouter) const
{
for (const auto& id : textureIDs)
{
const nod::Node* node;
const PAK::Entry* texEntry = pakRouter.lookupEntry(id, &node);
if (!texEntry)
continue;
hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (txtrPath.isNone())
{
txtrPath.makeDirChain(false);
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath);
}
}
template <class PAKBRIDGE>
void ensureTexturesExtracted(PAKRouter<PAKBRIDGE>& pakRouter) const {
for (const auto& id : textureIDs) {
const nod::Node* node;
const PAK::Entry* texEntry = pakRouter.lookupEntry(id, &node);
if (!texEntry)
continue;
hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (txtrPath.isNone()) {
txtrPath.makeDirChain(false);
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath);
}
} head;
}
}
} head;
struct Material : BigDNA
{
AT_DECL_DNA
struct Flags : BigDNA
{
AT_DECL_DNA
Value<atUint32> flags = 0;
bool konstValuesEnabled() const {return (flags & 0x8) != 0;}
void setKonstValuesEnabled(bool enabled) {flags &= ~0x8; flags |= atUint32(enabled) << 3;}
bool depthSorting() const {return (flags & 0x10) != 0;}
void setDepthSorting(bool enabled) {flags &= ~0x10; flags |= atUint32(enabled) << 4;}
bool alphaTest() const {return (flags & 0x20) != 0;}
void setPunchthroughAlpha(bool enabled) {flags &= ~0x20; flags |= atUint32(enabled) << 5;}
bool samusReflection() const {return (flags & 0x40) != 0;}
void setSamusReflection(bool enabled) {flags &= ~0x40; flags |= atUint32(enabled) << 6;}
bool depthWrite() const {return (flags & 0x80) != 0;}
void setDepthWrite(bool enabled) {flags &= ~0x80; flags |= atUint32(enabled) << 7;}
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;}
struct Material : BigDNA {
AT_DECL_DNA
struct Flags : BigDNA {
AT_DECL_DNA
Value<atUint32> flags = 0;
bool konstValuesEnabled() const { return (flags & 0x8) != 0; }
void setKonstValuesEnabled(bool enabled) {
flags &= ~0x8;
flags |= atUint32(enabled) << 3;
}
bool depthSorting() const { return (flags & 0x10) != 0; }
void setDepthSorting(bool enabled) {
flags &= ~0x10;
flags |= atUint32(enabled) << 4;
}
bool alphaTest() const { return (flags & 0x20) != 0; }
void setPunchthroughAlpha(bool enabled) {
flags &= ~0x20;
flags |= atUint32(enabled) << 5;
}
bool samusReflection() const { return (flags & 0x40) != 0; }
void setSamusReflection(bool enabled) {
flags &= ~0x40;
flags |= atUint32(enabled) << 6;
}
bool depthWrite() const { return (flags & 0x80) != 0; }
void setDepthWrite(bool enabled) {
flags &= ~0x80;
flags |= atUint32(enabled) << 7;
}
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;
Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
struct VAFlags : BigDNA
{
AT_DECL_DNA
Value<atUint32> vaFlags = 0;
GX::AttrType position() const {return GX::AttrType(vaFlags & 0x3);}
void setPosition(GX::AttrType val) {vaFlags &= ~0x3; vaFlags |= atUint32(val);}
GX::AttrType normal() const {return GX::AttrType(vaFlags >> 2 & 0x3);}
void setNormal(GX::AttrType val) {vaFlags &= ~0xC; vaFlags |= atUint32(val) << 2;}
GX::AttrType color0() const {return GX::AttrType(vaFlags >> 4 & 0x3);}
void setColor0(GX::AttrType val) {vaFlags &= ~0x30; vaFlags |= atUint32(val) << 4;}
GX::AttrType color1() const {return GX::AttrType(vaFlags >> 6 & 0x3);}
void setColor1(GX::AttrType val) {vaFlags &= ~0xC0; vaFlags |= atUint32(val) << 6;}
GX::AttrType tex0() const {return GX::AttrType(vaFlags >> 8 & 0x3);}
void setTex0(GX::AttrType val) {vaFlags &= ~0x300; vaFlags |= atUint32(val) << 8;}
GX::AttrType tex1() const {return GX::AttrType(vaFlags >> 10 & 0x3);}
void setTex1(GX::AttrType val) {vaFlags &= ~0xC00; vaFlags |= atUint32(val) << 10;}
GX::AttrType tex2() const {return GX::AttrType(vaFlags >> 12 & 0x3);}
void setTex2(GX::AttrType val) {vaFlags &= ~0x3000; vaFlags |= atUint32(val) << 12;}
GX::AttrType tex3() const {return GX::AttrType(vaFlags >> 14 & 0x3);}
void setTex3(GX::AttrType val) {vaFlags &= ~0xC000; 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;}
Value<atUint32> textureCount = 0;
Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
struct VAFlags : BigDNA {
AT_DECL_DNA
Value<atUint32> vaFlags = 0;
GX::AttrType position() const { return GX::AttrType(vaFlags & 0x3); }
void setPosition(GX::AttrType val) {
vaFlags &= ~0x3;
vaFlags |= atUint32(val);
}
GX::AttrType normal() const { return GX::AttrType(vaFlags >> 2 & 0x3); }
void setNormal(GX::AttrType val) {
vaFlags &= ~0xC;
vaFlags |= atUint32(val) << 2;
}
GX::AttrType color0() const { return GX::AttrType(vaFlags >> 4 & 0x3); }
void setColor0(GX::AttrType val) {
vaFlags &= ~0x30;
vaFlags |= atUint32(val) << 4;
}
GX::AttrType color1() const { return GX::AttrType(vaFlags >> 6 & 0x3); }
void setColor1(GX::AttrType val) {
vaFlags &= ~0xC0;
vaFlags |= atUint32(val) << 6;
}
GX::AttrType tex0() const { return GX::AttrType(vaFlags >> 8 & 0x3); }
void setTex0(GX::AttrType val) {
vaFlags &= ~0x300;
vaFlags |= atUint32(val) << 8;
}
GX::AttrType tex1() const { return GX::AttrType(vaFlags >> 10 & 0x3); }
void setTex1(GX::AttrType val) {
vaFlags &= ~0xC00;
vaFlags |= atUint32(val) << 10;
}
GX::AttrType tex2() const { return GX::AttrType(vaFlags >> 12 & 0x3); }
void setTex2(GX::AttrType val) {
vaFlags &= ~0x3000;
vaFlags |= atUint32(val) << 12;
}
GX::AttrType tex3() const { return GX::AttrType(vaFlags >> 14 & 0x3); }
void setTex3(GX::AttrType val) {
vaFlags &= ~0xC000;
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
{
static size_t ATTR_SZ[] = {0,1,1,2};
size_t ret = 0;
ret += ATTR_SZ[position()];
ret += ATTR_SZ[normal()];
ret += ATTR_SZ[color0()];
ret += ATTR_SZ[color1()];
ret += ATTR_SZ[tex0()];
ret += ATTR_SZ[tex1()];
ret += ATTR_SZ[tex2()];
ret += ATTR_SZ[tex3()];
ret += ATTR_SZ[tex4()];
ret += ATTR_SZ[tex5()];
ret += ATTR_SZ[tex6()];
ret += ATTR_SZ[pnMatIdx()];
ret += ATTR_SZ[tex0MatIdx()];
ret += ATTR_SZ[tex1MatIdx()];
ret += ATTR_SZ[tex2MatIdx()];
ret += ATTR_SZ[tex3MatIdx()];
ret += ATTR_SZ[tex4MatIdx()];
ret += ATTR_SZ[tex5MatIdx()];
ret += ATTR_SZ[tex6MatIdx()];
return ret;
}
} vaFlags;
const VAFlags& getVAFlags() const {return vaFlags;}
Value<atUint32> uniqueIdx;
size_t vertDLSize() const {
static size_t ATTR_SZ[] = {0, 1, 1, 2};
size_t ret = 0;
ret += ATTR_SZ[position()];
ret += ATTR_SZ[normal()];
ret += ATTR_SZ[color0()];
ret += ATTR_SZ[color1()];
ret += ATTR_SZ[tex0()];
ret += ATTR_SZ[tex1()];
ret += ATTR_SZ[tex2()];
ret += ATTR_SZ[tex3()];
ret += ATTR_SZ[tex4()];
ret += ATTR_SZ[tex5()];
ret += ATTR_SZ[tex6()];
ret += ATTR_SZ[pnMatIdx()];
ret += ATTR_SZ[tex0MatIdx()];
ret += ATTR_SZ[tex1MatIdx()];
ret += ATTR_SZ[tex2MatIdx()];
ret += ATTR_SZ[tex3MatIdx()];
ret += ATTR_SZ[tex4MatIdx()];
ret += ATTR_SZ[tex5MatIdx()];
ret += ATTR_SZ[tex6MatIdx()];
return ret;
}
} vaFlags;
const VAFlags& getVAFlags() const { return vaFlags; }
Value<atUint32> uniqueIdx;
Vector<atUint32, AT_DNA_COUNT(flags.konstValuesEnabled())> konstCount;
Vector<GX::Color, AT_DNA_COUNT(flags.konstValuesEnabled() ? konstCount[0] : 0)> konstColors;
Vector<atUint32, AT_DNA_COUNT(flags.konstValuesEnabled())> konstCount;
Vector<GX::Color, AT_DNA_COUNT(flags.konstValuesEnabled() ? konstCount[0] : 0)> konstColors;
using BlendFactor = GX::BlendFactor;
Value<BlendFactor> blendDstFac;
Value<BlendFactor> blendSrcFac;
Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
using BlendFactor = GX::BlendFactor;
Value<BlendFactor> blendDstFac;
Value<BlendFactor> blendSrcFac;
Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
Value<atUint32> colorChannelCount = 0;
struct ColorChannel : BigDNA
{
AT_DECL_DNA
Value<atUint32> flags = 0;
bool lighting() const {return (flags & 0x1) != 0;}
void setLighting(bool enabled) {flags &= ~0x1; flags |= atUint32(enabled);}
bool useAmbient() const {return (flags & 0x2) != 0;}
void setUseAmbient(bool enabled) {flags &= ~0x2; flags |= atUint32(enabled) << 1;}
bool useMaterial() const {return (flags & 0x4) != 0;}
void setUseMaterial(bool enabled) {flags &= ~0x4; flags |= atUint32(enabled) << 2;}
atUint8 lightmask() const {return atUint8(flags >> 3 & 0xff);}
void setLightmask(atUint8 mask) {flags &= ~0x7f8; flags |= atUint32(mask) << 3;}
GX::DiffuseFn diffuseFn() const {return GX::DiffuseFn(flags >> 11 & 0x3);}
void setDiffuseFn(GX::DiffuseFn fn) {flags &= ~0x1800; flags |= atUint32(fn) << 11;}
GX::AttnFn attenuationFn() const {return GX::AttnFn(flags >> 13 & 0x3);}
void setAttenuationFn(GX::AttnFn fn) {flags &= ~0x6000; flags |= atUint32(fn) << 13;}
};
Vector<ColorChannel, AT_DNA_COUNT(colorChannelCount)> colorChannels;
Value<atUint32> tevStageCount = 0;
struct TEVStage : BigDNA
{
AT_DECL_DNA
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;
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);
Value<atUint32> colorChannelCount = 0;
struct ColorChannel : BigDNA {
AT_DECL_DNA
Value<atUint32> flags = 0;
bool lighting() const { return (flags & 0x1) != 0; }
void setLighting(bool enabled) {
flags &= ~0x1;
flags |= atUint32(enabled);
}
bool useAmbient() const { return (flags & 0x2) != 0; }
void setUseAmbient(bool enabled) {
flags &= ~0x2;
flags |= atUint32(enabled) << 1;
}
bool useMaterial() const { return (flags & 0x4) != 0; }
void setUseMaterial(bool enabled) {
flags &= ~0x4;
flags |= atUint32(enabled) << 2;
}
atUint8 lightmask() const { return atUint8(flags >> 3 & 0xff); }
void setLightmask(atUint8 mask) {
flags &= ~0x7f8;
flags |= atUint32(mask) << 3;
}
GX::DiffuseFn diffuseFn() const { return GX::DiffuseFn(flags >> 11 & 0x3); }
void setDiffuseFn(GX::DiffuseFn fn) {
flags &= ~0x1800;
flags |= atUint32(fn) << 11;
}
GX::AttnFn attenuationFn() const { return GX::AttnFn(flags >> 13 & 0x3); }
void setAttenuationFn(GX::AttnFn fn) {
flags &= ~0x6000;
flags |= atUint32(fn) << 13;
}
};
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
Vector<ColorChannel, AT_DNA_COUNT(colorChannelCount)> colorChannels;
static void RegisterMaterialProps(hecl::blender::PyOutStream& out);
static void ConstructMaterial(hecl::blender::PyOutStream& out,
const MaterialSet::Material& material,
unsigned groupIdx, unsigned matIdx);
Value<atUint32> tevStageCount = 0;
struct TEVStage : BigDNA {
AT_DECL_DNA
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,
const PAKRouter<PAKBridge>& pakRouter,
const PAKRouter<PAKBridge>::EntryType& entry,
unsigned setIdx)
{
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx);
}
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;
}
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);
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;
}
if (mat.flags.lightmap() && stageIdx == 0)
{
texEntry->name += "light";
++stageIdx;
continue;
}
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;
}
++stageIdx;
}
++matIdx;
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;
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
{
head.ensureTexturesExtracted(pakRouter);
if (mat.flags.lightmap() && stageIdx == 0) {
texEntry->name += "light";
++stageIdx;
continue;
}
++stageIdx;
}
++matIdx;
}
}
void ensureTexturesExtracted(PAKRouter<PAKBridge>& pakRouter) const { head.ensureTexturesExtracted(pakRouter); }
};
struct HMDLMaterialSet : BigDNA
{
static constexpr bool OneSection() {return false;}
struct HMDLMaterialSet : BigDNA {
static constexpr bool OneSection() { return false; }
AT_DECL_DNA
MaterialSet::MaterialSetHead head;
struct Material : BigDNA {
AT_DECL_DNA
MaterialSet::MaterialSetHead head;
MaterialSet::Material::Flags flags;
struct Material : BigDNA
{
AT_DECL_DNA
MaterialSet::Material::Flags flags;
Value<atUint32> textureCount = 0;
Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
Value<atUint32> textureCount = 0;
Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
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;
Value<atUint32> uvAnimsCount = 0;
Vector<MaterialSet::Material::UVAnimation, AT_DNA_COUNT(uvAnimsCount)> uvAnims;
String<-1> heclSource;
hecl::Frontend::IR heclIr;
String<-1> heclSource;
hecl::Frontend::IR heclIr;
Material() = default;
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);
};
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
Material() = default;
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);
};
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
};
}
} // namespace DataSpec::DNAMP1

View File

@ -1,21 +1,16 @@
#include "CSKR.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
{
atUint32 accum = 0;
for (const SkinningRule& rule : skinningRules)
{
if (idx >= accum && idx < accum + rule.vertCount)
for (const SkinningRule::Weight& weight : rule.weights)
os.format("vert[dvert_lay][%u] = %f\n",
cinf.getBoneIdxFromId(weight.boneId),
weight.weight);
accum += rule.vertCount;
}
void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const {
atUint32 accum = 0;
for (const SkinningRule& rule : skinningRules) {
if (idx >= accum && idx < accum + rule.vertCount)
for (const SkinningRule::Weight& weight : rule.weights)
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 "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
Value<atUint32> skinningRuleCount;
struct SkinningRule : BigDNA
{
AT_DECL_DNA
Value<atUint32> weightCount;
struct Weight : BigDNA
{
AT_DECL_DNA
Value<atUint32> boneId;
Value<float> weight;
};
Vector<Weight, AT_DNA_COUNT(weightCount)> weights;
Value<atUint32> vertCount;
Value<atUint32> weightCount;
struct Weight : BigDNA {
AT_DECL_DNA
Value<atUint32> boneId;
Value<float> weight;
};
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
{
return nullptr;
}
const atInt16* getMatrixBank(size_t) const { 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 "amuse/SongConverter.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
hecl::ProjectPath midPath = outPath.getWithExtension(_SYS_STR(".mid"), true);
hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true);
bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
hecl::ProjectPath midPath = outPath.getWithExtension(_SYS_STR(".mid"), 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;
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);
}
{
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);
w.writeUBytes(sngData.data(), sngData.size());
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;
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;
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;
}
}
} // namespace DataSpec::DNAMP1

View File

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

View File

@ -9,103 +9,86 @@
#define DCLN_DUMP_OBB 0
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
struct DCLN : BigDNA
{
using Mesh = hecl::blender::ColMesh;
struct DCLN : BigDNA {
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
Value<atUint32> colCount;
struct Collision : BigDNA
{
using Material = DeafBabe::Material;
using Edge = DeafBabe::Edge;
using Triangle = DeafBabe::Triangle;
Value<atUint32> magic;
Value<atUint32> version;
Value<atUint32> memSize;
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 {
AT_DECL_EXPLICIT_DNA
struct LeafData : BigDNA {
AT_DECL_DNA
Value<atUint32> magic;
Value<atUint32> version;
Value<atUint32> memSize;
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;
Value<atUint32> triangleIndexCount;
Vector<atUint16, AT_DNA_COUNT(triangleIndexCount)> triangleIndices;
size_t getMemoryUsage() const { return (((triangleIndices.size() * 2) + 16) + 3) & ~3; }
};
struct Node : BigDNA
{
AT_DECL_EXPLICIT_DNA
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;
struct LeafData : BigDNA
{
AT_DECL_DNA
Value<atUint32> triangleIndexCount;
Vector<atUint16, AT_DNA_COUNT(triangleIndexCount)> triangleIndices;
size_t getMemoryUsage() const { return (((triangleIndices.size() * 2) + 16) + 3) & ~3; }
};
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();
size_t getMemoryUsage() const {
size_t ret = 80;
if (isLeaf)
ret += leafData->getMemoryUsage();
else {
ret += left->getMemoryUsage();
ret += right->getMemoryUsage();
}
/* Dummy MP2 member */
void insertNoClimb(hecl::blender::PyOutStream&) const {}
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 */
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,
PAKEntryReadStream& rs,
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 bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, 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 bool Cook(const hecl::ProjectPath& outPath,
const std::vector<Mesh>& meshes);
static bool Cook(const hecl::ProjectPath& outPath, const std::vector<Mesh>& meshes);
};
}
} // namespace DataSpec::DNAMP1

View File

@ -47,419 +47,373 @@
#include "MazeSeeds.hpp"
#include "SnowForces.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
logvisor::Module Log("urde::DNAMP1");
static bool GetNoShare(std::string_view name)
{
std::string lowerName(name);
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
if (!lowerName.compare(0, 7, "metroid"))
return false;
return true;
static bool GetNoShare(std::string_view name) {
std::string lowerName(name);
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
if (!lowerName.compare(0, 7, "metroid"))
return false;
return true;
}
PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
: m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract)
{
nod::AthenaPartReadStream rs(node.beginReadStream());
m_pak.read(rs);
: m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract) {
nod::AthenaPartReadStream rs(node.beginReadStream());
m_pak.read(rs);
/* Append Level String */
for (auto& ent : m_pak.m_entries)
{
PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL'))
{
PAKEntryReadStream rs = entry.beginReadStream(m_node);
MLVL mlvl;
mlvl.read(rs);
PAK::Entry* nameEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldNameId);
if (nameEnt)
{
nameEnt->name = entry.name + "_name";
PAKEntryReadStream rs = nameEnt->beginReadStream(m_node);
STRG mlvlName;
mlvlName.read(rs);
if (m_levelString.size())
m_levelString += _SYS_STR(", ");
m_levelString += mlvlName.getSystemString(FOURCC('ENGL'), 0);
}
}
/* Append Level String */
for (auto& ent : m_pak.m_entries) {
PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL')) {
PAKEntryReadStream rs = entry.beginReadStream(m_node);
MLVL mlvl;
mlvl.read(rs);
PAK::Entry* nameEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldNameId);
if (nameEnt) {
nameEnt->name = entry.name + "_name";
PAKEntryReadStream rs = nameEnt->beginReadStream(m_node);
STRG mlvlName;
mlvlName.read(rs);
if (m_levelString.size())
m_levelString += _SYS_STR(", ");
m_levelString += mlvlName.getSystemString(FOURCC('ENGL'), 0);
}
}
}
}
static hecl::SystemString LayerName(std::string_view name)
{
hecl::SystemString ret(hecl::SystemStringConv(name).sys_str());
for (auto& ch : ret)
if (ch == _SYS_STR('/') || ch == _SYS_STR('\\'))
ch = _SYS_STR('-');
return ret;
static hecl::SystemString LayerName(std::string_view name) {
hecl::SystemString ret(hecl::SystemStringConv(name).sys_str());
for (auto& ch : ret)
if (ch == _SYS_STR('/') || ch == _SYS_STR('\\'))
ch = _SYS_STR('-');
return ret;
}
void PAKBridge::build()
{
/* First pass: build per-area/per-layer dependency map */
for (const auto& ent : m_pak.m_entries)
{
const PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL'))
{
Level& level = m_levelDeps[entry.id];
void PAKBridge::build() {
/* First pass: build per-area/per-layer dependency map */
for (const auto& ent : m_pak.m_entries) {
const PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL')) {
Level& level = m_levelDeps[entry.id];
MLVL mlvl;
{
PAKEntryReadStream rs = entry.beginReadStream(m_node);
mlvl.read(rs);
}
bool named;
std::string bestName = m_pak.bestEntryName(m_node, entry, named);
level.name = hecl::SystemStringConv(bestName).sys_str();
level.areas.reserve(mlvl.areaCount);
unsigned layerIdx = 0;
MLVL mlvl;
{
PAKEntryReadStream rs = entry.beginReadStream(m_node);
mlvl.read(rs);
}
bool named;
std::string bestName = m_pak.bestEntryName(m_node, entry, named);
level.name = hecl::SystemStringConv(bestName).sys_str();
level.areas.reserve(mlvl.areaCount);
unsigned layerIdx = 0;
/* Make MAPW available to lookup MAPAs */
PAK::Entry* worldMapEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldMap);
std::vector<UniqueID32> mapw;
if (worldMapEnt)
{
worldMapEnt->name = entry.name + "_mapw";
PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node);
rs.seek(8, athena::Current);
atUint32 areaCount = rs.readUint32Big();
mapw.reserve(areaCount);
for (atUint32 i=0 ; i<areaCount ; ++i)
mapw.emplace_back(rs);
}
/* Make MAPW available to lookup MAPAs */
PAK::Entry* worldMapEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldMap);
std::vector<UniqueID32> mapw;
if (worldMapEnt) {
worldMapEnt->name = entry.name + "_mapw";
PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node);
rs.seek(8, athena::Current);
atUint32 areaCount = rs.readUint32Big();
mapw.reserve(areaCount);
for (atUint32 i = 0; i < areaCount; ++i)
mapw.emplace_back(rs);
}
PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId);
if (savwEnt)
savwEnt->name = entry.name + "_savw";
PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId);
if (savwEnt)
savwEnt->name = entry.name + "_savw";
PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId);
if (skyEnt)
skyEnt->name = entry.name + "_skybox";
PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId);
if (skyEnt)
skyEnt->name = entry.name + "_skybox";
/* Index areas */
unsigned ai = 0;
for (const MLVL::Area& area : mlvl.areas)
{
Level::Area& areaDeps = level.areas[area.areaMREAId];
MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai];
PAK::Entry* areaNameEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaNameId);
if (areaNameEnt)
{
STRG areaName;
{
PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node);
areaName.read(rs);
}
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;
}
/* Index areas */
unsigned ai = 0;
for (const MLVL::Area& area : mlvl.areas) {
Level::Area& areaDeps = level.areas[area.areaMREAId];
MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai];
PAK::Entry* areaNameEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaNameId);
if (areaNameEnt) {
STRG areaName;
{
PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node);
areaName.read(rs);
}
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;
/* Second pass: cross-compare uniqueness */
for (auto& entry : m_pak.m_entries)
{
entry.second.unique.checkEntry(*this, entry.second);
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;
}
}
}
/* 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
{
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);
ANCS ancs;
ancs.read(rs);
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
{
charAssoc.m_cmdlRigs[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
charAssoc.m_cskrCinfToCharacter[ci.cskr] =
std::make_pair(entry.second.id, hecl::Format("%s.CSKR", ci.name.c_str()));
charAssoc.m_cskrCinfToCharacter[ci.cinf] =
std::make_pair(entry.second.id, hecl::Format("CINF_%08X.CINF", ci.cinf.toUint32()));
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl);
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr);
PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf);
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_model", entry.first.toUint32(), ci.name.c_str());
cskrEnt->name = hecl::Format("ANCS_%08X_%s_skin", entry.first.toUint32(), ci.name.c_str());
cinfEnt->name = hecl::Format("ANCS_%08X_%s_skel", entry.first.toUint32(), ci.name.c_str());
if (ci.cmdlIce && ci.cskrIce)
{
charAssoc.m_cmdlRigs[ci.cmdlIce] = std::make_pair(ci.cskrIce, ci.cinf);
charAssoc.m_cskrCinfToCharacter[ci.cskrIce] =
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()));
}
}
void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
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);
ANCS ancs;
ancs.read(rs);
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) {
charAssoc.m_cmdlRigs[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
charAssoc.m_cskrCinfToCharacter[ci.cskr] =
std::make_pair(entry.second.id, hecl::Format("%s.CSKR", ci.name.c_str()));
charAssoc.m_cskrCinfToCharacter[ci.cinf] =
std::make_pair(entry.second.id, hecl::Format("CINF_%08X.CINF", ci.cinf.toUint32()));
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl);
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr);
PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf);
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_model", entry.first.toUint32(), ci.name.c_str());
cskrEnt->name = hecl::Format("ANCS_%08X_%s_skin", entry.first.toUint32(), ci.name.c_str());
cinfEnt->name = hecl::Format("ANCS_%08X_%s_skel", entry.first.toUint32(), ci.name.c_str());
if (ci.cmdlIce && ci.cskrIce) {
charAssoc.m_cmdlRigs[ci.cmdlIce] = std::make_pair(ci.cskrIce, ci.cinf);
charAssoc.m_cskrCinfToCharacter[ci.cskrIce] =
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());
}
else if (entry.second.type == FOURCC('MREA'))
{
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc);
}
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')) {
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc);
}
}
}
void PAKBridge::addPATHToMREA(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const
{
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);
UniqueID32 pathID = MREA::GetPATHId(rs);
if (pathID)
pathToMrea[pathID] = entry.first;
}
std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const {
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);
UniqueID32 pathID = MREA::GetPATHId(rs);
if (pathID)
pathToMrea[pathID] = entry.first;
}
}
}
static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}};
void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const
{
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries)
{
if (entry.second.type == FOURCC('MLVL'))
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const {
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) {
if (entry.second.type == FOURCC('MLVL')) {
MLVL mlvl;
{
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
mlvl.read(rs);
}
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
if (mlvl.worldNameId)
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _SYS_STR("!name.yaml"));
for (const MLVL::Area& area : mlvl.areas) {
{
MLVL mlvl;
{
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
mlvl.read(rs);
}
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
if (mlvl.worldNameId)
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _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();
}
}
}
}
/* 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();
}
}
}
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")}};
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();
}
}
}
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 "zeus/CMatrix4f.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
extern logvisor::Module Log;
/* MP1-specific, one-shot PAK traversal/extraction class */
class PAKBridge
{
const nod::Node& m_node;
PAK m_pak;
class PAKBridge {
const nod::Node& m_node;
PAK m_pak;
public:
bool m_doExtract;
using Level = DataSpec::Level<UniqueID32>;
std::unordered_map<UniqueID32, Level> m_levelDeps;
hecl::SystemString m_levelString;
bool m_doExtract;
using Level = DataSpec::Level<UniqueID32>;
std::unordered_map<UniqueID32, Level> m_levelDeps;
hecl::SystemString m_levelString;
PAKBridge(const nod::Node& node, bool doExtract=true);
void build();
static ResExtractor<PAKBridge> LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry);
std::string_view getName() const {return m_node.getName();}
hecl::SystemStringView getLevelString() const {return m_levelString;}
using PAKType = PAK;
const PAKType& getPAK() const {return m_pak;}
const nod::Node& getNode() const {return m_node;}
PAKBridge(const nod::Node& node, bool doExtract = true);
void build();
static ResExtractor<PAKBridge> LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry);
std::string_view getName() const { return m_node.getName(); }
hecl::SystemStringView getLevelString() const { return m_levelString; }
using PAKType = PAK;
const PAKType& getPAK() const { return m_pak; }
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,
std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const;
void addPATHToMREA(PAKRouter<PAKBridge>& pakRouter, std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const;
void addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const;
void addMAPATransforms(PAKRouter<PAKBridge>& pakRouter, std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const;
};
}
} // namespace DataSpec::DNAMP1

View File

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

View File

@ -2,152 +2,239 @@
#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
using BspNodeType = DataSpec::BspNodeType;
struct Material : BigDNA
{
AT_DECL_DNA
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);
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); }
};
}
} // namespace DataSpec::DNAMP1

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