Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SM64/F3D] Area fog improvements #378

Merged
merged 7 commits into from
Dec 28, 2024
Merged
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
2 changes: 1 addition & 1 deletion fast64_internal/f3d/f3d_gbi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2257,7 +2257,7 @@ def requiresKey(self, material):

class FGlobalData:
def __init__(self):
# dict of area index : FFogData
# dict of area index : FAreaData
self.area_data = {}
self.current_area_index = 1

Expand Down
33 changes: 28 additions & 5 deletions fast64_internal/f3d/f3d_material.py
Original file line number Diff line number Diff line change
Expand Up @@ -1099,10 +1099,29 @@ def ui_misc(self, f3dMat: "F3DMaterialProperty", inputCol: UILayout, showCheckBo
if showCheckBox:
inputGroup.prop(f3dMat, "set_fog", text="Set Fog")
if f3dMat.set_fog:
inputGroup.prop(f3dMat, "use_global_fog", text="Use Global Fog (SM64)")
if f3dMat.use_global_fog:
inputGroup.label(text="Only applies to levels (area fog settings).", icon="INFO")
else:
draw_fog = True
if bpy.context.scene.gameEditorMode == "SM64":
obj, area_obj = bpy.context.object.parent, None
while obj:
if obj.type == "EMPTY" and obj.sm64_obj_type == "Area Root" and obj.fast64.sm64.area.set_fog:
area_obj = obj
break
obj = obj.parent
if area_obj:
inputGroup.prop(f3dMat, "use_global_fog", text=f'Use Area "{area_obj.name}"\'s Fog')
if f3dMat.use_global_fog:
settings_col = inputGroup.column()
settings_col.enabled = not f3dMat.use_global_fog
prop_split(settings_col.row(), area_obj, "area_fog_color", "Fog Color")
prop_split(settings_col.row(), area_obj, "area_fog_position", "Fog Range")
draw_fog = False
else:
# show setting for preview
inputGroup.prop(f3dMat, "use_global_fog", text="Use Area's Fog")
inputGroup.label(
text="Preview only in this context, no area fog settings to pick up", icon="INFO"
)
if draw_fog:
prop_split(inputGroup.row(), f3dMat, "fog_color", "Fog Color")
prop_split(inputGroup.row(), f3dMat, "fog_position", "Fog Range")

Expand Down Expand Up @@ -1755,7 +1774,11 @@ def update_fog_nodes(material: Material, context: Context):
else: # If fog is not being calculated, pass in shade alpha
material.node_tree.links.new(nodes["Shade Color"].outputs["Alpha"], fogBlender.inputs["FogAmount"])

if f3dMat.use_global_fog or not f3dMat.set_fog or inherit_light_and_fog(): # Inherit fog
if (
(bpy.context.scene.gameEditorMode == "SM64" and f3dMat.use_global_fog)
or not f3dMat.set_fog
or inherit_light_and_fog()
): # Inherit fog
link_if_none_exist(material, nodes["SceneProperties"].outputs["FogColor"], nodes["FogColor"].inputs[0])
link_if_none_exist(material, nodes["GlobalFogColor"].outputs[0], fogBlender.inputs["Fog Color"])
link_if_none_exist(material, nodes["SceneProperties"].outputs["FogNear"], nodes["CalcFog"].inputs["FogNear"])
Expand Down
5 changes: 3 additions & 2 deletions fast64_internal/f3d/f3d_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1416,8 +1416,9 @@ def saveOrGetF3DMaterial(material, fModel, obj, drawLayer, convertTextureData):
fMaterial.mat_only_DL.commands.append(SPAttrOffsetZ(f3dMat.attroffs_z))

if f3dMat.set_fog and f3dMat.rdp_settings.using_fog:
if f3dMat.use_global_fog and fModel.global_data.getCurrentAreaData() is not None:
fogData = fModel.global_data.getCurrentAreaData().fog_data
area = fModel.global_data.getCurrentAreaData()
if f3dMat.use_global_fog and area and area.fog_data:
fogData = area.fog_data
fog_position = fogData.position
fog_color = fogData.color
else:
Expand Down
8 changes: 5 additions & 3 deletions fast64_internal/sm64/sm64_geolayout_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,9 +473,11 @@ def convertObjectToGeolayout(
# cameraObj = getCameraObj(camera)
meshGeolayout = saveCameraSettingsToGeolayout(geolayoutGraph, areaObj, obj, name + "_geo")
rootObj = areaObj
fModel.global_data.addAreaData(
areaObj.areaIndex, FAreaData(FFogData(areaObj.area_fog_position, areaObj.area_fog_color))
)
if areaObj.fast64.sm64.area.set_fog:
fog_data = FFogData(areaObj.area_fog_position, areaObj.area_fog_color)
else:
fog_data = None
fModel.global_data.addAreaData(areaObj.areaIndex, FAreaData(fog_data))

else:
geolayoutGraph = GeolayoutGraph(name + "_geo")
Expand Down
33 changes: 25 additions & 8 deletions fast64_internal/sm64/sm64_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,8 @@ def draw(self, context):
column = self.layout.box().column() # added just for puppycam trigger importing
box.box().label(text="SM64 Object Inspector")
obj = context.object
props = obj.fast64.sm64

prop_split(box, obj, "sm64_obj_type", "Object Type")
if obj.sm64_obj_type == "Object":
prop_split(box, obj, "sm64_model_enum", "Model")
Expand Down Expand Up @@ -1257,6 +1259,7 @@ def draw(self, context):
obj.starGetCutscenes.draw(box)

elif obj.sm64_obj_type == "Area Root":
area_props = props.area
# Code that used to be in area inspector
prop_split(box, obj, "areaIndex", "Area Index")
box.prop(obj, "noMusic", text="Disable Music")
Expand All @@ -1279,21 +1282,29 @@ def draw(self, context):
camBox.label(text="Warning: Camera modes can be overriden by area specific camera code.")
camBox.label(text="Check the switch statment in camera_course_processing() in src/game/camera.c.")

fogBox = box.box()
fogInfoBox = fogBox.box()
fogInfoBox.label(text="Warning: Fog only applies to materials that:")
fogInfoBox.label(text="- use fog")
fogInfoBox.label(text="- have global fog enabled.")
prop_split(fogBox, obj, "area_fog_color", "Area Fog Color")
prop_split(fogBox, obj, "area_fog_position", "Area Fog Position")
fog_box = box.box().column()
fog_box.prop(area_props, "set_fog")
fog_props = fog_box.column()
fog_props.enabled = area_props.set_fog
multilineLabel(
fog_props,
"All materials in the area with fog and\n"
'"Use Area\'s Fog" enabled will use these fog\n'
"settings.\n"
"Each material will have its own fog\n"
"applied as vanilla SM64 has no fog system.",
icon="INFO",
)
prop_split(fog_props, obj, "area_fog_color", "Color")
prop_split(fog_props, obj, "area_fog_position", "Position")

if obj.areaIndex == 1 or obj.areaIndex == 2 or obj.areaIndex == 3:
prop_split(box, obj, "echoLevel", "Echo Level")

if obj.areaIndex == 1 or obj.areaIndex == 2 or obj.areaIndex == 3 or obj.areaIndex == 4:
box.prop(obj, "zoomOutOnPause")

box.prop(obj.fast64.sm64.area, "disable_background")
box.prop(area_props, "disable_background")

areaLayout = box.box()
areaLayout.enabled = not obj.fast64.sm64.area.disable_background
Expand Down Expand Up @@ -2665,6 +2676,11 @@ class SM64_AreaProperties(bpy.types.PropertyGroup):
default=False,
description="Disable rendering background. Ideal for interiors or areas that should never see a background.",
)
set_fog: bpy.props.BoolProperty(
name="Set Fog Settings",
default=True,
description='All materials in the area with fog and "Use Area\'s Fog" enabled will use these fog settings. Each material will have its own fog applied as vanilla SM64 has no fog system',
)


class SM64_LevelProperties(bpy.types.PropertyGroup):
Expand Down Expand Up @@ -2953,6 +2969,7 @@ def sm64_obj_register():
size=2,
min=0,
max=0x7FFFFFFF,
step=100,
default=(985, 1000),
update=sm64_on_update_area_render_settings,
)
Expand Down
Loading