Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions fast64_internal/z64/collision/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ def execute(self, context):
try:
transform = Matrix.Scale(getOOTScale(obj.ootActorScale), 4)
settings: OOTCollisionExportSettings = context.scene.fast64.oot.collisionExportSettings
CollisionHeader.export(obj, transform, settings)
degen_tris_found_in = CollisionHeader.export(obj, transform, settings)

self.report({"INFO"}, "Success!")
if degen_tris_found_in:
details = ", ".join(f"{mesh} (material {material})" for mesh, material in degen_tris_found_in)
self.report({"WARNING"}, "Success, but skipped degenerate tris in meshes " + details)
else:
self.report({"INFO"}, "Success!")
return {"FINISHED"}
except Exception as e:
if context.mode != "OBJECT":
Expand Down
10 changes: 6 additions & 4 deletions fast64_internal/z64/exporter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class SceneExport:
"""This class is the main exporter class, it handles generating the C data and writing the files"""

@staticmethod
def create_scene(originalSceneObj: Object, transform: Matrix, exportInfo: ExportInfo) -> Scene:
def create_scene(originalSceneObj: Object, transform: Matrix, exportInfo: ExportInfo):
"""Returns and creates scene data"""
# init
if originalSceneObj.type != "EMPTY" or originalSceneObj.ootEmptyType != "Scene":
Expand All @@ -70,7 +70,7 @@ def create_scene(originalSceneObj: Object, transform: Matrix, exportInfo: Export

try:
sceneName = f"{toAlnum(exportInfo.name)}_scene"
newScene = Scene.new(
newScene, degen_tris_found_in = Scene.new(
sceneName,
originalSceneObj,
sceneObj,
Expand All @@ -85,7 +85,7 @@ def create_scene(originalSceneObj: Object, transform: Matrix, exportInfo: Export
finally:
ootCleanupScene(originalSceneObj, allObjs)

return newScene
return newScene, degen_tris_found_in

@staticmethod
def export(originalSceneObj: Object, transform: Matrix, exportInfo: ExportInfo):
Expand All @@ -94,7 +94,7 @@ def export(originalSceneObj: Object, transform: Matrix, exportInfo: ExportInfo):
from .decomp_edit.config import Config

checkObjectReference(originalSceneObj, "Scene object")
scene = SceneExport.create_scene(originalSceneObj, transform, exportInfo)
scene, degen_tris_found_in = SceneExport.create_scene(originalSceneObj, transform, exportInfo)

isCustomExport = exportInfo.isCustomExportPath
exportPath = exportInfo.exportPath
Expand Down Expand Up @@ -135,3 +135,5 @@ def export(originalSceneObj: Object, transform: Matrix, exportInfo: ExportInfo):
f"ENTR_{sceneName.upper()}_{hackerootBootOption.spawnIndex}",
hackerootBootOption,
)

return degen_tris_found_in
27 changes: 16 additions & 11 deletions fast64_internal/z64/exporter/collision/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ def getCollisionData(dataHolder: Optional[Object], transform: Matrix, useMacros:
vertexList: list[CollisionVertex] = []
colBounds: list[tuple[int, int, int]] = []

degen_tris_found_in: set[tuple[str, str]] = set()

transformFromMeshObj: dict[Object, Matrix] = {}
if dataHolder.type == "MESH" and not dataHolder.ignore_collision:
transformFromMeshObj[dataHolder] = transform
Expand All @@ -113,7 +115,7 @@ def getCollisionData(dataHolder: Optional[Object], transform: Matrix, useMacros:
for i, face in enumerate(meshObj.data.loop_triangles):
material = meshObj.material_slots[face.material_index].material
colProp = material.ootCollisionProperty
raise_error = False
is_degen_tri = False

# get bounds and vertices data
planePoint = transform @ meshObj.data.vertices[face.vertices[0]].co
Expand All @@ -138,18 +140,17 @@ def sq(val):
nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2)
magSqr = sq(nx) + sq(ny) + sq(nz)
if magSqr <= 0:
raise_error = True
is_degen_tri = True

# for walls only, see https://github.com/zeldaret/oot/blob/eb5dac74d6435baf85ced9158d3ff915ba8872ca/src/code/z_bgcheck.c#L751
if normal[1] >= -0.8 and normal[1] <= 0.5:
normal_xz = math.sqrt(sq(normal[0]) + sq(normal[2]))
if math.fabs(normal_xz) < 0.008:
raise_error = True
is_degen_tri = True

if raise_error:
raise PluginError(
f"degenerate triangle detected on mesh object '{meshObj.name}' (material name is '{material.name}')"
)
if is_degen_tri:
degen_tris_found_in.add((meshObj.name, material.name))
continue

indices: list[int] = []
for pos in [(x1, y1, z1), (x2, y2, z2), (x3, y3, z3)]:
Expand Down Expand Up @@ -212,7 +213,7 @@ def sq(val):
surfaceList.append(surface)
count += 1

return colBounds, vertexList, polyList, surfaceList
return colBounds, vertexList, polyList, surfaceList, degen_tris_found_in


@dataclass
Expand Down Expand Up @@ -242,11 +243,11 @@ def new(
settings: Optional[OOTCollisionExportSettings] = None,
):
# Ideally everything would be separated but this is complicated since it's all tied together
colBounds, vertexList, polyList, surfaceTypeList = CollisionUtility.getCollisionData(
colBounds, vertexList, polyList, surfaceTypeList, degen_tris_found_in = CollisionUtility.getCollisionData(
dataHolder, transform, useMacros, includeChildren
)

return CollisionHeader(
col_header = CollisionHeader(
name,
colBounds[0],
colBounds[1],
Expand All @@ -259,6 +260,8 @@ def new(
WaterBoxes.new(f"{sceneName}_waterBoxes", dataHolder, transform, useMacros),
)

return col_header, degen_tris_found_in

@staticmethod
def export(original_obj: Object, transform: Matrix, settings: OOTCollisionExportSettings):
"""Exports collision data as C files, this should be called to do a separate export from the scene."""
Expand All @@ -280,7 +283,7 @@ def export(original_obj: Object, transform: Matrix, settings: OOTCollisionExport
# write file
if not obj.ignore_collision:
# create the collision header
col_header = CollisionHeader.new(
col_header, degen_tris_found_in = CollisionHeader.new(
f"{name}_collisionHeader",
name,
obj,
Expand All @@ -304,6 +307,8 @@ def export(original_obj: Object, transform: Matrix, settings: OOTCollisionExport

cleanupDuplicatedObjects([obj])

return degen_tris_found_in

def getCmd(self):
"""Returns the collision header scene command"""

Expand Down
4 changes: 2 additions & 2 deletions fast64_internal/z64/exporter/scene/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def new(
)

# process collisions first so we can use it for animated materials (dumb but works!)
colHeader = CollisionHeader.new(
colHeader, degen_tris_found_in = CollisionHeader.new(
f"{name}_collisionHeader",
name,
sceneObj,
Expand Down Expand Up @@ -204,7 +204,7 @@ def new(

hasAlternateHeaders = True if len(altHeader.cutscenes) > 0 else hasAlternateHeaders
altHeader = altHeader if hasAlternateHeaders else None
return Scene(name, model, mainHeader, altHeader, rooms, colHeader, hasAlternateHeaders)
return Scene(name, model, mainHeader, altHeader, rooms, colHeader, hasAlternateHeaders), degen_tris_found_in

def validateRoomIndices(self):
"""Checks if there are multiple rooms with the same room index"""
Expand Down
8 changes: 6 additions & 2 deletions fast64_internal/z64/scene/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,17 @@ def execute(self, context):
settings.auto_add_room_objects,
)

SceneExport.export(
degen_tris_found_in = SceneExport.export(
obj,
finalTransform,
exportInfo,
)

self.report({"INFO"}, "Success!")
if degen_tris_found_in:
details = ", ".join(f"{mesh} (material {material})" for mesh, material in degen_tris_found_in)
self.report({"WARNING"}, "Success, but skipped degenerate tris in meshes " + details)
else:
self.report({"INFO"}, "Success!")

# don't select the scene
for elem in context.selectable_objects:
Expand Down