mirror of https://github.com/AxioDL/metaforce.git
added 'bintoc' tool; embedded blender python scripts
This commit is contained in:
parent
73185fc32c
commit
8e89d7efd0
|
@ -0,0 +1,29 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <BlenderConnection.hpp>
|
||||||
|
#include "BlenderSupport.hpp"
|
||||||
|
|
||||||
|
extern "C" uint8_t RETRO_MASTER_SHADER[];
|
||||||
|
extern "C" size_t RETRO_MASTER_SHADER_SZ;
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace Blender
|
||||||
|
{
|
||||||
|
|
||||||
|
bool BuildMasterShader(const HECL::ProjectPath& path)
|
||||||
|
{
|
||||||
|
if (path.getPathType() == HECL::ProjectPath::PT_FILE)
|
||||||
|
return true;
|
||||||
|
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
||||||
|
if (!conn.createBlend(path.getAbsolutePath()))
|
||||||
|
return false;
|
||||||
|
{
|
||||||
|
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut();
|
||||||
|
os << RETRO_MASTER_SHADER;
|
||||||
|
os << "make_master_shader_library()\n";
|
||||||
|
}
|
||||||
|
return conn.saveBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef _RETRO_BLENDER_SUPPORT_HPP_
|
||||||
|
#define _RETRO_BLENDER_SUPPORT_HPP_
|
||||||
|
|
||||||
|
#include <HECL/HECL.hpp>
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace Blender
|
||||||
|
{
|
||||||
|
|
||||||
|
bool BuildMasterShader(const HECL::ProjectPath& path);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _RETRO_BLENDER_SUPPORT_HPP_
|
|
@ -0,0 +1,419 @@
|
||||||
|
"Defines a node group for all game shaders to provide individual outputs to"
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
# UV modifier nodes:
|
||||||
|
# http://www.metroid2002.com/retromodding/wiki/Materials_(Metroid_Prime)#UV_Animations
|
||||||
|
|
||||||
|
# 0 - Modelview Inverse (zero translation)
|
||||||
|
def make_uvm0():
|
||||||
|
new_grp = bpy.data.node_groups.new('RWKUVMode0Node', 'ShaderNodeTree')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||||
|
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-100, 0)
|
||||||
|
|
||||||
|
# Group outputs
|
||||||
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
|
grp_out.location = (500, 0)
|
||||||
|
|
||||||
|
# UV vertical-flip (to match GameCube's UV-coordinate space)
|
||||||
|
v_flip = new_grp.nodes.new('ShaderNodeMapping')
|
||||||
|
v_flip.location = (100, 0)
|
||||||
|
v_flip.vector_type = 'TEXTURE'
|
||||||
|
v_flip.scale[1] = -1.0
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs[0], v_flip.inputs[0])
|
||||||
|
new_grp.links.new(v_flip.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
|
# 1 - Modelview Inverse
|
||||||
|
def make_uvm1():
|
||||||
|
new_grp = bpy.data.node_groups.new('RWKUVMode1Node', 'ShaderNodeTree')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||||
|
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-300, 0)
|
||||||
|
|
||||||
|
# Group outputs
|
||||||
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
|
grp_out.location = (500, 0)
|
||||||
|
|
||||||
|
# Geometry input
|
||||||
|
geom_in = new_grp.nodes.new('ShaderNodeGeometry')
|
||||||
|
geom_in.location = (-700, 0)
|
||||||
|
|
||||||
|
# View flip
|
||||||
|
view_flip = new_grp.nodes.new('ShaderNodeMapping')
|
||||||
|
view_flip.location = (-500, -100)
|
||||||
|
view_flip.vector_type = 'TEXTURE'
|
||||||
|
view_flip.scale = (-1.0, -1.0, 1.0)
|
||||||
|
|
||||||
|
# Normal/translation add
|
||||||
|
adder = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
|
adder.location = (-100, 0)
|
||||||
|
adder.operation = 'ADD'
|
||||||
|
|
||||||
|
# UV vertical-flip (to match GameCube's UV-coordinate space)
|
||||||
|
v_flip = new_grp.nodes.new('ShaderNodeMapping')
|
||||||
|
v_flip.location = (100, 0)
|
||||||
|
v_flip.vector_type = 'TEXTURE'
|
||||||
|
v_flip.scale[1] = -1.0
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs[0], adder.inputs[0])
|
||||||
|
new_grp.links.new(geom_in.outputs['View'], view_flip.inputs[0])
|
||||||
|
new_grp.links.new(view_flip.outputs[0], adder.inputs[1])
|
||||||
|
new_grp.links.new(adder.outputs[0], v_flip.inputs[0])
|
||||||
|
new_grp.links.new(v_flip.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
|
# 2 - UV Scroll
|
||||||
|
def make_uvm2():
|
||||||
|
new_grp = bpy.data.node_groups.new('RWKUVMode2Node', 'ShaderNodeTree')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'Offset')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'Scale')
|
||||||
|
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-100, 0)
|
||||||
|
|
||||||
|
# Group outputs
|
||||||
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
|
grp_out.location = (500, 0)
|
||||||
|
|
||||||
|
# Adder1
|
||||||
|
adder1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
|
adder1.operation = 'ADD'
|
||||||
|
adder1.location = (100, 0)
|
||||||
|
|
||||||
|
# Adder2
|
||||||
|
adder2 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
|
adder2.operation = 'ADD'
|
||||||
|
adder2.location = (100, 200)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs[0], adder2.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs[1], adder1.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs[2], adder1.inputs[1])
|
||||||
|
new_grp.links.new(adder1.outputs[0], adder2.inputs[1])
|
||||||
|
new_grp.links.new(adder2.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
|
# 3 - Rotation
|
||||||
|
def make_uvm3():
|
||||||
|
new_grp = bpy.data.node_groups.new('RWKUVMode3Node', 'ShaderNodeTree')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'Offset')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'Scale')
|
||||||
|
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-100, 0)
|
||||||
|
|
||||||
|
# Group outputs
|
||||||
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
|
grp_out.location = (700, 0)
|
||||||
|
|
||||||
|
# Adder1
|
||||||
|
add1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
add1.operation = 'ADD'
|
||||||
|
add1.location = (500, 0)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs[1], add1.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs[2], add1.inputs[1])
|
||||||
|
|
||||||
|
# 4 - Horizontal Filmstrip Animation
|
||||||
|
def make_uvm4():
|
||||||
|
new_grp = bpy.data.node_groups.new('RWKUVMode4Node', 'ShaderNodeTree')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'Scale')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'NumFrames')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'Step')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'Offset')
|
||||||
|
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-1000, 0)
|
||||||
|
|
||||||
|
# Group outputs
|
||||||
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
|
grp_out.location = (800, 0)
|
||||||
|
|
||||||
|
# Multiply1
|
||||||
|
mult1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult1.operation = 'MULTIPLY'
|
||||||
|
mult1.location = (-800, 0)
|
||||||
|
|
||||||
|
# Multiply2
|
||||||
|
mult2 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult2.operation = 'MULTIPLY'
|
||||||
|
mult2.location = (-600, 0)
|
||||||
|
|
||||||
|
# Modulo
|
||||||
|
mod1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mod1.operation = 'MODULO'
|
||||||
|
mod1.inputs[1].default_value = 1.0
|
||||||
|
mod1.location = (-400, 0)
|
||||||
|
|
||||||
|
# Multiply3
|
||||||
|
mult3 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult3.operation = 'MULTIPLY'
|
||||||
|
mult3.location = (-200, 0)
|
||||||
|
|
||||||
|
# Multiply4
|
||||||
|
mult4 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult4.operation = 'MULTIPLY'
|
||||||
|
mult4.location = (0, 0)
|
||||||
|
|
||||||
|
# Mapping
|
||||||
|
map1 = new_grp.nodes.new('ShaderNodeMapping')
|
||||||
|
map1.scale = (1.0, 0.0, 0.0)
|
||||||
|
map1.location = (200, 0)
|
||||||
|
|
||||||
|
# Add
|
||||||
|
add1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
|
add1.operation = 'ADD'
|
||||||
|
add1.location = (600, 0)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs[0], add1.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[1], mult1.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[2], mult3.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[3], mult4.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[3], mult1.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs[4], mult2.inputs[1])
|
||||||
|
new_grp.links.new(mult1.outputs[0], mult2.inputs[0])
|
||||||
|
new_grp.links.new(mult2.outputs[0], mod1.inputs[0])
|
||||||
|
new_grp.links.new(mod1.outputs[0], mult3.inputs[0])
|
||||||
|
new_grp.links.new(mult3.outputs[0], mult4.inputs[0])
|
||||||
|
new_grp.links.new(mult4.outputs[0], map1.inputs[0])
|
||||||
|
new_grp.links.new(map1.outputs[0], add1.inputs[0])
|
||||||
|
new_grp.links.new(add1.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
|
# 5 - Vertical Filmstrip Animation
|
||||||
|
def make_uvm5():
|
||||||
|
new_grp = bpy.data.node_groups.new('RWKUVMode5Node', 'ShaderNodeTree')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'Scale')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'NumFrames')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'Step')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'Offset')
|
||||||
|
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-1000, 0)
|
||||||
|
|
||||||
|
# Group outputs
|
||||||
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
|
grp_out.location = (800, 0)
|
||||||
|
|
||||||
|
# Multiply1
|
||||||
|
mult1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult1.operation = 'MULTIPLY'
|
||||||
|
mult1.location = (-800, 0)
|
||||||
|
|
||||||
|
# Multiply2
|
||||||
|
mult2 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult2.operation = 'MULTIPLY'
|
||||||
|
mult2.location = (-600, 0)
|
||||||
|
|
||||||
|
# Modulo
|
||||||
|
mod1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mod1.operation = 'MODULO'
|
||||||
|
mod1.inputs[1].default_value = 1.0
|
||||||
|
mod1.location = (-400, 0)
|
||||||
|
|
||||||
|
# Multiply3
|
||||||
|
mult3 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult3.operation = 'MULTIPLY'
|
||||||
|
mult3.location = (-200, 0)
|
||||||
|
|
||||||
|
# Multiply4
|
||||||
|
mult4 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult4.operation = 'MULTIPLY'
|
||||||
|
mult4.location = (0, 0)
|
||||||
|
|
||||||
|
# Mapping
|
||||||
|
map1 = new_grp.nodes.new('ShaderNodeMapping')
|
||||||
|
map1.scale = (0.0, 1.0, 0.0)
|
||||||
|
map1.location = (200, 0)
|
||||||
|
|
||||||
|
# Add
|
||||||
|
add1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
|
add1.operation = 'ADD'
|
||||||
|
add1.location = (600, 0)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs[0], add1.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[1], mult1.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[2], mult3.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[3], mult4.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[3], mult1.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs[4], mult2.inputs[1])
|
||||||
|
new_grp.links.new(mult1.outputs[0], mult2.inputs[0])
|
||||||
|
new_grp.links.new(mult2.outputs[0], mod1.inputs[0])
|
||||||
|
new_grp.links.new(mod1.outputs[0], mult3.inputs[0])
|
||||||
|
new_grp.links.new(mult3.outputs[0], mult4.inputs[0])
|
||||||
|
new_grp.links.new(mult4.outputs[0], map1.inputs[0])
|
||||||
|
new_grp.links.new(map1.outputs[0], add1.inputs[0])
|
||||||
|
new_grp.links.new(add1.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
|
# 6 - Model Matrix
|
||||||
|
def make_uvm6():
|
||||||
|
new_grp = bpy.data.node_groups.new('RWKUVMode6Node', 'ShaderNodeTree')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||||
|
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-100, 0)
|
||||||
|
|
||||||
|
# Group outputs
|
||||||
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
|
grp_out.location = (300, 0)
|
||||||
|
|
||||||
|
# Geometry input
|
||||||
|
geom_in = new_grp.nodes.new('ShaderNodeGeometry')
|
||||||
|
geom_in.location = (-300, 0)
|
||||||
|
|
||||||
|
# Adder1
|
||||||
|
adder1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
|
adder1.operation = 'ADD'
|
||||||
|
adder1.location = (100, 0)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs[0], adder1.inputs[0])
|
||||||
|
new_grp.links.new(geom_in.outputs['Global'], adder1.inputs[1])
|
||||||
|
new_grp.links.new(adder1.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
|
# 7 - Mode Who Must Not Be Named
|
||||||
|
def make_uvm7():
|
||||||
|
new_grp = bpy.data.node_groups.new('RWKUVMode7Node', 'ShaderNodeTree')
|
||||||
|
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'ParamA')
|
||||||
|
new_grp.inputs.new('NodeSocketFloat', 'ParamB')
|
||||||
|
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-800, 0)
|
||||||
|
|
||||||
|
# Group outputs
|
||||||
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
|
grp_out.location = (0, 0)
|
||||||
|
|
||||||
|
# Geometry input
|
||||||
|
geom_in = new_grp.nodes.new('ShaderNodeGeometry')
|
||||||
|
geom_in.location = (-1000, 0)
|
||||||
|
|
||||||
|
# View flip
|
||||||
|
view_flip = new_grp.nodes.new('ShaderNodeMapping')
|
||||||
|
view_flip.location = (-800, -150)
|
||||||
|
view_flip.vector_type = 'TEXTURE'
|
||||||
|
view_flip.scale = (-1.0, -1.0, 1.0)
|
||||||
|
|
||||||
|
# Separate
|
||||||
|
sep1 = new_grp.nodes.new('ShaderNodeSeparateRGB')
|
||||||
|
sep1.location = (-400, -200)
|
||||||
|
|
||||||
|
# Add1
|
||||||
|
add1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
add1.operation = 'ADD'
|
||||||
|
add1.location = (-200, -200)
|
||||||
|
|
||||||
|
# Multiply1
|
||||||
|
mult1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult1.operation = 'MULTIPLY'
|
||||||
|
mult1.inputs[1].default_value = 0.025
|
||||||
|
mult1.location = (0, -200)
|
||||||
|
|
||||||
|
# Multiply2
|
||||||
|
mult2 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult2.operation = 'MULTIPLY'
|
||||||
|
mult2.location = (200, -200)
|
||||||
|
|
||||||
|
# Multiply3
|
||||||
|
mult3 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult3.operation = 'MULTIPLY'
|
||||||
|
mult3.inputs[1].default_value = 0.05
|
||||||
|
mult3.location = (0, -400)
|
||||||
|
|
||||||
|
# Multiply4
|
||||||
|
mult4 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult4.operation = 'MULTIPLY'
|
||||||
|
mult4.location = (200, -400)
|
||||||
|
|
||||||
|
# Combine1
|
||||||
|
comb1 = new_grp.nodes.new('ShaderNodeCombineRGB')
|
||||||
|
comb1.location = (400, -300)
|
||||||
|
|
||||||
|
# Combine2
|
||||||
|
comb2 = new_grp.nodes.new('ShaderNodeCombineRGB')
|
||||||
|
comb2.location = (-600, 0)
|
||||||
|
|
||||||
|
# Multiply5
|
||||||
|
mult5 = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
mult5.blend_type = 'MULTIPLY'
|
||||||
|
mult5.inputs[0].default_value = 1.0
|
||||||
|
mult5.location = (-400, 0)
|
||||||
|
|
||||||
|
# Add2
|
||||||
|
add2 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
|
add2.operation = 'ADD'
|
||||||
|
add2.location = (-200, 0)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs[0], add2.inputs[0])
|
||||||
|
new_grp.links.new(geom_in.outputs['View'], view_flip.inputs[0])
|
||||||
|
new_grp.links.new(view_flip.outputs[0], sep1.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs[1], comb2.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs[1], comb2.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[1], comb2.inputs[2])
|
||||||
|
new_grp.links.new(comb2.outputs[0], mult5.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[2], mult2.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs[2], mult4.inputs[1])
|
||||||
|
new_grp.links.new(sep1.outputs[0], add1.inputs[0])
|
||||||
|
new_grp.links.new(sep1.outputs[1], add1.inputs[1])
|
||||||
|
new_grp.links.new(sep1.outputs[2], mult3.inputs[0])
|
||||||
|
new_grp.links.new(add1.outputs[0], mult1.inputs[0])
|
||||||
|
new_grp.links.new(mult1.outputs[0], mult2.inputs[0])
|
||||||
|
new_grp.links.new(mult2.outputs[0], comb1.inputs[0])
|
||||||
|
new_grp.links.new(mult3.outputs[0], mult4.inputs[0])
|
||||||
|
new_grp.links.new(mult4.outputs[0], comb1.inputs[1])
|
||||||
|
new_grp.links.new(comb1.outputs[0], mult5.inputs[2])
|
||||||
|
new_grp.links.new(mult5.outputs[0], add2.inputs[1])
|
||||||
|
new_grp.links.new(add2.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
|
UV_MODIFIER_GROUPS = [
|
||||||
|
make_uvm0,
|
||||||
|
make_uvm1,
|
||||||
|
make_uvm2,
|
||||||
|
make_uvm3,
|
||||||
|
make_uvm4,
|
||||||
|
make_uvm5,
|
||||||
|
make_uvm6,
|
||||||
|
make_uvm7
|
||||||
|
]
|
||||||
|
|
||||||
|
def make_master_shader_library():
|
||||||
|
for uvm in UV_MODIFIER_GROUPS:
|
||||||
|
uvm()
|
||||||
|
|
|
@ -20,9 +20,16 @@ add_subdirectory(DNAMP1)
|
||||||
add_subdirectory(DNAMP2)
|
add_subdirectory(DNAMP2)
|
||||||
add_subdirectory(DNAMP3)
|
add_subdirectory(DNAMP3)
|
||||||
|
|
||||||
|
# Embed master shader script
|
||||||
|
bintoc(RetroMasterShader.c Blender/RetroMasterShader.py RETRO_MASTER_SHADER)
|
||||||
|
|
||||||
# Each game's DataSpec implementation
|
# Each game's DataSpec implementation
|
||||||
add_library(RetroDataSpec
|
add_library(RetroDataSpec
|
||||||
SpecBase.cpp
|
SpecBase.cpp
|
||||||
SpecMP1.cpp
|
SpecMP1.cpp
|
||||||
SpecMP2.cpp
|
SpecMP2.cpp
|
||||||
SpecMP3.cpp)
|
SpecMP3.cpp
|
||||||
|
Blender/BlenderSupport.hpp
|
||||||
|
Blender/BlenderSupport.cpp
|
||||||
|
Blender/RetroMasterShader.py
|
||||||
|
RetroMasterShader.c)
|
||||||
|
|
|
@ -247,7 +247,8 @@ template <class PAKBRIDGE>
|
||||||
struct ResExtractor
|
struct ResExtractor
|
||||||
{
|
{
|
||||||
std::function<bool(PAKEntryReadStream&, const HECL::ProjectPath&)> func_a;
|
std::function<bool(PAKEntryReadStream&, const HECL::ProjectPath&)> func_a;
|
||||||
std::function<bool(PAKEntryReadStream&, const HECL::ProjectPath&, PAKRouter<PAKBRIDGE>&)> func_b;
|
std::function<bool(PAKEntryReadStream&, const HECL::ProjectPath&, PAKRouter<PAKBRIDGE>&,
|
||||||
|
const typename PAKBRIDGE::PAKType::Entry&)> func_b;
|
||||||
const char* fileExt;
|
const char* fileExt;
|
||||||
unsigned weight;
|
unsigned weight;
|
||||||
};
|
};
|
||||||
|
@ -368,6 +369,43 @@ public:
|
||||||
return HECL::ProjectPath();
|
return HECL::ProjectPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HECL::SystemString getResourceRelativePath(const typename BRIDGETYPE::PAKType::Entry& a,
|
||||||
|
const typename BRIDGETYPE::PAKType::IDType& b) const
|
||||||
|
{
|
||||||
|
if (!m_pak)
|
||||||
|
LogDNACommon.report(LogVisor::FatalError,
|
||||||
|
"PAKRouter::enterPAKBridge() must be called before PAKRouter::getResourceRelativePath()");
|
||||||
|
const typename BRIDGETYPE::PAKType::Entry* be = m_pak->lookupEntry(b);
|
||||||
|
if (!be)
|
||||||
|
return HECL::SystemString();
|
||||||
|
HECL::ProjectPath aPath = getWorking(&a, BRIDGETYPE::LookupExtractor(a));
|
||||||
|
HECL::SystemString ret;
|
||||||
|
for (int i=0 ; i<aPath.levelCount() ; ++i)
|
||||||
|
ret += "../";
|
||||||
|
HECL::ProjectPath bPath = getWorking(be, BRIDGETYPE::LookupExtractor(*be));
|
||||||
|
ret += bPath.getRelativePath();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getBestEntryName(const typename BRIDGETYPE::PAKType::Entry& entry) const
|
||||||
|
{
|
||||||
|
if (!m_pak)
|
||||||
|
LogDNACommon.report(LogVisor::FatalError,
|
||||||
|
"PAKRouter::enterPAKBridge() must be called before PAKRouter::getBestEntryName()");
|
||||||
|
return m_pak->bestEntryName(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getBestEntryName(const typename BRIDGETYPE::PAKType::IDType& entry) const
|
||||||
|
{
|
||||||
|
if (!m_pak)
|
||||||
|
LogDNACommon.report(LogVisor::FatalError,
|
||||||
|
"PAKRouter::enterPAKBridge() must be called before PAKRouter::getBestEntryName()");
|
||||||
|
const typename BRIDGETYPE::PAKType::Entry* e = m_pak->lookupEntry(entry);
|
||||||
|
if (!e)
|
||||||
|
return entry.toString();
|
||||||
|
return m_pak->bestEntryName(*e);
|
||||||
|
}
|
||||||
|
|
||||||
bool extractResources(const BRIDGETYPE& pakBridge, bool force, std::function<void(float)> progress)
|
bool extractResources(const BRIDGETYPE& pakBridge, bool force, std::function<void(float)> progress)
|
||||||
{
|
{
|
||||||
enterPAKBridge(pakBridge);
|
enterPAKBridge(pakBridge);
|
||||||
|
@ -405,7 +443,7 @@ public:
|
||||||
if (force || working.getPathType() == HECL::ProjectPath::PT_NONE)
|
if (force || working.getPathType() == HECL::ProjectPath::PT_NONE)
|
||||||
{
|
{
|
||||||
PAKEntryReadStream s = item.second->beginReadStream(*m_node);
|
PAKEntryReadStream s = item.second->beginReadStream(*m_node);
|
||||||
extractor.func_b(s, working, *this);
|
extractor.func_b(s, working, *this, *item.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,9 @@ namespace DNAMP1
|
||||||
|
|
||||||
bool CMDL::ReadToBlender(HECL::BlenderConnection& conn,
|
bool CMDL::ReadToBlender(HECL::BlenderConnection& conn,
|
||||||
Athena::io::IStreamReader& reader,
|
Athena::io::IStreamReader& reader,
|
||||||
PAKRouter<PAKBridge>& pakRouter)
|
PAKRouter<PAKBridge>& pakRouter,
|
||||||
|
const PAK::Entry& entry)
|
||||||
{
|
{
|
||||||
return true;
|
|
||||||
reader.setEndian(Athena::BigEndian);
|
reader.setEndian(Athena::BigEndian);
|
||||||
|
|
||||||
CMDL::Header head;
|
CMDL::Header head;
|
||||||
|
@ -32,24 +32,104 @@ bool CMDL::ReadToBlender(HECL::BlenderConnection& conn,
|
||||||
|
|
||||||
/* Open Py Stream */
|
/* Open Py Stream */
|
||||||
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut();
|
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut();
|
||||||
os << "import bmesh\n"
|
os << "import bpy\n"
|
||||||
"import bpy\n"
|
"import bmesh\n"
|
||||||
"bm = bmesh.new()\n";
|
"\n"
|
||||||
|
"bpy.context.scene.name = '%s'\n"
|
||||||
|
"bpy.context.scene.rwk_type = 'MESH'\n"
|
||||||
|
"bpy.context.scene.rwk_mesh = 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 RWKOriginalIndex(bpy.types.PropertyGroup):\n"
|
||||||
|
" index = bpy.props.IntProperty(name='Original Vertex Index')\n"
|
||||||
|
"bpy.utils.register_class(RWKOriginalIndex)\n"
|
||||||
|
"bpy.types.Mesh.rwk_orig_verts = bpy.props.CollectionProperty(type=RWKOriginalIndex)\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";
|
||||||
|
|
||||||
|
/* Link master shader library */
|
||||||
|
HECL::ProjectPath selfPath = pakRouter.getWorking(&entry, PAKBridge::LookupExtractor(entry));
|
||||||
|
std::string masterShaderPath;
|
||||||
|
for (int i=0 ; i<selfPath.levelCount() ; ++i)
|
||||||
|
masterShaderPath += "../";
|
||||||
|
masterShaderPath += ".hecl/RetroMasterShader.blend";
|
||||||
|
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.c_str());
|
||||||
|
|
||||||
MaterialSet::RegisterMaterialProps(os);
|
MaterialSet::RegisterMaterialProps(os);
|
||||||
|
|
||||||
for (size_t s=0 ; s<head.secCount ; ++s)
|
for (size_t s=0 ; s<head.secCount ; ++s)
|
||||||
{
|
{
|
||||||
atUint64 secStart = reader.position();
|
atUint64 secStart = reader.position();
|
||||||
|
|
||||||
/*
|
|
||||||
std::unique_ptr<atVec3f[]> vertPos;
|
|
||||||
std::unique_ptr<atVec3f[]> vertNorm;
|
|
||||||
typedef atInt16 ShortVec3[3];
|
|
||||||
std::unique_ptr<ShortVec3[]> vertNormShort;
|
|
||||||
std::unique_ptr<atVec2f[]> vertUVs;
|
|
||||||
typedef atInt16 ShortVec2[2];
|
|
||||||
std::unique_ptr<ShortVec2[]> vertUVsShort;
|
|
||||||
*/
|
|
||||||
std::vector<std::vector<unsigned>> matUVCounts;
|
std::vector<std::vector<unsigned>> matUVCounts;
|
||||||
matUVCounts.reserve(head.matSetCount);
|
matUVCounts.reserve(head.matSetCount);
|
||||||
bool visitedDLOffsets = false;
|
bool visitedDLOffsets = false;
|
||||||
|
@ -62,18 +142,20 @@ bool CMDL::ReadToBlender(HECL::BlenderConnection& conn,
|
||||||
os << "texmap_list = []\n";
|
os << "texmap_list = []\n";
|
||||||
for (const UniqueID32& tex : matSet.head.textureIDs)
|
for (const UniqueID32& tex : matSet.head.textureIDs)
|
||||||
{
|
{
|
||||||
|
std::string texName = pakRouter.getBestEntryName(tex);
|
||||||
|
HECL::SystemString resPath = pakRouter.getResourceRelativePath(entry, tex);
|
||||||
|
HECL::SystemUTF8View resPathView(resPath);
|
||||||
os.format("if '%s' in bpy.data.textures:\n"
|
os.format("if '%s' in bpy.data.textures:\n"
|
||||||
" image = bpy.data.images['%s']\n"
|
" image = bpy.data.images['%s']\n"
|
||||||
" texture = bpy.data.textures[image.name]\n"
|
" texture = bpy.data.textures[image.name]\n"
|
||||||
"else:\n"
|
"else:\n"
|
||||||
" image_path = os.path.relpath('../../%s/textures/%s.png')\n"
|
" image = bpy.data.images.load('//%s')\n"
|
||||||
" print(os.getcwd()+image_path)\n"
|
|
||||||
" image = bpy.data.images.load('//' + image_path)\n"
|
|
||||||
" image.name = '%s'\n"
|
" image.name = '%s'\n"
|
||||||
" texture = bpy.data.textures.new(image.name, 'IMAGE')\n"
|
" texture = bpy.data.textures.new(image.name, 'IMAGE')\n"
|
||||||
" texture.image = image\n"
|
" texture.image = image\n"
|
||||||
"texmap_list.append(texture)\n"
|
"texmap_list.append(texture)\n"
|
||||||
"\n");
|
"\n", texName.c_str(), texName.c_str(),
|
||||||
|
resPathView.str().c_str(), texName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
matUVCounts.emplace_back();
|
matUVCounts.emplace_back();
|
||||||
|
@ -96,10 +178,8 @@ bool CMDL::ReadToBlender(HECL::BlenderConnection& conn,
|
||||||
{
|
{
|
||||||
/* Positions */
|
/* Positions */
|
||||||
size_t vertCount = head.secSizes[s] / 12;
|
size_t vertCount = head.secSizes[s] / 12;
|
||||||
//vertPos.reset(new atVec3f[vertCount]);
|
|
||||||
for (size_t i=0 ; i<vertCount ; ++i)
|
for (size_t i=0 ; i<vertCount ; ++i)
|
||||||
{
|
{
|
||||||
//vertPos[i] = reader.readVec3f();
|
|
||||||
atVec3f pos = reader.readVec3f();
|
atVec3f pos = reader.readVec3f();
|
||||||
os.format("bm.verts.new(co=(%f,%f,%f))\n",
|
os.format("bm.verts.new(co=(%f,%f,%f))\n",
|
||||||
pos.vec[0], pos.vec[1], pos.vec[2]);
|
pos.vec[0], pos.vec[1], pos.vec[2]);
|
||||||
|
@ -113,12 +193,8 @@ bool CMDL::ReadToBlender(HECL::BlenderConnection& conn,
|
||||||
if (head.flags.shortNormals())
|
if (head.flags.shortNormals())
|
||||||
{
|
{
|
||||||
size_t normCount = head.secSizes[s] / 6;
|
size_t normCount = head.secSizes[s] / 6;
|
||||||
//vertNormShort.reset(new ShortVec3[normCount]);
|
|
||||||
for (size_t i=0 ; i<normCount ; ++i)
|
for (size_t i=0 ; i<normCount ; ++i)
|
||||||
{
|
{
|
||||||
//vertNormShort[i][0] = reader.readInt16();
|
|
||||||
//vertNormShort[i][1] = reader.readInt16();
|
|
||||||
//vertNormShort[i][2] = reader.readInt16();
|
|
||||||
os.format("normals.append((%f,%f,%f))\n",
|
os.format("normals.append((%f,%f,%f))\n",
|
||||||
reader.readInt16(), reader.readInt16(), reader.readInt16());
|
reader.readInt16(), reader.readInt16(), reader.readInt16());
|
||||||
}
|
}
|
||||||
|
@ -126,10 +202,8 @@ bool CMDL::ReadToBlender(HECL::BlenderConnection& conn,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t normCount = head.secSizes[s] / 12;
|
size_t normCount = head.secSizes[s] / 12;
|
||||||
//vertNorm.reset(new atVec3f[normCount]);
|
|
||||||
for (size_t i=0 ; i<normCount ; ++i)
|
for (size_t i=0 ; i<normCount ; ++i)
|
||||||
{
|
{
|
||||||
//vertNorm[i] = reader.readVec3f();
|
|
||||||
atVec3f norm = reader.readVec3f();
|
atVec3f norm = reader.readVec3f();
|
||||||
os.format("normals.append((%f,%f,%f))\n",
|
os.format("normals.append((%f,%f,%f))\n",
|
||||||
norm.vec[0], norm.vec[1], norm.vec[2]);
|
norm.vec[0], norm.vec[1], norm.vec[2]);
|
||||||
|
@ -147,10 +221,8 @@ bool CMDL::ReadToBlender(HECL::BlenderConnection& conn,
|
||||||
/* Float UVs */
|
/* Float UVs */
|
||||||
os << "uv_list = []\n";
|
os << "uv_list = []\n";
|
||||||
size_t uvCount = head.secSizes[s] / 8;
|
size_t uvCount = head.secSizes[s] / 8;
|
||||||
//vertUVs.reset(new atVec2f[uvCount]);
|
|
||||||
for (size_t i=0 ; i<uvCount ; ++i)
|
for (size_t i=0 ; i<uvCount ; ++i)
|
||||||
{
|
{
|
||||||
//vertUVs[i] = reader.readVec2f();
|
|
||||||
atVec2f uv = reader.readVec2f();
|
atVec2f uv = reader.readVec2f();
|
||||||
os.format("uv_list.append((%f,%f))\n",
|
os.format("uv_list.append((%f,%f))\n",
|
||||||
uv.vec[0], uv.vec[1]);
|
uv.vec[0], uv.vec[1]);
|
||||||
|
@ -164,7 +236,6 @@ bool CMDL::ReadToBlender(HECL::BlenderConnection& conn,
|
||||||
if (head.flags.shortUVs())
|
if (head.flags.shortUVs())
|
||||||
{
|
{
|
||||||
size_t uvCount = head.secSizes[s] / 4;
|
size_t uvCount = head.secSizes[s] / 4;
|
||||||
//vertUVsShort.reset(new ShortVec2[uvCount]);
|
|
||||||
for (size_t i=0 ; i<uvCount ; ++i)
|
for (size_t i=0 ; i<uvCount ; ++i)
|
||||||
{
|
{
|
||||||
os.format("suv_list.append((%f,%f))\n",
|
os.format("suv_list.append((%f,%f))\n",
|
||||||
|
|
|
@ -51,16 +51,18 @@ struct CMDL
|
||||||
|
|
||||||
static bool ReadToBlender(HECL::BlenderConnection& conn,
|
static bool ReadToBlender(HECL::BlenderConnection& conn,
|
||||||
Athena::io::IStreamReader& reader,
|
Athena::io::IStreamReader& reader,
|
||||||
PAKRouter<PAKBridge>& pakRouter);
|
PAKRouter<PAKBridge>& pakRouter,
|
||||||
|
const PAK::Entry& entry);
|
||||||
|
|
||||||
static bool Extract(PAKEntryReadStream& rs,
|
static bool Extract(PAKEntryReadStream& rs,
|
||||||
const HECL::ProjectPath& outPath,
|
const HECL::ProjectPath& outPath,
|
||||||
PAKRouter<PAKBridge>& pakRouter)
|
PAKRouter<PAKBridge>& pakRouter,
|
||||||
|
const PAK::Entry& entry)
|
||||||
{
|
{
|
||||||
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
||||||
if (!conn.createBlend(outPath.getAbsolutePath()))
|
if (!conn.createBlend(outPath.getAbsolutePath()))
|
||||||
return false;
|
return false;
|
||||||
return ReadToBlender(conn, rs, pakRouter);
|
return ReadToBlender(conn, rs, pakRouter, entry);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -136,11 +136,20 @@ void PAKBridge::build()
|
||||||
}
|
}
|
||||||
if (areaDeps.name.empty())
|
if (areaDeps.name.empty())
|
||||||
{
|
{
|
||||||
|
areaDeps.name = area.internalAreaName;
|
||||||
#if HECL_UCS2
|
#if HECL_UCS2
|
||||||
areaDeps.name = _S("MREA_") + HECL::UTF8ToWide(area.areaMREAId.toString());
|
areaDeps.name = HECL::UTF8ToWide(area.internalAreaName);
|
||||||
#else
|
#else
|
||||||
areaDeps.name = "MREA_" + area.areaMREAId.toString();
|
areaDeps.name = area.internalAreaName;
|
||||||
#endif
|
#endif
|
||||||
|
if (areaDeps.name.empty())
|
||||||
|
{
|
||||||
|
#if HECL_UCS2
|
||||||
|
areaDeps.name = _S("MREA_") + HECL::UTF8ToWide(area.areaMREAId.toString());
|
||||||
|
#else
|
||||||
|
areaDeps.name = "MREA_" + area.areaMREAId.toString();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
areaDeps.layers.reserve(area.depLayerCount-1);
|
areaDeps.layers.reserve(area.depLayerCount-1);
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#include "SpecBase.hpp"
|
#include "SpecBase.hpp"
|
||||||
|
#include "Blender/BlenderSupport.hpp"
|
||||||
|
|
||||||
namespace Retro
|
namespace Retro
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static LogVisor::LogModule Log("Retro::SpecBase");
|
||||||
|
|
||||||
bool SpecBase::canExtract(HECL::Database::Project& project,
|
bool SpecBase::canExtract(HECL::Database::Project& project,
|
||||||
const ExtractPassInfo& info, std::vector<ExtractReport>& reps)
|
const ExtractPassInfo& info, std::vector<ExtractReport>& reps)
|
||||||
{
|
{
|
||||||
|
@ -46,6 +49,8 @@ bool SpecBase::canExtract(HECL::Database::Project& project,
|
||||||
void SpecBase::doExtract(HECL::Database::Project& project, const ExtractPassInfo& info,
|
void SpecBase::doExtract(HECL::Database::Project& project, const ExtractPassInfo& info,
|
||||||
FExtractProgress progress)
|
FExtractProgress progress)
|
||||||
{
|
{
|
||||||
|
if (!Blender::BuildMasterShader(HECL::ProjectPath(project.getProjectRootPath(), ".hecl/RetroMasterShader.blend")))
|
||||||
|
Log.report(LogVisor::FatalError, "Unable to build master shader blend");
|
||||||
if (m_isWii)
|
if (m_isWii)
|
||||||
{
|
{
|
||||||
/* Extract update partition for repacking later */
|
/* Extract update partition for repacking later */
|
||||||
|
|
Loading…
Reference in New Issue