mirror of https://github.com/AxioDL/metaforce.git
Initial MP3 MREA support
This commit is contained in:
parent
604484ac69
commit
bee7388242
|
@ -465,13 +465,13 @@ def make_pass_diff():
|
|||
|
||||
# Multiply1
|
||||
mult1 = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||
mult1.blend_type = 'MULTIPLY'
|
||||
mult1.blend_type = 'ADD'
|
||||
mult1.inputs[0].default_value = 1.0
|
||||
mult1.location = (-600, 0)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], mult1.inputs[1])
|
||||
new_grp.links.new(grp_in.outputs[1], mult1.inputs[2])
|
||||
new_grp.links.new(grp_in.outputs[2], mult1.inputs[2])
|
||||
new_grp.links.new(mult1.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
|
|
|
@ -334,7 +334,8 @@ atUint32 ReadGeomSectionsToBlender(HECL::BlenderConnection::PyOutStream& os,
|
|||
int meshIdx,
|
||||
atUint32 secCount,
|
||||
atUint32 matSetCount,
|
||||
const atUint32* secSizes)
|
||||
const atUint32* secSizes,
|
||||
atUint32 surfaceCount=0)
|
||||
{
|
||||
os << "# Begin bmesh\n"
|
||||
"bm = bmesh.new()\n"
|
||||
|
@ -348,7 +349,9 @@ atUint32 ReadGeomSectionsToBlender(HECL::BlenderConnection::PyOutStream& os,
|
|||
"\n";
|
||||
|
||||
/* Pre-read pass to determine maximum used vert indices */
|
||||
atUint32 matSecCount = MaterialSet::OneSection() ? 1 : matSetCount;
|
||||
atUint32 matSecCount = 0;
|
||||
if (matSetCount)
|
||||
matSecCount = MaterialSet::OneSection() ? 1 : matSetCount;
|
||||
bool visitedDLOffsets = false;
|
||||
atUint32 lastDlSec = secCount;
|
||||
atUint64 afterHeaderPos = reader.position();
|
||||
|
@ -391,14 +394,23 @@ atUint32 ReadGeomSectionsToBlender(HECL::BlenderConnection::PyOutStream& os,
|
|||
}
|
||||
case 4:
|
||||
{
|
||||
/* Short UVs */
|
||||
if (shortUVs)
|
||||
break;
|
||||
if (surfaceCount)
|
||||
{
|
||||
/* MP3 MREA case */
|
||||
visitedDLOffsets = true;
|
||||
lastDlSec = 4 + surfaceCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Short UVs */
|
||||
if (shortUVs)
|
||||
break;
|
||||
|
||||
/* DL Offsets (here or next section) */
|
||||
visitedDLOffsets = true;
|
||||
lastDlSec = s + reader.readUint32Big() + 1;
|
||||
break;
|
||||
/* DL Offsets (here or next section) */
|
||||
visitedDLOffsets = true;
|
||||
lastDlSec = s + reader.readUint32Big() + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
@ -508,24 +520,32 @@ atUint32 ReadGeomSectionsToBlender(HECL::BlenderConnection::PyOutStream& os,
|
|||
}
|
||||
case 4:
|
||||
{
|
||||
/* Short UVs */
|
||||
os << "suv_list = []\n";
|
||||
if (shortUVs)
|
||||
if (surfaceCount)
|
||||
{
|
||||
size_t uvCount = secSizes[s] / 4;
|
||||
for (size_t i=0 ; i<uvCount ; ++i)
|
||||
/* MP3 MREA case */
|
||||
visitedDLOffsets = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Short UVs */
|
||||
os << "suv_list = []\n";
|
||||
if (shortUVs)
|
||||
{
|
||||
float x = reader.readInt16Big() / 32768.0f;
|
||||
float y = reader.readInt16Big() / 32768.0f;
|
||||
os.format("suv_list.append((%f,%f))\n",
|
||||
x, y);
|
||||
size_t uvCount = secSizes[s] / 4;
|
||||
for (size_t i=0 ; i<uvCount ; ++i)
|
||||
{
|
||||
float x = reader.readInt16Big() / 32768.0f;
|
||||
float y = reader.readInt16Big() / 32768.0f;
|
||||
os.format("suv_list.append((%f,%f))\n",
|
||||
x, y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* DL Offsets (here or next section) */
|
||||
visitedDLOffsets = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* DL Offsets (here or next section) */
|
||||
visitedDLOffsets = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@ struct MREA
|
|||
{
|
||||
class StreamReader : public Athena::io::IStreamReader
|
||||
{
|
||||
protected:
|
||||
struct BlockInfo : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
|
@ -39,6 +40,11 @@ struct MREA
|
|||
atUint32 m_blkSz = 0;
|
||||
void nextBlock();
|
||||
|
||||
StreamReader(Athena::io::IStreamReader& source)
|
||||
: m_compBufSz(0x4120), m_compBuf(new atUint8[0x4120]),
|
||||
m_decompBufSz(0x4120), m_decompBuf(new atUint8[0x4120]),
|
||||
m_source(source) {} /* Empty constructor for inheriting */
|
||||
|
||||
public:
|
||||
StreamReader(Athena::io::IStreamReader& source, atUint32 blkCount);
|
||||
void seek(atInt64 diff, Athena::SeekOrigin whence);
|
||||
|
|
|
@ -3,11 +3,13 @@ make_dnalist(liblist
|
|||
MLVL
|
||||
CMDLMaterials
|
||||
CINF
|
||||
CSKR)
|
||||
CSKR
|
||||
MREA)
|
||||
add_library(DNAMP3
|
||||
DNAMP3.hpp DNAMP3.cpp
|
||||
${liblist}
|
||||
PAK.cpp
|
||||
CMDL.hpp
|
||||
CMDLMaterials.cpp
|
||||
STRG.hpp STRG.cpp)
|
||||
STRG.hpp STRG.cpp
|
||||
MREA.cpp)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "STRG.hpp"
|
||||
#include "MLVL.hpp"
|
||||
#include "CMDL.hpp"
|
||||
#include "MREA.hpp"
|
||||
#include "../DNACommon/TXTR.hpp"
|
||||
|
||||
namespace Retro
|
||||
|
@ -73,6 +74,8 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
|||
return {TXTR::Extract, nullptr, {_S(".png")}};
|
||||
case SBIG('CMDL'):
|
||||
return {nullptr, CMDL::Extract, {_S(".blend")}, 1};
|
||||
case SBIG('MREA'):
|
||||
return {nullptr, MREA::Extract, {_S(".blend")}, 2};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,310 @@
|
|||
#include <Athena/FileWriter.hpp>
|
||||
#include "MREA.hpp"
|
||||
#include "../DNAMP2/DeafBabe.hpp"
|
||||
|
||||
namespace Retro
|
||||
{
|
||||
namespace DNAMP3
|
||||
{
|
||||
|
||||
MREA::StreamReader::StreamReader(Athena::io::IStreamReader& source,
|
||||
atUint32 blkCount, atUint32 secIdxCount)
|
||||
: DNAMP2::MREA::StreamReader(source)
|
||||
{
|
||||
m_blkCount = blkCount;
|
||||
m_blockInfos.reserve(blkCount);
|
||||
for (int i=0 ; i<blkCount ; ++i)
|
||||
{
|
||||
m_blockInfos.emplace_back();
|
||||
BlockInfo& info = m_blockInfos.back();
|
||||
info.read(source);
|
||||
m_totalDecompLen += info.decompSize;
|
||||
}
|
||||
source.seekAlign32();
|
||||
m_secIdxs.reserve(secIdxCount);
|
||||
for (int i=0 ; i<secIdxCount ; ++i)
|
||||
{
|
||||
m_secIdxs.emplace_back();
|
||||
std::pair<DNAFourCC, atUint32>& idx = m_secIdxs.back();
|
||||
idx.first.read(source);
|
||||
idx.second = source.readUint32Big();
|
||||
}
|
||||
source.seekAlign32();
|
||||
m_blkBase = source.position();
|
||||
nextBlock();
|
||||
}
|
||||
|
||||
void MREA::StreamReader::writeSecIdxs(Athena::io::IStreamWriter& writer) const
|
||||
{
|
||||
for (const std::pair<DNAFourCC, atUint32>& idx : m_secIdxs)
|
||||
{
|
||||
idx.first.write(writer);
|
||||
writer.writeUint32Big(idx.second);
|
||||
}
|
||||
}
|
||||
|
||||
void MREA::ReadBabeDeadToBlender_3(HECL::BlenderConnection::PyOutStream& os,
|
||||
Athena::io::IStreamReader& rs)
|
||||
{
|
||||
atUint32 bdMagic = rs.readUint32Big();
|
||||
if (bdMagic != 0xBABEDEAD)
|
||||
Log.report(LogVisor::FatalError, "invalid BABEDEAD magic");
|
||||
os << "bpy.context.scene.render.engine = 'CYCLES'\n"
|
||||
"bpy.context.scene.world.use_nodes = True\n"
|
||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
||||
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n";
|
||||
for (atUint32 s=0 ; s<4 ; ++s)
|
||||
{
|
||||
atUint32 lightCount = rs.readUint32Big();
|
||||
for (atUint32 l=0 ; l<lightCount ; ++l)
|
||||
{
|
||||
BabeDeadLight light;
|
||||
light.read(rs);
|
||||
#if 0
|
||||
switch (light.lightType)
|
||||
{
|
||||
case BabeDeadLight::LightLocalAmbient:
|
||||
os.format("bg_node.inputs[0].default_value = (%f,%f,%f,1.0)\n"
|
||||
"bg_node.inputs[1].default_value = %f\n",
|
||||
light.color.vec[0], light.color.vec[1], light.color.vec[2],
|
||||
light.q / 8.0);
|
||||
continue;
|
||||
case BabeDeadLight::LightDirectional:
|
||||
os.format("lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SUN')\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"
|
||||
"\n", s, l,
|
||||
light.direction.vec[0], light.direction.vec[1], light.direction.vec[2]);
|
||||
break;
|
||||
case BabeDeadLight::LightCustom:
|
||||
os.format("lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'POINT')\n"
|
||||
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
||||
"\n", s, l);
|
||||
break;
|
||||
case BabeDeadLight::LightSpot:
|
||||
os.format("lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SPOT')\n"
|
||||
"lamp.spot_size = %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"
|
||||
"\n", s, l,
|
||||
light.spotCutoff * M_PI / 180.f,
|
||||
light.direction.vec[0], light.direction.vec[1], light.direction.vec[2]);
|
||||
break;
|
||||
default: continue;
|
||||
}
|
||||
|
||||
os.format("lamp.retro_layer = %u\n"
|
||||
"lamp.use_nodes = True\n"
|
||||
"falloff_node = lamp.node_tree.nodes.new('ShaderNodeLightFalloff')\n"
|
||||
"lamp.energy = 0.0\n"
|
||||
"falloff_node.inputs[0].default_value = %f\n"
|
||||
"hue_sat_node = lamp.node_tree.nodes.new('ShaderNodeHueSaturation')\n"
|
||||
"hue_sat_node.inputs[1].default_value = 1.25\n"
|
||||
"hue_sat_node.inputs[4].default_value = (%f,%f,%f,1.0)\n"
|
||||
"lamp.node_tree.links.new(hue_sat_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[0])\n"
|
||||
"lamp_obj.location = (%f,%f,%f)\n"
|
||||
"bpy.context.scene.objects.link(lamp_obj)\n"
|
||||
"\n", s, light.q / 8.0,
|
||||
light.color.vec[0], light.color.vec[1], light.color.vec[2],
|
||||
light.position.vec[0], light.position.vec[1], light.position.vec[2]);
|
||||
|
||||
switch (light.falloff)
|
||||
{
|
||||
case BabeDeadLight::FalloffConstant:
|
||||
os << "falloff_node.inputs[0].default_value *= 75.0\n"
|
||||
"lamp.node_tree.links.new(falloff_node.outputs[2], lamp.node_tree.nodes['Emission'].inputs[1])\n";
|
||||
break;
|
||||
case BabeDeadLight::FalloffLinear:
|
||||
os << "lamp.node_tree.links.new(falloff_node.outputs[1], lamp.node_tree.nodes['Emission'].inputs[1])\n";
|
||||
break;
|
||||
case BabeDeadLight::FalloffQuadratic:
|
||||
os << "lamp.node_tree.links.new(falloff_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[1])\n";
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MREA::Extract(const SpecBase& dataSpec,
|
||||
PAKEntryReadStream& rs,
|
||||
const HECL::ProjectPath& outPath,
|
||||
PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
bool,
|
||||
std::function<void(const HECL::SystemChar*)>)
|
||||
{
|
||||
using RigPair = std::pair<CSKR*, CINF*>;
|
||||
RigPair dummy(nullptr, nullptr);
|
||||
|
||||
/* Do extract */
|
||||
Header head;
|
||||
head.read(rs);
|
||||
rs.seekAlign32();
|
||||
|
||||
/* MREA decompression stream */
|
||||
StreamReader drs(rs, head.compressedBlockCount, head.secIndexCount);
|
||||
Athena::io::FileWriter mreaDecompOut(pakRouter.getCooked(&entry).getWithExtension(_S(".decomp")).getAbsolutePath());
|
||||
head.write(mreaDecompOut);
|
||||
mreaDecompOut.seekAlign32();
|
||||
drs.writeDecompInfos(mreaDecompOut);
|
||||
mreaDecompOut.seekAlign32();
|
||||
drs.writeSecIdxs(mreaDecompOut);
|
||||
mreaDecompOut.seekAlign32();
|
||||
atUint64 decompLen = drs.length();
|
||||
mreaDecompOut.writeBytes(drs.readBytes(decompLen).get(), decompLen);
|
||||
drs.seek(0, Athena::Begin);
|
||||
|
||||
|
||||
/* Start up blender connection */
|
||||
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
||||
if (!conn.createBlend(outPath.getAbsolutePath()))
|
||||
return false;
|
||||
|
||||
/* Open Py Stream and read sections */
|
||||
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut(true);
|
||||
os.format("import bpy\n"
|
||||
"import bmesh\n"
|
||||
"from mathutils import Vector\n"
|
||||
"\n"
|
||||
"bpy.context.scene.name = '%s'\n"
|
||||
"bpy.context.scene.hecl_type = 'AREA'\n",
|
||||
pakRouter.getBestEntryName(entry).c_str());
|
||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath());
|
||||
MaterialSet::RegisterMaterialProps(os);
|
||||
os << "# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"bpy.types.Lamp.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
||||
"\n";
|
||||
|
||||
/* One shared material set for all meshes */
|
||||
os << "# Materials\n"
|
||||
"materials = []\n"
|
||||
"\n";
|
||||
MaterialSet matSet;
|
||||
atUint64 secStart = drs.position();
|
||||
matSet.read(drs);
|
||||
matSet.readToBlender(os, pakRouter, entry, 0);
|
||||
drs.seek(secStart + head.secSizes[0], Athena::Begin);
|
||||
std::vector<DNACMDL::VertexAttributes> vertAttribs;
|
||||
DNACMDL::GetVertexAttributes(matSet, vertAttribs);
|
||||
|
||||
/* Read mesh info */
|
||||
atUint32 curSec = 1;
|
||||
auto secIdxIt = drs.beginSecIdxs();
|
||||
std::vector<atUint32> surfaceCounts;
|
||||
surfaceCounts.reserve(head.meshCount);
|
||||
for (int m=0 ; m<head.meshCount ; ++m)
|
||||
{
|
||||
if (secIdxIt->first == FOURCC('WOBJ'))
|
||||
{
|
||||
/* Mesh header */
|
||||
MeshHeader mHeader;
|
||||
secStart = drs.position();
|
||||
mHeader.read(drs);
|
||||
drs.seek(secStart + head.secSizes[curSec++], Athena::Begin);
|
||||
|
||||
/* Surface count from here */
|
||||
secStart = drs.position();
|
||||
surfaceCounts.push_back(drs.readUint32Big());
|
||||
drs.seek(secStart + head.secSizes[curSec++], Athena::Begin);
|
||||
|
||||
/* Seek through AROT-relation sections */
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
++secIdxIt;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip AROT */
|
||||
if (secIdxIt->first == FOURCC('ROCT'))
|
||||
{
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
++secIdxIt;
|
||||
}
|
||||
|
||||
/* Skip AABB */
|
||||
if (secIdxIt->first == FOURCC('AABB'))
|
||||
{
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
++secIdxIt;
|
||||
}
|
||||
|
||||
/* Now the meshes themselves */
|
||||
if (secIdxIt->first == FOURCC('GPUD'))
|
||||
{
|
||||
for (int m=0 ; m<head.meshCount ; ++m)
|
||||
{
|
||||
curSec += DNACMDL::ReadGeomSectionsToBlender<PAKRouter<PAKBridge>, MaterialSet, RigPair>
|
||||
(os, drs, pakRouter, entry, dummy, true,
|
||||
false, vertAttribs, m, head.secCount, 0, &head.secSizes[curSec], surfaceCounts[m]);
|
||||
}
|
||||
++secIdxIt;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
/* Skip AROT */
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
|
||||
/* Skip BVH */
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
|
||||
/* Skip Bitmap */
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
|
||||
/* Skip SCLY (for now) */
|
||||
for (atUint32 l=0 ; l<head.sclyLayerCount ; ++l)
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
|
||||
/* Skip SCGN (for now) */
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
|
||||
/* Read collision meshes */
|
||||
DNAMP2::DeafBabe collision;
|
||||
secStart = drs.position();
|
||||
collision.read(drs);
|
||||
DNAMP2::DeafBabe::BlenderInit(os);
|
||||
collision.sendToBlender(os);
|
||||
drs.seek(secStart + head.secSizes[curSec++], Athena::Begin);
|
||||
|
||||
/* Skip unknown section */
|
||||
drs.seek(head.secSizes[curSec++], Athena::Current);
|
||||
|
||||
/* Read BABEDEAD Lights as Cycles emissives */
|
||||
secStart = drs.position();
|
||||
ReadBabeDeadToBlender_3(os, drs);
|
||||
drs.seek(secStart + head.secSizes[curSec++], Athena::Begin);
|
||||
#endif
|
||||
|
||||
/* Origins to center of mass */
|
||||
os << "bpy.context.scene.layers[1] = True\n"
|
||||
"bpy.ops.object.select_by_type(type='MESH')\n"
|
||||
"bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n"
|
||||
"bpy.ops.object.select_all(action='DESELECT')\n"
|
||||
"bpy.context.scene.layers[1] = False\n";
|
||||
|
||||
/* Center view */
|
||||
os << "bpy.context.user_preferences.view.smooth_view = 0\n"
|
||||
"for window in bpy.context.window_manager.windows:\n"
|
||||
" screen = window.screen\n"
|
||||
" for area in screen.areas:\n"
|
||||
" if area.type == 'VIEW_3D':\n"
|
||||
" for region in area.regions:\n"
|
||||
" if region.type == 'WINDOW':\n"
|
||||
" override = {'scene': bpy.context.scene, 'window': window, 'screen': screen, 'area': area, 'region': region}\n"
|
||||
" bpy.ops.view3d.view_all(override)\n"
|
||||
" break\n";
|
||||
|
||||
os.close();
|
||||
return conn.saveBlend();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
#ifndef __DNAMP3_MREA_HPP__
|
||||
#define __DNAMP3_MREA_HPP__
|
||||
|
||||
#include "../DNACommon/DNACommon.hpp"
|
||||
#include "CMDLMaterials.hpp"
|
||||
#include "CSKR.hpp"
|
||||
#include "../DNAMP2/MREA.hpp"
|
||||
|
||||
namespace Retro
|
||||
{
|
||||
namespace DNAMP3
|
||||
{
|
||||
|
||||
struct MREA
|
||||
{
|
||||
class StreamReader : public DNAMP2::MREA::StreamReader
|
||||
{
|
||||
std::vector<std::pair<DNAFourCC, atUint32>> m_secIdxs;
|
||||
public:
|
||||
StreamReader(Athena::io::IStreamReader& source,
|
||||
atUint32 blkCount, atUint32 secIdxCount);
|
||||
std::vector<std::pair<DNAFourCC, atUint32>>::const_iterator beginSecIdxs()
|
||||
{
|
||||
return m_secIdxs.begin();
|
||||
}
|
||||
void writeSecIdxs(Athena::io::IStreamWriter& writer) const;
|
||||
};
|
||||
|
||||
struct Header : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> magic;
|
||||
Value<atUint32> version;
|
||||
Value<atVec4f> localToWorldMtx[3];
|
||||
Value<atUint32> meshCount;
|
||||
Value<atUint32> sclyLayerCount;
|
||||
Value<atUint32> secCount;
|
||||
Value<atUint32> compressedBlockCount;
|
||||
Value<atUint32> secIndexCount;
|
||||
Seek<20, Athena::Current> align1;
|
||||
Vector<atUint32, DNA_COUNT(secCount)> secSizes;
|
||||
};
|
||||
|
||||
struct MeshHeader : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
struct VisorFlags : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> flags;
|
||||
} visorFlags;
|
||||
Value<atVec4f> xfMtx[3];
|
||||
Value<atVec3f> aabb[2];
|
||||
};
|
||||
|
||||
struct BabeDeadLight : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
enum LightType : atUint32
|
||||
{
|
||||
LightLocalAmbient,
|
||||
LightDirectional,
|
||||
LightCustom,
|
||||
LightSpot
|
||||
};
|
||||
Value<LightType> lightType;
|
||||
Value<atVec4f> color;
|
||||
Value<atVec3f> position;
|
||||
Value<atVec4f> unk3;
|
||||
Value<float> power;
|
||||
Value<float> unk4;
|
||||
Value<float> unk5;
|
||||
Value<float> unk6;
|
||||
Value<atUint8> unk7;
|
||||
Value<atUint32> unk8;
|
||||
Value<atUint32> unk9;
|
||||
Value<float> unk10;
|
||||
Value<atUint32> unk11;
|
||||
Value<atVec4f> unk12;
|
||||
Value<atUint32> unk13;
|
||||
};
|
||||
|
||||
static void ReadBabeDeadToBlender_3(HECL::BlenderConnection::PyOutStream& os,
|
||||
Athena::io::IStreamReader& rs);
|
||||
|
||||
static bool Extract(const SpecBase& dataSpec,
|
||||
PAKEntryReadStream& rs,
|
||||
const HECL::ProjectPath& outPath,
|
||||
PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
bool,
|
||||
std::function<void(const HECL::SystemChar*)>);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __DNAMP3_MREA_HPP__
|
Loading…
Reference in New Issue