6 Commits

2 changed files with 106 additions and 31 deletions

View File

@@ -107,45 +107,119 @@ to provide an exact emulation"""
def execute(self, context):
material = bpy.data.materials[self.material_name]
material = bpy.data.materials.get(self.material_name, None)
if material and material.swbf_msh_mat:
if not material or not material.swbf_msh_mat:
return {'CANCELLED'}
mat_props = material.swbf_msh_mat
mat_props = material.swbf_msh_mat
diffuse_texture_path = mat_props.diffuse_map
if diffuse_texture_path and os.path.exists(diffuse_texture_path):
material.use_nodes = True
material.node_tree.nodes.clear()
bsdf = material.node_tree.nodes.new("ShaderNodeBsdfPrincipled")
texImage = material.node_tree.nodes.new('ShaderNodeTexImage')
texImage.image = bpy.data.images.load(diffuse_texture_path)
texImage.image.alpha_mode = 'CHANNEL_PACKED'
material.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color'])
texture_input_nodes = []
surface_output_nodes = []
bsdf.inputs["Roughness"].default_value = 1.0
bsdf.inputs["Specular"].default_value = 0.0
if mat_props.hardedged_transparency:
material.blend_method = "CLIP"
material.node_tree.links.new(bsdf.inputs['Alpha'], texImage.outputs['Alpha'])
diffuse_texture_path = mat_props.diffuse_map
if diffuse_texture_path and os.path.exists(diffuse_texture_path):
material.use_backface_culling = not bool(mat_props.doublesided)
material.use_nodes = True
material.node_tree.nodes.clear()
output = material.node_tree.nodes.new("ShaderNodeOutputMaterial")
material.node_tree.links.new(output.inputs['Surface'], bsdf.outputs['BSDF'])
bsdf = material.node_tree.nodes.new("ShaderNodeBsdfPrincipled")
texImage = material.node_tree.nodes.new('ShaderNodeTexImage')
texImage.image = bpy.data.images.load(diffuse_texture_path)
texImage.image.alpha_mode = 'CHANNEL_PACKED'
material.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color'])
texture_input_nodes.append(texImage)
bsdf.inputs["Roughness"].default_value = 1.0
bsdf.inputs["Specular"].default_value = 0.0
if mat_props.hardedged_transparency and not mat_props.glow:
material.blend_method = "CLIP"
material.node_tree.links.new(bsdf.inputs['Alpha'], texImage.outputs['Alpha'])
material.use_backface_culling = not bool(mat_props.doublesided)
surface_output_nodes.append(tuple(('BSDF', bsdf)))
if mat_props.glow:
emission = material.node_tree.nodes.new("ShaderNodeEmission")
material.node_tree.links.new(emission.inputs['Color'], texImage.outputs['Color'])
emission_strength_multiplier = material.node_tree.nodes.new("ShaderNodeMath")
emission_strength_multiplier.operation = 'MULTIPLY'
emission_strength_multiplier.inputs[1].default_value = 32.0
material.node_tree.links.new(emission_strength_multiplier.inputs[0], texImage.outputs['Alpha'])
material.node_tree.links.new(emission.inputs['Strength'], emission_strength_multiplier.outputs[0])
surface_output_nodes.append(tuple(("Emission", emission)))
surfaces_output = None
if (len(surface_output_nodes) == 1):
surfaces_output = surface_output_nodes[0][1]
else:
mix = material.node_tree.nodes.new("ShaderNodeMixShader")
material.node_tree.links.new(mix.inputs[1], surface_output_nodes[0][1].outputs[0])
material.node_tree.links.new(mix.inputs[2], surface_output_nodes[1][1].outputs[0])
# Todo: figure out some way to raise an error but continue operator execution...
if self.fail_silently:
return {'CANCELLED'}
else:
raise RuntimeError(f"Diffuse texture at path: '{diffuse_texture_path}' was not found.")
surfaces_output = mix
output = material.node_tree.nodes.new("ShaderNodeOutputMaterial")
material.node_tree.links.new(output.inputs['Surface'], surfaces_output.outputs[0])
# Clear all anims in all cases
if material.node_tree.animation_data:
material.node_tree.animation_data.action.fcurves.clear()
if "SCROLL" in mat_props.rendertype:
uv_input = material.node_tree.nodes.new("ShaderNodeUVMap")
vector_add = material.node_tree.nodes.new("ShaderNodeVectorMath")
# Add keyframes
scroll_per_sec_divisor = 255.0
frame_step = 60.0
fps = bpy.context.scene.render.fps
for i in range(2):
vector_add.inputs[1].default_value[0] = i * mat_props.scroll_speed_u * frame_step / scroll_per_sec_divisor
vector_add.inputs[1].keyframe_insert("default_value", index=0, frame=i * frame_step * fps)
vector_add.inputs[1].default_value[1] = i * mat_props.scroll_speed_v * frame_step / scroll_per_sec_divisor
vector_add.inputs[1].keyframe_insert("default_value", index=1, frame=i * frame_step * fps)
material.node_tree.links.new(vector_add.inputs[0], uv_input.outputs[0])
for texture_node in texture_input_nodes:
material.node_tree.links.new(texture_node.inputs["Vector"], vector_add.outputs[0])
# Don't know how to set interpolation when adding keyframes
# so we must do it after the fact
if material.node_tree.animation_data:
for fcurve in material.node_tree.animation_data.action.fcurves:
for kf in fcurve.keyframe_points.values():
kf.interpolation = 'LINEAR'
'''
else:
# Todo: figure out some way to raise an error but continue operator execution...
if self.fail_silently:
return {'CANCELLED'}
else:
raise RuntimeError(f"Diffuse texture at path: '{diffuse_texture_path}' was not found.")
'''
return {'FINISHED'}

View File

@@ -2,10 +2,9 @@
import bpy
from typing import Dict
from .msh_material import *
from .msh_material_gather import *
from .msh_material_properties import *
from .msh_material_operators import *
from .msh_material import *
from .msh_material_utilities import _REVERSE_RENDERTYPES_MAPPING
@@ -15,6 +14,8 @@ import os
def find_texture_path(folder_path : str, name : str) -> str:
if not folder_path or not name:
@@ -105,7 +106,7 @@ def _fill_material_props_data(material, material_properties):
anim_length_index = int(sqrt(material.data[0]))
if anim_length_index < 0:
anim_length_index = 0
elif anim_length_index > len(UI_MATERIAL_ANIMATION_LENGTHS):
elif anim_length_index >= len(UI_MATERIAL_ANIMATION_LENGTHS):
anim_length_index = len(UI_MATERIAL_ANIMATION_LENGTHS) - 1
material_properties.animation_length = UI_MATERIAL_ANIMATION_LENGTHS[anim_length_index][0]