mirror of https://github.com/AxioDL/metaforce.git
Initial MP1 MREA support
This commit is contained in:
parent
35a6ddab14
commit
2fef79ceaa
|
@ -0,0 +1,152 @@
|
|||
#include "CMDL.hpp"
|
||||
|
||||
namespace Retro
|
||||
{
|
||||
namespace DNACMDL
|
||||
{
|
||||
|
||||
void InitGeomBlenderContext(HECL::BlenderConnection::PyOutStream& os,
|
||||
const HECL::ProjectPath& masterShaderPath)
|
||||
{
|
||||
os << "# Using 'Blender Game'\n"
|
||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
||||
"\n"
|
||||
"# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'LAMP':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"\n"
|
||||
"# Property to convey original vert indices in overdraw meshes\n"
|
||||
"class CMDLOriginalIndex(bpy.types.PropertyGroup):\n"
|
||||
" index = bpy.props.IntProperty(name='Original Vertex Index')\n"
|
||||
"bpy.utils.register_class(CMDLOriginalIndex)\n"
|
||||
"bpy.types.Mesh.cmdl_orig_verts = bpy.props.CollectionProperty(type=CMDLOriginalIndex)\n"
|
||||
"\n"
|
||||
"def loop_from_facevert(face, vert_idx):\n"
|
||||
" for loop in face.loops:\n"
|
||||
" if loop.vert.index == vert_idx:\n"
|
||||
" return loop\n"
|
||||
"\n"
|
||||
"def add_triangle(bm, vert_seq, vert_indices, norm_seq, norm_indices, mat_nr, od_list):\n"
|
||||
" if len(set(vert_indices)) != 3:\n"
|
||||
" return None, None\n"
|
||||
"\n"
|
||||
" ret_mesh = bm\n"
|
||||
" vert_seq.ensure_lookup_table()\n"
|
||||
" verts = [vert_seq[i] for i in vert_indices]\n"
|
||||
" norms = [norm_seq[i] for i in norm_indices]\n"
|
||||
"\n"
|
||||
" # Make the face\n"
|
||||
" face = bm.faces.get(verts)\n"
|
||||
"\n"
|
||||
" if face is not None and face.material_index != mat_nr: # Same poly, new material\n"
|
||||
" # Overdraw detected; track copy\n"
|
||||
" od_entry = None\n"
|
||||
" for entry in od_list:\n"
|
||||
" if entry['material'] == mat_nr:\n"
|
||||
" od_entry = entry\n"
|
||||
" if od_entry is None:\n"
|
||||
" bm_cpy = bm.copy()\n"
|
||||
" od_entry = {'material':mat_nr, 'bm':bm_cpy}\n"
|
||||
" bmesh.ops.delete(od_entry['bm'], geom=od_entry['bm'].faces, context=3)\n"
|
||||
" od_list.append(od_entry)\n"
|
||||
" od_entry['bm'].verts.ensure_lookup_table()\n"
|
||||
" verts = [od_entry['bm'].verts[i] for i in vert_indices]\n"
|
||||
" face = od_entry['bm'].faces.get(verts)\n"
|
||||
" if face is None:\n"
|
||||
" face = od_entry['bm'].faces.new(verts)\n"
|
||||
" else: # Probably a double-sided surface\n"
|
||||
" face = face.copy()\n"
|
||||
" face.normal_flip()\n"
|
||||
" ret_mesh = od_entry['bm']\n"
|
||||
"\n"
|
||||
" elif face is not None: # Same material, probably double-sided\n"
|
||||
" face = face.copy()\n"
|
||||
" face.normal_flip()\n"
|
||||
"\n"
|
||||
" else: \n"
|
||||
" face = bm.faces.new(verts)\n"
|
||||
"\n"
|
||||
" # Apply normals\n"
|
||||
" for i in range(3):\n"
|
||||
" verts[i].normal = norms[i]\n"
|
||||
"\n"
|
||||
" for i in range(3):\n"
|
||||
" face.verts[i].index = vert_indices[i]\n"
|
||||
" face.material_index = mat_nr\n"
|
||||
" face.smooth = True\n"
|
||||
"\n"
|
||||
" return face, ret_mesh\n"
|
||||
"\n";
|
||||
|
||||
/* Link master shader library */
|
||||
os.format("# Master shader library\n"
|
||||
"with bpy.data.libraries.load('%s', link=True, relative=True) as (data_from, data_to):\n"
|
||||
" data_to.node_groups = data_from.node_groups\n"
|
||||
"\n", masterShaderPath.getAbsolutePathUTF8().c_str());
|
||||
}
|
||||
|
||||
void FinishBlenderMesh(HECL::BlenderConnection::PyOutStream& os,
|
||||
unsigned matSetCount, int meshIdx)
|
||||
{
|
||||
if (meshIdx < 0)
|
||||
os.format("mesh = bpy.data.meshes.new(bpy.context.scene.name)\n"
|
||||
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
||||
"obj.show_transparent = True\n"
|
||||
"bpy.context.scene.objects.link(obj)\n"
|
||||
"mesh.hecl_material_count = %u\n", matSetCount);
|
||||
else
|
||||
os.format("mesh = bpy.data.meshes.new(bpy.context.scene.name + '_%3d')\n"
|
||||
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
||||
"obj.show_transparent = True\n"
|
||||
"bpy.context.scene.objects.link(obj)\n"
|
||||
"mesh.hecl_material_count = %u\n", meshIdx, matSetCount);
|
||||
|
||||
os << "for material in materials:\n"
|
||||
" mesh.materials.append(material)\n"
|
||||
"\n"
|
||||
"# Preserve original indices\n"
|
||||
"for vert in bm.verts:\n"
|
||||
" ov = mesh.cmdl_orig_verts.add()\n"
|
||||
" ov.index = vert.index\n"
|
||||
"\n"
|
||||
"# Merge OD meshes\n"
|
||||
"for od_entry in od_list:\n"
|
||||
" vert_dict = {}\n"
|
||||
"\n"
|
||||
" for vert in od_entry['bm'].verts:\n"
|
||||
" if len(vert.link_faces):\n"
|
||||
" vert_dict[vert.index] = bm.verts.new(vert.co, vert)\n"
|
||||
" ov = mesh.cmdl_orig_verts.add()\n"
|
||||
" ov.index = vert.index\n"
|
||||
"\n"
|
||||
" for face in od_entry['bm'].faces:\n"
|
||||
" merge_verts = [vert_dict[fv.index] for fv in face.verts]\n"
|
||||
" if bm.faces.get(merge_verts) is not None:\n"
|
||||
" continue\n"
|
||||
" merge_face = bm.faces.new(merge_verts)\n"
|
||||
" for i in range(len(face.loops)):\n"
|
||||
" old = face.loops[i]\n"
|
||||
" new = merge_face.loops[i]\n"
|
||||
" for j in range(len(od_entry['bm'].loops.layers.uv)):\n"
|
||||
" new[bm.loops.layers.uv[j]] = old[od_entry['bm'].loops.layers.uv[j]]\n"
|
||||
" merge_face.smooth = True\n"
|
||||
" merge_face.material_index = face.material_index\n"
|
||||
"\n"
|
||||
" od_entry['bm'].free()\n"
|
||||
"\n"
|
||||
"# Remove loose vertices\n"
|
||||
"#to_remove = []\n"
|
||||
"#for vert in bm.verts:\n"
|
||||
"# if not len(vert.link_faces):\n"
|
||||
"# to_remove.append(vert)\n"
|
||||
"#bmesh.ops.delete(bm, geom=to_remove, context=1)\n"
|
||||
"\n"
|
||||
"bm.to_mesh(mesh)\n"
|
||||
"bm.free()\n"
|
||||
"\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -58,6 +58,7 @@ struct VertexAttributes
|
|||
GX::AttrType pnMtxIdx = GX::NONE;
|
||||
unsigned texMtxIdxCount = 0;
|
||||
GX::AttrType texMtxIdx[7] = {GX::NONE};
|
||||
bool shortUVs;
|
||||
};
|
||||
|
||||
template <class MaterialSet>
|
||||
|
@ -109,6 +110,8 @@ void GetVertexAttributes(const MaterialSet& matSet,
|
|||
++va.texMtxIdxCount;
|
||||
if ((va.texMtxIdx[6] = vaFlags.tex6MatIdx()))
|
||||
++va.texMtxIdxCount;
|
||||
|
||||
va.shortUVs = mat.getFlags().lightmapUVArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,141 +307,46 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <class PAKRouter, class MaterialSet, class RIGPAIR, atUint32 Version>
|
||||
bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
||||
Athena::io::IStreamReader& reader,
|
||||
PAKRouter& pakRouter,
|
||||
const typename PAKRouter::EntryType& entry,
|
||||
const SpecBase& dataspec,
|
||||
const RIGPAIR& rp)
|
||||
void InitGeomBlenderContext(HECL::BlenderConnection::PyOutStream& os,
|
||||
const HECL::ProjectPath& masterShaderPath);
|
||||
void FinishBlenderMesh(HECL::BlenderConnection::PyOutStream& os,
|
||||
unsigned matSetCount, int meshIdx);
|
||||
|
||||
template <class PAKRouter, class MaterialSet, class RIGPAIR>
|
||||
atUint32 ReadGeomSectionsToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
Athena::io::IStreamReader& reader,
|
||||
PAKRouter& pakRouter,
|
||||
const typename PAKRouter::EntryType& entry,
|
||||
const SpecBase& dataspec,
|
||||
const RIGPAIR& rp,
|
||||
bool shortNormals,
|
||||
bool shortUVs,
|
||||
std::vector<VertexAttributes>& vertAttribs,
|
||||
int meshIdx,
|
||||
atUint32 secCount,
|
||||
atUint32 matSetCount,
|
||||
const atUint32* secSizes)
|
||||
{
|
||||
Header head;
|
||||
head.read(reader);
|
||||
|
||||
if (head.magic != 0xDEADBABE)
|
||||
{
|
||||
LogDNACommon.report(LogVisor::Error, "invalid CMDL magic");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (head.version != Version)
|
||||
{
|
||||
LogDNACommon.report(LogVisor::Error, "invalid CMDL version");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Open Py Stream */
|
||||
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut(true);
|
||||
os.format("import bpy\n"
|
||||
"import bmesh\n"
|
||||
"\n"
|
||||
"bpy.context.scene.name = '%s'\n"
|
||||
"bpy.context.scene.hecl_type = 'MESH'\n"
|
||||
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n"
|
||||
"\n"
|
||||
"# Using 'Blender Game'\n"
|
||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
||||
"\n"
|
||||
"# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'LAMP':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"\n"
|
||||
"# Property to convey original vert indices in overdraw meshes\n"
|
||||
"class CMDLOriginalIndex(bpy.types.PropertyGroup):\n"
|
||||
" index = bpy.props.IntProperty(name='Original Vertex Index')\n"
|
||||
"bpy.utils.register_class(CMDLOriginalIndex)\n"
|
||||
"bpy.types.Mesh.cmdl_orig_verts = bpy.props.CollectionProperty(type=CMDLOriginalIndex)\n"
|
||||
"\n"
|
||||
"def loop_from_facevert(face, vert_idx):\n"
|
||||
" for loop in face.loops:\n"
|
||||
" if loop.vert.index == vert_idx:\n"
|
||||
" return loop\n"
|
||||
"\n"
|
||||
"def add_triangle(bm, vert_seq, vert_indices, norm_seq, norm_indices, mat_nr, od_list):\n"
|
||||
" if len(set(vert_indices)) != 3:\n"
|
||||
" return None, None\n"
|
||||
"\n"
|
||||
" ret_mesh = bm\n"
|
||||
" vert_seq.ensure_lookup_table()\n"
|
||||
" verts = [vert_seq[i] for i in vert_indices]\n"
|
||||
" norms = [norm_seq[i] for i in norm_indices]\n"
|
||||
"\n"
|
||||
" # Make the face\n"
|
||||
" face = bm.faces.get(verts)\n"
|
||||
"\n"
|
||||
" if face is not None and face.material_index != mat_nr: # Same poly, new material\n"
|
||||
" # Overdraw detected; track copy\n"
|
||||
" od_entry = None\n"
|
||||
" for entry in od_list:\n"
|
||||
" if entry['material'] == mat_nr:\n"
|
||||
" od_entry = entry\n"
|
||||
" if od_entry is None:\n"
|
||||
" bm_cpy = bm.copy()\n"
|
||||
" od_entry = {'material':mat_nr, 'bm':bm_cpy}\n"
|
||||
" bmesh.ops.delete(od_entry['bm'], geom=od_entry['bm'].faces, context=3)\n"
|
||||
" od_list.append(od_entry)\n"
|
||||
" od_entry['bm'].verts.ensure_lookup_table()\n"
|
||||
" verts = [od_entry['bm'].verts[i] for i in vert_indices]\n"
|
||||
" face = od_entry['bm'].faces.get(verts)\n"
|
||||
" if face is None:\n"
|
||||
" face = od_entry['bm'].faces.new(verts)\n"
|
||||
" else: # Probably a double-sided surface\n"
|
||||
" face = face.copy()\n"
|
||||
" face.normal_flip()\n"
|
||||
" ret_mesh = od_entry['bm']\n"
|
||||
"\n"
|
||||
" elif face is not None: # Same material, probably double-sided\n"
|
||||
" face = face.copy()\n"
|
||||
" face.normal_flip()\n"
|
||||
"\n"
|
||||
" else: \n"
|
||||
" face = bm.faces.new(verts)\n"
|
||||
"\n"
|
||||
" # Apply normals\n"
|
||||
" for i in range(3):\n"
|
||||
" verts[i].normal = norms[i]\n"
|
||||
"\n"
|
||||
" for i in range(3):\n"
|
||||
" face.verts[i].index = vert_indices[i]\n"
|
||||
" face.material_index = mat_nr\n"
|
||||
" face.smooth = True\n"
|
||||
"\n"
|
||||
" return face, ret_mesh\n"
|
||||
"\n"
|
||||
"# Begin bmesh\n"
|
||||
"bm = bmesh.new()\n"
|
||||
"\n", pakRouter.getBestEntryName(entry).c_str());
|
||||
os << "# Begin bmesh\n"
|
||||
"bm = bmesh.new()\n"
|
||||
"\n";
|
||||
|
||||
if (rp.first)
|
||||
os << "dvert_lay = bm.verts.layers.deform.verify()\n";
|
||||
|
||||
/* Link master shader library */
|
||||
os.format("# Master shader library\n"
|
||||
"with bpy.data.libraries.load('%s', link=True, relative=True) as (data_from, data_to):\n"
|
||||
" data_to.node_groups = data_from.node_groups\n"
|
||||
"\n", dataspec.getMasterShaderPath().getAbsolutePathUTF8().c_str());
|
||||
|
||||
MaterialSet::RegisterMaterialProps(os);
|
||||
os << "# Materials\n"
|
||||
"materials = []\n"
|
||||
"\n"
|
||||
"# Overdraw-tracking\n"
|
||||
os << "# Overdraw-tracking\n"
|
||||
"od_list = []\n"
|
||||
"\n";
|
||||
|
||||
/* Pre-read pass to determine maximum used vert indices */
|
||||
bool visitedDLOffsets = false;
|
||||
std::vector<VertexAttributes> vertAttribs;
|
||||
|
||||
atUint32 lastDlSec = secCount;
|
||||
atUint64 afterHeaderPos = reader.position();
|
||||
|
||||
DLReader::DLPrimVert maxIdxs;
|
||||
for (size_t s=0 ; s<head.secCount ; ++s)
|
||||
for (size_t s=0 ; s<lastDlSec ; ++s)
|
||||
{
|
||||
atUint64 secStart = reader.position();
|
||||
if (s < head.matSetCount)
|
||||
if (s < matSetCount)
|
||||
{
|
||||
if (!s)
|
||||
{
|
||||
|
@ -449,7 +357,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (s-head.matSetCount)
|
||||
switch (s-matSetCount)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
|
@ -474,11 +382,12 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
case 4:
|
||||
{
|
||||
/* Short UVs */
|
||||
if (head.flags.shortUVs())
|
||||
if (shortUVs)
|
||||
break;
|
||||
|
||||
/* DL Offsets (here or next section) */
|
||||
visitedDLOffsets = true;
|
||||
lastDlSec = s + reader.readUint32Big() + 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -486,6 +395,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
if (!visitedDLOffsets)
|
||||
{
|
||||
visitedDLOffsets = true;
|
||||
lastDlSec = s + reader.readUint32Big() + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -494,7 +404,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
sHead.read(reader);
|
||||
|
||||
/* Do max index pre-read */
|
||||
atUint32 realDlSize = head.secSizes[s] - (reader.position() - secStart);
|
||||
atUint32 realDlSize = secSizes[s] - (reader.position() - secStart);
|
||||
DLReader dl(vertAttribs[sHead.matIdx], reader.readUBytes(realDlSize), realDlSize);
|
||||
dl.preReadMaxIdxs(maxIdxs);
|
||||
|
||||
|
@ -502,8 +412,8 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
}
|
||||
}
|
||||
|
||||
if (s < head.secCount - 1)
|
||||
reader.seek(secStart + head.secSizes[s], Athena::Begin);
|
||||
if (s < secCount - 1)
|
||||
reader.seek(secStart + secSizes[s], Athena::Begin);
|
||||
}
|
||||
|
||||
reader.seek(afterHeaderPos, Athena::Begin);
|
||||
|
@ -512,10 +422,10 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
unsigned createdUVLayers = 0;
|
||||
unsigned surfIdx = 0;
|
||||
|
||||
for (size_t s=0 ; s<head.secCount ; ++s)
|
||||
for (size_t s=0 ; s<lastDlSec ; ++s)
|
||||
{
|
||||
atUint64 secStart = reader.position();
|
||||
if (s < head.matSetCount)
|
||||
if (s < matSetCount)
|
||||
{
|
||||
MaterialSet matSet;
|
||||
matSet.read(reader);
|
||||
|
@ -525,7 +435,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (s-head.matSetCount)
|
||||
switch (s-matSetCount)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
|
@ -544,18 +454,20 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
{
|
||||
/* Normals */
|
||||
os << "norm_list = []\n";
|
||||
if (head.flags.shortNormals())
|
||||
if (shortNormals)
|
||||
{
|
||||
size_t normCount = head.secSizes[s] / 6;
|
||||
size_t normCount = secSizes[s] / 6;
|
||||
for (size_t i=0 ; i<normCount ; ++i)
|
||||
{
|
||||
os.format("norm_list.append((%f,%f,%f))\n",
|
||||
reader.readInt16Big(), reader.readInt16Big(), reader.readInt16Big());
|
||||
reader.readInt16Big() / 16834.0f,
|
||||
reader.readInt16Big() / 16834.0f,
|
||||
reader.readInt16Big() / 16834.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t normCount = head.secSizes[s] / 12;
|
||||
size_t normCount = secSizes[s] / 12;
|
||||
for (size_t i=0 ; i<normCount ; ++i)
|
||||
{
|
||||
atVec3f norm = reader.readVec3fBig();
|
||||
|
@ -574,7 +486,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
{
|
||||
/* Float UVs */
|
||||
os << "uv_list = []\n";
|
||||
size_t uvCount = head.secSizes[s] / 8;
|
||||
size_t uvCount = secSizes[s] / 8;
|
||||
for (size_t i=0 ; i<uvCount ; ++i)
|
||||
{
|
||||
atVec2f uv = reader.readVec2fBig();
|
||||
|
@ -587,13 +499,14 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
{
|
||||
/* Short UVs */
|
||||
os << "suv_list = []\n";
|
||||
if (head.flags.shortUVs())
|
||||
if (shortUVs)
|
||||
{
|
||||
size_t uvCount = head.secSizes[s] / 4;
|
||||
size_t uvCount = secSizes[s] / 4;
|
||||
for (size_t i=0 ; i<uvCount ; ++i)
|
||||
{
|
||||
os.format("suv_list.append((%f,%f))\n",
|
||||
reader.readInt16Big(), reader.readInt16Big());
|
||||
reader.readInt16Big() / 32768.0f,
|
||||
reader.readInt16Big() / 32768.0f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -613,7 +526,9 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
/* GX Display List (surface) */
|
||||
SurfaceHeader sHead;
|
||||
sHead.read(reader);
|
||||
unsigned matUVCount = vertAttribs[sHead.matIdx].uvCount;
|
||||
VertexAttributes& curVA = vertAttribs[sHead.matIdx];
|
||||
unsigned matUVCount = curVA.uvCount;
|
||||
bool matShortUVs = curVA.shortUVs;
|
||||
|
||||
os.format("materials[%u].pass_index = %u\n", sHead.matIdx, surfIdx++);
|
||||
if (matUVCount > createdUVLayers)
|
||||
|
@ -623,7 +538,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
createdUVLayers = matUVCount;
|
||||
}
|
||||
|
||||
atUint32 realDlSize = head.secSizes[s] - (reader.position() - secStart);
|
||||
atUint32 realDlSize = secSizes[s] - (reader.position() - secStart);
|
||||
DLReader dl(vertAttribs[sHead.matIdx], reader.readUBytes(realDlSize), realDlSize);
|
||||
|
||||
while (dl)
|
||||
|
@ -664,12 +579,22 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
{
|
||||
os << "if last_face is not None:\n";
|
||||
for (unsigned j=0 ; j<matUVCount ; ++j)
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n",
|
||||
primVerts[c%3].pos, j, primVerts[c%3].uvs[j],
|
||||
primVerts[(c+2)%3].pos, j, primVerts[(c+2)%3].uvs[j],
|
||||
primVerts[(c+1)%3].pos, j, primVerts[(c+1)%3].uvs[j]);
|
||||
{
|
||||
if (j==0 && matShortUVs)
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n",
|
||||
primVerts[c%3].pos, j, primVerts[c%3].uvs[j],
|
||||
primVerts[(c+2)%3].pos, j, primVerts[(c+2)%3].uvs[j],
|
||||
primVerts[(c+1)%3].pos, j, primVerts[(c+1)%3].uvs[j]);
|
||||
else
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n",
|
||||
primVerts[c%3].pos, j, primVerts[c%3].uvs[j],
|
||||
primVerts[(c+2)%3].pos, j, primVerts[(c+2)%3].uvs[j],
|
||||
primVerts[(c+1)%3].pos, j, primVerts[(c+1)%3].uvs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -686,12 +611,22 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
{
|
||||
os << "if last_face is not None:\n";
|
||||
for (unsigned j=0 ; j<matUVCount ; ++j)
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n",
|
||||
primVerts[c%3].pos, j, primVerts[c%3].uvs[j],
|
||||
primVerts[(c+1)%3].pos, j, primVerts[(c+1)%3].uvs[j],
|
||||
primVerts[(c+2)%3].pos, j, primVerts[(c+2)%3].uvs[j]);
|
||||
{
|
||||
if (j==0 && matShortUVs)
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n",
|
||||
primVerts[c%3].pos, j, primVerts[c%3].uvs[j],
|
||||
primVerts[(c+1)%3].pos, j, primVerts[(c+1)%3].uvs[j],
|
||||
primVerts[(c+2)%3].pos, j, primVerts[(c+2)%3].uvs[j]);
|
||||
else
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n",
|
||||
primVerts[c%3].pos, j, primVerts[c%3].uvs[j],
|
||||
primVerts[(c+1)%3].pos, j, primVerts[(c+1)%3].uvs[j],
|
||||
primVerts[(c+2)%3].pos, j, primVerts[(c+2)%3].uvs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
flip ^= 1;
|
||||
|
@ -721,12 +656,22 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
{
|
||||
os << "if last_face is not None:\n";
|
||||
for (unsigned j=0 ; j<matUVCount ; ++j)
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n",
|
||||
primVerts[0].pos, j, primVerts[0].uvs[j],
|
||||
primVerts[1].pos, j, primVerts[1].uvs[j],
|
||||
primVerts[2].pos, j, primVerts[2].uvs[j]);
|
||||
{
|
||||
if (j==0 && matShortUVs)
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n",
|
||||
primVerts[0].pos, j, primVerts[0].uvs[j],
|
||||
primVerts[1].pos, j, primVerts[1].uvs[j],
|
||||
primVerts[2].pos, j, primVerts[2].uvs[j]);
|
||||
else
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n",
|
||||
primVerts[0].pos, j, primVerts[0].uvs[j],
|
||||
primVerts[1].pos, j, primVerts[1].uvs[j],
|
||||
primVerts[2].pos, j, primVerts[2].uvs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Break if done */
|
||||
|
@ -757,12 +702,22 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
{
|
||||
os << "if last_face is not None:\n";
|
||||
for (unsigned j=0 ; j<matUVCount ; ++j)
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n",
|
||||
firstPrimVert.pos, j, firstPrimVert.uvs[j],
|
||||
primVerts[c%3].pos, j, primVerts[c%3].uvs[j],
|
||||
primVerts[(c+1)%3].pos, j, primVerts[(c+1)%3].uvs[j]);
|
||||
{
|
||||
if (j==0 && matShortUVs)
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = suv_list[%u]\n",
|
||||
firstPrimVert.pos, j, firstPrimVert.uvs[j],
|
||||
primVerts[c%3].pos, j, primVerts[c%3].uvs[j],
|
||||
primVerts[(c+1)%3].pos, j, primVerts[(c+1)%3].uvs[j]);
|
||||
else
|
||||
os.format(" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n"
|
||||
" loop_from_facevert(last_face, %u)[last_mesh.loops.layers.uv[%u]].uv = uv_list[%u]\n",
|
||||
firstPrimVert.pos, j, firstPrimVert.uvs[j],
|
||||
primVerts[c%3].pos, j, primVerts[c%3].uvs[j],
|
||||
primVerts[(c+1)%3].pos, j, primVerts[(c+1)%3].uvs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
bool peek = (v >= vertCount - 3);
|
||||
|
@ -778,63 +733,64 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
}
|
||||
}
|
||||
|
||||
if (s < head.secCount - 1)
|
||||
reader.seek(secStart + head.secSizes[s], Athena::Begin);
|
||||
if (s < secCount - 1)
|
||||
reader.seek(secStart + secSizes[s], Athena::Begin);
|
||||
}
|
||||
|
||||
/* Finish Mesh */
|
||||
os.format("mesh = bpy.data.meshes.new(bpy.context.scene.name)\n"
|
||||
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
||||
"obj.show_transparent = True\n"
|
||||
"bpy.context.scene.objects.link(obj)\n"
|
||||
"mesh.hecl_material_count = %u\n"
|
||||
"for material in materials:\n"
|
||||
" mesh.materials.append(material)\n"
|
||||
"\n"
|
||||
"# Preserve original indices\n"
|
||||
"for vert in bm.verts:\n"
|
||||
" ov = mesh.cmdl_orig_verts.add()\n"
|
||||
" ov.index = vert.index\n"
|
||||
"\n"
|
||||
"# Merge OD meshes\n"
|
||||
"for od_entry in od_list:\n"
|
||||
" vert_dict = {}\n"
|
||||
"\n"
|
||||
" for vert in od_entry['bm'].verts:\n"
|
||||
" if len(vert.link_faces):\n"
|
||||
" vert_dict[vert.index] = bm.verts.new(vert.co, vert)\n"
|
||||
" ov = mesh.cmdl_orig_verts.add()\n"
|
||||
" ov.index = vert.index\n"
|
||||
"\n"
|
||||
" for face in od_entry['bm'].faces:\n"
|
||||
" merge_verts = [vert_dict[fv.index] for fv in face.verts]\n"
|
||||
" if bm.faces.get(merge_verts) is not None:\n"
|
||||
" continue\n"
|
||||
" merge_face = bm.faces.new(merge_verts)\n"
|
||||
" for i in range(len(face.loops)):\n"
|
||||
" old = face.loops[i]\n"
|
||||
" new = merge_face.loops[i]\n"
|
||||
" for j in range(len(od_entry['bm'].loops.layers.uv)):\n"
|
||||
" new[bm.loops.layers.uv[j]] = old[od_entry['bm'].loops.layers.uv[j]]\n"
|
||||
" merge_face.smooth = True\n"
|
||||
" merge_face.material_index = face.material_index\n"
|
||||
"\n"
|
||||
" od_entry['bm'].free()\n"
|
||||
"\n"
|
||||
"# Remove loose vertices\n"
|
||||
"#to_remove = []\n"
|
||||
"#for vert in bm.verts:\n"
|
||||
"# if not len(vert.link_faces):\n"
|
||||
"# to_remove.append(vert)\n"
|
||||
"#bmesh.ops.delete(bm, geom=to_remove, context=1)\n"
|
||||
"\n"
|
||||
"bm.to_mesh(mesh)\n"
|
||||
"bm.free()\n"
|
||||
"\n", head.matSetCount);
|
||||
FinishBlenderMesh(os, matSetCount, meshIdx);
|
||||
|
||||
if (rp.first)
|
||||
rp.second->sendVertexGroupsToBlender(os);
|
||||
|
||||
return lastDlSec;
|
||||
}
|
||||
|
||||
template <class PAKRouter, class MaterialSet, class RIGPAIR, atUint32 Version>
|
||||
bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
||||
Athena::io::IStreamReader& reader,
|
||||
PAKRouter& pakRouter,
|
||||
const typename PAKRouter::EntryType& entry,
|
||||
const SpecBase& dataspec,
|
||||
const RIGPAIR& rp)
|
||||
{
|
||||
Header head;
|
||||
head.read(reader);
|
||||
|
||||
if (head.magic != 0xDEADBABE)
|
||||
{
|
||||
LogDNACommon.report(LogVisor::Error, "invalid CMDL magic");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (head.version != Version)
|
||||
{
|
||||
LogDNACommon.report(LogVisor::Error, "invalid CMDL version");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Open Py Stream and read sections */
|
||||
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut(true);
|
||||
os.format("import bpy\n"
|
||||
"import bmesh\n"
|
||||
"\n"
|
||||
"bpy.context.scene.name = '%s'\n"
|
||||
"bpy.context.scene.hecl_type = 'MESH'\n"
|
||||
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n",
|
||||
pakRouter.getBestEntryName(entry).c_str());
|
||||
InitGeomBlenderContext(os, dataspec.getMasterShaderPath());
|
||||
MaterialSet::RegisterMaterialProps(os);
|
||||
|
||||
os << "# Materials\n"
|
||||
"materials = []\n"
|
||||
"\n";
|
||||
|
||||
std::vector<VertexAttributes> vertAttribs;
|
||||
ReadGeomSectionsToBlender<PAKRouter, MaterialSet, RIGPAIR>
|
||||
(os, reader, pakRouter, entry, dataspec, rp, head.flags.shortNormals(),
|
||||
head.flags.shortUVs(), vertAttribs, -1,
|
||||
head.secCount, head.matSetCount, head.secSizes.data());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ add_library(DNACommon
|
|||
${liblist}
|
||||
PAK.hpp
|
||||
GX.hpp
|
||||
CMDL.cpp
|
||||
STRG.hpp STRG.cpp
|
||||
TXTR.hpp TXTR.cpp
|
||||
ANCS.hpp
|
||||
|
|
|
@ -31,29 +31,30 @@ struct MaterialSet : BigDNA
|
|||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> flags;
|
||||
inline bool konstValuesEnabled() const {return (flags & 0x8) != 0;}
|
||||
inline void setKonstValuesEnabled(bool enabled) {flags &= ~0x8; flags |= atUint32(enabled) << 3;}
|
||||
inline bool depthSorting() const {return (flags & 0x10) != 0;}
|
||||
inline void setDepthSorting(bool enabled) {flags &= ~0x10; flags |= atUint32(enabled) << 4;}
|
||||
inline bool punchthroughAlpha() const {return (flags & 0x20) != 0;}
|
||||
inline void setPunchthroughAlpha(bool enabled) {flags &= ~0x20; flags |= atUint32(enabled) << 5;}
|
||||
inline bool samusReflection() const {return (flags & 0x40) != 0;}
|
||||
inline void setSamusReflection(bool enabled) {flags &= ~0x40; flags |= atUint32(enabled) << 6;}
|
||||
inline bool depthWrite() const {return (flags & 0x80) != 0;}
|
||||
inline void setDepthWrite(bool enabled) {flags &= ~0x80; flags |= atUint32(enabled) << 7;}
|
||||
inline bool samusReflectionSurfaceEye() const {return (flags & 0x100) != 0;}
|
||||
inline void setSamusReflectionSurfaceEye(bool enabled) {flags &= ~0x100; flags |= atUint32(enabled) << 8;}
|
||||
inline bool shadowOccluderMesh() const {return (flags & 0x200) != 0;}
|
||||
inline void setShadowOccluderMesh(bool enabled) {flags &= ~0x200; flags |= atUint32(enabled) << 9;}
|
||||
inline bool samusReflectionIndirectTexture() const {return (flags & 0x400) != 0;}
|
||||
inline void setSamusReflectionIndirectTexture(bool enabled) {flags &= ~0x400; flags |= atUint32(enabled) << 10;}
|
||||
inline bool lightmap() const {return (flags & 0x800) != 0;}
|
||||
inline void setLightmap(bool enabled) {flags &= ~0x800; flags |= atUint32(enabled) << 11;}
|
||||
inline bool lightmapUVArray() const {return (flags & 0x2000) != 0;}
|
||||
inline void setLightmapUVArray(bool enabled) {flags &= ~0x2000; flags |= atUint32(enabled) << 13;}
|
||||
inline atUint16 textureSlots() const {return (flags >> 16) != 0;}
|
||||
inline void setTextureSlots(atUint16 texslots) {flags &= ~0xffff0000; flags |= atUint32(texslots) << 16;}
|
||||
bool konstValuesEnabled() const {return (flags & 0x8) != 0;}
|
||||
void setKonstValuesEnabled(bool enabled) {flags &= ~0x8; flags |= atUint32(enabled) << 3;}
|
||||
bool depthSorting() const {return (flags & 0x10) != 0;}
|
||||
void setDepthSorting(bool enabled) {flags &= ~0x10; flags |= atUint32(enabled) << 4;}
|
||||
bool punchthroughAlpha() const {return (flags & 0x20) != 0;}
|
||||
void setPunchthroughAlpha(bool enabled) {flags &= ~0x20; flags |= atUint32(enabled) << 5;}
|
||||
bool samusReflection() const {return (flags & 0x40) != 0;}
|
||||
void setSamusReflection(bool enabled) {flags &= ~0x40; flags |= atUint32(enabled) << 6;}
|
||||
bool depthWrite() const {return (flags & 0x80) != 0;}
|
||||
void setDepthWrite(bool enabled) {flags &= ~0x80; flags |= atUint32(enabled) << 7;}
|
||||
bool samusReflectionSurfaceEye() const {return (flags & 0x100) != 0;}
|
||||
void setSamusReflectionSurfaceEye(bool enabled) {flags &= ~0x100; flags |= atUint32(enabled) << 8;}
|
||||
bool shadowOccluderMesh() const {return (flags & 0x200) != 0;}
|
||||
void setShadowOccluderMesh(bool enabled) {flags &= ~0x200; flags |= atUint32(enabled) << 9;}
|
||||
bool samusReflectionIndirectTexture() const {return (flags & 0x400) != 0;}
|
||||
void setSamusReflectionIndirectTexture(bool enabled) {flags &= ~0x400; flags |= atUint32(enabled) << 10;}
|
||||
bool lightmap() const {return (flags & 0x800) != 0;}
|
||||
void setLightmap(bool enabled) {flags &= ~0x800; flags |= atUint32(enabled) << 11;}
|
||||
bool lightmapUVArray() const {return (flags & 0x2000) != 0;}
|
||||
void setLightmapUVArray(bool enabled) {flags &= ~0x2000; flags |= atUint32(enabled) << 13;}
|
||||
atUint16 textureSlots() const {return (flags >> 16) != 0;}
|
||||
void setTextureSlots(atUint16 texslots) {flags &= ~0xffff0000; flags |= atUint32(texslots) << 16;}
|
||||
} flags;
|
||||
const Flags& getFlags() const {return flags;}
|
||||
|
||||
Value<atUint32> textureCount;
|
||||
Vector<atUint32, DNA_COUNT(textureCount)> texureIdxs;
|
||||
|
@ -61,46 +62,46 @@ struct MaterialSet : BigDNA
|
|||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> vaFlags;
|
||||
inline GX::AttrType position() const {return GX::AttrType(vaFlags & 0x3);}
|
||||
inline void setPosition(GX::AttrType val) {vaFlags &= ~0x3; vaFlags |= atUint32(val);}
|
||||
inline GX::AttrType normal() const {return GX::AttrType(vaFlags >> 2 & 0x3);}
|
||||
inline void setNormal(GX::AttrType val) {vaFlags &= ~0xC; vaFlags |= atUint32(val) << 2;}
|
||||
inline GX::AttrType color0() const {return GX::AttrType(vaFlags >> 4 & 0x3);}
|
||||
inline void setColor0(GX::AttrType val) {vaFlags &= ~0x30; vaFlags |= atUint32(val) << 4;}
|
||||
inline GX::AttrType color1() const {return GX::AttrType(vaFlags >> 6 & 0x3);}
|
||||
inline void setColor1(GX::AttrType val) {vaFlags &= ~0xC0; vaFlags |= atUint32(val) << 6;}
|
||||
inline GX::AttrType tex0() const {return GX::AttrType(vaFlags >> 8 & 0x3);}
|
||||
inline void setTex0(GX::AttrType val) {vaFlags &= ~0x300; vaFlags |= atUint32(val) << 8;}
|
||||
inline GX::AttrType tex1() const {return GX::AttrType(vaFlags >> 10 & 0x3);}
|
||||
inline void setTex1(GX::AttrType val) {vaFlags &= ~0xC00; vaFlags |= atUint32(val) << 10;}
|
||||
inline GX::AttrType tex2() const {return GX::AttrType(vaFlags >> 12 & 0x3);}
|
||||
inline void setTex2(GX::AttrType val) {vaFlags &= ~0x3000; vaFlags |= atUint32(val) << 12;}
|
||||
inline GX::AttrType tex3() const {return GX::AttrType(vaFlags >> 14 & 0x3);}
|
||||
inline void setTex3(GX::AttrType val) {vaFlags &= ~0xC000; vaFlags |= atUint32(val) << 14;}
|
||||
inline GX::AttrType tex4() const {return GX::AttrType(vaFlags >> 16 & 0x3);}
|
||||
inline void setTex4(GX::AttrType val) {vaFlags &= ~0x30000; vaFlags |= atUint32(val) << 16;}
|
||||
inline GX::AttrType tex5() const {return GX::AttrType(vaFlags >> 18 & 0x3);}
|
||||
inline void setTex5(GX::AttrType val) {vaFlags &= ~0xC0000; vaFlags |= atUint32(val) << 18;}
|
||||
inline GX::AttrType tex6() const {return GX::AttrType(vaFlags >> 20 & 0x3);}
|
||||
inline void setTex6(GX::AttrType val) {vaFlags &= ~0x300000; vaFlags |= atUint32(val) << 20;}
|
||||
inline GX::AttrType pnMatIdx() const {return GX::AttrType(vaFlags >> 24 & 0x1);}
|
||||
inline void setPnMatIdx(GX::AttrType val) {vaFlags &= ~0x1000000; vaFlags |= atUint32(val & 0x1) << 24;}
|
||||
inline GX::AttrType tex0MatIdx() const {return GX::AttrType(vaFlags >> 25 & 0x1);}
|
||||
inline void setTex0MatIdx(GX::AttrType val) {vaFlags &= ~0x2000000; vaFlags |= atUint32(val & 0x1) << 25;}
|
||||
inline GX::AttrType tex1MatIdx() const {return GX::AttrType(vaFlags >> 26 & 0x1);}
|
||||
inline void setTex1MatIdx(GX::AttrType val) {vaFlags &= ~0x4000000; vaFlags |= atUint32(val & 0x1) << 26;}
|
||||
inline GX::AttrType tex2MatIdx() const {return GX::AttrType(vaFlags >> 27 & 0x1);}
|
||||
inline void setTex2MatIdx(GX::AttrType val) {vaFlags &= ~0x8000000; vaFlags |= atUint32(val & 0x1) << 27;}
|
||||
inline GX::AttrType tex3MatIdx() const {return GX::AttrType(vaFlags >> 28 & 0x1);}
|
||||
inline void setTex3MatIdx(GX::AttrType val) {vaFlags &= ~0x10000000; vaFlags |= atUint32(val & 0x1) << 28;}
|
||||
inline GX::AttrType tex4MatIdx() const {return GX::AttrType(vaFlags >> 29 & 0x1);}
|
||||
inline void setTex4MatIdx(GX::AttrType val) {vaFlags &= ~0x20000000; vaFlags |= atUint32(val & 0x1) << 29;}
|
||||
inline GX::AttrType tex5MatIdx() const {return GX::AttrType(vaFlags >> 30 & 0x1);}
|
||||
inline void setTex5MatIdx(GX::AttrType val) {vaFlags &= ~0x40000000; vaFlags |= atUint32(val & 0x1) << 30;}
|
||||
inline GX::AttrType tex6MatIdx() const {return GX::AttrType(vaFlags >> 31 & 0x1);}
|
||||
inline void setTex6MatIdx(GX::AttrType val) {vaFlags &= ~0x80000000; vaFlags |= atUint32(val & 0x1) << 31;}
|
||||
GX::AttrType position() const {return GX::AttrType(vaFlags & 0x3);}
|
||||
void setPosition(GX::AttrType val) {vaFlags &= ~0x3; vaFlags |= atUint32(val);}
|
||||
GX::AttrType normal() const {return GX::AttrType(vaFlags >> 2 & 0x3);}
|
||||
void setNormal(GX::AttrType val) {vaFlags &= ~0xC; vaFlags |= atUint32(val) << 2;}
|
||||
GX::AttrType color0() const {return GX::AttrType(vaFlags >> 4 & 0x3);}
|
||||
void setColor0(GX::AttrType val) {vaFlags &= ~0x30; vaFlags |= atUint32(val) << 4;}
|
||||
GX::AttrType color1() const {return GX::AttrType(vaFlags >> 6 & 0x3);}
|
||||
void setColor1(GX::AttrType val) {vaFlags &= ~0xC0; vaFlags |= atUint32(val) << 6;}
|
||||
GX::AttrType tex0() const {return GX::AttrType(vaFlags >> 8 & 0x3);}
|
||||
void setTex0(GX::AttrType val) {vaFlags &= ~0x300; vaFlags |= atUint32(val) << 8;}
|
||||
GX::AttrType tex1() const {return GX::AttrType(vaFlags >> 10 & 0x3);}
|
||||
void setTex1(GX::AttrType val) {vaFlags &= ~0xC00; vaFlags |= atUint32(val) << 10;}
|
||||
GX::AttrType tex2() const {return GX::AttrType(vaFlags >> 12 & 0x3);}
|
||||
void setTex2(GX::AttrType val) {vaFlags &= ~0x3000; vaFlags |= atUint32(val) << 12;}
|
||||
GX::AttrType tex3() const {return GX::AttrType(vaFlags >> 14 & 0x3);}
|
||||
void setTex3(GX::AttrType val) {vaFlags &= ~0xC000; vaFlags |= atUint32(val) << 14;}
|
||||
GX::AttrType tex4() const {return GX::AttrType(vaFlags >> 16 & 0x3);}
|
||||
void setTex4(GX::AttrType val) {vaFlags &= ~0x30000; vaFlags |= atUint32(val) << 16;}
|
||||
GX::AttrType tex5() const {return GX::AttrType(vaFlags >> 18 & 0x3);}
|
||||
void setTex5(GX::AttrType val) {vaFlags &= ~0xC0000; vaFlags |= atUint32(val) << 18;}
|
||||
GX::AttrType tex6() const {return GX::AttrType(vaFlags >> 20 & 0x3);}
|
||||
void setTex6(GX::AttrType val) {vaFlags &= ~0x300000; vaFlags |= atUint32(val) << 20;}
|
||||
GX::AttrType pnMatIdx() const {return GX::AttrType(vaFlags >> 24 & 0x1);}
|
||||
void setPnMatIdx(GX::AttrType val) {vaFlags &= ~0x1000000; vaFlags |= atUint32(val & 0x1) << 24;}
|
||||
GX::AttrType tex0MatIdx() const {return GX::AttrType(vaFlags >> 25 & 0x1);}
|
||||
void setTex0MatIdx(GX::AttrType val) {vaFlags &= ~0x2000000; vaFlags |= atUint32(val & 0x1) << 25;}
|
||||
GX::AttrType tex1MatIdx() const {return GX::AttrType(vaFlags >> 26 & 0x1);}
|
||||
void setTex1MatIdx(GX::AttrType val) {vaFlags &= ~0x4000000; vaFlags |= atUint32(val & 0x1) << 26;}
|
||||
GX::AttrType tex2MatIdx() const {return GX::AttrType(vaFlags >> 27 & 0x1);}
|
||||
void setTex2MatIdx(GX::AttrType val) {vaFlags &= ~0x8000000; vaFlags |= atUint32(val & 0x1) << 27;}
|
||||
GX::AttrType tex3MatIdx() const {return GX::AttrType(vaFlags >> 28 & 0x1);}
|
||||
void setTex3MatIdx(GX::AttrType val) {vaFlags &= ~0x10000000; vaFlags |= atUint32(val & 0x1) << 28;}
|
||||
GX::AttrType tex4MatIdx() const {return GX::AttrType(vaFlags >> 29 & 0x1);}
|
||||
void setTex4MatIdx(GX::AttrType val) {vaFlags &= ~0x20000000; vaFlags |= atUint32(val & 0x1) << 29;}
|
||||
GX::AttrType tex5MatIdx() const {return GX::AttrType(vaFlags >> 30 & 0x1);}
|
||||
void setTex5MatIdx(GX::AttrType val) {vaFlags &= ~0x40000000; vaFlags |= atUint32(val & 0x1) << 30;}
|
||||
GX::AttrType tex6MatIdx() const {return GX::AttrType(vaFlags >> 31 & 0x1);}
|
||||
void setTex6MatIdx(GX::AttrType val) {vaFlags &= ~0x80000000; vaFlags |= atUint32(val & 0x1) << 31;}
|
||||
} vaFlags;
|
||||
inline const VAFlags& getVAFlags() const {return vaFlags;}
|
||||
const VAFlags& getVAFlags() const {return vaFlags;}
|
||||
Value<atUint32> groupIdx;
|
||||
|
||||
Vector<atUint32, DNA_COUNT(flags.konstValuesEnabled())> konstCount;
|
||||
|
@ -127,18 +128,18 @@ struct MaterialSet : BigDNA
|
|||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> flags;
|
||||
inline bool lighting() const {return (flags & 0x1) != 0;}
|
||||
inline void setLighting(bool enabled) {flags &= ~0x1; flags |= atUint32(enabled);}
|
||||
inline bool useAmbient() const {return (flags & 0x2) != 0;}
|
||||
inline void setUseAmbient(bool enabled) {flags &= ~0x2; flags |= atUint32(enabled) << 1;}
|
||||
inline bool useMaterial() const {return (flags & 0x4) != 0;}
|
||||
inline void setUseMaterial(bool enabled) {flags &= ~0x4; flags |= atUint32(enabled) << 2;}
|
||||
inline atUint8 lightmask() const {return atUint8(flags >> 3 & 0xff);}
|
||||
inline void setLightmask(atUint8 mask) {flags &= ~0x7f8; flags |= atUint32(mask) << 3;}
|
||||
inline atUint8 diffuseFn() const {return atUint8(flags >> 11 & 0x3);}
|
||||
inline void setDiffuseFn(atUint8 fn) {flags &= ~0x1800; flags |= atUint32(fn) << 11;}
|
||||
inline atUint8 attenuationFn() const {return atUint8(flags >> 13 & 0x3);}
|
||||
inline void setAttenuationFn(atUint8 fn) {flags &= ~0x6000; flags |= atUint32(fn) << 13;}
|
||||
bool lighting() const {return (flags & 0x1) != 0;}
|
||||
void setLighting(bool enabled) {flags &= ~0x1; flags |= atUint32(enabled);}
|
||||
bool useAmbient() const {return (flags & 0x2) != 0;}
|
||||
void setUseAmbient(bool enabled) {flags &= ~0x2; flags |= atUint32(enabled) << 1;}
|
||||
bool useMaterial() const {return (flags & 0x4) != 0;}
|
||||
void setUseMaterial(bool enabled) {flags &= ~0x4; flags |= atUint32(enabled) << 2;}
|
||||
atUint8 lightmask() const {return atUint8(flags >> 3 & 0xff);}
|
||||
void setLightmask(atUint8 mask) {flags &= ~0x7f8; flags |= atUint32(mask) << 3;}
|
||||
atUint8 diffuseFn() const {return atUint8(flags >> 11 & 0x3);}
|
||||
void setDiffuseFn(atUint8 fn) {flags &= ~0x1800; flags |= atUint32(fn) << 11;}
|
||||
atUint8 attenuationFn() const {return atUint8(flags >> 13 & 0x3);}
|
||||
void setAttenuationFn(atUint8 fn) {flags &= ~0x6000; flags |= atUint32(fn) << 13;}
|
||||
};
|
||||
Vector<ColorChannel, DNA_COUNT(colorChannelCount)> colorChannels;
|
||||
|
||||
|
@ -155,48 +156,48 @@ struct MaterialSet : BigDNA
|
|||
Value<atUint8> kcInput;
|
||||
Value<atUint8> rascInput;
|
||||
|
||||
inline GX::TevColorArg colorInA() const {return GX::TevColorArg(ciFlags & 0xf);}
|
||||
inline void setColorInA(GX::TevColorArg val) {ciFlags &= ~0x1f; ciFlags |= atUint32(val);}
|
||||
inline GX::TevColorArg colorInB() const {return GX::TevColorArg(ciFlags >> 5 & 0xf);}
|
||||
inline void setColorInB(GX::TevColorArg val) {ciFlags &= ~0x3e0; ciFlags |= atUint32(val) << 5;}
|
||||
inline GX::TevColorArg colorInC() const {return GX::TevColorArg(ciFlags >> 10 & 0xf);}
|
||||
inline void setColorInC(GX::TevColorArg val) {ciFlags &= ~0x7c00; ciFlags |= atUint32(val) << 10;}
|
||||
inline GX::TevColorArg colorInD() const {return GX::TevColorArg(ciFlags >> 15 & 0xf);}
|
||||
inline void setColorInD(GX::TevColorArg val) {ciFlags &= ~0xf8000; ciFlags |= atUint32(val) << 15;}
|
||||
GX::TevColorArg colorInA() const {return GX::TevColorArg(ciFlags & 0xf);}
|
||||
void setColorInA(GX::TevColorArg val) {ciFlags &= ~0x1f; ciFlags |= atUint32(val);}
|
||||
GX::TevColorArg colorInB() const {return GX::TevColorArg(ciFlags >> 5 & 0xf);}
|
||||
void setColorInB(GX::TevColorArg val) {ciFlags &= ~0x3e0; ciFlags |= atUint32(val) << 5;}
|
||||
GX::TevColorArg colorInC() const {return GX::TevColorArg(ciFlags >> 10 & 0xf);}
|
||||
void setColorInC(GX::TevColorArg val) {ciFlags &= ~0x7c00; ciFlags |= atUint32(val) << 10;}
|
||||
GX::TevColorArg colorInD() const {return GX::TevColorArg(ciFlags >> 15 & 0xf);}
|
||||
void setColorInD(GX::TevColorArg val) {ciFlags &= ~0xf8000; ciFlags |= atUint32(val) << 15;}
|
||||
|
||||
inline GX::TevAlphaArg alphaInA() const {return GX::TevAlphaArg(aiFlags & 0x7);}
|
||||
inline void setAlphaInA(GX::TevAlphaArg val) {aiFlags &= ~0x1f; aiFlags |= atUint32(val);}
|
||||
inline GX::TevAlphaArg alphaInB() const {return GX::TevAlphaArg(aiFlags >> 5 & 0x7);}
|
||||
inline void setAlphaInB(GX::TevAlphaArg val) {aiFlags &= ~0x3e0; aiFlags |= atUint32(val) << 5;}
|
||||
inline GX::TevAlphaArg alphaInC() const {return GX::TevAlphaArg(aiFlags >> 10 & 0x7);}
|
||||
inline void setAlphaInC(GX::TevAlphaArg val) {aiFlags &= ~0x7c00; aiFlags |= atUint32(val) << 10;}
|
||||
inline GX::TevAlphaArg alphaInD() const {return GX::TevAlphaArg(aiFlags >> 15 & 0x7);}
|
||||
inline void setAlphaInD(GX::TevAlphaArg val) {aiFlags &= ~0xf8000; aiFlags |= atUint32(val) << 15;}
|
||||
GX::TevAlphaArg alphaInA() const {return GX::TevAlphaArg(aiFlags & 0x7);}
|
||||
void setAlphaInA(GX::TevAlphaArg val) {aiFlags &= ~0x1f; aiFlags |= atUint32(val);}
|
||||
GX::TevAlphaArg alphaInB() const {return GX::TevAlphaArg(aiFlags >> 5 & 0x7);}
|
||||
void setAlphaInB(GX::TevAlphaArg val) {aiFlags &= ~0x3e0; aiFlags |= atUint32(val) << 5;}
|
||||
GX::TevAlphaArg alphaInC() const {return GX::TevAlphaArg(aiFlags >> 10 & 0x7);}
|
||||
void setAlphaInC(GX::TevAlphaArg val) {aiFlags &= ~0x7c00; aiFlags |= atUint32(val) << 10;}
|
||||
GX::TevAlphaArg alphaInD() const {return GX::TevAlphaArg(aiFlags >> 15 & 0x7);}
|
||||
void setAlphaInD(GX::TevAlphaArg val) {aiFlags &= ~0xf8000; aiFlags |= atUint32(val) << 15;}
|
||||
|
||||
inline GX::TevOp colorOp() const {return GX::TevOp(ccFlags & 0xf);}
|
||||
inline void setColorOp(GX::TevOp val) {ccFlags &= ~0x1; ccFlags |= atUint32(val);}
|
||||
inline GX::TevBias colorOpBias() const {return GX::TevBias(ccFlags >> 4 & 0x3);}
|
||||
inline void setColorOpBias(GX::TevBias val) {ccFlags &= ~0x30; ccFlags |= atUint32(val) << 4;}
|
||||
inline GX::TevScale colorOpScale() const {return GX::TevScale(ccFlags >> 6 & 0x3);}
|
||||
inline void setColorOpScale(GX::TevScale val) {ccFlags &= ~0xc0; ccFlags |= atUint32(val) << 6;}
|
||||
inline bool colorOpClamp() const {return ccFlags >> 8 & 0x1;}
|
||||
inline void setColorOpClamp(bool val) {ccFlags &= ~0x100; ccFlags |= atUint32(val) << 8;}
|
||||
inline GX::TevRegID colorOpOutReg() const {return GX::TevRegID(ccFlags >> 9 & 0x3);}
|
||||
inline void setColorOpOutReg(GX::TevRegID val) {ccFlags &= ~0x600; ccFlags |= atUint32(val) << 9;}
|
||||
GX::TevOp colorOp() const {return GX::TevOp(ccFlags & 0xf);}
|
||||
void setColorOp(GX::TevOp val) {ccFlags &= ~0x1; ccFlags |= atUint32(val);}
|
||||
GX::TevBias colorOpBias() const {return GX::TevBias(ccFlags >> 4 & 0x3);}
|
||||
void setColorOpBias(GX::TevBias val) {ccFlags &= ~0x30; ccFlags |= atUint32(val) << 4;}
|
||||
GX::TevScale colorOpScale() const {return GX::TevScale(ccFlags >> 6 & 0x3);}
|
||||
void setColorOpScale(GX::TevScale val) {ccFlags &= ~0xc0; ccFlags |= atUint32(val) << 6;}
|
||||
bool colorOpClamp() const {return ccFlags >> 8 & 0x1;}
|
||||
void setColorOpClamp(bool val) {ccFlags &= ~0x100; ccFlags |= atUint32(val) << 8;}
|
||||
GX::TevRegID colorOpOutReg() const {return GX::TevRegID(ccFlags >> 9 & 0x3);}
|
||||
void setColorOpOutReg(GX::TevRegID val) {ccFlags &= ~0x600; ccFlags |= atUint32(val) << 9;}
|
||||
|
||||
inline GX::TevOp alphaOp() const {return GX::TevOp(acFlags & 0xf);}
|
||||
inline void setAlphaOp(GX::TevOp val) {acFlags &= ~0x1; acFlags |= atUint32(val);}
|
||||
inline GX::TevBias alphaOpBias() const {return GX::TevBias(acFlags >> 4 & 0x3);}
|
||||
inline void setAlphaOpBias(GX::TevBias val) {acFlags &= ~0x30; acFlags |= atUint32(val) << 4;}
|
||||
inline GX::TevScale alphaOpScale() const {return GX::TevScale(acFlags >> 6 & 0x3);}
|
||||
inline void setAlphaOpScale(GX::TevScale val) {acFlags &= ~0xc0; acFlags |= atUint32(val) << 6;}
|
||||
inline bool alphaOpClamp() const {return acFlags >> 8 & 0x1;}
|
||||
inline void setAlphaOpClamp(bool val) {acFlags &= ~0x100; acFlags |= atUint32(val) << 8;}
|
||||
inline GX::TevRegID alphaOpOutReg() const {return GX::TevRegID(acFlags >> 9 & 0x3);}
|
||||
inline void setAlphaOpOutReg(GX::TevRegID val) {acFlags &= ~0x600; acFlags |= atUint32(val) << 9;}
|
||||
GX::TevOp alphaOp() const {return GX::TevOp(acFlags & 0xf);}
|
||||
void setAlphaOp(GX::TevOp val) {acFlags &= ~0x1; acFlags |= atUint32(val);}
|
||||
GX::TevBias alphaOpBias() const {return GX::TevBias(acFlags >> 4 & 0x3);}
|
||||
void setAlphaOpBias(GX::TevBias val) {acFlags &= ~0x30; acFlags |= atUint32(val) << 4;}
|
||||
GX::TevScale alphaOpScale() const {return GX::TevScale(acFlags >> 6 & 0x3);}
|
||||
void setAlphaOpScale(GX::TevScale val) {acFlags &= ~0xc0; acFlags |= atUint32(val) << 6;}
|
||||
bool alphaOpClamp() const {return acFlags >> 8 & 0x1;}
|
||||
void setAlphaOpClamp(bool val) {acFlags &= ~0x100; acFlags |= atUint32(val) << 8;}
|
||||
GX::TevRegID alphaOpOutReg() const {return GX::TevRegID(acFlags >> 9 & 0x3);}
|
||||
void setAlphaOpOutReg(GX::TevRegID val) {acFlags &= ~0x600; acFlags |= atUint32(val) << 9;}
|
||||
|
||||
inline GX::TevKColorSel kColorIn() const {return GX::TevKColorSel(kcInput);}
|
||||
inline GX::TevKAlphaSel kAlphaIn() const {return GX::TevKAlphaSel(kaInput);}
|
||||
GX::TevKColorSel kColorIn() const {return GX::TevKColorSel(kcInput);}
|
||||
GX::TevKAlphaSel kAlphaIn() const {return GX::TevKAlphaSel(kaInput);}
|
||||
};
|
||||
Vector<TEVStage, DNA_COUNT(tevStageCount)> tevStages;
|
||||
struct TEVStageTexInfo : BigDNA
|
||||
|
@ -214,16 +215,16 @@ struct MaterialSet : BigDNA
|
|||
DECL_DNA
|
||||
Value<atUint32> flags;
|
||||
|
||||
inline GX::TexGenType type() const {return GX::TexGenType(flags & 0xf);}
|
||||
inline void setType(GX::TexGenType val) {flags &= ~0xf; flags |= atUint32(val);}
|
||||
inline GX::TexGenSrc source() const {return GX::TexGenSrc(flags >> 4 & 0x1f);}
|
||||
inline void setSource(GX::TexGenSrc val) {flags &= ~0x1f0; flags |= atUint32(val) << 4;}
|
||||
inline GX::TexMtx mtx() const {return GX::TexMtx(flags >> 9 & 0x1f + 30);}
|
||||
inline void setMtx(GX::TexMtx val) {flags &= ~0x3e00; flags |= (atUint32(val)-30) << 9;}
|
||||
inline bool normalize() const {return flags >> 14 & 0x1;}
|
||||
inline void setNormalize(bool val) {flags &= ~0x4000; flags |= atUint32(val) << 14;}
|
||||
inline GX::PTTexMtx postMtx() const {return GX::PTTexMtx(flags >> 15 & 0x3f + 64);}
|
||||
inline void setPostMtx(GX::PTTexMtx val) {flags &= ~0x1f8000; flags |= (atUint32(val)-64) << 15;}
|
||||
GX::TexGenType type() const {return GX::TexGenType(flags & 0xf);}
|
||||
void setType(GX::TexGenType val) {flags &= ~0xf; flags |= atUint32(val);}
|
||||
GX::TexGenSrc source() const {return GX::TexGenSrc(flags >> 4 & 0x1f);}
|
||||
void setSource(GX::TexGenSrc val) {flags &= ~0x1f0; flags |= atUint32(val) << 4;}
|
||||
GX::TexMtx mtx() const {return GX::TexMtx(flags >> 9 & 0x1f + 30);}
|
||||
void setMtx(GX::TexMtx val) {flags &= ~0x3e00; flags |= (atUint32(val)-30) << 9;}
|
||||
bool normalize() const {return flags >> 14 & 0x1;}
|
||||
void setNormalize(bool val) {flags &= ~0x4000; flags |= atUint32(val) << 14;}
|
||||
GX::PTTexMtx postMtx() const {return GX::PTTexMtx(flags >> 15 & 0x3f + 64);}
|
||||
void setPostMtx(GX::PTTexMtx val) {flags &= ~0x1f8000; flags |= (atUint32(val)-64) << 15;}
|
||||
};
|
||||
Vector<TexCoordGen, DNA_COUNT(tcgCount)> tcgs;
|
||||
|
||||
|
@ -302,11 +303,11 @@ struct MaterialSet : BigDNA
|
|||
const MaterialSet::Material& material,
|
||||
unsigned groupIdx, unsigned matIdx);
|
||||
|
||||
inline void readToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAKRouter<PAKBridge>::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
void readToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAKRouter<PAKBridge>::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
{
|
||||
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx, dataspec);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "../DNACommon/TXTR.hpp"
|
||||
#include "CMDL.hpp"
|
||||
#include "ANCS.hpp"
|
||||
#include "MREA.hpp"
|
||||
|
||||
namespace Retro
|
||||
{
|
||||
|
@ -217,6 +218,8 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
|||
return {nullptr, CMDL::Extract, {_S(".blend")}, 1};
|
||||
case SBIG('ANCS'):
|
||||
return {nullptr, ANCS::Extract, {_S(".yaml"), _S(".blend")}, 2};
|
||||
case SBIG('MREA'):
|
||||
return {nullptr, MREA::Extract, {_S(".yaml"), _S(".blend")}, 3};
|
||||
case SBIG('MLVL'):
|
||||
return {MLVL::Extract, nullptr, {_S(".yaml")}};
|
||||
}
|
||||
|
|
|
@ -2,17 +2,164 @@
|
|||
#define __DNAMP1_MREA_HPP__
|
||||
|
||||
#include "../DNACommon/DNACommon.hpp"
|
||||
#include "CMDLMaterials.hpp"
|
||||
#include "CSKR.hpp"
|
||||
|
||||
namespace Retro
|
||||
{
|
||||
namespace DNAMP1
|
||||
{
|
||||
|
||||
struct MREA : BigDNA
|
||||
struct MREA
|
||||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> magic;
|
||||
struct Header : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> magic;
|
||||
Value<atUint32> version;
|
||||
Value<atVec4f> localToWorldMtx[3];
|
||||
Value<atUint32> meshCount;
|
||||
Value<atUint32> secCount;
|
||||
Value<atUint32> geomSecIdx;
|
||||
Value<atUint32> sclySecIdx;
|
||||
Value<atUint32> collisionSecIdx;
|
||||
Value<atUint32> unkSecIdx;
|
||||
Value<atUint32> lightSecIdx;
|
||||
Value<atUint32> visiSecIdx;
|
||||
Value<atUint32> pathSecIdx;
|
||||
Value<atUint32> arotSecIdx;
|
||||
Vector<atUint32, DNA_COUNT(secCount)> secSizes;
|
||||
};
|
||||
|
||||
struct MeshHeader : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
struct VisorFlags : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> flags;
|
||||
enum ThermalLevel
|
||||
{
|
||||
ThermalCool,
|
||||
ThermalHot,
|
||||
ThermalWarm
|
||||
};
|
||||
static const char* GetThermalLevelStr(ThermalLevel t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case ThermalCool: return "COOL";
|
||||
case ThermalHot: return "HOT";
|
||||
case ThermalWarm: return "WARM";
|
||||
default: break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
bool disableEnviro() const {return flags >> 1 & 0x1;}
|
||||
void setDisableEnviro(bool v) {flags &= ~0x2; flags |= v << 1;}
|
||||
bool disableThermal() const {return flags >> 2 & 0x1;}
|
||||
void setDisableThermal(bool v) {flags &= ~0x4; flags |= v << 2;}
|
||||
bool disableXray() const {return flags >> 3 & 0x1;}
|
||||
void setDisableXray(bool v) {flags &= ~0x8; flags |= v << 3;}
|
||||
ThermalLevel thermalLevel() const {return ThermalLevel(flags >> 4 & 0x3);}
|
||||
void setThermalLevel(ThermalLevel v) {flags &= ~0x30; flags |= v << 4;}
|
||||
const char* thermalLevelStr() const {return GetThermalLevelStr(thermalLevel());}
|
||||
} visorFlags;
|
||||
Value<atVec4f> xfMtx[3];
|
||||
Value<atVec3f> aabb[2];
|
||||
};
|
||||
|
||||
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*)>)
|
||||
{
|
||||
using RigPair = std::pair<CSKR*, CINF*>;
|
||||
RigPair dummy(nullptr, nullptr);
|
||||
|
||||
/* Do extract */
|
||||
Header head;
|
||||
head.read(rs);
|
||||
rs.seekAlign32();
|
||||
|
||||
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
||||
if (!conn.createBlend(outPath.getWithExtension(_S(".blend")).getAbsolutePath()))
|
||||
return false;
|
||||
|
||||
/* Open Py Stream and read sections */
|
||||
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut(true);
|
||||
os.format("import bpy\n"
|
||||
"import bmesh\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.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan Visor')\n"
|
||||
"bpy.types.Object.retro_disable_thermal_visor = bpy.props.BoolProperty(name='Retro: Disable in Thermal Visor')\n"
|
||||
"bpy.types.Object.retro_disable_xray_visor = bpy.props.BoolProperty(name='Retro: Disable in X-Ray Visor')\n"
|
||||
"bpy.types.Object.retro_thermal_level = bpy.props.EnumProperty(items=[('COOL', 'Cool', 'Cool Temperature'),"
|
||||
"('HOT', 'Hot', 'Hot Temperature'),"
|
||||
"('WARM', 'Warm', 'Warm Temperature')],"
|
||||
"name='Retro: Thermal Visor Level')\n"
|
||||
"\n";
|
||||
|
||||
/* One shared material set for all meshes */
|
||||
os << "# Materials\n"
|
||||
"materials = []\n"
|
||||
"\n";
|
||||
MaterialSet matSet;
|
||||
atUint64 secStart = rs.position();
|
||||
matSet.read(rs);
|
||||
matSet.readToBlender(os, pakRouter, entry, 0, dataSpec);
|
||||
rs.seek(secStart + head.secSizes[0], Athena::Begin);
|
||||
std::vector<DNACMDL::VertexAttributes> vertAttribs;
|
||||
DNACMDL::GetVertexAttributes(matSet, vertAttribs);
|
||||
|
||||
/* Read meshes */
|
||||
atUint32 curSec = 1;
|
||||
for (int m=0 ; m<head.meshCount ; ++m)
|
||||
{
|
||||
MeshHeader mHeader;
|
||||
secStart = rs.position();
|
||||
mHeader.read(rs);
|
||||
rs.seek(secStart + head.secSizes[curSec++], Athena::Begin);
|
||||
curSec += DNACMDL::ReadGeomSectionsToBlender<PAKRouter<PAKBridge>, MaterialSet, RigPair>
|
||||
(os, rs, pakRouter, entry, dataSpec, dummy, true,
|
||||
true, vertAttribs, m, head.secCount, 0, &head.secSizes[curSec]);
|
||||
os.format("obj.retro_disable_enviro_visor = %s\n"
|
||||
"obj.retro_disable_thermal_visor = %s\n"
|
||||
"obj.retro_disable_xray_visor = %s\n"
|
||||
"obj.retro_thermal_level = '%s'\n",
|
||||
mHeader.visorFlags.disableEnviro() ? "True" : "False",
|
||||
mHeader.visorFlags.disableThermal() ? "True" : "False",
|
||||
mHeader.visorFlags.disableXray() ? "True" : "False",
|
||||
mHeader.visorFlags.thermalLevelStr());
|
||||
}
|
||||
|
||||
/* 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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -20,13 +20,15 @@ struct MaterialSet : BigDNA
|
|||
struct Material : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
DNAMP1::MaterialSet::Material::Flags flags;
|
||||
using Flags = DNAMP1::MaterialSet::Material::Flags;
|
||||
Flags flags;
|
||||
const Flags& getFlags() const {return flags;}
|
||||
|
||||
Value<atUint32> textureCount;
|
||||
Vector<atUint32, DNA_COUNT(textureCount)> texureIdxs;
|
||||
using VAFlags = DNAMP1::MaterialSet::Material::VAFlags;
|
||||
DNAMP1::MaterialSet::Material::VAFlags vaFlags;
|
||||
inline const VAFlags& getVAFlags() const {return vaFlags;}
|
||||
const VAFlags& getVAFlags() const {return vaFlags;}
|
||||
Value<atUint32> unk0; /* MP2 only */
|
||||
Value<atUint32> unk1; /* MP2 only */
|
||||
Value<atUint32> groupIdx;
|
||||
|
@ -55,7 +57,7 @@ struct MaterialSet : BigDNA
|
|||
};
|
||||
Vector<Material, DNA_COUNT(head.materialCount)> materials;
|
||||
|
||||
static inline void RegisterMaterialProps(HECL::BlenderConnection::PyOutStream& out)
|
||||
static void RegisterMaterialProps(HECL::BlenderConnection::PyOutStream& out)
|
||||
{
|
||||
DNAMP1::MaterialSet::RegisterMaterialProps(out);
|
||||
}
|
||||
|
@ -63,11 +65,11 @@ struct MaterialSet : BigDNA
|
|||
const MaterialSet::Material& material,
|
||||
unsigned groupIdx, unsigned matIdx);
|
||||
|
||||
inline void readToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAKRouter<PAKBridge>::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
void readToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAKRouter<PAKBridge>::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
{
|
||||
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx, dataspec);
|
||||
}
|
||||
|
|
|
@ -28,14 +28,15 @@ struct MaterialSet : BigDNA
|
|||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> flags;
|
||||
inline bool alphaBlending() const {return (flags & 0x8) != 0;}
|
||||
inline void setAlphaBlending(bool enabled) {flags &= ~0x8; flags |= atUint32(enabled) << 3;}
|
||||
inline bool punchthroughAlpha() const {return (flags & 0x10) != 0;}
|
||||
inline void setPunchthroughAlpha(bool enabled) {flags &= ~0x10; flags |= atUint32(enabled) << 4;}
|
||||
inline bool additiveBlending() const {return (flags & 0x20) != 0;}
|
||||
inline void setAdditiveBlending(bool enabled) {flags &= ~0x20; flags |= atUint32(enabled) << 5;}
|
||||
inline bool shadowOccluderMesh() const {return (flags & 0x100) != 0;}
|
||||
inline void setShadowOccluderMesh(bool enabled) {flags &= ~0x100; flags |= atUint32(enabled) << 8;}
|
||||
bool alphaBlending() const {return (flags & 0x8) != 0;}
|
||||
void setAlphaBlending(bool enabled) {flags &= ~0x8; flags |= atUint32(enabled) << 3;}
|
||||
bool punchthroughAlpha() const {return (flags & 0x10) != 0;}
|
||||
void setPunchthroughAlpha(bool enabled) {flags &= ~0x10; flags |= atUint32(enabled) << 4;}
|
||||
bool additiveBlending() const {return (flags & 0x20) != 0;}
|
||||
void setAdditiveBlending(bool enabled) {flags &= ~0x20; flags |= atUint32(enabled) << 5;}
|
||||
bool shadowOccluderMesh() const {return (flags & 0x100) != 0;}
|
||||
void setShadowOccluderMesh(bool enabled) {flags &= ~0x100; flags |= atUint32(enabled) << 8;}
|
||||
bool lightmapUVArray() const {return false;} /* For polymorphic compatibility with MP1/2 */
|
||||
} flags;
|
||||
Value<atUint32> groupIdx;
|
||||
Value<atUint32> unk1;
|
||||
|
@ -44,7 +45,8 @@ struct MaterialSet : BigDNA
|
|||
Value<atUint32> unk3;
|
||||
Value<atUint32> unk4;
|
||||
} header;
|
||||
inline const VAFlags& getVAFlags() const {return header.vaFlags;}
|
||||
const Header::Flags& getFlags() const {return header.flags;}
|
||||
const VAFlags& getVAFlags() const {return header.vaFlags;}
|
||||
|
||||
struct ISection : BigDNA
|
||||
{
|
||||
|
@ -180,7 +182,7 @@ struct MaterialSet : BigDNA
|
|||
};
|
||||
Vector<Material, DNA_COUNT(materialCount)> materials;
|
||||
|
||||
static inline void RegisterMaterialProps(HECL::BlenderConnection::PyOutStream& out)
|
||||
static void RegisterMaterialProps(HECL::BlenderConnection::PyOutStream& out)
|
||||
{
|
||||
DNAMP1::MaterialSet::RegisterMaterialProps(out);
|
||||
}
|
||||
|
@ -188,11 +190,11 @@ struct MaterialSet : BigDNA
|
|||
const MaterialSet::Material& material,
|
||||
unsigned groupIdx, unsigned matIdx);
|
||||
|
||||
inline void readToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAKRouter<PAKBridge>::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
void readToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAKRouter<PAKBridge>::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
{
|
||||
DNACMDL::ReadMaterialSetToBlender_3(os, *this, pakRouter, entry, setIdx, dataspec);
|
||||
}
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit d4db7e3dbe400bd900af32b05cdb726e4fc4f8f9
|
||||
Subproject commit 1e643175a85cea0d72c0023384e522d3cd4bb472
|
Loading…
Reference in New Issue