2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-08 13:44:56 +00:00

Refactor for blender 2.8 and new shader model

This commit is contained in:
Jack Andersen
2019-05-07 17:50:21 -10:00
parent 1f10769af3
commit 233d13ceb9
67 changed files with 2827 additions and 2105 deletions

View File

@@ -100,14 +100,9 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
"bpy.context.scene.name = '%s'\n"
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n"
"\n"
"# Using 'Blender Game'\n"
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'LAMP' and ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"if 'Collection 1' in bpy.data.collections:\n"
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
"\n"
"actor_data = bpy.context.scene.hecl_sact_data\n"
"arm_obj = None\n",
@@ -143,7 +138,7 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.objects.link(obj)\n"
" bpy.context.scene.collection.objects.link(obj)\n"
"obj.parent = arm_obj\n"
"obj.parent_type = 'ARMATURE'\n"
"actor_subtype.linked_mesh = obj.name\n\n";
@@ -162,7 +157,7 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.objects.link(obj)\n"
" bpy.context.scene.collection.objects.link(obj)\n"
"obj.parent = arm_obj\n"
"obj.parent_type = 'ARMATURE'\n"
"overlay.linked_mesh = obj.name\n\n";
@@ -202,7 +197,7 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.objects.link(obj)\n"
" bpy.context.scene.collection.objects.link(obj)\n"
"obj.parent = arm_obj\n"
"obj.parent_type = 'ARMATURE'\n"
"attachment.linked_mesh = obj.name\n\n";

View File

@@ -18,42 +18,42 @@ void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLi
return;
case BabeDeadLight::LightType::Directional:
os.format(
"lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SUN')\n"
"lamp = bpy.data.lights.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"
"lamp.use_shadow = %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");
light.direction.simd[1], light.direction.simd[2], light.castShadows ? "True" : "False");
return;
case BabeDeadLight::LightType::Custom:
os.format(
"lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'POINT')\n"
"lamp = bpy.data.lights.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"
"lamp.use_shadow = %s\n"
"\n",
s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2],
light.castShadows ? "RAY_SHADOW" : "NOSHADOW");
light.castShadows ? "True" : "False");
break;
case BabeDeadLight::LightType::Spot:
case BabeDeadLight::LightType::Spot2:
os.format(
"lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SPOT')\n"
"lamp = bpy.data.lights.new('LAMP_%01u_%03u', 'SPOT')\n"
"lamp.color = (%f,%f,%f)\n"
"lamp.spot_size = %.6g\n"
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
"lamp_obj.rotation_mode = 'QUATERNION'\n"
"lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector((%f,%f,%f)))\n"
"lamp.shadow_soft_size = 0.5\n"
"lamp.shadow_method = '%s'\n"
"lamp.use_shadow = %s\n"
"\n",
s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], zeus::degToRad(light.spotCutoff),
light.direction.simd[0], light.direction.simd[1], light.direction.simd[2],
light.castShadows ? "RAY_SHADOW" : "NOSHADOW");
light.castShadows ? "True" : "False");
break;
default:
return;
@@ -73,7 +73,7 @@ void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLi
"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"
"bpy.context.scene.collection.objects.link(lamp_obj)\n"
"\n",
s, light.lightType, light.q / 8.f, light.color.simd[0], light.color.simd[1], light.color.simd[2],
light.position.simd[0], light.position.simd[1], light.position.simd[2]);

View File

@@ -80,15 +80,12 @@ void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const Material
hecl::SystemString resPath = pakRouter.getResourceRelativePath(entry, tex);
hecl::SystemUTF8Conv resPathView(resPath);
os.format(
"if '%s' in bpy.data.textures:\n"
"if '%s' in bpy.data.images:\n"
" image = bpy.data.images['%s']\n"
" texture = bpy.data.textures[image.name]\n"
"else:\n"
" image = bpy.data.images.load('''//%s''')\n"
" image.name = '%s'\n"
" texture = bpy.data.textures.new(image.name, 'IMAGE')\n"
" texture.image = image\n"
"texmap_list.append(texture)\n"
"texmap_list.append(image)\n"
"\n",
texName.c_str(), texName.c_str(), resPathView.c_str(), texName.c_str());
}
@@ -375,19 +372,13 @@ public:
}
};
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath,
bool solidShading) {
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath) {
os << "import math\n"
"from mathutils import Vector\n"
"\n"
"# Using 'Blender Game'\n"
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'LAMP' and ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"if 'Collection 1' in bpy.data.collections:\n"
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
"\n"
"def loop_from_facevert(bm, face, vert_idx):\n"
" for loop in face.loops:\n"
@@ -422,7 +413,7 @@ void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectP
" 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"
" bmesh.ops.delete(od_entry['bm'], geom=od_entry['bm'].faces, context='FACES_ONLY')\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"
@@ -469,13 +460,6 @@ void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectP
" return result\n"
"\n";
if (solidShading) {
os << "for ar in bpy.context.screen.areas:\n"
" for sp in ar.spaces:\n"
" if sp.type == 'VIEW_3D':\n"
" sp.viewport_shade = 'SOLID'\n";
}
/* Link master shader library */
os.format(
"# Master shader library\n"
@@ -486,26 +470,27 @@ void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectP
}
void FinishBlenderMesh(hecl::blender::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 + '_%03d')\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 << "if 'Render' not in bpy.data.collections:\n"
" coll = bpy.data.collections.new('Render')\n"
" bpy.context.scene.collection.children.link(coll)\n"
"else:\n"
" coll = bpy.data.collections['Render']\n";
if (meshIdx < 0) {
os << "mesh = bpy.data.meshes.new(bpy.context.scene.name)\n"
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
"obj.show_transparent = True\n"
"coll.objects.link(obj)\n";
os.format("mesh.hecl_material_count = %u\n", matSetCount);
} else {
os.format("mesh = bpy.data.meshes.new(bpy.context.scene.name + '_%03d')\n", meshIdx);
os << "obj = bpy.data.objects.new(mesh.name, mesh)\n"
"obj.show_transparent = True\n"
"coll.objects.link(obj)\n";
os.format("mesh.hecl_material_count = %u\n", matSetCount);
}
os << "mesh.use_auto_smooth = True\n"
"mesh.auto_smooth_angle = math.pi\n"
"mesh.show_edge_sharp = True\n"
"\n"
"for material in materials:\n"
" mesh.materials.append(material)\n"
@@ -549,7 +534,7 @@ void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int
"for v in bm.verts:\n"
" if len(v.link_faces) == 0:\n"
" verts_to_del.append(v)\n"
"bmesh.ops.delete(bm, geom=verts_to_del, context=1)\n"
"bmesh.ops.delete(bm, geom=verts_to_del, context='VERTS')\n"
"\n"
"for edge in bm.edges:\n"
" if edge.is_manifold:\n"
@@ -1037,7 +1022,7 @@ bool ReadCMDLToBlender(hecl::blender::Connection& conn, athena::io::IStreamReade
"bpy.context.scene.name = '%s'\n"
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n",
pakRouter.getBestEntryName(entry).c_str());
InitGeomBlenderContext(os, dataspec.getMasterShaderPath(), false);
InitGeomBlenderContext(os, dataspec.getMasterShaderPath());
MaterialSet::RegisterMaterialProps(os);
os << "# Materials\n"
@@ -1142,9 +1127,9 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
/* Build material sets */
std::vector<MaterialSet> matSets;
#if 0
matSets.reserve(mesh.materialSets.size());
{
hecl::Frontend::Frontend FE;
for (const std::vector<Material>& mset : mesh.materialSets) {
matSets.emplace_back();
MaterialSet& targetMSet = matSets.back();
@@ -1191,6 +1176,7 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
paddingSizes.push_back(secSz32 - secSz);
}
}
#endif
/* Vertex Positions */
size_t secSz = mesh.pos.size() * 12;
@@ -1435,44 +1421,24 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
/* Build material sets */
std::vector<MaterialSet> matSets;
matSets.reserve(mesh.materialSets.size());
{
hecl::Frontend::Frontend FE;
for (const std::vector<Material>& mset : mesh.materialSets) {
matSets.emplace_back();
MaterialSet& targetMSet = matSets.back();
std::vector<hecl::ProjectPath> texPaths;
texPaths.reserve(mset.size() * 4);
for (const Material& mat : mset) {
for (const hecl::ProjectPath& path : mat.texs) {
bool found = false;
for (const hecl::ProjectPath& ePath : texPaths) {
if (path == ePath) {
found = true;
break;
}
}
if (!found)
texPaths.push_back(path);
}
}
size_t endOff = 0;
for (const Material& mat : mset) {
std::string diagName = hecl::Format("%s:%s", inPath.getLastComponentUTF8().data(), mat.name.c_str());
targetMSet.materials.emplace_back(FE, diagName, mat, mat.iprops, texPaths);
targetMSet.materials.back().binarySize(endOff);
targetMSet.head.addMaterialEndOff(endOff);
}
for (const std::vector<Material>& mset : mesh.materialSets) {
matSets.emplace_back();
MaterialSet& targetMSet = matSets.back();
for (const hecl::ProjectPath& path : texPaths)
targetMSet.head.addTexture(path);
size_t secSz = 0;
targetMSet.binarySize(secSz);
size_t secSz32 = ROUND_UP_32(secSz);
head.secSizes.push_back(secSz32);
paddingSizes.push_back(secSz32 - secSz);
size_t endOff = 0;
for (const Material& mat : mset) {
++targetMSet.materialCount;
targetMSet.materials.emplace_back(mat);
targetMSet.materials.back().binarySize(endOff);
targetMSet.materialEndOffs.push_back(endOff);
}
size_t secSz = 0;
targetMSet.binarySize(secSz);
size_t secSz32 = ROUND_UP_32(secSz);
head.secSizes.push_back(secSz32);
paddingSizes.push_back(secSz32 - secSz);
}
hecl::blender::HMDLBuffers bufs = mesh.getHMDLBuffers(false, poolSkinIndex);
@@ -1614,10 +1580,8 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
surfCount += mesh.surfaces.size();
surfToGlobalMats.reserve(surfCount);
hecl::Frontend::Frontend FE;
size_t endOff = 0;
std::vector<hecl::ProjectPath> texPaths;
std::vector<hecl::Backend::GX> setBackends;
for (const Mesh& mesh : meshes) {
if (mesh.materialSets.size()) {
std::vector<size_t> meshToGlobalMats;
@@ -1630,28 +1594,24 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
if (!newMat)
continue;
for (const hecl::ProjectPath& path : mat.texs) {
bool found = false;
for (const hecl::ProjectPath& ePath : texPaths) {
if (path == ePath) {
found = true;
break;
for (const auto& chunk : mat.chunks) {
if (auto pass = chunk.get_if<Material::PASS>()) {
bool found = false;
for (const hecl::ProjectPath& ePath : texPaths) {
if (pass->tex == ePath) {
found = true;
break;
}
}
if (!found)
texPaths.push_back(pass->tex);
}
if (!found)
texPaths.push_back(path);
}
std::string diagName = hecl::Format("%s:%s", inPath.getLastComponentUTF8().data(), mat.name.c_str());
hecl::Frontend::IR matIR = FE.compileSource(mat.source, diagName);
setBackends.emplace_back();
hecl::Backend::GX& matGX = setBackends.back();
matGX.reset(matIR, FE.getDiagnostics());
auto lightmapped = mat.iprops.find("retro_lightmapped");
bool lm = lightmapped != mat.iprops.cend() && lightmapped->second != 0;
matSet.materials.emplace_back(matGX, mat.iprops, mat.texs, texPaths, mesh.colorLayerCount, lm, false);
matSet.materials.emplace_back(mat, texPaths, mesh.colorLayerCount, lm, false);
matSet.materials.back().binarySize(endOff);
matSet.head.addMaterialEndOff(endOff);
@@ -1917,10 +1877,8 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
surfCount += mesh.surfaces.size();
surfToGlobalMats.reserve(surfCount);
MaterialSet matSet;
hecl::Frontend::Frontend FE;
MaterialSet matSet = {};
size_t endOff = 0;
std::vector<hecl::ProjectPath> texPaths;
for (const Mesh& mesh : meshes) {
if (mesh.materialSets.size()) {
std::vector<size_t> meshToGlobalMats;
@@ -1933,30 +1891,16 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
if (!newMat)
continue;
for (const hecl::ProjectPath& path : mat.texs) {
bool found = false;
for (const hecl::ProjectPath& ePath : texPaths) {
if (path == ePath) {
found = true;
break;
}
}
if (!found)
texPaths.push_back(path);
}
std::string diagName = hecl::Format("%s:%s", inPath.getLastComponentUTF8().data(), mat.name.c_str());
matSet.materials.emplace_back(FE, diagName, mat, mat.iprops, texPaths);
++matSet.materialCount;
matSet.materials.emplace_back(mat);
matSet.materials.back().binarySize(endOff);
matSet.head.addMaterialEndOff(endOff);
matSet.materialEndOffs.push_back(endOff);
}
for (const Mesh::Surface& surf : mesh.surfaces)
surfToGlobalMats.push_back(meshToGlobalMats[surf.materialIdx]);
}
}
for (const hecl::ProjectPath& path : texPaths)
matSet.head.addTexture(path);
size_t secSz = 0;
matSet.binarySize(secSz);

View File

@@ -1,8 +1,6 @@
#pragma once
#include "athena/FileWriter.hpp"
#include "hecl/Frontend.hpp"
#include "hecl/Backend/GX.hpp"
#include "PAK.hpp"
#include "GX.hpp"
#include "TXTR.hpp"
@@ -121,8 +119,7 @@ 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 InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath,
bool solidShading);
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath);
void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx);
template <class PAKRouter, class MaterialSet, class RigPair, class SurfaceHeader>

View File

@@ -13,7 +13,7 @@ make_dnalist(liblist DNACommon
set(DNACOMMON_SOURCES
DNACommon.hpp DNACommon.cpp
PAK.hpp PAK.cpp
GX.hpp
GX.hpp GX.cpp
FSM2.hpp FSM2.cpp
MLVL.hpp MLVL.cpp
CMDL.cpp

View File

@@ -75,18 +75,18 @@ void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, b
" mat = material_dict[mat_name]\n"
" col_mesh.materials.append(mat)\n"
"\n"
"bpy.context.scene.objects.link(col_mesh_obj)\n"
"bpy.context.scene.objects.active = col_mesh_obj\n"
"if 'Collision' not in bpy.data.collections:\n"
" coll = bpy.data.collections.new('Collision')\n"
" bpy.context.scene.collection.children.link(coll)\n"
"else:\n"
" coll = bpy.data.collections['Collision']\n"
"coll.objects.link(col_mesh_obj)\n"
"bpy.context.view_layer.objects.active = col_mesh_obj\n"
"bpy.ops.object.mode_set(mode='EDIT')\n"
"bpy.ops.mesh.tris_convert_to_quads()\n"
"bpy.ops.object.mode_set(mode='OBJECT')\n"
"bpy.context.scene.objects.active = None\n";
if (!isDcln)
os << "col_mesh_obj.layers[1] = True\n"
"col_mesh_obj.layers[0] = False\n";
os << "col_mesh_obj.draw_type = 'SOLID'\n"
"col_mesh_obj.game.physics_type = 'STATIC'\n"
"bpy.context.view_layer.objects.active = None\n"
"col_mesh_obj.display_type = 'SOLID'\n"
"\n";
}

18
DataSpec/DNACommon/GX.cpp Normal file
View File

@@ -0,0 +1,18 @@
#include "GX.hpp"
namespace GX {
template <>
void Color::Enumerate<athena::io::DNA<athena::Big>::Read>(typename Read::StreamT& reader) {
reader.readUBytesToBuf(&num, 4);
}
template <>
void Color::Enumerate<athena::io::DNA<athena::Big>::Write>(typename Write::StreamT& writer) {
writer.writeUBytes(reinterpret_cast<const atUint8*>(&num), 4);
}
template <>
void Color::Enumerate<athena::io::DNA<athena::Big>::BinarySize>(typename BinarySize::StreamT& s) {
s += 4;
}
}

View File

@@ -1,4 +1,296 @@
#pragma once
#include "athena/DNA.hpp"
namespace GX {
enum AttrType { NONE, DIRECT, INDEX8, INDEX16 };
enum TevColorArg {
CC_CPREV = 0,
CC_APREV = 1,
CC_C0 = 2,
CC_A0 = 3,
CC_C1 = 4,
CC_A1 = 5,
CC_C2 = 6,
CC_A2 = 7,
CC_TEXC = 8,
CC_TEXA = 9,
CC_RASC = 10,
CC_RASA = 11,
CC_ONE = 12,
CC_HALF = 13,
CC_KONST = 14,
CC_ZERO = 15,
};
enum TevAlphaArg {
CA_APREV = 0,
CA_A0 = 1,
CA_A1 = 2,
CA_A2 = 3,
CA_TEXA = 4,
CA_RASA = 5,
CA_KONST = 6,
CA_ZERO = 7,
};
enum TevKColorSel {
TEV_KCSEL_8_8 = 0x00,
TEV_KCSEL_7_8 = 0x01,
TEV_KCSEL_6_8 = 0x02,
TEV_KCSEL_5_8 = 0x03,
TEV_KCSEL_4_8 = 0x04,
TEV_KCSEL_3_8 = 0x05,
TEV_KCSEL_2_8 = 0x06,
TEV_KCSEL_1_8 = 0x07,
TEV_KCSEL_1 = TEV_KCSEL_8_8,
TEV_KCSEL_3_4 = TEV_KCSEL_6_8,
TEV_KCSEL_1_2 = TEV_KCSEL_4_8,
TEV_KCSEL_1_4 = TEV_KCSEL_2_8,
TEV_KCSEL_K0 = 0x0C,
TEV_KCSEL_K1 = 0x0D,
TEV_KCSEL_K2 = 0x0E,
TEV_KCSEL_K3 = 0x0F,
TEV_KCSEL_K0_R = 0x10,
TEV_KCSEL_K1_R = 0x11,
TEV_KCSEL_K2_R = 0x12,
TEV_KCSEL_K3_R = 0x13,
TEV_KCSEL_K0_G = 0x14,
TEV_KCSEL_K1_G = 0x15,
TEV_KCSEL_K2_G = 0x16,
TEV_KCSEL_K3_G = 0x17,
TEV_KCSEL_K0_B = 0x18,
TEV_KCSEL_K1_B = 0x19,
TEV_KCSEL_K2_B = 0x1A,
TEV_KCSEL_K3_B = 0x1B,
TEV_KCSEL_K0_A = 0x1C,
TEV_KCSEL_K1_A = 0x1D,
TEV_KCSEL_K2_A = 0x1E,
TEV_KCSEL_K3_A = 0x1F
};
enum TevKAlphaSel {
TEV_KASEL_8_8 = 0x00,
TEV_KASEL_7_8 = 0x01,
TEV_KASEL_6_8 = 0x02,
TEV_KASEL_5_8 = 0x03,
TEV_KASEL_4_8 = 0x04,
TEV_KASEL_3_8 = 0x05,
TEV_KASEL_2_8 = 0x06,
TEV_KASEL_1_8 = 0x07,
TEV_KASEL_1 = TEV_KASEL_8_8,
TEV_KASEL_3_4 = TEV_KASEL_6_8,
TEV_KASEL_1_2 = TEV_KASEL_4_8,
TEV_KASEL_1_4 = TEV_KASEL_2_8,
TEV_KASEL_K0_R = 0x10,
TEV_KASEL_K1_R = 0x11,
TEV_KASEL_K2_R = 0x12,
TEV_KASEL_K3_R = 0x13,
TEV_KASEL_K0_G = 0x14,
TEV_KASEL_K1_G = 0x15,
TEV_KASEL_K2_G = 0x16,
TEV_KASEL_K3_G = 0x17,
TEV_KASEL_K0_B = 0x18,
TEV_KASEL_K1_B = 0x19,
TEV_KASEL_K2_B = 0x1A,
TEV_KASEL_K3_B = 0x1B,
TEV_KASEL_K0_A = 0x1C,
TEV_KASEL_K1_A = 0x1D,
TEV_KASEL_K2_A = 0x1E,
TEV_KASEL_K3_A = 0x1F
};
enum TevOp {
TEV_ADD = 0,
TEV_SUB = 1,
TEV_COMP_R8_GT = 8,
TEV_COMP_R8_EQ = 9,
TEV_COMP_GR16_GT = 10,
TEV_COMP_GR16_EQ = 11,
TEV_COMP_BGR24_GT = 12,
TEV_COMP_BGR24_EQ = 13,
TEV_COMP_RGB8_GT = 14,
TEV_COMP_RGB8_EQ = 15,
TEV_COMP_A8_GT = TEV_COMP_RGB8_GT,
TEV_COMP_A8_EQ = TEV_COMP_RGB8_EQ
};
enum TevBias {
TB_ZERO = 0,
TB_ADDHALF = 1,
TB_SUBHALF = 2,
};
enum TevScale { CS_SCALE_1 = 0, CS_SCALE_2 = 1, CS_SCALE_4 = 2, CS_DIVIDE_2 = 3 };
enum TexGenType {
TG_MTX3x4 = 0,
TG_MTX2x4,
TG_BUMP0,
TG_BUMP1,
TG_BUMP2,
TG_BUMP3,
TG_BUMP4,
TG_BUMP5,
TG_BUMP6,
TG_BUMP7,
TG_SRTG
};
enum TexGenSrc {
TG_POS = 0,
TG_NRM,
TG_BINRM,
TG_TANGENT,
TG_TEX0,
TG_TEX1,
TG_TEX2,
TG_TEX3,
TG_TEX4,
TG_TEX5,
TG_TEX6,
TG_TEX7,
TG_TEXCOORD0,
TG_TEXCOORD1,
TG_TEXCOORD2,
TG_TEXCOORD3,
TG_TEXCOORD4,
TG_TEXCOORD5,
TG_TEXCOORD6,
TG_COLOR0,
TG_COLOR1
};
enum TexMtx {
TEXMTX0 = 30,
TEXMTX1 = 33,
TEXMTX2 = 36,
TEXMTX3 = 39,
TEXMTX4 = 42,
TEXMTX5 = 45,
TEXMTX6 = 48,
TEXMTX7 = 51,
TEXMTX8 = 54,
TEXMTX9 = 57,
IDENTITY = 60
};
enum PTTexMtx {
PTTEXMTX0 = 64,
PTTEXMTX1 = 67,
PTTEXMTX2 = 70,
PTTEXMTX3 = 73,
PTTEXMTX4 = 76,
PTTEXMTX5 = 79,
PTTEXMTX6 = 82,
PTTEXMTX7 = 85,
PTTEXMTX8 = 88,
PTTEXMTX9 = 91,
PTTEXMTX10 = 94,
PTTEXMTX11 = 97,
PTTEXMTX12 = 100,
PTTEXMTX13 = 103,
PTTEXMTX14 = 106,
PTTEXMTX15 = 109,
PTTEXMTX16 = 112,
PTTEXMTX17 = 115,
PTTEXMTX18 = 118,
PTTEXMTX19 = 121,
PTIDENTITY = 125
};
enum TevRegID { TEVPREV = 0, TEVREG0 = 1, TEVREG1 = 2, TEVREG2 = 3, TEVLAZY = 5 };
enum DiffuseFn { DF_NONE = 0, DF_SIGN, DF_CLAMP };
enum AttnFn { AF_SPEC = 0, AF_SPOT = 1, AF_NONE };
enum Primitive {
POINTS = 0xb8,
LINES = 0xa8,
LINESTRIP = 0xb0,
TRIANGLES = 0x90,
TRIANGLESTRIP = 0x98,
TRIANGLEFAN = 0xa0,
QUADS = 0x80
};
enum ChannelID {
GX_COLOR0,
GX_COLOR1,
GX_ALPHA0,
GX_ALPHA1,
GX_COLOR0A0,
GX_COLOR1A1,
GX_COLOR_ZERO,
GX_ALPHA_BUMP,
GX_ALPHA_BUMPN,
GX_COLOR_NULL = 0xff
};
enum BlendFactor : uint16_t {
BL_ZERO,
BL_ONE,
BL_SRCCLR,
BL_INVSRCCLR,
BL_SRCALPHA,
BL_INVSRCALPHA,
BL_DSTALPHA,
BL_INVDSTALPHA
};
struct Color : athena::io::DNA<athena::Big> {
union {
uint8_t color[4];
uint32_t num = 0;
};
Color() = default;
Color& operator=(const atVec4f& vec) {
athena::simd_floats f(vec.simd);
color[0] = uint8_t(std::min(std::max(f[0] * 255.f, 0.f), 255.f));
color[1] = uint8_t(std::min(std::max(f[1] * 255.f, 0.f), 255.f));
color[2] = uint8_t(std::min(std::max(f[2] * 255.f, 0.f), 255.f));
color[3] = uint8_t(std::min(std::max(f[3] * 255.f, 0.f), 255.f));
return *this;
}
Color& operator=(const atVec3f& vec) {
athena::simd_floats f(vec.simd);
color[0] = uint8_t(std::min(std::max(f[0] * 255.f, 0.f), 255.f));
color[1] = uint8_t(std::min(std::max(f[1] * 255.f, 0.f), 255.f));
color[2] = uint8_t(std::min(std::max(f[2] * 255.f, 0.f), 255.f));
color[3] = 0xff;
return *this;
}
Color& operator=(uint8_t val) {
color[0] = val;
color[1] = val;
color[2] = val;
color[3] = val;
return *this;
}
atVec4f toVec4f() const {
atVec4f out;
athena::simd_floats f;
f[0] = color[0] / 255.f;
f[1] = color[1] / 255.f;
f[2] = color[2] / 255.f;
f[3] = color[3] / 255.f;
out.simd.copy_from(f);
return out;
}
Color(const atVec4f& vec) { *this = vec; }
Color(const atVec3f& vec) { *this = vec; }
Color(uint8_t val) { *this = val; }
bool operator==(const Color& other) const { return num == other.num; }
bool operator!=(const Color& other) const { return num != other.num; }
uint8_t operator[](size_t idx) const { return color[idx]; }
uint8_t& operator[](size_t idx) { return color[idx]; }
AT_DECL_EXPLICIT_DNA
};
}
#include "hecl/Backend/GX.hpp"
using GX = hecl::Backend::GX;

View File

@@ -120,16 +120,9 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
"('MAPSTATIONORVISIT2', 'Map Station or Visit 2', 'Visible after Map Station or Visit', 4)],"
"name='Retro: Map Object Visibility Mode')\n"
"\n"
"for ar in bpy.context.screen.areas:\n"
" for sp in ar.spaces:\n"
" if sp.type == 'VIEW_3D':\n"
" sp.viewport_shade = 'SOLID'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"if 'Collection 1' in bpy.data.collections:\n"
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
"\n"
"def add_triangle(bm, verts):\n"
" verts = [bm.verts[vi] for vi in verts]\n"
@@ -164,7 +157,7 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
moMP12->transformMtx[i].simd.copy_to(mtxF[i]);
os.format(
"obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
"bpy.context.scene.objects.link(obj)\n"
"bpy.context.scene.collection.objects.link(obj)\n"
"obj.retro_mappable_type = %d\n"
"obj.retro_mapobj_vis_mode = '%s'\n"
"obj.retro_mappable_sclyid = '0x%08X'\n"
@@ -185,7 +178,7 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
moMP3->transformMtx[i].simd.copy_to(mtxF[i]);
os.format(
"obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
"bpy.context.scene.objects.link(obj)\n"
"bpy.context.scene.collection.objects.link(obj)\n"
"obj.retro_mappable_type = %d\n"
"obj.retro_mapobj_vis_mode = '%s'\n"
"obj.retro_mappable_sclyid = '0x%08X'\n"
@@ -272,10 +265,9 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
}
os << "mesh = bpy.data.meshes.new('MAP')\n"
"mesh.show_edge_seams = True\n"
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
"bm.to_mesh(mesh)\n"
"bpy.context.scene.objects.link(obj)\n"
"bpy.context.scene.collection.objects.link(obj)\n"
"bm.free()\n";
const zeus::CMatrix4f* tmpMtx = pakRouter.lookupMAPATransform(entry.id);

View File

@@ -21,10 +21,8 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
"from mathutils import Matrix\n"
"\n"
"# Clear Scene\n"
"bpy.context.scene.camera = None\n"
"for ob in bpy.data.objects:\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"if 'Collection 1' in bpy.data.collections:\n"
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
"\n"
"bpy.types.Object.retro_mapworld_color = bpy.props.FloatVectorProperty(name='Retro: MapWorld Color',"
" description='Sets map world color', subtype='COLOR', size=4, min=0.0, max=1.0)\n"
@@ -53,7 +51,7 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
"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",
"bpy.context.scene.collection.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());
@@ -70,7 +68,7 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
"obj.location = mtxd[0]\n"
"obj.rotation_quaternion = mtxd[1]\n"
"obj.scale = mtxd[2]\n"
"bpy.context.scene.objects.link(obj)\n"
"bpy.context.scene.collection.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]);
@@ -81,7 +79,6 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
" for area in screen.areas:\n"
" for space in area.spaces:\n"
" if space.type == 'VIEW_3D':\n"
" space.viewport_shade = 'SOLID'\n"
" space.clip_end = 8000.0\n";
os.centerView();

View File

@@ -18,18 +18,15 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
if (!conn.createBlend(blendPath, hecl::blender::BlendType::World))
return false;
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os.format(
"import bpy\n"
"import bmesh\n"
"from mathutils import Matrix\n"
"\n"
"bpy.context.scene.name = 'World'\n"
"\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n");
os << "import bpy\n"
"import bmesh\n"
"from mathutils import Matrix\n"
"\n"
"bpy.context.scene.name = 'World'\n"
"\n"
"# Clear Scene\n"
"if 'Collection 1' in bpy.data.collections:\n"
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n";
/* Insert area empties */
int areaIdx = 0;
@@ -46,7 +43,7 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
"bm.to_mesh(box_mesh)\n"
"bm.free()\n"
"box = bpy.data.objects.new(box_mesh.name, box_mesh)\n"
"bpy.context.scene.objects.link(box)\n"
"bpy.context.scene.collection.objects.link(box)\n"
"mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n"
"mtxd = mtx.decompose()\n"
"box.rotation_mode = 'QUATERNION'\n"
@@ -78,7 +75,7 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
os << "bm.edges.new((bm.verts[-1], bm.verts[0]))\n";
os.format("dockMesh = bpy.data.meshes.new('DOCK_%02d_%02d')\n", areaIdx, dockIdx);
os << "dockObj = bpy.data.objects.new(dockMesh.name, dockMesh)\n"
"bpy.context.scene.objects.link(dockObj)\n"
"bpy.context.scene.collection.objects.link(dockObj)\n"
"bm.to_mesh(dockMesh)\n"
"bm.free()\n"
"dockObj.parent = box\n";

View File

@@ -322,7 +322,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const
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));
overrideSearch->second, m_dataSpec.getDataSpecEntry()));
}
const PAKType* pak = m_pak.get();