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,19 +6,15 @@ 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
{
struct SAsset {
std::string name;
std::string directory;
hecl::FourCC type;
SAsset() = default;
SAsset(const hecl::FourCC& typeIn, athena::io::IStreamReader& in)
: type(typeIn)
{
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();
@ -29,21 +25,18 @@ struct SAsset
static std::unordered_map<uint64_t, SAsset> g_AssetNameMap;
static bool g_AssetNameMapInit = false;
void LoadAssetMap(athena::io::MemoryReader& ar)
{
if (!ar.hasError())
{
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
{
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)
{
for (uint32_t i = 0; i < assetCount; ++i) {
hecl::FourCC type;
ar.readBytesToBuf(&type, 4);
uint64_t id = ar.readUint64Big();
@ -53,8 +46,7 @@ void LoadAssetMap(athena::io::MemoryReader& ar)
}
}
void InitAssetNameMap()
{
void InitAssetNameMap() {
if (g_AssetNameMapInit)
return;
@ -73,12 +65,11 @@ void InitAssetNameMap()
g_AssetNameMapInit = true;
}
const std::string* TranslateIdToName(const UniqueID32& id)
{
const std::string* TranslateIdToName(const UniqueID32& id) {
if (g_AssetNameMap.find(id.toUint64()) == g_AssetNameMap.end())
return nullptr;
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,11 +5,9 @@
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)
{
bool BuildMasterShader(const hecl::ProjectPath& path) {
hecl::blender::Connection& conn = hecl::blender::Connection::SharedConnection();
if (!conn.createBlend(path, hecl::blender::BlendType::None))
return false;
@ -21,4 +19,4 @@ bool BuildMasterShader(const hecl::ProjectPath& path)
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,32 +7,21 @@
#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)
{
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)
{
for (const auto& info : chResInfo) {
const nod::Node* node;
const typename PAKRouter::EntryType* cmdlE =
pakRouter.lookupEntry(info.cmdl, &node, true, false);
if (cmdlE)
{
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node, true, false);
if (cmdlE) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
if (force || cmdlPath.isNone())
{
if (force || cmdlPath.isNone()) {
cmdlPath.makeDirChain(false);
if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh))
return false;
@ -49,8 +38,8 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
RigPair rigPair(&cskr, &cinf);
PAKEntryReadStream rs = cmdlE->beginReadStream(*node);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>
(conn, rs, pakRouter, *cmdlE, dataspec, rigPair);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>(
conn, rs, pakRouter, *cmdlE, dataspec, rigPair);
conn.saveBlend();
}
@ -59,18 +48,14 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
/* Extract attachment CMDL/CSKRs first */
auto attRange = pakRouter.lookupCharacterAttachmentRigs(entry.id);
for (auto it = attRange.first; it != attRange.second; ++it)
{
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)
{
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, &node, true, false);
if (cmdlE) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
if (force || cmdlPath.isNone())
{
if (force || cmdlPath.isNone()) {
cmdlPath.makeDirChain(false);
if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh))
return false;
@ -88,8 +73,8 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
RigPair rigPair(&cskr, &cinf);
PAKEntryReadStream rs = cmdlE->beginReadStream(*node);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>
(conn, rs, pakRouter, *cmdlE, dataspec, rigPair);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>(
conn, rs, pakRouter, *cmdlE, dataspec, rigPair);
conn.saveBlend();
}
@ -109,7 +94,8 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
{
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os.format("import bpy\n"
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"
@ -128,38 +114,32 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
pakRouter.getBestEntryName(entry).c_str());
std::unordered_set<typename PAKRouter::IDType> cinfsDone;
for (const auto& info : chResInfo)
{
for (const auto& info : chResInfo) {
/* Provide data to add-on */
os.format("actor_subtype = actor_data.subtypes.add()\n"
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())
{
if (cinfsDone.find(info.cinf) == cinfsDone.end()) {
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(info.cinf, cinf);
cinf.sendCINFToBlender(os, info.cinf);
if (cinfsDone.empty())
{
if (cinfsDone.empty()) {
firstName = ANCSDNA::CINFType::GetCINFArmatureName(info.cinf);
firstCinf = cinf;
}
cinfsDone.insert(info.cinf);
}
else
} 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)
{
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);
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"
@ -170,19 +150,15 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
}
/* Link overlays */
for (const auto& overlay : info.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)
{
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);
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"
@ -195,42 +171,34 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
}
/* Link attachments */
for (auto it = attRange.first; it != attRange.second; ++it)
{
for (auto it = attRange.first; it != attRange.second; ++it) {
os << "attachment = actor_data.attachments.add()\n";
os.format("attachment.name = '%s'\n", it->second.second.c_str());
auto cinfid = it->second.first.first;
auto cmdlid = it->second.first.second;
if (cinfid)
{
if (cinfid) {
/* Build CINF if needed */
if (cinfsDone.find(cinfid) == cinfsDone.end())
{
if (cinfsDone.find(cinfid) == cinfsDone.end()) {
typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(cinfid, cinf);
cinf.sendCINFToBlender(os, cinfid);
if (cinfsDone.empty())
{
if (cinfsDone.empty()) {
firstName = ANCSDNA::CINFType::GetCINFArmatureName(cinfid);
firstCinf = cinf;
}
cinfsDone.insert(cinfid);
}
else
} 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)
{
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);
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"
@ -244,8 +212,7 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
{
hecl::blender::DataStream ds = conn.beginData();
std::unordered_map<std::string,
hecl::blender::Matrix3f> matrices = ds.getBoneMatrices(firstName);
std::unordered_map<std::string, hecl::blender::Matrix3f> matrices = ds.getBoneMatrices(firstName);
ds.close();
DNAANIM::RigInverter<typename ANCSDNA::CINFType> inverter(firstCinf, matrices);
@ -256,18 +223,20 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
/* Get animation primitives */
std::map<atUint32, AnimationResInfo<typename PAKRouter::IDType>> animResInfo;
ancs.getAnimationResInfo(&pakRouter, animResInfo);
for (const auto& id : 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());
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());
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);
@ -277,32 +246,20 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn,
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,16 +5,14 @@
#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
{
struct CharacterResInfo {
std::string name;
IDTYPE cmdl;
IDTYPE cskr;
@ -23,8 +21,7 @@ struct CharacterResInfo
};
template <typename IDTYPE>
struct AnimationResInfo
{
struct AnimationResInfo {
std::string name;
IDTYPE animId;
IDTYPE evntId;
@ -32,14 +29,8 @@ struct AnimationResInfo
};
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,16 +3,12 @@
#define DUMP_KEYS 0
namespace DataSpec::DNAANIM
{
namespace DataSpec::DNAANIM {
size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels)
{
size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels) {
size_t bitsPerKeyFrame = 0;
for (const Channel& chan : channels)
{
switch (chan.type)
{
for (const Channel& chan : channels) {
switch (chan.type) {
case Channel::Type::Rotation:
bitsPerKeyFrame += 1;
case Channel::Type::Translation:
@ -30,29 +26,25 @@ size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& ch
bitsPerKeyFrame += chan.q[2];
bitsPerKeyFrame += chan.q[3];
break;
default: break;
default:
break;
}
}
return (bitsPerKeyFrame * keyFrameCount + 31) / 32 * 4;
}
static inline QuantizedRot QuantizeRotation(const Value& quat, atUint32 div)
{
static inline QuantizedRot QuantizeRotation(const Value& quat, atUint32 div) {
float q = M_PIF / 2.0f / float(div);
zeus::simd_floats f(quat.simd);
return
{
{
return {{
atInt32(std::asin(f[1]) / q),
atInt32(std::asin(f[2]) / q),
atInt32(std::asin(f[3]) / q),
},
(f[0] < 0.f)
};
(f[0] < 0.f)};
}
static inline Value DequantizeRotation(const QuantizedRot& v, atUint32 div)
{
static inline Value DequantizeRotation(const QuantizedRot& v, atUint32 div) {
float q = M_PIF / 2.0f / float(div);
athena::simd_floats f = {
0.0f,
@ -60,18 +52,14 @@ static inline Value DequantizeRotation(const QuantizedRot& v, atUint32 div)
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] = 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)
{
static inline Value DequantizeRotation_3(const QuantizedRot& v, atUint32 div) {
float q = 1.0f / float(div);
athena::simd_floats f = {
0.0f,
@ -79,18 +67,14 @@ static inline Value DequantizeRotation_3(const QuantizedRot& v, atUint32 div)
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] = 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)
{
bool BitstreamReader::dequantizeBit(const atUint8* data) {
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
@ -103,8 +87,7 @@ bool BitstreamReader::dequantizeBit(const atUint8* data)
return tempBuf & 0x1;
}
atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 q)
{
atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 q) {
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
@ -114,8 +97,7 @@ atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 q)
/* If this shift underflows the value, buffer the next 32 bits */
/* And tack onto shifted buffer */
if ((bitRem + q) > 32)
{
if ((bitRem + q) > 32) {
atUint32 tempBuf2 = hecl::SBig(*reinterpret_cast<const atUint32*>(data + byteCur + 4));
tempBuf |= (tempBuf2 << (32 - bitRem));
}
@ -134,80 +116,64 @@ atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 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)
{
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)
{
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:
{
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:
{
case Channel::Type::Translation: {
keys.push_back({chan.i[0] * transMult, chan.i[1] * transMult, chan.i[2] * transMult});
break;
}
case Channel::Type::Scale:
{
case Channel::Type::Scale: {
keys.push_back({chan.i[0] * scaleMult, chan.i[1] * scaleMult, chan.i[2] * scaleMult});
break;
}
case Channel::Type::KfHead:
{
case Channel::Type::KfHead: {
break;
}
case Channel::Type::RotationMP3:
{
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;
default:
break;
}
}
for (size_t f=0 ; f<keyFrameCount ; ++f)
{
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)
{
for (const Channel& chan : channels) {
#if DUMP_KEYS
if (chan.id != lastId)
{
if (chan.id != lastId) {
lastId = chan.id;
fprintf(stderr, "\n");
}
#endif
QuantizedValue& p = *ait;
switch (chan.type)
{
case Channel::Type::Rotation:
{
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]);
@ -219,8 +185,7 @@ BitstreamReader::read(const atUint8* data,
#endif
break;
}
case Channel::Type::Translation:
{
case Channel::Type::Translation: {
atInt32 val1 = dequantize(data, chan.q[0]);
p[0] += val1;
atInt32 val2 = dequantize(data, chan.q[1]);
@ -233,8 +198,7 @@ BitstreamReader::read(const atUint8* data,
#endif
break;
}
case Channel::Type::Scale:
{
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]);
@ -244,13 +208,11 @@ BitstreamReader::read(const atUint8* data,
#endif
break;
}
case Channel::Type::KfHead:
{
case Channel::Type::KfHead: {
dequantizeBit(data);
break;
}
case Channel::Type::RotationMP3:
{
case Channel::Type::RotationMP3: {
atInt32 val1 = dequantize(data, chan.q[0]);
p[0] += val1;
atInt32 val2 = dequantize(data, chan.q[1]);
@ -263,7 +225,8 @@ BitstreamReader::read(const atUint8* data,
kit->emplace_back(DequantizeRotation_3(qr, rotDiv));
break;
}
default: break;
default:
break;
}
++kit;
++ait;
@ -276,21 +239,18 @@ BitstreamReader::read(const atUint8* data,
return chanKeys;
}
void BitstreamWriter::quantizeBit(atUint8* data, bool val)
{
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));
*(atUint32*)(data + byteCur) = hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (val << bitRem));
m_bitCur += 1;
}
void BitstreamWriter::quantize(atUint8* data, atUint8 q, atInt32 val)
{
void BitstreamWriter::quantize(atUint8* data, atUint8 q, atInt32 val) {
atUint32 byteCur = (m_bitCur / 32) * 4;
atUint32 bitRem = m_bitCur % 32;
@ -298,13 +258,11 @@ void BitstreamWriter::quantize(atUint8* data, atUint8 q, atInt32 val)
/* Fill 32 bit buffer with region containing bits */
/* Make them least significant */
*(atUint32*)(data + byteCur) =
hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (masked << bitRem));
*(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)
{
if ((bitRem + q) > 32) {
*(atUint32*)(data + byteCur + 4) =
hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur + 4)) | (masked >> (32 - bitRem)));
}
@ -312,15 +270,10 @@ void BitstreamWriter::quantize(atUint8* data, atUint8 q, atInt32 val)
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)
{
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);
@ -329,16 +282,10 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
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)
{
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]));
@ -347,12 +294,8 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
}
break;
}
case Channel::Type::Scale:
{
for (auto it=kit->begin();
it != kit->end();
++it)
{
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]));
@ -361,7 +304,8 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
}
break;
}
default: break;
default:
break;
}
++kit;
}
@ -372,39 +316,31 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
std::vector<QuantizedValue> initVals;
initVals.reserve(channels.size());
kit = chanKeys.begin();
for (Channel& chan : channels)
{
for (Channel& chan : channels) {
chan.q[0] = 1;
chan.q[1] = 1;
chan.q[2] = 1;
switch (chan.type)
{
case Channel::Type::Rotation:
{
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:
{
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)};
chan.i = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)};
initVals.push_back(chan.i);
break;
}
case Channel::Type::Scale:
{
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)};
chan.i = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)};
initVals.push_back(chan.i);
break;
}
default: break;
default:
break;
}
++kit;
}
@ -413,17 +349,11 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
std::vector<QuantizedValue> lastVals = initVals;
kit = chanKeys.begin();
auto vit = lastVals.begin();
for (Channel& chan : channels)
{
for (Channel& chan : channels) {
QuantizedValue& last = *vit++;
switch (chan.type)
{
case Channel::Type::Rotation:
{
for (auto it=kit->begin() + 1;
it != kit->end();
++it)
{
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)));
@ -432,16 +362,10 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
}
break;
}
case Channel::Type::Translation:
{
for (auto it=kit->begin() + 1;
it != kit->end();
++it)
{
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)};
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)));
@ -449,16 +373,10 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
}
break;
}
case Channel::Type::Scale:
{
for (auto it=kit->begin() + 1;
it != kit->end();
++it)
{
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)};
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)));
@ -466,7 +384,8 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
}
break;
}
default: break;
default:
break;
}
++kit;
}
@ -477,18 +396,14 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
memset(newData.get(), 0, sizeOut);
lastVals = initVals;
for (size_t f=0 ; f<keyFrameCount ; ++f)
{
for (size_t f = 0; f < keyFrameCount; ++f) {
kit = chanKeys.begin();
vit = lastVals.begin();
for (const Channel& chan : channels)
{
for (const Channel& chan : channels) {
const Value& val = (*kit++)[f + 1];
QuantizedValue& last = *vit++;
switch (chan.type)
{
case Channel::Type::Rotation:
{
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]);
@ -497,35 +412,30 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
last = qrCur.v;
break;
}
case Channel::Type::Translation:
{
case Channel::Type::Translation: {
zeus::simd_floats f(val.simd);
QuantizedValue cur = {atInt32(f[0] / transMultOut),
atInt32(f[1] / transMultOut),
atInt32(f[2] / transMultOut)};
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:
{
case Channel::Type::Scale: {
zeus::simd_floats f(val.simd);
QuantizedValue cur = {atInt32(f[0] / scaleMultOut),
atInt32(f[1] / scaleMultOut),
atInt32(f[2] / scaleMultOut)};
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;
default:
break;
}
}
}
return newData;
}
}
} // namespace DataSpec::DNAANIM

View File

@ -3,11 +3,9 @@
#include "DNACommon.hpp"
#include <cmath>
namespace DataSpec::DNAANIM
{
namespace DataSpec::DNAANIM {
struct Value
{
struct Value {
athena::simd<float> simd;
Value() = default;
Value(const athena::simd<float>& s) : simd(s) {}
@ -16,37 +14,24 @@ struct Value
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
{
struct QuantizedValue {
atInt32 v[4];
atInt32& operator[] (size_t idx)
{return v[idx];}
atInt32 operator[] (size_t idx) const
{return v[idx];}
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
{
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
{
struct QuantizedRot {
QuantizedValue v;
bool w;
};
struct Channel
{
enum class Type
{
Rotation,
Translation,
Scale,
KfHead,
RotationMP3
} type;
struct Channel {
enum class Type { Rotation, Translation, Scale, KfHead, RotationMP3 } type;
atInt32 id = -1;
QuantizedValue i = {};
atUint8 q[4] = {};
@ -54,36 +39,25 @@ struct Channel
size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels);
class BitstreamReader
{
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
{
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,43 +11,33 @@ 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)
{
static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i) {
zeus::CAABox pos, neg;
aabb.splitZ(neg, pos);
if (i & 4)
{
if (i & 4) {
zeus::CAABox(pos).splitY(neg, pos);
if (i & 2)
{
if (i & 2) {
zeus::CAABox(pos).splitX(neg, pos);
if (i & 1)
return pos;
else
return neg;
}
else
{
} else {
zeus::CAABox(neg).splitX(neg, pos);
if (i & 1)
return pos;
else
return neg;
}
}
else
{
} else {
zeus::CAABox(neg).splitY(neg, pos);
if (i & 2)
{
if (i & 2) {
zeus::CAABox(pos).splitX(neg, pos);
if (i & 1)
return pos;
else
return neg;
}
else
{
} else {
zeus::CAABox(neg).splitX(neg, pos);
if (i & 1)
return pos;
@ -58,20 +47,17 @@ static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i)
}
}
void AROTBuilder::Node::mergeSets(int a, int b)
{
void AROTBuilder::Node::mergeSets(int a, int b) {
childNodes[a].childIndices.insert(childNodes[b].childIndices.cbegin(), childNodes[b].childIndices.cend());
childNodes[b].childIndices = childNodes[a].childIndices;
}
bool AROTBuilder::Node::compareSets(int a, int b) const
{
bool AROTBuilder::Node::compareSets(int a, int b) const {
return childNodes[a].childIndices != childNodes[b].childIndices;
}
void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes,
const zeus::CAABox& curAABB, BspNodeType& typeOut)
{
const zeus::CAABox& curAABB, BspNodeType& typeOut) {
/* Gather intersecting faces */
for (int i = 0; i < triBoxes.size(); ++i)
if (triBoxes[i].intersects(curAABB))
@ -80,14 +66,11 @@ void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<z
zeus::CVector3f extents = curAABB.extents();
/* Return early if empty, triangle intersection below performance threshold, or at max level */
if (childIndices.empty())
{
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)
{
} 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;
}
@ -95,30 +78,26 @@ void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<z
/* Subdivide */
typeOut = BspNodeType::Branch;
childNodes.resize(8);
for (int i=0 ; i<8 ; ++i)
{
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)
{
if (extents.x() < AROT_MIN_SUBDIV) {
mergeSets(0, 1);
mergeSets(4, 5);
mergeSets(2, 3);
mergeSets(6, 7);
}
if (extents.y() < AROT_MIN_SUBDIV)
{
if (extents.y() < AROT_MIN_SUBDIV) {
mergeSets(0, 2);
mergeSets(1, 3);
mergeSets(4, 6);
mergeSets(5, 7);
}
if (extents.z() < AROT_MIN_SUBDIV)
{
if (extents.z() < AROT_MIN_SUBDIV) {
mergeSets(0, 4);
mergeSets(1, 5);
mergeSets(2, 6);
@ -127,32 +106,21 @@ void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<z
/* Unsubdivide */
compSubdivs = 0;
if (compareSets(0, 1) ||
compareSets(4, 5) ||
compareSets(2, 3) ||
compareSets(6, 7))
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))
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))
if (compareSets(0, 4) || compareSets(1, 5) || compareSets(2, 6) || compareSets(3, 7))
compSubdivs |= 0x4;
if (!compSubdivs)
{
if (!compSubdivs) {
typeOut = BspNodeType::Leaf;
childNodes = std::vector<Node>();
flags = 0;
}
}
size_t AROTBuilder::BitmapPool::addIndices(const std::set<int>& indices)
{
size_t AROTBuilder::BitmapPool::addIndices(const std::set<int>& indices) {
for (size_t i = 0; i < m_pool.size(); ++i)
if (m_pool[i] == indices)
return i;
@ -162,8 +130,7 @@ size_t AROTBuilder::BitmapPool::addIndices(const std::set<int>& indices)
static const uint32_t AROTChildCounts[] = {0, 2, 2, 4, 2, 4, 4, 8};
void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff)
{
void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff) {
sz += 1;
poolIdx = bmpPool.addIndices(childIndices);
if (poolIdx > 65535)
@ -173,14 +140,10 @@ void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPo
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)
{
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);
}
@ -190,17 +153,12 @@ void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPo
}
}
void AROTBuilder::Node::writeIndirectionTable(athena::io::MemoryWriter& 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)
{
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);
}
@ -209,25 +167,20 @@ void AROTBuilder::Node::writeIndirectionTable(athena::io::MemoryWriter& w)
}
}
void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx)
{
void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx) {
w.writeUint16Big(poolIdx);
w.writeUint16Big(compSubdivs);
if (childNodes.size())
{
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];
for (int k=0 ; k < 1 + ((compSubdivs & 0x4) != 0) ; ++k)
{
for (int j=0 ; j < 1 + ((compSubdivs & 0x2) != 0) ; ++j)
{
for (int i=0 ; i < 1 + ((compSubdivs & 0x1) != 0) ; ++i)
{
for (int 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;
@ -236,12 +189,9 @@ void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx)
}
}
for (int k=0 ; k < 1 + ((compSubdivs & 0x4) != 0) ; ++k)
{
for (int j=0 ; j < 1 + ((compSubdivs & 0x2) != 0) ; ++j)
{
for (int i=0 ; i < 1 + ((compSubdivs & 0x1) != 0) ; ++i)
{
for (int 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]);
}
@ -250,17 +200,12 @@ void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx)
}
}
void AROTBuilder::Node::advanceIndex(int& 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)
{
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);
}
@ -269,17 +214,12 @@ void AROTBuilder::Node::advanceIndex(int& nodeIdx)
}
}
void AROTBuilder::Node::colSize(size_t& totalSz)
{
if (childIndices.size())
{
void AROTBuilder::Node::colSize(size_t& totalSz) {
if (childIndices.size()) {
nodeOff = totalSz;
if (childNodes.empty())
{
if (childNodes.empty()) {
totalSz += 26 + childIndices.size() * 2;
}
else
{
} else {
totalSz += 36;
for (int i = 0; i < 8; ++i)
childNodes[i].colSize(totalSz);
@ -287,12 +227,9 @@ void AROTBuilder::Node::colSize(size_t& totalSz)
}
}
void AROTBuilder::Node::writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB)
{
if (childIndices.size())
{
if (childNodes.empty())
{
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]);
@ -305,14 +242,11 @@ void AROTBuilder::Node::writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB
for (int idx : childIndices)
w.writeUint16Big(idx);
ptr += 26 + childIndices.size() * 2;
}
else
{
} 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)
{
for (int i = 0; i < 8; ++i) {
const Node& chNode = childNodes[i];
BspNodeType type = BspNodeType((flags >> (i * 2)) & 0x3);
if (type != BspNodeType::Invalid)
@ -328,24 +262,18 @@ void AROTBuilder::Node::writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB
}
}
void AROTBuilder::Node::pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount)
{
void AROTBuilder::Node::pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount) {
++nodeCount;
if (childNodes.empty())
{
if (childNodes.empty()) {
lookupCount += childIndices.size();
}
else
{
} 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())
{
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;
@ -358,12 +286,9 @@ void AROTBuilder::Node::pathWrite(DNAMP1::PATH& path, const zeus::CAABox& curAAB
n.regionStart = path.octreeRegionLookup.size();
for (int r : childIndices)
path.octreeRegionLookup.push_back(r);
}
else
{
} else {
atUint32 children[8];
for (int i=0 ; i<8 ; ++i)
{
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));
@ -383,8 +308,7 @@ void AROTBuilder::Node::pathWrite(DNAMP1::PATH& path, const zeus::CAABox& curAAB
}
void AROTBuilder::build(std::vector<std::vector<uint8_t>>& secs, const zeus::CAABox& fullAabb,
const std::vector<zeus::CAABox>& meshAabbs, const std::vector<DNACMDL::Mesh>& meshes)
{
const std::vector<zeus::CAABox>& meshAabbs, const std::vector<DNACMDL::Mesh>& meshes) {
/* Recursively split */
BspNodeType rootType;
rootNode.addChild(0, AROT_MIN_MODELS, meshAabbs, fullAabb, rootType);
@ -412,21 +336,16 @@ void AROTBuilder::build(std::vector<std::vector<uint8_t>>& secs, const zeus::CAA
/* Write bitmap */
std::vector<uint32_t> bmpWords;
bmpWords.reserve(bmpWordCount);
for (const std::set<int>& bmp : bmpPool.m_pool)
{
for (const std::set<int>& bmp : bmpPool.m_pool) {
bmpWords.clear();
bmpWords.resize(bmpWordCount);
auto bmpIt = bmp.cbegin();
if (bmpIt != bmp.cend())
{
if (bmpIt != bmp.cend()) {
int curIdx = 0;
for (int w=0 ; w<bmpWordCount ; ++w)
{
for (int b=0 ; b<32 ; ++b)
{
if (*bmpIt == curIdx)
{
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())
@ -448,8 +367,7 @@ void AROTBuilder::build(std::vector<std::vector<uint8_t>>& secs, const zeus::CAA
rootNode.writeNodes(w, 0);
}
std::pair<std::unique_ptr<uint8_t[]>, uint32_t> AROTBuilder::buildCol(const ColMesh& mesh, BspNodeType& rootOut)
{
std::pair<std::unique_ptr<uint8_t[]>, uint32_t> AROTBuilder::buildCol(const ColMesh& mesh, BspNodeType& rootOut) {
/* Accumulate total AABB */
zeus::CAABox fullAABB;
for (const auto& vert : mesh.verts)
@ -458,15 +376,12 @@ std::pair<std::unique_ptr<uint8_t[]>, uint32_t> AROTBuilder::buildCol(const ColM
/* Predetermine triangle AABBs */
std::vector<zeus::CAABox> triBoxes;
triBoxes.reserve(mesh.trianges.size());
for (const ColMesh::Triangle& tri : mesh.trianges)
{
for (const ColMesh::Triangle& tri : mesh.trianges) {
triBoxes.emplace_back();
zeus::CAABox& aabb = triBoxes.back();
for (int e=0 ; e<3 ; ++e)
{
for (int e = 0; e < 3; ++e) {
const ColMesh::Edge& edge = mesh.edges[tri.edges[e]];
for (int v=0 ; v<2 ; ++v)
{
for (int v = 0; v < 2; ++v) {
const auto& vert = mesh.verts[edge.verts[v]];
aabb.accumulateBounds(zeus::CVector3f(vert));
}
@ -486,14 +401,12 @@ std::pair<std::unique_ptr<uint8_t[]>, uint32_t> AROTBuilder::buildCol(const ColM
return {std::move(ret), totalSize};
}
void AROTBuilder::buildPath(DNAMP1::PATH& path)
{
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)
{
for (const DNAMP1::PATH::Region& r : path.regions) {
regionBoxes.emplace_back(r.aabb[0], r.aabb[1]);
fullAABB.accumulateBounds(regionBoxes.back());
}
@ -513,4 +426,4 @@ void AROTBuilder::buildPath(DNAMP1::PATH& path)
rootNode.pathWrite(path, fullAABB);
}
}
} // namespace DataSpec

View File

@ -6,25 +6,20 @@
#include "CMDL.hpp"
#include <set>
namespace DataSpec
{
namespace DNAMP1
{
namespace DataSpec {
namespace DNAMP1 {
struct PATH;
}
struct AROTBuilder
{
struct AROTBuilder {
using ColMesh = hecl::blender::ColMesh;
struct BitmapPool
{
struct BitmapPool {
std::vector<std::set<int>> m_pool;
size_t addIndices(const std::set<int>& indices);
} bmpPool;
struct Node
{
struct Node {
std::vector<Node> childNodes;
std::set<int> childIndices;
size_t poolIdx = 0;
@ -34,8 +29,8 @@ struct AROTBuilder
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 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);
@ -56,5 +51,4 @@ struct AROTBuilder
void buildPath(DNAMP1::PATH& path);
};
}
} // namespace DataSpec

View File

@ -1,14 +1,11 @@
#include "ATBL.hpp"
namespace DataSpec::DNAAudio
{
namespace DataSpec::DNAAudio {
bool ATBL::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ATBL::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
uint32_t idxCount = rs.readUint32Big();
athena::io::YAMLDocWriter w("ATBL");
for (uint32_t i=0 ; i<idxCount ; ++i)
{
for (uint32_t i = 0; i < idxCount; ++i) {
uint16_t idx = rs.readUint16Big();
if (idx == 0xffff)
continue;
@ -23,8 +20,7 @@ bool ATBL::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
return true;
}
bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath)
{
bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
athena::io::FileReader r(inPath.getAbsolutePath());
if (r.hasError())
return false;
@ -34,8 +30,7 @@ bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
return false;
unsigned long maxI = 0;
for (const auto& pair : dr.getRootNode()->m_mapChildren)
{
for (const auto& pair : dr.getRootNode()->m_mapChildren) {
unsigned long i = strtoul(pair.first.c_str(), nullptr, 0);
maxI = std::max(maxI, i);
}
@ -43,8 +38,7 @@ bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
std::vector<uint16_t> vecOut;
vecOut.resize(maxI + 1, 0xffff);
for (const auto& pair : dr.getRootNode()->m_mapChildren)
{
for (const auto& pair : dr.getRootNode()->m_mapChildren) {
unsigned long i = strtoul(pair.first.c_str(), nullptr, 0);
vecOut[i] = hecl::SBig(uint16_t(strtoul(pair.second->m_scalarString.c_str(), nullptr, 0)));
}
@ -58,4 +52,4 @@ bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
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);
};
}
} // namespace DataSpec::DNAAudio

View File

@ -4,45 +4,45 @@
#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)
{
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"
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);
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"
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");
"\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"
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],
"\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"
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"
@ -50,15 +50,17 @@ void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os,
"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),
"\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;
default:
return;
}
os.format("lamp.retro_layer = %u\n"
os.format(
"lamp.retro_layer = %u\n"
"lamp.retro_origtype = %u\n"
"lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n"
"lamp.constant_coefficient = 0\n"
@ -72,12 +74,11 @@ void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os,
"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],
"\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)
{
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";
@ -94,21 +95,22 @@ void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os,
if (light.q > FLT_EPSILON)
os.format("lamp.quadratic_coefficient = 25000 / %f\n", light.q);
break;
default: 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)
{
void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender::Light& lightIn) {
using InterType = hecl::blender::Light::Type;
switch (lightIn.type)
{
switch (lightIn.type) {
case InterType::Ambient:
lightOut.lightType = BabeDeadLight::LightType::LocalAmbient;
break;
@ -124,25 +126,16 @@ void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender:
break;
}
if (lightIn.type == InterType::Ambient)
{
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)
{
} 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)
{
} else if (lightIn.quadratic > lightIn.constant && lightIn.quadratic > lightIn.linear) {
lightOut.falloff = BabeDeadLight::Falloff::Quadratic;
lightOut.q = 25000.f / lightIn.quadratic;
}
else
{
} else {
lightOut.falloff = BabeDeadLight::Falloff::Constant;
lightOut.q = 2.f / lightIn.constant;
}
@ -158,9 +151,9 @@ void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender:
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);
void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLight& light, unsigned s, unsigned l);
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,27 +8,33 @@
#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
{
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;}
void setSkinned(bool val) {
flags &= ~0x1;
flags |= val;
}
bool shortNormals() const { return (flags & 0x2) != 0; }
void setShortNormals(bool val) {flags &= ~0x2; flags |= val << 1;}
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;}
void setShortUVs(bool val) {
flags &= ~0x4;
flags |= val << 2;
}
} flags;
Value<atVec3f> aabbMin;
Value<atVec3f> aabbMax;
@ -38,8 +44,7 @@ struct Header : BigDNA
Align<32> align;
};
struct SurfaceHeader_1 : BigDNA
{
struct SurfaceHeader_1 : BigDNA {
AT_DECL_EXPLICIT_DNA
Value<atVec3f> centroid;
Value<atUint32> matIdx = 0;
@ -55,8 +60,7 @@ struct SurfaceHeader_1 : BigDNA
static constexpr atInt16 skinMatrixBankIdx() { return -1; }
};
struct SurfaceHeader_2 : BigDNA
{
struct SurfaceHeader_2 : BigDNA {
AT_DECL_EXPLICIT_DNA
Value<atVec3f> centroid;
Value<atUint32> matIdx = 0;
@ -74,8 +78,7 @@ struct SurfaceHeader_2 : BigDNA
atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; }
};
struct SurfaceHeader_3 : BigDNA
{
struct SurfaceHeader_3 : BigDNA {
AT_DECL_EXPLICIT_DNA
Value<atVec3f> centroid;
Value<atUint32> matIdx = 0;
@ -94,8 +97,7 @@ struct SurfaceHeader_3 : BigDNA
atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; }
};
struct VertexAttributes
{
struct VertexAttributes {
GX::AttrType pos = GX::NONE;
GX::AttrType norm = GX::NONE;
GX::AttrType color0 = GX::NONE;
@ -109,64 +111,41 @@ struct VertexAttributes
};
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 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,115 +1,77 @@
#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'),
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>"; }
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)
{
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()))
{
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())
{
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())
{
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())
{
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;
}
@ -122,8 +84,7 @@ void CRSM<IDType>::_read(athena::io::YAMLDocReader& r)
}
template <class IDType>
void CRSM<IDType>::_write(athena::io::YAMLDocWriter& w) const
{
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()))
@ -145,27 +106,21 @@ void CRSM<IDType>::_write(athena::io::YAMLDocWriter& w) const
}
template <class IDType>
void CRSM<IDType>::_binarySize(size_t& __isz) const
{
void CRSM<IDType>::_binarySize(size_t& __isz) const {
__isz += 4;
for (const auto& pair : x0_generators)
{
if (pair.second)
{
for (const auto& pair : x0_generators) {
if (pair.second) {
__isz += 4;
pair.second.binarySize(__isz);
}
}
for (const auto& pair : x10_sfx)
{
for (const auto& pair : x10_sfx) {
if (pair.second != ~0)
__isz += 12;
}
for (const auto& pair : x20_decals)
{
if (pair.second)
{
for (const auto& pair : x20_decals) {
if (pair.second) {
__isz += 4;
pair.second.binarySize(__isz);
}
@ -178,33 +133,26 @@ void CRSM<IDType>::_binarySize(size_t& __isz) const
}
template <class IDType>
void CRSM<IDType>::_read(athena::io::IStreamReader &r)
{
void CRSM<IDType>::_read(athena::io::IStreamReader& r) {
uint32_t clsId;
r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('CRSM'))
{
if (clsId != SBIG('CRSM')) {
LogModule.report(logvisor::Warning, "non CRSM provided to CRSM parser");
return;
}
while (clsId != SBIG('_END'))
{
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())
{
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())
{
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'))
@ -214,22 +162,18 @@ void CRSM<IDType>::_read(athena::io::IStreamReader &r)
continue;
}
auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (decal != DecalTypes.end())
{
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'))
{
if (clsId == SBIG('RNGE')) {
r.readUint32();
x30_RNGE = r.readFloatBig();
continue;
}
if (clsId == SBIG('FOFF'))
{
if (clsId == SBIG('FOFF')) {
r.readUint32();
x34_FOFF = r.readFloatBig();
continue;
@ -240,42 +184,33 @@ void CRSM<IDType>::_read(athena::io::IStreamReader &r)
}
template <class IDType>
void CRSM<IDType>::_write(athena::io::IStreamWriter& w) const
{
void CRSM<IDType>::_write(athena::io::IStreamWriter& w) const {
w.writeBytes("CRSM", 4);
for (const auto& pair : x0_generators)
{
for (const auto& pair : x0_generators) {
w.writeBytes(pair.first.getChars(), 4);
pair.second.write(w);
}
for (const auto& pair : x10_sfx)
{
for (const auto& pair : x10_sfx) {
w.writeBytes(pair.first.getChars(), 4);
if (pair.second != ~0)
{
if (pair.second != ~0) {
w.writeBytes("CNST", 4);
w.writeUint32Big(pair.second);
}
else
{
} else {
w.writeBytes("NONE", 4);
}
}
for (const auto& pair : x20_decals)
{
for (const auto& pair : x20_decals) {
w.writeBytes(pair.first.getChars(), 4);
pair.second.write(w);
}
if (x30_RNGE != 50.f)
{
if (x30_RNGE != 50.f) {
w.writeBytes("RNGECNST", 8);
w.writeFloatBig(x30_RNGE);
}
if (x34_FOFF != 0.2f)
{
if (x34_FOFF != 0.2f) {
w.writeBytes("FOFFCNST", 8);
w.writeFloatBig(x34_FOFF);
}
@ -286,8 +221,7 @@ 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
{
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)
@ -295,10 +229,7 @@ void CRSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut)
}
template <class IDType>
CRSM<IDType>::CRSM()
: x30_RNGE(50.f),
x34_FOFF(0.2f)
{
CRSM<IDType>::CRSM() : x30_RNGE(50.f), x34_FOFF(0.2f) {
for (const auto& sfx : SFXTypes)
x10_sfx[sfx] = ~0;
}
@ -307,11 +238,9 @@ template struct CRSM<UniqueID32>;
template struct CRSM<UniqueID64>;
template <class IDType>
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
CRSM<IDType> crsm;
crsm.read(rs);
athena::io::ToYAMLStream(crsm, writer);
@ -323,8 +252,7 @@ template bool ExtractCRSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::Projec
template bool ExtractCRSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath)
{
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -337,5 +265,4 @@ bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath)
}
template bool WriteCRSM<UniqueID32>(const CRSM<UniqueID32>& crsm, const hecl::ProjectPath& outPath);
template bool WriteCRSM<UniqueID64>(const CRSM<UniqueID64>& crsm, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAParticle

View File

@ -5,11 +5,9 @@
#include "athena/FileWriter.hpp"
#include "optional.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
struct CRSM : BigDNA
{
struct CRSM : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x0_generators;
@ -27,4 +25,4 @@ 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,15 +3,12 @@
#include "athena/FileWriter.hpp"
#include "DGRP.hpp"
namespace DataSpec::DNADGRP
{
namespace DataSpec::DNADGRP {
template <class IDType>
bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
DGRP<IDType> dgrp;
dgrp.read(rs);
athena::io::ToYAMLStream(dgrp, writer);
@ -23,8 +20,7 @@ template bool ExtractDGRP<UniqueID32>(PAKEntryReadStream& rs, const hecl::Projec
template bool ExtractDGRP<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath)
{
bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -38,4 +34,4 @@ bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath)
template bool WriteDGRP<UniqueID32>(const DGRP<UniqueID32>& dgrp, const hecl::ProjectPath& outPath);
template bool WriteDGRP<UniqueID64>(const DGRP<UniqueID64>& dgrp, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNADGRP

View File

@ -3,22 +3,18 @@
#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
{
struct ObjectTag : BigDNA {
AT_DECL_DNA_YAML
DNAFourCC type;
Value<IDType> id;
bool validate() const
{
bool validate() const {
if (!id.operator bool())
return false;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
@ -28,8 +24,7 @@ struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) DGRP : Bi
Vector<ObjectTag, AT_DNA_COUNT(dependCount)> depends;
void validateDeps()
{
void validateDeps() {
std::vector<ObjectTag> newDeps;
newDeps.reserve(depends.size());
for (const ObjectTag& tag : depends)
@ -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,12 +15,10 @@ ThreadLocalPtr<IDRestorer<UniqueID128>> UniqueIDBridge::s_restorer128;
UniqueID32 UniqueID32::kInvalidId;
template <class IDType>
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool silenceWarnings)
{
hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool silenceWarnings) {
/* Try PAKRouter first (only available at extract) */
PAKRouterBase* pakRouter = g_PakRouter.get();
if (pakRouter)
{
if (pakRouter) {
hecl::ProjectPath path = pakRouter->getWorking(id, silenceWarnings);
if (path)
return path;
@ -29,13 +26,10 @@ hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool si
/* Try project cache second (populated with paths read from YAML resources) */
hecl::Database::Project* project = s_Project.get();
if (!project)
{
if (pakRouter)
{
if (!project) {
if (pakRouter) {
if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id)
LogDNACommon.report(logvisor::Warning,
"unable to translate %s to path", id.toString().c_str());
LogDNACommon.report(logvisor::Warning, "unable to translate %s to path", id.toString().c_str());
return {};
}
LogDNACommon.report(logvisor::Fatal,
@ -45,62 +39,46 @@ hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool si
}
const hecl::ProjectPath* search = project->lookupBridgePath(id.toUint64());
if (!search)
{
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());
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)
{
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");
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)
{
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)
{
void UniqueID32::assign(uint32_t id, bool noOriginal) {
m_id = id ? id : 0xffffffff;
if (!noOriginal)
if (IDRestorer<UniqueID32>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID32>())
@ -109,67 +87,69 @@ void UniqueID32::assign(uint32_t id, bool noOriginal)
}
template <>
void UniqueID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
{assign(reader.readUint32Big());}
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);}
void UniqueID32::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint32Big(m_id);
}
template <>
void UniqueID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
{
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)
{
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());
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;}
void UniqueID32::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
s += 4;
}
std::string UniqueID32::toString() const
{
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);}
void UniqueID32Zero::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
UniqueID32::Enumerate<BigDNA::BinarySize>(s);
}
AuxiliaryID32& AuxiliaryID32::operator=(const hecl::ProjectPath& path)
{
AuxiliaryID32& AuxiliaryID32::operator=(const hecl::ProjectPath& path) {
assign(path.ensureAuxInfo(m_auxStr).hash().val32());
return *this;
}
AuxiliaryID32& AuxiliaryID32::operator=(const UniqueID32& id)
{
AuxiliaryID32& AuxiliaryID32::operator=(const UniqueID32& id) {
m_baseId = id;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
if (path)
{
if (path) {
if (m_addExtension)
path = path.getWithExtension(m_addExtension);
*this = path;
@ -178,25 +158,21 @@ AuxiliaryID32& AuxiliaryID32::operator=(const UniqueID32& id)
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
{
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)
{
void AuxiliaryID32::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint32Big(m_id);
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
{
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)
{
void AuxiliaryID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
if (!operator bool())
return;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath<UniqueID32>(*this, true);
@ -210,10 +186,8 @@ void AuxiliaryID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& wr
writer.writeString(nullptr, std::string(path.getRelativePathUTF8()) + '|' + ufx8AuxStr);
}
/** PAK 64-bit Unique ID */
void UniqueID64::assign(uint64_t id, bool noOriginal)
{
void UniqueID64::assign(uint64_t id, bool noOriginal) {
m_id = id ? id : 0xffffffffffffffff;
if (!noOriginal)
if (IDRestorer<UniqueID64>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID64>())
@ -222,34 +196,34 @@ void UniqueID64::assign(uint64_t id, bool noOriginal)
}
template <>
void UniqueID64::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
{assign(reader.readUint64Big());}
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);}
void UniqueID64::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint64Big(m_id);
}
template <>
void UniqueID64::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
{
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)
{
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());
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;}
void UniqueID64::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
s += 8;
}
std::string UniqueID64::toString() const
{
std::string UniqueID64::toString() const {
char buf[17];
snprintf(buf, 17, "%016" PRIX64, m_id);
return std::string(buf);
@ -257,49 +231,43 @@ std::string UniqueID64::toString() const
/** PAK 128-bit Unique ID */
template <>
void UniqueID128::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
{
void UniqueID128::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
m_id.id[0] = reader.readUint64Big();
m_id.id[1] = reader.readUint64Big();
}
template <>
void UniqueID128::Enumerate<BigDNA::Write>(typename Write::StreamT& writer)
{
void UniqueID128::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint64Big(m_id.id[0]);
writer.writeUint64Big(m_id.id[1]);
}
template <>
void UniqueID128::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
{
void UniqueID128::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
*this = UniqueIDBridge::MakePathFromString<UniqueID128>(reader.readString(nullptr));
}
template <>
void UniqueID128::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer)
{
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());
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;}
void UniqueID128::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
s += 16;
}
std::string UniqueID128::toString() const
{
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)
{
void WordBitmap::read(athena::io::IStreamReader& reader, size_t bitCount) {
m_bitCount = bitCount;
size_t wordCount = (bitCount + 31) / 32;
m_words.clear();
@ -307,14 +275,10 @@ void WordBitmap::read(athena::io::IStreamReader& reader, size_t bitCount)
for (size_t w = 0; w < wordCount; ++w)
m_words.push_back(reader.readUint32Big());
}
void WordBitmap::write(athena::io::IStreamWriter& writer) const
{
void WordBitmap::write(athena::io::IStreamWriter& writer) const {
for (atUint32 word : m_words)
writer.writeUint32Big(word);
}
void WordBitmap::binarySize(size_t& __isz) const
{
__isz += m_words.size() * 4;
}
void WordBitmap::binarySize(size_t& __isz) const { __isz += m_words.size() * 4; }
}
} // namespace DataSpec

View File

@ -8,8 +8,7 @@
#include "boo/ThreadLocalPtr.hpp"
#include "zeus/CColor.hpp"
namespace DataSpec
{
namespace DataSpec {
struct SpecBase;
extern logvisor::Module LogDNACommon;
@ -25,22 +24,24 @@ 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
};
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)
{
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))
{
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;
@ -49,10 +50,9 @@ template <> inline void DNAColor::Enumerate<BigDNA::ReadYaml>(typename ReadYaml:
mSimd.copy_from(f);
}
}
template <> inline void DNAColor::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& _w)
{
if (auto v = _w.enterSubVector(nullptr))
{
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]);
@ -60,8 +60,10 @@ template <> inline void DNAColor::Enumerate<BigDNA::WriteYaml>(typename WriteYam
_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,37 +71,30 @@ class UniqueID64;
class UniqueID128;
/** Common virtual interface for runtime ambiguity resolution */
class PAKRouterBase
{
class PAKRouterBase {
protected:
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");
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");
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");
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
{
class UniqueIDBridge {
friend class UniqueID32;
friend class UniqueID64;
@ -107,6 +102,7 @@ class UniqueIDBridge
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);
@ -124,46 +120,40 @@ public:
};
template <>
inline IDRestorer<UniqueID32>* UniqueIDBridge::GetIDRestorer<UniqueID32>()
{
inline IDRestorer<UniqueID32>* UniqueIDBridge::GetIDRestorer<UniqueID32>() {
return s_restorer32.get();
}
template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID32>(IDRestorer<UniqueID32>* restorer)
{
inline void UniqueIDBridge::SetIDRestorer<UniqueID32>(IDRestorer<UniqueID32>* restorer) {
s_restorer32.reset(restorer);
}
template <>
inline IDRestorer<UniqueID64>* UniqueIDBridge::GetIDRestorer<UniqueID64>()
{
inline IDRestorer<UniqueID64>* UniqueIDBridge::GetIDRestorer<UniqueID64>() {
return s_restorer64.get();
}
template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID64>(IDRestorer<UniqueID64>* restorer)
{
inline void UniqueIDBridge::SetIDRestorer<UniqueID64>(IDRestorer<UniqueID64>* restorer) {
s_restorer64.reset(restorer);
}
template <>
inline IDRestorer<UniqueID128>* UniqueIDBridge::GetIDRestorer<UniqueID128>()
{
inline IDRestorer<UniqueID128>* UniqueIDBridge::GetIDRestorer<UniqueID128>() {
return s_restorer128.get();
}
template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID128>(IDRestorer<UniqueID128>* 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;
public:
using value_type = uint32_t;
static UniqueID32 kInvalidId;
@ -171,8 +161,10 @@ public:
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; }
@ -186,15 +178,13 @@ public:
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)
{
UniqueID32(const char* hexStr) {
char copy[9];
strncpy(copy, hexStr, 8);
copy[8] = '\0';
assign(strtoul(copy, nullptr, 16));
}
UniqueID32(const wchar_t* hexStr)
{
UniqueID32(const wchar_t* hexStr) {
wchar_t copy[9];
wcsncpy(copy, hexStr, 8);
copy[8] = L'\0';
@ -205,24 +195,22 @@ public:
};
/** 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;
};
class AuxiliaryID32 : public 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)
AuxiliaryID32(const hecl::SystemChar* auxStr, const hecl::SystemChar* addExtension = nullptr)
: m_auxStr(auxStr), m_addExtension(addExtension) {}
AuxiliaryID32& operator=(const hecl::ProjectPath& path);
@ -231,17 +219,19 @@ public:
};
/** PAK 64-bit Unique ID */
class UniqueID64 : public BigDNA
{
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);
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; }
@ -254,8 +244,7 @@ public:
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)
{
UniqueID64(const char* hexStr) {
char copy[17];
strncpy(copy, hexStr, 16);
copy[16] = '\0';
@ -265,8 +254,7 @@ public:
assign(strtouq(copy, nullptr, 16));
#endif
}
UniqueID64(const wchar_t* hexStr)
{
UniqueID64(const wchar_t* hexStr) {
wchar_t copy[17];
wcsncpy(copy, hexStr, 16);
copy[16] = L'\0';
@ -281,40 +269,41 @@ public:
};
/** PAK 128-bit Unique ID */
class UniqueID128 : public BigDNA
{
class UniqueID128 : public BigDNA {
public:
union Value
{
union Value {
uint64_t id[2];
#if __SSE__
__m128i id128;
#endif
};
private:
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)
{
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;}
operator bool() const {
return m_id.id[0] != 0xffffffffffffffff && m_id.id[0] != 0 && m_id.id[1] != 0xffffffffffffffff && m_id.id[1] != 0;
}
UniqueID128& operator=(const hecl::ProjectPath& path)
{
UniqueID128& operator=(const hecl::ProjectPath& path) {
m_id.id[0] = path.hash().val64();
m_id.id[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);
@ -323,8 +312,7 @@ public:
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);
@ -333,7 +321,10 @@ public:
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;}
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]; }
@ -347,26 +338,24 @@ template <class T>
using CastIDToZero = typename std::conditional_t<std::is_same_v<T, UniqueID32>, UniqueID32Zero, T>;
/** Word Bitmap reader/writer */
class WordBitmap
{
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
{
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)
{
void setBit(size_t idx) {
size_t wordIdx = idx / 32;
while (wordIdx >= m_words.size())
m_words.push_back(0);
@ -374,8 +363,7 @@ public:
m_words[wordIdx] |= (1 << wordCur);
m_bitCount = std::max(m_bitCount, idx + 1);
}
void unsetBit(size_t idx)
{
void unsetBit(size_t idx) {
size_t wordIdx = idx / 32;
while (wordIdx >= m_words.size())
m_words.push_back(0);
@ -383,14 +371,17 @@ public:
m_words[wordIdx] &= ~(1 << wordCur);
m_bitCount = std::max(m_bitCount, idx + 1);
}
void clear() { m_words.clear(); m_bitCount = 0; }
void clear() {
m_words.clear();
m_bitCount = 0;
}
class Iterator
{
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;
@ -398,7 +389,10 @@ public:
using pointer = bool*;
using reference = bool&;
Iterator& operator++() {++m_idx; return *this;}
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; }
};
@ -411,8 +405,7 @@ typedef std::function<bool(const hecl::ProjectPath&, const hecl::ProjectPath&)>
/** Mappings of resources involved in extracting characters */
template <class IDType>
struct CharacterAssociations
{
struct CharacterAssociations {
using RigPair = std::pair<IDType, IDType>;
/* CMDL -> (CSKR, CINF) */
std::unordered_map<IDType, RigPair> m_cmdlRigs;
@ -420,51 +413,39 @@ struct CharacterAssociations
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,
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)
{
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)));
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
{
namespace std {
template <>
struct hash<DataSpec::DNAFourCC>
{
size_t operator()(const DataSpec::DNAFourCC& fcc) const
{return fcc.toUint32();}
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();}
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();}
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();}
struct hash<DataSpec::UniqueID128> {
size_t operator()(const DataSpec::UniqueID128& id) const { return id.toHighUint64() ^ id.toLowUint64(); }
};
}
} // namespace std

View File

@ -1,31 +1,29 @@
#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>"; }
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)
{
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()))
{
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)
{
switch (clsId) {
case SBIG('1SZE'):
case SBIG('1LFT'):
case SBIG('1ROT'):
@ -76,8 +74,7 @@ void DPSM<IDType>::_read(athena::io::YAMLDocReader& r)
}
template <class IDType>
void DPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const
{
void DPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const {
writeQuadDecalInfo(w, x0_quad, true);
writeQuadDecalInfo(w, x1c_quad, false);
@ -108,10 +105,8 @@ void DPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const
template <class IDType>
template <class Reader>
void DPSM<IDType>::readQuadDecalInfo(Reader& r, uint32_t clsId, typename DPSM<IDType>::SQuadDescr& quad)
{
switch(clsId)
{
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);
@ -144,9 +139,8 @@ void DPSM<IDType>::readQuadDecalInfo(Reader& r, uint32_t clsId, typename DPSM<ID
}
template <class IDType>
void DPSM<IDType>::writeQuadDecalInfo(athena::io::YAMLDocWriter& w,
const typename DPSM<IDType>::SQuadDescr& quad, bool first) const
{
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);
@ -171,38 +165,31 @@ void DPSM<IDType>::writeQuadDecalInfo(athena::io::YAMLDocWriter& 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)
{
if (x38_DMDL) {
s += 4;
x38_DMDL.binarySize(s);
}
if (x48_DLFT)
{
if (x48_DLFT) {
s += 4;
x48_DLFT.binarySize(s);
}
if (x4c_DMOP)
{
if (x4c_DMOP) {
s += 4;
x4c_DMOP.binarySize(s);
}
if (x50_DMRT)
{
if (x50_DMRT) {
s += 4;
x50_DMRT.binarySize(s);
}
if (x54_DMSC)
{
if (x54_DMSC) {
s += 4;
x54_DMSC.binarySize(s);
}
if (x58_DMCL)
{
if (x58_DMCL) {
x58_DMCL.binarySize(s);
}
if (x5c_24_DMAB)
@ -212,61 +199,49 @@ void DPSM<IDType>::_binarySize(size_t& s) const
}
template <class IDType>
void DPSM<IDType>::getQuadDecalBinarySize(size_t& s, const typename DPSM<IDType>::SQuadDescr& quad) const
{
if (quad.x0_LFT)
{
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)
{
if (quad.x4_SZE) {
s += 4;
quad.x4_SZE.binarySize(s);
}
if (quad.x8_ROT)
{
if (quad.x8_ROT) {
s += 4;
quad.x8_ROT.binarySize(s);
}
if (quad.xc_OFF)
{
if (quad.xc_OFF) {
s += 4;
quad.xc_OFF.binarySize(s);
}
if (quad.x10_CLR)
{
if (quad.x10_CLR) {
s += 4;
quad.x10_CLR.binarySize(s);
}
if (quad.x14_TEX)
{
if (quad.x14_TEX) {
s += 4;
quad.x14_TEX.binarySize(s);
}
if (quad.x18_ADD)
{
if (quad.x18_ADD) {
s += 4;
quad.x18_ADD.binarySize(s);
}
}
template <class IDType>
void DPSM<IDType>::_read(athena::io::IStreamReader& r)
{
void DPSM<IDType>::_read(athena::io::IStreamReader& r) {
uint32_t clsId;
r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('DPSM'))
{
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)
{
while (clsId != SBIG('_END')) {
switch (clsId) {
case SBIG('1SZE'):
case SBIG('1LFT'):
case SBIG('1ROT'):
@ -322,38 +297,31 @@ void DPSM<IDType>::_read(athena::io::IStreamReader& r)
}
template <class IDType>
void DPSM<IDType>::_write(athena::io::IStreamWriter& w) const
{
void DPSM<IDType>::_write(athena::io::IStreamWriter& w) const {
w.writeBytes("DPSM", 4);
writeQuadDecalInfo(w, x0_quad, true);
writeQuadDecalInfo(w, x1c_quad, false);
if (x38_DMDL)
{
if (x38_DMDL) {
w.writeBytes("DMDL", 4);
x38_DMDL.write(w);
}
if (x48_DLFT)
{
if (x48_DLFT) {
w.writeBytes("DLFT", 4);
x48_DLFT.write(w);
}
if (x4c_DMOP)
{
if (x4c_DMOP) {
w.writeBytes("DMOP", 4);
x4c_DMOP.write(w);
}
if (x50_DMRT)
{
if (x50_DMRT) {
w.writeBytes("DMRT", 4);
x50_DMRT.write(w);
}
if (x54_DMSC)
{
if (x54_DMSC) {
w.writeBytes("DMSC", 4);
x54_DMSC.write(w);
}
if (x58_DMCL)
{
if (x58_DMCL) {
w.writeBytes("DMCL", 4);
x58_DMCL.write(w);
}
@ -365,49 +333,40 @@ void DPSM<IDType>::_write(athena::io::IStreamWriter& w) const
}
template <class IDType>
void DPSM<IDType>::writeQuadDecalInfo(athena::io::IStreamWriter& w,
const typename DPSM<IDType>::SQuadDescr& quad, bool first) const
{
if (quad.x0_LFT)
{
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)
{
if (quad.x4_SZE) {
w.writeBytes((first ? "1SZE" : "2SZE"), 4);
quad.x4_SZE.write(w);
}
if (quad.x8_ROT)
{
if (quad.x8_ROT) {
w.writeBytes((first ? "1ROT" : "2ROT"), 4);
quad.x8_ROT.write(w);
}
if (quad.xc_OFF)
{
if (quad.xc_OFF) {
w.writeBytes((first ? "1OFF" : "2OFF"), 4);
quad.xc_OFF.write(w);
}
if (quad.x10_CLR)
{
if (quad.x10_CLR) {
w.writeBytes((first ? "1CLR" : "2CLR"), 4);
quad.x10_CLR.write(w);
}
if (quad.x14_TEX)
{
if (quad.x14_TEX) {
w.writeBytes((first ? "1TEX" : "2TEX"), 4);
quad.x14_TEX.write(w);
}
if (quad.x18_ADD)
{
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
{
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)
@ -421,11 +380,9 @@ template struct DPSM<UniqueID32>;
template struct DPSM<UniqueID64>;
template <class IDType>
bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
DPSM<IDType> dpsm;
dpsm.read(rs);
athena::io::ToYAMLStream(dpsm, writer);
@ -437,8 +394,7 @@ template bool ExtractDPSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::Projec
template bool ExtractDPSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath)
{
bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -452,5 +408,4 @@ bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath)
template bool WriteDPSM<UniqueID32>(const DPSM<UniqueID32>& dpsm, const hecl::ProjectPath& outPath);
template bool WriteDPSM<UniqueID64>(const DPSM<UniqueID64>& dpsm, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAParticle

View File

@ -4,17 +4,14 @@
#include "PAK.hpp"
#include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
struct DPSM : BigDNA
{
struct DPSM : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
struct SQuadDescr
{
struct SQuadDescr {
IntElementFactory x0_LFT;
RealElementFactory x4_SZE;
RealElementFactory x8_ROT;
@ -32,9 +29,11 @@ struct DPSM : BigDNA
VectorElementFactory x50_DMRT;
VectorElementFactory x54_DMSC;
ColorElementFactory x58_DMCL;
union
{
struct { bool x5c_24_DMAB : 1; bool x5c_25_DMOO : 1;};
union {
struct {
bool x5c_24_DMAB : 1;
bool x5c_25_DMOO : 1;
};
uint8_t dummy;
};
template <class Reader>
@ -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,16 +6,13 @@
#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)
{
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)
{
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]);
}
@ -23,8 +20,7 @@ void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, b
os << "col_bm.verts.ensure_lookup_table()\n";
int triIdx = 0;
for (const typename DEAFBABE::Triangle& tri : db.triangleEdgeConnections)
{
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]];
@ -34,16 +30,12 @@ void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, b
int vindices[3];
vindices[2] =
(edge1.verts[0] != edge0.verts[0] && edge1.verts[0] != edge0.verts[1]) ?
edge1.verts[0] : edge1.verts[1];
(edge1.verts[0] != edge0.verts[0] && edge1.verts[0] != edge0.verts[1]) ? edge1.verts[0] : edge1.verts[1];
if (triMat.flipFace())
{
if (triMat.flipFace()) {
vindices[0] = edge0.verts[1];
vindices[1] = edge0.verts[0];
}
else
{
} else {
vindices[0] = edge0.verts[0];
vindices[1] = edge0.verts[1];
}
@ -53,7 +45,8 @@ void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, b
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.format("face = col_bm.faces.get(tri_verts)\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"
@ -61,7 +54,8 @@ void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, b
" 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.material_index = select_material(0x%016" PRIX64
")\n"
"face.smooth = False\n"
"\n",
atUint64(triMat.material));
@ -91,23 +85,24 @@ void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, b
os << "col_mesh_obj.layers[1] = True\n"
"col_mesh_obj.layers[0] = False\n";
os << "col_mesh_obj.draw_type = 'SOLID'\n"
"col_mesh_obj.game.physics_type = 'STATIC'\n"
"\n";
}
template void DeafBabeSendToBlender<DNAMP1::DeafBabe>(hecl::blender::PyOutStream& os, const DNAMP1::DeafBabe& db, bool isDcln, atInt32 idx);
template void DeafBabeSendToBlender<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)
{
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);
@ -124,23 +119,19 @@ static void PopulateAreaFields(DEAFBABE& db,
}
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)
{
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
{
class MaterialPool {
std::unordered_map<u64, int> m_materials;
public:
template <class M, class V>
int AddOrLookup(const M& mat, V& vec)
{
int AddOrLookup(const M& mat, V& vec) {
auto search = m_materials.find(mat.material);
if (search != m_materials.end())
return search->second;
@ -152,12 +143,10 @@ public:
};
template <class DEAFBABE>
void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh)
{
void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh) {
using BlendMat = hecl::blender::ColMesh::Material;
auto MakeMat = [](const BlendMat& mat, bool flipFace) -> typename DEAFBABE::Material
{
auto MakeMat = [](const BlendMat& mat, bool flipFace) -> typename DEAFBABE::Material {
typename DEAFBABE::Material dbMat = {};
dbMat.setUnknown(mat.unknown);
dbMat.setSurfaceStone(mat.surfaceStone);
@ -212,8 +201,7 @@ void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMes
db.verts.reserve(colMesh.verts.size());
db.vertMats.resize(colMesh.verts.size());
for (const auto& vert : colMesh.verts)
{
for (const auto& vert : colMesh.verts) {
fullAABB.accumulateBounds(zeus::CVector3f(vert));
db.verts.push_back(vert);
}
@ -222,8 +210,7 @@ void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMes
db.edgeVertConnections.reserve(colMesh.edges.size());
db.edgeMats.resize(colMesh.edges.size());
for (const auto& edge : colMesh.edges)
{
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];
@ -233,8 +220,7 @@ void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMes
db.triMats.reserve(colMesh.trianges.size());
db.triangleEdgeConnections.reserve(colMesh.trianges.size());
for (const auto& tri : colMesh.trianges)
{
for (const auto& tri : colMesh.trianges) {
int triMatIdx = matPool.AddOrLookup(MakeMat(colMesh.materials[tri.matIdx], tri.flip), db.materials);
db.triMats.push_back(triMatIdx);
@ -243,8 +229,7 @@ void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMes
db.triangleEdgeConnections.back().edges[1] = tri.edges[1];
db.triangleEdgeConnections.back().edges[2] = tri.edges[2];
for (int e=0 ; e<3 ; ++e)
{
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;
@ -260,6 +245,7 @@ void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMes
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,15 +2,9 @@
#include "DNACommon.hpp"
namespace DataSpec
{
namespace DataSpec {
enum class BspNodeType : atUint32
{
Invalid,
Branch,
Leaf
};
enum class BspNodeType : atUint32 { Invalid, Branch, Leaf };
template <class DEAFBABE>
void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln = false, atInt32 idx = -1);
@ -18,5 +12,4 @@ void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, b
template <class DEAFBABE>
void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh);
}
} // namespace DataSpec

View File

@ -2,15 +2,12 @@
#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
{
struct Object : BigDNA {
AT_DECL_DNA
Value<atUint32> mesh;
Value<atUint32> instanceId;
@ -18,4 +15,4 @@ struct EGMC : public BigDNA
Vector<Object, AT_DNA_COUNT(count)> objects;
};
}
} // namespace DataSpec::DNACommon

View File

@ -1,24 +1,19 @@
#include "ELSC.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
void ELSM<IDType>::_read(athena::io::IStreamReader& r)
{
void ELSM<IDType>::_read(athena::io::IStreamReader& r) {
uint32_t clsId;
r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('ELSM'))
{
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)
{
while (clsId != SBIG('_END')) {
switch (clsId) {
case SBIG('LIFE'):
x0_LIFE.read(r);
break;
@ -88,106 +83,85 @@ void ELSM<IDType>::_read(athena::io::IStreamReader& r)
}
template <class IDType>
void ELSM<IDType>::_write(athena::io::IStreamWriter& w) const
{
void ELSM<IDType>::_write(athena::io::IStreamWriter& w) const {
w.writeBytes((atInt8*)"ELSM", 4);
if (x0_LIFE)
{
if (x0_LIFE) {
w.writeBytes((atInt8*)"LIFE", 4);
x0_LIFE.write(w);
}
if (x4_SLIF)
{
if (x4_SLIF) {
w.writeBytes((atInt8*)"SLIF", 4);
x4_SLIF.write(w);
}
if (x8_GRAT)
{
if (x8_GRAT) {
w.writeBytes((atInt8*)"GRAT", 4);
x8_GRAT.write(w);
}
if (xc_SCNT)
{
if (xc_SCNT) {
w.writeBytes((atInt8*)"SCNT", 4);
xc_SCNT.write(w);
}
if (x10_SSEG)
{
if (x10_SSEG) {
w.writeBytes((atInt8*)"SSEG", 4);
x10_SSEG.write(w);
}
if (x14_COLR)
{
if (x14_COLR) {
w.writeBytes((atInt8*)"COLR", 4);
x14_COLR.write(w);
}
if (x18_IEMT)
{
if (x18_IEMT) {
w.writeBytes((atInt8*)"IEMT", 4);
x18_IEMT.write(w);
}
if (x1c_FEMT)
{
if (x1c_FEMT) {
w.writeBytes((atInt8*)"FEMT", 4);
x1c_FEMT.write(w);
}
if (x20_AMPL)
{
if (x20_AMPL) {
w.writeBytes((atInt8*)"AMPL", 4);
x20_AMPL.write(w);
}
if (x24_AMPD)
{
if (x24_AMPD) {
w.writeBytes((atInt8*)"AMPD", 4);
x24_AMPD.write(w);
}
if (x28_LWD1)
{
if (x28_LWD1) {
w.writeBytes((atInt8*)"LWD1", 4);
x28_LWD1.write(w);
}
if (x2c_LWD2)
{
if (x2c_LWD2) {
w.writeBytes((atInt8*)"LWD2", 4);
x2c_LWD2.write(w);
}
if (x30_LWD3)
{
if (x30_LWD3) {
w.writeBytes((atInt8*)"LWD3", 4);
x30_LWD3.write(w);
}
if (x34_LCL1)
{
if (x34_LCL1) {
w.writeBytes((atInt8*)"LCL1", 4);
x34_LCL1.write(w);
}
if (x38_LCL2)
{
if (x38_LCL2) {
w.writeBytes((atInt8*)"LCL2", 4);
x38_LCL2.write(w);
}
if (x3c_LCL3)
{
if (x3c_LCL3) {
w.writeBytes((atInt8*)"LCL3", 4);
x3c_LCL3.write(w);
}
if (x40_SSWH)
{
if (x40_SSWH) {
w.writeBytes((atInt8*)"SSWH", 4);
x40_SSWH.write(w);
}
if (x50_GPSM)
{
if (x50_GPSM) {
w.writeBytes((atInt8*)"GPSM", 4);
x50_GPSM.write(w);
}
if (x60_EPSM)
{
if (x60_EPSM) {
w.writeBytes((atInt8*)"EPSM", 4);
x60_EPSM.write(w);
}
if (x70_ZERY)
{
if (x70_ZERY) {
w.writeBytes((atInt8*)"ZERY", 4);
x70_ZERY.write(w);
}
@ -195,126 +169,100 @@ void ELSM<IDType>::_write(athena::io::IStreamWriter& w) const
}
template <class IDType>
void ELSM<IDType>::_binarySize(size_t& s) const
{
void ELSM<IDType>::_binarySize(size_t& s) const {
s += 4;
if (x0_LIFE)
{
if (x0_LIFE) {
s += 4;
x0_LIFE.binarySize(s);
}
if (x4_SLIF)
{
if (x4_SLIF) {
s += 4;
x4_SLIF.binarySize(s);
}
if (x8_GRAT)
{
if (x8_GRAT) {
s += 4;
x8_GRAT.binarySize(s);
}
if (xc_SCNT)
{
if (xc_SCNT) {
s += 4;
xc_SCNT.binarySize(s);
}
if (x10_SSEG)
{
if (x10_SSEG) {
s += 4;
x10_SSEG.binarySize(s);
}
if (x14_COLR)
{
if (x14_COLR) {
s += 4;
x14_COLR.binarySize(s);
}
if (x18_IEMT)
{
if (x18_IEMT) {
s += 4;
x18_IEMT.binarySize(s);
}
if (x1c_FEMT)
{
if (x1c_FEMT) {
s += 4;
x1c_FEMT.binarySize(s);
}
if (x20_AMPL)
{
if (x20_AMPL) {
s += 4;
x20_AMPL.binarySize(s);
}
if (x24_AMPD)
{
if (x24_AMPD) {
s += 4;
x24_AMPD.binarySize(s);
}
if (x28_LWD1)
{
if (x28_LWD1) {
s += 4;
x28_LWD1.binarySize(s);
}
if (x2c_LWD2)
{
if (x2c_LWD2) {
s += 4;
x2c_LWD2.binarySize(s);
}
if (x30_LWD3)
{
if (x30_LWD3) {
s += 4;
x30_LWD3.binarySize(s);
}
if (x34_LCL1)
{
if (x34_LCL1) {
s += 4;
x34_LCL1.binarySize(s);
}
if (x38_LCL2)
{
if (x38_LCL2) {
s += 4;
x38_LCL2.binarySize(s);
}
if (x3c_LCL3)
{
if (x3c_LCL3) {
s += 4;
x3c_LCL3.binarySize(s);
}
if (x40_SSWH)
{
if (x40_SSWH) {
s += 4;
x40_SSWH.binarySize(s);
}
if (x50_GPSM)
{
if (x50_GPSM) {
s += 4;
x50_GPSM.binarySize(s);
}
if (x60_EPSM)
{
if (x60_EPSM) {
s += 4;
x60_EPSM.binarySize(s);
}
if (x70_ZERY)
{
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)
{
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()))
{
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;
@ -383,8 +331,7 @@ void ELSM<IDType>::_read(athena::io::YAMLDocReader& r)
}
template <class IDType>
void ELSM<IDType>::_write(athena::io::YAMLDocWriter& w) const
{
void ELSM<IDType>::_write(athena::io::YAMLDocWriter& w) const {
if (x0_LIFE)
if (auto rec = w.enterSubRecord("LIFE"))
x0_LIFE.write(w);
@ -451,14 +398,17 @@ 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
{
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);
@ -468,11 +418,9 @@ template struct ELSM<UniqueID32>;
template struct ELSM<UniqueID64>;
template <class IDType>
bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
ELSM<IDType> elsm;
elsm.read(rs);
athena::io::ToYAMLStream(elsm, writer);
@ -484,8 +432,7 @@ template bool ExtractELSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::Projec
template bool ExtractELSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteELSM(const ELSM<IDType>& elsm, const hecl::ProjectPath& outPath)
{
bool WriteELSM(const ELSM<IDType>& elsm, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -499,4 +446,4 @@ bool WriteELSM(const ELSM<IDType>& elsm, const hecl::ProjectPath& outPath)
template bool WriteELSM<UniqueID32>(const ELSM<UniqueID32>& gpsm, const hecl::ProjectPath& outPath);
template bool WriteELSM<UniqueID64>(const ELSM<UniqueID64>& gpsm, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAParticle

View File

@ -4,11 +4,9 @@
#include "PAK.hpp"
#include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
struct ELSM : BigDNA
{
struct ELSM : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
IntElementFactory x0_LIFE;
@ -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,17 +1,14 @@
#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)
{
void FONT<IDType>::_read(athena::io::IStreamReader& __dna_reader) {
/* magic */
atUint32 magic;
__dna_reader.readBytesToBuf(&magic, 4);
if (magic != SBIG('FONT'))
{
if (magic != SBIG('FONT')) {
LogModule.report(logvisor::Fatal, "Invalid FONT magic '%s'", &magic);
return;
}
@ -42,8 +39,7 @@ void FONT<IDType>::_read(athena::io::IStreamReader& __dna_reader)
/* glyphCount */
glyphCount = __dna_reader.readUint32Big();
/* glyphs */
for (atUint32 i = 0; i < glyphCount; i++)
{
for (atUint32 i = 0; i < glyphCount; i++) {
if (version < 4)
glyphs.emplace_back(new GlyphMP1);
else
@ -57,8 +53,7 @@ void FONT<IDType>::_read(athena::io::IStreamReader& __dna_reader)
}
template <class IDType>
void FONT<IDType>::_write(athena::io::IStreamWriter& __dna_writer) const
{
void FONT<IDType>::_write(athena::io::IStreamWriter& __dna_writer) const {
/* magic */
__dna_writer.writeBytes((atInt8*)"FONT", 4);
/* version */
@ -97,8 +92,7 @@ void FONT<IDType>::_write(athena::io::IStreamWriter& __dna_writer) const
}
template <class IDType>
void FONT<IDType>::_read(athena::io::YAMLDocReader& __dna_docin)
{
void FONT<IDType>::_read(athena::io::YAMLDocReader& __dna_docin) {
/* version */
version = __dna_docin.readUint32("version");
/* unknown1 */
@ -126,11 +120,9 @@ void FONT<IDType>::_read(athena::io::YAMLDocReader& __dna_docin)
/* glyphCount */
/* glyphs */
size_t count;
if (auto v = __dna_docin.enterSubVector("glyphs", count))
{
if (auto v = __dna_docin.enterSubVector("glyphs", count)) {
glyphCount = count;
for (atUint32 i = 0; i < glyphCount; i++)
{
for (atUint32 i = 0; i < glyphCount; i++) {
if (version < 4)
glyphs.emplace_back(new GlyphMP1);
else
@ -146,8 +138,7 @@ void FONT<IDType>::_read(athena::io::YAMLDocReader& __dna_docin)
}
template <class IDType>
void FONT<IDType>::_write(athena::io::YAMLDocWriter& __dna_docout) const
{
void FONT<IDType>::_write(athena::io::YAMLDocWriter& __dna_docout) const {
/* version */
__dna_docout.writeUint32("version", version);
/* unknown1 */
@ -184,20 +175,17 @@ void FONT<IDType>::_write(athena::io::YAMLDocWriter& __dna_docout) const
}
template <>
const char* FONT<UniqueID32>::DNAType()
{
const char* FONT<UniqueID32>::DNAType() {
return "FONT<UniqueID32>";
}
template <>
const char* FONT<UniqueID64>::DNAType()
{
const char* FONT<UniqueID64>::DNAType() {
return "FONT<UniqueID64>";
}
template <class IDType>
void FONT<IDType>::_binarySize(size_t& __isz) const
{
void FONT<IDType>::_binarySize(size_t& __isz) const {
__isz += name.size() + 1;
textureId.binarySize(__isz);
for (const std::unique_ptr<IGlyph>& glyph : glyphs)
@ -211,11 +199,9 @@ AT_SUBSPECIALIZE_DNA_YAML(FONT<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(FONT<UniqueID64>)
template <class IDType>
bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
FONT<IDType> font;
font.read(rs);
athena::io::ToYAMLStream(font, writer);
@ -228,8 +214,7 @@ template bool ExtractFONT<UniqueID32>(PAKEntryReadStream& rs, const hecl::Projec
template bool ExtractFONT<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath)
{
bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -243,4 +228,4 @@ bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath)
template bool WriteFONT<UniqueID32>(const FONT<UniqueID32>& font, const hecl::ProjectPath& outPath);
template bool WriteFONT<UniqueID64>(const FONT<UniqueID64>& font, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAFont

View File

@ -3,18 +3,15 @@
#include "PAK.hpp"
#include "athena/FileWriter.hpp"
namespace DataSpec::DNAFont
{
struct GlyphRect : BigDNA
{
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
{
struct IGlyph : BigDNAVYaml {
AT_DECL_DNA_YAML
Value<atUint16> m_character;
GlyphRect m_glyphRect;
@ -36,8 +33,7 @@ struct IGlyph : BigDNAVYaml
virtual atInt32 kerningIndex() const = 0;
};
struct GlyphMP1 : IGlyph
{
struct GlyphMP1 : IGlyph {
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atInt32> m_leftPadding;
@ -57,8 +53,7 @@ struct GlyphMP1 : IGlyph
atInt32 kerningIndex() const { return m_kerningIndex; }
};
struct GlyphMP2 : IGlyph
{
struct GlyphMP2 : IGlyph {
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atInt8> m_layer;
@ -80,8 +75,7 @@ struct GlyphMP2 : IGlyph
atInt32 kerningIndex() const { return m_kerningIndex; }
};
struct KerningInfo : BigDNA
{
struct KerningInfo : BigDNA {
AT_DECL_DNA_YAML
Value<atUint16> thisChar;
Value<atUint16> nextChar;
@ -89,8 +83,7 @@ struct KerningInfo : BigDNA
};
template <class IDType>
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FONT : BigDNA
{
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FONT : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
Value<atUint32> version;
@ -110,8 +103,7 @@ struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FONT : Bi
Value<atUint32> kerningInfoCount;
Vector<KerningInfo, AT_DNA_COUNT(kerningInfoCount)> kerningInfo;
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
g_curSpec->flattenDependencies(textureId, pathsOut);
}
};
@ -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,35 +4,27 @@
#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)
{
void FSM2<IDType>::Enumerate(typename Op::StreamT& s) {
Do<Op>({"header"}, header, s);
if (header.magic != SBIG('FSM2'))
{
if (header.magic != SBIG('FSM2')) {
LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 magic '%.4s' expected 'FSM2'", header.magic.toString().c_str());
return;
}
if (header.version == 1)
{
if (header.version == 1) {
if (!detail)
detail.reset(new FSMV1);
Do<Op>({"detail"}, static_cast<FSMV1&>(*detail), s);
}
else if (header.version == 2)
{
} else if (header.version == 2) {
if (!detail)
detail.reset(new FSMV2);
Do<Op>({"detail"}, static_cast<FSMV2&>(*detail), s);
}
else
{
} else {
LogDNAFSM2.report(logvisor::Fatal, "Invalid FSM2 version '%i'", header.version);
return;
}
@ -42,20 +34,22 @@ 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)
{
bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
FSM2<IDType> fsm2;
fsm2.read(rs);
athena::io::ToYAMLStream(fsm2, writer);
@ -67,8 +61,7 @@ template bool ExtractFSM2<UniqueID32>(PAKEntryReadStream& rs, const hecl::Projec
template bool ExtractFSM2<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath)
{
bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -82,4 +75,4 @@ bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath)
template bool WriteFSM2<UniqueID32>(const FSM2<UniqueID32>& fsm2, const hecl::ProjectPath& outPath);
template bool WriteFSM2<UniqueID64>(const FSM2<UniqueID64>& fsm2, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAFSM2

View File

@ -4,48 +4,40 @@
#include "DNACommon.hpp"
#include "athena/FileWriter.hpp"
namespace DataSpec::DNAFSM2
{
struct IFSM : BigDNAVYaml
{
namespace DataSpec::DNAFSM2 {
struct IFSM : BigDNAVYaml {
Delete _d;
};
template <class IDType>
struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : BigDNA
{
struct Header : BigDNA
{
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
{
struct CommonStruct : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown;
};
struct FSMV1 : IFSM
{
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
{
struct State : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknownCount;
Vector<CommonStruct, AT_DNA_COUNT(unknownCount)> unknown;
};
struct Unknown1 : BigDNA
{
struct Unknown1 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<float> unknown1;
@ -54,16 +46,14 @@ struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : Bi
Value<atUint8> unknown3;
};
struct Unknown2 : BigDNA
{
struct Unknown2 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknownCount;
Vector<CommonStruct, AT_DNA_COUNT(unknownCount)> unknown;
};
struct Unknown3 : BigDNA
{
struct Unknown3 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknownCount;
@ -77,16 +67,14 @@ struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : Bi
Vector<Unknown3, AT_DNA_COUNT(unknown3Count)> unknown3;
};
struct FSMV2 : IFSM
{
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
{
struct State : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
@ -97,8 +85,7 @@ struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : Bi
Vector<CommonStruct, AT_DNA_COUNT(unknown5Count)> unknown5;
};
struct Unknown1 : BigDNA
{
struct Unknown1 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
@ -111,8 +98,7 @@ struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : Bi
Value<atUint8> unknown7;
};
struct Unknown2 : BigDNA
{
struct Unknown2 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
@ -123,8 +109,7 @@ struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : Bi
Vector<CommonStruct, AT_DNA_COUNT(unknown5Count)> unknown5;
};
struct Unknown3 : BigDNA
{
struct Unknown3 : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unknown1;
@ -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,18 +9,15 @@
#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)
{
void MAPA::Enumerate<BigDNA::Read>(typename Read::StreamT& __dna_reader) {
/* magic */
magic = __dna_reader.readUint32Big();
if (magic != 0xDEADD00D)
{
if (magic != 0xDEADD00D) {
LogDNACommon.report(logvisor::Error, "invalid MAPA magic");
return;
}
@ -32,16 +29,14 @@ void MAPA::Enumerate<BigDNA::Read>(typename Read::StreamT& __dna_reader)
header.reset(new HeaderMP2);
else if (version == 5)
header.reset(new HeaderMP3);
else
{
else {
LogDNACommon.report(logvisor::Error, "invalid MAPA version");
return;
}
header->read(__dna_reader);
for (atUint32 i = 0; i < header->mappableObjectCount(); i++)
{
for (atUint32 i = 0; i < header->mappableObjectCount(); i++) {
std::unique_ptr<IMappableObject> mo = nullptr;
if (version != 5)
mo.reset(new MappableObjectMP1_2);
@ -60,8 +55,7 @@ void MAPA::Enumerate<BigDNA::Read>(typename Read::StreamT& __dna_reader)
}
template <>
void MAPA::Enumerate<BigDNA::Write>(typename Write::StreamT& __dna_writer)
{
void MAPA::Enumerate<BigDNA::Write>(typename Write::StreamT& __dna_writer) {
/* magic */
__dna_writer.writeUint32Big(magic);
/* version */
@ -80,8 +74,7 @@ void MAPA::Enumerate<BigDNA::Write>(typename Write::StreamT& __dna_writer)
}
template <>
void MAPA::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
{
void MAPA::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
header->binarySize(s);
for (const std::unique_ptr<IMappableObject>& mo : mappableObjects)
@ -95,31 +88,13 @@ void MAPA::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& 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)
{
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;
@ -137,7 +112,8 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn,
"('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),"
"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),"
@ -173,22 +149,21 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn,
" edge.seam = True\n"
"\n";
os.format("bpy.context.scene.name = 'MAPA_%s'\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()]);
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)
{
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"
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"
@ -199,20 +174,17 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn,
"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, 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
{
} 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"
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"
@ -223,10 +195,8 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn,
"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, 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;
}
@ -237,46 +207,29 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn,
"\n";
/* Read in verts */
for (const atVec3f& vert : mapa.vertices)
{
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)
{
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++
};
unsigned int primVerts[3] = {*iit++, *iit++, *iit++};
if (GX::Primitive(prim.type) == GX::TRIANGLESTRIP)
{
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],
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],
} else {
os.format("add_triangle(bm, (%u,%u,%u))\n", primVerts[c % 3], primVerts[(c + 1) % 3],
primVerts[(c + 2) % 3]);
}
flip ^= 1;
@ -294,15 +247,9 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn,
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]);
} 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)
@ -315,19 +262,15 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn,
}
}
for (const typename MAPA::Surface::Border& border : surf.borders)
{
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));
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"
@ -337,15 +280,15 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn,
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"
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]);
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");
@ -358,37 +301,29 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn,
return true;
}
template bool ReadMAPAToBlender<PAKRouter<DNAMP1::PAKBridge>>
(hecl::blender::Connection& conn,
const MAPA& mapa,
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,
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,
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);
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;
}
@ -411,8 +346,7 @@ bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out)
header.surfCount = mapaIn.surfaces.size();
mapa.mappableObjects.reserve(mapaIn.pois.size());
for (const hecl::blender::MapArea::POI& poi : mapaIn.pois)
{
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());
@ -436,8 +370,7 @@ bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out)
mapa.surfaceHeaders.reserve(mapaIn.surfaces.size());
mapa.surfaces.reserve(mapaIn.surfaces.size());
for (const hecl::blender::MapArea::Surface& surfIn : mapaIn.surfaces)
{
for (const hecl::blender::MapArea::Surface& surfIn : mapaIn.surfaces) {
mapa.surfaceHeaders.emplace_back();
DNAMAPA::MAPA::SurfaceHeader& surfHead = mapa.surfaceHeaders.back();
mapa.surfaces.emplace_back();
@ -456,8 +389,7 @@ bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out)
surf.borderCount = surfIn.borders.size();
surf.borders.reserve(surfIn.borders.size());
for (const auto& borderIn : surfIn.borders)
{
for (const auto& borderIn : surfIn.borders) {
surf.borders.emplace_back();
DNAMAPA::MAPA::Surface::Border& border = surf.borders.back();
border.indexCount = borderIn.second.val;
@ -492,4 +424,4 @@ template bool Cook<DNAMP1::MAPA>(const hecl::blender::MapArea& mapa, const hecl:
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,16 +3,12 @@
#include "DNACommon.hpp"
#include "GX.hpp"
namespace DataSpec::DNAMAPA
{
struct MAPA : BigDNA
{
namespace DataSpec::DNAMAPA {
struct MAPA : BigDNA {
AT_DECL_EXPLICIT_DNA
Value<atUint32> magic;
Value<atUint32> version;
struct IMAPAHeader : BigDNAV
{
struct IMAPAHeader : BigDNAV {
Delete _d;
virtual atUint32 visMode() const = 0;
virtual atUint32 mappableObjectCount() const = 0;
@ -20,8 +16,7 @@ struct MAPA : BigDNA
virtual atUint32 surfaceCount() const = 0;
};
struct HeaderMP1 : IMAPAHeader
{
struct HeaderMP1 : IMAPAHeader {
AT_DECL_DNA
AT_DECL_DNAV
Value<atUint32> unknown1 = 0;
@ -36,8 +31,7 @@ struct MAPA : BigDNA
atUint32 surfaceCount() const { return surfCount; }
};
struct HeaderMP2 : IMAPAHeader
{
struct HeaderMP2 : IMAPAHeader {
AT_DECL_DNA
AT_DECL_DNAV
Value<atUint32> unknown1 = 0;
@ -55,8 +49,7 @@ struct MAPA : BigDNA
atUint32 surfaceCount() const { return surfCount; }
};
struct HeaderMP3 : IMAPAHeader
{
struct HeaderMP3 : IMAPAHeader {
AT_DECL_DNA
AT_DECL_DNAV
Value<atUint32> unknown1 = 0;
@ -78,14 +71,11 @@ struct MAPA : BigDNA
atUint32 surfaceCount() const { return surfCount; }
};
std::unique_ptr<IMAPAHeader> header;
struct IMappableObject : BigDNAV
{
struct IMappableObject : BigDNAV {
Delete _d;
enum class Type : atUint32
{
enum class Type : atUint32 {
BlueDoor = 0,
ShieldDoor = 1,
IceDoor = 2,
@ -111,8 +101,7 @@ struct MAPA : BigDNA
};
};
struct MappableObjectMP1_2 : IMappableObject
{
struct MappableObjectMP1_2 : IMappableObject {
AT_DECL_DNA
AT_DECL_DNAV
Value<Type> type;
@ -123,8 +112,7 @@ struct MAPA : BigDNA
Value<atInt32> seek2[4] = {-1, -1, -1, -1};
};
struct MappableObjectMP3 : IMappableObject
{
struct MappableObjectMP3 : IMappableObject {
AT_DECL_DNA
AT_DECL_DNAV
Value<Type> type;
@ -139,8 +127,7 @@ struct MAPA : BigDNA
std::vector<std::unique_ptr<IMappableObject>> mappableObjects;
Vector<atVec3f, AT_DNA_COUNT(header->vertexCount())> vertices;
struct SurfaceHeader : BigDNA
{
struct SurfaceHeader : BigDNA {
AT_DECL_DNA
Value<atVec3f> normal;
Value<atVec3f> centroid;
@ -150,12 +137,10 @@ struct MAPA : BigDNA
Vector<SurfaceHeader, AT_DNA_COUNT(header->surfaceCount())> surfaceHeaders;
struct Surface : BigDNA
{
struct Surface : BigDNA {
AT_DECL_DNA
Value<atUint32> primitiveCount;
struct Primitive : BigDNA
{
struct Primitive : BigDNA {
AT_DECL_DNA
Value<atUint32> type;
Value<atUint32> indexCount;
@ -164,8 +149,7 @@ struct MAPA : BigDNA
};
Vector<Primitive, AT_DNA_COUNT(primitiveCount)> primitives;
Value<atUint32> borderCount;
struct Border : BigDNA
{
struct Border : BigDNA {
AT_DECL_DNA
Value<atUint32> indexCount;
Vector<atUint8, AT_DNA_COUNT(indexCount)> indices;
@ -178,15 +162,10 @@ struct MAPA : BigDNA
};
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,17 +5,11 @@
#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)
{
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;
@ -39,19 +33,18 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn,
"\n";
hecl::ProjectPath hexPath = pakRouter.getWorking(mapu.hexMapa);
os.linkBlend(hexPath.getAbsolutePathUTF8().data(),
pakRouter.getBestEntryName(mapu.hexMapa).data());
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)
{
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"
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"
@ -60,19 +53,17 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn,
"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());
"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)
{
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"
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"
@ -81,10 +72,8 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn,
"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]);
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]);
}
}
@ -101,24 +90,19 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn,
return true;
}
template bool ReadMAPUToBlender<PAKRouter<DNAMP1::PAKBridge>>
(hecl::blender::Connection& conn,
const MAPU& mapu,
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,
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)
{
bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPath& out) {
MAPU mapu;
mapu.magic = 0xABCDEF01;
@ -127,8 +111,7 @@ bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPat
mapu.worldCount = mapuIn.worlds.size();
mapu.worlds.reserve(mapuIn.worlds.size());
for (const hecl::blender::MapUniverse::World& wld : mapuIn.worlds)
{
for (const hecl::blender::MapUniverse::World& wld : mapuIn.worlds) {
mapu.worlds.emplace_back();
MAPU::World& wldOut = mapu.worlds.back();
wldOut.name = wld.name;
@ -138,8 +121,7 @@ bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPat
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)
{
for (const hecl::blender::Matrix4f& mtx : wld.hexagons) {
wldOut.hexTransforms.emplace_back();
MAPU::Transform& xf = wldOut.hexTransforms.back();
xf.xf[0] = mtx.val[0];
@ -158,4 +140,4 @@ bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPat
return true;
}
}
} // namespace DataSpec::DNAMAPU

View File

@ -2,22 +2,18 @@
#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
{
struct Transform : BigDNA {
AT_DECL_DNA
Value<atVec4f> xf[3];
};
struct World : BigDNA
{
struct World : BigDNA {
AT_DECL_DNA
String<-1> name;
UniqueID32 mlvl;
@ -32,12 +28,7 @@ struct MAPU : BigDNA
};
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,18 +4,12 @@
#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)
{
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;
@ -24,7 +18,8 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn,
if (!conn.createBlend(blendPath, hecl::blender::BlendType::World))
return false;
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os.format("import bpy\n"
os.format(
"import bpy\n"
"import bmesh\n"
"from mathutils import Matrix\n"
"\n"
@ -38,8 +33,7 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn,
/* Insert area empties */
int areaIdx = 0;
for (const auto& area : mlvl.areas)
{
for (const auto& area : mlvl.areas) {
const typename PAKRouter::EntryType* mreaEntry = pakRouter.lookupEntry(area.areaMREAId);
hecl::SystemUTF8Conv areaDirName(*mreaEntry->unique.m_areaName);
@ -47,7 +41,8 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn,
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"
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"
@ -58,25 +53,22 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn,
"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]);
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)
{
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)
{
for (const atVec3f& pv : dock.planeVerts) {
const zeus::CVector3f pvRel = zeus::CVector3f(pv) - pvAvg;
os.format("bm.verts.new((%f,%f,%f))\n"
os.format(
"bm.verts.new((%f,%f,%f))\n"
"bm.verts.ensure_lookup_table()\n",
pvRel[0], pvRel[1], pvRel[2]);
if (idx)
@ -90,8 +82,7 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn,
"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]));
os.format("dockObj.location = (%f,%f,%f)\n", float(pvAvg[0]), float(pvAvg[1]), float(pvAvg[2]));
++dockIdx;
}
++areaIdx;
@ -103,31 +94,19 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn,
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,
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,
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,
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,19 +5,16 @@
#include "gmm/gmm.h"
#include "hecl/Blender/Connection.hpp"
namespace DataSpec
{
namespace DataSpec {
using ColMesh = hecl::blender::ColMesh;
struct FittedOBB
{
struct FittedOBB {
zeus::CTransform xf;
zeus::CVector3f he;
};
static std::vector<int> MakeRootTriangleIndex(const ColMesh& mesh)
{
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)
@ -25,8 +22,7 @@ static std::vector<int> MakeRootTriangleIndex(const ColMesh& mesh)
return ret;
}
static std::unordered_set<uint32_t> GetTriangleVerts(const ColMesh& mesh, int triIdx)
{
static std::unordered_set<uint32_t> GetTriangleVerts(const ColMesh& mesh, int triIdx) {
const ColMesh::Triangle& T = mesh.trianges[triIdx];
std::unordered_set<uint32_t> verts;
verts.insert(mesh.edges[T.edges[0]].verts[0]);
@ -40,9 +36,8 @@ static std::unordered_set<uint32_t> GetTriangleVerts(const ColMesh& mesh, int tr
// 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)
{
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
@ -56,7 +51,8 @@ static FittedOBB BuildFromCovarianceMatrix(gmm::dense_matrix<float>& C,
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();
r.normalize();
u.normalize(), f.normalize();
// set the rotation matrix using the eigvenvectors
ret.xf.basis[0] = r;
@ -65,11 +61,9 @@ static FittedOBB BuildFromCovarianceMatrix(gmm::dense_matrix<float>& C,
// now build the bounding box extents in the rotated frame
zeus::CVector3f minim(1e10f, 1e10f, 1e10f), maxim(-1e10f, -1e10f, -1e10f);
for (int triIdx : index)
{
for (int triIdx : index) {
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, triIdx);
for (uint32_t v : verts)
{
for (uint32_t v : verts) {
const zeus::CVector3f& p = mesh.verts[v].val;
zeus::CVector3f p_prime(r.dot(p), u.dot(p), f.dot(p));
minim = zeus::min(minim, p_prime);
@ -93,8 +87,7 @@ 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)
{
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);
@ -102,8 +95,7 @@ static FittedOBB FitOBB(const ColMesh& mesh, const std::vector<int>& index)
// loop over the triangles this time to find the
// mean location
for (int i : index)
{
for (int i : index) {
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, i);
auto it = verts.begin();
zeus::CVector3f p = mesh.verts[*it++].val;
@ -128,24 +120,38 @@ static FittedOBB FitOBB(const ColMesh& mesh, const std::vector<int>& index)
// 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;
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();
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;
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);
}
template <typename Node>
static void MakeLeaf(const ColMesh& mesh, const std::vector<int>& index, Node& n)
{
static void MakeLeaf(const ColMesh& mesh, const std::vector<int>& index, Node& n) {
n.left.reset();
n.right.reset();
n.isLeaf = true;
@ -157,8 +163,7 @@ static void MakeLeaf(const ColMesh& mesh, const std::vector<int>& index, Node& n
}
template <typename Node>
static std::unique_ptr<Node> RecursiveMakeNode(const ColMesh& mesh, const std::vector<int>& index)
{
static std::unique_ptr<Node> RecursiveMakeNode(const ColMesh& mesh, const std::vector<int>& index) {
// calculate root OBB
FittedOBB obb = FitOBB(mesh, index);
@ -166,16 +171,14 @@ static std::unique_ptr<Node> RecursiveMakeNode(const ColMesh& mesh, const std::v
obb.xf.basis.transpose();
std::unique_ptr<Node> n = std::make_unique<Node>();
for (int i = 0; i < 3; ++i)
{
for (int i = 0; i < 3; ++i) {
n->xf[i] = zeus::CVector4f{obb.xf.basis[i]};
n->xf[i].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)
{
if (obb.he[0] * obb.he[1] * obb.he[2] < 1.f) {
MakeLeaf(mesh, index, *n);
return n;
}
@ -184,19 +187,15 @@ static std::unique_ptr<Node> RecursiveMakeNode(const ColMesh& mesh, const std::v
std::vector<int> indexNeg[3];
std::vector<int> indexPos[3];
for (int c = 0; c < 3; ++c)
{
for (int c = 0; c < 3; ++c) {
// subdivide negative side
indexNeg[c].reserve(index.size());
for (int i : index)
{
for (int i : index) {
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, i);
for (uint32_t vtx : verts)
{
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)
{
if (v[c] < 0.f) {
indexNeg[c].push_back(i);
break;
}
@ -205,15 +204,12 @@ static std::unique_ptr<Node> RecursiveMakeNode(const ColMesh& mesh, const std::v
// subdivide positive side
indexPos[c].reserve(index.size());
for (int i : index)
{
for (int i : index) {
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, i);
for (uint32_t vtx : verts)
{
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)
{
if (v[c] >= 0.f) {
indexPos[c].push_back(i);
break;
}
@ -223,18 +219,15 @@ static std::unique_ptr<Node> RecursiveMakeNode(const ColMesh& mesh, const std::v
size_t idxMin = index.size();
int minComp = -1;
for (int c = 0; c < 3; ++c)
{
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)
{
if (test < idxMin && test < index.size() * 3 / 4) {
minComp = c;
idxMin = test;
}
}
if (minComp == -1)
{
if (minComp == -1) {
MakeLeaf(mesh, index, *n);
return n;
}
@ -246,8 +239,7 @@ static std::unique_ptr<Node> RecursiveMakeNode(const ColMesh& mesh, const std::v
}
template <typename Node>
std::unique_ptr<Node> OBBTreeBuilder::buildCol(const ColMesh& mesh)
{
std::unique_ptr<Node> OBBTreeBuilder::buildCol(const ColMesh& mesh) {
std::vector<int> root = MakeRootTriangleIndex(mesh);
return RecursiveMakeNode<Node>(mesh, root);
}
@ -255,4 +247,4 @@ std::unique_ptr<Node> OBBTreeBuilder::buildCol(const ColMesh& mesh)
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
{
struct OBBTreeBuilder {
using ColMesh = hecl::blender::ColMesh;
template <typename Node>
static std::unique_ptr<Node> buildCol(const ColMesh& mesh);
};
}
} // namespace DataSpec

View File

@ -3,53 +3,39 @@
#include "../DNAMP2/DNAMP2.hpp"
#include "../DNAMP3/DNAMP3.hpp"
namespace DataSpec
{
namespace DataSpec {
template <class PAKBRIDGE>
void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry)
{
void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry) {
UniqueResult::Type resultType = UniqueResult::Type::NotFound;
bool foundOneLayer = false;
const hecl::SystemString* levelName = nullptr;
typename PAKBRIDGE::PAKType::IDType levelId;
typename PAKBRIDGE::PAKType::IDType areaId;
unsigned layerIdx;
for (const auto& lpair : pakBridge.m_levelDeps)
{
if (entry.id == lpair.first)
{
for (const auto& lpair : pakBridge.m_levelDeps) {
if (entry.id == lpair.first) {
levelName = &lpair.second.name;
resultType = UniqueResult::Type::Level;
break;
}
for (const auto& pair : lpair.second.areas)
{
for (const auto& pair : lpair.second.areas) {
unsigned l = 0;
for (const auto& layer : pair.second.layers)
{
if (layer.resources.find(entry.id) != layer.resources.end())
{
if (foundOneLayer)
{
if (areaId == pair.first)
{
for (const auto& layer : pair.second.layers) {
if (layer.resources.find(entry.id) != layer.resources.end()) {
if (foundOneLayer) {
if (areaId == pair.first) {
resultType = UniqueResult::Type::Area;
}
else if (levelId == lpair.first)
{
} else if (levelId == lpair.first) {
resultType = UniqueResult::Type::Level;
break;
}
else
{
} else {
m_type = UniqueResult::Type::Pak;
return;
}
continue;
}
else
} else
resultType = UniqueResult::Type::Layer;
levelName = &lpair.second.name;
levelId = lpair.first;
@ -59,27 +45,19 @@ void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRID
}
++l;
}
if (pair.second.resources.find(entry.id) != pair.second.resources.end())
{
if (foundOneLayer)
{
if (areaId == pair.first)
{
if (pair.second.resources.find(entry.id) != pair.second.resources.end()) {
if (foundOneLayer) {
if (areaId == pair.first) {
resultType = UniqueResult::Type::Area;
}
else if (levelId == lpair.first)
{
} else if (levelId == lpair.first) {
resultType = UniqueResult::Type::Level;
break;
}
else
{
} else {
m_type = UniqueResult::Type::Pak;
return;
}
continue;
}
else
} else
resultType = UniqueResult::Type::Area;
levelName = &lpair.second.name;
levelId = lpair.first;
@ -90,12 +68,10 @@ void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRID
}
m_type = resultType;
m_levelName = levelName;
if (resultType == UniqueResult::Type::Layer || resultType == UniqueResult::Type::Area)
{
if (resultType == UniqueResult::Type::Layer || resultType == UniqueResult::Type::Area) {
const typename PAKBRIDGE::Level::Area& area = pakBridge.m_levelDeps.at(levelId).areas.at(areaId);
m_areaName = &area.name;
if (resultType == UniqueResult::Type::Layer)
{
if (resultType == UniqueResult::Type::Layer) {
const typename PAKBRIDGE::Level::Area::Layer& layer = area.layers[layerIdx];
m_layerName = &layer.name;
}
@ -109,8 +85,7 @@ template void UniqueResult::checkEntry(const DNAMP2::PAKBridge& pakBridge,
template void UniqueResult::checkEntry(const DNAMP3::PAKBridge& pakBridge,
const DNAMP3::PAKBridge::PAKType::Entry& entry);
hecl::ProjectPath UniqueResult::uniquePath(const hecl::ProjectPath& pakPath) const
{
hecl::ProjectPath UniqueResult::uniquePath(const hecl::ProjectPath& pakPath) const {
if (m_type == Type::Pak)
return pakPath;
@ -120,13 +95,10 @@ hecl::ProjectPath UniqueResult::uniquePath(const hecl::ProjectPath& pakPath) con
else
levelDir = pakPath;
if (m_type == Type::Area)
{
if (m_type == Type::Area) {
hecl::ProjectPath areaDir(levelDir, *m_areaName);
return areaDir;
}
else if (m_type == Type::Layer)
{
} else if (m_type == Type::Layer) {
hecl::ProjectPath areaDir(levelDir, *m_areaName);
hecl::ProjectPath layerDir(areaDir, *m_layerName);
return layerDir;
@ -136,8 +108,7 @@ hecl::ProjectPath UniqueResult::uniquePath(const hecl::ProjectPath& pakPath) con
}
template <class BRIDGETYPE>
void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::function<void(float)> progress)
{
void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::function<void(float)> progress) {
m_bridges = &bridges;
m_bridgePaths.clear();
@ -149,39 +120,33 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
/* Route entries unique/shared per-pak */
size_t bridgeIdx = 0;
for (BRIDGETYPE& bridge : bridges)
{
for (BRIDGETYPE& bridge : bridges) {
const auto& name = bridge.getName();
hecl::SystemStringConv sysName(name);
hecl::SystemStringView::const_iterator extit = sysName.sys_str().end() - 4;
hecl::SystemString baseName(sysName.sys_str().begin(), extit);
m_bridgePaths.emplace_back(std::make_pair(hecl::ProjectPath(m_gameWorking, baseName),
hecl::ProjectPath(m_gameCooked, baseName)));
m_bridgePaths.emplace_back(
std::make_pair(hecl::ProjectPath(m_gameWorking, baseName), hecl::ProjectPath(m_gameCooked, baseName)));
/* Index this PAK */
bridge.build();
/* Add to global entry lookup */
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK();
for (const auto& entry : pak.m_entries)
{
if (!pak.m_noShare)
{
for (const auto& entry : pak.m_entries) {
if (!pak.m_noShare) {
auto sSearch = m_sharedEntries.find(entry.first);
if (sSearch != m_sharedEntries.end())
continue;
auto uSearch = m_uniqueEntries.find(entry.first);
if (uSearch != m_uniqueEntries.end())
{
if (uSearch != m_uniqueEntries.end()) {
m_uniqueEntries.erase(uSearch);
m_sharedEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second);
}
else
} else
m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second);
}
else
} else
m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second);
}
@ -193,8 +158,7 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
}
/* Add named resources to catalog YAML files */
for (BRIDGETYPE& bridge : bridges)
{
for (BRIDGETYPE& bridge : bridges) {
athena::io::YAMLDocWriter catalogWriter(nullptr);
enterPAKBridge(bridge);
@ -203,22 +167,17 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
bridge.addMAPATransforms(*this, m_mapaTransforms, m_overrideEntries);
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK();
for (const auto& namedEntry : pak.m_nameEntries)
{
for (const auto& namedEntry : pak.m_nameEntries) {
if (namedEntry.name == "holo_cinf")
continue; /* Problematic corner case */
if (auto rec = catalogWriter.enterSubRecord(namedEntry.name.c_str()))
{
if (auto rec = catalogWriter.enterSubRecord(namedEntry.name.c_str())) {
hecl::ProjectPath working = getWorking(namedEntry.id);
if (working.getAuxInfoUTF8().size())
{
if (auto v = catalogWriter.enterSubVector(nullptr))
{
if (working.getAuxInfoUTF8().size()) {
if (auto v = catalogWriter.enterSubVector(nullptr)) {
catalogWriter.writeString(nullptr, working.getRelativePathUTF8());
catalogWriter.writeString(nullptr, working.getAuxInfoUTF8());
}
}
else
} else
catalogWriter.writeString(nullptr, working.getRelativePathUTF8());
}
}
@ -233,15 +192,12 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
}
template <class BRIDGETYPE>
void PAKRouter<BRIDGETYPE>::enterPAKBridge(const BRIDGETYPE& pakBridge)
{
void PAKRouter<BRIDGETYPE>::enterPAKBridge(const BRIDGETYPE& pakBridge) {
g_PakRouter.reset(this);
auto pit = m_bridgePaths.begin();
size_t bridgeIdx = 0;
for (const BRIDGETYPE& bridge : *m_bridges)
{
if (&bridge == &pakBridge)
{
for (const BRIDGETYPE& bridge : *m_bridges) {
if (&bridge == &pakBridge) {
m_pak.reset(&pakBridge.getPAK());
m_node.reset(&pakBridge.getNode());
m_curBridgeIdx.reset(reinterpret_cast<void*>(bridgeIdx));
@ -250,19 +206,15 @@ void PAKRouter<BRIDGETYPE>::enterPAKBridge(const BRIDGETYPE& pakBridge)
++pit;
++bridgeIdx;
}
LogDNACommon.report(logvisor::Fatal,
"PAKBridge provided to PAKRouter::enterPAKBridge() was not part of build()");
LogDNACommon.report(logvisor::Fatal, "PAKBridge provided to PAKRouter::enterPAKBridge() was not part of build()");
}
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCharacterWorking(const EntryType* entry) const
{
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCharacterWorking(const EntryType* entry) const {
auto characterSearch = m_charAssoc.m_cskrCinfToCharacter.find(entry->id);
if (characterSearch != m_charAssoc.m_cskrCinfToCharacter.cend())
{
if (characterSearch != m_charAssoc.m_cskrCinfToCharacter.cend()) {
hecl::ProjectPath characterPath = getWorking(characterSearch->second.first);
if (entry->type == FOURCC('EVNT'))
{
if (entry->type == FOURCC('EVNT')) {
hecl::SystemStringConv wideStr(characterSearch->second.second);
return characterPath.getWithExtension((hecl::SystemString(_SYS_STR(".")) + wideStr.c_str()).c_str(), true);
}
@ -273,8 +225,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCharacterWorking(const EntryType* en
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
const ResExtractor<BRIDGETYPE>& extractor) const
{
const ResExtractor<BRIDGETYPE>& extractor) const {
if (!entry)
return hecl::ProjectPath();
@ -284,11 +235,9 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
const PAKType* pak = m_pak.get();
intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get());
if (pak && pak->m_noShare)
{
if (pak && pak->m_noShare) {
const EntryType* singleSearch = pak->lookupEntry(entry->id);
if (singleSearch)
{
if (singleSearch) {
const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first;
#if HECL_UCS2
hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry));
@ -307,8 +256,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
}
auto uniqueSearch = m_uniqueEntries.find(entry->id);
if (uniqueSearch != m_uniqueEntries.end())
{
if (uniqueSearch != m_uniqueEntries.end()) {
const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first);
const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].first;
#if HECL_UCS2
@ -323,20 +271,16 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
entName += _SYS_STR(".*");
else if (hecl::ProjectPath chWork = getCharacterWorking(entry))
return chWork;
if (bridge.getPAK().m_noShare)
{
if (bridge.getPAK().m_noShare) {
return hecl::ProjectPath(pakPath, entName).ensureAuxInfo(auxInfo);
}
else
{
} else {
hecl::ProjectPath uniquePath = entry->unique.uniquePath(pakPath);
return hecl::ProjectPath(uniquePath, entName).ensureAuxInfo(auxInfo);
}
}
auto sharedSearch = m_sharedEntries.find(entry->id);
if (sharedSearch != m_sharedEntries.end())
{
if (sharedSearch != m_sharedEntries.end()) {
#if HECL_UCS2
hecl::SystemString entBase = hecl::UTF8ToWide(getBestEntryName(*entry));
#else
@ -359,63 +303,50 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
}
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry) const
{
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry) const {
if (!entry)
return hecl::ProjectPath();
return getWorking(entry, BRIDGETYPE::LookupExtractor(*m_node.get(), *m_pak.get(), *entry));
}
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const IDType& id, bool silenceWarnings) const
{
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const IDType& id, bool silenceWarnings) const {
return getWorking(lookupEntry(id, nullptr, silenceWarnings, false));
}
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const
{
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const {
if (!entry)
return hecl::ProjectPath();
auto overrideSearch = m_overrideEntries.find(entry->id);
if (overrideSearch != m_overrideEntries.end())
{
return overrideSearch->second.getCookedPath(
*m_dataSpec.overrideDataSpec(overrideSearch->second,
m_dataSpec.getDataSpecEntry(),
hecl::blender::SharedBlenderToken));
if (overrideSearch != m_overrideEntries.end()) {
return overrideSearch->second.getCookedPath(*m_dataSpec.overrideDataSpec(
overrideSearch->second, m_dataSpec.getDataSpecEntry(), hecl::blender::SharedBlenderToken));
}
const PAKType* pak = m_pak.get();
intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get());
if (pak && pak->m_noShare)
{
if (pak && pak->m_noShare) {
const EntryType* singleSearch = pak->lookupEntry(entry->id);
if (singleSearch)
{
if (singleSearch) {
const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].second;
return hecl::ProjectPath(pakPath, getBestEntryName(*entry));
}
}
auto uniqueSearch = m_uniqueEntries.find(entry->id);
if (uniqueSearch != m_uniqueEntries.end())
{
if (uniqueSearch != m_uniqueEntries.end()) {
const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first);
const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].second;
if (bridge.getPAK().m_noShare)
{
if (bridge.getPAK().m_noShare) {
return hecl::ProjectPath(pakPath, getBestEntryName(*entry));
}
else
{
} else {
hecl::ProjectPath uniquePath = entry->unique.uniquePath(pakPath);
return hecl::ProjectPath(uniquePath, getBestEntryName(*entry));
}
}
auto sharedSearch = m_sharedEntries.find(entry->id);
if (sharedSearch != m_sharedEntries.end())
{
if (sharedSearch != m_sharedEntries.end()) {
return hecl::ProjectPath(m_sharedCooked, getBestEntryName(*entry));
}
LogDNACommon.report(logvisor::Fatal, "Unable to find entry %s", entry->id.toString().c_str());
@ -423,14 +354,12 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const
}
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const IDType& id, bool silenceWarnings) const
{
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const IDType& id, bool silenceWarnings) const {
return getCooked(lookupEntry(id, nullptr, silenceWarnings, false));
}
template <class BRIDGETYPE>
hecl::SystemString PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryType& a, const IDType& b) const
{
hecl::SystemString PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryType& a, const IDType& b) const {
const nod::Node* node = m_node.get();
const PAKType* pak = m_pak.get();
if (!pak)
@ -449,15 +378,12 @@ hecl::SystemString PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryTyp
}
template <class BRIDGETYPE>
std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const EntryType& entry, bool stdOverride) const
{
std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const EntryType& entry, bool stdOverride) const {
std::string name;
for (const BRIDGETYPE& bridge : *m_bridges)
{
for (const BRIDGETYPE& bridge : *m_bridges) {
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK();
if (stdOverride && isShared())
{
if (stdOverride && isShared()) {
if (entry.type == FOURCC('MLVL'))
return "!world";
else if (entry.type == FOURCC('MREA'))
@ -477,18 +403,15 @@ std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const EntryType& entry, bool
}
template <class BRIDGETYPE>
std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const IDType& entry, bool stdOverride) const
{
std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const IDType& entry, bool stdOverride) const {
std::string name;
for (const BRIDGETYPE& bridge : *m_bridges)
{
for (const BRIDGETYPE& bridge : *m_bridges) {
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK();
const typename BRIDGETYPE::PAKType::Entry* e = pak.lookupEntry(entry);
if (!e)
continue;
if (stdOverride && isShared())
{
if (stdOverride && isShared()) {
if (e->type == FOURCC('MLVL'))
return "!world";
else if (e->type == FOURCC('MREA'))
@ -509,16 +432,13 @@ std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const IDType& entry, bool st
template <class BRIDGETYPE>
bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*, float)> progress)
{
std::function<void(const hecl::SystemChar*, float)> progress) {
enterPAKBridge(pakBridge);
size_t count = 0;
size_t sz = m_pak->m_entries.size();
float fsz = sz;
for (unsigned w=0 ; count<sz ; ++w)
{
for (const auto& item : m_pak->m_firstEntries)
{
for (unsigned w = 0; count < sz; ++w) {
for (const auto& item : m_pak->m_firstEntries) {
const auto* entryPtr = m_pak->lookupEntry(item);
ResExtractor<BRIDGETYPE> extractor = BRIDGETYPE::LookupExtractor(*m_node.get(), *m_pak.get(), *entryPtr);
if (extractor.weight != w)
@ -539,8 +459,7 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
/* Extract to unmodified directory */
hecl::ProjectPath cooked = working.getCookedPath(m_dataSpec.getUnmodifiedSpec());
if (force || cooked.isNone())
{
if (force || cooked.isNone()) {
cooked.makeDirChain(false);
PAKEntryReadStream s = entryPtr->beginReadStream(*node);
FILE* fout = hecl::Fopen(cooked.getAbsolutePath().data(), _SYS_STR("wb"));
@ -550,22 +469,16 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
if (extractor.func_a) /* Doesn't need PAKRouter access */
{
if (force || !extractor.IsFullyExtracted(working))
{
if (force || !extractor.IsFullyExtracted(working)) {
PAKEntryReadStream s = entryPtr->beginReadStream(*node);
extractor.func_a(s, working);
}
}
else if (extractor.func_b) /* Needs PAKRouter access */
{
if (force || !extractor.IsFullyExtracted(working))
} else if (extractor.func_b) /* Needs PAKRouter access */
{
if (force || !extractor.IsFullyExtracted(working)) {
PAKEntryReadStream s = entryPtr->beginReadStream(*node);
extractor.func_b(m_dataSpec, s, working, *this, *entryPtr, force, btok,
[&progress, thisFac](const hecl::SystemChar* update)
{
progress(update, thisFac);
});
[&progress, thisFac](const hecl::SystemChar* update) { progress(update, thisFac); });
}
}
}
@ -578,44 +491,36 @@ template <class BRIDGETYPE>
const typename BRIDGETYPE::PAKType::Entry* PAKRouter<BRIDGETYPE>::lookupEntry(const IDType& entry,
const nod::Node** nodeOut,
bool silenceWarnings,
bool currentPAK) const
{
bool currentPAK) const {
if (!entry)
return nullptr;
if (!m_bridges)
LogDNACommon.report(logvisor::Fatal,
"PAKRouter::build() must be called before PAKRouter::lookupEntry()");
LogDNACommon.report(logvisor::Fatal, "PAKRouter::build() must be called before PAKRouter::lookupEntry()");
const PAKType* pak = m_pak.get();
const nod::Node* node = m_node.get();
if (pak)
{
if (pak) {
const EntryType* ent = pak->lookupEntry(entry);
if (ent)
{
if (ent) {
if (nodeOut)
*nodeOut = node;
return ent;
}
}
if (currentPAK)
{
if (currentPAK) {
#ifndef NDEBUG
if (!silenceWarnings)
LogDNACommon.report(logvisor::Warning,
"unable to find PAK entry %s in current PAK", entry.toString().c_str());
LogDNACommon.report(logvisor::Warning, "unable to find PAK entry %s in current PAK", entry.toString().c_str());
#endif
return nullptr;
}
for (const BRIDGETYPE& bridge : *m_bridges)
{
for (const BRIDGETYPE& bridge : *m_bridges) {
const PAKType& pak = bridge.getPAK();
const EntryType* ent = pak.lookupEntry(entry);
if (ent)
{
if (ent) {
if (nodeOut)
*nodeOut = &bridge.getNode();
return ent;
@ -624,8 +529,7 @@ const typename BRIDGETYPE::PAKType::Entry* PAKRouter<BRIDGETYPE>::lookupEntry(co
#ifndef NDEBUG
if (!silenceWarnings)
LogDNACommon.report(logvisor::Warning,
"unable to find PAK entry %s", entry.toString().c_str());
LogDNACommon.report(logvisor::Warning, "unable to find PAK entry %s", entry.toString().c_str());
#endif
if (nodeOut)
*nodeOut = nullptr;
@ -634,8 +538,7 @@ const typename BRIDGETYPE::PAKType::Entry* PAKRouter<BRIDGETYPE>::lookupEntry(co
template <class BRIDGETYPE>
const typename CharacterAssociations<typename PAKRouter<BRIDGETYPE>::IDType>::RigPair*
PAKRouter<BRIDGETYPE>::lookupCMDLRigPair(const IDType& id) const
{
PAKRouter<BRIDGETYPE>::lookupCMDLRigPair(const IDType& id) const {
auto search = m_charAssoc.m_cmdlRigs.find(id);
if (search == m_charAssoc.m_cmdlRigs.end())
return nullptr;
@ -644,14 +547,12 @@ PAKRouter<BRIDGETYPE>::lookupCMDLRigPair(const IDType& id) const
template <class BRIDGETYPE>
const typename CharacterAssociations<typename PAKRouter<BRIDGETYPE>::IDType>::MultimapIteratorPair
PAKRouter<BRIDGETYPE>::lookupCharacterAttachmentRigs(const IDType& id) const
{
PAKRouter<BRIDGETYPE>::lookupCharacterAttachmentRigs(const IDType& id) const {
return m_charAssoc.m_characterToAttachmentRigs.equal_range(id);
}
template <class BRIDGETYPE>
const zeus::CMatrix4f* PAKRouter<BRIDGETYPE>::lookupMAPATransform(const IDType& id) const
{
const zeus::CMatrix4f* PAKRouter<BRIDGETYPE>::lookupMAPATransform(const IDType& id) const {
auto search = m_mapaTransforms.find(id);
if (search == m_mapaTransforms.end())
return nullptr;
@ -659,18 +560,14 @@ const zeus::CMatrix4f* PAKRouter<BRIDGETYPE>::lookupMAPATransform(const IDType&
}
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerWorking(const IDType& areaId, int layerIdx) const
{
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerWorking(const IDType& areaId, int layerIdx) const {
if (!m_bridges)
LogDNACommon.report(logvisor::Fatal,
"PAKRouter::build() must be called before PAKRouter::getAreaLayerWorking()");
LogDNACommon.report(logvisor::Fatal, "PAKRouter::build() must be called before PAKRouter::getAreaLayerWorking()");
auto bridgePathIt = m_bridgePaths.cbegin();
for (const BRIDGETYPE& bridge : *m_bridges)
{
for (const BRIDGETYPE& bridge : *m_bridges) {
for (const auto& level : bridge.m_levelDeps)
for (const auto& area : level.second.areas)
if (area.first == areaId)
{
if (area.first == areaId) {
hecl::ProjectPath levelPath(bridgePathIt->first, level.second.name);
hecl::ProjectPath areaPath(levelPath, area.second.name);
if (layerIdx < 0)
@ -683,19 +580,16 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerWorking(const IDType& areaI
}
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerWorking(const IDType& areaId, int layerIdx, bool& activeOut) const
{
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerWorking(const IDType& areaId, int layerIdx,
bool& activeOut) const {
activeOut = false;
if (!m_bridges)
LogDNACommon.report(logvisor::Fatal,
"PAKRouter::build() must be called before PAKRouter::getAreaLayerWorking()");
LogDNACommon.report(logvisor::Fatal, "PAKRouter::build() must be called before PAKRouter::getAreaLayerWorking()");
auto bridgePathIt = m_bridgePaths.cbegin();
for (const BRIDGETYPE& bridge : *m_bridges)
{
for (const BRIDGETYPE& bridge : *m_bridges) {
for (const auto& level : bridge.m_levelDeps)
for (const auto& area : level.second.areas)
if (area.first == areaId)
{
if (area.first == areaId) {
hecl::ProjectPath levelPath(bridgePathIt->first, level.second.name);
hecl::ProjectPath areaPath(levelPath, area.second.name);
if (layerIdx < 0)
@ -709,20 +603,15 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerWorking(const IDType& areaI
return hecl::ProjectPath();
}
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerCooked(const IDType& areaId, int layerIdx) const
{
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerCooked(const IDType& areaId, int layerIdx) const {
if (!m_bridges)
LogDNACommon.report(logvisor::Fatal,
"PAKRouter::build() must be called before PAKRouter::getAreaLayerCooked()");
LogDNACommon.report(logvisor::Fatal, "PAKRouter::build() must be called before PAKRouter::getAreaLayerCooked()");
auto bridgePathIt = m_bridgePaths.cbegin();
for (const BRIDGETYPE& bridge : *m_bridges)
{
for (const BRIDGETYPE& bridge : *m_bridges) {
for (const auto& level : bridge.m_levelDeps)
for (const auto& area : level.second.areas)
if (area.first == areaId)
{
if (area.first == areaId) {
hecl::ProjectPath levelPath(bridgePathIt->second, level.second.name);
hecl::ProjectPath areaPath(levelPath, area.second.name);
if (layerIdx < 0)
@ -735,19 +624,15 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerCooked(const IDType& areaId
}
template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const
{
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const {
activeOut = false;
if (!m_bridges)
LogDNACommon.report(logvisor::Fatal,
"PAKRouter::build() must be called before PAKRouter::getAreaLayerCooked()");
LogDNACommon.report(logvisor::Fatal, "PAKRouter::build() must be called before PAKRouter::getAreaLayerCooked()");
auto bridgePathIt = m_bridgePaths.cbegin();
for (const BRIDGETYPE& bridge : *m_bridges)
{
for (const BRIDGETYPE& bridge : *m_bridges) {
for (const auto& level : bridge.m_levelDeps)
for (const auto& area : level.second.areas)
if (area.first == areaId)
{
if (area.first == areaId) {
hecl::ProjectPath levelPath(bridgePathIt->second, level.second.name);
hecl::ProjectPath areaPath(levelPath, area.second.name);
if (layerIdx < 0)
@ -762,11 +647,9 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getAreaLayerCooked(const IDType& areaId
}
template <class BRIDGETYPE>
void PAKRouter<BRIDGETYPE>::enumerateResources(const std::function<bool(const EntryType*)>& func)
{
void PAKRouter<BRIDGETYPE>::enumerateResources(const std::function<bool(const EntryType*)>& func) {
if (!m_bridges)
LogDNACommon.report(logvisor::Fatal,
"PAKRouter::build() must be called before PAKRouter::enumerateResources()");
LogDNACommon.report(logvisor::Fatal, "PAKRouter::build() must be called before PAKRouter::enumerateResources()");
for (const auto& entryPair : m_uniqueEntries)
if (!func(entryPair.second.second))
return;
@ -776,8 +659,7 @@ void PAKRouter<BRIDGETYPE>::enumerateResources(const std::function<bool(const En
}
template <class BRIDGETYPE>
bool PAKRouter<BRIDGETYPE>::mreaHasDupeResources(const IDType& id) const
{
bool PAKRouter<BRIDGETYPE>::mreaHasDupeResources(const IDType& id) const {
const PAKType* pak = m_pak.get();
if (!pak)
LogDNACommon.report(logvisor::Fatal,
@ -789,4 +671,4 @@ template class PAKRouter<DNAMP1::PAKBridge>;
template class PAKRouter<DNAMP2::PAKBridge>;
template class PAKRouter<DNAMP3::PAKBridge>;
}
} // namespace DataSpec

View File

@ -5,15 +5,14 @@
#include <array>
#include "zeus/CMatrix4f.hpp"
namespace DataSpec
{
namespace DataSpec {
/** PAK entry stream reader */
class PAKEntryReadStream : public athena::io::IStreamReader
{
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(); }
@ -22,13 +21,11 @@ public:
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)
{
: 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)
{
void seek(atInt64 pos, athena::SeekOrigin origin) {
if (origin == athena::Begin)
m_pos = pos;
else if (origin == athena::Current)
@ -41,8 +38,7 @@ public:
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 readUBytesToBuf(void* buf, atUint64 len) {
atUint64 bufEnd = m_pos + len;
if (bufEnd > m_sz)
len -= bufEnd - m_sz;
@ -52,16 +48,8 @@ public:
}
};
struct UniqueResult
{
enum class Type
{
NotFound,
Pak,
Level,
Area,
Layer
} m_type = Type::NotFound;
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;
@ -79,42 +67,42 @@ class PAKRouter;
/** Resource extractor type */
template <class PAKBRIDGE>
struct ResExtractor
{
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::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;
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&, typename PAKBRIDGE::PAKType::Entry&)>
func_name;
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={})
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::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={})
typename PAKBRIDGE::PAKType::Entry&)>
nfunc = {})
: func_b(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {}
bool IsFullyExtracted(const hecl::ProjectPath& path) const
{
bool IsFullyExtracted(const hecl::ProjectPath& path) const {
hecl::ProjectPath::Type tp = path.getPathType();
if (tp == hecl::ProjectPath::Type::None)
return false;
else if (tp == hecl::ProjectPath::Type::Glob)
{
for (int i=0 ; i<6 ; ++i)
{
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);
@ -128,14 +116,11 @@ struct ResExtractor
/** Level hierarchy representation */
template <class IDType>
struct Level
{
struct Level {
hecl::SystemString name;
struct Area
{
struct Area {
hecl::SystemString name;
struct Layer
{
struct Layer {
hecl::SystemString name;
bool active;
std::unordered_set<IDType> resources;
@ -148,8 +133,7 @@ struct Level
/** 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;
@ -175,23 +159,23 @@ private:
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") {}
: 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 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 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
{
bool isShared() const {
const PAKType* pak = m_pak.get();
return pak ? !pak->m_noShare : false;
}
@ -204,14 +188,11 @@ public:
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)
{
bool lookupAndReadDNA(const IDType& id, DNA& out, bool silenceWarnings = false) {
const nod::Node* node;
const EntryType* entry = lookupEntry(id, &node, silenceWarnings);
if (!entry)
@ -222,7 +203,8 @@ public:
}
const typename CharacterAssociations<IDType>::RigPair* lookupCMDLRigPair(const IDType& id) const;
const typename CharacterAssociations<IDType>::MultimapIteratorPair lookupCharacterAttachmentRigs(const IDType& id) const;
const typename CharacterAssociations<IDType>::MultimapIteratorPair
lookupCharacterAttachmentRigs(const IDType& id) const;
const zeus::CMatrix4f* lookupMAPATransform(const IDType& mapaId) const;
hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx) const;
@ -235,5 +217,4 @@ public:
bool mreaHasDupeResources(const IDType& id) const;
};
}
} // namespace DataSpec

View File

@ -1,29 +1,27 @@
#include "PART.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <>
const char* GPSM<UniqueID32>::DNAType() {return "GPSM<UniqueID32>";}
const char* GPSM<UniqueID32>::DNAType() {
return "GPSM<UniqueID32>";
}
template <>
const char* GPSM<UniqueID64>::DNAType() {return "GPSM<UniqueID64>";}
const char* GPSM<UniqueID64>::DNAType() {
return "GPSM<UniqueID64>";
}
template <class IDType>
void GPSM<IDType>::_read(typename ReadYaml::StreamT& r)
{
for (const auto& elem : r.getCurNode()->m_mapChildren)
{
if (elem.first.size() < 4)
{
void GPSM<IDType>::_read(typename ReadYaml::StreamT& 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()))
{
if (auto rec = r.enterSubRecord(elem.first.c_str())) {
switch (*reinterpret_cast<const uint32_t*>(elem.first.data())) {
case SBIG('PMCL'):
x78_PMCL.read(r);
break;
@ -272,8 +270,7 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r)
}
template <class IDType>
void GPSM<IDType>::_write(typename WriteYaml::StreamT& w) const
{
void GPSM<IDType>::_write(typename WriteYaml::StreamT& w) const {
if (x0_PSIV)
if (auto rec = w.enterSubRecord("PSIV"))
x0_PSIV.write(w);
@ -502,91 +499,73 @@ void GPSM<IDType>::_write(typename WriteYaml::StreamT& w) const
}
template <class IDType>
void GPSM<IDType>::_binarySize(typename BinarySize::StreamT& s) const
{
void GPSM<IDType>::_binarySize(typename BinarySize::StreamT& s) const {
s += 4;
if (x0_PSIV)
{
if (x0_PSIV) {
s += 4;
x0_PSIV.binarySize(s);
}
if (x4_PSVM)
{
if (x4_PSVM) {
s += 4;
x4_PSVM.binarySize(s);
}
if (x8_PSOV)
{
if (x8_PSOV) {
s += 4;
x8_PSOV.binarySize(s);
}
if (xc_PSLT)
{
if (xc_PSLT) {
s += 4;
xc_PSLT.binarySize(s);
}
if (x10_PSWT)
{
if (x10_PSWT) {
s += 4;
x10_PSWT.binarySize(s);
}
if (x14_PSTS)
{
if (x14_PSTS) {
s += 4;
x14_PSTS.binarySize(s);
}
if (x18_POFS)
{
if (x18_POFS) {
s += 4;
x18_POFS.binarySize(s);
}
if (x1c_SEED)
{
if (x1c_SEED) {
s += 4;
x1c_SEED.binarySize(s);
}
if (x20_LENG)
{
if (x20_LENG) {
s += 4;
x20_LENG.binarySize(s);
}
if (x24_WIDT)
{
if (x24_WIDT) {
s += 4;
x24_WIDT.binarySize(s);
}
if (x28_MAXP)
{
if (x28_MAXP) {
s += 4;
x28_MAXP.binarySize(s);
}
if (x2c_GRTE)
{
if (x2c_GRTE) {
s += 4;
x2c_GRTE.binarySize(s);
}
if (x30_COLR)
{
if (x30_COLR) {
s += 4;
x30_COLR.binarySize(s);
}
if (x34_LTME)
{
if (x34_LTME) {
s += 4;
x34_LTME.binarySize(s);
}
if (x38_ILOC)
{
if (x38_ILOC) {
s += 4;
x38_ILOC.binarySize(s);
}
if (x3c_IVEC)
{
if (x3c_IVEC) {
s += 4;
x3c_IVEC.binarySize(s);
}
if (x40_EMTR)
{
if (x40_EMTR) {
s += 4;
x40_EMTR.binarySize(s);
}
@ -626,253 +605,203 @@ void GPSM<IDType>::_binarySize(typename BinarySize::StreamT& s) const
s += 9;
if (x30_31_RSOP)
s += 9;
if (x48_MBSP)
{
if (x48_MBSP) {
s += 4;
x48_MBSP.binarySize(s);
}
if (x4c_SIZE)
{
if (x4c_SIZE) {
s += 4;
x4c_SIZE.binarySize(s);
}
if (x50_ROTA)
{
if (x50_ROTA) {
s += 4;
x50_ROTA.binarySize(s);
}
if (x54_TEXR)
{
if (x54_TEXR) {
s += 4;
x54_TEXR.binarySize(s);
}
if (x58_TIND)
{
if (x58_TIND) {
s += 4;
x58_TIND.binarySize(s);
}
if (x5c_PMDL)
{
if (x5c_PMDL) {
s += 4;
x5c_PMDL.binarySize(s);
}
if (x6c_PMOP)
{
if (x6c_PMOP) {
s += 4;
x6c_PMOP.binarySize(s);
}
if (x70_PMRT)
{
if (x70_PMRT) {
s += 4;
x70_PMRT.binarySize(s);
}
if (x74_PMSC)
{
if (x74_PMSC) {
s += 4;
x74_PMSC.binarySize(s);
}
if (x78_PMCL)
{
if (x78_PMCL) {
s += 4;
x78_PMCL.binarySize(s);
}
if (x7c_VEL1)
{
if (x7c_VEL1) {
s += 4;
x7c_VEL1.binarySize(s);
}
if (x80_VEL2)
{
if (x80_VEL2) {
s += 4;
x80_VEL2.binarySize(s);
}
if (x84_VEL3)
{
if (x84_VEL3) {
s += 4;
x84_VEL3.binarySize(s);
}
if (x88_VEL4)
{
if (x88_VEL4) {
s += 4;
x88_VEL4.binarySize(s);
}
if (x8c_ICTS)
{
if (x8c_ICTS) {
s += 4;
x8c_ICTS.binarySize(s);
}
if (x9c_NCSY)
{
if (x9c_NCSY) {
s += 4;
x9c_NCSY.binarySize(s);
}
if (xa0_CSSD)
{
if (xa0_CSSD) {
s += 4;
xa0_CSSD.binarySize(s);
}
if (xa4_IDTS)
{
if (xa4_IDTS) {
s += 4;
xa4_IDTS.binarySize(s);
}
if (xb4_NDSY)
{
if (xb4_NDSY) {
s += 4;
xb4_NDSY.binarySize(s);
}
if (xb8_IITS)
{
if (xb8_IITS) {
s += 4;
xb8_IITS.binarySize(s);
}
if (xc8_PISY)
{
if (xc8_PISY) {
s += 4;
xc8_PISY.binarySize(s);
}
if (xcc_SISY)
{
if (xcc_SISY) {
s += 4;
xcc_SISY.binarySize(s);
}
if (xd0_KSSM)
{
if (xd0_KSSM) {
s += 4;
xd0_KSSM.binarySize(s);
}
if (xd4_SSWH)
{
if (xd4_SSWH) {
s += 4;
xd4_SSWH.binarySize(s);
}
if (xd8_SELC)
{
if (xd8_SELC) {
s += 4;
xd8_SELC.binarySize(s);
}
if (xe4_SSSD)
{
if (xe4_SSSD) {
s += 4;
xe4_SSSD.binarySize(s);
}
if (xe8_SSPO)
{
if (xe8_SSPO) {
s += 4;
xe8_SSPO.binarySize(s);
}
if (xf8_SESD)
{
if (xf8_SESD) {
s += 4;
xf8_SESD.binarySize(s);
}
if (xfc_SEPO)
{
if (xfc_SEPO) {
s += 4;
xfc_SEPO.binarySize(s);
}
if (xec_PMLC)
{
if (xec_PMLC) {
s += 4;
xec_PMLC.binarySize(s);
}
if (x100_LTYP)
{
if (x100_LTYP) {
s += 4;
x100_LTYP.binarySize(s);
}
if (x104_LCLR)
{
if (x104_LCLR) {
s += 4;
x104_LCLR.binarySize(s);
}
if (x108_LINT)
{
if (x108_LINT) {
s += 4;
x108_LINT.binarySize(s);
}
if (x10c_LOFF)
{
if (x10c_LOFF) {
s += 4;
x10c_LOFF.binarySize(s);
}
if (x110_LDIR)
{
if (x110_LDIR) {
s += 4;
x110_LDIR.binarySize(s);
}
if (x114_LFOT)
{
if (x114_LFOT) {
s += 4;
x114_LFOT.binarySize(s);
}
if (x118_LFOR)
{
if (x118_LFOR) {
s += 4;
x118_LFOR.binarySize(s);
}
if (x11c_LSLA)
{
if (x11c_LSLA) {
s += 4;
x11c_LSLA.binarySize(s);
}
if (x10c_ADV1)
{
if (x10c_ADV1) {
s += 4;
x10c_ADV1.binarySize(s);
}
if (x110_ADV2)
{
if (x110_ADV2) {
s += 4;
x110_ADV2.binarySize(s);
}
if (x114_ADV3)
{
if (x114_ADV3) {
s += 4;
x114_ADV3.binarySize(s);
}
if (x118_ADV4)
{
if (x118_ADV4) {
s += 4;
x118_ADV4.binarySize(s);
}
if (x11c_ADV5)
{
if (x11c_ADV5) {
s += 4;
x11c_ADV5.binarySize(s);
}
if (x120_ADV6)
{
if (x120_ADV6) {
s += 4;
x120_ADV6.binarySize(s);
}
if (x124_ADV7)
{
if (x124_ADV7) {
s += 4;
x124_ADV7.binarySize(s);
}
if (x128_ADV8)
{
if (x128_ADV8) {
s += 4;
x128_ADV8.binarySize(s);
}
}
template <class IDType>
void GPSM<IDType>::_read(typename Read::StreamT& r)
{
void GPSM<IDType>::_read(typename Read::StreamT& r) {
uint32_t clsId;
r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('GPSM'))
{
if (clsId != SBIG('GPSM')) {
LogModule.report(logvisor::Warning, "non GPSM provided to GPSM parser");
return;
}
r.readBytesToBuf(&clsId, 4);
while (clsId != SBIG('_END'))
{
switch (clsId)
{
while (clsId != SBIG('_END')) {
switch (clsId) {
case SBIG('PMCL'):
x78_PMCL.read(r);
break;
@ -1143,393 +1072,311 @@ void GPSM<IDType>::_read(typename Read::StreamT& r)
}
template <class IDType>
void GPSM<IDType>::_write(typename Write::StreamT& w) const
{
void GPSM<IDType>::_write(typename Write::StreamT& w) const {
w.writeBytes((atInt8*)"GPSM", 4);
if (x0_PSIV)
{
if (x0_PSIV) {
w.writeBytes((atInt8*)"PSIV", 4);
x0_PSIV.write(w);
}
if (x4_PSVM)
{
if (x4_PSVM) {
w.writeBytes((atInt8*)"PSVM", 4);
x4_PSVM.write(w);
}
if (x8_PSOV)
{
if (x8_PSOV) {
w.writeBytes((atInt8*)"PSOV", 4);
x8_PSOV.write(w);
}
if (xc_PSLT)
{
if (xc_PSLT) {
w.writeBytes((atInt8*)"PSLT", 4);
xc_PSLT.write(w);
}
if (x10_PSWT)
{
if (x10_PSWT) {
w.writeBytes((atInt8*)"PSWT", 4);
x10_PSWT.write(w);
}
if (x14_PSTS)
{
if (x14_PSTS) {
w.writeBytes((atInt8*)"PSTS", 4);
x14_PSTS.write(w);
}
if (x18_POFS)
{
if (x18_POFS) {
w.writeBytes((atInt8*)"POFS", 4);
x18_POFS.write(w);
}
if (x1c_SEED)
{
if (x1c_SEED) {
w.writeBytes((atInt8*)"SEED", 4);
x1c_SEED.write(w);
}
if (x20_LENG)
{
if (x20_LENG) {
w.writeBytes((atInt8*)"LENG", 4);
x20_LENG.write(w);
}
if (x24_WIDT)
{
if (x24_WIDT) {
w.writeBytes((atInt8*)"WIDT", 4);
x24_WIDT.write(w);
}
if (x28_MAXP)
{
if (x28_MAXP) {
w.writeBytes((atInt8*)"MAXP", 4);
x28_MAXP.write(w);
}
if (x2c_GRTE)
{
if (x2c_GRTE) {
w.writeBytes((atInt8*)"GRTE", 4);
x2c_GRTE.write(w);
}
if (x30_COLR)
{
if (x30_COLR) {
w.writeBytes((atInt8*)"COLR", 4);
x30_COLR.write(w);
}
if (x34_LTME)
{
if (x34_LTME) {
w.writeBytes((atInt8*)"LTME", 4);
x34_LTME.write(w);
}
if (x38_ILOC)
{
if (x38_ILOC) {
w.writeBytes((atInt8*)"ILOC", 4);
x38_ILOC.write(w);
}
if (x3c_IVEC)
{
if (x3c_IVEC) {
w.writeBytes((atInt8*)"IVEC", 4);
x3c_IVEC.write(w);
}
if (x40_EMTR)
{
if (x40_EMTR) {
w.writeBytes((atInt8*)"EMTR", 4);
x40_EMTR.write(w);
}
if (x44_24_LINE)
{
if (x44_24_LINE) {
w.writeBytes((atInt8*)"LINECNST\x01", 9);
}
if (x44_25_FXLL)
{
if (x44_25_FXLL) {
w.writeBytes((atInt8*)"FXLLCNST\x01", 9);
}
if (x44_26_AAPH)
{
if (x44_26_AAPH) {
w.writeBytes((atInt8*)"AAPHCNST\x01", 9);
}
if (x44_27_ZBUF)
{
if (x44_27_ZBUF) {
w.writeBytes((atInt8*)"ZBUFCNST\x01", 9);
}
if (x44_28_SORT)
{
if (x44_28_SORT) {
w.writeBytes((atInt8*)"SORTCNST\x01", 9);
}
if (x44_29_LIT_)
{
if (x44_29_LIT_) {
w.writeBytes((atInt8*)"LIT_CNST\x01", 9);
}
if (x44_30_MBLR)
{
if (x44_30_MBLR) {
w.writeBytes((atInt8*)"MBLRCNST\x01", 9);
}
if (x44_31_PMAB)
{
if (x44_31_PMAB) {
w.writeBytes((atInt8*)"PMABCNST\x01", 9);
}
if (x45_24_PMUS)
{
if (x45_24_PMUS) {
w.writeBytes((atInt8*)"PMUSCNST\x01", 9);
}
if (!x45_25_PMOO)
{
if (!x45_25_PMOO) {
w.writeBytes((atInt8*)"PMOOCNST\x00", 9);
}
if (x45_26_VMD1)
{
if (x45_26_VMD1) {
w.writeBytes((atInt8*)"VMD1CNST\x01", 9);
}
if (x45_27_VMD2)
{
if (x45_27_VMD2) {
w.writeBytes((atInt8*)"VMD2CNST\x01", 9);
}
if (x45_28_VMD3)
{
if (x45_28_VMD3) {
w.writeBytes((atInt8*)"VMD3CNST\x01", 9);
}
if (x45_29_VMD4)
{
if (x45_29_VMD4) {
w.writeBytes((atInt8*)"VMD4CNST\x01", 9);
}
if (x45_30_CIND)
{
if (x45_30_CIND) {
w.writeBytes((atInt8*)"CINDCNST\x01", 9);
}
if (x45_31_OPTS)
{
if (x45_31_OPTS) {
w.writeBytes((atInt8*)"OPTSCNST\x01", 9);
}
if (x30_30_ORNT)
{
if (x30_30_ORNT) {
w.writeBytes((atInt8*)"ORNTCNST\x01", 9);
}
if (x30_31_RSOP)
{
if (x30_31_RSOP) {
w.writeBytes((atInt8*)"RSOPCNST\x01", 9);
}
if (x48_MBSP)
{
if (x48_MBSP) {
w.writeBytes((atInt8*)"MBSP", 4);
x48_MBSP.write(w);
}
if (x4c_SIZE)
{
if (x4c_SIZE) {
w.writeBytes((atInt8*)"SIZE", 4);
x4c_SIZE.write(w);
}
if (x50_ROTA)
{
if (x50_ROTA) {
w.writeBytes((atInt8*)"ROTA", 4);
x50_ROTA.write(w);
}
if (x54_TEXR)
{
if (x54_TEXR) {
w.writeBytes((atInt8*)"TEXR", 4);
x54_TEXR.write(w);
}
if (x58_TIND)
{
if (x58_TIND) {
w.writeBytes((atInt8*)"TIND", 4);
x58_TIND.write(w);
}
if (x5c_PMDL)
{
if (x5c_PMDL) {
w.writeBytes((atInt8*)"PMDL", 4);
x5c_PMDL.write(w);
}
if (x6c_PMOP)
{
if (x6c_PMOP) {
w.writeBytes((atInt8*)"PMOP", 4);
x6c_PMOP.write(w);
}
if (x70_PMRT)
{
if (x70_PMRT) {
w.writeBytes((atInt8*)"PMRT", 4);
x70_PMRT.write(w);
}
if (x74_PMSC)
{
if (x74_PMSC) {
w.writeBytes((atInt8*)"PMSC", 4);
x74_PMSC.write(w);
}
if (x78_PMCL)
{
if (x78_PMCL) {
w.writeBytes((atInt8*)"PMCL", 4);
x78_PMCL.write(w);
}
if (x7c_VEL1)
{
if (x7c_VEL1) {
w.writeBytes((atInt8*)"VEL1", 4);
x7c_VEL1.write(w);
}
if (x80_VEL2)
{
if (x80_VEL2) {
w.writeBytes((atInt8*)"VEL2", 4);
x80_VEL2.write(w);
}
if (x84_VEL3)
{
if (x84_VEL3) {
w.writeBytes((atInt8*)"VEL3", 4);
x84_VEL3.write(w);
}
if (x88_VEL4)
{
if (x88_VEL4) {
w.writeBytes((atInt8*)"VEL4", 4);
x88_VEL4.write(w);
}
if (x8c_ICTS)
{
if (x8c_ICTS) {
w.writeBytes((atInt8*)"ICTS", 4);
x8c_ICTS.write(w);
}
if (x9c_NCSY)
{
if (x9c_NCSY) {
w.writeBytes((atInt8*)"NCSY", 4);
x9c_NCSY.write(w);
}
if (xa0_CSSD)
{
if (xa0_CSSD) {
w.writeBytes((atInt8*)"CSSD", 4);
xa0_CSSD.write(w);
}
if (xa4_IDTS)
{
if (xa4_IDTS) {
w.writeBytes((atInt8*)"IDTS", 4);
xa4_IDTS.write(w);
}
if (xb4_NDSY)
{
if (xb4_NDSY) {
w.writeBytes((atInt8*)"NDSY", 4);
xb4_NDSY.write(w);
}
if (xb8_IITS)
{
if (xb8_IITS) {
w.writeBytes((atInt8*)"IITS", 4);
xb8_IITS.write(w);
}
if (xc8_PISY)
{
if (xc8_PISY) {
w.writeBytes((atInt8*)"PISY", 4);
xc8_PISY.write(w);
}
if (xcc_SISY)
{
if (xcc_SISY) {
w.writeBytes((atInt8*)"SISY", 4);
xcc_SISY.write(w);
}
if (xd0_KSSM)
{
if (xd0_KSSM) {
w.writeBytes((atInt8*)"KSSM", 4);
xd0_KSSM.write(w);
}
if (xd4_SSWH)
{
if (xd4_SSWH) {
w.writeBytes((atInt8*)"SSWH", 4);
xd4_SSWH.write(w);
}
if (xd8_SELC)
{
if (xd8_SELC) {
w.writeBytes((atInt8*)"SELC", 4);
xd8_SELC.write(w);
}
if (xe4_SSSD)
{
if (xe4_SSSD) {
w.writeBytes((atInt8*)"SSSD", 4);
xe4_SSSD.write(w);
}
if (xe8_SSPO)
{
if (xe8_SSPO) {
w.writeBytes((atInt8*)"SSPO", 4);
xe8_SSPO.write(w);
}
if (xf8_SESD)
{
if (xf8_SESD) {
w.writeBytes((atInt8*)"SESD", 4);
xf8_SESD.write(w);
}
if (xfc_SEPO)
{
if (xfc_SEPO) {
w.writeBytes((atInt8*)"SEPO", 4);
xfc_SEPO.write(w);
}
if (xec_PMLC)
{
if (xec_PMLC) {
w.writeBytes((atInt8*)"PMLC", 4);
xec_PMLC.write(w);
}
if (x100_LTYP)
{
if (x100_LTYP) {
w.writeBytes((atInt8*)"LTYP", 4);
x100_LTYP.write(w);
}
if (x104_LCLR)
{
if (x104_LCLR) {
w.writeBytes((atInt8*)"LCLR", 4);
x104_LCLR.write(w);
}
if (x108_LINT)
{
if (x108_LINT) {
w.writeBytes((atInt8*)"LINT", 4);
x108_LINT.write(w);
}
if (x10c_LOFF)
{
if (x10c_LOFF) {
w.writeBytes((atInt8*)"LOFF", 4);
x10c_LOFF.write(w);
}
if (x110_LDIR)
{
if (x110_LDIR) {
w.writeBytes((atInt8*)"LDIR", 4);
x110_LDIR.write(w);
}
if (x114_LFOT)
{
if (x114_LFOT) {
w.writeBytes((atInt8*)"LFOT", 4);
x114_LFOT.write(w);
}
if (x118_LFOR)
{
if (x118_LFOR) {
w.writeBytes((atInt8*)"LFOR", 4);
x118_LFOR.write(w);
}
if (x11c_LSLA)
{
if (x11c_LSLA) {
w.writeBytes((atInt8*)"LSLA", 4);
x11c_LSLA.write(w);
}
if (x10c_ADV1)
{
if (x10c_ADV1) {
w.writeBytes((atInt8*)"ADV1", 4);
x10c_ADV1.write(w);
}
if (x110_ADV2)
{
if (x110_ADV2) {
w.writeBytes((atInt8*)"ADV2", 4);
x110_ADV2.write(w);
}
if (x114_ADV3)
{
if (x114_ADV3) {
w.writeBytes((atInt8*)"ADV3", 4);
x114_ADV3.write(w);
}
if (x118_ADV4)
{
if (x118_ADV4) {
w.writeBytes((atInt8*)"ADV4", 4);
x118_ADV4.write(w);
}
if (x11c_ADV5)
{
if (x11c_ADV5) {
w.writeBytes((atInt8*)"ADV5", 4);
x11c_ADV5.write(w);
}
if (x120_ADV6)
{
if (x120_ADV6) {
w.writeBytes((atInt8*)"ADV6", 4);
x120_ADV6.write(w);
}
if (x124_ADV7)
{
if (x124_ADV7) {
w.writeBytes((atInt8*)"ADV7", 4);
x124_ADV7.write(w);
}
if (x128_ADV8)
{
if (x128_ADV8) {
w.writeBytes((atInt8*)"ADV8", 4);
x128_ADV8.write(w);
}
@ -1540,8 +1387,7 @@ AT_SUBSPECIALIZE_DNA_YAML(GPSM<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(GPSM<UniqueID64>)
template <class IDType>
void GPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
void GPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
if (x54_TEXR.m_elem)
x54_TEXR.m_elem->gatherDependencies(pathsOut);
if (x58_TIND.m_elem)
@ -1560,11 +1406,9 @@ template struct GPSM<UniqueID32>;
template struct GPSM<UniqueID64>;
template <class IDType>
bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
GPSM<IDType> gpsm;
gpsm.read(rs);
athena::io::ToYAMLStream(gpsm, writer);
@ -1576,8 +1420,7 @@ template bool ExtractGPSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::Projec
template bool ExtractGPSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteGPSM(const GPSM<IDType>& gpsm, const hecl::ProjectPath& outPath)
{
bool WriteGPSM(const GPSM<IDType>& gpsm, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -1591,4 +1434,4 @@ bool WriteGPSM(const GPSM<IDType>& gpsm, const hecl::ProjectPath& outPath)
template bool WriteGPSM<UniqueID32>(const GPSM<UniqueID32>& gpsm, const hecl::ProjectPath& outPath);
template bool WriteGPSM<UniqueID64>(const GPSM<UniqueID64>& gpsm, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAParticle

View File

@ -4,12 +4,10 @@
#include "PAK.hpp"
#include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
struct GPSM : BigDNA
{
struct GPSM : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
VectorElementFactory x0_PSIV;
@ -29,14 +27,24 @@ struct GPSM : BigDNA
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;
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;
};
@ -80,10 +88,8 @@ struct GPSM : BigDNA
/* 0-00 additions */
ChildResourceFactory<IDType> xd8_SELC;
union
{
struct
{
union {
struct {
bool x30_30_ORNT : 1;
bool x30_31_RSOP : 1;
};
@ -98,10 +104,7 @@ struct GPSM : BigDNA
RealElementFactory x124_ADV7;
RealElementFactory x128_ADV8;
GPSM()
{
x45_25_PMOO = true;
}
GPSM() { x45_25_PMOO = true; }
void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
};
@ -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

View File

@ -2,98 +2,100 @@
#include "DNACommon.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
extern logvisor::Module LogModule;
struct IElement : BigDNAVYaml
{
struct IElement : BigDNAVYaml {
Delete _d;
virtual ~IElement() = default;
virtual const char* ClassID() const = 0;
const char* DNATypeV() const { return ClassID(); }
};
struct IRealElement : IElement {Delete _d2;};
struct RealElementFactory : BigDNA
{
struct IRealElement : IElement {
Delete _d2;
};
struct RealElementFactory : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
std::unique_ptr<IRealElement> m_elem;
operator bool() const { return m_elem.operator bool(); }
};
struct IIntElement : IElement {Delete _d2;};
struct IntElementFactory : BigDNA
{
struct IIntElement : IElement {
Delete _d2;
};
struct IntElementFactory : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
std::unique_ptr<IIntElement> m_elem;
operator bool() const { return m_elem.operator bool(); }
};
struct IVectorElement : IElement {Delete _d2;};
struct VectorElementFactory : BigDNA
{
struct IVectorElement : IElement {
Delete _d2;
};
struct VectorElementFactory : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
std::unique_ptr<IVectorElement> m_elem;
operator bool() const { return m_elem.operator bool(); }
};
struct IColorElement : IElement {Delete _d2;};
struct ColorElementFactory : BigDNA
{
struct IColorElement : IElement {
Delete _d2;
};
struct ColorElementFactory : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
std::unique_ptr<IColorElement> m_elem;
operator bool() const { return m_elem.operator bool(); }
};
struct IModVectorElement : IElement {Delete _d2;};
struct ModVectorElementFactory : BigDNA
{
struct IModVectorElement : IElement {
Delete _d2;
};
struct ModVectorElementFactory : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
std::unique_ptr<IModVectorElement> m_elem;
operator bool() const { return m_elem.operator bool(); }
};
struct IEmitterElement : IElement {Delete _d2;};
struct EmitterElementFactory : BigDNA
{
struct IEmitterElement : IElement {
Delete _d2;
};
struct EmitterElementFactory : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
std::unique_ptr<IEmitterElement> m_elem;
operator bool() const { return m_elem.operator bool(); }
};
struct IUVElement : IElement
{
struct IUVElement : IElement {
Delete _d2;
virtual void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const = 0;
};
struct BoolHelper : IElement
{
struct BoolHelper : IElement {
AT_DECL_EXPLICIT_DNA_YAML
bool value = false;
operator bool() const { return value; }
BoolHelper& operator=(bool val) {value = val; return *this;}
BoolHelper& operator=(bool val) {
value = val;
return *this;
}
const char* ClassID() const { return "BoolHelper"; }
};
struct RELifetimeTween : IRealElement
{
struct RELifetimeTween : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory a;
RealElementFactory b;
const char* ClassID() const { return "LFTW"; }
};
struct REConstant : IRealElement
{
struct REConstant : IRealElement {
AT_DECL_EXPLICIT_DNA_YAML
Value<float> val;
const char* ClassID() const { return "CNST"; }
};
struct RETimeChain : IRealElement
{
struct RETimeChain : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory a;
RealElementFactory b;
@ -101,16 +103,14 @@ struct RETimeChain : IRealElement
const char* ClassID() const { return "CHAN"; }
};
struct REAdd : IRealElement
{
struct REAdd : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory a;
RealElementFactory b;
const char* ClassID() const { return "ADD_"; }
};
struct REClamp : IRealElement
{
struct REClamp : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory min;
RealElementFactory max;
@ -118,8 +118,7 @@ struct REClamp : IRealElement
const char* ClassID() const { return "CLMP"; }
};
struct REKeyframeEmitter : IRealElement
{
struct REKeyframeEmitter : IRealElement {
AT_DECL_DNA_YAML
Value<atUint32> percentageTween;
Value<atUint32> unk1;
@ -132,32 +131,28 @@ struct REKeyframeEmitter : IRealElement
const char* ClassID() const { return percentageTween ? "KEYP" : "KEYE"; }
};
struct REInitialRandom : IRealElement
{
struct REInitialRandom : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory a;
RealElementFactory b;
const char* ClassID() const { return "IRND"; }
};
struct RERandom : IRealElement
{
struct RERandom : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory a;
RealElementFactory b;
const char* ClassID() const { return "RAND"; }
};
struct REMultiply : IRealElement
{
struct REMultiply : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory a;
RealElementFactory b;
const char* ClassID() const { return "MULT"; }
};
struct REPulse : IRealElement
{
struct REPulse : IRealElement {
AT_DECL_DNA_YAML
IntElementFactory aDuration;
IntElementFactory bDuration;
@ -166,22 +161,19 @@ struct REPulse : IRealElement
const char* ClassID() const { return "PULS"; }
};
struct RETimeScale : IRealElement
{
struct RETimeScale : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory dv;
const char* ClassID() const { return "SCAL"; }
};
struct RELifetimePercent : IRealElement
{
struct RELifetimePercent : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory percent;
const char* ClassID() const { return "RLPT"; }
};
struct RESineWave : IRealElement
{
struct RESineWave : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory frequency;
RealElementFactory amplitude;
@ -189,16 +181,14 @@ struct RESineWave : IRealElement
const char* ClassID() const { return "SINE"; }
};
struct REInitialSwitch : IRealElement
{
struct REInitialSwitch : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory a;
RealElementFactory b;
const char* ClassID() const { return "ISWT"; }
};
struct RECompareLessThan : IRealElement
{
struct RECompareLessThan : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory ca;
RealElementFactory cb;
@ -207,8 +197,7 @@ struct RECompareLessThan : IRealElement
const char* ClassID() const { return "CLTN"; }
};
struct RECompareEquals : IRealElement
{
struct RECompareEquals : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory ca;
RealElementFactory cb;
@ -217,119 +206,101 @@ struct RECompareEquals : IRealElement
const char* ClassID() const { return "CEQL"; }
};
struct REParticleAdvanceParam1 : IRealElement
{
struct REParticleAdvanceParam1 : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PAP1"; }
};
struct REParticleAdvanceParam2 : IRealElement
{
struct REParticleAdvanceParam2 : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PAP2"; }
};
struct REParticleAdvanceParam3 : IRealElement
{
struct REParticleAdvanceParam3 : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PAP3"; }
};
struct REParticleAdvanceParam4 : IRealElement
{
struct REParticleAdvanceParam4 : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PAP4"; }
};
struct REParticleAdvanceParam5 : IRealElement
{
struct REParticleAdvanceParam5 : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PAP5"; }
};
struct REParticleAdvanceParam6 : IRealElement
{
struct REParticleAdvanceParam6 : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PAP6"; }
};
struct REParticleAdvanceParam7 : IRealElement
{
struct REParticleAdvanceParam7 : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PAP7"; }
};
struct REParticleAdvanceParam8 : IRealElement
{
struct REParticleAdvanceParam8 : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PAP8"; }
};
struct REParticleSizeOrLineLength : IRealElement
{
struct REParticleSizeOrLineLength : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PSLL"; }
};
struct REParticleRotationOrLineWidth : IRealElement
{
struct REParticleRotationOrLineWidth : IRealElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PRLW"; }
};
struct RESubtract : IRealElement
{
struct RESubtract : IRealElement {
AT_DECL_DNA_YAML
RealElementFactory a;
RealElementFactory b;
const char* ClassID() const { return "SUB_"; }
};
struct REVectorMagnitude : IRealElement
{
struct REVectorMagnitude : IRealElement {
AT_DECL_DNA_YAML
VectorElementFactory vec;
const char* ClassID() const { return "VMAG"; }
};
struct REVectorXToReal : IRealElement
{
struct REVectorXToReal : IRealElement {
AT_DECL_DNA_YAML
VectorElementFactory vec;
const char* ClassID() const { return "VXTR"; }
};
struct REVectorYToReal : IRealElement
{
struct REVectorYToReal : IRealElement {
AT_DECL_DNA_YAML
VectorElementFactory vec;
const char* ClassID() const { return "VYTR"; }
};
struct REVectorZToReal : IRealElement
{
struct REVectorZToReal : IRealElement {
AT_DECL_DNA_YAML
VectorElementFactory vec;
const char* ClassID() const { return "VZTR"; }
};
struct RECEXT : IRealElement
{
struct RECEXT : IRealElement {
AT_DECL_DNA_YAML
IntElementFactory index;
const char* ClassID() const { return "CEXT"; }
};
struct REIntTimesReal : IRealElement
{
struct REIntTimesReal : IRealElement {
AT_DECL_DNA_YAML
IntElementFactory a;
RealElementFactory b;
const char* ClassID() const { return "ITRL"; }
};
struct IEKeyframeEmitter : IIntElement
{
struct IEKeyframeEmitter : IIntElement {
AT_DECL_DNA_YAML
Value<atUint32> percentageTween;
Value<atUint32> unk1;
@ -342,16 +313,14 @@ struct IEKeyframeEmitter : IIntElement
const char* ClassID() const { return percentageTween ? "KEYP" : "KEYE"; }
};
struct IEDeath : IIntElement
{
struct IEDeath : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory passthrough;
IntElementFactory thresholdFrame;
const char* ClassID() const { return "DETH"; }
};
struct IEClamp : IIntElement
{
struct IEClamp : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory min;
IntElementFactory max;
@ -359,8 +328,7 @@ struct IEClamp : IIntElement
const char* ClassID() const { return "CLMP"; }
};
struct IETimeChain : IIntElement
{
struct IETimeChain : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory a;
IntElementFactory b;
@ -368,45 +336,39 @@ struct IETimeChain : IIntElement
const char* ClassID() const { return "CHAN"; }
};
struct IEAdd : IIntElement
{
struct IEAdd : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory a;
IntElementFactory b;
const char* ClassID() const { return "ADD_"; }
};
struct IEConstant : IIntElement
{
struct IEConstant : IIntElement {
AT_DECL_EXPLICIT_DNA_YAML
Value<atUint32> val;
const char* ClassID() const { return "CNST"; }
};
struct IEImpulse : IIntElement
{
struct IEImpulse : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory val;
const char* ClassID() const { return "IMPL"; }
};
struct IELifetimePercent : IIntElement
{
struct IELifetimePercent : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory percent;
const char* ClassID() const { return "ILPT"; }
};
struct IEInitialRandom : IIntElement
{
struct IEInitialRandom : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory a;
IntElementFactory b;
const char* ClassID() const { return "IRND"; }
};
struct IEPulse : IIntElement
{
struct IEPulse : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory aDuration;
IntElementFactory bDuration;
@ -415,16 +377,14 @@ struct IEPulse : IIntElement
const char* ClassID() const { return "PULS"; }
};
struct IEMultiply : IIntElement
{
struct IEMultiply : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory a;
IntElementFactory b;
const char* ClassID() const { return "MULT"; }
};
struct IESampleAndHold : IIntElement
{
struct IESampleAndHold : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory val;
IntElementFactory waitMin;
@ -432,53 +392,46 @@ struct IESampleAndHold : IIntElement
const char* ClassID() const { return "SPAH"; }
};
struct IERandom : IIntElement
{
struct IERandom : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory a;
IntElementFactory b;
const char* ClassID() const { return "RAND"; }
};
struct IETimeScale : IIntElement
{
struct IETimeScale : IIntElement {
AT_DECL_DNA_YAML
RealElementFactory dv;
const char* ClassID() const { return "TSCL"; }
};
struct IEGTCP : IIntElement
{
struct IEGTCP : IIntElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "GTCP"; }
};
struct IEModulo : IIntElement
{
struct IEModulo : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory a;
IntElementFactory b;
const char* ClassID() const { return "MODU"; }
};
struct IESubtract : IIntElement
{
struct IESubtract : IIntElement {
AT_DECL_DNA_YAML
IntElementFactory direction;
IntElementFactory baseRadius;
const char* ClassID() const { return "SUB_"; }
};
struct VECone : IVectorElement
{
struct VECone : IVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory a;
RealElementFactory b;
const char* ClassID() const { return "CONE"; }
};
struct VETimeChain : IVectorElement
{
struct VETimeChain : IVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory a;
VectorElementFactory b;
@ -486,8 +439,7 @@ struct VETimeChain : IVectorElement
const char* ClassID() const { return "CHAN"; }
};
struct VEAngleCone : IVectorElement
{
struct VEAngleCone : IVectorElement {
AT_DECL_DNA_YAML
RealElementFactory angleXBias;
RealElementFactory angleYBias;
@ -497,16 +449,14 @@ struct VEAngleCone : IVectorElement
const char* ClassID() const { return "ANGC"; }
};
struct VEAdd : IVectorElement
{
struct VEAdd : IVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory a;
VectorElementFactory b;
const char* ClassID() const { return "ADD_"; }
};
struct VECircleCluster : IVectorElement
{
struct VECircleCluster : IVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory circleOffset;
VectorElementFactory circleNormal;
@ -515,15 +465,13 @@ struct VECircleCluster : IVectorElement
const char* ClassID() const { return "CCLU"; }
};
struct VEConstant : IVectorElement
{
struct VEConstant : IVectorElement {
AT_DECL_EXPLICIT_DNA_YAML
RealElementFactory comps[3];
const char* ClassID() const { return "CNST"; }
};
struct VECircle : IVectorElement
{
struct VECircle : IVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory circleOffset;
VectorElementFactory circleNormal;
@ -533,8 +481,7 @@ struct VECircle : IVectorElement
const char* ClassID() const { return "CIRC"; }
};
struct VEKeyframeEmitter : IVectorElement
{
struct VEKeyframeEmitter : IVectorElement {
AT_DECL_DNA_YAML
Value<atUint32> percentageTween;
Value<atUint32> unk1;
@ -547,23 +494,20 @@ struct VEKeyframeEmitter : IVectorElement
const char* ClassID() const { return percentageTween ? "KEYP" : "KEYE"; }
};
struct VEMultiply : IVectorElement
{
struct VEMultiply : IVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory a;
VectorElementFactory b;
const char* ClassID() const { return "MULT"; }
};
struct VERealToVector : IVectorElement
{
struct VERealToVector : IVectorElement {
AT_DECL_DNA_YAML
RealElementFactory a;
const char* ClassID() const { return "RTOV"; }
};
struct VEPulse : IVectorElement
{
struct VEPulse : IVectorElement {
AT_DECL_DNA_YAML
IntElementFactory aDuration;
IntElementFactory bDuration;
@ -572,45 +516,38 @@ struct VEPulse : IVectorElement
const char* ClassID() const { return "PULS"; }
};
struct VEParticleVelocity : IVectorElement
{
struct VEParticleVelocity : IVectorElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PVEL"; }
};
struct VESPOS : IVectorElement
{
struct VESPOS : IVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory a;
const char* ClassID() const { return "SPOS"; }
};
struct VEPLCO : IVectorElement
{
struct VEPLCO : IVectorElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PLCO"; }
};
struct VEPLOC : IVectorElement
{
struct VEPLOC : IVectorElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PLOC"; }
};
struct VEPSOR : IVectorElement
{
struct VEPSOR : IVectorElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PSOR"; }
};
struct VEPSOF : IVectorElement
{
struct VEPSOF : IVectorElement {
AT_DECL_DNA_YAML
const char* ClassID() const { return "PSOF"; }
};
struct CEKeyframeEmitter : IColorElement
{
struct CEKeyframeEmitter : IColorElement {
AT_DECL_DNA_YAML
Value<atUint32> percentageTween;
Value<atUint32> unk1;
@ -623,15 +560,13 @@ struct CEKeyframeEmitter : IColorElement
const char* ClassID() const { return percentageTween ? "KEYP" : "KEYE"; }
};
struct CEConstant : IColorElement
{
struct CEConstant : IColorElement {
AT_DECL_EXPLICIT_DNA_YAML
RealElementFactory comps[4];
const char* ClassID() const { return "CNST"; }
};
struct CETimeChain : IColorElement
{
struct CETimeChain : IColorElement {
AT_DECL_DNA_YAML
ColorElementFactory a;
ColorElementFactory b;
@ -639,8 +574,7 @@ struct CETimeChain : IColorElement
const char* ClassID() const { return "CHAN"; }
};
struct CEFadeEnd : IColorElement
{
struct CEFadeEnd : IColorElement {
AT_DECL_DNA_YAML
ColorElementFactory a;
ColorElementFactory b;
@ -649,8 +583,7 @@ struct CEFadeEnd : IColorElement
const char* ClassID() const { return "CFDE"; }
};
struct CEFade : IColorElement
{
struct CEFade : IColorElement {
AT_DECL_DNA_YAML
ColorElementFactory a;
ColorElementFactory b;
@ -658,8 +591,7 @@ struct CEFade : IColorElement
const char* ClassID() const { return "FADE"; }
};
struct CEPulse : IColorElement
{
struct CEPulse : IColorElement {
AT_DECL_DNA_YAML
IntElementFactory aDuration;
IntElementFactory bDuration;
@ -668,8 +600,7 @@ struct CEPulse : IColorElement
const char* ClassID() const { return "PULS"; }
};
struct MVEImplosion : IModVectorElement
{
struct MVEImplosion : IModVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory implodePoint;
RealElementFactory velocityScale;
@ -679,8 +610,7 @@ struct MVEImplosion : IModVectorElement
const char* ClassID() const { return "IMPL"; }
};
struct MVEExponentialImplosion : IModVectorElement
{
struct MVEExponentialImplosion : IModVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory implodePoint;
RealElementFactory velocityScale;
@ -690,8 +620,7 @@ struct MVEExponentialImplosion : IModVectorElement
const char* ClassID() const { return "EMPL"; }
};
struct MVETimeChain : IModVectorElement
{
struct MVETimeChain : IModVectorElement {
AT_DECL_DNA_YAML
ModVectorElementFactory a;
ModVectorElementFactory b;
@ -699,8 +628,7 @@ struct MVETimeChain : IModVectorElement
const char* ClassID() const { return "CHAN"; }
};
struct MVEBounce : IModVectorElement
{
struct MVEBounce : IModVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory planePoint;
VectorElementFactory planeNormal;
@ -710,37 +638,32 @@ struct MVEBounce : IModVectorElement
const char* ClassID() const { return "BNCE"; }
};
struct MVEConstant : IModVectorElement
{
struct MVEConstant : IModVectorElement {
AT_DECL_EXPLICIT_DNA_YAML
RealElementFactory comps[3];
const char* ClassID() const { return "CNST"; }
};
struct MVEGravity : IModVectorElement
{
struct MVEGravity : IModVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory acceleration;
const char* ClassID() const { return "GRAV"; }
};
struct MVEExplode : IModVectorElement
{
struct MVEExplode : IModVectorElement {
AT_DECL_DNA_YAML
RealElementFactory impulseMagnitude;
RealElementFactory falloffFactor;
const char* ClassID() const { return "EXPL"; }
};
struct MVESetPosition : IModVectorElement
{
struct MVESetPosition : IModVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory position;
const char* ClassID() const { return "SPOS"; }
};
struct MVELinearImplosion : IModVectorElement
{
struct MVELinearImplosion : IModVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory implodePoint;
RealElementFactory velocityScale;
@ -750,8 +673,7 @@ struct MVELinearImplosion : IModVectorElement
const char* ClassID() const { return "LMPL"; }
};
struct MVEPulse : IModVectorElement
{
struct MVEPulse : IModVectorElement {
AT_DECL_DNA_YAML
IntElementFactory aDuration;
IntElementFactory bDuration;
@ -760,16 +682,14 @@ struct MVEPulse : IModVectorElement
const char* ClassID() const { return "PULS"; }
};
struct MVEWind : IModVectorElement
{
struct MVEWind : IModVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory windVelocity;
RealElementFactory factor;
const char* ClassID() const { return "WIND"; }
};
struct MVESwirl : IModVectorElement
{
struct MVESwirl : IModVectorElement {
AT_DECL_DNA_YAML
VectorElementFactory helixPoint;
VectorElementFactory curveBinormal;
@ -778,16 +698,14 @@ struct MVESwirl : IModVectorElement
const char* ClassID() const { return "SWRL"; }
};
struct EESimpleEmitter : IEmitterElement
{
struct EESimpleEmitter : IEmitterElement {
AT_DECL_DNA_YAML
VectorElementFactory position;
VectorElementFactory velocity;
const char* ClassID() const { return "SEMR"; }
};
struct VESphere : IEmitterElement
{
struct VESphere : IEmitterElement {
AT_DECL_DNA_YAML
VectorElementFactory sphereOrigin;
RealElementFactory sphereRadius;
@ -795,8 +713,7 @@ struct VESphere : IEmitterElement
const char* ClassID() const { return "SPHE"; }
};
struct VEAngleSphere : IEmitterElement
{
struct VEAngleSphere : IEmitterElement {
AT_DECL_DNA_YAML
VectorElementFactory sphereOrigin;
RealElementFactory sphereRadius;
@ -808,29 +725,25 @@ struct VEAngleSphere : IEmitterElement
const char* ClassID() const { return "ASPH"; }
};
struct EESimpleEmitterTR : EESimpleEmitter
{
struct EESimpleEmitterTR : EESimpleEmitter {
AT_DECL_EXPLICIT_DNA_YAML
const char* ClassID() const { return "SETR"; }
};
template <class IDType>
struct UVEConstant : IUVElement
{
struct UVEConstant : IUVElement {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
CastIDToZero<IDType> tex;
const char* ClassID() const { return "CNST"; }
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
g_curSpec->flattenDependencies(tex, pathsOut);
}
};
template <class IDType>
struct UVEAnimTexture : IUVElement
{
struct UVEAnimTexture : IUVElement {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
CastIDToZero<IDType> tex;
@ -842,15 +755,13 @@ struct UVEAnimTexture : IUVElement
Value<bool> loop = false;
const char* ClassID() const { return "ATEX"; }
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
g_curSpec->flattenDependencies(tex, pathsOut);
}
};
template <class IDType>
struct UVElementFactory : BigDNA
{
struct UVElementFactory : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
DNAFourCC m_type;
@ -859,15 +770,13 @@ struct UVElementFactory : BigDNA
};
template <class IDType>
struct SpawnSystemKeyframeData : BigDNA
{
struct SpawnSystemKeyframeData : BigDNA {
Value<atUint32> a;
Value<atUint32> b;
Value<atUint32> endFrame;
Value<atUint32> d;
struct SpawnSystemKeyframeInfo : BigDNA
{
struct SpawnSystemKeyframeInfo : BigDNA {
IDType id;
Value<atUint32> a;
Value<atUint32> b;
@ -882,8 +791,7 @@ struct SpawnSystemKeyframeData : BigDNA
operator bool() const { return spawns.size() != 0; }
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
for (const auto& p : spawns)
for (const SpawnSystemKeyframeInfo& info : p.second)
g_curSpec->flattenDependencies(info.id, pathsOut);
@ -891,13 +799,11 @@ struct SpawnSystemKeyframeData : BigDNA
};
template <class IDType>
struct ChildResourceFactory : BigDNA
{
struct ChildResourceFactory : BigDNA {
IDType id;
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
operator bool() const { return id.operator bool(); }
};
}
} // namespace DataSpec::DNAParticle

View File

@ -4,25 +4,21 @@
#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)
{
: 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)
{
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)
{
for (atUint32 chId : origBone.linked) {
if (chId == origBone.parentId)
continue;
atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId);
@ -35,21 +31,16 @@ RigInverter<CINFType>::Bone::Bone(const CINFType& cinf, const typename CINFType:
if (bName)
isLCTR = bName->find("_LCTR") != std::string::npos;
if (parentIdx == -1)
{
if (parentIdx == -1) {
/* Root will always use +Y tail */
m_tail = naturalTail;
}
else if (actualChildren)
{
} else if (actualChildren) {
/* Position tail to average of children */
for (atUint32 chId : origBone.linked)
{
for (atUint32 chId : origBone.linked) {
if (chId == origBone.parentId)
continue;
atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId);
if (chIdx != -1)
{
if (chIdx != -1) {
const typename CINFType::Bone& chBone = cinf.bones[chIdx];
m_tail += chBone.origin;
}
@ -59,19 +50,14 @@ RigInverter<CINFType>::Bone::Bone(const CINFType& cinf, const typename CINFType:
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)
{
} else if (parentIdx != -1) {
/* Extrapolate by delta with parent */
m_tail = boneOrigin + m_parentDelta;
float deltaMag = m_parentDelta.magnitude();
if (deltaMag < 0.001f)
{
if (deltaMag < 0.001f) {
deltaMag = 0.5f;
m_tail = naturalTail;
}
else if (deltaMag > 0.5f)
{
} else if (deltaMag > 0.5f) {
/* Extreme bones capped to +0.5 value */
deltaMag = 0.5f;
m_tail = boneOrigin + m_parentDelta.normalized() * 0.5f;
@ -79,18 +65,14 @@ RigInverter<CINFType>::Bone::Bone(const CINFType& cinf, const typename CINFType:
if (isLCTR)
m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * deltaMag;
}
else
{
} else {
/* Fallback to +Y tail */
m_tail = naturalTail;
}
}
template <class CINFType>
RigInverter<CINFType>::RigInverter(const CINFType& cinf)
: m_cinf(cinf)
{
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);
@ -98,24 +80,17 @@ RigInverter<CINFType>::RigInverter(const CINFType& cinf)
template <class CINFType>
RigInverter<CINFType>::RigInverter(const CINFType& cinf,
const std::unordered_map<std::string,
hecl::blender::Matrix3f>& matrices)
: m_cinf(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)
{
for (const typename CINFType::Bone& b : cinf.bones) {
m_bones.emplace_back(cinf, b);
const std::string* name = cinf.getBoneNameFromId(b.id);
if (name)
{
if (name) {
auto search = matrices.find(*name);
if (search != matrices.cend())
{
zeus::CMatrix3f boneMtx(search->second[0],
search->second[1],
search->second[2]);
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;
}
@ -124,9 +99,7 @@ RigInverter<CINFType>::RigInverter(const CINFType& cinf,
}
template <class CINFType>
zeus::CQuaternion
RigInverter<CINFType>::invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const
{
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;
@ -134,12 +107,10 @@ RigInverter<CINFType>::invertRotation(atUint32 boneId, const zeus::CQuaternion&
}
template <class CINFType>
zeus::CVector3f
RigInverter<CINFType>::invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const
{
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)
{
if (b.m_origBone.id == boneId) {
zeus::CVector3f localPos = origPos;
if (subDelta)
localPos -= b.m_parentDelta;
@ -149,9 +120,7 @@ RigInverter<CINFType>::invertPosition(atUint32 boneId, const zeus::CVector3f& or
}
template <class CINFType>
zeus::CQuaternion
RigInverter<CINFType>::restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const
{
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;
@ -159,12 +128,10 @@ RigInverter<CINFType>::restoreRotation(atUint32 boneId, const zeus::CQuaternion&
}
template <class CINFType>
zeus::CVector3f
RigInverter<CINFType>::restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const
{
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)
{
if (b.m_origBone.id == boneId) {
zeus::CVector3f localPos = b.m_inverter * origPos;
if (subDelta)
localPos += b.m_parentDelta;
@ -177,4 +144,4 @@ template class RigInverter<DNAMP1::CINF>;
template class RigInverter<DNAMP2::CINF>;
template class RigInverter<DNAMP3::CINF>;
}
} // namespace DataSpec::DNAANIM

View File

@ -5,17 +5,14 @@
#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
{
struct Bone {
const typename CINFType::Bone& m_origBone;
zeus::CMatrix3f m_inverter;
zeus::CMatrix3f m_restorer;
@ -23,13 +20,14 @@ public:
zeus::CVector3f m_parentDelta;
Bone(const CINFType& cinf, const typename CINFType::Bone& origBone);
};
private:
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);
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; }
@ -40,5 +38,4 @@ public:
zeus::CVector3f restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const;
};
}
} // namespace DataSpec::DNAANIM

View File

@ -2,28 +2,17 @@
#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
{
struct Header : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> magic;
Value<atUint32> version;
Value<atUint32> areaCount;
};
struct EnvironmentVariable : BigDNA
{
struct EnvironmentVariable : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> unk1;
@ -31,16 +20,14 @@ struct EnvironmentVariable : BigDNA
Value<atUint32> unk3;
};
struct Layer : BigDNA
{
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)
{
static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
SAVW savw;
savw.read(rs);
athena::io::FileWriter writer(outPath.getAbsolutePath());
@ -48,5 +35,4 @@ static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath
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)
{
std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader) {
uint32_t magic = reader.readUint32Big();
if (magic != 0x87654321)
{
if (magic != 0x87654321) {
LogDNACommon.report(logvisor::Error, "invalid STRG magic");
return std::unique_ptr<ISTRG>();
}
uint32_t version = reader.readUint32Big();
switch (version)
{
case 0:
{
switch (version) {
case 0: {
DNAMP1::STRG* newStrg = new DNAMP1::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
case 1:
{
case 1: {
DNAMP2::STRG* newStrg = new DNAMP2::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
case 3:
{
case 3: {
DNAMP3::STRG* newStrg = new DNAMP3::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
default: break;
default:
break;
}
return std::unique_ptr<ISTRG>();
}
}
} // namespace DataSpec

View File

@ -7,10 +7,8 @@
#include <athena/FileWriter.hpp>
#include "DNACommon.hpp"
namespace DataSpec
{
struct ISTRG : BigDNAVYaml
{
namespace DataSpec {
struct ISTRG : BigDNAVYaml {
virtual ~ISTRG() = default;
virtual size_t count() const = 0;
@ -23,5 +21,4 @@ struct ISTRG : BigDNAVYaml
};
std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader);
}
} // namespace DataSpec

View File

@ -1,29 +1,27 @@
#include "SWHC.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <>
const char* SWSH<UniqueID32>::DNAType() { return "SWSH<UniqueID32>"; }
const char* SWSH<UniqueID32>::DNAType() {
return "SWSH<UniqueID32>";
}
template <>
const char* SWSH<UniqueID64>::DNAType() { return "SWSH<UniqueID64>"; }
const char* SWSH<UniqueID64>::DNAType() {
return "SWSH<UniqueID64>";
}
template <class IDType>
void SWSH<IDType>::_read(typename BigDNA::ReadYaml::StreamT& r)
{
for (const auto& elem : r.getCurNode()->m_mapChildren)
{
if (elem.first.size() < 4)
{
void SWSH<IDType>::_read(typename BigDNA::ReadYaml::StreamT& 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()))
{
if (auto rec = r.enterSubRecord(elem.first.c_str())) {
switch (*reinterpret_cast<const uint32_t*>(elem.first.data())) {
case SBIG('PSLT'):
x0_PSLT.read(r);
break;
@ -116,8 +114,7 @@ void SWSH<IDType>::_read(typename BigDNA::ReadYaml::StreamT& r)
}
template <class IDType>
void SWSH<IDType>::_write(typename BigDNA::WriteYaml::StreamT& w) const
{
void SWSH<IDType>::_write(typename BigDNA::WriteYaml::StreamT& w) const {
if (x0_PSLT)
if (auto rec = w.enterSubRecord("PSLT"))
x0_PSLT.write(w);
@ -194,93 +191,74 @@ void SWSH<IDType>::_write(typename BigDNA::WriteYaml::StreamT& w) const
w.writeBool("CRND", true);
}
template <class IDType>
void SWSH<IDType>::_binarySize(typename BigDNA::BinarySize::StreamT& s) const
{
void SWSH<IDType>::_binarySize(typename BigDNA::BinarySize::StreamT& s) const {
s += 4;
if (x0_PSLT)
{
if (x0_PSLT) {
s += 4;
x0_PSLT.binarySize(s);
}
if (x4_TIME)
{
if (x4_TIME) {
s += 4;
x4_TIME.binarySize(s);
}
if (x8_LRAD)
{
if (x8_LRAD) {
s += 4;
x8_LRAD.binarySize(s);
}
if (xc_RRAD)
{
if (xc_RRAD) {
s += 4;
xc_RRAD.binarySize(s);
}
if (x10_LENG)
{
if (x10_LENG) {
s += 4;
x10_LENG.binarySize(s);
}
if (x14_COLR)
{
if (x14_COLR) {
s += 4;
x14_COLR.binarySize(s);
}
if (x18_SIDE)
{
if (x18_SIDE) {
s += 4;
x18_SIDE.binarySize(s);
}
if (x1c_IROT)
{
if (x1c_IROT) {
s += 4;
x1c_IROT.binarySize(s);
}
if (x20_ROTM)
{
if (x20_ROTM) {
s += 4;
x20_ROTM.binarySize(s);
}
if (x24_POFS)
{
if (x24_POFS) {
s += 4;
x24_POFS.binarySize(s);
}
if (x28_IVEL)
{
if (x28_IVEL) {
s += 4;
x28_IVEL.binarySize(s);
}
if (x2c_NPOS)
{
if (x2c_NPOS) {
s += 4;
x2c_NPOS.binarySize(s);
}
if (x30_VELM)
{
if (x30_VELM) {
s += 4;
x30_VELM.binarySize(s);
}
if (x34_VLM2)
{
if (x34_VLM2) {
s += 4;
x34_VLM2.binarySize(s);
}
if (x38_SPLN)
{
if (x38_SPLN) {
s += 4;
x38_SPLN.binarySize(s);
}
if (x3c_TEXR)
{
if (x3c_TEXR) {
s += 4;
x3c_TEXR.binarySize(s);
}
if (x40_TSPN)
{
if (x40_TSPN) {
s += 4;
x40_TSPN.binarySize(s);
}
@ -309,21 +287,17 @@ void SWSH<IDType>::_binarySize(typename BigDNA::BinarySize::StreamT& s) const
}
template <class IDType>
void SWSH<IDType>::_read(typename BigDNA::Read::StreamT& r)
{
void SWSH<IDType>::_read(typename BigDNA::Read::StreamT& r) {
uint32_t clsId;
r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('SWSH'))
{
if (clsId != SBIG('SWSH')) {
LogModule.report(logvisor::Warning, "non SWSH provided to SWSH parser");
return;
}
r.readBytesToBuf(&clsId, 4);
while (clsId != SBIG('_END'))
{
switch(clsId)
{
while (clsId != SBIG('_END')) {
switch (clsId) {
case SBIG('PSLT'):
x0_PSLT.read(r);
break;
@ -428,91 +402,73 @@ void SWSH<IDType>::_read(typename BigDNA::Read::StreamT& r)
}
template <class IDType>
void SWSH<IDType>::_write(typename BigDNA::Write::StreamT& w) const
{
void SWSH<IDType>::_write(typename BigDNA::Write::StreamT& w) const {
w.writeBytes((atInt8*)"SWSH", 4);
if (x0_PSLT)
{
if (x0_PSLT) {
w.writeBytes((atInt8*)"PSLT", 4);
x0_PSLT.write(w);
}
if (x4_TIME)
{
if (x4_TIME) {
w.writeBytes((atInt8*)"TIME", 4);
x4_TIME.write(w);
}
if (x8_LRAD)
{
if (x8_LRAD) {
w.writeBytes((atInt8*)"LRAD", 4);
x8_LRAD.write(w);
}
if (xc_RRAD)
{
if (xc_RRAD) {
w.writeBytes((atInt8*)"RRAD", 4);
xc_RRAD.write(w);
}
if (x10_LENG)
{
if (x10_LENG) {
w.writeBytes((atInt8*)"LENG", 4);
x10_LENG.write(w);
}
if (x14_COLR)
{
if (x14_COLR) {
w.writeBytes((atInt8*)"COLR", 4);
x14_COLR.write(w);
}
if (x18_SIDE)
{
if (x18_SIDE) {
w.writeBytes((atInt8*)"SIDE", 4);
x18_SIDE.write(w);
}
if (x1c_IROT)
{
if (x1c_IROT) {
w.writeBytes((atInt8*)"IROT", 4);
x1c_IROT.write(w);
}
if (x20_ROTM)
{
if (x20_ROTM) {
w.writeBytes((atInt8*)"ROTM", 4);
x20_ROTM.write(w);
}
if (x24_POFS)
{
if (x24_POFS) {
w.writeBytes((atInt8*)"POFS", 4);
x24_POFS.write(w);
}
if (x28_IVEL)
{
if (x28_IVEL) {
w.writeBytes((atInt8*)"IVEL", 4);
x28_IVEL.write(w);
}
if (x2c_NPOS)
{
if (x2c_NPOS) {
w.writeBytes((atInt8*)"NPOS", 4);
x2c_NPOS.write(w);
}
if (x30_VELM)
{
if (x30_VELM) {
w.writeBytes((atInt8*)"VELM", 4);
x30_VELM.write(w);
}
if (x34_VLM2)
{
if (x34_VLM2) {
w.writeBytes((atInt8*)"VLM2", 4);
x34_VLM2.write(w);
}
if (x38_SPLN)
{
if (x38_SPLN) {
w.writeBytes((atInt8*)"SPLN", 4);
x38_SPLN.write(w);
}
if (x3c_TEXR)
{
if (x3c_TEXR) {
w.writeBytes((atInt8*)"TEXR", 4);
x3c_TEXR.write(w);
}
if (x40_TSPN)
{
if (x40_TSPN) {
w.writeBytes((atInt8*)"TSPN", 4);
x40_TSPN.write(w);
}
@ -546,8 +502,7 @@ AT_SUBSPECIALIZE_DNA_YAML(SWSH<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(SWSH<UniqueID64>)
template <class IDType>
void SWSH<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
void SWSH<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
if (x3c_TEXR.m_elem)
x3c_TEXR.m_elem->gatherDependencies(pathsOut);
}
@ -556,11 +511,9 @@ template struct SWSH<UniqueID32>;
template struct SWSH<UniqueID64>;
template <class IDType>
bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
SWSH<IDType> swsh;
swsh.read(rs);
athena::io::ToYAMLStream(swsh, writer);
@ -572,8 +525,7 @@ template bool ExtractSWSH<UniqueID32>(PAKEntryReadStream& rs, const hecl::Projec
template bool ExtractSWSH<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteSWSH(const SWSH<IDType>& swsh, const hecl::ProjectPath& outPath)
{
bool WriteSWSH(const SWSH<IDType>& swsh, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -587,4 +539,4 @@ bool WriteSWSH(const SWSH<IDType>& swsh, const hecl::ProjectPath& outPath)
template bool WriteSWSH<UniqueID32>(const SWSH<UniqueID32>& swsh, const hecl::ProjectPath& outPath);
template bool WriteSWSH<UniqueID64>(const SWSH<UniqueID64>& swsh, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAParticle

View File

@ -4,12 +4,10 @@
#include "PAK.hpp"
#include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
struct SWSH : public BigDNA
{
struct SWSH : public BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
@ -30,21 +28,24 @@ struct SWSH : public BigDNA
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;
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;
};
@ -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
{
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*) {}
};
}
} // namespace DataSpec

View File

@ -2,10 +2,8 @@
#include "ITweak.hpp"
namespace DataSpec
{
struct ITweakAutoMapper : public ITweak
{
namespace DataSpec {
struct ITweakAutoMapper : public ITweak {
virtual bool GetShowOneMiniMapArea() const = 0;
virtual bool GetScaleMoveSpeedWithCamDist() const = 0;
virtual float GetCamDist() const = 0;
@ -62,6 +60,4 @@ struct ITweakAutoMapper : public ITweak
virtual const zeus::CColor& GetDoorColor(int idx) const = 0;
virtual const zeus::CColor& GetOpenDoorColor() const = 0;
};
}
} // namespace DataSpec

View File

@ -2,10 +2,8 @@
#include "ITweak.hpp"
namespace DataSpec
{
struct ITweakBall : ITweak
{
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;
@ -68,5 +66,4 @@ struct ITweakBall : ITweak
virtual float GetBoostBallChargeTimeTable(int i) const = 0;
virtual float GetBoostBallIncrementalSpeedTable(int i) const = 0;
};
}
} // namespace DataSpec

View File

@ -2,11 +2,9 @@
#include "ITweak.hpp"
namespace DataSpec
{
namespace DataSpec {
struct ITweakGame : ITweak
{
struct ITweakGame : ITweak {
virtual std::string_view GetWorldPrefix() const = 0;
virtual bool GetSplashScreensDisabled() const = 0;
virtual float GetFirstPersonFOV() const = 0;
@ -25,5 +23,4 @@ struct ITweakGame : ITweak
virtual float GetHardModeDamageMultiplier() const = 0;
virtual float GetHardModeWeaponMultiplier() const = 0;
};
}
} // namespace DataSpec

View File

@ -3,28 +3,12 @@
#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;
@ -149,5 +133,4 @@ struct ITweakGui : ITweak
static float FaceReflectionOrthoHeightDebugValueToActualValue(float v) { return 0.007f * v + 0.02f; }
};
}
} // namespace DataSpec

View File

@ -2,20 +2,16 @@
#include "ITweak.hpp"
namespace DataSpec
{
struct ITweakGuiColors : ITweak
{
struct VisorEnergyInitColors
{
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
{
struct VisorEnergyBarColors {
const zeus::CColor& filled;
const zeus::CColor& empty;
const zeus::CColor& shadow;
@ -103,5 +99,4 @@ struct ITweakGuiColors : ITweak
virtual VisorEnergyInitColors GetVisorEnergyInitColors(int idx) const = 0;
virtual VisorEnergyBarColors GetVisorEnergyBarColors(int idx) const = 0;
};
}
} // namespace DataSpec

View File

@ -4,11 +4,9 @@
#include "Runtime/IFactory.hpp"
#include "Runtime/CPlayerState.hpp"
namespace DataSpec
{
namespace DataSpec {
struct ITweakGunRes : ITweak
{
struct ITweakGunRes : ITweak {
using ResId = urde::CAssetId;
using EBeamId = urde::CPlayerState::EBeamId;
@ -40,13 +38,11 @@ struct ITweakGunRes : ITweak
ResId xc0_grappleMuzzle;
ResId xc4_grappleSwoosh;
ResId GetBeamModel(EBeamId beam) const
{
ResId GetBeamModel(EBeamId beam) const {
auto b = int(beam);
if (b < 0 || b > 4)
b = 0;
switch (EBeamId(b))
{
switch (EBeamId(b)) {
default:
case EBeamId::Power:
return x10_powerBeam;
@ -61,16 +57,14 @@ struct ITweakGunRes : ITweak
}
}
const ResId* GetWeaponPair(EBeamId beam) const
{
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)
{
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;
@ -136,5 +130,4 @@ protected:
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,11 +3,9 @@
#include "ITweak.hpp"
#include "zeus/CAABox.hpp"
namespace DataSpec
{
namespace DataSpec {
struct ITweakPlayer : ITweak
{
struct ITweakPlayer : ITweak {
virtual float GetMaxTranslationalAcceleration(int s) const = 0;
virtual float GetMaxRotationalAcceleration(int s) const = 0;
virtual float GetPlayerTranslationFriction(int s) const = 0;
@ -143,5 +141,4 @@ struct ITweakPlayer : ITweak
virtual float GetPhazonDamageReduction() const = 0;
};
}
} // namespace DataSpec

View File

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

View File

@ -3,11 +3,9 @@
#include "ITweak.hpp"
#include "zeus/CAABox.hpp"
namespace DataSpec
{
namespace DataSpec {
/* Same as CDamageInfo */
struct SShotParam : BigDNA
{
struct SShotParam : BigDNA {
AT_DECL_DNA_YAML
Value<atInt32> weaponType = -1;
bool charged : 1;
@ -18,31 +16,32 @@ struct SShotParam : BigDNA
Value<float> radius = 0.f;
Value<float> knockback = 0.f;
bool noImmunity : 1;
SShotParam() { charged = false; combo = false; instaKill = false; noImmunity = false; }
SShotParam() {
charged = false;
combo = false;
instaKill = false;
noImmunity = false;
}
};
struct SComboShotParam : SShotParam
{
struct SComboShotParam : SShotParam {
AT_DECL_DNA_YAML
SComboShotParam() { combo = true; }
};
struct SChargedShotParam : SShotParam
{
struct SChargedShotParam : SShotParam {
AT_DECL_DNA_YAML
SChargedShotParam() { charged = true; }
};
struct SWeaponInfo : BigDNA
{
struct SWeaponInfo : BigDNA {
AT_DECL_DNA_YAML
Value<float> x0_coolDown = 0.1f;
SShotParam x4_normal;
SChargedShotParam x20_charged;
};
struct ITweakPlayerGun : ITweak
{
struct ITweakPlayerGun : ITweak {
AT_DECL_DNA_YAML
virtual float GetUpLookAngle() const = 0;
virtual float GetDownLookAngle() const = 0;
@ -70,5 +69,4 @@ struct ITweakPlayerGun : ITweak
virtual const SShotParam& GetBombInfo() const = 0;
virtual const SShotParam& GetPowerBombInfo() const = 0;
};
}
} // namespace DataSpec

View File

@ -4,11 +4,9 @@
#include "Runtime/IFactory.hpp"
#include "Runtime/CPlayerState.hpp"
namespace DataSpec
{
namespace DataSpec {
struct ITweakPlayerRes : ITweak
{
struct ITweakPlayerRes : ITweak {
using ResId = urde::CAssetId;
using EBeamId = urde::CPlayerState::EBeamId;
@ -42,13 +40,11 @@ struct ITweakPlayerRes : ITweak
float xf0_cinematicMoveOutofIntoPlayerDistance;
ResId GetBeamBallTransitionModel(EBeamId beam) const
{
ResId GetBeamBallTransitionModel(EBeamId beam) const {
int b = int(beam);
if (b < 0 || b > 4)
b = 0;
switch (EBeamId(b))
{
switch (EBeamId(b)) {
case EBeamId::Power:
default:
return xc8_ballTransitions[0];
@ -63,13 +59,11 @@ struct ITweakPlayerRes : ITweak
}
}
ResId GetBeamCineModel(EBeamId beam) const
{
ResId GetBeamCineModel(EBeamId beam) const {
int b = int(beam);
if (b < 0 || b > 4)
b = 0;
switch (EBeamId(b))
{
switch (EBeamId(b)) {
case EBeamId::Power:
default:
return xc8_cineGun[0];
@ -84,8 +78,7 @@ struct ITweakPlayerRes : ITweak
}
}
void ResolveResources(const urde::IFactory& factory)
{
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;
@ -162,5 +155,4 @@ protected:
virtual float _GetCinematicMoveOutofIntoPlayerDistance() const = 0;
};
}
} // namespace DataSpec

View File

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

View File

@ -1,10 +1,8 @@
#pragma once
#include "ITweak.hpp"
namespace DataSpec
{
struct ITweakTargeting : public ITweak
{
namespace DataSpec {
struct ITweakTargeting : public ITweak {
virtual atUint32 GetTargetRadiusMode() const = 0;
virtual float GetCurrLockOnExitDuration() const = 0;
virtual float GetCurrLockOnEnterDuration() const = 0;
@ -94,5 +92,4 @@ struct ITweakTargeting : public ITweak
virtual float GetScanTargetClampMax() const = 0;
virtual float GetAngularLagSpeed() const = 0;
};
}
} // namespace DataSpec

View File

@ -2,12 +2,10 @@
#include "../PAK.hpp"
namespace DataSpec
{
namespace DataSpec {
template <class T>
bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath)
{
bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -20,11 +18,9 @@ bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath)
}
template <class T>
bool ExtractTweak(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ExtractTweak(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
T tweak;
tweak.read(rs);
athena::io::ToYAMLStream(tweak, writer);
@ -33,5 +29,4 @@ bool ExtractTweak(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
return false;
}
}
} // namespace DataSpec

View File

@ -1,23 +1,17 @@
#include "WPSC.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
void WPSM<IDType>::_read(athena::io::YAMLDocReader& r)
{
for (const auto& elem : r.getCurNode()->m_mapChildren)
{
if (elem.first.size() < 4)
{
void WPSM<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()))
{
if (auto rec = r.enterSubRecord(elem.first.c_str())) {
switch (*reinterpret_cast<const uint32_t*>(elem.first.data())) {
case SBIG('IORN'):
x0_IORN.read(r);
break;
@ -126,8 +120,7 @@ void WPSM<IDType>::_read(athena::io::YAMLDocReader& r)
}
template <class IDType>
void WPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const
{
void WPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const {
if (x0_IORN)
if (auto rec = w.enterSubRecord("IORN"))
x0_IORN.write(w);
@ -232,193 +225,155 @@ void WPSM<IDType>::_write(athena::io::YAMLDocWriter& w) const
}
template <class IDType>
void WPSM<IDType>::_binarySize(size_t& __isz) const
{
void WPSM<IDType>::_binarySize(size_t& __isz) const {
__isz += 4;
if (x0_IORN)
{
if (x0_IORN) {
__isz += 4;
x0_IORN.binarySize(__isz);
}
if (x4_IVEC)
{
if (x4_IVEC) {
__isz += 4;
x4_IVEC.binarySize(__isz);
}
if (x8_PSOV)
{
if (x8_PSOV) {
__isz += 4;
x8_PSOV.binarySize(__isz);
}
if (xc_PSVM)
{
if (xc_PSVM) {
__isz += 4;
xc_PSVM.binarySize(__isz);
}
if (x10_VMD2)
{
if (x10_VMD2) {
__isz += 4;
x10_VMD2.binarySize(__isz);
}
if (x14_PSLT)
{
if (x14_PSLT) {
__isz += 4;
x14_PSLT.binarySize(__isz);
}
if (x18_PSCL)
{
if (x18_PSCL) {
__isz += 4;
x18_PSCL.binarySize(__isz);
}
if (x1c_PCOL)
{
if (x1c_PCOL) {
__isz += 4;
x1c_PCOL.binarySize(__isz);
}
if (x20_POFS)
{
if (x20_POFS) {
__isz += 4;
x20_POFS.binarySize(__isz);
}
if (x24_OFST)
{
if (x24_OFST) {
__isz += 4;
x24_OFST.binarySize(__isz);
}
if (x28_APSO)
{
if (x28_APSO) {
__isz += 4;
x28_APSO.binarySize(__isz);
}
if (x29_HOMG)
{
if (x29_HOMG) {
__isz += 4;
x29_HOMG.binarySize(__isz);
}
if (x2a_AP11)
{
if (x2a_AP11) {
__isz += 4;
x2a_AP11.binarySize(__isz);
}
if (x2b_AP21)
{
if (x2b_AP21) {
__isz += 4;
x2b_AP21.binarySize(__isz);
}
if (x2c_AS11)
{
if (x2c_AS11) {
__isz += 4;
x2c_AS11.binarySize(__isz);
}
if (x2d_AS12)
{
if (x2d_AS12) {
__isz += 4;
x2d_AS12.binarySize(__isz);
}
if (x2e_AS13)
{
if (x2e_AS13) {
__isz += 4;
x2e_AS13.binarySize(__isz);
}
if (x30_TRAT)
{
if (x30_TRAT) {
__isz += 4;
x30_TRAT.binarySize(__isz);
}
if (x34_APSM)
{
if (x34_APSM) {
__isz += 4;
x34_APSM.binarySize(__isz);
}
if (x44_APS2)
{
if (x44_APS2) {
__isz += 4;
x44_APS2.binarySize(__isz);
}
if (x54_ASW1)
{
if (x54_ASW1) {
__isz += 4;
x54_ASW1.binarySize(__isz);
}
if (x64_ASW2)
{
if (x64_ASW2) {
__isz += 4;
x64_ASW2.binarySize(__isz);
}
if (x74_ASW3)
{
if (x74_ASW3) {
__isz += 4;
x74_ASW3.binarySize(__isz);
}
if (x84_OHEF)
{
if (x84_OHEF) {
__isz += 4;
x84_OHEF.binarySize(__isz);
}
if (x94_COLR)
{
if (x94_COLR) {
__isz += 4;
x94_COLR.binarySize(__isz);
}
if (!xa4_EWTR)
{
if (!xa4_EWTR) {
__isz += 4;
xa4_EWTR.binarySize(__isz);
}
if (!xa5_LWTR)
{
if (!xa5_LWTR) {
__isz += 4;
xa5_LWTR.binarySize(__isz);
}
if (!xa6_SWTR)
{
if (!xa6_SWTR) {
__isz += 4;
xa6_SWTR.binarySize(__isz);
}
if (xa8_PJFX != ~0)
__isz += 12;
if (xac_RNGE)
{
if (xac_RNGE) {
__isz += 4;
xac_RNGE.binarySize(__isz);
}
if (xb0_FOFF)
{
if (xb0_FOFF) {
__isz += 4;
xb0_FOFF.binarySize(__isz);
}
if (xunk_FC60)
{
if (xunk_FC60) {
__isz += 4;
xunk_FC60.binarySize(__isz);
}
if (xunk_SPS1)
{
if (xunk_SPS1) {
__isz += 4;
xunk_SPS1.binarySize(__isz);
}
if (xunk_SPS2)
{
if (xunk_SPS2) {
__isz += 4;
xunk_SPS2.binarySize(__isz);
}
}
template <class IDType>
void WPSM<IDType>::_read(athena::io::IStreamReader& r)
{
void WPSM<IDType>::_read(athena::io::IStreamReader& r) {
uint32_t clsId;
r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('WPSM'))
{
if (clsId != SBIG('WPSM')) {
LogModule.report(logvisor::Warning, "non WPSM provided to WPSM parser");
return;
}
r.readBytesToBuf(&clsId, 4);
while (clsId != SBIG('_END'))
{
switch(clsId)
{
while (clsId != SBIG('_END')) {
switch (clsId) {
case SBIG('IORN'):
x0_IORN.read(r);
break;
@ -507,14 +462,12 @@ void WPSM<IDType>::_read(athena::io::IStreamReader& r)
r.readUint32();
xa6_SWTR = r.readBool();
break;
case SBIG('PJFX'):
{
case SBIG('PJFX'): {
uint32_t fcc;
r.readBytesToBuf(&fcc, 4);
if (fcc != SBIG('NONE'))
xa8_PJFX = r.readUint32Big();
}
break;
} break;
case SBIG('RNGE'):
xac_RNGE.read(r);
break;
@ -539,176 +492,141 @@ void WPSM<IDType>::_read(athena::io::IStreamReader& r)
}
template <class IDType>
void WPSM<IDType>::_write(athena::io::IStreamWriter &w) const
{
void WPSM<IDType>::_write(athena::io::IStreamWriter& w) const {
w.writeBytes("WPSM", 4);
if (x0_IORN)
{
if (x0_IORN) {
w.writeBytes("IORN", 4);
x0_IORN.write(w);
}
if (x4_IVEC)
{
if (x4_IVEC) {
w.writeBytes("IVEC", 4);
x4_IVEC.write(w);
}
if (x8_PSOV)
{
if (x8_PSOV) {
w.writeBytes("PSOV", 4);
x8_PSOV.write(w);
}
if (xc_PSVM)
{
if (xc_PSVM) {
w.writeBytes("PSVM", 4);
xc_PSVM.write(w);
}
if (x10_VMD2)
{
if (x10_VMD2) {
w.writeBytes("VMD2", 4);
x10_VMD2.write(w);
}
if (x14_PSLT)
{
if (x14_PSLT) {
w.writeBytes("PSLT", 4);
x14_PSLT.write(w);
}
if (x18_PSCL)
{
if (x18_PSCL) {
w.writeBytes("PSCL", 4);
x18_PSCL.write(w);
}
if (x1c_PCOL)
{
if (x1c_PCOL) {
w.writeBytes("PCOL", 4);
x1c_PCOL.write(w);
}
if (x20_POFS)
{
if (x20_POFS) {
w.writeBytes("POFS", 4);
x20_POFS.write(w);
}
if (x24_OFST)
{
if (x24_OFST) {
w.writeBytes("OFST", 4);
x24_OFST.write(w);
}
if (x28_APSO)
{
if (x28_APSO) {
w.writeBytes("APSO", 4);
x28_APSO.write(w);
}
if (x29_HOMG)
{
if (x29_HOMG) {
w.writeBytes("HOMG", 4);
x29_HOMG.write(w);
}
if (x2a_AP11)
{
if (x2a_AP11) {
w.writeBytes("AP11", 4);
x2a_AP11.write(w);
}
if (x2b_AP21)
{
if (x2b_AP21) {
w.writeBytes("AP21", 4);
x2b_AP21.write(w);
}
if (x2c_AS11)
{
if (x2c_AS11) {
w.writeBytes("AS11", 4);
x2c_AS11.write(w);
}
if (x2d_AS12)
{
if (x2d_AS12) {
w.writeBytes("AS12", 4);
x2d_AS12.write(w);
}
if (x2e_AS13)
{
if (x2e_AS13) {
w.writeBytes("AS13", 4);
x2e_AS13.write(w);
}
if (x30_TRAT)
{
if (x30_TRAT) {
w.writeBytes("TRAT", 4);
x30_TRAT.write(w);
}
if (x34_APSM)
{
if (x34_APSM) {
w.writeBytes("APSM", 4);
x34_APSM.write(w);
}
if (x44_APS2)
{
if (x44_APS2) {
w.writeBytes("APS2", 4);
x44_APS2.write(w);
}
if (x54_ASW1)
{
if (x54_ASW1) {
w.writeBytes("ASW1", 4);
x54_ASW1.write(w);
}
if (x64_ASW2)
{
if (x64_ASW2) {
w.writeBytes("ASW2", 4);
x64_ASW2.write(w);
}
if (x74_ASW3)
{
if (x74_ASW3) {
w.writeBytes("ASW3", 4);
x74_ASW3.write(w);
}
if (x84_OHEF)
{
if (x84_OHEF) {
w.writeBytes("OHEF", 4);
x84_OHEF.write(w);
}
if (x94_COLR)
{
if (x94_COLR) {
w.writeBytes("COLR", 4);
x94_COLR.write(w);
}
if (!xa4_EWTR)
{
if (!xa4_EWTR) {
w.writeBytes("EWTR", 4);
xa4_EWTR.write(w);
}
if (!xa5_LWTR)
{
if (!xa5_LWTR) {
w.writeBytes("LWTR", 4);
xa5_LWTR.write(w);
}
if (!xa6_SWTR)
{
if (!xa6_SWTR) {
w.writeBytes("SWTR", 4);
xa6_SWTR.write(w);
}
if (xa8_PJFX != ~0)
{
if (xa8_PJFX != ~0) {
w.writeBytes("PJFXCNST", 8);
w.writeUint32(xa8_PJFX);
}
if (xac_RNGE)
{
if (xac_RNGE) {
w.writeBytes("RNGE", 4);
xac_RNGE.write(w);
}
if (xb0_FOFF)
{
if (xb0_FOFF) {
w.writeBytes("FOFF", 4);
xb0_FOFF.write(w);
}
if (xunk_FC60)
{
if (xunk_FC60) {
w.writeBytes("FC60", 4);
xunk_FC60.write(w);
}
if (xunk_SPS1)
{
if (xunk_SPS1) {
w.writeBytes("SPS1", 4);
xunk_SPS1.write(w);
}
if (xunk_SPS2)
{
if (xunk_SPS2) {
w.writeBytes("SPS2", 4);
xunk_SPS2.write(w);
}
@ -720,14 +638,17 @@ AT_SUBSPECIALIZE_DNA_YAML(WPSM<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(WPSM<UniqueID64>)
template <>
const char* WPSM<UniqueID32>::DNAType() { return "WPSM<UniqueID32>"; }
const char* WPSM<UniqueID32>::DNAType() {
return "WPSM<UniqueID32>";
}
template <>
const char* WPSM<UniqueID64>::DNAType() { return "WPSM<UniqueID64>"; }
const char* WPSM<UniqueID64>::DNAType() {
return "WPSM<UniqueID64>";
}
template <class IDType>
void WPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
void WPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
g_curSpec->flattenDependencies(x34_APSM.id, pathsOut);
g_curSpec->flattenDependencies(x44_APS2.id, pathsOut);
g_curSpec->flattenDependencies(x54_ASW1.id, pathsOut);
@ -741,11 +662,9 @@ template struct WPSM<UniqueID32>;
template struct WPSM<UniqueID64>;
template <class IDType>
bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
athena::io::FileWriter writer(outPath.getAbsolutePath());
if (writer.isOpen())
{
if (writer.isOpen()) {
WPSM<IDType> wpsm;
wpsm.read(rs);
athena::io::ToYAMLStream(wpsm, writer);
@ -757,8 +676,7 @@ template bool ExtractWPSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::Projec
template bool ExtractWPSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteWPSM(const WPSM<IDType>& wpsm, const hecl::ProjectPath& outPath)
{
bool WriteWPSM(const WPSM<IDType>& wpsm, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
@ -772,4 +690,4 @@ bool WriteWPSM(const WPSM<IDType>& wpsm, const hecl::ProjectPath& outPath)
template bool WriteWPSM<UniqueID32>(const WPSM<UniqueID32>& wpsm, const hecl::ProjectPath& outPath);
template bool WriteWPSM<UniqueID64>(const WPSM<UniqueID64>& wpsm, const hecl::ProjectPath& outPath);
}
} // namespace DataSpec::DNAParticle

View File

@ -4,11 +4,9 @@
#include "PAK.hpp"
#include "athena/FileWriter.hpp"
namespace DataSpec::DNAParticle
{
namespace DataSpec::DNAParticle {
template <class IDType>
struct WPSM : BigDNA
{
struct WPSM : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
AT_SUBDECL_DNA
VectorElementFactory x0_IORN;
@ -46,9 +44,10 @@ struct WPSM : BigDNA
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;
@ -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,15 +1,12 @@
#include "AFSM.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
template <>
void AFSM::State::Transition::Enumerate<BigDNA::Read>(typename Read::StreamT& r)
{
void AFSM::State::Transition::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {
triggerCount = r.readUint32Big();
int i = 0;
r.enumerate<Trigger>(triggers, triggerCount,
[&](athena::io::IStreamReader& in, Trigger& tr){
r.enumerate<Trigger>(triggers, triggerCount, [&](athena::io::IStreamReader& in, Trigger& tr) {
tr.first = i == 0;
tr.read(in);
i++;
@ -17,19 +14,16 @@ void AFSM::State::Transition::Enumerate<BigDNA::Read>(typename Read::StreamT& r)
}
template <>
void AFSM::State::Transition::Enumerate<BigDNA::Write>(typename Write::StreamT& w)
{
void AFSM::State::Transition::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
w.writeInt32Big(triggerCount);
w.enumerate(triggers);
}
template <>
void AFSM::State::Transition::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r)
{
void AFSM::State::Transition::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
int i = 0;
/* triggers */
triggerCount = r.enumerate<Trigger>("triggers", triggers,
[&](athena::io::YAMLDocReader& in, Trigger& tr){
triggerCount = r.enumerate<Trigger>("triggers", triggers, [&](athena::io::YAMLDocReader& in, Trigger& tr) {
tr.first = i == 0;
tr.read(in);
i++;
@ -37,91 +31,74 @@ void AFSM::State::Transition::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::Str
}
template <>
void AFSM::State::Transition::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w)
{
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)
{
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)
{
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)
{
if (first) {
/* targetState */
targetState = __dna_reader.readUint32Big();
}
}
template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& __dna_writer)
{
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)
{
if (first) {
/* targetState */
__dna_writer.writeUint32Big(targetState);
}
}
template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& __dna_docin)
{
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)
{
if (first) {
/* targetState */
targetState = __dna_docin.readUint32("targetState");
}
}
template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& __dna_docout)
{
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)
{
if (first) {
/* targetState */
__dna_docout.writeUint32("targetState", targetState);
}
}
template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::BinarySize>(size_t& __isz)
{
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,26 +4,21 @@
#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
{
struct State : public BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> transitionCount;
struct Transition : public BigDNA
{
struct Transition : public BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
Value<atUint32> triggerCount;
struct Trigger : public BigDNA
{
struct Trigger : public BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
bool first = false;
String<-1> name;
@ -36,8 +31,7 @@ struct AFSM : public BigDNA
};
Vector<State, AT_DNA_COUNT(stateCount)> states;
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
AFSM afsm;
afsm.read(rs);
athena::io::FileWriter writer(outPath.getAbsolutePath());
@ -45,8 +39,7 @@ struct AFSM : public BigDNA
return true;
}
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath)
{
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
AFSM afsm;
athena::io::FileReader reader(inPath.getAbsolutePath());
athena::io::FromYAMLStream(afsm, reader);
@ -55,5 +48,4 @@ struct AFSM : public BigDNA
return true;
}
};
}
} // namespace DataSpec::DNAMP1

View File

@ -74,14 +74,11 @@ 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},
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},
@ -151,11 +148,9 @@ static const std::pair<std::string_view, const uint8_t*> Headers[] =
{"ZZZ"sv, ZZZ_H},
{"Zoomer"sv, Zoomer_H},
{"lumigek"sv, lumigek_H},
{"test"sv, test_H}
};
{"test"sv, test_H}};
bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir)
{
bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) {
dir.makeDirChain(true);
Header head;
@ -173,8 +168,8 @@ bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir)
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;
@ -212,8 +207,7 @@ bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir)
return true;
}
bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath)
{
bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath());
if (w.hasError())
return false;
@ -246,4 +240,4 @@ bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath)
return true;
}
}
} // namespace DataSpec::DNAMP1

View File

@ -3,14 +3,11 @@
#include "DataSpec/DNACommon/DNACommon.hpp"
#include "DNAMP1.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
class AGSC
{
class AGSC {
public:
struct Header : BigDNA
{
struct Header : BigDNA {
AT_DECL_DNA
String<-1> audioDir;
String<-1> groupName;
@ -19,5 +16,4 @@ public:
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,11 +10,9 @@
#include "EVNT.hpp"
#include "athena/FileReader.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
struct ANCS : BigDNA
{
struct ANCS : BigDNA {
using CINFType = CINF;
using CSKRType = CSKR;
using ANIMType = ANIM;
@ -22,13 +20,11 @@ struct ANCS : BigDNA
AT_DECL_DNA_YAML
Value<atUint16> version;
struct CharacterSet : BigDNA
{
struct CharacterSet : BigDNA {
AT_DECL_DNA_YAML
Value<atUint16> version;
Value<atUint32> characterCount;
struct CharacterInfo : BigDNA
{
struct CharacterInfo : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
@ -38,8 +34,7 @@ struct ANCS : BigDNA
UniqueID32 cskr;
UniqueID32 cinf;
struct Animation : BigDNA
{
struct Animation : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
String<-1> strA;
@ -47,32 +42,21 @@ struct ANCS : BigDNA
};
std::vector<Animation> animations;
struct PASDatabase : BigDNA
{
struct PASDatabase : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> magic;
Value<atUint32> animStateCount;
Value<atUint32> defaultState;
struct AnimState : BigDNA
{
struct AnimState : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
atUint32 id;
struct ParmInfo : BigDNA
{
struct ParmInfo : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
enum class DataType
{
Int32 = 0,
UInt32 = 1,
Float = 2,
Bool = 3,
Enum = 4
};
union Parm
{
enum class DataType { Int32 = 0, UInt32 = 1, Float = 2, Bool = 3, Enum = 4 };
union Parm {
atInt32 int32;
atUint32 uint32;
float float32;
@ -91,8 +75,7 @@ struct ANCS : BigDNA
};
std::vector<ParmInfo> parmInfos;
struct AnimInfo
{
struct AnimInfo {
atUint32 id;
std::vector<ParmInfo::Parm> parmVals;
};
@ -101,8 +84,7 @@ struct ANCS : BigDNA
Vector<AnimState, AT_DNA_COUNT(animStateCount)> animStates;
} pasDatabase;
struct ParticleResData
{
struct ParticleResData {
std::vector<UniqueID32> part;
std::vector<UniqueID32> swhc;
std::vector<UniqueID32> unk;
@ -111,21 +93,18 @@ struct ANCS : BigDNA
atUint32 unk1 = 0;
struct ActionAABB : BigDNA
{
struct ActionAABB : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atVec3f> aabb[2];
};
std::vector<ActionAABB> animAABBs;
struct Effect : BigDNA
{
struct Effect : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
Value<atUint32> compCount;
struct EffectComponent : BigDNA
{
struct EffectComponent : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
DNAFourCC type;
@ -147,37 +126,25 @@ struct ANCS : BigDNA
Vector<CharacterInfo, AT_DNA_COUNT(characterCount)> characters;
} characterSet;
struct AnimationSet : BigDNA
{
struct AnimationSet : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
struct MetaAnimPrimitive;
struct IMetaAnim : BigDNAVYaml
{
struct IMetaAnim : BigDNAVYaml {
Delete expl;
enum class Type
{
Primitive = 0,
Blend = 1,
PhaseBlend = 2,
Random = 3,
Sequence = 4
} m_type;
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) {}
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
{
struct MetaAnimFactory : BigDNA {
AT_DECL_EXPLICIT_DNA_YAML
std::unique_ptr<IMetaAnim> m_anim;
};
struct MetaAnimPrimitive : IMetaAnim
{
struct MetaAnimPrimitive : IMetaAnim {
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {}
@ -191,15 +158,10 @@ struct ANCS : BigDNA
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out);
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
return func(*this);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) { return func(*this); }
};
struct MetaAnimBlend : IMetaAnim
{
MetaAnimBlend()
: IMetaAnim(Type::Blend, "Blend") {}
struct MetaAnimBlend : IMetaAnim {
MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory animA;
@ -208,14 +170,12 @@ struct ANCS : BigDNA
Value<atUint8> unk;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{
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)
{
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
if (!animA.m_anim->enumeratePrimitives(func))
return false;
if (!animB.m_anim->enumeratePrimitives(func))
@ -223,10 +183,8 @@ struct ANCS : BigDNA
return true;
}
};
struct MetaAnimPhaseBlend : IMetaAnim
{
MetaAnimPhaseBlend()
: IMetaAnim(Type::PhaseBlend, "PhaseBlend") {}
struct MetaAnimPhaseBlend : IMetaAnim {
MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
MetaAnimFactory animA;
@ -235,14 +193,12 @@ struct ANCS : BigDNA
Value<atUint8> unk;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{
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)
{
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
if (!animA.m_anim->enumeratePrimitives(func))
return false;
if (!animB.m_anim->enumeratePrimitives(func))
@ -250,14 +206,12 @@ struct ANCS : BigDNA
return true;
}
};
struct MetaAnimRandom : IMetaAnim
{
struct MetaAnimRandom : IMetaAnim {
MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<atUint32> animCount;
struct Child : BigDNA
{
struct Child : BigDNA {
AT_DECL_DNA
MetaAnimFactory anim;
Value<atUint32> probability;
@ -265,22 +219,19 @@ struct ANCS : BigDNA
Vector<Child, AT_DNA_COUNT(animCount)> children;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{
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)
{
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
{
struct MetaAnimSequence : IMetaAnim {
MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
@ -288,14 +239,12 @@ struct ANCS : BigDNA
Vector<MetaAnimFactory, AT_DNA_COUNT(animCount)> children;
void gatherPrimitives(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{
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)
{
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
for (auto& child : children)
if (!child.m_anim->enumeratePrimitives(func))
return false;
@ -303,60 +252,49 @@ struct ANCS : BigDNA
}
};
struct Animation : BigDNA
{
struct Animation : BigDNA {
AT_DECL_DNA_YAML
String<-1> name;
MetaAnimFactory metaAnim;
};
std::vector<Animation> animations;
struct IMetaTrans : BigDNAVYaml
{
struct IMetaTrans : BigDNAVYaml {
Delete expl;
enum class Type
{
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) {}
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
{
struct MetaTransFactory : BigDNA {
AT_DECL_DNA_YAML
Delete expl;
std::unique_ptr<IMetaTrans> m_trans;
};
struct MetaTransMetaAnim : IMetaTrans
{
MetaTransMetaAnim()
: IMetaTrans(Type::MetaAnim, "MetaAnim") {}
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)
{
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {
anim.m_anim->gatherPrimitives(pakRouter, out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {
return anim.m_anim->enumeratePrimitives(func);
}
};
struct MetaTransTrans : IMetaTrans
{
MetaTransTrans()
: IMetaTrans(Type::Trans, "Trans") {}
struct MetaTransTrans : IMetaTrans {
MetaTransTrans() : IMetaTrans(Type::Trans, "Trans") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<float> transDurTime;
@ -365,10 +303,8 @@ struct ANCS : BigDNA
Value<bool> runA;
Value<atUint32> flags;
};
struct MetaTransPhaseTrans : IMetaTrans
{
MetaTransPhaseTrans()
: IMetaTrans(Type::PhaseTrans, "PhaseTrans") {}
struct MetaTransPhaseTrans : IMetaTrans {
MetaTransPhaseTrans() : IMetaTrans(Type::PhaseTrans, "PhaseTrans") {}
AT_DECL_DNA_YAML
AT_DECL_DNAV
Value<float> transDurTime;
@ -378,8 +314,7 @@ struct ANCS : BigDNA
Value<atUint32> flags;
};
struct Transition : BigDNA
{
struct Transition : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> unk;
Value<atUint32> animIdxA;
@ -389,8 +324,7 @@ struct ANCS : BigDNA
std::vector<Transition> transitions;
MetaTransFactory defaultTransition;
struct AdditiveAnimationInfo : BigDNA
{
struct AdditiveAnimationInfo : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
Value<float> unk1;
@ -401,16 +335,14 @@ struct ANCS : BigDNA
float floatA = 0.0;
float floatB = 0.0;
struct HalfTransition : BigDNA
{
struct HalfTransition : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> animIdx;
MetaTransFactory metaTrans;
};
std::vector<HalfTransition> halfTransitions;
struct AnimationResources : BigDNA
{
struct AnimationResources : BigDNA {
AT_DECL_DNA_YAML
UniqueID32 animId;
UniqueID32 evntId;
@ -418,12 +350,10 @@ struct ANCS : BigDNA
std::vector<AnimationResources> animResources;
} animationSet;
void getCharacterResInfo(std::vector<DNAANCS::CharacterResInfo<UniqueID32>>& out) const
{
void getCharacterResInfo(std::vector<DNAANCS::CharacterResInfo<UniqueID32>>& out) const {
out.clear();
out.reserve(characterSet.characters.size());
for (const CharacterSet::CharacterInfo& ci : characterSet.characters)
{
for (const CharacterSet::CharacterInfo& ci : characterSet.characters) {
out.emplace_back();
DNAANCS::CharacterResInfo<UniqueID32>& chOut = out.back();
chOut.name = ci.name;
@ -437,8 +367,7 @@ struct ANCS : BigDNA
}
void getAnimationResInfo(PAKRouter<PAKBridge>* pakRouter,
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) const
{
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())
@ -450,8 +379,7 @@ struct ANCS : BigDNA
trans->gatherPrimitives(pakRouter, out);
}
void enumeratePrimitives(const std::function<bool(AnimationSet::MetaAnimPrimitive& prim)>& func)
{
void enumeratePrimitives(const std::function<bool(AnimationSet::MetaAnimPrimitive& prim)>& func) {
for (const AnimationSet::Animation& ai : animationSet.animations)
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
anim->enumeratePrimitives(func);
@ -462,10 +390,8 @@ struct ANCS : BigDNA
trans->enumeratePrimitives(func);
}
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, int charIdx) const
{
auto doCi = [&](const CharacterSet::CharacterInfo& ci)
{
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)
@ -482,38 +408,21 @@ struct ANCS : BigDNA
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,
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,
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

View File

@ -2,14 +2,13 @@
#include "zeus/CVector3f.hpp"
#include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
using ANIMOutStream = hecl::blender::ANIMOutStream;
void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig) const
{
os.format("act.hecl_fps = round(%f)\n"
void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig) const {
os.format(
"act.hecl_fps = round(%f)\n"
"act.hecl_looping = %s\n",
(1.0f / mainInterval), looping ? "True" : "False");
@ -18,8 +17,7 @@ void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANI
std::vector<zeus::CQuaternion> fixedRotKeys;
std::vector<zeus::CVector3f> fixedTransKeys;
for (const std::pair<atUint32, bool>& bone : bones)
{
for (const std::pair<atUint32, bool>& bone : bones) {
const std::string* bName = rig.getCINF().getBoneNameFromId(bone.first);
if (!bName)
continue;
@ -28,17 +26,24 @@ void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANI
os << "action_group = act.groups.new(bone_string)\n"
"\n"
"rotCurves = []\n"
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=0, action_group=bone_string))\n"
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=1, action_group=bone_string))\n"
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=2, action_group=bone_string))\n"
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=3, action_group=bone_string))\n"
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=0, "
"action_group=bone_string))\n"
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=1, "
"action_group=bone_string))\n"
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=2, "
"action_group=bone_string))\n"
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=3, "
"action_group=bone_string))\n"
"\n";
if (bone.second)
os << "transCurves = []\n"
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, action_group=bone_string))\n"
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, action_group=bone_string))\n"
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, action_group=bone_string))\n"
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, "
"action_group=bone_string))\n"
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, "
"action_group=bone_string))\n"
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, "
"action_group=bone_string))\n"
"\n";
ANIMOutStream ao = os.beginANIMCurve();
@ -48,8 +53,7 @@ void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANI
fixedRotKeys.clear();
fixedRotKeys.resize(rotKeys.size());
for (int c=0 ; c<4 ; ++c)
{
for (int c = 0; c < 4; ++c) {
size_t idx = 0;
for (const DNAANIM::Value& val : rotKeys)
fixedRotKeys[idx++][c] = val.simd[c];
@ -58,8 +62,7 @@ void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANI
for (zeus::CQuaternion& rot : fixedRotKeys)
rot = rig.invertRotation(bone.first, rot);
for (int c=0 ; c<4 ; ++c)
{
for (int c = 0; c < 4; ++c) {
auto frameit = frames.begin();
ao.changeCurve(ANIMOutStream::CurveType::Rotate, c, rotKeys.size());
for (const zeus::CQuaternion& val : fixedRotKeys)
@ -67,14 +70,12 @@ void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANI
}
}
if (bone.second)
{
if (bone.second) {
const std::vector<DNAANIM::Value>& transKeys = *kit++;
fixedTransKeys.clear();
fixedTransKeys.resize(transKeys.size());
for (int c=0 ; c<3 ; ++c)
{
for (int c = 0; c < 3; ++c) {
size_t idx = 0;
for (const DNAANIM::Value& val : transKeys)
fixedTransKeys[idx++][c] = val.simd[c];
@ -83,8 +84,7 @@ void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANI
for (zeus::CVector3f& t : fixedTransKeys)
t = rig.invertPosition(bone.first, t, true);
for (int c=0 ; c<3 ; ++c)
{
for (int c = 0; c < 3; ++c) {
auto frameit = frames.begin();
ao.changeCurve(ANIMOutStream::CurveType::Translate, c, fixedTransKeys.size());
for (const zeus::CVector3f& val : fixedTransKeys)
@ -94,13 +94,10 @@ void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANI
}
}
UniqueID32 ANIM::GetEVNTId(athena::io::IStreamReader& reader)
{
UniqueID32 ANIM::GetEVNTId(athena::io::IStreamReader& reader) {
atUint32 version = reader.readUint32Big();
switch (version)
{
case 0:
{
switch (version) {
case 0: {
ANIM0 anim0;
anim0.read(reader);
return anim0.evnt;
@ -117,11 +114,9 @@ UniqueID32 ANIM::GetEVNTId(athena::io::IStreamReader& reader)
}
template <>
void ANIM::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
{
void ANIM::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
atUint32 version = reader.readUint32Big();
switch (version)
{
switch (version) {
case 0:
m_anim.reset(new struct ANIM0);
m_anim->read(reader);
@ -141,15 +136,13 @@ void ANIM::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
}
template <>
void ANIM::Enumerate<BigDNA::Write>(typename Write::StreamT& writer)
{
void ANIM::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint32Big(m_anim->m_version);
m_anim->write(writer);
}
template <>
void ANIM::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
{
void ANIM::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
s += 4;
m_anim->binarySize(s);
}
@ -157,8 +150,7 @@ void ANIM::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
const char* ANIM::ANIM0::DNAType() { return "ANIM0"; }
template <>
void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
{
void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
Header head;
head.read(reader);
mainInterval = head.interval;
@ -169,8 +161,7 @@ void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
frames.push_back(k);
std::map<atUint8, atUint32> boneMap;
for (size_t b=0 ; b<head.boneSlotCount ; ++b)
{
for (size_t b = 0; b < head.boneSlotCount; ++b) {
atUint8 idx = reader.readUByte();
if (idx == 0xff)
continue;
@ -181,15 +172,13 @@ void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
bones.clear();
bones.reserve(boneCount);
channels.clear();
for (size_t b=0 ; b<boneCount ; ++b)
{
for (size_t b = 0; b < boneCount; ++b) {
bones.emplace_back(boneMap[b], false);
atUint8 idx = reader.readUByte();
channels.emplace_back();
DNAANIM::Channel& chan = channels.back();
chan.type = DNAANIM::Channel::Type::Rotation;
if (idx != 0xff)
{
if (idx != 0xff) {
bones.back().second = true;
channels.emplace_back();
DNAANIM::Channel& chan = channels.back();
@ -200,8 +189,7 @@ void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
reader.readUint32Big();
chanKeys.clear();
chanKeys.reserve(channels.size());
for (const std::pair<atUint32, bool>& bone : bones)
{
for (const std::pair<atUint32, bool>& bone : bones) {
chanKeys.emplace_back();
std::vector<DNAANIM::Value>& keys = chanKeys.back();
for (size_t k = 0; k < head.keyCount; ++k)
@ -213,11 +201,9 @@ void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
reader.readUint32Big();
auto kit = chanKeys.begin();
for (const std::pair<atUint32, bool>& bone : bones)
{
for (const std::pair<atUint32, bool>& bone : bones) {
++kit;
if (bone.second)
{
if (bone.second) {
std::vector<DNAANIM::Value>& keys = *kit++;
for (size_t k = 0; k < head.keyCount; ++k)
keys.emplace_back(reader.readVec3fBig());
@ -228,8 +214,7 @@ void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
}
template <>
void ANIM::ANIM0::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
{
void ANIM::ANIM0::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
Header head;
head.unk0 = 0;
head.unk1 = 0;
@ -244,14 +229,11 @@ void ANIM::ANIM0::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
head.boneSlotCount = maxId + 1;
head.write(writer);
for (size_t s=0 ; s<head.boneSlotCount ; ++s)
{
for (size_t s = 0; s < head.boneSlotCount; ++s) {
size_t boneIdx = 0;
bool found = false;
for (const std::pair<atUint32, bool>& bone : bones)
{
if (s == bone.first)
{
for (const std::pair<atUint32, bool>& bone : bones) {
if (s == bone.first) {
writer.writeUByte(boneIdx);
found = true;
break;
@ -264,8 +246,7 @@ void ANIM::ANIM0::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
writer.writeUint32Big(bones.size());
size_t boneIdx = 0;
for (const std::pair<atUint32, bool>& bone : bones)
{
for (const std::pair<atUint32, bool>& bone : bones) {
if (bone.second)
writer.writeUByte(boneIdx);
else
@ -276,14 +257,12 @@ void ANIM::ANIM0::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
writer.writeUint32Big(bones.size() * head.keyCount);
auto cit = chanKeys.begin();
atUint32 transKeyCount = 0;
for (const std::pair<atUint32, bool>& bone : bones)
{
for (const std::pair<atUint32, bool>& bone : bones) {
const std::vector<DNAANIM::Value>& keys = *cit++;
auto kit = keys.begin();
for (size_t k = 0; k < head.keyCount; ++k)
writer.writeVec4fBig(atVec4f{(*kit++).simd});
if (bone.second)
{
if (bone.second) {
transKeyCount += head.keyCount;
++cit;
}
@ -291,11 +270,9 @@ void ANIM::ANIM0::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
writer.writeUint32Big(transKeyCount);
cit = chanKeys.begin();
for (const std::pair<atUint32, bool>& bone : bones)
{
for (const std::pair<atUint32, bool>& bone : bones) {
++cit;
if (bone.second)
{
if (bone.second) {
const std::vector<DNAANIM::Value>& keys = *cit++;
auto kit = keys.begin();
for (size_t k = 0; k < head.keyCount; ++k)
@ -307,8 +284,7 @@ void ANIM::ANIM0::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
}
template <>
void ANIM::ANIM0::Enumerate<BigDNA::BinarySize>(size_t& __isz)
{
void ANIM::ANIM0::Enumerate<BigDNA::BinarySize>(size_t& __isz) {
Header head;
atUint32 maxId = 0;
@ -320,8 +296,7 @@ void ANIM::ANIM0::Enumerate<BigDNA::BinarySize>(size_t& __isz)
__isz += bones.size() + 4;
__isz += 8;
for (const std::pair<atUint32, bool>& bone : bones)
{
for (const std::pair<atUint32, bool>& bone : bones) {
__isz += head.keyCount * 16;
if (bone.second)
__isz += head.keyCount * 12;
@ -333,8 +308,7 @@ void ANIM::ANIM0::Enumerate<BigDNA::BinarySize>(size_t& __isz)
const char* ANIM::ANIM2::DNAType() { return "ANIM2"; }
template <>
void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
{
void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
Header head;
head.read(reader);
evnt = head.evnt;
@ -345,8 +319,7 @@ void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
keyBmp.read(reader, head.keyBitmapBitCount);
frames.clear();
atUint32 frameAccum = 0;
for (bool bit : keyBmp)
{
for (bool bit : keyBmp) {
if (bit)
frames.push_back(frameAccum);
++frameAccum;
@ -359,16 +332,13 @@ void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
channels.reserve(head.boneChannelCount);
atUint32 keyframeCount = 0;
if (m_version == 3)
{
for (size_t b=0 ; b<head.boneChannelCount ; ++b)
{
if (m_version == 3) {
for (size_t b = 0; b < head.boneChannelCount; ++b) {
ChannelDescPC desc;
desc.read(reader);
bones.emplace_back(desc.id, desc.keyCount2 != 0);
if (desc.keyCount1)
{
if (desc.keyCount1) {
channels.emplace_back();
DNAANIM::Channel& chan = channels.back();
chan.type = DNAANIM::Channel::Type::Rotation;
@ -382,8 +352,7 @@ void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
}
keyframeCount = std::max(keyframeCount, desc.keyCount1);
if (desc.keyCount2)
{
if (desc.keyCount2) {
channels.emplace_back();
DNAANIM::Channel& chan = channels.back();
chan.type = DNAANIM::Channel::Type::Translation;
@ -396,17 +365,13 @@ void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
chan.q[2] = desc.QinitTZ & 0xff;
}
}
}
else
{
for (size_t b=0 ; b<head.boneChannelCount ; ++b)
{
} else {
for (size_t b = 0; b < head.boneChannelCount; ++b) {
ChannelDesc desc;
desc.read(reader);
bones.emplace_back(desc.id, desc.keyCount2 != 0);
if (desc.keyCount1)
{
if (desc.keyCount1) {
channels.emplace_back();
DNAANIM::Channel& chan = channels.back();
chan.type = DNAANIM::Channel::Type::Rotation;
@ -420,8 +385,7 @@ void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
}
keyframeCount = std::max(keyframeCount, atUint32(desc.keyCount1));
if (desc.keyCount2)
{
if (desc.keyCount2) {
channels.emplace_back();
DNAANIM::Channel& chan = channels.back();
chan.type = DNAANIM::Channel::Type::Translation;
@ -443,8 +407,7 @@ void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader)
}
template <>
void ANIM::ANIM2::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
{
void ANIM::ANIM2::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
Header head;
head.evnt = evnt;
head.unk0 = 1;
@ -455,10 +418,8 @@ void ANIM::ANIM2::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
WordBitmap keyBmp;
size_t frameCount = 0;
for (atUint32 frame : frames)
{
if (!keyBmp.getBit(frame))
{
for (atUint32 frame : frames) {
if (!keyBmp.getBit(frame)) {
keyBmp.setBit(frame);
frameCount += 1;
}
@ -472,30 +433,25 @@ void ANIM::ANIM2::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
DNAANIM::BitstreamWriter bsWriter;
size_t bsSize;
float scaleMult;
std::unique_ptr<atUint8[]> bsData = bsWriter.write(chanKeys, keyframeCount, qChannels,
m_version == 3 ? 0x7fffff : 0x7fff,
head.rotDiv, head.translationMult, scaleMult, bsSize);
std::unique_ptr<atUint8[]> bsData =
bsWriter.write(chanKeys, keyframeCount, qChannels, m_version == 3 ? 0x7fffff : 0x7fff, head.rotDiv,
head.translationMult, scaleMult, bsSize);
/* Tally up buffer size */
size_t scratchSize = 0;
head.binarySize(scratchSize);
keyBmp.binarySize(scratchSize);
scratchSize += bsSize;
if (m_version == 3)
{
for (const std::pair<atUint32, bool>& bone : bones)
{
if (m_version == 3) {
for (const std::pair<atUint32, bool>& bone : bones) {
ChannelDescPC desc;
desc.keyCount1 = keyframeCount;
if (bone.second)
desc.keyCount2 = keyframeCount;
desc.binarySize(scratchSize);
}
}
else
{
for (const std::pair<atUint32, bool>& bone : bones)
{
} else {
for (const std::pair<atUint32, bool>& bone : bones) {
ChannelDesc desc;
desc.keyCount1 = keyframeCount;
if (bone.second)
@ -511,10 +467,8 @@ void ANIM::ANIM2::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
writer.writeUint32Big(head.boneChannelCount);
auto cit = qChannels.begin();
if (m_version == 3)
{
for (const std::pair<atUint32, bool>& bone : bones)
{
if (m_version == 3) {
for (const std::pair<atUint32, bool>& bone : bones) {
ChannelDescPC desc;
desc.id = bone.first;
DNAANIM::Channel& chan = *cit++;
@ -522,8 +476,7 @@ void ANIM::ANIM2::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
desc.QinitRX = (chan.i[0] << 8) | chan.q[0];
desc.QinitRY = (chan.i[1] << 8) | chan.q[1];
desc.QinitRZ = (chan.i[2] << 8) | chan.q[2];
if (bone.second)
{
if (bone.second) {
DNAANIM::Channel& chan = *cit++;
desc.keyCount2 = keyframeCount;
desc.QinitTX = (chan.i[0] << 8) | chan.q[0];
@ -532,11 +485,8 @@ void ANIM::ANIM2::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
}
desc.write(writer);
}
}
else
{
for (const std::pair<atUint32, bool>& bone : bones)
{
} else {
for (const std::pair<atUint32, bool>& bone : bones) {
ChannelDesc desc;
desc.id = bone.first;
DNAANIM::Channel& chan = *cit++;
@ -547,8 +497,7 @@ void ANIM::ANIM2::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
desc.qRY = chan.q[1];
desc.initRZ = chan.i[2];
desc.qRZ = chan.q[2];
if (bone.second)
{
if (bone.second) {
DNAANIM::Channel& chan = *cit++;
desc.keyCount2 = keyframeCount;
desc.initTX = chan.i[0];
@ -566,8 +515,7 @@ void ANIM::ANIM2::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer)
}
template <>
void ANIM::ANIM2::Enumerate<BigDNA::BinarySize>(size_t& __isz)
{
void ANIM::ANIM2::Enumerate<BigDNA::BinarySize>(size_t& __isz) {
Header head;
WordBitmap keyBmp;
@ -577,19 +525,14 @@ void ANIM::ANIM2::Enumerate<BigDNA::BinarySize>(size_t& __isz)
head.binarySize(__isz);
keyBmp.binarySize(__isz);
__isz += 8;
if (m_version == 3)
{
for (const std::pair<atUint32, bool>& bone : bones)
{
if (m_version == 3) {
for (const std::pair<atUint32, bool>& bone : bones) {
__isz += 24;
if (bone.second)
__isz += 12;
}
}
else
{
for (const std::pair<atUint32, bool>& bone : bones)
{
} else {
for (const std::pair<atUint32, bool>& bone : bones) {
__isz += 17;
if (bone.second)
__isz += 9;
@ -599,11 +542,8 @@ void ANIM::ANIM2::Enumerate<BigDNA::BinarySize>(size_t& __isz)
__isz += DNAANIM::ComputeBitstreamSize(frames.size(), channels);
}
ANIM::ANIM(const BlenderAction& act,
const std::unordered_map<std::string, atInt32>& idMap,
const DNAANIM::RigInverter<CINF>& rig,
bool pc)
{
ANIM::ANIM(const BlenderAction& act, const std::unordered_map<std::string, atInt32>& idMap,
const DNAANIM::RigInverter<CINF>& rig, bool pc) {
m_anim.reset(new struct ANIM2(pc));
IANIM& newAnim = *m_anim;
newAnim.looping = act.looping;
@ -612,11 +552,9 @@ ANIM::ANIM(const BlenderAction& act,
size_t extChanCount = 0;
std::unordered_set<atInt32> addedBones;
addedBones.reserve(act.channels.size());
for (const BlenderAction::Channel& chan : act.channels)
{
for (const BlenderAction::Channel& chan : act.channels) {
auto search = idMap.find(chan.boneName);
if (search == idMap.cend())
{
if (search == idMap.cend()) {
Log.report(logvisor::Warning, "unable to find id for bone '%s'", chan.boneName.c_str());
continue;
}
@ -635,8 +573,7 @@ ANIM::ANIM(const BlenderAction& act,
newAnim.channels.reserve(extChanCount);
newAnim.chanKeys.reserve(extChanCount);
for (const BlenderAction::Channel& chan : act.channels)
{
for (const BlenderAction::Channel& chan : act.channels) {
auto search = idMap.find(chan.boneName);
if (search == idMap.cend())
continue;
@ -650,8 +587,7 @@ ANIM::ANIM(const BlenderAction& act,
std::vector<DNAANIM::Value>& rotVals = newAnim.chanKeys.back();
rotVals.reserve(chan.keys.size());
float sign = 0.f;
for (const BlenderAction::Channel::Key& key : chan.keys)
{
for (const BlenderAction::Channel::Key& key : chan.keys) {
zeus::CQuaternion q(key.rotation.val);
q = rig.restoreRotation(newChan.id, q);
if (sign == 0.f)
@ -660,8 +596,7 @@ ANIM::ANIM(const BlenderAction& act,
rotVals.emplace_back(q.mSimd);
}
if (chan.attrMask & 0x2)
{
if (chan.attrMask & 0x2) {
newAnim.channels.emplace_back();
DNAANIM::Channel& newChan = newAnim.channels.back();
newChan.type = DNAANIM::Channel::Type::Translation;
@ -670,8 +605,7 @@ ANIM::ANIM(const BlenderAction& act,
newAnim.chanKeys.emplace_back();
std::vector<DNAANIM::Value>& transVals = newAnim.chanKeys.back();
transVals.reserve(chan.keys.size());
for (const BlenderAction::Channel::Key& key : chan.keys)
{
for (const BlenderAction::Channel::Key& key : chan.keys) {
zeus::CVector3f pos(key.position.val);
pos = rig.restorePosition(newChan.id, pos, true);
transVals.emplace_back(pos.mSimd);
@ -682,4 +616,4 @@ ANIM::ANIM(const BlenderAction& act,
newAnim.mainInterval = act.interval;
}
}
} // namespace DataSpec::DNAMP1

View File

@ -7,17 +7,14 @@
#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
{
struct IANIM : BigDNAV {
Delete expl;
atUint32 m_version;
IANIM(atUint32 version) : m_version(version) {}
@ -33,14 +30,12 @@ struct ANIM : BigDNA
void sendANIMToBlender(hecl::blender::PyOutStream&, const DNAANIM::RigInverter<CINF>& rig) const;
};
struct ANIM0 : IANIM
{
struct ANIM0 : IANIM {
AT_DECL_EXPLICIT_DNA
AT_DECL_DNAV
ANIM0() : IANIM(0) {}
struct Header : BigDNA
{
struct Header : BigDNA {
AT_DECL_DNA
Value<float> duration;
Value<atUint32> unk0;
@ -52,14 +47,12 @@ struct ANIM : BigDNA
};
};
struct ANIM2 : IANIM
{
struct ANIM2 : IANIM {
AT_DECL_EXPLICIT_DNA
AT_DECL_DNAV
ANIM2(bool pc) : IANIM(pc ? 3 : 2) {}
struct Header : BigDNA
{
struct Header : BigDNA {
AT_DECL_DNA
Value<atUint32> scratchSize;
UniqueID32Zero evnt;
@ -75,8 +68,7 @@ struct ANIM : BigDNA
Value<atUint32> keyBitmapBitCount;
};
struct ChannelDesc : BigDNA
{
struct ChannelDesc : BigDNA {
Delete expl;
Value<atUint32> id = 0;
Value<atUint16> keyCount1 = 0;
@ -94,8 +86,7 @@ struct ANIM : BigDNA
Value<atInt16> initTZ = 0;
Value<atUint8> qTZ = 0;
void read(athena::io::IStreamReader& reader)
{
void read(athena::io::IStreamReader& reader) {
id = reader.readUint32Big();
keyCount1 = reader.readUint16Big();
initRX = reader.readInt16Big();
@ -105,8 +96,7 @@ struct ANIM : BigDNA
initRZ = reader.readInt16Big();
qRZ = reader.readUByte();
keyCount2 = reader.readUint16Big();
if (keyCount2)
{
if (keyCount2) {
initTX = reader.readInt16Big();
qTX = reader.readUByte();
initTY = reader.readInt16Big();
@ -115,8 +105,7 @@ struct ANIM : BigDNA
qTZ = reader.readUByte();
}
}
void write(athena::io::IStreamWriter& writer) const
{
void write(athena::io::IStreamWriter& writer) const {
writer.writeUint32Big(id);
writer.writeUint16Big(keyCount1);
writer.writeInt16Big(initRX);
@ -126,8 +115,7 @@ struct ANIM : BigDNA
writer.writeInt16Big(initRZ);
writer.writeUByte(qRZ);
writer.writeUint16Big(keyCount2);
if (keyCount2)
{
if (keyCount2) {
writer.writeInt16Big(initTX);
writer.writeUByte(qTX);
writer.writeInt16Big(initTY);
@ -136,16 +124,14 @@ struct ANIM : BigDNA
writer.writeUByte(qTZ);
}
}
void binarySize(size_t& __isz) const
{
void binarySize(size_t& __isz) const {
__isz += 17;
if (keyCount2)
__isz += 9;
}
};
struct ChannelDescPC : BigDNA
{
struct ChannelDescPC : BigDNA {
Delete expl;
Value<atUint32> id = 0;
Value<atUint32> keyCount1 = 0;
@ -157,38 +143,33 @@ struct ANIM : BigDNA
Value<atUint32> QinitTY = 0;
Value<atUint32> QinitTZ = 0;
void read(athena::io::IStreamReader& reader)
{
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)
{
if (keyCount2) {
QinitTX = reader.readUint32Big();
QinitTY = reader.readUint32Big();
QinitTZ = reader.readUint32Big();
}
}
void write(athena::io::IStreamWriter& writer) const
{
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)
{
if (keyCount2) {
writer.writeUint32Big(QinitTX);
writer.writeUint32Big(QinitTY);
writer.writeUint32Big(QinitTZ);
}
}
void binarySize(size_t& __isz) const
{
void binarySize(size_t& __isz) const {
__isz += 24;
if (keyCount2)
__isz += 12;
@ -198,34 +179,27 @@ struct ANIM : BigDNA
std::unique_ptr<IANIM> m_anim;
void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig, bool) const
{
void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter<CINF>& rig, bool) const {
m_anim->sendANIMToBlender(os, rig);
}
bool isLooping() const
{
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)
{
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 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)
{
if (force || evntYamlType == hecl::ProjectPath::Type::None) {
EVNT evnt;
if (pakRouter.lookupAndReadDNA(m_anim->evnt, evnt, true))
{
if (pakRouter.lookupAndReadDNA(m_anim->evnt, evnt, true)) {
athena::io::FileWriter writer(evntYamlPath.getAbsolutePath());
athena::io::ToYAMLStream(evnt, writer);
}
@ -236,11 +210,8 @@ struct ANIM : BigDNA
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(const BlenderAction& act, const std::unordered_map<std::string, atInt32>& idMap,
const DNAANIM::RigInverter<CINF>& rig, bool pc);
};
}
} // namespace DataSpec::DNAMP1

View File

@ -1,14 +1,11 @@
#include "CINF.hpp"
#include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const
{
atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const {
atUint32 idx = 0;
for (const Bone& b : bones)
{
for (const Bone& b : bones) {
if (b.id == id)
return idx;
++idx;
@ -16,11 +13,9 @@ atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const
return -1;
}
atUint32 CINF::getBoneIdxFromId(atUint32 id) const
{
atUint32 CINF::getBoneIdxFromId(atUint32 id) const {
atUint32 idx = 0;
for (atUint32 bid : boneIds)
{
for (atUint32 bid : boneIds) {
if (bid == id)
return idx;
++idx;
@ -28,22 +23,17 @@ atUint32 CINF::getBoneIdxFromId(atUint32 id) const
return 0;
}
const std::string* CINF::getBoneNameFromId(atUint32 id) const
{
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)
{
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;
}
@ -51,11 +41,11 @@ void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const
}
}
void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const
{
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"
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"
@ -63,19 +53,17 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
"arm_bone_table = {}\n",
cinfId.toUint32());
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
{
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"
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);
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)
@ -86,26 +74,21 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
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);
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)
{
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())
{
if (search == idMap.end()) {
selId = curId++;
idMap.emplace(std::make_pair(bone->name, selId));
}
else
} else
selId = search->second;
bones.emplace_back();
@ -125,18 +108,15 @@ int CINF::RecursiveAddArmatureBone(const Armature& armature, const BlenderBone*
return boneOut.id;
}
CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& idMap)
{
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())
{
if (bone) {
if (bone->children.size()) {
int curId = 4;
const BlenderBone* child;
for (size_t i = 0; (child = armature.getChild(bone, i)); ++i)
@ -151,13 +131,10 @@ CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& i
boneOut.origin = bone->origin;
idMap.emplace(std::make_pair(bone->name, 3));
if (bone->children.size())
{
if (bone->children.size()) {
boneOut.linkedCount = 2;
boneOut.linked = {2, 4};
}
else
{
} else {
boneOut.linkedCount = 1;
boneOut.linked = {2};
}
@ -167,8 +144,7 @@ CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& i
names.reserve(nameMap.size());
nameCount = nameMap.size();
for (const auto& name : nameMap)
{
for (const auto& name : nameMap) {
names.emplace_back();
Name& nameOut = names.back();
nameOut.name = name.first;
@ -181,4 +157,4 @@ CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& i
boneIds.push_back(it->id);
}
}
} // namespace DataSpec::DNAMP1

View File

@ -3,15 +3,12 @@
#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
{
struct Bone : BigDNA {
AT_DECL_DNA
Value<atUint32> id;
Value<atUint32> parentId;
@ -25,8 +22,7 @@ struct CINF : BigDNA
Vector<atUint32, AT_DNA_COUNT(boneIdCount)> boneIds;
Value<atUint32> nameCount;
struct Name : BigDNA
{
struct Name : BigDNA {
AT_DECL_DNA
String<-1> name;
Value<atUint32> boneId;
@ -50,5 +46,4 @@ struct CINF : BigDNA
CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& idMap);
};
}
} // namespace DataSpec::DNAMP1

View File

@ -1,25 +1,17 @@
#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)
{
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)
{
if (rp) {
pakRouter.lookupAndReadDNA(rp->first, cskr);
pakRouter.lookupAndReadDNA(rp->second, cinf);
loadRp.first = &cskr;
@ -30,8 +22,8 @@ bool CMDL::Extract(const SpecBase& dataSpec,
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);
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*, CINF*>, DNACMDL::SurfaceHeader_1, 2>(
conn, rs, pakRouter, entry, dataSpec, loadRp);
conn.saveBlend();
#if 0
@ -61,12 +53,8 @@ bool CMDL::Extract(const SpecBase& dataSpec,
return true;
}
bool CMDL::Cook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNACMDL::Mesh& mesh)
{
if (!mesh.skins.empty())
{
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;
@ -79,11 +67,9 @@ bool CMDL::Cook(const hecl::ProjectPath& outPath,
writer.writeString(boneName);
writer.writeUint32Big(skinMesh.skins.size());
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins)
{
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins) {
writer.writeUint32Big(skin.size());
for (const DNACMDL::Mesh::SkinBind& bind : skin)
{
for (const DNACMDL::Mesh::SkinBind& bind : skin) {
writer.writeUint32Big(bind.boneIdx);
writer.writeFloatBig(bind.weight);
}
@ -91,28 +77,21 @@ bool CMDL::Cook(const hecl::ProjectPath& outPath,
}
writer.writeUint32Big(skinMesh.pos.size());
writer.writeUint32Big(skinMesh.norm.size());
}
else if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, mesh))
} 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)
{
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))
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)
{
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);
@ -123,11 +102,9 @@ bool CMDL::HMDLCook(const hecl::ProjectPath& outPath,
/* CVirtualBone structure just like original (for CPU skinning) */
writer.writeUint32Big(mesh.skins.size());
for (auto& s : mesh.skins)
{
for (auto& s : mesh.skins) {
writer.writeUint32Big(s.size());
for (auto& b : s)
{
for (auto& b : s) {
writer.writeUint32Big(b.boneIdx);
writer.writeFloatBig(b.weight);
}
@ -137,11 +114,10 @@ bool CMDL::HMDLCook(const hecl::ProjectPath& outPath,
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))
} 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,
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)
{
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,37 +5,37 @@
#include "DataSpec/DNACommon/CMDL.hpp"
#include "DNAMP1.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
struct MaterialSet : BigDNA
{
struct MaterialSet : BigDNA {
static constexpr bool OneSection() { return false; }
AT_DECL_DNA
struct MaterialSetHead : BigDNA
{
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;
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)
{
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())
{
if (txtrPath.isNone()) {
txtrPath.makeDirChain(false);
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath);
@ -44,85 +44,171 @@ struct MaterialSet : BigDNA
}
} head;
struct Material : BigDNA
{
struct Material : BigDNA {
AT_DECL_DNA
struct Flags : BigDNA
{
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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
{
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);}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
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;}
void setTex6MatIdx(GX::AttrType val) {
vaFlags &= ~0x80000000;
vaFlags |= atUint32(val & 0x1) << 31;
}
size_t vertDLSize() const
{
size_t vertDLSize() const {
static size_t ATTR_SZ[] = {0, 1, 1, 2};
size_t ret = 0;
ret += ATTR_SZ[position()];
@ -159,28 +245,44 @@ struct MaterialSet : BigDNA
Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
Value<atUint32> colorChannelCount = 0;
struct ColorChannel : BigDNA
{
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);}
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;}
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;}
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;}
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;}
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;}
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
{
struct TEVStage : BigDNA {
AT_DECL_DNA
Value<atUint32> ciFlags = 0;
Value<atUint32> aiFlags = 0;
@ -192,44 +294,98 @@ struct MaterialSet : BigDNA
Value<atUint8> rascInput = 0;
GX::TevColorArg colorInA() const { return GX::TevColorArg(ciFlags & 0xf); }
void setColorInA(GX::TevColorArg val) {ciFlags &= ~0x1f; ciFlags |= atUint32(val);}
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;}
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;}
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;}
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);}
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;}
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;}
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;}
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);}
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;}
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;}
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;}
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;}
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);}
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;}
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;}
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;}
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;}
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; }
@ -240,8 +396,7 @@ struct MaterialSet : BigDNA
void setRASIn(GX::ChannelID id) { rascInput = id; }
};
Vector<TEVStage, AT_DNA_COUNT(tevStageCount)> tevStages;
struct TEVStageTexInfo : BigDNA
{
struct TEVStageTexInfo : BigDNA {
AT_DECL_DNA
Value<atUint16> pad = 0;
Value<atUint8> texSlot = 0xff;
@ -250,31 +405,43 @@ struct MaterialSet : BigDNA
Vector<TEVStageTexInfo, AT_DNA_COUNT(tevStageCount)> tevStageTexInfo;
Value<atUint32> tcgCount = 0;
struct TexCoordGen : BigDNA
{
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);}
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;}
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;}
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;}
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;}
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
{
struct UVAnimation : BigDNA {
AT_DECL_EXPLICIT_DNA
enum class Mode
{
enum class Mode {
MvInvNoTranslation,
MvInv,
Scroll,
@ -288,66 +455,49 @@ struct MaterialSet : BigDNA
float vals[9];
UVAnimation() = default;
UVAnimation(const std::string& gameFunction,
const std::vector<atVec4f>& gameArgs);
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,
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 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);
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,
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)
{
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
{
void nameTextures(PAKRouter& pakRouter, const char* prefix, int setIdx) const {
int matIdx = 0;
for (const Material& mat : materials)
{
for (const Material& mat : materials) {
int stageIdx = 0;
for (const Material::TEVStage& stage : mat.tevStages)
{
for (const Material::TEVStage& stage : mat.tevStages) {
(void)stage;
const Material::TEVStageTexInfo& texInfo = mat.tevStageTexInfo[stageIdx];
if (texInfo.texSlot == 0xff)
{
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())
{
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;
@ -358,8 +508,7 @@ struct MaterialSet : BigDNA
else
texEntry->name = hecl::Format("%s_%d_%d_%d", prefix, setIdx, matIdx, stageIdx);
if (mat.flags.lightmap() && stageIdx == 0)
{
if (mat.flags.lightmap() && stageIdx == 0) {
texEntry->name += "light";
++stageIdx;
continue;
@ -371,21 +520,16 @@ struct MaterialSet : BigDNA
}
}
void ensureTexturesExtracted(PAKRouter<PAKBridge>& pakRouter) const
{
head.ensureTexturesExtracted(pakRouter);
}
void ensureTexturesExtracted(PAKRouter<PAKBridge>& pakRouter) const { head.ensureTexturesExtracted(pakRouter); }
};
struct HMDLMaterialSet : BigDNA
{
struct HMDLMaterialSet : BigDNA {
static constexpr bool OneSection() { return false; }
AT_DECL_DNA
MaterialSet::MaterialSetHead head;
struct Material : BigDNA
{
struct Material : BigDNA {
AT_DECL_DNA
MaterialSet::Material::Flags flags;
@ -402,14 +546,10 @@ struct HMDLMaterialSet : BigDNA
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);
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
{
void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const {
atUint32 accum = 0;
for (const SkinningRule& rule : skinningRules)
{
for (const SkinningRule& rule : skinningRules) {
if (idx >= accum && idx < accum + rule.vertCount)
for (const SkinningRule::Weight& weight : rule.weights)
os.format("vert[dvert_lay][%u] = %f\n",
cinf.getBoneIdxFromId(weight.boneId),
weight.weight);
os.format("vert[dvert_lay][%u] = %f\n", cinf.getBoneIdxFromId(weight.boneId), weight.weight);
accum += rule.vertCount;
}
}
}
} // namespace DataSpec::DNAMP1

View File

@ -3,19 +3,15 @@
#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
{
struct SkinningRule : BigDNA {
AT_DECL_DNA
Value<atUint32> weightCount;
struct Weight : BigDNA
{
struct Weight : BigDNA {
AT_DECL_DNA
Value<atUint32> boneId;
Value<float> weight;
@ -25,13 +21,9 @@ struct CSKR : BigDNA
};
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;
};
}
} // namespace DataSpec::DNAMP1

View File

@ -1,11 +1,9 @@
#include "CSNG.hpp"
#include "amuse/SongConverter.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
hecl::ProjectPath midPath = outPath.getWithExtension(_SYS_STR(".mid"), true);
hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true);
@ -55,8 +53,7 @@ bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
return true;
}
bool CSNG::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath)
{
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);
@ -99,4 +96,4 @@ bool CSNG::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
return true;
}
}
} // namespace DataSpec::DNAMP1

View File

@ -3,13 +3,10 @@
#include "DataSpec/DNACommon/DNACommon.hpp"
#include "DNAMP1.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
class CSNG
{
struct Header : BigDNA
{
class CSNG {
struct Header : BigDNA {
AT_DECL_DNA
Value<atUint32> magic = 0x2;
Value<atUint32> midiSetupId;
@ -17,10 +14,10 @@ class CSNG
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);
};
}
} // namespace DataSpec::DNAMP1

View File

@ -1,13 +1,12 @@
#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"
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"
@ -15,15 +14,13 @@ void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const
"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]);
"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)
{
if (!isLeaf) {
left->sendToBlender(os);
right->sendToBlender(os);
}
@ -31,21 +28,17 @@ void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const
#endif
template <class Op>
void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s)
{
void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) {
Do<Op>({"xf[0]"}, xf[0], s);
Do<Op>({"xf[1]"}, xf[1], s);
Do<Op>({"xf[2]"}, xf[2], s);
Do<Op>({"halfExtent"}, halfExtent, s);
Do<Op>({"isLeaf"}, isLeaf, s);
if (isLeaf)
{
if (isLeaf) {
if (!leafData)
leafData.reset(new LeafData);
Do<Op>({"leafData"}, *leafData, s);
}
else
{
} else {
if (!left)
left.reset(new Node);
Do<Op>({"left"}, *left, s);
@ -57,11 +50,11 @@ void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s)
AT_SPECIALIZE_DNA(DCLN::Collision::Node)
void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName)
{
void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName) {
/* Open Py Stream and read sections */
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os.format("import bpy\n"
os.format(
"import bpy\n"
"import bmesh\n"
"from mathutils import Vector, Matrix\n"
"\n"
@ -75,8 +68,7 @@ void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
DeafBabe::BlenderInit(os);
atInt32 idx = 0;
for (const Collision& col : collision)
{
for (const Collision& col : collision) {
DeafBabeSendToBlender(os, col, true, idx++);
#if DCLN_DUMP_OBB
col.root.sendToBlender(os);
@ -86,15 +78,9 @@ void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
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)
{
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();
@ -105,13 +91,10 @@ bool DCLN::Extract(const SpecBase& dataSpec,
return conn.saveBlend();
}
bool DCLN::Cook(const hecl::ProjectPath& outPath,
const std::vector<Mesh>& meshes)
{
bool DCLN::Cook(const hecl::ProjectPath& outPath, const std::vector<Mesh>& meshes) {
DCLN dcln;
dcln.colCount = atUint32(meshes.size());
for (const Mesh& mesh : meshes)
{
for (const Mesh& mesh : meshes) {
dcln.collision.emplace_back();
Collision& colOut = dcln.collision.back();
DeafBabeBuildFromBlender(colOut, mesh);
@ -135,4 +118,4 @@ bool DCLN::Cook(const hecl::ProjectPath& outPath,
return true;
}
}
} // namespace DataSpec::DNAMP1

View File

@ -9,17 +9,14 @@
#define DCLN_DUMP_OBB 0
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
struct DCLN : BigDNA
{
struct DCLN : BigDNA {
using Mesh = hecl::blender::ColMesh;
AT_DECL_DNA
Value<atUint32> colCount;
struct Collision : BigDNA
{
struct Collision : BigDNA {
using Material = DeafBabe::Material;
using Edge = DeafBabe::Edge;
using Triangle = DeafBabe::Triangle;
@ -43,12 +40,10 @@ struct DCLN : BigDNA
Value<atUint32> vertCount;
Vector<atVec3f, AT_DNA_COUNT(vertCount)> verts;
struct Node : BigDNA
{
struct Node : BigDNA {
AT_DECL_EXPLICIT_DNA
struct LeafData : BigDNA
{
struct LeafData : BigDNA {
AT_DECL_DNA
Value<atUint32> triangleIndexCount;
Vector<atUint16, AT_DNA_COUNT(triangleIndexCount)> triangleIndices;
@ -62,13 +57,11 @@ struct DCLN : BigDNA
std::unique_ptr<Node> left;
std::unique_ptr<Node> right;
size_t getMemoryUsage() const
{
size_t getMemoryUsage() const {
size_t ret = 80;
if (isLeaf)
ret += leafData->getMemoryUsage();
else
{
else {
ret += left->getMemoryUsage();
ret += right->getMemoryUsage();
}
@ -81,31 +74,21 @@ struct DCLN : BigDNA
#endif
};
Node root;
size_t getMemoryUsage()
{
return root.getMemoryUsage();
}
size_t getMemoryUsage() { return root.getMemoryUsage(); }
/* Dummy MP2 member */
void insertNoClimb(hecl::blender::PyOutStream&) const {}
};
Vector<Collision, AT_DNA_COUNT(colCount)> collision;
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,
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,12 +47,10 @@
#include "MazeSeeds.hpp"
#include "SnowForces.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
logvisor::Module Log("urde::DNAMP1");
static bool GetNoShare(std::string_view name)
{
static bool GetNoShare(std::string_view name) {
std::string lowerName(name);
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
if (!lowerName.compare(0, 7, "metroid"))
@ -61,23 +59,19 @@ static bool GetNoShare(std::string_view name)
}
PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
: m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract)
{
: m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract) {
nod::AthenaPartReadStream rs(node.beginReadStream());
m_pak.read(rs);
/* Append Level String */
for (auto& ent : m_pak.m_entries)
{
for (auto& ent : m_pak.m_entries) {
PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL'))
{
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)
{
if (nameEnt) {
nameEnt->name = entry.name + "_name";
PAKEntryReadStream rs = nameEnt->beginReadStream(m_node);
STRG mlvlName;
@ -90,8 +84,7 @@ PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
}
}
static hecl::SystemString LayerName(std::string_view name)
{
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('\\'))
@ -99,14 +92,11 @@ static hecl::SystemString LayerName(std::string_view name)
return ret;
}
void PAKBridge::build()
{
void PAKBridge::build() {
/* First pass: build per-area/per-layer dependency map */
for (const auto& ent : m_pak.m_entries)
{
for (const auto& ent : m_pak.m_entries) {
const PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL'))
{
if (entry.type == FOURCC('MLVL')) {
Level& level = m_levelDeps[entry.id];
MLVL mlvl;
@ -123,8 +113,7 @@ void PAKBridge::build()
/* Make MAPW available to lookup MAPAs */
PAK::Entry* worldMapEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldMap);
std::vector<UniqueID32> mapw;
if (worldMapEnt)
{
if (worldMapEnt) {
worldMapEnt->name = entry.name + "_mapw";
PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node);
rs.seek(8, athena::Current);
@ -144,13 +133,11 @@ void PAKBridge::build()
/* Index areas */
unsigned ai = 0;
for (const MLVL::Area& area : mlvl.areas)
{
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)
{
if (areaNameEnt) {
STRG areaName;
{
PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node);
@ -159,8 +146,7 @@ void PAKBridge::build()
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
}
if (areaDeps.name.empty())
{
if (areaDeps.name.empty()) {
std::string idStr = area.areaMREAId.toString();
areaDeps.name = hecl::SystemString(_SYS_STR("MREA_")) + hecl::SystemStringConv(idStr).c_str();
}
@ -169,8 +155,7 @@ void PAKBridge::build()
areaDeps.name = num + areaDeps.name;
std::string lowerName(hecl::SystemUTF8Conv(areaDeps.name).str());
for (char& ch : lowerName)
{
for (char& ch : lowerName) {
ch = tolower(ch);
if (ch == ' ')
ch = '_';
@ -183,8 +168,7 @@ void PAKBridge::build()
areaDeps.layers.reserve(area.depLayerCount - 1);
unsigned r = 0;
for (unsigned l=1 ; l<area.depLayerCount ; ++l)
{
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++]);
@ -210,23 +194,18 @@ void PAKBridge::build()
}
/* Second pass: cross-compare uniqueness */
for (auto& entry : m_pak.m_entries)
{
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'))
{
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)
{
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()));
@ -238,8 +217,7 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssoci
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)
{
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()));
@ -251,23 +229,19 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssoci
}
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animInfo;
ancs.getAnimationResInfo(&pakRouter, animInfo);
for (auto& ae : 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)
{
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'))
{
} else if (entry.second.type == FOURCC('MREA')) {
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc);
}
@ -275,12 +249,9 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssoci
}
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'))
{
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)
@ -293,12 +264,9 @@ 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, 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);
@ -309,8 +277,7 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
if (mlvl.worldNameId)
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _SYS_STR("!name.yaml"));
for (const MLVL::Area& area : mlvl.areas)
{
for (const MLVL::Area& area : mlvl.areas) {
{
/* Get PATH transform */
const nod::Node* areaNode;
@ -318,11 +285,8 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
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();
addTo[pathId] = zeus::CMatrix4f(area.transformMtx[0], area.transformMtx[1], area.transformMtx[2], BottomRow)
.transposed();
}
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
@ -330,28 +294,22 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _SYS_STR("!name.yaml"));
}
if (mlvl.worldMap)
{
if (mlvl.worldMap) {
const nod::Node* mapNode;
const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode);
if (mapEntry)
{
if (mapEntry) {
PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode);
u32 magic = rs.readUint32Big();
if (magic == 0xDEADF00D)
{
if (magic == 0xDEADF00D) {
rs.readUint32Big();
u32 count = rs.readUint32Big();
for (u32 i=0 ; i<count && i<mlvl.areas.size() ; ++i)
{
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();
addTo[mapaId] = zeus::CMatrix4f(areaData.transformMtx[0], areaData.transformMtx[1],
areaData.transformMtx[2], BottomRow)
.transposed();
}
}
}
@ -360,10 +318,8 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
}
}
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry)
{
switch (entry.type)
{
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'):
@ -417,12 +373,10 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
case SBIG('ATBL'):
return {DNAAudio::ATBL::Extract, {_SYS_STR(".yaml")}};
case SBIG('CTWK'):
case SBIG('DUMB'):
{
case SBIG('DUMB'): {
bool named;
std::string name = pak.bestEntryName(pakNode, entry, named);
if (named)
{
if (named) {
if (!name.compare("PlayerRes"))
return {ExtractTweak<CTweakPlayerRes>, {_SYS_STR(".yaml")}};
if (!name.compare("GunRes"))
@ -462,4 +416,4 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
return {};
}
}
} // namespace DataSpec::DNAMP1

View File

@ -4,16 +4,15 @@
#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
{
class PAKBridge {
const nod::Node& m_node;
PAK m_pak;
public:
bool m_doExtract;
using Level = DataSpec::Level<UniqueID32>;
@ -31,13 +30,10 @@ public:
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,
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,11 +1,9 @@
#include "DeafBabe.hpp"
#include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1
{
namespace DataSpec::DNAMP1 {
void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os)
{
void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) {
os << "TYPE_COLORS = {'NoSFX':(0.0, 0.0, 0.0),\n"
" 'Stone':(1.0, 0.43, 0.15),\n"
" 'Metal':(0.5, 0.5, 0.5),\n"
@ -53,7 +51,8 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os)
"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_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"
@ -230,4 +229,4 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os)
"\n";
}
}
} // namespace DataSpec::DNAMP1

View File

@ -2,82 +2,175 @@
#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
{
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
void setFloor(bool v) {
material &= ~(1ull << 31);
material |= (v << 31);
}
/* Dummies for later games */
bool surfaceSPMetal() const { return false; }
@ -104,14 +197,12 @@ struct DeafBabe : BigDNA
void setScrewAttackWallJump(bool v) {}
};
struct Edge : BigDNA
{
struct Edge : BigDNA {
AT_DECL_DNA
Value<atUint16> verts[2];
};
struct Triangle : BigDNA
{
struct Triangle : BigDNA {
AT_DECL_DNA
Value<atUint16> edges[3];
};
@ -143,11 +234,7 @@ struct DeafBabe : BigDNA
void insertNoClimb(hecl::blender::PyOutStream&) const {}
static void BlenderInit(hecl::blender::PyOutStream& os);
void sendToBlender(hecl::blender::PyOutStream& os) const
{
DeafBabeSendToBlender(os, *this);
}
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