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

Merge branch 'shader-refactor'

This commit is contained in:
Jack Andersen
2019-05-10 13:10:12 -10:00
76 changed files with 4161 additions and 2117 deletions

View File

@@ -34,7 +34,7 @@ void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const {
for (atUint32 bid : boneIds) {
for (const Name& name : names) {
if (name.boneId == bid) {
os.format("obj.vertex_groups.new('%s')\n", name.name.c_str());
os.format("obj.vertex_groups.new(name='%s')\n", name.name.c_str());
break;
}
}
@@ -47,8 +47,8 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
os.format(
"arm = bpy.data.armatures.new('CINF_%08X')\n"
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
"bpy.context.scene.objects.link(arm_obj)\n"
"bpy.context.scene.objects.active = arm_obj\n"
"bpy.context.scene.collection.objects.link(arm_obj)\n"
"bpy.context.view_layer.objects.active = arm_obj\n"
"bpy.ops.object.mode_set(mode='EDIT')\n"
"arm_bone_table = {}\n",
cinfId.toUint32());
@@ -72,10 +72,9 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
os << "bpy.ops.object.mode_set(mode='OBJECT')\n";
const char* rotMode = os.getConnection().hasSLERP() ? "QUATERNION_SLERP" : "QUATERNION";
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
os.format("arm_obj.pose.bones['%s'].rotation_mode = '%s'\n", getBoneNameFromId(bone.m_origBone.id)->c_str(),
rotMode);
os.format("arm_obj.pose.bones['%s'].rotation_mode = 'QUATERNION'\n",
getBoneNameFromId(bone.m_origBone.id)->c_str());
}
std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId) { return hecl::Format("CINF_%08X", cinfId.toUint32()); }

View File

@@ -67,11 +67,12 @@ bool CMDL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
writer.writeString(boneName);
writer.writeUint32Big(skinMesh.skins.size());
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins) {
writer.writeUint32Big(skin.size());
for (const DNACMDL::Mesh::SkinBind& bind : skin) {
writer.writeUint32Big(bind.boneIdx);
writer.writeFloatBig(bind.weight);
for (const auto& skin : skinMesh.skins) {
size_t numBinds = skinMesh.countSkinBinds(skin);
writer.writeUint32Big(numBinds);
for (size_t i = 0; i < numBinds; ++i) {
writer.writeUint32Big(skin[i].vg_idx);
writer.writeFloatBig(skin[i].weight);
}
writer.writeUint32Big(*vertCountIt++);
}
@@ -103,10 +104,11 @@ bool CMDL::HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
/* CVirtualBone structure just like original (for CPU skinning) */
writer.writeUint32Big(mesh.skins.size());
for (auto& s : mesh.skins) {
writer.writeUint32Big(s.size());
for (auto& b : s) {
writer.writeUint32Big(b.boneIdx);
writer.writeFloatBig(b.weight);
size_t numBinds = mesh.countSkinBinds(s);
writer.writeUint32Big(numBinds);
for (size_t i = 0; i < numBinds; ++i) {
writer.writeUint32Big(s[i].vg_idx);
writer.writeFloatBig(s[i].weight);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
#include "DataSpec/DNACommon/GX.hpp"
#include "DataSpec/DNACommon/CMDL.hpp"
#include "DNAMP1.hpp"
#include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1 {
@@ -60,7 +61,7 @@ struct MaterialSet : BigDNA {
flags |= atUint32(enabled) << 4;
}
bool alphaTest() const { return (flags & 0x20) != 0; }
void setPunchthroughAlpha(bool enabled) {
void setAlphaTest(bool enabled) {
flags &= ~0x20;
flags |= atUint32(enabled) << 5;
}
@@ -468,8 +469,8 @@ struct MaterialSet : BigDNA {
static void AddDynamicAlpha(hecl::blender::PyOutStream& out, unsigned idx);
Material() = default;
Material(const hecl::Backend::GX& gx, const std::unordered_map<std::string, int32_t>& iprops,
const std::vector<hecl::ProjectPath>& texPathsIn, std::vector<hecl::ProjectPath>& texPathsOut,
Material(const hecl::blender::Material& material,
std::vector<hecl::ProjectPath>& texPathsOut,
int colorCount, bool lightmapUVs, bool matrixSkinning);
};
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
@@ -528,29 +529,114 @@ struct HMDLMaterialSet : BigDNA {
static constexpr bool OneSection() { return false; }
AT_DECL_DNA
MaterialSet::MaterialSetHead head;
Value<atUint32> materialCount = 0;
Vector<atUint32, AT_DNA_COUNT(materialCount)> materialEndOffs;
struct Material : BigDNA {
AT_DECL_DNA
MaterialSet::Material::Flags flags;
Value<atUint32> textureCount = 0;
Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
using BlendMaterial = hecl::blender::Material;
Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
struct PASS : hecl::TypedRecordBigDNA<BlendMaterial::ChunkType::TexturePass> {
AT_DECL_EXPLICIT_DNA
Value<BlendMaterial::PassType> type;
UniqueID32 texId;
Value<BlendMaterial::TexCoordSource> source;
Value<BlendMaterial::UVAnimType> uvAnimType;
Value<float> uvAnimParms[9] = {};
Value<bool> alpha;
PASS() = default;
explicit PASS(const BlendMaterial::PASS& pass)
: type(pass.type), texId(pass.tex), source(pass.source), uvAnimType(pass.uvAnimType), alpha(pass.alpha) {
std::copy(pass.uvAnimParms.begin(), pass.uvAnimParms.end(), std::begin(uvAnimParms));
}
bool shouldNormalizeUv() const {
switch (uvAnimType) {
case BlendMaterial::UVAnimType::MvInvNoTranslation:
case BlendMaterial::UVAnimType::MvInv:
case BlendMaterial::UVAnimType::Model:
case BlendMaterial::UVAnimType::CylinderEnvironment:
return true;
default:
return false;
}
}
size_t uvAnimParamsCount() const {
switch (uvAnimType) {
default:
return 0;
case BlendMaterial::UVAnimType::Scroll:
case BlendMaterial::UVAnimType::HStrip:
case BlendMaterial::UVAnimType::VStrip:
return 4;
case BlendMaterial::UVAnimType::Rotation:
case BlendMaterial::UVAnimType::CylinderEnvironment:
return 2;
case BlendMaterial::UVAnimType::Eight:
return 9;
}
}
};
struct CLR : hecl::TypedRecordBigDNA<BlendMaterial::ChunkType::ColorPass> {
AT_DECL_DNA
Value<BlendMaterial::PassType> type;
Value<atVec4f> color;
CLR() = default;
explicit CLR(const BlendMaterial::CLR& clr) : type(clr.type), color(clr.color.val) {}
};
using Chunk = hecl::TypedVariantBigDNA<PASS, CLR>;
Value<atUint32> uvAnimsSize = 4;
Value<atUint32> uvAnimsCount = 0;
Vector<MaterialSet::Material::UVAnimation, AT_DNA_COUNT(uvAnimsCount)> uvAnims;
static unsigned TexMapIdx(BlendMaterial::PassType type) {
switch (type) {
case BlendMaterial::PassType::Lightmap:
return 0;
case BlendMaterial::PassType::Diffuse:
return 1;
case BlendMaterial::PassType::Emissive:
return 2;
case BlendMaterial::PassType::Specular:
return 3;
case BlendMaterial::PassType::ExtendedSpecular:
return 4;
case BlendMaterial::PassType::Reflection:
return 5;
case BlendMaterial::PassType::Alpha:
return 6;
case BlendMaterial::PassType::IndirectTex:
return 7;
default:
assert(false && "Unknown pass type");
return 0;
}
}
String<-1> heclSource;
hecl::Frontend::IR heclIr;
Value<atUint64> hash;
Value<BlendMaterial::ShaderType> shaderType;
Value<atUint32> chunkCount;
Vector<Chunk, AT_DNA_COUNT(chunkCount)> chunks;
Value<BlendMaterial::BlendMode> blendMode = BlendMaterial::BlendMode::Opaque;
std::pair<hecl::Backend::BlendFactor, hecl::Backend::BlendFactor>
blendFactors() const {
switch (blendMode) {
case BlendMaterial::BlendMode::Opaque:
default:
return {hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::Zero};
case BlendMaterial::BlendMode::Alpha:
return {hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha};
case BlendMaterial::BlendMode::Additive:
return {hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One};
}
}
Material() = default;
Material(hecl::Frontend::Frontend& FE, const std::string& diagName, const hecl::blender::Material& mat,
const std::unordered_map<std::string, int32_t>& iprops, const std::vector<hecl::ProjectPath>& texPaths);
Material(const hecl::blender::Material& mat);
};
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
Vector<Material, AT_DNA_COUNT(materialCount)> materials;
};
} // namespace DataSpec::DNAMP1
AT_SPECIALIZE_TYPED_VARIANT_BIGDNA(DataSpec::DNAMP1::HMDLMaterialSet::Material::PASS,
DataSpec::DNAMP1::HMDLMaterialSet::Material::CLR)

View File

@@ -7,8 +7,8 @@ namespace DataSpec::DNAMP1 {
void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const {
os.format(
"obj = bpy.data.objects.new('%s', None)\n"
"obj.empty_draw_type = 'CUBE'\n"
"bpy.context.scene.objects.link(obj)\n"
"obj.empty_display_type = 'CUBE'\n"
"bpy.context.scene.collection.objects.link(obj)\n"
"mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n"
"mtxd = mtx.decompose()\n"
"obj.rotation_mode = 'QUATERNION'\n"
@@ -27,29 +27,6 @@ void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const
}
#endif
template <class Op>
void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) {
Do<Op>({"xf[0]"}, xf[0], s);
Do<Op>({"xf[1]"}, xf[1], s);
Do<Op>({"xf[2]"}, xf[2], s);
Do<Op>({"halfExtent"}, halfExtent, s);
Do<Op>({"isLeaf"}, isLeaf, s);
if (isLeaf) {
if (!leafData)
leafData.reset(new LeafData);
Do<Op>({"leafData"}, *leafData, s);
} else {
if (!left)
left.reset(new Node);
Do<Op>({"left"}, *left, s);
if (!right)
right.reset(new Node);
Do<Op>({"right"}, *right, s);
}
}
AT_SPECIALIZE_DNA(DCLN::Collision::Node)
void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName) {
/* Open Py Stream and read sections */
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
@@ -60,10 +37,8 @@ void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
"\n"
"bpy.context.scene.name = '%s'\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n",
"if 'Collection 1' in bpy.data.collections:\n"
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n",
entryName.data());
DeafBabe::BlenderInit(os);

View File

@@ -91,4 +91,27 @@ struct DCLN : BigDNA {
static bool Cook(const hecl::ProjectPath& outPath, const std::vector<Mesh>& meshes);
};
template <class Op>
void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) {
Do<Op>({"xf[0]"}, xf[0], s);
Do<Op>({"xf[1]"}, xf[1], s);
Do<Op>({"xf[2]"}, xf[2], s);
Do<Op>({"halfExtent"}, halfExtent, s);
Do<Op>({"isLeaf"}, isLeaf, s);
if (isLeaf) {
if (!leafData)
leafData.reset(new LeafData);
Do<Op>({"leafData"}, *leafData, s);
} else {
if (!left)
left.reset(new Node);
Do<Op>({"left"}, *left, s);
if (!right)
right.reset(new Node);
Do<Op>({"right"}, *right, s);
}
}
AT_SPECIALIZE_DNA(DCLN::Collision::Node)
} // namespace DataSpec::DNAMP1

View File

@@ -25,12 +25,15 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) {
" 'Organic':(0.19, 0.45, 0.2)}\n"
"\n"
"# Diffuse Color Maker\n"
"from mathutils import Color\n"
"def make_color(index, mat_type, name):\n"
" new_mat = bpy.data.materials.new(name)\n"
" if mat_type in TYPE_COLORS:\n"
" new_mat.diffuse_color = TYPE_COLORS[mat_type]\n"
" new_mat.diffuse_color = TYPE_COLORS[mat_type] + (1.0,)\n"
" else:\n"
" new_mat.diffuse_color.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n"
" col = Color()\n"
" col.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n"
" new_mat.diffuse_color = tuple(col) + (1.0,)\n"
" return new_mat\n"
"\n"
"bpy.types.Material.retro_unknown = bpy.props.BoolProperty(name='Retro: Unknown (U)')\n"
@@ -189,8 +192,6 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) {
" return len(material_index)-1\n"
" else:\n"
" mat = make_color(len(material_dict), mat_type, mat_name)\n"
" mat.diffuse_intensity = 1.0\n"
" mat.specular_intensity = 0.0\n"
" mat.retro_unknown = ((data >> 0) & 1)\n"
" mat.retro_surface_stone = ((data >> 1) & 1)\n"
" mat.retro_surface_metal = ((data >> 2) & 1)\n"

View File

@@ -292,10 +292,8 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
os << "import bpy, math, bmesh\n"
"from mathutils import Matrix, Quaternion\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 duplicateObject(copy_obj):\n"
" # Create new mesh\n"
@@ -307,16 +305,14 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
" ob_new.scale = copy_obj.scale\n"
" ob_new.location = copy_obj.location\n"
" # Link new object to the given scene and select it\n"
" bpy.context.scene.objects.link(ob_new)\n"
" bpy.context.scene.collection.objects.link(ob_new)\n"
" return ob_new\n";
os.format(
"bpy.context.scene.name = '%s'\n"
"bpy.context.scene.render.resolution_x = 640\n"
"bpy.context.scene.render.resolution_y = 480\n"
"bpy.context.scene.render.engine = 'CYCLES'\n"
"bpy.context.scene.world.use_nodes = True\n"
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
"bg_node.inputs[1].default_value = 0.0\n",
pakRouter.getBestEntryName(entry).c_str());
@@ -377,12 +373,11 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
default: {
zeus::simd_floats colorF(w.header.color.simd);
os.format(
"lamp = bpy.data.lamps.new(name='%s', type='POINT')\n"
"lamp = bpy.data.lights.new(name='%s', type='POINT')\n"
"lamp.color = (%f, %f, %f)\n"
"lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n"
"lamp.constant_coefficient = %f\n"
"lamp.linear_coefficient = %f\n"
"lamp.quadratic_coefficient = %f\n"
"lamp.hecl_falloff_constant = %f\n"
"lamp.hecl_falloff_linear = %f\n"
"lamp.hecl_falloff_quadratic = %f\n"
"lamp.retro_light_angle_constant = %f\n"
"lamp.retro_light_angle_linear = %f\n"
"lamp.retro_light_angle_quadratic = %f\n"
@@ -396,7 +391,7 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
"lamp.spot_size = %f\n",
info->cutoff);
else if (info->type == LITEInfo::ELightType::Directional)
os << "lamp.type = 'HEMI'\n";
os << "lamp.type = 'SUN'\n";
}
}
}
@@ -433,14 +428,15 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
os.format(
"material = bpy.data.materials.new('%s')\n"
"material.specular_intensity = 0.0\n"
"tex_slot = material.texture_slots.add()\n"
"tex_slot.texture = bpy.data.textures.new('%s', 'IMAGE')\n"
"tex_slot.texture.image = image\n"
"material.active_texture = tex_slot.texture\n"
"material.use_nodes = True\n"
"new_nodetree = material.node_tree\n"
"for n in new_nodetree.nodes:\n"
" new_nodetree.nodes.remove(n)\n"
"tex_node = new_nodetree.nodes.new('ShaderNodeTexImage')\n"
"tex_node.image = image\n"
"bm = bmesh.new()\n"
"verts = []\n",
w.header.name.c_str(), w.header.name.c_str());
w.header.name.c_str());
for (int i = 0; i < info->quadCoordCount; ++i) {
int ti;
@@ -511,12 +507,12 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
os << "print(obj.name)\n"
"copy_obj = duplicateObject(obj)\n"
"copy_obj.parent = frme_obj\n"
"copy_obj.hide = False\n";
"copy_obj.hide_set(False)\n";
} else if (w.type == SBIG('CAMR')) {
os << "bpy.context.scene.camera = frme_obj\n"
"if 'Camera' in bpy.data.objects:\n"
" cam = bpy.data.objects['Camera']\n"
" bpy.context.scene.objects.unlink(cam)\n"
" #bpy.context.scene.objects.unlink(cam)\n"
" bpy.data.objects.remove(cam)\n";
} else if (w.type == SBIG('PANE')) {
using PANEInfo = Widget::PANEInfo;
@@ -611,9 +607,9 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
"mtxd = mtx.decompose()\n"
"frme_obj.rotation_mode = 'QUATERNION'\n"
"frme_obj.location = mtxd[0]\n"
"frme_obj.rotation_quaternion = mtxd[1] * angle\n"
"frme_obj.rotation_quaternion = mtxd[1] @ angle\n"
"frme_obj.scale = mtxd[2]\n"
"bpy.context.scene.objects.link(frme_obj)\n",
"bpy.context.scene.collection.objects.link(frme_obj)\n",
xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], originF[0], xfMtxF[1][0], xfMtxF[1][1], xfMtxF[1][2], originF[1],
xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], originF[2]);
}

View File

@@ -298,7 +298,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
areaOut.depLayers.push_back(areaOut.deps.size());
for (const std::pair<hecl::ProjectPath, bool>& path : layer) {
if (path.first) {
urde::SObjectTag tag = g_curSpec->buildTagFromPath(path.first, btok);
urde::SObjectTag tag = g_curSpec->buildTagFromPath(path.first);
if (tag.id.IsValid()) {
if (path.second)
areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type);
@@ -326,7 +326,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
layerResources.addSharedPath(path, false);
for (const std::pair<hecl::ProjectPath, bool>& path : layerResources.sharedPaths) {
urde::SObjectTag tag = g_curSpec->buildTagFromPath(path.first, btok);
urde::SObjectTag tag = g_curSpec->buildTagFromPath(path.first);
if (tag.id.IsValid()) {
if (path.second)
areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type);
@@ -337,7 +337,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
}
hecl::ProjectPath pathPath(areaPath.getParentPath(), _SYS_STR("!path.blend"));
urde::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath, btok);
urde::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath);
if (pathTag.id.IsValid()) {
areaOut.deps.emplace_back(pathTag.id.Value(), pathTag.type);
areaOut.lazyDeps.emplace_back(0, FOURCC('NONE'));
@@ -369,7 +369,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
return true;
}
bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld, hecl::blender::Token& btok) {
bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld) {
std::vector<urde::SObjectTag> mapaTags;
mapaTags.reserve(wld.areas.size());
@@ -380,7 +380,7 @@ bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld, hecl::bl
/* Area map */
hecl::ProjectPath mapPath(area.path, _SYS_STR("/!map.blend"));
if (mapPath.isFile())
mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath, btok));
mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath));
}
/* Write out MAPW */

View File

@@ -136,7 +136,7 @@ struct MLVL : BigDNA {
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld,
hecl::blender::Token& btok);
static bool CookMAPW(const hecl::ProjectPath& outPath, const World& wld, hecl::blender::Token& btok);
static bool CookMAPW(const hecl::ProjectPath& outPath, const World& wld);
static bool CookSAVW(const hecl::ProjectPath& outPath, const World& wld);
};

View File

@@ -21,9 +21,7 @@ void MREA::ReadBabeDeadToBlender_1_2(hecl::blender::PyOutStream& os, athena::io:
atUint32 bdMagic = rs.readUint32Big();
if (bdMagic != 0xBABEDEAD)
Log.report(logvisor::Fatal, "invalid BABEDEAD magic");
os << "bpy.context.scene.render.engine = 'CYCLES'\n"
"bpy.context.scene.world.use_nodes = True\n"
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
os << "bpy.context.scene.world.use_nodes = True\n"
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
"bg_node.inputs[1].default_value = 0.0\n";
for (atUint32 s = 0; s < 2; ++s) {
@@ -127,10 +125,10 @@ static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::MemoryR
zeus::CVector3f extent = aabb.extents();
os.format(
"obj = bpy.data.objects.new('Leaf', None)\n"
"bpy.context.scene.objects.link(obj)\n"
"bpy.context.scene.collection.objects.link(obj)\n"
"obj.location = (%f,%f,%f)\n"
"obj.scale = (%f,%f,%f)\n"
"obj.empty_draw_type = 'CUBE'\n"
"obj.empty_display_type = 'CUBE'\n"
"obj.layers[1] = True\n"
"obj.layers[0] = False\n",
pos.x, pos.y, pos.z, extent.x, extent.y, extent.z);
@@ -168,10 +166,10 @@ static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::IStream
zeus::CVector3f extent = aabb.extents();
os.format(
"obj = bpy.data.objects.new('Leaf', None)\n"
"bpy.context.scene.objects.link(obj)\n"
"bpy.context.scene.collection.objects.link(obj)\n"
"obj.location = (%f,%f,%f)\n"
"obj.scale = (%f,%f,%f)\n"
"obj.empty_draw_type = 'CUBE'\n"
"obj.empty_display_type = 'CUBE'\n"
"obj.layers[1] = True\n"
"obj.layers[0] = False\n",
pos.x, pos.y, pos.z, extent.x, extent.y, extent.z);
@@ -199,22 +197,21 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
/* Open Py Stream and read sections */
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os.format(
"import bpy\n"
"import bmesh\n"
"from mathutils import Vector\n"
"\n"
"bpy.context.scene.name = '%s'\n",
os << "import bpy\n"
"import bmesh\n"
"from mathutils import Vector\n"
"bpy.context.scene.render.fps = 60\n"
"\n";
os.format("bpy.context.scene.name = '%s'\n",
pakRouter.getBestEntryName(entry, false).c_str());
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath(), true);
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath());
MaterialSet::RegisterMaterialProps(os);
os << "# 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"
"bpy.types.Lamp.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
"bpy.types.Lamp.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
"if 'Collection 1' in bpy.data.collections:\n"
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
"\n"
"bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
"bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\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 "
@@ -310,11 +307,11 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
}
/* Origins to center of mass */
os << "bpy.context.scene.layers[1] = True\n"
os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n"
"bpy.ops.object.select_by_type(type='MESH')\n"
"bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n"
"bpy.ops.object.select_all(action='DESELECT')\n"
"bpy.context.scene.layers[1] = False\n";
"bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n";
/* Link MLVL scene as background */
os.linkBackground("//../!world.blend", "World");
@@ -678,7 +675,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
for (const DNACMDL::Mesh::Surface::Vert& vert : surf.verts)
w.writeUint32Big(vert.iPos);
const DNACMDL::Material& mat = mesh.materialSets[0][surf.materialIdx];
w.writeBool(mat.transparent);
w.writeBool(mat.blendMode != DNACMDL::Material::BlendMode::Opaque);
}
}

View File

@@ -14,10 +14,10 @@ static void OutputOctreeNode(hecl::blender::PyOutStream& os, int idx, const zeus
const zeus::CVector3f extent = aabb.extents();
os.format(
"obj = bpy.data.objects.new('Leaf_%d', None)\n"
"bpy.context.scene.objects.link(obj)\n"
"bpy.context.scene.collection.objects.link(obj)\n"
"obj.location = (%f,%f,%f)\n"
"obj.scale = (%f,%f,%f)\n"
"obj.empty_draw_type = 'CUBE'\n"
"obj.empty_display_type = 'CUBE'\n"
"obj.layers[1] = True\n"
"obj.layers[0] = False\n", idx,
pos.x(), pos.y(), pos.z(), extent.x(), extent.y(), extent.z());
@@ -39,15 +39,15 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
"material_index = []\n"
"def make_ground_material(idxMask):\n"
" mat = bpy.data.materials.new('Ground %%X' %% idxMask)\n"
" mat.diffuse_color = (0.8, 0.460, 0.194)\n"
" mat.diffuse_color = (0.8, 0.460, 0.194, 1.0)\n"
" return mat\n"
"def make_flyer_material(idxMask):\n"
" mat = bpy.data.materials.new('Flyer %%X' %% idxMask)\n"
" mat.diffuse_color = (0.016, 0.8, 0.8)\n"
" mat.diffuse_color = (0.016, 0.8, 0.8, 1.0)\n"
" return mat\n"
"def make_swimmer_material(idxMask):\n"
" mat = bpy.data.materials.new('Swimmer %%X' %% idxMask)\n"
" mat.diffuse_color = (0.074, 0.293, 0.8)\n"
" mat.diffuse_color = (0.074, 0.293, 0.8, 1.0)\n"
" return mat\n"
"def select_material(meshIdxMask, meshTypeMask):\n"
" key = (meshIdxMask, meshTypeMask)\n"
@@ -71,10 +71,8 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
"\n"
"bpy.context.scene.name = '%s'\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n"
" bpy.context.scene.objects.unlink(ob)\n"
" bpy.data.objects.remove(ob)\n"
"if 'Collection 1' in bpy.data.collections:\n"
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
"\n"
"bm = bmesh.new()\n"
"height_lay = bm.faces.layers.float.new('Height')\n",
@@ -109,11 +107,11 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
os.format("aabb = bpy.data.objects.new('AABB', None)\n"
"aabb.location = (%f,%f,%f)\n"
"aabb.scale = (%f,%f,%f)\n"
"aabb.empty_draw_type = 'CUBE'\n"
"bpy.context.scene.objects.link(aabb)\n"
"aabb.empty_display_type = 'CUBE'\n"
"bpy.context.scene.collection.objects.link(aabb)\n"
"centr = bpy.data.objects.new('Center', None)\n"
"centr.location = (%f,%f,%f)\n"
"bpy.context.scene.objects.link(centr)\n",
"bpy.context.scene.collection.objects.link(centr)\n",
aabb.min[0] + (aabb.max[0] - aabb.min[0]) / 2.f,
aabb.min[1] + (aabb.max[1] - aabb.min[1]) / 2.f,
aabb.min[2] + (aabb.max[2] - aabb.min[2]) / 2.f,
@@ -143,16 +141,10 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
" mat = material_dict[mat_name]\n"
" path_mesh.materials.append(mat)\n"
"\n"
"bpy.context.scene.objects.link(path_mesh_obj)\n"
"path_mesh_obj.draw_type = 'SOLID'\n"
"path_mesh_obj.game.physics_type = 'STATIC'\n"
"path_mesh_obj.layers[1] = True\n"
"bpy.context.scene.collection.objects.link(path_mesh_obj)\n"
"path_mesh_obj.display_type = 'SOLID'\n"
"bpy.context.scene.hecl_path_obj = path_mesh_obj.name\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";
if (xf) {
const zeus::CMatrix4f& w = *xf;