mirror of
https://github.com/ApfelTeeSaft/lightspeed64.git
synced 2026-08-26 19:33:24 +00:00
applied black formatting to files changed in the future
This commit is contained in:
+366
-352
@@ -17,440 +17,454 @@ from . import addon_updater_ops
|
||||
|
||||
# info about add on
|
||||
bl_info = {
|
||||
"name": "Fast64",
|
||||
"version": (1, 0, 0),
|
||||
"author": "kurethedead",
|
||||
"location": "3DView",
|
||||
"description": "Plugin for exporting F3D display lists and other game data related to Super Mario 64.",
|
||||
"category": "Import-Export",
|
||||
"blender": (2, 82, 0),
|
||||
}
|
||||
"name": "Fast64",
|
||||
"version": (1, 0, 0),
|
||||
"author": "kurethedead",
|
||||
"location": "3DView",
|
||||
"description": "Plugin for exporting F3D display lists and other game data related to Super Mario 64.",
|
||||
"category": "Import-Export",
|
||||
"blender": (2, 82, 0),
|
||||
}
|
||||
|
||||
gameEditorEnum = (
|
||||
("SM64", "SM64", "Super Mario 64"),
|
||||
("OOT", "OOT", "Ocarina Of Time"),
|
||||
("SM64", "SM64", "Super Mario 64"),
|
||||
("OOT", "OOT", "Ocarina Of Time"),
|
||||
)
|
||||
|
||||
|
||||
class ArmatureApplyWithMesh(bpy.types.Operator):
|
||||
# set bl_ properties
|
||||
bl_description = 'Applies current pose as default pose. Useful for ' + \
|
||||
"rigging an armature that is not in T/A pose. Note that when using " +\
|
||||
" with an SM64 armature, you must revert to the default pose after " +\
|
||||
"skinning."
|
||||
bl_idname = 'object.armature_apply_w_mesh'
|
||||
bl_label = "Apply As Rest Pose"
|
||||
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
|
||||
# set bl_ properties
|
||||
bl_description = (
|
||||
"Applies current pose as default pose. Useful for "
|
||||
+ "rigging an armature that is not in T/A pose. Note that when using "
|
||||
+ " with an SM64 armature, you must revert to the default pose after "
|
||||
+ "skinning."
|
||||
)
|
||||
bl_idname = "object.armature_apply_w_mesh"
|
||||
bl_label = "Apply As Rest Pose"
|
||||
bl_options = {"REGISTER", "UNDO", "PRESET"}
|
||||
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode = "OBJECT")
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != "OBJECT":
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Armature not selected.")
|
||||
elif type(context.selected_objects[0].data) is not\
|
||||
bpy.types.Armature:
|
||||
raise PluginError("Armature not selected.")
|
||||
|
||||
armatureObj = context.selected_objects[0]
|
||||
for child in armatureObj.children:
|
||||
if type(child.data) is not bpy.types.Mesh:
|
||||
continue
|
||||
armatureModifier = None
|
||||
for modifier in child.modifiers:
|
||||
if isinstance(modifier, bpy.types.ArmatureModifier):
|
||||
armatureModifier = modifier
|
||||
if armatureModifier is None:
|
||||
continue
|
||||
print(armatureModifier.name)
|
||||
bpy.ops.object.select_all(action = "DESELECT")
|
||||
context.view_layer.objects.active = child
|
||||
bpy.ops.object.modifier_copy(modifier=armatureModifier.name)
|
||||
print(len(child.modifiers))
|
||||
attemptModifierApply(armatureModifier)
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Armature not selected.")
|
||||
elif type(context.selected_objects[0].data) is not bpy.types.Armature:
|
||||
raise PluginError("Armature not selected.")
|
||||
|
||||
bpy.ops.object.select_all(action = "DESELECT")
|
||||
context.view_layer.objects.active = armatureObj
|
||||
bpy.ops.object.mode_set(mode = "POSE")
|
||||
bpy.ops.pose.armature_apply()
|
||||
if context.mode != 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode = "OBJECT")
|
||||
except Exception as e:
|
||||
if context.mode != 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode = "OBJECT")
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
armatureObj = context.selected_objects[0]
|
||||
for child in armatureObj.children:
|
||||
if type(child.data) is not bpy.types.Mesh:
|
||||
continue
|
||||
armatureModifier = None
|
||||
for modifier in child.modifiers:
|
||||
if isinstance(modifier, bpy.types.ArmatureModifier):
|
||||
armatureModifier = modifier
|
||||
if armatureModifier is None:
|
||||
continue
|
||||
print(armatureModifier.name)
|
||||
bpy.ops.object.select_all(action="DESELECT")
|
||||
context.view_layer.objects.active = child
|
||||
bpy.ops.object.modifier_copy(modifier=armatureModifier.name)
|
||||
print(len(child.modifiers))
|
||||
attemptModifierApply(armatureModifier)
|
||||
|
||||
bpy.ops.object.select_all(action="DESELECT")
|
||||
context.view_layer.objects.active = armatureObj
|
||||
bpy.ops.object.mode_set(mode="POSE")
|
||||
bpy.ops.pose.armature_apply()
|
||||
if context.mode != "OBJECT":
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
except Exception as e:
|
||||
if context.mode != "OBJECT":
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
|
||||
self.report({"INFO"}, "Applied armature with mesh.")
|
||||
return {"FINISHED"} # must return a set
|
||||
|
||||
self.report({'INFO'}, 'Applied armature with mesh.')
|
||||
return {'FINISHED'} # must return a set
|
||||
|
||||
class AddBoneGroups(bpy.types.Operator):
|
||||
# set bl_ properties
|
||||
bl_description = 'Add bone groups respresenting other node types in ' +\
|
||||
'SM64 geolayouts (ex. Shadow, Switch, Function).'
|
||||
bl_idname = 'object.add_bone_groups'
|
||||
bl_label = "Add Bone Groups"
|
||||
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
|
||||
# set bl_ properties
|
||||
bl_description = (
|
||||
"Add bone groups respresenting other node types in " + "SM64 geolayouts (ex. Shadow, Switch, Function)."
|
||||
)
|
||||
bl_idname = "object.add_bone_groups"
|
||||
bl_label = "Add Bone Groups"
|
||||
bl_options = {"REGISTER", "UNDO", "PRESET"}
|
||||
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != 'OBJECT' and context.mode != 'POSE':
|
||||
raise PluginError("Operator can only be used in object or pose mode.")
|
||||
elif context.mode == 'POSE':
|
||||
bpy.ops.object.mode_set(mode = "OBJECT")
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != "OBJECT" and context.mode != "POSE":
|
||||
raise PluginError("Operator can only be used in object or pose mode.")
|
||||
elif context.mode == "POSE":
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Armature not selected.")
|
||||
elif type(context.selected_objects[0].data) is not\
|
||||
bpy.types.Armature:
|
||||
raise PluginError("Armature not selected.")
|
||||
|
||||
armatureObj = context.selected_objects[0]
|
||||
createBoneGroups(armatureObj)
|
||||
except Exception as e:
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Armature not selected.")
|
||||
elif type(context.selected_objects[0].data) is not bpy.types.Armature:
|
||||
raise PluginError("Armature not selected.")
|
||||
|
||||
armatureObj = context.selected_objects[0]
|
||||
createBoneGroups(armatureObj)
|
||||
except Exception as e:
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
|
||||
self.report({"INFO"}, "Created bone groups.")
|
||||
return {"FINISHED"} # must return a set
|
||||
|
||||
self.report({'INFO'}, 'Created bone groups.')
|
||||
return {'FINISHED'} # must return a set
|
||||
|
||||
class CreateMetarig(bpy.types.Operator):
|
||||
# set bl_ properties
|
||||
bl_description = 'SM64 imported armatures are usually not good for ' + \
|
||||
'rigging. There are often intermediate bones between deform bones ' + \
|
||||
'and they don\'t usually point to their children. This operator ' +\
|
||||
'creates a metarig on armature layer 4 useful for IK.'
|
||||
bl_idname = 'object.create_metarig'
|
||||
bl_label = "Create Animatable Metarig"
|
||||
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
|
||||
# set bl_ properties
|
||||
bl_description = (
|
||||
"SM64 imported armatures are usually not good for "
|
||||
+ "rigging. There are often intermediate bones between deform bones "
|
||||
+ "and they don't usually point to their children. This operator "
|
||||
+ "creates a metarig on armature layer 4 useful for IK."
|
||||
)
|
||||
bl_idname = "object.create_metarig"
|
||||
bl_label = "Create Animatable Metarig"
|
||||
bl_options = {"REGISTER", "UNDO", "PRESET"}
|
||||
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode = "OBJECT")
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != "OBJECT":
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Armature not selected.")
|
||||
elif type(context.selected_objects[0].data) is not\
|
||||
bpy.types.Armature:
|
||||
raise PluginError("Armature not selected.")
|
||||
|
||||
armatureObj = context.selected_objects[0]
|
||||
generateMetarig(armatureObj)
|
||||
except Exception as e:
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Armature not selected.")
|
||||
elif type(context.selected_objects[0].data) is not bpy.types.Armature:
|
||||
raise PluginError("Armature not selected.")
|
||||
|
||||
armatureObj = context.selected_objects[0]
|
||||
generateMetarig(armatureObj)
|
||||
except Exception as e:
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
|
||||
self.report({"INFO"}, "Created metarig.")
|
||||
return {"FINISHED"} # must return a set
|
||||
|
||||
self.report({'INFO'}, 'Created metarig.')
|
||||
return {'FINISHED'} # must return a set
|
||||
|
||||
class SM64_AddWaterBox(AddWaterBox):
|
||||
bl_idname = 'object.sm64_add_water_box'
|
||||
bl_idname = "object.sm64_add_water_box"
|
||||
|
||||
scale: bpy.props.FloatProperty(default=10)
|
||||
preset: bpy.props.StringProperty(default="Shaded Solid")
|
||||
matName: bpy.props.StringProperty(default="sm64_water_mat")
|
||||
|
||||
def setEmptyType(self, emptyObj):
|
||||
emptyObj.sm64_obj_type = "Water Box"
|
||||
|
||||
scale : bpy.props.FloatProperty(default = 10)
|
||||
preset : bpy.props.StringProperty(default = "Shaded Solid")
|
||||
matName : bpy.props.StringProperty(default = "sm64_water_mat")
|
||||
|
||||
def setEmptyType(self, emptyObj):
|
||||
emptyObj.sm64_obj_type = "Water Box"
|
||||
|
||||
class SM64_ArmatureToolsPanel(SM64_Panel):
|
||||
bl_idname = "SM64_PT_armature_tools"
|
||||
bl_label = "SM64 Tools"
|
||||
bl_idname = "SM64_PT_armature_tools"
|
||||
bl_label = "SM64 Tools"
|
||||
|
||||
# called every frame
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.operator(ArmatureApplyWithMesh.bl_idname)
|
||||
col.operator(AddBoneGroups.bl_idname)
|
||||
col.operator(CreateMetarig.bl_idname)
|
||||
col.operator(SM64_AddWaterBox.bl_idname)
|
||||
|
||||
|
||||
# called every frame
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.operator(ArmatureApplyWithMesh.bl_idname)
|
||||
col.operator(AddBoneGroups.bl_idname)
|
||||
col.operator(CreateMetarig.bl_idname)
|
||||
col.operator(SM64_AddWaterBox.bl_idname)
|
||||
|
||||
class F3D_GlobalSettingsPanel(bpy.types.Panel):
|
||||
bl_idname = "F3D_PT_global_settings"
|
||||
bl_label = "F3D Global Settings"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = 'Fast64'
|
||||
bl_idname = "F3D_PT_global_settings"
|
||||
bl_label = "F3D Global Settings"
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = "UI"
|
||||
bl_category = "Fast64"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
# called every frame
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.scale_y = 1.1 # extra padding
|
||||
prop_split(col, context.scene, "f3d_type", "F3D Microcode")
|
||||
col.prop(context.scene, "isHWv1")
|
||||
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, "decomp_compatible", invert_checkbox=True, text="Homebrew Compatibility")
|
||||
col.prop(context.scene, "ignoreTextureRestrictions")
|
||||
if context.scene.ignoreTextureRestrictions:
|
||||
col.box().label(text="Width/height must be < 1024. Must be RGBA32. Must be png format.")
|
||||
|
||||
# called every frame
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.scale_y = 1.1 # extra padding
|
||||
prop_split(col, context.scene, 'f3d_type', "F3D Microcode")
|
||||
col.prop(context.scene, 'isHWv1')
|
||||
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, 'decomp_compatible', invert_checkbox = True, text = 'Homebrew Compatibility')
|
||||
col.prop(context.scene, 'ignoreTextureRestrictions')
|
||||
if context.scene.ignoreTextureRestrictions:
|
||||
col.box().label(text = "Width/height must be < 1024. Must be RGBA32. Must be png format.")
|
||||
|
||||
class Fast64_GlobalObjectPanel(bpy.types.Panel):
|
||||
bl_label = "Global Object Inspector"
|
||||
bl_idname = "OBJECT_PT_OOT_Global_Object_Inspector"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "object"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
bl_label = "Global Object Inspector"
|
||||
bl_idname = "OBJECT_PT_OOT_Global_Object_Inspector"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "object"
|
||||
bl_options = {"HIDE_HEADER"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.object is not None and context.object.data is None)
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.object is not None and context.object.data is None
|
||||
|
||||
def draw(self, context):
|
||||
box = self.layout
|
||||
prop_split(box, context.scene, "gameEditorMode", "Game")
|
||||
|
||||
def draw(self, context):
|
||||
box = self.layout
|
||||
prop_split(box, context.scene, 'gameEditorMode', "Game")
|
||||
|
||||
class Fast64_GlobalSettingsPanel(bpy.types.Panel):
|
||||
bl_idname = "FAST64_PT_global_settings"
|
||||
bl_label = "Fast64 Global Settings"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = 'Fast64'
|
||||
bl_idname = "FAST64_PT_global_settings"
|
||||
bl_label = "Fast64 Global Settings"
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = "UI"
|
||||
bl_category = "Fast64"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
# called every frame
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.scale_y = 1.1 # extra padding
|
||||
prop_split(col, context.scene, "gameEditorMode", "Game")
|
||||
col.prop(context.scene, "exportHiddenGeometry")
|
||||
col.prop(context.scene, "fullTraceback")
|
||||
prop_split(col, context.scene.fast64.settings, "anim_range_choice", "Anim Range")
|
||||
|
||||
# called every frame
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.scale_y = 1.1 # extra padding
|
||||
prop_split(col, context.scene, 'gameEditorMode', "Game")
|
||||
col.prop(context.scene, 'exportHiddenGeometry')
|
||||
col.prop(context.scene, 'fullTraceback')
|
||||
prop_split(col, context.scene.fast64.settings, 'anim_range_choice', 'Anim Range')
|
||||
|
||||
class Fast64_GlobalToolsPanel(bpy.types.Panel):
|
||||
bl_idname = "FAST64_PT_global_tools"
|
||||
bl_label = "Fast64 Tools"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = 'Fast64'
|
||||
bl_idname = "FAST64_PT_global_tools"
|
||||
bl_label = "Fast64 Tools"
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = "UI"
|
||||
bl_category = "Fast64"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
# called every frame
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.operator(ArmatureApplyWithMesh.bl_idname)
|
||||
# col.operator(CreateMetarig.bl_idname)
|
||||
addon_updater_ops.update_notice_box_ui(self, context)
|
||||
|
||||
# called every frame
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.operator(ArmatureApplyWithMesh.bl_idname)
|
||||
#col.operator(CreateMetarig.bl_idname)
|
||||
addon_updater_ops.update_notice_box_ui(self, context)
|
||||
|
||||
class Fast64Settings_Properties(bpy.types.PropertyGroup):
|
||||
'''Settings affecting exports for all games found in scene.fast64.settings'''
|
||||
version: bpy.props.IntProperty(name="Fast64Settings_Properties Version", default=0)
|
||||
"""Settings affecting exports for all games found in scene.fast64.settings"""
|
||||
|
||||
version: bpy.props.IntProperty(name="Fast64Settings_Properties Version", default=0)
|
||||
|
||||
anim_range_choice: bpy.props.EnumProperty(
|
||||
name="Anim Range",
|
||||
description="What to use to determine what frames of the animation to export",
|
||||
items=[
|
||||
("action", "Action", "Export all frames from the action", 0),
|
||||
(
|
||||
"scene",
|
||||
"Playback",
|
||||
(
|
||||
"Export all frames in the scene's animation preview playback range.\n"
|
||||
"(export frames being played in Blender)"
|
||||
),
|
||||
1,
|
||||
),
|
||||
(
|
||||
"intersect_action_and_scene",
|
||||
"Smart",
|
||||
(
|
||||
"Intersect Action & Scene\n"
|
||||
"Export all frames from the action that are also in the scene playback range.\n"
|
||||
"(export frames being played in Blender that also are part of the action frames)"
|
||||
),
|
||||
2,
|
||||
),
|
||||
],
|
||||
default="intersect_action_and_scene",
|
||||
)
|
||||
|
||||
anim_range_choice: bpy.props.EnumProperty(
|
||||
name="Anim Range",
|
||||
description="What to use to determine what frames of the animation to export",
|
||||
items=[
|
||||
(
|
||||
"action",
|
||||
"Action",
|
||||
"Export all frames from the action",
|
||||
0
|
||||
),
|
||||
(
|
||||
"scene",
|
||||
"Playback",
|
||||
(
|
||||
"Export all frames in the scene's animation preview playback range.\n"
|
||||
"(export frames being played in Blender)"
|
||||
),
|
||||
1,
|
||||
),
|
||||
(
|
||||
"intersect_action_and_scene",
|
||||
"Smart",
|
||||
(
|
||||
"Intersect Action & Scene\n"
|
||||
"Export all frames from the action that are also in the scene playback range.\n"
|
||||
"(export frames being played in Blender that also are part of the action frames)"
|
||||
),
|
||||
2,
|
||||
),
|
||||
],
|
||||
default="intersect_action_and_scene",
|
||||
)
|
||||
|
||||
class Fast64_Properties(bpy.types.PropertyGroup):
|
||||
'''
|
||||
Properties in scene.fast64.
|
||||
All new properties should be children of one of these three property groups.
|
||||
'''
|
||||
sm64: bpy.props.PointerProperty(type=SM64_Properties, name="SM64 Properties")
|
||||
oot: bpy.props.PointerProperty(type=OOT_Properties, name="OOT Properties")
|
||||
settings: bpy.props.PointerProperty(type=Fast64Settings_Properties, name="Fast64 Settings")
|
||||
"""
|
||||
Properties in scene.fast64.
|
||||
All new properties should be children of one of these three property groups.
|
||||
"""
|
||||
|
||||
sm64: bpy.props.PointerProperty(type=SM64_Properties, name="SM64 Properties")
|
||||
oot: bpy.props.PointerProperty(type=OOT_Properties, name="OOT Properties")
|
||||
settings: bpy.props.PointerProperty(type=Fast64Settings_Properties, name="Fast64 Settings")
|
||||
|
||||
|
||||
class Fast64_BoneProperties(bpy.types.PropertyGroup):
|
||||
'''
|
||||
Properties in bone.fast64 (bpy.types.Bone)
|
||||
All new bone properties should be children of this property group.
|
||||
'''
|
||||
sm64: bpy.props.PointerProperty(type=SM64_BoneProperties, name="SM64 Properties")
|
||||
"""
|
||||
Properties in bone.fast64 (bpy.types.Bone)
|
||||
All new bone properties should be children of this property group.
|
||||
"""
|
||||
|
||||
sm64: bpy.props.PointerProperty(type=SM64_BoneProperties, name="SM64 Properties")
|
||||
|
||||
|
||||
class Fast64_ObjectProperties(bpy.types.PropertyGroup):
|
||||
'''
|
||||
Properties in object.fast64 (bpy.types.Object)
|
||||
All new object properties should be children of this property group.
|
||||
'''
|
||||
sm64: bpy.props.PointerProperty(type=SM64_ObjectProperties, name="SM64 Object Properties")
|
||||
oot: bpy.props.PointerProperty(type=OOT_ObjectProperties, name="OOT Object Properties")
|
||||
"""
|
||||
Properties in object.fast64 (bpy.types.Object)
|
||||
All new object properties should be children of this property group.
|
||||
"""
|
||||
|
||||
sm64: bpy.props.PointerProperty(type=SM64_ObjectProperties, name="SM64 Object Properties")
|
||||
oot: bpy.props.PointerProperty(type=OOT_ObjectProperties, name="OOT Object Properties")
|
||||
|
||||
|
||||
#def updateGameEditor(scene, context):
|
||||
# if scene.currentGameEditorMode == 'SM64':
|
||||
# sm64_panel_unregister()
|
||||
# elif scene.currentGameEditorMode == 'Z64':
|
||||
# oot_panel_unregister()
|
||||
# else:
|
||||
# raise PluginError("Unhandled game editor mode " + str(scene.currentGameEditorMode))
|
||||
# def updateGameEditor(scene, context):
|
||||
# if scene.currentGameEditorMode == 'SM64':
|
||||
# sm64_panel_unregister()
|
||||
# elif scene.currentGameEditorMode == 'Z64':
|
||||
# oot_panel_unregister()
|
||||
# else:
|
||||
# raise PluginError("Unhandled game editor mode " + str(scene.currentGameEditorMode))
|
||||
#
|
||||
# if scene.gameEditorMode == 'SM64':
|
||||
# sm64_panel_register()
|
||||
# elif scene.gameEditorMode == 'Z64':
|
||||
# oot_panel_register()
|
||||
# else:
|
||||
# raise PluginError("Unhandled game editor mode " + str(scene.gameEditorMode))
|
||||
# if scene.gameEditorMode == 'SM64':
|
||||
# sm64_panel_register()
|
||||
# elif scene.gameEditorMode == 'Z64':
|
||||
# oot_panel_register()
|
||||
# else:
|
||||
# raise PluginError("Unhandled game editor mode " + str(scene.gameEditorMode))
|
||||
#
|
||||
# scene.currentGameEditorMode = scene.gameEditorMode
|
||||
# scene.currentGameEditorMode = scene.gameEditorMode
|
||||
|
||||
|
||||
class ExampleAddonPreferences(bpy.types.AddonPreferences, addon_updater_ops.AddonUpdaterPreferences):
|
||||
bl_idname = __package__
|
||||
bl_idname = __package__
|
||||
|
||||
def draw(self, context):
|
||||
addon_updater_ops.update_settings_ui(self, context)
|
||||
def draw(self, context):
|
||||
addon_updater_ops.update_settings_ui(self, context)
|
||||
|
||||
|
||||
classes = (
|
||||
Fast64Settings_Properties,
|
||||
Fast64_Properties,
|
||||
Fast64_BoneProperties,
|
||||
Fast64_ObjectProperties,
|
||||
|
||||
ArmatureApplyWithMesh,
|
||||
AddBoneGroups,
|
||||
CreateMetarig,
|
||||
SM64_AddWaterBox,
|
||||
|
||||
#Fast64_GlobalObjectPanel,
|
||||
F3D_GlobalSettingsPanel,
|
||||
Fast64_GlobalSettingsPanel,
|
||||
SM64_ArmatureToolsPanel,
|
||||
Fast64_GlobalToolsPanel,
|
||||
Fast64Settings_Properties,
|
||||
Fast64_Properties,
|
||||
Fast64_BoneProperties,
|
||||
Fast64_ObjectProperties,
|
||||
ArmatureApplyWithMesh,
|
||||
AddBoneGroups,
|
||||
CreateMetarig,
|
||||
SM64_AddWaterBox,
|
||||
# Fast64_GlobalObjectPanel,
|
||||
F3D_GlobalSettingsPanel,
|
||||
Fast64_GlobalSettingsPanel,
|
||||
SM64_ArmatureToolsPanel,
|
||||
Fast64_GlobalToolsPanel,
|
||||
)
|
||||
|
||||
|
||||
def upgrade_changed_props():
|
||||
'''Set scene properties after a scene loads, used for migrating old properties'''
|
||||
SM64_Properties.upgrade_changed_props()
|
||||
SM64_ObjectProperties.upgrade_changed_props()
|
||||
"""Set scene properties after a scene loads, used for migrating old properties"""
|
||||
SM64_Properties.upgrade_changed_props()
|
||||
SM64_ObjectProperties.upgrade_changed_props()
|
||||
|
||||
|
||||
@bpy.app.handlers.persistent
|
||||
def after_load(_a, _b):
|
||||
upgrade_changed_props()
|
||||
upgrade_changed_props()
|
||||
|
||||
|
||||
# called on add-on enabling
|
||||
# register operators and panels here
|
||||
# append menu layout drawing function to an existing window
|
||||
def register():
|
||||
|
||||
if bpy.app.version >= (3, 1, 0):
|
||||
msg = "\n".join(
|
||||
(
|
||||
"This version of Fast64 does not work properly in Blender 3.1.0 and later Blender versions.",
|
||||
"Your Blender version is: " + ".".join(str(i) for i in bpy.app.version),
|
||||
"This is a known issue, the fix is not trivial and is in progress.",
|
||||
"See the GitHub issue: https://github.com/Fast-64/fast64/issues/85",
|
||||
"If it has been resolved, update Fast64.",
|
||||
)
|
||||
)
|
||||
print(msg)
|
||||
blender_3_1_0_and_later_unsupported = Exception("\n\n" + msg)
|
||||
raise blender_3_1_0_and_later_unsupported
|
||||
if bpy.app.version >= (3, 1, 0):
|
||||
msg = "\n".join(
|
||||
(
|
||||
"This version of Fast64 does not work properly in Blender 3.1.0 and later Blender versions.",
|
||||
"Your Blender version is: " + ".".join(str(i) for i in bpy.app.version),
|
||||
"This is a known issue, the fix is not trivial and is in progress.",
|
||||
"See the GitHub issue: https://github.com/Fast-64/fast64/issues/85",
|
||||
"If it has been resolved, update Fast64.",
|
||||
)
|
||||
)
|
||||
print(msg)
|
||||
blender_3_1_0_and_later_unsupported = Exception("\n\n" + msg)
|
||||
raise blender_3_1_0_and_later_unsupported
|
||||
|
||||
# Register addon updater first,
|
||||
# this way if a broken version fails to register the user can still pick another version.
|
||||
register_class(ExampleAddonPreferences)
|
||||
addon_updater_ops.register(bl_info)
|
||||
# Register addon updater first,
|
||||
# this way if a broken version fails to register the user can still pick another version.
|
||||
register_class(ExampleAddonPreferences)
|
||||
addon_updater_ops.register(bl_info)
|
||||
|
||||
mat_register()
|
||||
render_engine_register()
|
||||
bsdf_conv_register()
|
||||
sm64_register(True)
|
||||
oot_register(True)
|
||||
mat_register()
|
||||
render_engine_register()
|
||||
bsdf_conv_register()
|
||||
sm64_register(True)
|
||||
oot_register(True)
|
||||
|
||||
for cls in classes:
|
||||
register_class(cls)
|
||||
for cls in classes:
|
||||
register_class(cls)
|
||||
|
||||
bsdf_conv_panel_regsiter()
|
||||
f3d_writer_register()
|
||||
f3d_parser_register()
|
||||
bsdf_conv_panel_regsiter()
|
||||
f3d_writer_register()
|
||||
f3d_parser_register()
|
||||
|
||||
# ROM
|
||||
|
||||
bpy.types.Scene.decomp_compatible = bpy.props.BoolProperty(
|
||||
name = 'Decomp Compatibility', default = True)
|
||||
bpy.types.Scene.ignoreTextureRestrictions = bpy.props.BoolProperty(
|
||||
name = 'Ignore Texture Restrictions (Breaks CI Textures)')
|
||||
bpy.types.Scene.fullTraceback = \
|
||||
bpy.props.BoolProperty(name = 'Show Full Error Traceback', default = False)
|
||||
bpy.types.Scene.gameEditorMode = bpy.props.EnumProperty(
|
||||
name = 'Game', default = 'SM64', items = gameEditorEnum)
|
||||
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.blenderF3DScale = bpy.props.FloatProperty(name = "F3D Blender Scale", default = 100)
|
||||
# ROM
|
||||
|
||||
bpy.types.Scene.fast64 = bpy.props.PointerProperty(type=Fast64_Properties, name="Fast64 Properties")
|
||||
bpy.types.Bone.fast64 = bpy.props.PointerProperty(type=Fast64_BoneProperties, name="Fast64 Bone Properties")
|
||||
bpy.types.Object.fast64 = bpy.props.PointerProperty(type=Fast64_ObjectProperties, name="Fast64 Object Properties")
|
||||
bpy.types.Scene.decomp_compatible = bpy.props.BoolProperty(name="Decomp Compatibility", default=True)
|
||||
bpy.types.Scene.ignoreTextureRestrictions = bpy.props.BoolProperty(
|
||||
name="Ignore Texture Restrictions (Breaks CI Textures)"
|
||||
)
|
||||
bpy.types.Scene.fullTraceback = bpy.props.BoolProperty(name="Show Full Error Traceback", default=False)
|
||||
bpy.types.Scene.gameEditorMode = bpy.props.EnumProperty(name="Game", default="SM64", items=gameEditorEnum)
|
||||
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.blenderF3DScale = bpy.props.FloatProperty(name="F3D Blender Scale", default=100)
|
||||
|
||||
bpy.types.Scene.fast64 = bpy.props.PointerProperty(type=Fast64_Properties, name="Fast64 Properties")
|
||||
bpy.types.Bone.fast64 = bpy.props.PointerProperty(type=Fast64_BoneProperties, name="Fast64 Bone Properties")
|
||||
bpy.types.Object.fast64 = bpy.props.PointerProperty(type=Fast64_ObjectProperties, name="Fast64 Object Properties")
|
||||
|
||||
bpy.app.handlers.load_post.append(after_load)
|
||||
|
||||
bpy.app.handlers.load_post.append(after_load)
|
||||
|
||||
# called on add-on disabling
|
||||
def unregister():
|
||||
f3d_writer_unregister()
|
||||
f3d_parser_unregister()
|
||||
sm64_unregister(True)
|
||||
oot_unregister(True)
|
||||
mat_unregister()
|
||||
bsdf_conv_unregister()
|
||||
bsdf_conv_panel_unregsiter()
|
||||
render_engine_unregister()
|
||||
f3d_writer_unregister()
|
||||
f3d_parser_unregister()
|
||||
sm64_unregister(True)
|
||||
oot_unregister(True)
|
||||
mat_unregister()
|
||||
bsdf_conv_unregister()
|
||||
bsdf_conv_panel_unregsiter()
|
||||
render_engine_unregister()
|
||||
|
||||
del bpy.types.Scene.fullTraceback
|
||||
del bpy.types.Scene.decomp_compatible
|
||||
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
|
||||
del bpy.types.Scene.fullTraceback
|
||||
del bpy.types.Scene.decomp_compatible
|
||||
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
|
||||
|
||||
del bpy.types.Scene.fast64
|
||||
del bpy.types.Bone.fast64
|
||||
del bpy.types.Object.fast64
|
||||
del bpy.types.Scene.fast64
|
||||
del bpy.types.Bone.fast64
|
||||
del bpy.types.Object.fast64
|
||||
|
||||
for cls in classes:
|
||||
unregister_class(cls)
|
||||
|
||||
bpy.app.handlers.load_post.remove(after_load)
|
||||
for cls in classes:
|
||||
unregister_class(cls)
|
||||
|
||||
addon_updater_ops.unregister()
|
||||
unregister_class(ExampleAddonPreferences)
|
||||
bpy.app.handlers.load_post.remove(after_load)
|
||||
|
||||
addon_updater_ops.unregister()
|
||||
unregister_class(ExampleAddonPreferences)
|
||||
|
||||
+6320
-4866
File diff suppressed because it is too large
Load Diff
+2987
-2846
File diff suppressed because it is too large
Load Diff
+1091
-1065
File diff suppressed because it is too large
Load Diff
+1949
-1772
File diff suppressed because it is too large
Load Diff
+2479
-1953
File diff suppressed because it is too large
Load Diff
@@ -7,292 +7,310 @@ from .sm64.sm64_collision import CollisionSettings
|
||||
from .utility import *
|
||||
from bl_operators.presets import AddPresetBase
|
||||
|
||||
def upgradeF3DVersionAll(objs, armatures, version):
|
||||
# Remove original v2 node groups so that they can be recreated.
|
||||
deleteGroups = []
|
||||
for node_tree in bpy.data.node_groups:
|
||||
if node_tree.name[-6:] == 'F3D v' + str(version):
|
||||
deleteGroups.append(node_tree)
|
||||
for deleteGroup in deleteGroups:
|
||||
bpy.data.node_groups.remove(deleteGroup)
|
||||
|
||||
# Dict of non-f3d materials : converted f3d materials
|
||||
# handles cases where materials are used in multiple objects
|
||||
materialDict = {}
|
||||
for obj in objs:
|
||||
upgradeF3DVersionOneObject(obj, materialDict, version)
|
||||
|
||||
for armature in armatures:
|
||||
for bone in armature.bones:
|
||||
if bone.geo_cmd == "Switch":
|
||||
for switchOption in bone.switch_options:
|
||||
if switchOption.switchType == "Material":
|
||||
if switchOption.materialOverride in materialDict:
|
||||
switchOption.materialOverride = materialDict[switchOption.materialOverride]
|
||||
for i in range(len(switchOption.specificOverrideArray)):
|
||||
material = switchOption.specificOverrideArray[i].material
|
||||
if material in materialDict:
|
||||
switchOption.specificOverrideArray[i].material = materialDict[material]
|
||||
for i in range(len(switchOption.specificIgnoreArray)):
|
||||
material = switchOption.specificIgnoreArray[i].material
|
||||
if material in materialDict:
|
||||
switchOption.specificIgnoreArray[i].material = materialDict[material]
|
||||
def upgradeF3DVersionAll(objs, armatures, version):
|
||||
# Remove original v2 node groups so that they can be recreated.
|
||||
deleteGroups = []
|
||||
for node_tree in bpy.data.node_groups:
|
||||
if node_tree.name[-6:] == "F3D v" + str(version):
|
||||
deleteGroups.append(node_tree)
|
||||
for deleteGroup in deleteGroups:
|
||||
bpy.data.node_groups.remove(deleteGroup)
|
||||
|
||||
# Dict of non-f3d materials : converted f3d materials
|
||||
# handles cases where materials are used in multiple objects
|
||||
materialDict = {}
|
||||
for obj in objs:
|
||||
upgradeF3DVersionOneObject(obj, materialDict, version)
|
||||
|
||||
for armature in armatures:
|
||||
for bone in armature.bones:
|
||||
if bone.geo_cmd == "Switch":
|
||||
for switchOption in bone.switch_options:
|
||||
if switchOption.switchType == "Material":
|
||||
if switchOption.materialOverride in materialDict:
|
||||
switchOption.materialOverride = materialDict[switchOption.materialOverride]
|
||||
for i in range(len(switchOption.specificOverrideArray)):
|
||||
material = switchOption.specificOverrideArray[i].material
|
||||
if material in materialDict:
|
||||
switchOption.specificOverrideArray[i].material = materialDict[material]
|
||||
for i in range(len(switchOption.specificIgnoreArray)):
|
||||
material = switchOption.specificIgnoreArray[i].material
|
||||
if material in materialDict:
|
||||
switchOption.specificIgnoreArray[i].material = materialDict[material]
|
||||
|
||||
|
||||
def upgradeF3DVersionOneObject(obj, materialDict, version):
|
||||
for index in range(len(obj.material_slots)):
|
||||
material = obj.material_slots[index].material
|
||||
if material is not None and material.is_f3d:
|
||||
if material in materialDict:
|
||||
obj.material_slots[index].material = materialDict[material]
|
||||
else:
|
||||
convertF3DtoNewVersion(obj, index, material, materialDict, version)
|
||||
for index in range(len(obj.material_slots)):
|
||||
material = obj.material_slots[index].material
|
||||
if material is not None and material.is_f3d:
|
||||
if material in materialDict:
|
||||
obj.material_slots[index].material = materialDict[material]
|
||||
else:
|
||||
convertF3DtoNewVersion(obj, index, material, materialDict, version)
|
||||
|
||||
|
||||
V4PresetName = {
|
||||
'Unlit Texture' : "sm64_unlit_texture",
|
||||
'Unlit Texture Cutout' : "sm64_unlit_texture_cutout",
|
||||
'Shaded Solid' : "sm64_shaded_solid",
|
||||
'Shaded Texture' : "sm64_shaded_texture",
|
||||
'Shaded Texture Cutout' : "sm64_shaded_texture_cutout",
|
||||
'Shaded Texture Transparent' : "sm64_shaded_texture_transparent",
|
||||
'Environment Mapped' : "sm64_environment_map",
|
||||
'Decal On Shaded Solid' : "sm64_decal",
|
||||
'Vertex Colored Texture' : "sm64_vertex_colored_texture",
|
||||
'Fog Shaded Texture' : "sm64_fog_shaded_texture",
|
||||
'Fog Shaded Texture Cutout' : "sm64_fog_shaded_texture_cutout",
|
||||
'Fog Shaded Texture Transparent' : "sm64_fog_shaded_texture_transparent",
|
||||
'Vertex Colored Texture Transparent' : "sm64_vertex_colored_texture_transparent",
|
||||
'Shaded Noise' : "sm64_shaded_noise",
|
||||
"Unlit Texture": "sm64_unlit_texture",
|
||||
"Unlit Texture Cutout": "sm64_unlit_texture_cutout",
|
||||
"Shaded Solid": "sm64_shaded_solid",
|
||||
"Shaded Texture": "sm64_shaded_texture",
|
||||
"Shaded Texture Cutout": "sm64_shaded_texture_cutout",
|
||||
"Shaded Texture Transparent": "sm64_shaded_texture_transparent",
|
||||
"Environment Mapped": "sm64_environment_map",
|
||||
"Decal On Shaded Solid": "sm64_decal",
|
||||
"Vertex Colored Texture": "sm64_vertex_colored_texture",
|
||||
"Fog Shaded Texture": "sm64_fog_shaded_texture",
|
||||
"Fog Shaded Texture Cutout": "sm64_fog_shaded_texture_cutout",
|
||||
"Fog Shaded Texture Transparent": "sm64_fog_shaded_texture_transparent",
|
||||
"Vertex Colored Texture Transparent": "sm64_vertex_colored_texture_transparent",
|
||||
"Shaded Noise": "sm64_shaded_noise",
|
||||
}
|
||||
|
||||
|
||||
def getV4PresetName(name):
|
||||
newName = None
|
||||
if name in V4PresetName:
|
||||
newName = V4PresetName[name]
|
||||
else:
|
||||
newName = "Custom"
|
||||
return newName
|
||||
newName = None
|
||||
if name in V4PresetName:
|
||||
newName = V4PresetName[name]
|
||||
else:
|
||||
newName = "Custom"
|
||||
return newName
|
||||
|
||||
|
||||
def convertF3DtoNewVersion(obj, index, material, materialDict, version):
|
||||
|
||||
if material.mat_ver > 3:
|
||||
oldPreset = AddPresetBase.as_filename(material.f3d_mat.presetName)
|
||||
else:
|
||||
oldPreset = material.f3d_preset
|
||||
|
||||
if version > 3:
|
||||
newMat = createF3DMat(obj, preset = getV4PresetName(oldPreset), index = index)
|
||||
if material.mat_ver > 3:
|
||||
copyPropertyGroup(material.f3d_mat, newMat.f3d_mat)
|
||||
else:
|
||||
convertToNewMat(newMat, material)
|
||||
if newMat.f3d_mat.draw_layer.sm64 != obj.draw_layer_static:
|
||||
newMat.f3d_mat.draw_layer.sm64 = obj.draw_layer_static
|
||||
else:
|
||||
newMat = createF3DMat(obj, preset = oldPreset, index = index)
|
||||
matSettings = F3DMaterialSettings()
|
||||
matSettings.loadFromMaterial(material, True)
|
||||
matSettings.applyToMaterial(newMat, True, update_node_values_of_material, bpy.context)
|
||||
if material.mat_ver > 3:
|
||||
oldPreset = AddPresetBase.as_filename(material.f3d_mat.presetName)
|
||||
else:
|
||||
oldPreset = material.f3d_preset
|
||||
|
||||
copyPropertyGroup(material.ootMaterial, newMat.ootMaterial)
|
||||
copyPropertyGroup(material.ootCollisionProperty, newMat.ootCollisionProperty)
|
||||
if version > 3:
|
||||
newMat = createF3DMat(obj, preset=getV4PresetName(oldPreset), index=index)
|
||||
if material.mat_ver > 3:
|
||||
copyPropertyGroup(material.f3d_mat, newMat.f3d_mat)
|
||||
else:
|
||||
convertToNewMat(newMat, material)
|
||||
if newMat.f3d_mat.draw_layer.sm64 != obj.draw_layer_static:
|
||||
newMat.f3d_mat.draw_layer.sm64 = obj.draw_layer_static
|
||||
else:
|
||||
newMat = createF3DMat(obj, preset=oldPreset, index=index)
|
||||
matSettings = F3DMaterialSettings()
|
||||
matSettings.loadFromMaterial(material, True)
|
||||
matSettings.applyToMaterial(newMat, True, update_node_values_of_material, bpy.context)
|
||||
|
||||
colSettings = CollisionSettings()
|
||||
colSettings.load(material)
|
||||
colSettings.apply(newMat)
|
||||
copyPropertyGroup(material.ootMaterial, newMat.ootMaterial)
|
||||
copyPropertyGroup(material.ootCollisionProperty, newMat.ootCollisionProperty)
|
||||
|
||||
colSettings = CollisionSettings()
|
||||
colSettings.load(material)
|
||||
colSettings.apply(newMat)
|
||||
|
||||
updateMatWithNewVersionName(newMat, material, materialDict, version)
|
||||
|
||||
updateMatWithNewVersionName(newMat, material, materialDict, version)
|
||||
|
||||
def convertAllBSDFtoF3D(objs, renameUV):
|
||||
# Dict of non-f3d materials : converted f3d materials
|
||||
# handles cases where materials are used in multiple objects
|
||||
materialDict = {}
|
||||
for obj in objs:
|
||||
if renameUV:
|
||||
for uv_layer in obj.data.uv_layers:
|
||||
uv_layer.name = "UVMap"
|
||||
for index in range(len(obj.material_slots)):
|
||||
material = obj.material_slots[index].material
|
||||
if material is not None and not material.is_f3d:
|
||||
if material in materialDict:
|
||||
print("Existing material")
|
||||
obj.material_slots[index].material = materialDict[material]
|
||||
else:
|
||||
print("New material")
|
||||
convertBSDFtoF3D(obj, index, material, materialDict)
|
||||
# Dict of non-f3d materials : converted f3d materials
|
||||
# handles cases where materials are used in multiple objects
|
||||
materialDict = {}
|
||||
for obj in objs:
|
||||
if renameUV:
|
||||
for uv_layer in obj.data.uv_layers:
|
||||
uv_layer.name = "UVMap"
|
||||
for index in range(len(obj.material_slots)):
|
||||
material = obj.material_slots[index].material
|
||||
if material is not None and not material.is_f3d:
|
||||
if material in materialDict:
|
||||
print("Existing material")
|
||||
obj.material_slots[index].material = materialDict[material]
|
||||
else:
|
||||
print("New material")
|
||||
convertBSDFtoF3D(obj, index, material, materialDict)
|
||||
|
||||
|
||||
def convertBSDFtoF3D(obj, index, material, materialDict):
|
||||
if not material.use_nodes:
|
||||
newMaterial = createF3DMat(obj, preset = 'Shaded Solid', index = index)
|
||||
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
|
||||
f3dMat.default_light_color = material.diffuse_color
|
||||
updateMatWithName(newMaterial, material, materialDict)
|
||||
if not material.use_nodes:
|
||||
newMaterial = createF3DMat(obj, preset="Shaded Solid", index=index)
|
||||
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
|
||||
f3dMat.default_light_color = material.diffuse_color
|
||||
updateMatWithName(newMaterial, material, materialDict)
|
||||
|
||||
elif "Principled BSDF" in material.node_tree.nodes:
|
||||
tex0Node = material.node_tree.nodes["Principled BSDF"].inputs["Base Color"]
|
||||
tex1Node = material.node_tree.nodes["Principled BSDF"].inputs["Subsurface Color"]
|
||||
if len(tex0Node.links) == 0:
|
||||
newMaterial = createF3DMat(obj, preset=getDefaultMaterialPreset("Shaded Solid"), index=index)
|
||||
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
|
||||
f3dMat.default_light_color = tex0Node.default_value
|
||||
updateMatWithName(newMaterial, material, materialDict)
|
||||
else:
|
||||
if isinstance(tex0Node.links[0].from_node, bpy.types.ShaderNodeTexImage):
|
||||
if "convert_preset" in material:
|
||||
presetName = material["convert_preset"]
|
||||
if presetName not in [enumValue[0] for enumValue in enumMaterialPresets]:
|
||||
raise PluginError(
|
||||
"During BSDF to F3D conversion, for material '"
|
||||
+ material.name
|
||||
+ "',"
|
||||
+ " enum '"
|
||||
+ presetName
|
||||
+ "' was not found in material preset enum list."
|
||||
)
|
||||
else:
|
||||
presetName = getDefaultMaterialPreset("Shaded Texture")
|
||||
newMaterial = createF3DMat(obj, preset=presetName, index=index)
|
||||
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
|
||||
f3dMat.tex0.tex = tex0Node.links[0].from_node.image
|
||||
if len(tex1Node.links) > 0 and isinstance(tex1Node.links[0].from_node, bpy.types.ShaderNodeTexImage):
|
||||
f3dMat.tex1.tex = tex1Node.links[0].from_node.image
|
||||
updateMatWithName(newMaterial, material, materialDict)
|
||||
else:
|
||||
print("Principled BSDF material does not have an Image Node attached to its Base Color.")
|
||||
else:
|
||||
print("Material is not a Principled BSDF or non-node material.")
|
||||
|
||||
elif "Principled BSDF" in material.node_tree.nodes:
|
||||
tex0Node = material.node_tree.nodes['Principled BSDF'].inputs['Base Color']
|
||||
tex1Node = material.node_tree.nodes['Principled BSDF'].inputs['Subsurface Color']
|
||||
if len(tex0Node.links) == 0:
|
||||
newMaterial = createF3DMat(obj, preset = getDefaultMaterialPreset("Shaded Solid"), index = index)
|
||||
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
|
||||
f3dMat.default_light_color = tex0Node.default_value
|
||||
updateMatWithName(newMaterial, material, materialDict)
|
||||
else:
|
||||
if isinstance(tex0Node.links[0].from_node, bpy.types.ShaderNodeTexImage):
|
||||
if 'convert_preset' in material:
|
||||
presetName = material['convert_preset']
|
||||
if presetName not in [enumValue[0] for enumValue in enumMaterialPresets]:
|
||||
raise PluginError('During BSDF to F3D conversion, for material \'' + material.name + '\',' + \
|
||||
' enum \'' + presetName + '\' was not found in material preset enum list.')
|
||||
else:
|
||||
presetName = getDefaultMaterialPreset('Shaded Texture')
|
||||
newMaterial = createF3DMat(obj, preset = presetName, index = index)
|
||||
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
|
||||
f3dMat.tex0.tex = tex0Node.links[0].from_node.image
|
||||
if len(tex1Node.links) > 0 and \
|
||||
isinstance(tex1Node.links[0].from_node, bpy.types.ShaderNodeTexImage):
|
||||
f3dMat.tex1.tex = tex1Node.links[0].from_node.image
|
||||
updateMatWithName(newMaterial, material, materialDict)
|
||||
else:
|
||||
print("Principled BSDF material does not have an Image Node attached to its Base Color.")
|
||||
else:
|
||||
print("Material is not a Principled BSDF or non-node material.")
|
||||
|
||||
def updateMatWithName(f3dMat, oldMat, materialDict):
|
||||
f3dMat.name = oldMat.name + "_f3d"
|
||||
update_preset_manual(f3dMat, bpy.context)
|
||||
materialDict[oldMat] = f3dMat
|
||||
f3dMat.name = oldMat.name + "_f3d"
|
||||
update_preset_manual(f3dMat, bpy.context)
|
||||
materialDict[oldMat] = f3dMat
|
||||
|
||||
|
||||
def updateMatWithNewVersionName(f3dMat, oldMat, materialDict, version):
|
||||
name = oldMat.name
|
||||
if oldMat.name[-3:-1] == '_v':
|
||||
name = oldMat.name[:-3]
|
||||
f3dMat.name = name + "_v" + str(version)
|
||||
update_preset_manual(f3dMat, bpy.context)
|
||||
materialDict[oldMat] = f3dMat
|
||||
name = oldMat.name
|
||||
if oldMat.name[-3:-1] == "_v":
|
||||
name = oldMat.name[:-3]
|
||||
f3dMat.name = name + "_v" + str(version)
|
||||
update_preset_manual(f3dMat, bpy.context)
|
||||
materialDict[oldMat] = f3dMat
|
||||
|
||||
|
||||
class BSDFConvert(bpy.types.Operator):
|
||||
# set bl_ properties
|
||||
bl_idname = 'object.convert_bsdf'
|
||||
bl_label = "Principled BSDF to F3D Converter"
|
||||
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
|
||||
# set bl_ properties
|
||||
bl_idname = "object.convert_bsdf"
|
||||
bl_label = "Principled BSDF to F3D Converter"
|
||||
bl_options = {"REGISTER", "UNDO", "PRESET"}
|
||||
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != 'OBJECT':
|
||||
raise PluginError("Operator can only be used in object mode.")
|
||||
|
||||
if context.scene.bsdf_conv_all:
|
||||
convertAllBSDFtoF3D([obj for obj in bpy.data.objects if isinstance(obj.data, bpy.types.Mesh)],
|
||||
context.scene.rename_uv_maps)
|
||||
else:
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Mesh not selected.")
|
||||
elif type(context.selected_objects[0].data) is not\
|
||||
bpy.types.Mesh:
|
||||
raise PluginError("Mesh not selected.")
|
||||
|
||||
obj = context.selected_objects[0]
|
||||
convertAllBSDFtoF3D([obj], context.scene.rename_uv_maps)
|
||||
|
||||
except Exception as e:
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != "OBJECT":
|
||||
raise PluginError("Operator can only be used in object mode.")
|
||||
|
||||
if context.scene.bsdf_conv_all:
|
||||
convertAllBSDFtoF3D(
|
||||
[obj for obj in bpy.data.objects if isinstance(obj.data, bpy.types.Mesh)],
|
||||
context.scene.rename_uv_maps,
|
||||
)
|
||||
else:
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Mesh not selected.")
|
||||
elif type(context.selected_objects[0].data) is not bpy.types.Mesh:
|
||||
raise PluginError("Mesh not selected.")
|
||||
|
||||
obj = context.selected_objects[0]
|
||||
convertAllBSDFtoF3D([obj], context.scene.rename_uv_maps)
|
||||
|
||||
except Exception as e:
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
|
||||
self.report({"INFO"}, "Created F3D material.")
|
||||
return {"FINISHED"} # must return a set
|
||||
|
||||
self.report({'INFO'}, 'Created F3D material.')
|
||||
return {'FINISHED'} # must return a set
|
||||
|
||||
class MatUpdateConvert(bpy.types.Operator):
|
||||
# set bl_ properties
|
||||
version = 4
|
||||
bl_idname = 'object.convert_f3d_update'
|
||||
bl_label = "Recreate F3D Materials As v" + str(version)
|
||||
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
|
||||
# set bl_ properties
|
||||
version = 4
|
||||
bl_idname = "object.convert_f3d_update"
|
||||
bl_label = "Recreate F3D Materials As v" + str(version)
|
||||
bl_options = {"REGISTER", "UNDO", "PRESET"}
|
||||
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != 'OBJECT':
|
||||
raise PluginError("Operator can only be used in object mode.")
|
||||
|
||||
if context.scene.update_conv_all:
|
||||
upgradeF3DVersionAll([obj for obj in bpy.data.objects if isinstance(obj.data, bpy.types.Mesh)],
|
||||
bpy.data.armatures, self.version)
|
||||
else:
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Mesh not selected.")
|
||||
elif type(context.selected_objects[0].data) is not\
|
||||
bpy.types.Mesh:
|
||||
raise PluginError("Mesh not selected.")
|
||||
|
||||
obj = context.selected_objects[0]
|
||||
upgradeF3DVersionOneObject(obj, {}, self.version)
|
||||
|
||||
except Exception as e:
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
# Called on demand (i.e. button press, menu item)
|
||||
# Can also be called from operator search menu (Spacebar)
|
||||
def execute(self, context):
|
||||
try:
|
||||
if context.mode != "OBJECT":
|
||||
raise PluginError("Operator can only be used in object mode.")
|
||||
|
||||
if context.scene.update_conv_all:
|
||||
upgradeF3DVersionAll(
|
||||
[obj for obj in bpy.data.objects if isinstance(obj.data, bpy.types.Mesh)],
|
||||
bpy.data.armatures,
|
||||
self.version,
|
||||
)
|
||||
else:
|
||||
if len(context.selected_objects) == 0:
|
||||
raise PluginError("Mesh not selected.")
|
||||
elif type(context.selected_objects[0].data) is not bpy.types.Mesh:
|
||||
raise PluginError("Mesh not selected.")
|
||||
|
||||
obj = context.selected_objects[0]
|
||||
upgradeF3DVersionOneObject(obj, {}, self.version)
|
||||
|
||||
except Exception as e:
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"}
|
||||
|
||||
self.report({"INFO"}, "Created F3D material.")
|
||||
return {"FINISHED"} # must return a set
|
||||
|
||||
self.report({'INFO'}, 'Created F3D material.')
|
||||
return {'FINISHED'} # must return a set
|
||||
|
||||
class F3DMaterialConverterPanel(bpy.types.Panel):
|
||||
bl_label = "F3D Material Converter"
|
||||
bl_idname = "MATERIAL_PT_F3D_Material_Converter"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = 'Fast64'
|
||||
bl_label = "F3D Material Converter"
|
||||
bl_idname = "MATERIAL_PT_F3D_Material_Converter"
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = "UI"
|
||||
bl_category = "Fast64"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
#return hasattr(context, 'object') and context.object is not None and \
|
||||
# isinstance(context.object.data, bpy.types.Mesh)
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
# return hasattr(context, 'object') and context.object is not None and \
|
||||
# isinstance(context.object.data, bpy.types.Mesh)
|
||||
|
||||
def draw(self, context):
|
||||
#mesh = context.object.data
|
||||
self.layout.operator(BSDFConvert.bl_idname)
|
||||
self.layout.prop(context.scene, 'bsdf_conv_all')
|
||||
self.layout.prop(context.scene, 'rename_uv_maps')
|
||||
self.layout.operator(MatUpdateConvert.bl_idname)
|
||||
self.layout.prop(context.scene, 'update_conv_all')
|
||||
self.layout.operator(ReloadDefaultF3DPresets.bl_idname)
|
||||
def draw(self, context):
|
||||
# mesh = context.object.data
|
||||
self.layout.operator(BSDFConvert.bl_idname)
|
||||
self.layout.prop(context.scene, "bsdf_conv_all")
|
||||
self.layout.prop(context.scene, "rename_uv_maps")
|
||||
self.layout.operator(MatUpdateConvert.bl_idname)
|
||||
self.layout.prop(context.scene, "update_conv_all")
|
||||
self.layout.operator(ReloadDefaultF3DPresets.bl_idname)
|
||||
|
||||
|
||||
bsdf_conv_classes = (
|
||||
BSDFConvert,
|
||||
MatUpdateConvert,
|
||||
BSDFConvert,
|
||||
MatUpdateConvert,
|
||||
)
|
||||
|
||||
bsdf_conv_panel_classes = (
|
||||
F3DMaterialConverterPanel,
|
||||
)
|
||||
bsdf_conv_panel_classes = (F3DMaterialConverterPanel,)
|
||||
|
||||
|
||||
def bsdf_conv_panel_regsiter():
|
||||
for cls in bsdf_conv_panel_classes:
|
||||
register_class(cls)
|
||||
for cls in bsdf_conv_panel_classes:
|
||||
register_class(cls)
|
||||
|
||||
|
||||
def bsdf_conv_panel_unregsiter():
|
||||
for cls in bsdf_conv_panel_classes:
|
||||
unregister_class(cls)
|
||||
for cls in bsdf_conv_panel_classes:
|
||||
unregister_class(cls)
|
||||
|
||||
|
||||
def bsdf_conv_register():
|
||||
for cls in bsdf_conv_classes:
|
||||
register_class(cls)
|
||||
for cls in bsdf_conv_classes:
|
||||
register_class(cls)
|
||||
|
||||
# Moved to Level Root
|
||||
bpy.types.Scene.bsdf_conv_all = bpy.props.BoolProperty(name="Convert all objects", default=True)
|
||||
bpy.types.Scene.update_conv_all = bpy.props.BoolProperty(name="Convert all objects", default=True)
|
||||
bpy.types.Scene.rename_uv_maps = bpy.props.BoolProperty(name="Rename UV maps", default=True)
|
||||
|
||||
# Moved to Level Root
|
||||
bpy.types.Scene.bsdf_conv_all = bpy.props.BoolProperty(
|
||||
name = 'Convert all objects', default = True)
|
||||
bpy.types.Scene.update_conv_all = bpy.props.BoolProperty(
|
||||
name = 'Convert all objects', default = True)
|
||||
bpy.types.Scene.rename_uv_maps = bpy.props.BoolProperty(
|
||||
name = 'Rename UV maps', default = True)
|
||||
|
||||
def bsdf_conv_unregister():
|
||||
for cls in bsdf_conv_classes:
|
||||
unregister_class(cls)
|
||||
for cls in bsdf_conv_classes:
|
||||
unregister_class(cls)
|
||||
|
||||
del bpy.types.Scene.bsdf_conv_all
|
||||
del bpy.types.Scene.update_conv_all
|
||||
del bpy.types.Scene.rename_uv_maps
|
||||
del bpy.types.Scene.bsdf_conv_all
|
||||
del bpy.types.Scene.update_conv_all
|
||||
del bpy.types.Scene.rename_uv_maps
|
||||
|
||||
+1441
-1439
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+221
-221
@@ -18,277 +18,277 @@ import bpy
|
||||
from bpy.utils import register_class, unregister_class
|
||||
|
||||
enumRefreshVer = [
|
||||
("Refresh 3", "Refresh 3", "Refresh 3"),
|
||||
("Refresh 4", "Refresh 4", "Refresh 4"),
|
||||
("Refresh 5", "Refresh 5", "Refresh 5"),
|
||||
("Refresh 6", "Refresh 6", "Refresh 6"),
|
||||
("Refresh 7", "Refresh 7", "Refresh 7"),
|
||||
("Refresh 8", "Refresh 8", "Refresh 8"),
|
||||
("Refresh 10", "Refresh 10", "Refresh 10"),
|
||||
("Refresh 11", "Refresh 11", "Refresh 11"),
|
||||
("Refresh 12", "Refresh 12", "Refresh 12"),
|
||||
("Refresh 13", "Refresh 13", "Refresh 13"),
|
||||
("Refresh 3", "Refresh 3", "Refresh 3"),
|
||||
("Refresh 4", "Refresh 4", "Refresh 4"),
|
||||
("Refresh 5", "Refresh 5", "Refresh 5"),
|
||||
("Refresh 6", "Refresh 6", "Refresh 6"),
|
||||
("Refresh 7", "Refresh 7", "Refresh 7"),
|
||||
("Refresh 8", "Refresh 8", "Refresh 8"),
|
||||
("Refresh 10", "Refresh 10", "Refresh 10"),
|
||||
("Refresh 11", "Refresh 11", "Refresh 11"),
|
||||
("Refresh 12", "Refresh 12", "Refresh 12"),
|
||||
("Refresh 13", "Refresh 13", "Refresh 13"),
|
||||
]
|
||||
|
||||
|
||||
class SM64_AddrConv(bpy.types.Operator):
|
||||
# set bl_ properties
|
||||
bl_idname = 'object.addr_conv'
|
||||
bl_label = "Convert Address"
|
||||
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
|
||||
# set bl_ properties
|
||||
bl_idname = "object.addr_conv"
|
||||
bl_label = "Convert Address"
|
||||
bl_options = {"REGISTER", "UNDO", "PRESET"}
|
||||
|
||||
segToVirt : bpy.props.BoolProperty()
|
||||
segToVirt: bpy.props.BoolProperty()
|
||||
|
||||
def execute(self, context):
|
||||
romfileSrc = None
|
||||
try:
|
||||
address = int(context.scene.convertibleAddr, 16)
|
||||
importRom = context.scene.importRom
|
||||
romfileSrc = open(bpy.path.abspath(importRom), "rb")
|
||||
checkExpanded(bpy.path.abspath(importRom))
|
||||
levelParsed = parseLevelAtPointer(romfileSrc, level_pointers[context.scene.levelConvert])
|
||||
segmentData = levelParsed.segmentData
|
||||
if self.segToVirt:
|
||||
ptr = decodeSegmentedAddr(address.to_bytes(4, "big"), segmentData)
|
||||
self.report({"INFO"}, "Virtual pointer is 0x" + format(ptr, "08X"))
|
||||
else:
|
||||
ptr = int.from_bytes(encodeSegmentedAddr(address, segmentData), "big")
|
||||
self.report({"INFO"}, "Segmented pointer is 0x" + format(ptr, "08X"))
|
||||
romfileSrc.close()
|
||||
return {"FINISHED"}
|
||||
except Exception as e:
|
||||
if romfileSrc is not None:
|
||||
romfileSrc.close()
|
||||
raisePluginError(self, e)
|
||||
return {"CANCELLED"} # must return a set
|
||||
|
||||
def execute(self, context):
|
||||
romfileSrc = None
|
||||
try:
|
||||
address = int(context.scene.convertibleAddr, 16)
|
||||
importRom = context.scene.importRom
|
||||
romfileSrc = open(bpy.path.abspath(importRom), 'rb')
|
||||
checkExpanded(bpy.path.abspath(importRom))
|
||||
levelParsed = parseLevelAtPointer(romfileSrc,
|
||||
level_pointers[context.scene.levelConvert])
|
||||
segmentData = levelParsed.segmentData
|
||||
if self.segToVirt:
|
||||
ptr = decodeSegmentedAddr(
|
||||
address.to_bytes(4, 'big'), segmentData)
|
||||
self.report({'INFO'},
|
||||
'Virtual pointer is 0x' + format(ptr, '08X'))
|
||||
else:
|
||||
ptr = int.from_bytes(
|
||||
encodeSegmentedAddr(address, segmentData), 'big')
|
||||
self.report({'INFO'},
|
||||
'Segmented pointer is 0x' + format(ptr, '08X'))
|
||||
romfileSrc.close()
|
||||
return {'FINISHED'}
|
||||
except Exception as e:
|
||||
if romfileSrc is not None:
|
||||
romfileSrc.close()
|
||||
raisePluginError(self, e)
|
||||
return {'CANCELLED'} # must return a set
|
||||
|
||||
class SM64_MenuVisibilityPanel(SM64_Panel):
|
||||
bl_idname = "SM64_PT_menu_visibility_settings"
|
||||
bl_label = "SM64 Menu Visibility Settings"
|
||||
bl_options = set() # default to open
|
||||
bl_order = 0 # force to front
|
||||
bl_idname = "SM64_PT_menu_visibility_settings"
|
||||
bl_label = "SM64 Menu Visibility Settings"
|
||||
bl_options = set() # default to open
|
||||
bl_order = 0 # force to front
|
||||
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.scale_y = 1.1 # extra padding
|
||||
sm64Props: SM64_Properties = context.scene.fast64.sm64
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.scale_y = 1.1 # extra padding
|
||||
sm64Props: SM64_Properties = context.scene.fast64.sm64
|
||||
|
||||
prop_split(col, sm64Props, "goal", "Export goal")
|
||||
prop_split(col, sm64Props, "showImportingMenus", "Show Importing Options")
|
||||
|
||||
prop_split(col, sm64Props, 'goal', 'Export goal')
|
||||
prop_split(col, sm64Props, 'showImportingMenus', 'Show Importing Options')
|
||||
|
||||
class SM64_FileSettingsPanel(SM64_Panel):
|
||||
bl_idname = "SM64_PT_file_settings"
|
||||
bl_label = "SM64 File Settings"
|
||||
bl_options = set()
|
||||
bl_idname = "SM64_PT_file_settings"
|
||||
bl_label = "SM64 File Settings"
|
||||
bl_options = set()
|
||||
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.scale_y = 1.1 # extra padding
|
||||
sm64Props: SM64_Properties = context.scene.fast64.sm64
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
col.scale_y = 1.1 # extra padding
|
||||
sm64Props: SM64_Properties = context.scene.fast64.sm64
|
||||
|
||||
prop_split(col, sm64Props, 'exportType', 'Export type')
|
||||
prop_split(col, context.scene, 'blenderToSM64Scale', 'Blender To SM64 Scale')
|
||||
prop_split(col, sm64Props, "exportType", "Export type")
|
||||
prop_split(col, context.scene, "blenderToSM64Scale", "Blender To SM64 Scale")
|
||||
|
||||
if sm64Props.showImportingMenus:
|
||||
col.prop(context.scene, 'importRom')
|
||||
if sm64Props.showImportingMenus:
|
||||
col.prop(context.scene, "importRom")
|
||||
|
||||
if sm64Props.exportType == "Binary":
|
||||
col.prop(context.scene, "exportRom")
|
||||
col.prop(context.scene, "outputRom")
|
||||
col.prop(context.scene, "extendBank4")
|
||||
elif sm64Props.exportType == "C":
|
||||
col.prop(context.scene, "disableScroll")
|
||||
col.prop(context.scene, "decompPath")
|
||||
prop_split(col, context.scene, "refreshVer", "Decomp Func Map")
|
||||
prop_split(col, context.scene, "compressionFormat", "Compression Format")
|
||||
|
||||
if sm64Props.exportType == 'Binary':
|
||||
col.prop(context.scene, 'exportRom')
|
||||
col.prop(context.scene, 'outputRom')
|
||||
col.prop(context.scene, 'extendBank4')
|
||||
elif sm64Props.exportType == 'C':
|
||||
col.prop(context.scene, 'disableScroll')
|
||||
col.prop(context.scene, 'decompPath')
|
||||
prop_split(col, context.scene, 'refreshVer', 'Decomp Func Map')
|
||||
prop_split(col, context.scene, 'compressionFormat', 'Compression Format')
|
||||
|
||||
class SM64_AddressConvertPanel(SM64_Panel):
|
||||
bl_idname = "SM64_PT_addr_conv"
|
||||
bl_label = "SM64 Address Converter"
|
||||
goal = sm64GoalImport
|
||||
bl_idname = "SM64_PT_addr_conv"
|
||||
bl_label = "SM64 Address Converter"
|
||||
goal = sm64GoalImport
|
||||
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
segToVirtOp = col.operator(SM64_AddrConv.bl_idname, text="Convert Segmented To Virtual")
|
||||
segToVirtOp.segToVirt = True
|
||||
virtToSegOp = col.operator(SM64_AddrConv.bl_idname, text="Convert Virtual To Segmented")
|
||||
virtToSegOp.segToVirt = False
|
||||
prop_split(col, context.scene, "convertibleAddr", "Address")
|
||||
col.prop(context.scene, "levelConvert")
|
||||
|
||||
def draw(self, context):
|
||||
col = self.layout.column()
|
||||
segToVirtOp = col.operator(SM64_AddrConv.bl_idname,
|
||||
text = "Convert Segmented To Virtual")
|
||||
segToVirtOp.segToVirt = True
|
||||
virtToSegOp = col.operator(SM64_AddrConv.bl_idname,
|
||||
text = "Convert Virtual To Segmented")
|
||||
virtToSegOp.segToVirt = False
|
||||
prop_split(col, context.scene, 'convertibleAddr', 'Address')
|
||||
col.prop(context.scene, 'levelConvert')
|
||||
|
||||
def get_legacy_export_type():
|
||||
legacy_export_types = ('C', 'Binary', 'Insertable Binary')
|
||||
scene = bpy.context.scene
|
||||
legacy_export_types = ("C", "Binary", "Insertable Binary")
|
||||
scene = bpy.context.scene
|
||||
|
||||
for exportKey in ['animExportType', 'colExportType', 'DLExportType', 'geoExportType']:
|
||||
eType = scene.pop(exportKey, None)
|
||||
if eType is not None and legacy_export_types[eType] != 'C':
|
||||
return legacy_export_types[eType]
|
||||
for exportKey in ["animExportType", "colExportType", "DLExportType", "geoExportType"]:
|
||||
eType = scene.pop(exportKey, None)
|
||||
if eType is not None and legacy_export_types[eType] != "C":
|
||||
return legacy_export_types[eType]
|
||||
|
||||
return "C"
|
||||
|
||||
return 'C'
|
||||
|
||||
class SM64_Properties(bpy.types.PropertyGroup):
|
||||
'''Global SM64 Scene Properties found under scene.fast64.sm64'''
|
||||
version: bpy.props.IntProperty(name="SM64_Properties Version", default=0)
|
||||
cur_version = 1 # version after property migration
|
||||
"""Global SM64 Scene Properties found under scene.fast64.sm64"""
|
||||
|
||||
# UI Selection
|
||||
showImportingMenus: bpy.props.BoolProperty(name='Show Importing Menus', default=False)
|
||||
exportType: bpy.props.EnumProperty(items = enumExportType, name = 'Export Type', default = 'C')
|
||||
goal: bpy.props.EnumProperty(items=sm64GoalTypeEnum, name = 'Export Goal', default = 'All')
|
||||
|
||||
# TODO: Utilize these across all exports
|
||||
# C exporting
|
||||
# useCustomExportLocation = bpy.props.BoolProperty(name = 'Use Custom Export Path')
|
||||
# customExportPath: bpy.props.StringProperty(name = 'Custom Export Path', subtype = 'FILE_PATH')
|
||||
# exportLocation: bpy.props.EnumProperty(items = enumExportHeaderType, name = 'Export Location', default = 'Actor')
|
||||
# useSelectedObjectName = bpy.props.BoolProperty(name = 'Use Name From Selected Object', default=False)
|
||||
# exportName: bpy.props.StringProperty(name='Name', default='mario')
|
||||
# exportGeolayoutName: bpy.props.StringProperty(name='Name', default='mario_geo')
|
||||
version: bpy.props.IntProperty(name="SM64_Properties Version", default=0)
|
||||
cur_version = 1 # version after property migration
|
||||
|
||||
# Actor exports
|
||||
# exportGroup: bpy.props.StringProperty(name='Group', default='group0')
|
||||
# UI Selection
|
||||
showImportingMenus: bpy.props.BoolProperty(name="Show Importing Menus", default=False)
|
||||
exportType: bpy.props.EnumProperty(items=enumExportType, name="Export Type", default="C")
|
||||
goal: bpy.props.EnumProperty(items=sm64GoalTypeEnum, name="Export Goal", default="All")
|
||||
|
||||
# Level exports
|
||||
# exportLevelName: bpy.props.StringProperty(name = 'Level', default = 'bob')
|
||||
# exportLevelOption: bpy.props.EnumProperty(items = enumLevelNames, name = 'Level', default = 'bob')
|
||||
# TODO: Utilize these across all exports
|
||||
# C exporting
|
||||
# useCustomExportLocation = bpy.props.BoolProperty(name = 'Use Custom Export Path')
|
||||
# customExportPath: bpy.props.StringProperty(name = 'Custom Export Path', subtype = 'FILE_PATH')
|
||||
# exportLocation: bpy.props.EnumProperty(items = enumExportHeaderType, name = 'Export Location', default = 'Actor')
|
||||
# useSelectedObjectName = bpy.props.BoolProperty(name = 'Use Name From Selected Object', default=False)
|
||||
# exportName: bpy.props.StringProperty(name='Name', default='mario')
|
||||
# exportGeolayoutName: bpy.props.StringProperty(name='Name', default='mario_geo')
|
||||
|
||||
# Insertable Binary
|
||||
# exportInsertableBinaryPath: bpy.props.StringProperty(name = 'Filepath', subtype = 'FILE_PATH')
|
||||
# Actor exports
|
||||
# exportGroup: bpy.props.StringProperty(name='Group', default='group0')
|
||||
|
||||
@staticmethod
|
||||
def upgrade_changed_props():
|
||||
if bpy.context.scene.fast64.sm64.version != SM64_Properties.cur_version:
|
||||
bpy.context.scene.fast64.sm64.exportType = get_legacy_export_type()
|
||||
bpy.context.scene.fast64.sm64.version = SM64_Properties.cur_version
|
||||
# Level exports
|
||||
# exportLevelName: bpy.props.StringProperty(name = 'Level', default = 'bob')
|
||||
# exportLevelOption: bpy.props.EnumProperty(items = enumLevelNames, name = 'Level', default = 'bob')
|
||||
|
||||
# Insertable Binary
|
||||
# exportInsertableBinaryPath: bpy.props.StringProperty(name = 'Filepath', subtype = 'FILE_PATH')
|
||||
|
||||
@staticmethod
|
||||
def upgrade_changed_props():
|
||||
if bpy.context.scene.fast64.sm64.version != SM64_Properties.cur_version:
|
||||
bpy.context.scene.fast64.sm64.exportType = get_legacy_export_type()
|
||||
bpy.context.scene.fast64.sm64.version = SM64_Properties.cur_version
|
||||
|
||||
|
||||
sm64_classes = (
|
||||
SM64_AddrConv,
|
||||
SM64_Properties,
|
||||
SM64_AddrConv,
|
||||
SM64_Properties,
|
||||
)
|
||||
|
||||
sm64_panel_classes = (
|
||||
SM64_MenuVisibilityPanel,
|
||||
SM64_FileSettingsPanel,
|
||||
SM64_AddressConvertPanel,
|
||||
SM64_MenuVisibilityPanel,
|
||||
SM64_FileSettingsPanel,
|
||||
SM64_AddressConvertPanel,
|
||||
)
|
||||
|
||||
def sm64_panel_register():
|
||||
for cls in sm64_panel_classes:
|
||||
register_class(cls)
|
||||
|
||||
sm64_col_panel_register()
|
||||
sm64_bone_panel_register()
|
||||
sm64_cam_panel_register()
|
||||
sm64_obj_panel_register()
|
||||
sm64_geo_parser_panel_register()
|
||||
sm64_geo_writer_panel_register()
|
||||
sm64_level_panel_register()
|
||||
sm64_spline_panel_register()
|
||||
sm64_dl_writer_panel_register()
|
||||
sm64_dl_parser_panel_register()
|
||||
sm64_anim_panel_register()
|
||||
def sm64_panel_register():
|
||||
for cls in sm64_panel_classes:
|
||||
register_class(cls)
|
||||
|
||||
sm64_col_panel_register()
|
||||
sm64_bone_panel_register()
|
||||
sm64_cam_panel_register()
|
||||
sm64_obj_panel_register()
|
||||
sm64_geo_parser_panel_register()
|
||||
sm64_geo_writer_panel_register()
|
||||
sm64_level_panel_register()
|
||||
sm64_spline_panel_register()
|
||||
sm64_dl_writer_panel_register()
|
||||
sm64_dl_parser_panel_register()
|
||||
sm64_anim_panel_register()
|
||||
|
||||
|
||||
def sm64_panel_unregister():
|
||||
for cls in sm64_panel_classes:
|
||||
unregister_class(cls)
|
||||
for cls in sm64_panel_classes:
|
||||
unregister_class(cls)
|
||||
|
||||
sm64_col_panel_unregister()
|
||||
sm64_bone_panel_unregister()
|
||||
sm64_cam_panel_unregister()
|
||||
sm64_obj_panel_unregister()
|
||||
sm64_geo_parser_panel_unregister()
|
||||
sm64_geo_writer_panel_unregister()
|
||||
sm64_level_panel_unregister()
|
||||
sm64_spline_panel_unregister()
|
||||
sm64_dl_writer_panel_unregister()
|
||||
sm64_dl_parser_panel_unregister()
|
||||
sm64_anim_panel_unregister()
|
||||
|
||||
sm64_col_panel_unregister()
|
||||
sm64_bone_panel_unregister()
|
||||
sm64_cam_panel_unregister()
|
||||
sm64_obj_panel_unregister()
|
||||
sm64_geo_parser_panel_unregister()
|
||||
sm64_geo_writer_panel_unregister()
|
||||
sm64_level_panel_unregister()
|
||||
sm64_spline_panel_unregister()
|
||||
sm64_dl_writer_panel_unregister()
|
||||
sm64_dl_parser_panel_unregister()
|
||||
sm64_anim_panel_unregister()
|
||||
|
||||
def sm64_register(registerPanels):
|
||||
for cls in sm64_classes:
|
||||
register_class(cls)
|
||||
for cls in sm64_classes:
|
||||
register_class(cls)
|
||||
|
||||
sm64_col_register() # register first, so panel goes above mat panel
|
||||
sm64_bone_register()
|
||||
sm64_cam_register()
|
||||
sm64_obj_register()
|
||||
sm64_geo_parser_register()
|
||||
sm64_geo_writer_register()
|
||||
sm64_level_register()
|
||||
sm64_spline_register()
|
||||
sm64_dl_writer_register()
|
||||
sm64_dl_parser_register()
|
||||
sm64_anim_register()
|
||||
sm64_col_register() # register first, so panel goes above mat panel
|
||||
sm64_bone_register()
|
||||
sm64_cam_register()
|
||||
sm64_obj_register()
|
||||
sm64_geo_parser_register()
|
||||
sm64_geo_writer_register()
|
||||
sm64_level_register()
|
||||
sm64_spline_register()
|
||||
sm64_dl_writer_register()
|
||||
sm64_dl_parser_register()
|
||||
sm64_anim_register()
|
||||
|
||||
if registerPanels:
|
||||
sm64_panel_register()
|
||||
if registerPanels:
|
||||
sm64_panel_register()
|
||||
|
||||
bpy.types.Scene.importRom = bpy.props.StringProperty(
|
||||
name ='Import ROM', subtype = 'FILE_PATH')
|
||||
bpy.types.Scene.exportRom = bpy.props.StringProperty(
|
||||
name ='Export ROM', subtype = 'FILE_PATH')
|
||||
bpy.types.Scene.outputRom = bpy.props.StringProperty(
|
||||
name ='Output ROM', subtype = 'FILE_PATH')
|
||||
bpy.types.Scene.extendBank4 = bpy.props.BoolProperty(
|
||||
name = 'Extend Bank 4 on Export?', default = True,
|
||||
description = 'Sets bank 4 range to (' +\
|
||||
hex(defaultExtendSegment4[0]) + ', ' + \
|
||||
hex(defaultExtendSegment4[1]) + ') and copies data from old bank')
|
||||
bpy.types.Scene.convertibleAddr = bpy.props.StringProperty(
|
||||
name = 'Address')
|
||||
bpy.types.Scene.levelConvert = bpy.props.EnumProperty(
|
||||
items = level_enums, name = 'Level', default = 'IC')
|
||||
bpy.types.Scene.refreshVer = bpy.props.EnumProperty(
|
||||
items = enumRefreshVer, name = 'Refresh', default = 'Refresh 13')
|
||||
bpy.types.Scene.disableScroll = bpy.props.BoolProperty(
|
||||
name = 'Disable Scrolling Textures')
|
||||
bpy.types.Scene.importRom = bpy.props.StringProperty(name="Import ROM", subtype="FILE_PATH")
|
||||
bpy.types.Scene.exportRom = bpy.props.StringProperty(name="Export ROM", subtype="FILE_PATH")
|
||||
bpy.types.Scene.outputRom = bpy.props.StringProperty(name="Output ROM", subtype="FILE_PATH")
|
||||
bpy.types.Scene.extendBank4 = bpy.props.BoolProperty(
|
||||
name="Extend Bank 4 on Export?",
|
||||
default=True,
|
||||
description="Sets bank 4 range to ("
|
||||
+ hex(defaultExtendSegment4[0])
|
||||
+ ", "
|
||||
+ hex(defaultExtendSegment4[1])
|
||||
+ ") and copies data from old bank",
|
||||
)
|
||||
bpy.types.Scene.convertibleAddr = bpy.props.StringProperty(name="Address")
|
||||
bpy.types.Scene.levelConvert = bpy.props.EnumProperty(items=level_enums, name="Level", default="IC")
|
||||
bpy.types.Scene.refreshVer = bpy.props.EnumProperty(items=enumRefreshVer, name="Refresh", default="Refresh 13")
|
||||
bpy.types.Scene.disableScroll = bpy.props.BoolProperty(name="Disable Scrolling Textures")
|
||||
|
||||
bpy.types.Scene.blenderToSM64Scale = bpy.props.FloatProperty(name="Blender To SM64 Scale", default=100) # 212.766
|
||||
bpy.types.Scene.decompPath = bpy.props.StringProperty(name="Decomp Folder", subtype="FILE_PATH")
|
||||
|
||||
bpy.types.Scene.compressionFormat = bpy.props.EnumProperty(
|
||||
items=enumCompressionFormat, name="Compression", default="mio0"
|
||||
)
|
||||
|
||||
bpy.types.Scene.blenderToSM64Scale = bpy.props.FloatProperty(
|
||||
name = 'Blender To SM64 Scale', default = 100) # 212.766
|
||||
bpy.types.Scene.decompPath = bpy.props.StringProperty(
|
||||
name ='Decomp Folder', subtype = 'FILE_PATH')
|
||||
|
||||
bpy.types.Scene.compressionFormat = bpy.props.EnumProperty(
|
||||
items = enumCompressionFormat, name = 'Compression', default = 'mio0')
|
||||
|
||||
def sm64_unregister(unregisterPanels):
|
||||
for cls in reversed(sm64_classes):
|
||||
unregister_class(cls)
|
||||
for cls in reversed(sm64_classes):
|
||||
unregister_class(cls)
|
||||
|
||||
sm64_col_unregister() # register first, so panel goes above mat panel
|
||||
sm64_bone_unregister()
|
||||
sm64_cam_unregister()
|
||||
sm64_obj_unregister()
|
||||
sm64_geo_parser_unregister()
|
||||
sm64_geo_writer_unregister()
|
||||
sm64_level_unregister()
|
||||
sm64_spline_unregister()
|
||||
sm64_dl_writer_unregister()
|
||||
sm64_dl_parser_unregister()
|
||||
sm64_anim_unregister()
|
||||
sm64_col_unregister() # register first, so panel goes above mat panel
|
||||
sm64_bone_unregister()
|
||||
sm64_cam_unregister()
|
||||
sm64_obj_unregister()
|
||||
sm64_geo_parser_unregister()
|
||||
sm64_geo_writer_unregister()
|
||||
sm64_level_unregister()
|
||||
sm64_spline_unregister()
|
||||
sm64_dl_writer_unregister()
|
||||
sm64_dl_parser_unregister()
|
||||
sm64_anim_unregister()
|
||||
|
||||
if unregisterPanels:
|
||||
sm64_panel_unregister()
|
||||
if unregisterPanels:
|
||||
sm64_panel_unregister()
|
||||
|
||||
del bpy.types.Scene.importRom
|
||||
del bpy.types.Scene.exportRom
|
||||
del bpy.types.Scene.outputRom
|
||||
del bpy.types.Scene.extendBank4
|
||||
|
||||
del bpy.types.Scene.convertibleAddr
|
||||
del bpy.types.Scene.levelConvert
|
||||
del bpy.types.Scene.refreshVer
|
||||
del bpy.types.Scene.importRom
|
||||
del bpy.types.Scene.exportRom
|
||||
del bpy.types.Scene.outputRom
|
||||
del bpy.types.Scene.extendBank4
|
||||
|
||||
del bpy.types.Scene.disableScroll
|
||||
|
||||
del bpy.types.Scene.blenderToSM64Scale
|
||||
del bpy.types.Scene.decompPath
|
||||
del bpy.types.Scene.compressionFormat
|
||||
del bpy.types.Scene.convertibleAddr
|
||||
del bpy.types.Scene.levelConvert
|
||||
del bpy.types.Scene.refreshVer
|
||||
|
||||
del bpy.types.Scene.disableScroll
|
||||
|
||||
del bpy.types.Scene.blenderToSM64Scale
|
||||
del bpy.types.Scene.decompPath
|
||||
del bpy.types.Scene.compressionFormat
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+1717
-1486
File diff suppressed because it is too large
Load Diff
+969
-846
File diff suppressed because it is too large
Load Diff
+1
-2
@@ -6,8 +6,7 @@
|
||||
line-length = 120
|
||||
|
||||
target-version = [
|
||||
'py37', # used by Blender 2.80
|
||||
'py39', # used by Blender 3.0.1
|
||||
'py310', # used by Blender 3.1
|
||||
]
|
||||
|
||||
# What files to exclude when running Black on directories (for example `black .`)
|
||||
|
||||
Reference in New Issue
Block a user