Skip to content

Commit

Permalink
added reverts to all switch children that were last drawn, instead of…
Browse files Browse the repository at this point in the history
… just the last ones in the geo layout hierarchy (#353)

Co-authored-by: scut <scut>
  • Loading branch information
Scut authored May 28, 2024
1 parent 0434299 commit 1d2e6ae
Showing 1 changed file with 29 additions and 14 deletions.
43 changes: 29 additions & 14 deletions fast64_internal/sm64/sm64_geolayout_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,34 +343,49 @@ def appendRevertToGeolayout(geolayoutGraph, fModel):
revertMatAndEndDraw(materialRevert, [DPSetEnvColor(0xFF, 0xFF, 0xFF, 0xFF), DPSetAlphaCompare("G_AC_NONE")])

# walk the geo layout graph to find the last used DL for each layer
last_gfx_list = dict()

def walk(node, last_gfx_list):
# each switch child will be considered a last used DL, unless subsequent
# DL is drawn outside switch root
def walk(node, last_gfx_list: list[dict]):
base_node = node.node
if type(base_node) == JumpNode:
if base_node.geolayout:
for node in base_node.geolayout.nodes:
last_gfx_list = walk(node, last_gfx_list)
else:
last_materials = dict()
fMesh = getattr(base_node, "fMesh", None)
if fMesh:
cmd_list = fMesh.drawMatOverrides.get(base_node.override_hash, None) or fMesh.draw
last_gfx_list[base_node.drawLayer] = cmd_list
for draw_layer_dict in last_gfx_list:
draw_layer_dict[base_node.drawLayer] = cmd_list
switch_gfx_lists = []
for child in node.children:
last_gfx_list = walk(child, last_gfx_list)
if type(base_node) == SwitchNode:
switch_gfx_lists.extend(walk(child, [dict()]))
else:
last_gfx_list = walk(child, last_gfx_list)
# update the non switch nodes with the last switch node of each layer drawn
# that node will be overridden by at least one of the switch nodes
# for that layer, later items in the list will cover unique switch nodes
if switch_gfx_lists:
for draw_layer_dict in last_gfx_list:
draw_layer_dict.update(switch_gfx_lists[-1])
last_gfx_list.extend(switch_gfx_lists)
return last_gfx_list

for node in geolayoutGraph.startGeolayout.nodes:
last_gfx_list = walk(node, last_gfx_list)
last_gfx_list = walk(node, [dict()])

# Revert settings in each draw layer
for gfx_list in last_gfx_list.values():
# remove SPEndDisplayList from gfx_list, materialRevert has its own SPEndDisplayList cmd
while SPEndDisplayList() in gfx_list.commands:
gfx_list.commands.remove(SPEndDisplayList())
# Revert settings in each unique draw layer
reverted_gfx_lists = set()
for draw_layer_dict in last_gfx_list:
for gfx_list in draw_layer_dict.values():
if gfx_list in reverted_gfx_lists:
continue
# remove SPEndDisplayList from gfx_list, materialRevert has its own SPEndDisplayList cmd
while SPEndDisplayList() in gfx_list.commands:
gfx_list.commands.remove(SPEndDisplayList())

gfx_list.commands.extend(materialRevert.commands)
gfx_list.commands.extend(materialRevert.commands)
reverted_gfx_lists.add(gfx_list)


# Convert to Geolayout
Expand Down

0 comments on commit 1d2e6ae

Please sign in to comment.