From 4bfdacc7ff1ee34dbd8ff5c7cedfd728aa34dd88 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Mon, 10 Nov 2025 00:05:32 +0100 Subject: [PATCH 1/4] fixed exportpath missing in fast64 tab --- fast64_internal/sm64/sm64_f3d_writer.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fast64_internal/sm64/sm64_f3d_writer.py b/fast64_internal/sm64/sm64_f3d_writer.py index 1aad38346..ac11452b2 100644 --- a/fast64_internal/sm64/sm64_f3d_writer.py +++ b/fast64_internal/sm64/sm64_f3d_writer.py @@ -1013,11 +1013,18 @@ def sm64_dl_writer_register(): bpy.types.Scene.TexRectCustomExport = bpy.props.BoolProperty(name="Custom Export Path") bpy.types.Scene.TexRectExportType = bpy.props.EnumProperty(name="Export Type", items=enumHUDExportLocation) + # TODO: move them elsewhere, it's used by f3d_writer.py so we need them + bpy.types.Scene.DLExportPath = bpy.props.StringProperty(name="Directory", subtype="FILE_PATH") + bpy.types.Scene.DLTexDir = bpy.props.StringProperty(name="Include Path", default="levels/bob") + def sm64_dl_writer_unregister(): for cls in reversed(sm64_dl_writer_classes): unregister_class(cls) + del bpy.types.Scene.DLTexDir + del bpy.types.Scene.DLExportPath + del bpy.types.Scene.DLExportStart del bpy.types.Scene.DLExportEnd del bpy.types.Scene.DLExportGeoPtr From 7523982dbaa930f91bac3bb04ab890e4dd85c1a7 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Mon, 10 Nov 2025 00:05:38 +0100 Subject: [PATCH 2/4] start fixing oot dl exporter --- fast64_internal/f3d/f3d_gbi.py | 8 ++++++-- fast64_internal/f3d/f3d_writer.py | 28 ++++++++++++++++++++-------- fast64_internal/z64/f3d/operators.py | 2 +- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/fast64_internal/f3d/f3d_gbi.py b/fast64_internal/f3d/f3d_gbi.py index a240c99c5..a7dca2ab3 100644 --- a/fast64_internal/f3d/f3d_gbi.py +++ b/fast64_internal/f3d/f3d_gbi.py @@ -2940,7 +2940,7 @@ def save_binary(self, romfile, f3d, segments): for cmd_list in self.draw_overrides: cmd_list.save_binary(romfile, f3d, segments) - def to_c(self, f3d, gfxFormatter): + def to_c(self, f3d: F3D, gfxFormatter: GfxFormatter): staticData = CData() if self.cullVertexList is not None: staticData.append(self.cullVertexList.to_c()) @@ -3021,7 +3021,11 @@ def __init__(self, name, DLFormat): self.material = GfxList(f"mat_{name}", GfxListTag.Material, DLFormat) self.mat_only_DL = GfxList(f"mat_only_{name}", GfxListTag.Material, DLFormat) self.texture_DL = GfxList(f"tex_{name}", GfxListTag.Material, DLFormat.Static) - self.revert = GfxList(f"mat_revert_{name}", GfxListTag.MaterialRevert, DLFormat.Static) + + self.revert: Optional[GfxList] = None + if bpy.context.scene.gameEditorMode not in {"OOT", "MM"}: + self.revert = GfxList(f"mat_revert_{name}", GfxListTag.MaterialRevert, DLFormat.Static) + self.DLFormat = DLFormat self.scrollData = FScrollData() diff --git a/fast64_internal/f3d/f3d_writer.py b/fast64_internal/f3d/f3d_writer.py index 53af72694..b9126e6d3 100644 --- a/fast64_internal/f3d/f3d_writer.py +++ b/fast64_internal/f3d/f3d_writer.py @@ -1336,7 +1336,9 @@ def saveOrGetF3DMaterial(material, fModel, _obj, drawLayer, convertTextureData): fMaterial.mat_only_DL.commands.extend([SPSetLights(fLights)]) fMaterial.mat_only_DL.commands.append(DPPipeSync()) - fMaterial.revert.commands.append(DPPipeSync()) + + if fMaterial.revert is not None: + fMaterial.revert.commands.append(DPPipeSync()) fMaterial.getScrollData(material, getMaterialScrollDimensions(f3dMat)) @@ -1520,7 +1522,7 @@ def saveOrGetF3DMaterial(material, fModel, _obj, drawLayer, convertTextureData): fMaterial.material.commands.append(SPEndDisplayList()) # revertMatAndEndDraw(fMaterial.revert) - if len(fMaterial.revert.commands) > 1: # 1 being the pipe sync + if fMaterial.revert is not None and len(fMaterial.revert.commands) > 1: # 1 being the pipe sync if fMaterial.DLFormat == DLFormat.Static: fMaterial.revert.commands.append(SPEndDisplayList()) else: @@ -1620,13 +1622,17 @@ def saveGeoModeDefinition(fMaterial, settings, defaults, matWriteMethod, is_ex2: material, revert = get_geo_cmds(clear_modes, set_modes, is_ex2, matWriteMethod) fMaterial.mat_only_DL.commands.extend(material) - fMaterial.revert.commands.extend(revert) + + if fMaterial.revert is not None: + fMaterial.revert.commands.extend(revert) def saveModeSetting(fMaterial, value, defaultValue, cmdClass): if value != defaultValue: fMaterial.mat_only_DL.commands.append(cmdClass(value)) - fMaterial.revert.commands.append(cmdClass(defaultValue)) + + if fMaterial.revert is not None: + fMaterial.revert.commands.append(cmdClass(defaultValue)) def saveOtherModeHDefinition(fMaterial, settings, tlut, defaults, matWriteMethod, f3d): @@ -1694,7 +1700,9 @@ def saveOtherModeLDefinitionAll(fMaterial: FMaterial, settings, defaults, defaul 32 - f3d.F3D_OLD_GBI, {*defaultRenderMode, defaults.g_mdsft_alpha_compare, defaults.g_mdsft_zsrcsel}, ) - fMaterial.revert.commands.append(revert_cmd) + + if fMaterial.revert is not None: + fMaterial.revert.commands.append(revert_cmd) flagList, blender = getRenderModeFlagList(settings, fMaterial) cmd.flagList.update(flagList) if blender is not None: @@ -1709,14 +1717,16 @@ def saveOtherModeLDefinitionIndividual(fMaterial, settings, defaults, defaultRen if settings.g_mdsft_zsrcsel == "G_ZS_PRIM": fMaterial.mat_only_DL.commands.append(DPSetPrimDepth(z=settings.prim_depth.z, dz=settings.prim_depth.dz)) - fMaterial.revert.commands.append(DPSetPrimDepth()) + + if fMaterial.revert is not None: + fMaterial.revert.commands.append(DPSetPrimDepth()) if settings.set_rendermode: flagList, blender = getRenderModeFlagList(settings, fMaterial) renderModeSet = DPSetRenderMode(flagList, blender) fMaterial.mat_only_DL.commands.append(renderModeSet) - if defaultRenderMode is not None: + if defaultRenderMode is not None and fMaterial.revert is not None: fMaterial.revert.commands.append(DPSetRenderMode(defaultRenderMode, None)) @@ -1775,7 +1785,9 @@ def saveOtherDefinition(fMaterial, material, defaults): settings = material.rdp_settings if settings.clip_ratio != defaults.clip_ratio: fMaterial.mat_only_DL.commands.append(SPClipRatio(settings.clip_ratio)) - fMaterial.revert.commands.append(SPClipRatio(defaults.clip_ratio)) + + if fMaterial.revert is not None: + fMaterial.revert.commands.append(SPClipRatio(defaults.clip_ratio)) if material.set_blend: fMaterial.mat_only_DL.commands.append( diff --git a/fast64_internal/z64/f3d/operators.py b/fast64_internal/z64/f3d/operators.py index 5ac84dbe2..0495e3ce2 100644 --- a/fast64_internal/z64/f3d/operators.py +++ b/fast64_internal/z64/f3d/operators.py @@ -40,7 +40,7 @@ def ootConvertMeshToC( isCustomExport = settings.isCustom drawLayer = settings.drawLayer removeVanillaData = settings.removeVanillaData - name = toAlnum(originalObj.name) + name = f"{toAlnum(originalObj.name)}_dl" overlayName = settings.actorOverlayName flipbookUses2DArray = settings.flipbookUses2DArray flipbookArrayIndex2D = settings.flipbookArrayIndex2D if flipbookUses2DArray else None From 71c5786296e1f8bd645e79603c12f06447a04ff8 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Mon, 10 Nov 2025 02:03:50 +0100 Subject: [PATCH 3/4] fixed oot dl exporter --- fast64_internal/f3d/f3d_gbi.py | 26 ++++++++++++++++++-------- fast64_internal/f3d/f3d_writer.py | 11 +++++++++-- fast64_internal/z64/f3d/operators.py | 12 ++++++------ fast64_internal/z64/f3d/properties.py | 5 +---- fast64_internal/z64/model_classes.py | 7 ++++++- 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/fast64_internal/f3d/f3d_gbi.py b/fast64_internal/f3d/f3d_gbi.py index a7dca2ab3..363e995df 100644 --- a/fast64_internal/f3d/f3d_gbi.py +++ b/fast64_internal/f3d/f3d_gbi.py @@ -2078,7 +2078,8 @@ def vertexScrollToC(self, fMaterial: FMaterial, vtxListName: str, vtxCount: int) """ return CScrollData() - def drawToC(self, f3d: F3D, gfxList: "GfxList") -> CData: + # `layer`` argument used for Z64 overrides + def drawToC(self, f3d: F3D, gfxList: "GfxList", layer: Optional[str] = None) -> CData: """ Called for building the entry point DL for drawing a model. """ @@ -2199,8 +2200,8 @@ def to_binary(self, f3d, segments): data.extend(command.to_binary(f3d, segments)) return data - def to_c_static(self): - data = f"Gfx {self.name}[] = {{\n" + def to_c_static(self, name: str): + data = f"Gfx {name}[] = {{\n" for command in self.commands: data += f"\t{command.to_c(True)},\n" data += "};\n\n" @@ -2213,16 +2214,19 @@ def to_c_dynamic(self): data += "\treturn glistp;\n}\n\n" return data - def to_c(self, f3d): + def to_c(self, f3d, name_override: Optional[str] = None): data = CData() + name = name_override if name_override is not None else self.name + if self.DLFormat == DLFormat.Static: - data.header = f"extern Gfx {self.name}[];\n" - data.source = self.to_c_static() + data.header = f"extern Gfx {name}[];\n" + data.source = self.to_c_static(name) elif self.DLFormat == DLFormat.Dynamic: - data.header = f"Gfx* {self.name}(Gfx* glistp);\n" + data.header = f"Gfx* {name}(Gfx* glistp);\n" data.source = self.to_c_dynamic() else: raise PluginError("Invalid GfxList format: " + str(self.DLFormat)) + return data @@ -2942,13 +2946,19 @@ def save_binary(self, romfile, f3d, segments): def to_c(self, f3d: F3D, gfxFormatter: GfxFormatter): staticData = CData() + if self.cullVertexList is not None: staticData.append(self.cullVertexList.to_c()) + for triGroup in self.triangleGroups: staticData.append(triGroup.to_c(f3d, gfxFormatter)) - dynamicData = gfxFormatter.drawToC(f3d, self.draw) + + draw_layer = "Opaque" if "Opaque" in self.name else "Transparent" if "Transparent" in self.name else "Overlay" + dynamicData = gfxFormatter.drawToC(f3d, self.draw, layer=draw_layer) + for cmd_list in self.draw_overrides: dynamicData.append(cmd_list.to_c(f3d)) + return staticData, dynamicData diff --git a/fast64_internal/f3d/f3d_writer.py b/fast64_internal/f3d/f3d_writer.py index b9126e6d3..7514d1793 100644 --- a/fast64_internal/f3d/f3d_writer.py +++ b/fast64_internal/f3d/f3d_writer.py @@ -413,7 +413,14 @@ def saveMeshWithLargeTexturesByFaces( # Make sure to set original_name before calling this # used when duplicating an object def saveStaticModel( - triConverterInfo, fModel, obj, transformMatrix, ownerName, convertTextureData, revertMatAtEnd, drawLayerField + triConverterInfo, + fModel: FModel, + obj, + transformMatrix, + ownerName: str, + convertTextureData, + revertMatAtEnd: bool, + drawLayerField, ): if len(obj.data.polygons) == 0: return None @@ -433,7 +440,7 @@ def saveStaticModel( if mat_index in faces_by_mat } - fMeshes = {} + fMeshes: dict[str, FMesh] = {} for material_index, faces in faces_by_mat.items(): material = obj.material_slots[material_index].material diff --git a/fast64_internal/z64/f3d/operators.py b/fast64_internal/z64/f3d/operators.py index 0495e3ce2..69195ccc5 100644 --- a/fast64_internal/z64/f3d/operators.py +++ b/fast64_internal/z64/f3d/operators.py @@ -2,14 +2,15 @@ import os import mathutils -from bpy.types import Operator, Mesh +from bpy.types import Operator from bpy.ops import object from bpy.path import abspath from bpy.utils import register_class, unregister_class from mathutils import Matrix + from ...utility import CData, PluginError, raisePluginError, writeCData, toAlnum from ...f3d.f3d_parser import importMeshC, getImportData -from ...f3d.f3d_gbi import DLFormat, F3D, TextureExportSettings, ScrollMethod, get_F3D_GBI +from ...f3d.f3d_gbi import DLFormat, TextureExportSettings, ScrollMethod, get_F3D_GBI from ...f3d.f3d_writer import TriangleConverterInfo, removeDL, saveStaticModel, getInfoDict from ..utility import ootGetObjectPath, ootGetObjectHeaderPath, getOOTScale from ..model_classes import OOTF3DContext, ootGetIncludedAssetData @@ -38,9 +39,8 @@ def ootConvertMeshToC( folderName = settings.folder exportPath = bpy.path.abspath(settings.customPath) isCustomExport = settings.isCustom - drawLayer = settings.drawLayer removeVanillaData = settings.removeVanillaData - name = f"{toAlnum(originalObj.name)}_dl" + name = toAlnum(originalObj.name) overlayName = settings.actorOverlayName flipbookUses2DArray = settings.flipbookUses2DArray flipbookArrayIndex2D = settings.flipbookArrayIndex2D if flipbookUses2DArray else None @@ -48,14 +48,14 @@ def ootConvertMeshToC( try: obj, allObjs = ootDuplicateHierarchy(originalObj, None, False, OOTObjectCategorizer()) - fModel = OOTModel(name, DLFormat, drawLayer) + fModel = OOTModel(name, DLFormat, None) triConverterInfo = TriangleConverterInfo(obj, None, fModel.f3d, finalTransform, getInfoDict(obj)) fMeshes = saveStaticModel( triConverterInfo, fModel, obj, finalTransform, fModel.name, not saveTextures, False, "oot" ) # Since we provide a draw layer override, there should only be one fMesh. - for drawLayer, fMesh in fMeshes.items(): + for fMesh in fMeshes.values(): fMesh.draw.name = name ootCleanupScene(originalObj, allObjs) diff --git a/fast64_internal/z64/f3d/properties.py b/fast64_internal/z64/f3d/properties.py index f2f1ca742..4f29b0e8b 100644 --- a/fast64_internal/z64/f3d/properties.py +++ b/fast64_internal/z64/f3d/properties.py @@ -1,8 +1,7 @@ -import bpy - from bpy.types import PropertyGroup, Object, World, Material, UILayout from bpy.props import PointerProperty, StringProperty, BoolProperty, EnumProperty, IntProperty, FloatProperty from bpy.utils import register_class, unregister_class + from ...f3d.f3d_material import update_world_default_rendermode from ...f3d.f3d_parser import ootEnumDrawLayers from ...utility import prop_split @@ -19,7 +18,6 @@ class OOTDLExportSettings(PropertyGroup): name="Use Custom Path", description="Determines whether or not to export to an explicitly specified folder" ) removeVanillaData: BoolProperty(name="Replace Vanilla DLs") - drawLayer: EnumProperty(name="Draw Layer", items=ootEnumDrawLayers) actorOverlayName: StringProperty(name="Overlay", default="") flipbookUses2DArray: BoolProperty(name="Has 2D Flipbook Array", default=False) flipbookArrayIndex2D: IntProperty(name="Index if 2D Array", default=0, min=0) @@ -45,7 +43,6 @@ def draw_props(self, layout: UILayout): box = layout.box().column() prop_split(box, self, "flipbookArrayIndex2D", "Flipbook Index") - prop_split(layout, self, "drawLayer", "Export Draw Layer") layout.prop(self, "isCustom") layout.prop(self, "removeVanillaData") diff --git a/fast64_internal/z64/model_classes.py b/fast64_internal/z64/model_classes.py index 9973d48b8..c97c4bd93 100644 --- a/fast64_internal/z64/model_classes.py +++ b/fast64_internal/z64/model_classes.py @@ -1,5 +1,6 @@ import bpy, os, re, mathutils -from typing import Union +from typing import Union, Optional + from ..f3d.f3d_parser import F3DContext, F3DTextureReference, getImportData from ..f3d.f3d_material import TextureProperty, createF3DMat, texFormatOf, texBitSizeF3D from ..utility import PluginError, hexOrDecInt, create_or_get_world @@ -304,6 +305,10 @@ class OOTGfxFormatter(GfxFormatter): def __init__(self, scrollMethod): GfxFormatter.__init__(self, scrollMethod, 64, None) + # override the function to give a custom name to the DL array + def drawToC(self, f3d, gfxList, layer: Optional[str] = None): + return gfxList.to_c(f3d, name_override=f"{gfxList.name}_{layer.lower()}_dl") + class OOTTriangleConverterInfo(TriangleConverterInfo): def __init__(self, obj, armature, f3d, transformMatrix, infoDict): From a854969e532bc6badf68cbbe507ef2b1110f38c1 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Mon, 10 Nov 2025 15:37:15 +0100 Subject: [PATCH 4/4] review --- fast64_internal/f3d/f3d_writer.py | 4 ++++ fast64_internal/sm64/sm64_f3d_writer.py | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/fast64_internal/f3d/f3d_writer.py b/fast64_internal/f3d/f3d_writer.py index 7514d1793..c8ecfcce9 100644 --- a/fast64_internal/f3d/f3d_writer.py +++ b/fast64_internal/f3d/f3d_writer.py @@ -1990,10 +1990,14 @@ def f3d_writer_register(): register_class(cls) bpy.types.Scene.matWriteMethod = bpy.props.EnumProperty(items=enumMatWriteMethod) + bpy.types.Scene.DLExportPath = bpy.props.StringProperty(name="Directory", subtype="FILE_PATH") + bpy.types.Scene.DLTexDir = bpy.props.StringProperty(name="Include Path", default="levels/bob") def f3d_writer_unregister(): for cls in reversed(f3d_writer_classes): unregister_class(cls) + del bpy.types.Scene.DLTexDir + del bpy.types.Scene.DLExportPath del bpy.types.Scene.matWriteMethod diff --git a/fast64_internal/sm64/sm64_f3d_writer.py b/fast64_internal/sm64/sm64_f3d_writer.py index ac11452b2..1aad38346 100644 --- a/fast64_internal/sm64/sm64_f3d_writer.py +++ b/fast64_internal/sm64/sm64_f3d_writer.py @@ -1013,18 +1013,11 @@ def sm64_dl_writer_register(): bpy.types.Scene.TexRectCustomExport = bpy.props.BoolProperty(name="Custom Export Path") bpy.types.Scene.TexRectExportType = bpy.props.EnumProperty(name="Export Type", items=enumHUDExportLocation) - # TODO: move them elsewhere, it's used by f3d_writer.py so we need them - bpy.types.Scene.DLExportPath = bpy.props.StringProperty(name="Directory", subtype="FILE_PATH") - bpy.types.Scene.DLTexDir = bpy.props.StringProperty(name="Include Path", default="levels/bob") - def sm64_dl_writer_unregister(): for cls in reversed(sm64_dl_writer_classes): unregister_class(cls) - del bpy.types.Scene.DLTexDir - del bpy.types.Scene.DLExportPath - del bpy.types.Scene.DLExportStart del bpy.types.Scene.DLExportEnd del bpy.types.Scene.DLExportGeoPtr