Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into F3DEX3Preview
Browse files Browse the repository at this point in the history
  • Loading branch information
sauraen committed Jul 19, 2024
2 parents fe96385 + 3ca79e7 commit 89e300b
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 170 deletions.
21 changes: 1 addition & 20 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ def draw(self, context):
prop_split(col, context.scene, "f3d_type", "F3D Microcode")
col.prop(context.scene, "saveTextures")
col.prop(context.scene, "f3d_simple", text="Simple Material UI")
col.prop(context.scene, "generateF3DNodeGraph", text="Generate F3D Node Graph For Materials")
col.prop(context.scene, "exportInlineF3D", text="Bleed and Inline Material Exports")
if context.scene.exportInlineF3D:
multilineLabel(
Expand Down Expand Up @@ -243,22 +242,7 @@ def draw(self, context):
layout = self.layout
if self.done:
layout.label(text="Success!")
box = layout.box()
box.label(text="Materials were successfully upgraded.")
box.label(text="Please purge your remaining materials.")

purge_box = box.box()
purge_box.scale_y = 0.25
purge_box.separator(factor=0.5)
purge_box.label(text="How to purge:")
purge_box.separator(factor=0.5)
purge_box.label(text="Go to the outliner, change the display mode")
purge_box.label(text='to "Orphan Data" (broken heart icon)')
purge_box.separator(factor=0.25)
purge_box.label(text='Click "Purge" in the top right corner.')
purge_box.separator(factor=0.25)
purge_box.label(text="Purge multiple times until the node groups")
purge_box.label(text="are gone.")
layout.label(text="Materials were successfully upgraded.")
layout.separator(factor=0.25)
layout.label(text="You may click anywhere to close this dialog.")
return
Expand All @@ -282,7 +266,6 @@ def execute(self, context: "bpy.types.Context"):

upgradeF3DVersionAll(
[obj for obj in bpy.data.objects if obj.type == "MESH"],
list(bpy.data.armatures),
MatUpdateConvert.version,
)
self.done = True
Expand Down Expand Up @@ -408,7 +391,6 @@ def register():
name="Game", default="SM64", items=gameEditorEnum, update=gameEditorUpdate
)
bpy.types.Scene.saveTextures = bpy.props.BoolProperty(name="Save Textures As PNGs (Breaks CI Textures)")
bpy.types.Scene.generateF3DNodeGraph = bpy.props.BoolProperty(name="Generate F3D Node Graph", default=True)
bpy.types.Scene.exportHiddenGeometry = bpy.props.BoolProperty(name="Export Hidden Geometry", default=True)
bpy.types.Scene.exportInlineF3D = bpy.props.BoolProperty(
name="Bleed and Inline Material Exports",
Expand Down Expand Up @@ -444,7 +426,6 @@ def unregister():
del bpy.types.Scene.ignoreTextureRestrictions
del bpy.types.Scene.saveTextures
del bpy.types.Scene.gameEditorMode
del bpy.types.Scene.generateF3DNodeGraph
del bpy.types.Scene.exportHiddenGeometry
del bpy.types.Scene.blenderF3DScale

Expand Down
151 changes: 93 additions & 58 deletions fast64_internal/f3d/f3d_material.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from .f3d_material_presets import *
from ..utility import *
from ..render_settings import Fast64RenderSettings_Properties, update_scene_props_from_render_settings
from .f3d_material_helpers import F3DMaterial_UpdateLock
from .f3d_material_helpers import F3DMaterial_UpdateLock, node_tree_copy
from bpy.app.handlers import persistent
from typing import Generator, Optional, Tuple, Any, Dict, Union

Expand Down Expand Up @@ -487,9 +487,9 @@ def indentGroup(parent: UILayout, textOrProp: Union[str, "F3DMaterialProperty"],
c.label(text="Fog overrides Light-to-Alpha.", icon="ERROR")
if lightFxPrereq and settings.g_fresnel_alpha and settings.g_lighttoalpha:
c.label(text="Fresnel Alpha overrides Light-to-Alpha.", icon="ERROR")
if shadowMapInShadeAlpha and ccUse["Shade Alpha"]:
if shadowMapInShadeAlpha and ccWarnings and ccUse["Shade Alpha"]:
c.label(text="Shadow map = shade alpha used in CC, probably wrong.", icon="INFO")
if settings.g_fog and ccUse["Shade Alpha"]:
if settings.g_fog and ccWarnings and ccUse["Shade Alpha"]:
c.label(text="Fog = shade alpha used in CC, probably wrong.", icon="INFO")
if blendWarnings and shadeInBlender and not settings.g_fog:
c.label(text="Rendermode uses shade alpha, probably fog.", icon="INFO")
Expand Down Expand Up @@ -1246,6 +1246,15 @@ def draw(self, context):
titleCol = layout.column()
titleCol.box().label(text="F3D Material Inspector")

if material.mat_ver < 5:
box = layout.box().column()
box.label(
text=f"Material version is outdated (V{material.mat_ver})",
icon="ORPHAN_DATA",
)
box.operator("object.convert_f3d_update")
return

presetCol = layout.column()
split = presetCol.split(factor=0.33)
split.label(text="Preset")
Expand Down Expand Up @@ -1275,6 +1284,8 @@ def draw(self, context):
r.enabled = False
r.label(text="Use Cel Shading (requires F3DEX3)", icon="TRIA_RIGHT")

layout.operator(RecreateF3DNodes.bl_idname)


class F3DMeshPanel(Panel):
bl_label = "F3D Mesh Inspector"
Expand Down Expand Up @@ -1395,6 +1406,12 @@ def update_node_values(self, context, update_preset):
material.f3d_mat.presetName = "Custom"


def update_all_node_values(material, context):
update_node_values_without_preset(material, context)
update_tex_values_and_formats(material, context)
update_rendermode_preset(material, context)


def update_node_values_with_preset(self, context):
update_node_values(self, context, update_preset=True)

Expand Down Expand Up @@ -1922,9 +1939,6 @@ def update_tex_values_index(self: Material, *, texProperty: "TextureProperty", t

if tex_size: # only returns tex size if a texture is being set
if tex_size[0] > 0 and tex_size[1] > 0:
if texProperty.autoprop:
setAutoProp(texProperty.S, tex_size[0])
setAutoProp(texProperty.T, tex_size[1])
update_tex_values_field(self, texProperty, tex_size, texIndex)

texFormat = texProperty.tex_format
Expand Down Expand Up @@ -2393,6 +2407,15 @@ def link_f3d_material_library():
bpy.ops.object.mode_set(mode=get_mode_set_from_context_mode(prevMode))


def get_f3d_node_tree() -> bpy.types.NodeTree:
try:
link_f3d_material_library()
mat = bpy.data.materials["fast64_f3d_material_library_beefwashere"]
return mat.node_tree.copy()
finally:
bpy.data.materials.remove(mat)


def shouldConvOrCreateColorAttribute(mesh: Mesh, attr_name="Col"):
has_attr, conv_attr = False, False
if attr_name in mesh.attributes:
Expand Down Expand Up @@ -2559,6 +2582,24 @@ def execute(self, context):
UpdateColorManagementPopup.already_invoked = False


class RecreateF3DNodes(Operator):
bl_idname = "material.recreate_f3d_nodes"
bl_label = "Recreate F3D Shader Nodes"
bl_options = {"REGISTER", "UNDO", "PRESET"}
bl_description = "Recreates the node tree for f3d materials, use if material preview is broken."

def execute(self, context):
material = context.material
if material is None:
self.report({"ERROR"}, "No active material.")
else:
node_tree_copy(get_f3d_node_tree(), material.node_tree)
createScenePropertiesForMaterial(material)
update_all_node_values(material, context)
self.report({"INFO"}, "Success!")
return {"FINISHED"}


class CreateFast3DMaterial(Operator):
bl_idname = "object.create_f3d_mat"
bl_label = "Create Fast3D Material"
Expand Down Expand Up @@ -2620,10 +2661,8 @@ def toggle_auto_prop(self, context: Context):
tex_property, tex_index = get_tex_prop_from_path(material, prop_path)
if tex_property.autoprop:
tex_size = tuple([s for s in tex_property.get_tex_size()])

setAutoProp(tex_property.S, tex_size[0])
setAutoProp(tex_property.T, tex_size[1])
update_tex_values_field(material, tex_property, tex_size, tex_index)
if tex_size[0] > 0 and tex_size[1] > 0:
update_tex_values_field(material, tex_property, tex_size, tex_index)

set_texture_settings_node(material)

Expand Down Expand Up @@ -4019,38 +4058,34 @@ def rna_recursive_attr_expand(value, rna_path_step, level):


def convertToNewMat(material, oldMat):
material.f3d_mat.presetName = oldMat.get("presetName", "Custom")
material.f3d_mat.presetName = oldMat.pop("presetName", "Custom")

material.f3d_mat.scale_autoprop = oldMat.get("scale_autoprop", material.f3d_mat.scale_autoprop)
material.f3d_mat.uv_basis = oldMat.get("uv_basis", material.f3d_mat.uv_basis)
material.f3d_mat.scale_autoprop = oldMat.pop("scale_autoprop", material.f3d_mat.scale_autoprop)
material.f3d_mat.uv_basis = oldMat.pop("uv_basis", material.f3d_mat.uv_basis)

# Combiners
if "combiner1" in oldMat:
recursiveCopyOldPropertyGroup(oldMat["combiner1"], material.f3d_mat.combiner1)
if "combiner2" in oldMat:
recursiveCopyOldPropertyGroup(oldMat["combiner2"], material.f3d_mat.combiner2)
recursiveCopyOldPropertyGroup(oldMat.pop("combiner1", {}), material.f3d_mat.combiner1)
recursiveCopyOldPropertyGroup(oldMat.pop("combiner2", {}), material.f3d_mat.combiner2)

# Texture animation
material.f3d_mat.menu_procAnim = oldMat.get("menu_procAnim", material.f3d_mat.menu_procAnim)
if "UVanim" in oldMat:
recursiveCopyOldPropertyGroup(oldMat["UVanim"], material.f3d_mat.UVanim0)
if "UVanim_tex1" in oldMat:
recursiveCopyOldPropertyGroup(oldMat["UVanim_tex1"], material.f3d_mat.UVanim1)
material.f3d_mat.menu_procAnim = oldMat.pop("menu_procAnim", material.f3d_mat.menu_procAnim)
recursiveCopyOldPropertyGroup(oldMat.pop("UVanim", {}), material.f3d_mat.UVanim0)
recursiveCopyOldPropertyGroup(oldMat.pop("UVanim_tex1", {}), material.f3d_mat.UVanim1)

# material textures
material.f3d_mat.tex_scale = oldMat.get("tex_scale", material.f3d_mat.tex_scale)
recursiveCopyOldPropertyGroup(oldMat["tex0"], material.f3d_mat.tex0)
recursiveCopyOldPropertyGroup(oldMat["tex1"], material.f3d_mat.tex1)
material.f3d_mat.tex_scale = oldMat.pop("tex_scale", material.f3d_mat.tex_scale)
recursiveCopyOldPropertyGroup(oldMat.pop("tex0", {}), material.f3d_mat.tex0)
recursiveCopyOldPropertyGroup(oldMat.pop("tex1", {}), material.f3d_mat.tex1)

# Should Set?
material.f3d_mat.set_prim = oldMat.get("set_prim", material.f3d_mat.set_prim)
material.f3d_mat.set_lights = oldMat.get("set_lights", material.f3d_mat.set_lights)
material.f3d_mat.set_env = oldMat.get("set_env", material.f3d_mat.set_env)
material.f3d_mat.set_blend = oldMat.get("set_blend", material.f3d_mat.set_blend)
material.f3d_mat.set_key = oldMat.get("set_key", material.f3d_mat.set_key)
material.f3d_mat.set_k0_5 = oldMat.get("set_k0_5", material.f3d_mat.set_k0_5)
material.f3d_mat.set_combiner = oldMat.get("set_combiner", material.f3d_mat.set_combiner)
material.f3d_mat.use_default_lighting = oldMat.get("use_default_lighting", material.f3d_mat.use_default_lighting)
material.f3d_mat.set_prim = oldMat.pop("set_prim", material.f3d_mat.set_prim)
material.f3d_mat.set_lights = oldMat.pop("set_lights", material.f3d_mat.set_lights)
material.f3d_mat.set_env = oldMat.pop("set_env", material.f3d_mat.set_env)
material.f3d_mat.set_blend = oldMat.pop("set_blend", material.f3d_mat.set_blend)
material.f3d_mat.set_key = oldMat.pop("set_key", material.f3d_mat.set_key)
material.f3d_mat.set_k0_5 = oldMat.pop("set_k0_5", material.f3d_mat.set_k0_5)
material.f3d_mat.set_combiner = oldMat.pop("set_combiner", material.f3d_mat.set_combiner)
material.f3d_mat.use_default_lighting = oldMat.pop("use_default_lighting", material.f3d_mat.use_default_lighting)

# Colors
nodes = oldMat.node_tree.nodes
Expand All @@ -4062,52 +4097,51 @@ def convertToNewMat(material, oldMat):
prim = nodes["Primitive Color"].outputs[0].default_value
env = nodes["Environment Color"].outputs[0].default_value

material.f3d_mat.blend_color = oldMat.get("blend_color", material.f3d_mat.blend_color)
material.f3d_mat.blend_color = oldMat.pop("blend_color", material.f3d_mat.blend_color)
material.f3d_mat.prim_color = prim
material.f3d_mat.env_color = env
if "Chroma Key Center" in nodes:
material.f3d_mat.key_center = nodes["Chroma Key Center"].outputs[0].default_value

# Chroma
material.f3d_mat.key_scale = oldMat.get("key_scale", material.f3d_mat.key_scale)
material.f3d_mat.key_width = oldMat.get("key_width", material.f3d_mat.key_width)
material.f3d_mat.key_scale = oldMat.pop("key_scale", material.f3d_mat.key_scale)
material.f3d_mat.key_width = oldMat.pop("key_width", material.f3d_mat.key_width)

# Convert
material.f3d_mat.k0 = oldMat.get("k0", material.f3d_mat.k0)
material.f3d_mat.k1 = oldMat.get("k1", material.f3d_mat.k1)
material.f3d_mat.k2 = oldMat.get("k2", material.f3d_mat.k2)
material.f3d_mat.k3 = oldMat.get("k3", material.f3d_mat.k3)
material.f3d_mat.k4 = oldMat.get("k4", material.f3d_mat.k4)
material.f3d_mat.k5 = oldMat.get("k5", material.f3d_mat.k5)
material.f3d_mat.k0 = oldMat.pop("k0", material.f3d_mat.k0)
material.f3d_mat.k1 = oldMat.pop("k1", material.f3d_mat.k1)
material.f3d_mat.k2 = oldMat.pop("k2", material.f3d_mat.k2)
material.f3d_mat.k3 = oldMat.pop("k3", material.f3d_mat.k3)
material.f3d_mat.k4 = oldMat.pop("k4", material.f3d_mat.k4)
material.f3d_mat.k5 = oldMat.pop("k5", material.f3d_mat.k5)

# Prim
material.f3d_mat.prim_lod_frac = oldMat.get("prim_lod_frac", material.f3d_mat.prim_lod_frac)
material.f3d_mat.prim_lod_min = oldMat.get("prim_lod_min", material.f3d_mat.prim_lod_min)
material.f3d_mat.prim_lod_frac = oldMat.pop("prim_lod_frac", material.f3d_mat.prim_lod_frac)
material.f3d_mat.prim_lod_min = oldMat.pop("prim_lod_min", material.f3d_mat.prim_lod_min)

# lights
material.f3d_mat.default_light_color = oldMat.get("default_light_color", material.f3d_mat.default_light_color)
material.f3d_mat.ambient_light_color = oldMat.get("ambient_light_color", material.f3d_mat.ambient_light_color)
material.f3d_mat.default_light_color = oldMat.pop("default_light_color", material.f3d_mat.default_light_color)
material.f3d_mat.ambient_light_color = oldMat.pop("ambient_light_color", material.f3d_mat.ambient_light_color)
for i in range(1, 8):
old_light = oldMat.get(f"f3d_light{str(i)}")
old_light = oldMat.pop(f"f3d_light{str(i)}", None)
# can be a broken property with V1 materials (IDPropertyGroup), thankfully this isnt typical to see when upgrading but
# this method is safer
if type(old_light) is Light:
setattr(material.f3d_mat, f"f3d_light{str(i)}", old_light)

# Fog Properties
material.f3d_mat.fog_color = oldMat.get("fog_color", material.f3d_mat.fog_color)
material.f3d_mat.fog_position = oldMat.get("fog_position", material.f3d_mat.fog_position)
material.f3d_mat.set_fog = oldMat.get("set_fog", material.f3d_mat.set_fog)
material.f3d_mat.use_global_fog = oldMat.get("use_global_fog", material.f3d_mat.use_global_fog)
material.f3d_mat.fog_color = oldMat.pop("fog_color", material.f3d_mat.fog_color)
material.f3d_mat.fog_position = oldMat.pop("fog_position", material.f3d_mat.fog_position)
material.f3d_mat.set_fog = oldMat.pop("set_fog", material.f3d_mat.set_fog)
material.f3d_mat.use_global_fog = oldMat.pop("use_global_fog", material.f3d_mat.use_global_fog)

# geometry mode
material.f3d_mat.menu_geo = oldMat.get("menu_geo", material.f3d_mat.menu_geo)
material.f3d_mat.menu_upper = oldMat.get("menu_upper", material.f3d_mat.menu_upper)
material.f3d_mat.menu_lower = oldMat.get("menu_lower", material.f3d_mat.menu_lower)
material.f3d_mat.menu_other = oldMat.get("menu_other", material.f3d_mat.menu_other)
material.f3d_mat.menu_lower_render = oldMat.get("menu_lower_render", material.f3d_mat.menu_lower_render)
if "rdp_settings" in oldMat:
recursiveCopyOldPropertyGroup(oldMat["rdp_settings"], material.f3d_mat.rdp_settings)
material.f3d_mat.menu_geo = oldMat.pop("menu_geo", material.f3d_mat.menu_geo)
material.f3d_mat.menu_upper = oldMat.pop("menu_upper", material.f3d_mat.menu_upper)
material.f3d_mat.menu_lower = oldMat.pop("menu_lower", material.f3d_mat.menu_lower)
material.f3d_mat.menu_other = oldMat.pop("menu_other", material.f3d_mat.menu_other)
material.f3d_mat.menu_lower_render = oldMat.pop("menu_lower_render", material.f3d_mat.menu_lower_render)
recursiveCopyOldPropertyGroup(oldMat.pop("rdp_settings", {}), material.f3d_mat.rdp_settings)


class F3DMaterialProperty(PropertyGroup):
Expand Down Expand Up @@ -4671,6 +4705,7 @@ def draw_f3d_render_settings(self, context):
AddPresetF3D,
F3DPanel,
CreateFast3DMaterial,
RecreateF3DNodes,
TextureFieldProperty,
SetTileSizeScrollProperty,
TextureProperty,
Expand Down
59 changes: 59 additions & 0 deletions fast64_internal/f3d/f3d_material_helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import bpy
from bpy.types import NodeTree


class F3DMaterial_UpdateLock:
Expand Down Expand Up @@ -34,3 +35,61 @@ def lock_material(self):
def unlock_material(self):
if hasattr(self.material, "f3d_update_flag"):
self.material.f3d_update_flag = False


EXCLUDE_FROM_NODE = (
"rna_type",
"type",
"inputs",
"outputs",
"dimensions",
"interface",
"internal_links",
"texture_mapping",
"color_mapping",
"image_user",
)
EXCLUDE_FROM_INPUT_OUTPUT = (
"rna_type",
"label",
"identifier",
"is_output",
"is_linked",
"is_multi_input",
"node",
"bl_idname",
"default_value",
"is_unavailable",
)


def node_tree_copy(src: NodeTree, dst: NodeTree):
def copy_attributes(src, dst, excludes=None):
fails, excludes = [], excludes if excludes else []
attributes = (attr.identifier for attr in src.bl_rna.properties if attr.identifier not in excludes)
for attr in attributes:
try:
setattr(dst, attr, getattr(src, attr))
except Exception as exc: # pylint: disable=broad-except
fails.append(exc)
if fails:
raise AttributeError("Failed to copy all attributes: " + str(fails))

dst.nodes.clear()
dst.links.clear()

node_mapping = {} # To not have to look up the new node for linking
for src_node in src.nodes: # Copy all nodes
new_node = dst.nodes.new(src_node.bl_idname)
copy_attributes(src_node, new_node, excludes=EXCLUDE_FROM_NODE)
node_mapping[src_node] = new_node
for src_node, dst_node in node_mapping.items():
for i, src_input in enumerate(src_node.inputs): # Link all nodes
for link in src_input.links:
connected_node = dst.nodes[link.from_node.name]
dst.links.new(connected_node.outputs[link.from_socket.name], dst_node.inputs[i])

for src_input, dst_input in zip(src_node.inputs, dst_node.inputs): # Copy all inputs
copy_attributes(src_input, dst_input, excludes=EXCLUDE_FROM_INPUT_OUTPUT)
for src_output, dst_output in zip(src_node.outputs, dst_node.outputs): # Copy all outputs
copy_attributes(src_output, dst_output, excludes=EXCLUDE_FROM_INPUT_OUTPUT)
2 changes: 1 addition & 1 deletion fast64_internal/f3d/f3d_material_presets.py
Original file line number Diff line number Diff line change
Expand Up @@ -2944,7 +2944,7 @@
f3d_mat.combiner1.A_alpha = '0'
f3d_mat.combiner1.B_alpha = '0'
f3d_mat.combiner1.C_alpha = '0'
f3d_mat.combiner1.D_alpha = 'ENVIRONMENT'
f3d_mat.combiner1.D_alpha = 'TEXEL0'
f3d_mat.combiner2.name = ''
f3d_mat.combiner2.A = '0'
f3d_mat.combiner2.B = '0'
Expand Down
Loading

0 comments on commit 89e300b

Please sign in to comment.