mirror of https://github.com/AxioDL/metaforce.git
Initial MP3 Material Support
This commit is contained in:
parent
e6668ec0d3
commit
84531b676f
|
@ -1,13 +1,13 @@
|
|||
"Defines a node group for all game shaders to provide individual outputs to"
|
||||
"Defines node groups implementing shader components found in Retro games"
|
||||
|
||||
import bpy
|
||||
|
||||
# UV modifier nodes:
|
||||
# UV animation 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')
|
||||
def make_uva0():
|
||||
new_grp = bpy.data.node_groups.new('RetroUVMode0Node', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||
new_grp.use_fake_user = True
|
||||
|
@ -31,8 +31,8 @@ def make_uvm0():
|
|||
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')
|
||||
def make_uva1():
|
||||
new_grp = bpy.data.node_groups.new('RetroUVMode1Node', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||
new_grp.use_fake_user = True
|
||||
|
@ -74,8 +74,8 @@ def make_uvm1():
|
|||
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')
|
||||
def make_uva2():
|
||||
new_grp = bpy.data.node_groups.new('RetroUVMode2Node', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||
new_grp.inputs.new('NodeSocketVector', 'Offset')
|
||||
new_grp.inputs.new('NodeSocketVector', 'Scale')
|
||||
|
@ -108,8 +108,8 @@ def make_uvm2():
|
|||
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')
|
||||
def make_uva3():
|
||||
new_grp = bpy.data.node_groups.new('RetroUVMode3Node', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Offset')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Scale')
|
||||
|
@ -135,8 +135,8 @@ def make_uvm3():
|
|||
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')
|
||||
def make_uva4():
|
||||
new_grp = bpy.data.node_groups.new('RetroUVMode4Node', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Scale')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'NumFrames')
|
||||
|
@ -205,8 +205,8 @@ def make_uvm4():
|
|||
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')
|
||||
def make_uva5():
|
||||
new_grp = bpy.data.node_groups.new('RetroUVMode5Node', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Scale')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'NumFrames')
|
||||
|
@ -275,8 +275,8 @@ def make_uvm5():
|
|||
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')
|
||||
def make_uva6():
|
||||
new_grp = bpy.data.node_groups.new('RetroUVMode6Node', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||
new_grp.use_fake_user = True
|
||||
|
@ -304,8 +304,8 @@ def make_uvm6():
|
|||
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')
|
||||
def make_uva7():
|
||||
new_grp = bpy.data.node_groups.new('RetroUVMode7Node', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'ParamA')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'ParamB')
|
||||
|
@ -402,18 +402,402 @@ def make_uvm7():
|
|||
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
|
||||
]
|
||||
UV_ANIMATION_GROUPS = (
|
||||
make_uva0,
|
||||
make_uva1,
|
||||
make_uva2,
|
||||
make_uva3,
|
||||
make_uva4,
|
||||
make_uva5,
|
||||
make_uva6,
|
||||
make_uva7
|
||||
)
|
||||
|
||||
# MP3 / DKCR Material Passes:
|
||||
# http://www.metroid2002.com/retromodding/wiki/Materials_(Metroid_Prime_3)
|
||||
|
||||
# Lightmap
|
||||
def make_pass_diff():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassDIFF', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Multiply1
|
||||
mult1 = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||
mult1.blend_type = 'MULTIPLY'
|
||||
mult1.inputs[0].default_value = 1.0
|
||||
mult1.location = (-600, 0)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], mult1.inputs[1])
|
||||
new_grp.links.new(grp_in.outputs[1], mult1.inputs[2])
|
||||
new_grp.links.new(mult1.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
|
||||
# Rim Lighting Map
|
||||
def make_pass_riml():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassRIML', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# Bloom Lightmap
|
||||
def make_pass_blol():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassBLOL', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# Bloom Diffuse Map
|
||||
def make_pass_blod():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassBLOD', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# Diffuse Map
|
||||
def make_pass_clr():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassCLR', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[2], grp_out.inputs[0])
|
||||
grp_out.inputs[1].default_value = 1.0
|
||||
|
||||
# Opacity Map
|
||||
def make_pass_tran():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassTRAN', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[2], grp_out.inputs[1])
|
||||
|
||||
# Opacity Map Inverted
|
||||
def make_pass_tran_inv():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassTRANInv', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Subtract
|
||||
sub1 = new_grp.nodes.new('ShaderNodeMath')
|
||||
sub1.operation = 'SUBTRACT'
|
||||
sub1.inputs[0].default_value = 1.0
|
||||
sub1.location = (-400, 0)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], sub1.inputs[1])
|
||||
new_grp.links.new(sub1.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[2], grp_out.inputs[1])
|
||||
|
||||
# Incandescence Map
|
||||
def make_pass_inca():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassINCA', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# Reflectivity Map
|
||||
def make_pass_rflv():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassRFLV', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# Reflection Map
|
||||
def make_pass_rfld():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassRFLD', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# Unk1
|
||||
def make_pass_lrld():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassLRLD', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# Unk2
|
||||
def make_pass_lurd():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassLURD', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# Bloom Incandescence Map
|
||||
def make_pass_bloi():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassBLOI', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# X-ray Reflection Map
|
||||
def make_pass_xray():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassXRAY', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
# Unused
|
||||
def make_pass_toon():
|
||||
new_grp = bpy.data.node_groups.new('RetroPassTOON', 'ShaderNodeTree')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Prev Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Prev Alpha')
|
||||
new_grp.inputs.new('NodeSocketColor', 'Tex Color')
|
||||
new_grp.inputs.new('NodeSocketFloat', 'Tex Alpha')
|
||||
new_grp.outputs.new('NodeSocketColor', 'Next Color')
|
||||
new_grp.outputs.new('NodeSocketFloat', 'Next Alpha')
|
||||
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)
|
||||
|
||||
# Links
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
|
||||
MP3_PASS_GROUPS = (
|
||||
make_pass_diff,
|
||||
make_pass_riml,
|
||||
make_pass_blol,
|
||||
make_pass_blod,
|
||||
make_pass_clr,
|
||||
make_pass_tran,
|
||||
make_pass_tran_inv,
|
||||
make_pass_inca,
|
||||
make_pass_rflv,
|
||||
make_pass_rfld,
|
||||
make_pass_lrld,
|
||||
make_pass_lurd,
|
||||
make_pass_bloi,
|
||||
make_pass_xray,
|
||||
make_pass_toon
|
||||
)
|
||||
|
||||
def make_master_shader_library():
|
||||
for uvm in UV_MODIFIER_GROUPS:
|
||||
uvm()
|
||||
for uva in UV_ANIMATION_GROUPS:
|
||||
uva()
|
||||
for aPass in MP3_PASS_GROUPS:
|
||||
aPass()
|
||||
|
||||
|
|
|
@ -120,8 +120,7 @@ void ReadMaterialSetToBlender_1_2(HECL::BlenderConnection::PyOutStream& os,
|
|||
const MaterialSet& matSet,
|
||||
const PAKRouter& pakRouter,
|
||||
const typename PAKRouter::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
unsigned setIdx)
|
||||
{
|
||||
/* Texmaps */
|
||||
os << "texmap_list = []\n";
|
||||
|
@ -134,7 +133,7 @@ void ReadMaterialSetToBlender_1_2(HECL::BlenderConnection::PyOutStream& os,
|
|||
if (txtrPath.getPathType() == HECL::ProjectPath::PT_NONE)
|
||||
{
|
||||
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
|
||||
TXTR::Extract(dataspec, rs, txtrPath);
|
||||
TXTR::Extract(rs, txtrPath);
|
||||
}
|
||||
HECL::SystemString resPath = pakRouter.getResourceRelativePath(entry, tex);
|
||||
HECL::SystemUTF8View resPathView(resPath);
|
||||
|
@ -164,13 +163,12 @@ void ReadMaterialSetToBlender_3(HECL::BlenderConnection::PyOutStream& os,
|
|||
const MaterialSet& matSet,
|
||||
const PAKRouter& pakRouter,
|
||||
const typename PAKRouter::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
unsigned setIdx)
|
||||
{
|
||||
unsigned m=0;
|
||||
for (const typename MaterialSet::Material& mat : matSet.materials)
|
||||
{
|
||||
MaterialSet::ConstructMaterial(os, mat, setIdx, m++);
|
||||
MaterialSet::ConstructMaterial(os, pakRouter, entry, mat, setIdx, m++);
|
||||
os << "materials.append(new_material)\n";
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +321,6 @@ 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,
|
||||
|
@ -345,6 +342,7 @@ atUint32 ReadGeomSectionsToBlender(HECL::BlenderConnection::PyOutStream& os,
|
|||
"\n";
|
||||
|
||||
/* Pre-read pass to determine maximum used vert indices */
|
||||
atUint32 matSecCount = MaterialSet::OneSection() ? 1 : matSetCount;
|
||||
bool visitedDLOffsets = false;
|
||||
atUint32 lastDlSec = secCount;
|
||||
atUint64 afterHeaderPos = reader.position();
|
||||
|
@ -352,7 +350,7 @@ atUint32 ReadGeomSectionsToBlender(HECL::BlenderConnection::PyOutStream& os,
|
|||
for (size_t s=0 ; s<lastDlSec ; ++s)
|
||||
{
|
||||
atUint64 secStart = reader.position();
|
||||
if (s < matSetCount)
|
||||
if (s < matSecCount)
|
||||
{
|
||||
if (!s)
|
||||
{
|
||||
|
@ -363,7 +361,7 @@ atUint32 ReadGeomSectionsToBlender(HECL::BlenderConnection::PyOutStream& os,
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (s-matSetCount)
|
||||
switch (s-matSecCount)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
|
@ -431,17 +429,17 @@ atUint32 ReadGeomSectionsToBlender(HECL::BlenderConnection::PyOutStream& os,
|
|||
for (size_t s=0 ; s<lastDlSec ; ++s)
|
||||
{
|
||||
atUint64 secStart = reader.position();
|
||||
if (s < matSetCount)
|
||||
if (s < matSecCount)
|
||||
{
|
||||
MaterialSet matSet;
|
||||
matSet.read(reader);
|
||||
matSet.readToBlender(os, pakRouter, entry, s, dataspec);
|
||||
matSet.readToBlender(os, pakRouter, entry, s);
|
||||
if (!s)
|
||||
GetVertexAttributes(matSet, vertAttribs);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (s-matSetCount)
|
||||
switch (s-matSecCount)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
|
@ -803,7 +801,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
|||
|
||||
std::vector<VertexAttributes> vertAttribs;
|
||||
ReadGeomSectionsToBlender<PAKRouter, MaterialSet, RIGPAIR>
|
||||
(os, reader, pakRouter, entry, dataspec, rp, head.flags.shortNormals(),
|
||||
(os, reader, pakRouter, entry, rp, head.flags.shortNormals(),
|
||||
head.flags.shortUVs(), vertAttribs, -1,
|
||||
head.secCount, head.matSetCount, head.secSizes.data());
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ class PAKRouter;
|
|||
template <class PAKBRIDGE>
|
||||
struct ResExtractor
|
||||
{
|
||||
std::function<bool(const SpecBase&, PAKEntryReadStream&, const HECL::ProjectPath&)> func_a;
|
||||
std::function<bool(PAKEntryReadStream&, const HECL::ProjectPath&)> func_a;
|
||||
std::function<bool(const SpecBase&, PAKEntryReadStream&, const HECL::ProjectPath&, PAKRouter<PAKBRIDGE>&,
|
||||
const typename PAKBRIDGE::PAKType::Entry&, bool,
|
||||
std::function<void(const HECL::SystemChar*)>)> func_b;
|
||||
|
@ -368,7 +368,7 @@ public:
|
|||
if (force || working.getPathType() == HECL::ProjectPath::PT_NONE)
|
||||
{
|
||||
PAKEntryReadStream s = item.second->beginReadStream(*m_node);
|
||||
extractor.func_a(m_dataSpec, s, working);
|
||||
extractor.func_a(s, working);
|
||||
}
|
||||
}
|
||||
else if (extractor.func_b) /* Needs PAKRouter access */
|
||||
|
|
|
@ -481,7 +481,7 @@ static void PNGWarn(png_structp png, png_const_charp msg)
|
|||
Log.report(LogVisor::Warning, msg);
|
||||
}
|
||||
|
||||
bool TXTR::Extract(const SpecBase& dataspec, PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
bool TXTR::Extract(PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
{
|
||||
uint32_t format = rs.readUint32Big();
|
||||
uint16_t width = rs.readUint16Big();
|
||||
|
|
|
@ -9,7 +9,7 @@ class PAKEntryReadStream;
|
|||
|
||||
struct TXTR
|
||||
{
|
||||
static bool Extract(const SpecBase& dataspec, PAKEntryReadStream& rs, const HECL::ProjectPath& outPath);
|
||||
static bool Extract(PAKEntryReadStream& rs, const HECL::ProjectPath& outPath);
|
||||
static bool Cook(const HECL::ProjectPath& inPath, const HECL::ProjectPath& outPath);
|
||||
};
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Retro
|
|||
{
|
||||
namespace DNAMP1
|
||||
{
|
||||
using Material = MaterialSet::Material;
|
||||
|
||||
void MaterialSet::RegisterMaterialProps(Stream& out)
|
||||
{
|
||||
|
@ -21,7 +22,7 @@ void MaterialSet::RegisterMaterialProps(Stream& out)
|
|||
"\n";
|
||||
}
|
||||
|
||||
static void AddTexture(Stream& out, GX::TexGenSrc type, int mtxIdx, uint32_t texIdx)
|
||||
void Material::AddTexture(Stream& out, GX::TexGenSrc type, int mtxIdx, uint32_t texIdx)
|
||||
{
|
||||
char mtxLabel[64];
|
||||
if (mtxIdx == -1)
|
||||
|
@ -42,14 +43,14 @@ static void AddTexture(Stream& out, GX::TexGenSrc type, int mtxIdx, uint32_t tex
|
|||
"tex_node.location[1] += 176\n", mtxLabel, texIdx);
|
||||
|
||||
if (texIdx != 0xff)
|
||||
out.format("tex_node.texture = tex_maps[%u]\n",
|
||||
texIdx);
|
||||
out.format("tex_node.texture = tex_maps[%u]\n", texIdx);
|
||||
|
||||
if (type == GX::TG_POS)
|
||||
out.format("tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['View'], tex_node.inputs['Vector']))\n");
|
||||
else if (type == GX::TG_NRM)
|
||||
out.format("tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['Normal'], tex_node.inputs['Vector']))\n");
|
||||
else if (type >= GX::TG_TEX0 && type <= GX::TG_TEX7) {
|
||||
else if (type >= GX::TG_TEX0 && type <= GX::TG_TEX7)
|
||||
{
|
||||
uint8_t texIdx = type - GX::TG_TEX0;
|
||||
out.format("tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['UV'], tex_node.inputs['Vector']))\n"
|
||||
"tex_uv_node.uv_layer = 'UV_%u'\n", texIdx);
|
||||
|
@ -59,20 +60,20 @@ static void AddTexture(Stream& out, GX::TexGenSrc type, int mtxIdx, uint32_t tex
|
|||
|
||||
}
|
||||
|
||||
static void AddTextureAnim(Stream& out,
|
||||
MaterialSet::Material::UVAnimation::Mode type,
|
||||
unsigned idx, const float* vals)
|
||||
void Material::AddTextureAnim(Stream& out,
|
||||
UVAnimation::Mode type,
|
||||
unsigned idx, const float* vals)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MaterialSet::Material::UVAnimation::ANIM_MV_INV_NOTRANS:
|
||||
case UVAnimation::ANIM_MV_INV_NOTRANS:
|
||||
out.format("for link in list(tex_links):\n"
|
||||
" if link.from_node.label == 'MTX_%u':\n"
|
||||
" tex_links.remove(link)\n"
|
||||
" soc_from = link.from_socket\n"
|
||||
" soc_to = link.to_socket\n"
|
||||
" node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
|
||||
" node.node_tree = bpy.data.node_groups['RWKUVMode0Node']\n"
|
||||
" node.node_tree = bpy.data.node_groups['RetroUVMode0Node']\n"
|
||||
" node.location[0] = link.from_node.location[0] + 50\n"
|
||||
" node.location[1] = link.from_node.location[1] - 50\n"
|
||||
" new_nodetree.links.remove(link)\n"
|
||||
|
@ -80,14 +81,14 @@ static void AddTextureAnim(Stream& out,
|
|||
" new_nodetree.links.new(node.outputs[0], soc_to)\n\n",
|
||||
idx);
|
||||
break;
|
||||
case MaterialSet::Material::UVAnimation::ANIM_MV_INV:
|
||||
case UVAnimation::ANIM_MV_INV:
|
||||
out.format("for link in list(tex_links):\n"
|
||||
" if link.from_node.label == 'MTX_%u':\n"
|
||||
" tex_links.remove(link)\n"
|
||||
" soc_from = link.from_socket\n"
|
||||
" soc_to = link.to_socket\n"
|
||||
" node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
|
||||
" node.node_tree = bpy.data.node_groups['RWKUVMode1Node']\n"
|
||||
" node.node_tree = bpy.data.node_groups['RetroUVMode1Node']\n"
|
||||
" node.location[0] = link.from_node.location[0] + 50\n"
|
||||
" node.location[1] = link.from_node.location[1] - 50\n"
|
||||
" new_nodetree.links.remove(link)\n"
|
||||
|
@ -95,14 +96,14 @@ static void AddTextureAnim(Stream& out,
|
|||
" new_nodetree.links.new(node.outputs[0], soc_to)\n\n",
|
||||
idx);
|
||||
break;
|
||||
case MaterialSet::Material::UVAnimation::ANIM_SCROLL:
|
||||
case UVAnimation::ANIM_SCROLL:
|
||||
out.format("for link in list(tex_links):\n"
|
||||
" if link.from_node.label == 'MTX_%u':\n"
|
||||
" tex_links.remove(link)\n"
|
||||
" soc_from = link.from_socket\n"
|
||||
" soc_to = link.to_socket\n"
|
||||
" node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
|
||||
" node.node_tree = bpy.data.node_groups['RWKUVMode2Node']\n"
|
||||
" node.node_tree = bpy.data.node_groups['RetroUVMode2Node']\n"
|
||||
" node.location[0] = link.from_node.location[0] + 50\n"
|
||||
" node.location[1] = link.from_node.location[1] - 50\n"
|
||||
" node.inputs[1].default_value = (%f,%f,0)\n"
|
||||
|
@ -112,14 +113,14 @@ static void AddTextureAnim(Stream& out,
|
|||
" new_nodetree.links.new(node.outputs[0], soc_to)\n\n",
|
||||
idx, vals[0], vals[1], vals[2], vals[3]);
|
||||
break;
|
||||
case MaterialSet::Material::UVAnimation::ANIM_ROTATION:
|
||||
case UVAnimation::ANIM_ROTATION:
|
||||
out.format("for link in list(tex_links):\n"
|
||||
" if link.from_node.label == 'MTX_%u':\n"
|
||||
" tex_links.remove(link)\n"
|
||||
" soc_from = link.from_socket\n"
|
||||
" soc_to = link.to_socket\n"
|
||||
" node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
|
||||
" node.node_tree = bpy.data.node_groups['RWKUVMode3Node']\n"
|
||||
" node.node_tree = bpy.data.node_groups['RetroUVMode3Node']\n"
|
||||
" node.location[0] = link.from_node.location[0] + 50\n"
|
||||
" node.location[1] = link.from_node.location[1] - 50\n"
|
||||
" node.inputs[1].default_value = %f\n"
|
||||
|
@ -129,14 +130,14 @@ static void AddTextureAnim(Stream& out,
|
|||
" new_nodetree.links.new(node.outputs[0], soc_to)\n\n",
|
||||
idx, vals[0], vals[1]);
|
||||
break;
|
||||
case MaterialSet::Material::UVAnimation::ANIM_HSTRIP:
|
||||
case UVAnimation::ANIM_HSTRIP:
|
||||
out.format("for link in list(tex_links):\n"
|
||||
" if link.from_node.label == 'MTX_%u':\n"
|
||||
" tex_links.remove(link)\n"
|
||||
" soc_from = link.from_socket\n"
|
||||
" soc_to = link.to_socket\n"
|
||||
" node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
|
||||
" node.node_tree = bpy.data.node_groups['RWKUVMode4Node']\n"
|
||||
" node.node_tree = bpy.data.node_groups['RetroUVMode4Node']\n"
|
||||
" node.location[0] = link.from_node.location[0] + 50\n"
|
||||
" node.location[1] = link.from_node.location[1] - 50\n"
|
||||
" node.inputs[1].default_value = %f\n"
|
||||
|
@ -148,14 +149,14 @@ static void AddTextureAnim(Stream& out,
|
|||
" new_nodetree.links.new(node.outputs[0], soc_to)\n\n",
|
||||
idx, vals[0], vals[1], vals[2], vals[3]);
|
||||
break;
|
||||
case MaterialSet::Material::UVAnimation::ANIM_VSTRIP:
|
||||
case UVAnimation::ANIM_VSTRIP:
|
||||
out.format("for link in list(tex_links):\n"
|
||||
" if link.from_node.label == 'MTX_%u':\n"
|
||||
" tex_links.remove(link)\n"
|
||||
" soc_from = link.from_socket\n"
|
||||
" soc_to = link.to_socket\n"
|
||||
" node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
|
||||
" node.node_tree = bpy.data.node_groups['RWKUVMode5Node']\n"
|
||||
" node.node_tree = bpy.data.node_groups['RetroUVMode5Node']\n"
|
||||
" node.location[0] = link.from_node.location[0] + 50\n"
|
||||
" node.location[1] = link.from_node.location[1] - 50\n"
|
||||
" node.inputs[1].default_value = %f\n"
|
||||
|
@ -167,14 +168,14 @@ static void AddTextureAnim(Stream& out,
|
|||
" new_nodetree.links.new(node.outputs[0], soc_to)\n\n",
|
||||
idx, vals[0], vals[1], vals[3], vals[2]);
|
||||
break;
|
||||
case MaterialSet::Material::UVAnimation::ANIM_MODEL:
|
||||
case UVAnimation::ANIM_MODEL:
|
||||
out.format("for link in list(tex_links):\n"
|
||||
" if link.from_node.label == 'MTX_%u':\n"
|
||||
" tex_links.remove(link)\n"
|
||||
" soc_from = link.from_socket\n"
|
||||
" soc_to = link.to_socket\n"
|
||||
" node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
|
||||
" node.node_tree = bpy.data.node_groups['RWKUVMode6Node']\n"
|
||||
" node.node_tree = bpy.data.node_groups['RetroUVMode6Node']\n"
|
||||
" node.location[0] = link.from_node.location[0] + 50\n"
|
||||
" node.location[1] = link.from_node.location[1] - 50\n"
|
||||
" new_nodetree.links.remove(link)\n"
|
||||
|
@ -182,14 +183,14 @@ static void AddTextureAnim(Stream& out,
|
|||
" new_nodetree.links.new(node.outputs[0], soc_to)\n\n",
|
||||
idx);
|
||||
break;
|
||||
case MaterialSet::Material::UVAnimation::ANIM_MODE_WHO_MUST_NOT_BE_NAMED:
|
||||
case UVAnimation::ANIM_MODE_WHO_MUST_NOT_BE_NAMED:
|
||||
out.format("for link in list(tex_links):\n"
|
||||
" if link.from_node.label == 'MTX_%u':\n"
|
||||
" tex_links.remove(link)\n"
|
||||
" soc_from = link.from_socket\n"
|
||||
" soc_to = link.to_socket\n"
|
||||
" node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
|
||||
" node.node_tree = bpy.data.node_groups['RWKUVMode7Node']\n"
|
||||
" node.node_tree = bpy.data.node_groups['RetroUVMode7Node']\n"
|
||||
" node.location[0] = link.from_node.location[0] + 50\n"
|
||||
" node.location[1] = link.from_node.location[1] - 50\n"
|
||||
" node.inputs[1].default_value = %f\n"
|
||||
|
@ -199,12 +200,11 @@ static void AddTextureAnim(Stream& out,
|
|||
" new_nodetree.links.new(node.outputs[0], soc_to)\n\n",
|
||||
idx, vals[0], vals[1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
static void AddKcolor(Stream& out, const GX::Color& col, unsigned idx)
|
||||
void Material::AddKcolor(Stream& out, const GX::Color& col, unsigned idx)
|
||||
{
|
||||
out.format("# KColor\n"
|
||||
"kc_node = new_nodetree.nodes.new('ShaderNodeRGB')\n"
|
||||
|
@ -227,7 +227,6 @@ static void AddKcolor(Stream& out, const GX::Color& col, unsigned idx)
|
|||
(float)col.b / (float)0xff, (float)col.a / (float)0xff,
|
||||
idx,
|
||||
(float)col.a / (float)0xff);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -250,7 +249,8 @@ static void AddColorCombiner(Stream& out, CombinerType type,
|
|||
else if (type == COMB_MULT)
|
||||
out << "combiner_node.blend_type = 'MULTIPLY'\n";
|
||||
|
||||
if (a) {
|
||||
if (a)
|
||||
{
|
||||
if (!strcmp(a, "ZERO"))
|
||||
out << "combiner_node.inputs['Color1'].default_value = (0.0, 0.0, 0.0, 0.0)\n";
|
||||
else if (!strcmp(a, "HALF"))
|
||||
|
@ -263,7 +263,8 @@ static void AddColorCombiner(Stream& out, CombinerType type,
|
|||
out.format("new_nodetree.links.new(%s, combiner_node.inputs['Color1'])\n", a);
|
||||
}
|
||||
|
||||
if (b) {
|
||||
if (b)
|
||||
{
|
||||
if (!strcmp(b, "ZERO"))
|
||||
out << "combiner_node.inputs['Color2'].default_value = (0.0, 0.0, 0.0, 0.0)\n";
|
||||
else if (!strcmp(b, "HALF"))
|
||||
|
@ -294,7 +295,8 @@ static void AddAlphaCombiner(Stream& out, enum CombinerType type,
|
|||
else if (type == COMB_MULT)
|
||||
out << "combiner_node.operation = 'MULTIPLY'\n";
|
||||
|
||||
if (a) {
|
||||
if (a)
|
||||
{
|
||||
if (!strcmp(a, "ZERO"))
|
||||
out << "combiner_node.inputs[0].default_value = 0.0\n";
|
||||
else if (!strcmp(a, "HALF"))
|
||||
|
@ -305,7 +307,8 @@ static void AddAlphaCombiner(Stream& out, enum CombinerType type,
|
|||
out.format("new_nodetree.links.new(%s, combiner_node.inputs[0])\n", a);
|
||||
}
|
||||
|
||||
if (b) {
|
||||
if (b)
|
||||
{
|
||||
if (!strcmp(b, "ZERO"))
|
||||
out << "combiner_node.inputs[1].default_value = 0.0\n";
|
||||
else if (!strcmp(b, "HALF"))
|
||||
|
@ -332,21 +335,25 @@ static void TranslateColorSocket(char* socketOut, GX::TevColorArg arg,
|
|||
strcpy(socketOut, "HALF");
|
||||
else if (arg == GX::CC_ONE)
|
||||
strcpy(socketOut, "ONE");
|
||||
else if (arg == GX::CC_TEXC) {
|
||||
else if (arg == GX::CC_TEXC)
|
||||
{
|
||||
if (stageTex.tcgSlot == 0xff)
|
||||
strcpy(socketOut, "ONE");
|
||||
else
|
||||
sprintf(socketOut, "texture_nodes[%u].outputs['Color']", stageTex.tcgSlot);
|
||||
} else if (arg == GX::CC_TEXA) {
|
||||
}
|
||||
else if (arg == GX::CC_TEXA) {
|
||||
if (stageTex.tcgSlot == 0xff)
|
||||
strcpy(socketOut, "ONE");
|
||||
else
|
||||
sprintf(socketOut, "texture_nodes[%u].outputs['Value']", stageTex.tcgSlot);
|
||||
} else if (arg == GX::CC_RASC)
|
||||
}
|
||||
else if (arg == GX::CC_RASC)
|
||||
strcpy(socketOut, "material_node.outputs['Color']");
|
||||
else if (arg == GX::CC_RASA) {
|
||||
else if (arg == GX::CC_RASA)
|
||||
strcpy(socketOut, "material_node.outputs['Alpha']");
|
||||
} else if (arg == GX::CC_KONST) {
|
||||
else if (arg == GX::CC_KONST)
|
||||
{
|
||||
int kreg = (kcolor - GX::TEV_KCSEL_K0) % 4;
|
||||
if (kcolor < GX::TEV_KCSEL_K0)
|
||||
strcpy(socketOut, "ONE");
|
||||
|
@ -360,23 +367,23 @@ static void TranslateColorSocket(char* socketOut, GX::TevColorArg arg,
|
|||
strcpy(socketOut, "kcolor_nodes[3][0].outputs[0]");
|
||||
else
|
||||
strcpy(socketOut, "ONE");
|
||||
} else if (arg == GX::CC_CPREV)
|
||||
strcpy(socketOut, c_regs[GX::TEVPREV]);
|
||||
else if (arg == GX::CC_APREV) {
|
||||
strcpy(socketOut, a_regs[GX::TEVPREV]);
|
||||
} else if (arg == GX::CC_C0)
|
||||
strcpy(socketOut, c_regs[GX::TEVREG0]);
|
||||
else if (arg == GX::CC_A0) {
|
||||
strcpy(socketOut, a_regs[GX::TEVREG0]);
|
||||
} else if (arg == GX::CC_C1)
|
||||
strcpy(socketOut, c_regs[GX::TEVREG1]);
|
||||
else if (arg == GX::CC_A1) {
|
||||
strcpy(socketOut, a_regs[GX::TEVREG1]);
|
||||
} else if (arg == GX::CC_C2)
|
||||
strcpy(socketOut, c_regs[GX::TEVREG2]);
|
||||
else if (arg == GX::CC_A2) {
|
||||
strcpy(socketOut, a_regs[GX::TEVREG2]);
|
||||
}
|
||||
else if (arg == GX::CC_CPREV)
|
||||
strcpy(socketOut, c_regs[GX::TEVPREV]);
|
||||
else if (arg == GX::CC_APREV)
|
||||
strcpy(socketOut, a_regs[GX::TEVPREV]);
|
||||
else if (arg == GX::CC_C0)
|
||||
strcpy(socketOut, c_regs[GX::TEVREG0]);
|
||||
else if (arg == GX::CC_A0)
|
||||
strcpy(socketOut, a_regs[GX::TEVREG0]);
|
||||
else if (arg == GX::CC_C1)
|
||||
strcpy(socketOut, c_regs[GX::TEVREG1]);
|
||||
else if (arg == GX::CC_A1)
|
||||
strcpy(socketOut, a_regs[GX::TEVREG1]);
|
||||
else if (arg == GX::CC_C2)
|
||||
strcpy(socketOut, c_regs[GX::TEVREG2]);
|
||||
else if (arg == GX::CC_A2)
|
||||
strcpy(socketOut, a_regs[GX::TEVREG2]);
|
||||
}
|
||||
|
||||
static void TranslateAlphaSocket(char* socketOut, GX::TevAlphaArg arg,
|
||||
|
@ -385,12 +392,14 @@ static void TranslateAlphaSocket(char* socketOut, GX::TevAlphaArg arg,
|
|||
char a_regs[4][64]) {
|
||||
if (arg == GX::CA_ZERO)
|
||||
strcpy(socketOut, "ZERO");
|
||||
else if (arg == GX::CA_TEXA) {
|
||||
else if (arg == GX::CA_TEXA)
|
||||
{
|
||||
if (stageTex.tcgSlot == 0xff)
|
||||
strcpy(socketOut, "ONE");
|
||||
else
|
||||
sprintf(socketOut, "texture_nodes[%u].outputs['Value']", stageTex.tcgSlot);
|
||||
} else if (arg == GX::CA_RASA)
|
||||
}
|
||||
else if (arg == GX::CA_RASA)
|
||||
strcpy(socketOut, "material_node.outputs['Alpha']");
|
||||
else if (arg == GX::CA_KONST) {
|
||||
int kreg = kalpha - GX::TEV_KASEL_K0_A;
|
||||
|
@ -404,7 +413,8 @@ static void TranslateAlphaSocket(char* socketOut, GX::TevAlphaArg arg,
|
|||
strcpy(socketOut, "kcolor_nodes[3][1].outputs[0]");
|
||||
else
|
||||
strcpy(socketOut, "ONE");
|
||||
} else if (arg == GX::CA_APREV)
|
||||
}
|
||||
else if (arg == GX::CA_APREV)
|
||||
strcpy(socketOut, a_regs[GX::TEVPREV]);
|
||||
else if (arg == GX::CA_A0)
|
||||
strcpy(socketOut, a_regs[GX::TEVREG0]);
|
||||
|
@ -512,7 +522,8 @@ static void AddTEVStage(Stream& out, const MaterialSet::Material::TEVStage& stag
|
|||
++a_combiner_idx;
|
||||
}
|
||||
|
||||
if (!(a_tev_opts & 8)) {
|
||||
if (!(a_tev_opts & 8))
|
||||
{
|
||||
/* +D node */
|
||||
AddAlphaCombiner(out, COMB_ADD, "alpha_combiner_nodes[-1].outputs[0]", ad, NULL);
|
||||
++a_combiner_idx;
|
||||
|
@ -523,13 +534,15 @@ static void AddTEVStage(Stream& out, const MaterialSet::Material::TEVStage& stag
|
|||
{
|
||||
if (stage.colorInD() != GX::CC_ZERO)
|
||||
strncpy(c_regs[stage.colorOpOutReg()], cd, 64);
|
||||
} else
|
||||
}
|
||||
else
|
||||
snprintf(c_regs[stage.colorOpOutReg()], 64, "color_combiner_nodes[%u].outputs[0]", c_combiner_idx - 1);
|
||||
if (a_tev_opts == 0xf)
|
||||
{
|
||||
if (stage.alphaInD() != GX::CA_ZERO)
|
||||
strncpy(a_regs[stage.alphaOpOutReg()], ad, 64);
|
||||
} else
|
||||
}
|
||||
else
|
||||
snprintf(a_regs[stage.alphaOpOutReg()], 64, "alpha_combiner_nodes[%u].outputs[0]", a_combiner_idx - 1);
|
||||
|
||||
/* Row Break in gridder */
|
||||
|
@ -600,11 +613,11 @@ void _ConstructMaterial(Stream& out,
|
|||
{
|
||||
unsigned i=0;
|
||||
for (const GX::Color& col : material.konstColors)
|
||||
AddKcolor(out, col, i++);
|
||||
Material::AddKcolor(out, col, i++);
|
||||
}
|
||||
|
||||
/* Blend factors */
|
||||
using BlendFactor = MaterialSet::Material::BlendFactor;
|
||||
using BlendFactor = Material::BlendFactor;
|
||||
if (material.blendDstFac != BlendFactor::GX_BL_ZERO)
|
||||
{
|
||||
if (material.blendDstFac == BlendFactor::GX_BL_ONE)
|
||||
|
@ -620,7 +633,7 @@ void _ConstructMaterial(Stream& out,
|
|||
}
|
||||
|
||||
/* Color channels (for combining dynamic lighting) */
|
||||
for (const MaterialSet::Material::ColorChannel& chan : material.colorChannels)
|
||||
for (const Material::ColorChannel& chan : material.colorChannels)
|
||||
{
|
||||
if (!chan.lighting())
|
||||
out << "new_material.use_shadeless = True\n";
|
||||
|
@ -633,12 +646,12 @@ void _ConstructMaterial(Stream& out,
|
|||
if (material.tevStageTexInfo[i].tcgSlot != 0xff &&
|
||||
!(addedTcgs >> material.tevStageTexInfo[i].tcgSlot & 1))
|
||||
{
|
||||
const MaterialSet::Material::TexCoordGen& tcg = material.tcgs[material.tevStageTexInfo[i].tcgSlot];
|
||||
const Material::TexCoordGen& tcg = material.tcgs[material.tevStageTexInfo[i].tcgSlot];
|
||||
GX::TexMtx mtx = tcg.mtx();
|
||||
int mtxIdx = -1;
|
||||
if (mtx >= GX::TEXMTX0 && mtx <= GX::TEXMTX9)
|
||||
mtxIdx = (mtx - GX::TEXMTX0) / 3;
|
||||
AddTexture(out, tcg.source(), mtxIdx, material.tevStageTexInfo[i].texSlot);
|
||||
Material::AddTexture(out, tcg.source(), mtxIdx, material.tevStageTexInfo[i].texSlot);
|
||||
addedTcgs |= 1 << material.tevStageTexInfo[i].tcgSlot;
|
||||
}
|
||||
}
|
||||
|
@ -667,8 +680,8 @@ void _ConstructMaterial(Stream& out,
|
|||
/* Add TEV stages */
|
||||
for (i=0 ; i<material.tevStageCount ; ++i)
|
||||
{
|
||||
const MaterialSet::Material::TEVStage& stage = material.tevStages[i];
|
||||
const MaterialSet::Material::TEVStageTexInfo& stage_tex = material.tevStageTexInfo[i];
|
||||
const Material::TEVStage& stage = material.tevStages[i];
|
||||
const Material::TEVStageTexInfo& stage_tex = material.tevStageTexInfo[i];
|
||||
AddTEVStage(out, stage, stage_tex, c_regs, a_regs, c_combiner_idx, a_combiner_idx);
|
||||
}
|
||||
|
||||
|
@ -685,8 +698,8 @@ void _ConstructMaterial(Stream& out,
|
|||
|
||||
/* Texmtx Animation Section */
|
||||
i=0;
|
||||
for (const MaterialSet::Material::UVAnimation& anim : material.uvAnims)
|
||||
AddTextureAnim(out, anim.mode, i++, anim.vals);
|
||||
for (const Material::UVAnimation& anim : material.uvAnims)
|
||||
Material::AddTextureAnim(out, anim.mode, i++, anim.vals);
|
||||
}
|
||||
|
||||
void MaterialSet::ConstructMaterial(Stream& out,
|
||||
|
|
|
@ -14,6 +14,8 @@ namespace DNAMP1
|
|||
|
||||
struct MaterialSet : BigDNA
|
||||
{
|
||||
static constexpr bool OneSection() {return false;}
|
||||
|
||||
DECL_DNA
|
||||
struct MaterialSetHead : BigDNA
|
||||
{
|
||||
|
@ -295,6 +297,14 @@ struct MaterialSet : BigDNA
|
|||
}
|
||||
};
|
||||
Vector<UVAnimation, DNA_COUNT(uvAnimsCount)> uvAnims;
|
||||
|
||||
static void AddTexture(HECL::BlenderConnection::PyOutStream& out,
|
||||
GX::TexGenSrc type, int mtxIdx, uint32_t texIdx);
|
||||
static void AddTextureAnim(HECL::BlenderConnection::PyOutStream& out,
|
||||
MaterialSet::Material::UVAnimation::Mode type,
|
||||
unsigned idx, const float* vals);
|
||||
static void AddKcolor(HECL::BlenderConnection::PyOutStream& out,
|
||||
const GX::Color& col, unsigned idx);
|
||||
};
|
||||
Vector<Material, DNA_COUNT(head.materialCount)> materials;
|
||||
|
||||
|
@ -306,10 +316,9 @@ struct MaterialSet : BigDNA
|
|||
void readToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAKRouter<PAKBridge>::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
unsigned setIdx)
|
||||
{
|
||||
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx, dataspec);
|
||||
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ struct MLVL : BigYAML
|
|||
Value<atUint32> layerNameOffsetCount;
|
||||
Vector<atUint32, DNA_COUNT(layerNameOffsetCount)> layerNameOffsets;
|
||||
|
||||
static bool Extract(const SpecBase& dataspec, PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
static bool Extract(PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
{
|
||||
MLVL mlvl;
|
||||
mlvl.read(rs);
|
||||
|
|
|
@ -143,7 +143,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
|
|||
MaterialSet matSet;
|
||||
atUint64 secStart = rs.position();
|
||||
matSet.read(rs);
|
||||
matSet.readToBlender(os, pakRouter, entry, 0, dataSpec);
|
||||
matSet.readToBlender(os, pakRouter, entry, 0);
|
||||
rs.seek(secStart + head.secSizes[0], Athena::Begin);
|
||||
std::vector<DNACMDL::VertexAttributes> vertAttribs;
|
||||
DNACMDL::GetVertexAttributes(matSet, vertAttribs);
|
||||
|
@ -157,7 +157,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
|
|||
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,
|
||||
(os, rs, pakRouter, entry, 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"
|
||||
|
|
|
@ -58,7 +58,7 @@ struct STRG : ISTRG
|
|||
return HECL::SystemString();
|
||||
}
|
||||
|
||||
static bool Extract(const SpecBase&, PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
static bool Extract(PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
{
|
||||
STRG strg;
|
||||
strg.read(rs);
|
||||
|
|
|
@ -14,6 +14,8 @@ namespace DNAMP2
|
|||
/* Structurally identical to DNAMP1::MaterialSet except unk0 and unk1 fields */
|
||||
struct MaterialSet : BigDNA
|
||||
{
|
||||
static constexpr bool OneSection() {return false;}
|
||||
|
||||
DECL_DNA
|
||||
DNAMP1::MaterialSet::MaterialSetHead head;
|
||||
|
||||
|
@ -68,10 +70,9 @@ struct MaterialSet : BigDNA
|
|||
void readToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAKRouter<PAKBridge>::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
unsigned setIdx)
|
||||
{
|
||||
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx, dataspec);
|
||||
DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
|
|||
MaterialSet matSet;
|
||||
atUint64 secStart = drs.position();
|
||||
matSet.read(drs);
|
||||
matSet.readToBlender(os, pakRouter, entry, 0, dataSpec);
|
||||
matSet.readToBlender(os, pakRouter, entry, 0);
|
||||
drs.seek(secStart + head.secSizes[0], Athena::Begin);
|
||||
std::vector<DNACMDL::VertexAttributes> vertAttribs;
|
||||
DNACMDL::GetVertexAttributes(matSet, vertAttribs);
|
||||
|
@ -234,7 +234,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
|
|||
mHeader.read(drs);
|
||||
drs.seek(secStart + head.secSizes[curSec++], Athena::Begin);
|
||||
curSec += DNACMDL::ReadGeomSectionsToBlender<PAKRouter<PAKBridge>, MaterialSet, RigPair>
|
||||
(os, drs, pakRouter, entry, dataSpec, dummy, true,
|
||||
(os, drs, pakRouter, entry, 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"
|
||||
|
|
|
@ -64,7 +64,7 @@ struct STRG : ISTRG
|
|||
return HECL::SystemString();
|
||||
}
|
||||
|
||||
static bool Extract(const SpecBase&, PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
static bool Extract(PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
{
|
||||
STRG strg;
|
||||
strg.read(rs);
|
||||
|
|
|
@ -6,13 +6,263 @@ namespace Retro
|
|||
{
|
||||
namespace DNAMP3
|
||||
{
|
||||
using Material = MaterialSet::Material;
|
||||
|
||||
void MaterialSet::RegisterMaterialProps(Stream& out)
|
||||
{
|
||||
out << "bpy.types.Material.retro_punchthrough_alpha = bpy.props.BoolProperty(name='Retro: Punchthrough Alpha')\n"
|
||||
"bpy.types.Material.retro_shadow_occluder = bpy.props.BoolProperty(name='Retro: Shadow Occluder')\n"
|
||||
"bpy.types.Material.retro_lightmapped = bpy.props.BoolProperty(name='Retro: Lightmapped')\n"
|
||||
"bpy.types.Material.retro_opac = bpy.props.IntProperty(name='Retro: OPAC')\n"
|
||||
"bpy.types.Material.retro_blod = bpy.props.IntProperty(name='Retro: BLOD')\n"
|
||||
"bpy.types.Material.retro_bloi = bpy.props.IntProperty(name='Retro: BLOI')\n"
|
||||
"bpy.types.Material.retro_bnif = bpy.props.IntProperty(name='Retro: BNIF')\n"
|
||||
"bpy.types.Material.retro_xrbr = bpy.props.IntProperty(name='Retro: XRBR')\n"
|
||||
"\n";
|
||||
}
|
||||
|
||||
void MaterialSet::ConstructMaterial(Stream& out,
|
||||
const MaterialSet::Material& material,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
const Material& material,
|
||||
unsigned groupIdx,
|
||||
unsigned matIdx)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
out.format("new_material = bpy.data.materials.new('MAT_%u_%u')\n"
|
||||
"new_material.use_shadows = True\n"
|
||||
"new_material.use_transparent_shadows = True\n"
|
||||
"new_material.diffuse_color = (1.0,1.0,1.0)\n"
|
||||
"new_material.diffuse_intensity = 1.0\n"
|
||||
"new_material.specular_intensity = 0.0\n"
|
||||
"new_material.use_nodes = True\n"
|
||||
"new_nodetree = new_material.node_tree\n"
|
||||
"material_node = new_nodetree.nodes['Material']\n"
|
||||
"final_node = new_nodetree.nodes['Output']\n"
|
||||
"\n"
|
||||
"gridder = hecl.Nodegrid(new_nodetree)\n"
|
||||
"gridder.place_node(final_node, 3)\n"
|
||||
"gridder.place_node(material_node, 0)\n"
|
||||
"material_node.material = new_material\n"
|
||||
"\n"
|
||||
"texture_nodes = []\n"
|
||||
"kcolor_nodes = []\n"
|
||||
"color_combiner_nodes = []\n"
|
||||
"alpha_combiner_nodes = []\n"
|
||||
"tex_links = []\n"
|
||||
"tev_reg_sockets = [None]*4\n"
|
||||
"\n", groupIdx, matIdx);
|
||||
|
||||
/* Material Flags */
|
||||
out.format("new_material.retro_punchthrough_alpha = %s\n"
|
||||
"new_material.retro_shadow_occluder = %s\n"
|
||||
"new_material.game_settings.invisible = %s\n",
|
||||
material.header.flags.punchthroughAlpha() ? "True" : "False",
|
||||
material.header.flags.shadowOccluderMesh() ? "True" : "False",
|
||||
material.header.flags.shadowOccluderMesh() ? "True" : "False");
|
||||
|
||||
|
||||
/* Blend factors */
|
||||
if (material.header.flags.additiveBlending())
|
||||
out << "new_material.game_settings.alpha_blend = 'ADD'\n"
|
||||
"new_material.use_transparency = True\n"
|
||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
||||
"new_material.alpha = 1.0\n";
|
||||
else if (material.header.flags.alphaBlending())
|
||||
out << "new_material.game_settings.alpha_blend = 'ALPHA'\n"
|
||||
"new_material.use_transparency = True\n"
|
||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
||||
"new_material.alpha = 1.0\n";
|
||||
|
||||
/* Texmap list */
|
||||
out << "tex_maps = []\n"
|
||||
"pnode = None\n";
|
||||
|
||||
/* Add PASSes */
|
||||
i=0;
|
||||
unsigned texMapIdx = 0;
|
||||
unsigned texMtxIdx = 0;
|
||||
unsigned kColorIdx = 0;
|
||||
Material::ISection* prevSection = nullptr;
|
||||
for (const Material::SectionFactory& factory : material.sections)
|
||||
{
|
||||
factory.section->constructNode(out, pakRouter, entry, prevSection, i++, texMapIdx, texMtxIdx, kColorIdx);
|
||||
prevSection = factory.section.get();
|
||||
}
|
||||
|
||||
/* Connect final PASS */
|
||||
out << "if pnode:\n"
|
||||
" new_nodetree.links.new(pnode.outputs['Next Color'], final_node.inputs['Color'])\n"
|
||||
" new_nodetree.links.new(pnode.outputs['Next Alpha'], final_node.inputs['Alpha'])\n"
|
||||
"else:\n"
|
||||
" new_nodetree.links.new(kcolor_nodes[-1][0].outputs[0], final_node.inputs['Color'])\n"
|
||||
" new_nodetree.links.new(kcolor_nodes[-1][1].outputs[0], final_node.inputs['Alpha'])\n";
|
||||
}
|
||||
|
||||
void Material::SectionPASS::constructNode(HECL::BlenderConnection::PyOutStream& out,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
const Material::ISection* prevSection,
|
||||
unsigned idx,
|
||||
unsigned& texMapIdx,
|
||||
unsigned& texMtxIdx,
|
||||
unsigned& kColorIdx) const
|
||||
{
|
||||
/* Add Texture nodes */
|
||||
if (txtrId)
|
||||
{
|
||||
std::string texName = pakRouter.getBestEntryName(txtrId);
|
||||
const NOD::DiscBase::IPartition::Node* node;
|
||||
const PAK::Entry* texEntry = pakRouter.lookupEntry(txtrId, &node);
|
||||
HECL::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
|
||||
if (txtrPath.getPathType() == HECL::ProjectPath::PT_NONE)
|
||||
{
|
||||
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
|
||||
TXTR::Extract(rs, txtrPath);
|
||||
}
|
||||
HECL::SystemString resPath = pakRouter.getResourceRelativePath(entry, txtrId);
|
||||
HECL::SystemUTF8View resPathView(resPath);
|
||||
out.format("if '%s' in bpy.data.textures:\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"
|
||||
"tex_maps.append(texture)\n"
|
||||
"\n", texName.c_str(), texName.c_str(),
|
||||
resPathView.str().c_str(), texName.c_str());
|
||||
if (uvAnim.size())
|
||||
{
|
||||
DNAMP1::MaterialSet::Material::AddTexture(out, GX::TexGenSrc(uvSrc), texMtxIdx, texMapIdx++);
|
||||
const UVAnimation& uva = uvAnim[0];
|
||||
DNAMP1::MaterialSet::Material::AddTextureAnim(out, uva.anim.mode, texMtxIdx++, uva.anim.vals);
|
||||
}
|
||||
else
|
||||
DNAMP1::MaterialSet::Material::AddTexture(out, GX::TexGenSrc(uvSrc), -1, texMapIdx++);
|
||||
}
|
||||
|
||||
/* Add PASS node */
|
||||
out << "prev_pnode = pnode\n"
|
||||
"pnode = new_nodetree.nodes.new('ShaderNodeGroup')\n";
|
||||
switch (subtype)
|
||||
{
|
||||
case DIFF:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassDIFF']\n";
|
||||
break;
|
||||
case RIML:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassRIML']\n";
|
||||
break;
|
||||
case BLOL:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassBLOL']\n";
|
||||
break;
|
||||
case BLOD:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassBLOD']\n";
|
||||
break;
|
||||
case CLR:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassCLR']\n";
|
||||
break;
|
||||
case TRAN:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassTRAN']\n";
|
||||
break;
|
||||
case INCA:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassINCA']\n";
|
||||
break;
|
||||
case RFLV:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassRFLV']\n";
|
||||
break;
|
||||
case RFLD:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassRFLD']\n";
|
||||
break;
|
||||
case LRLD:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassLRLD']\n";
|
||||
break;
|
||||
case LURD:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassLURD']\n";
|
||||
break;
|
||||
case BLOI:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassBLOI']\n";
|
||||
break;
|
||||
case XRAY:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassXRAY']\n";
|
||||
break;
|
||||
case TOON:
|
||||
out << "pnode.node_tree = bpy.data.node_groups['RetroPassTOON']\n";
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
out << "gridder.place_node(pnode, 2)\n";
|
||||
|
||||
if (txtrId)
|
||||
{
|
||||
out << "new_nodetree.links.new(texture_nodes[-1].outputs['Color'], pnode.inputs['Tex Color'])\n"
|
||||
"new_nodetree.links.new(texture_nodes[-1].outputs['Value'], pnode.inputs['Tex Alpha'])\n";
|
||||
}
|
||||
|
||||
if (prevSection)
|
||||
{
|
||||
if (prevSection->m_type == ISection::PASS)
|
||||
out << "new_nodetree.links.new(prev_pnode.outputs['Next Color'], pnode.inputs['Prev Color'])\n"
|
||||
"new_nodetree.links.new(prev_pnode.outputs['Next Alpha'], pnode.inputs['Prev Alpha'])\n";
|
||||
else if (prevSection->m_type == ISection::CLR)
|
||||
out << "new_nodetree.links.new(kcolor_nodes[-1][0].outputs[0], pnode.inputs['Prev Color'])\n"
|
||||
"new_nodetree.links.new(kcolor_nodes[-1][1].outputs[0], pnode.inputs['Prev Alpha'])\n";
|
||||
}
|
||||
|
||||
/* Row Break in gridder */
|
||||
out << "gridder.row_break(2)\n";
|
||||
}
|
||||
|
||||
void Material::SectionCLR::constructNode(HECL::BlenderConnection::PyOutStream& out,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
const Material::ISection* prevSection,
|
||||
unsigned idx,
|
||||
unsigned& texMapIdx,
|
||||
unsigned& texMtxIdx,
|
||||
unsigned& kColorIdx) const
|
||||
{
|
||||
DNAMP1::MaterialSet::Material::AddKcolor(out, color, kColorIdx++);
|
||||
switch (subtype)
|
||||
{
|
||||
case DIFB:
|
||||
out << "kc_node.label += ' DIFB'\n"
|
||||
"ka_node.label += ' DIFB'\n";
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void Material::SectionINT::constructNode(HECL::BlenderConnection::PyOutStream& out,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
const Material::ISection* prevSection,
|
||||
unsigned idx,
|
||||
unsigned& texMapIdx,
|
||||
unsigned& texMtxIdx,
|
||||
unsigned& kColorIdx) const
|
||||
{
|
||||
switch (subtype)
|
||||
{
|
||||
case OPAC:
|
||||
out.format("new_material.retro_opac = %d\n", value);
|
||||
break;
|
||||
case BLOD:
|
||||
out.format("new_material.retro_blod = %d\n", value);
|
||||
break;
|
||||
case BLOI:
|
||||
out.format("new_material.retro_bloi = %d\n", value);
|
||||
break;
|
||||
case BNIF:
|
||||
out.format("new_material.retro_bnif = %d\n", value);
|
||||
break;
|
||||
case XRBR:
|
||||
out.format("new_material.retro_xrbr = %d\n", value);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace DNAMP3
|
|||
|
||||
struct MaterialSet : BigDNA
|
||||
{
|
||||
static constexpr bool OneSection() {return true;}
|
||||
|
||||
DECL_DNA
|
||||
Value<atUint32> materialCount;
|
||||
|
||||
|
@ -58,6 +60,14 @@ struct MaterialSet : BigDNA
|
|||
INT = SBIG('INT ')
|
||||
} m_type;
|
||||
ISection(Type type) : m_type(type) {}
|
||||
virtual void constructNode(HECL::BlenderConnection::PyOutStream& out,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
const Material::ISection* prevSection,
|
||||
unsigned idx,
|
||||
unsigned& texMapIdx,
|
||||
unsigned& texMtxIdx,
|
||||
unsigned& kColorIdx) const=0;
|
||||
};
|
||||
struct SectionPASS : ISection
|
||||
{
|
||||
|
@ -86,6 +96,8 @@ struct MaterialSet : BigDNA
|
|||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> flags;
|
||||
bool TRANInvert() const {return (flags & 0x10) != 0;}
|
||||
void setTRANInvert(bool enabled) {flags &= ~0x10; flags |= atUint32(enabled) << 4;}
|
||||
} flags;
|
||||
UniqueID64 txtrId;
|
||||
Value<atUint32> uvSrc;
|
||||
|
@ -98,6 +110,15 @@ struct MaterialSet : BigDNA
|
|||
DNAMP1::MaterialSet::Material::UVAnimation anim;
|
||||
};
|
||||
Vector<UVAnimation, DNA_COUNT(uvAnimSize != 0)> uvAnim;
|
||||
|
||||
void constructNode(HECL::BlenderConnection::PyOutStream& out,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
const Material::ISection* prevSection,
|
||||
unsigned idx,
|
||||
unsigned& texMapIdx,
|
||||
unsigned& texMtxIdx,
|
||||
unsigned& kColorIdx) const;
|
||||
};
|
||||
struct SectionCLR : ISection
|
||||
{
|
||||
|
@ -110,6 +131,15 @@ struct MaterialSet : BigDNA
|
|||
};
|
||||
DNAFourCC subtype;
|
||||
GX::Color color;
|
||||
|
||||
void constructNode(HECL::BlenderConnection::PyOutStream& out,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
const Material::ISection* prevSection,
|
||||
unsigned idx,
|
||||
unsigned& texMapIdx,
|
||||
unsigned& texMtxIdx,
|
||||
unsigned& kColorIdx) const;
|
||||
};
|
||||
struct SectionINT : ISection
|
||||
{
|
||||
|
@ -125,6 +155,15 @@ struct MaterialSet : BigDNA
|
|||
};
|
||||
DNAFourCC subtype;
|
||||
Value<atUint32> value;
|
||||
|
||||
void constructNode(HECL::BlenderConnection::PyOutStream& out,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
const Material::ISection* prevSection,
|
||||
unsigned idx,
|
||||
unsigned& texMapIdx,
|
||||
unsigned& texMtxIdx,
|
||||
unsigned& kColorIdx) const;
|
||||
};
|
||||
struct SectionFactory : BigDNA
|
||||
{
|
||||
|
@ -182,21 +221,19 @@ struct MaterialSet : BigDNA
|
|||
};
|
||||
Vector<Material, DNA_COUNT(materialCount)> materials;
|
||||
|
||||
static void RegisterMaterialProps(HECL::BlenderConnection::PyOutStream& out)
|
||||
{
|
||||
DNAMP1::MaterialSet::RegisterMaterialProps(out);
|
||||
}
|
||||
static void RegisterMaterialProps(HECL::BlenderConnection::PyOutStream& out);
|
||||
static void ConstructMaterial(HECL::BlenderConnection::PyOutStream& out,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAK::Entry& entry,
|
||||
const MaterialSet::Material& material,
|
||||
unsigned groupIdx, unsigned matIdx);
|
||||
|
||||
void readToBlender(HECL::BlenderConnection::PyOutStream& os,
|
||||
const PAKRouter<PAKBridge>& pakRouter,
|
||||
const PAKRouter<PAKBridge>::EntryType& entry,
|
||||
unsigned setIdx,
|
||||
const SpecBase& dataspec)
|
||||
unsigned setIdx)
|
||||
{
|
||||
DNACMDL::ReadMaterialSetToBlender_3(os, *this, pakRouter, entry, setIdx, dataspec);
|
||||
DNACMDL::ReadMaterialSetToBlender_3(os, *this, pakRouter, entry, setIdx);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -71,10 +71,8 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
|||
return {STRG::Extract, nullptr, {_S(".yaml")}};
|
||||
case SBIG('TXTR'):
|
||||
return {TXTR::Extract, nullptr, {_S(".png")}};
|
||||
/*
|
||||
case SBIG('CMDL'):
|
||||
return {nullptr, CMDL::Extract, {_S(".blend")}, 1};
|
||||
*/
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
inline const std::string& getName() const {return m_node.getName();}
|
||||
inline HECL::SystemString getLevelString() const {return m_levelString;}
|
||||
|
||||
typedef PAK PAKType;
|
||||
using PAKType = PAK;
|
||||
inline const PAKType& getPAK() const {return m_pak;}
|
||||
inline const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ struct STRG : ISTRG
|
|||
return HECL::SystemString();
|
||||
}
|
||||
|
||||
static bool Extract(const SpecBase&, PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
static bool Extract(PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||
{
|
||||
std::unique_ptr<ISTRG> strg = LoadSTRG(rs);
|
||||
FILE* fp = HECL::Fopen(outPath.getAbsolutePath().c_str(), _S("wb"));
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit d1392e4dfb5819cfaf4ea3e64ad2a3e348021653
|
||||
Subproject commit 36809b88f9ccaee782e0a4d2a30bbb6f0f88c385
|
Loading…
Reference in New Issue