144 lines
5.1 KiB
C#
144 lines
5.1 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using SplashEdit.RuntimeCode;
|
|
|
|
namespace SplashEdit.EditorCode
|
|
{
|
|
/// <summary>
|
|
/// Custom inspector for PSXSceneExporter.
|
|
/// When the component is selected and fog is enabled, activates a Unity scene-view
|
|
/// fog preview that approximates the PS1 linear fog distances.
|
|
///
|
|
/// Fog distance mapping:
|
|
/// fogFarSZ = 8000 / FogDensity (GTE SZ units)
|
|
/// fogNearSZ = fogFarSZ / 3
|
|
/// SZ is 20.12 fixed-point: SZ = (unityCoord / GTEScaling) * 4096
|
|
/// => unityDist = SZ * GTEScaling / 4096
|
|
/// => Unity fog near = (8000 / (FogDensity * 3)) * GTEScaling / 4096
|
|
/// => Unity fog far = (8000 / FogDensity) * GTEScaling / 4096
|
|
/// </summary>
|
|
[CustomEditor(typeof(PSXSceneExporter))]
|
|
public class PSXSceneExporterEditor : UnityEditor.Editor
|
|
{
|
|
// Saved RenderSettings state so we can restore it on deselect.
|
|
private bool _savedFog;
|
|
private Color _savedFogColor;
|
|
private FogMode _savedFogMode;
|
|
private float _savedFogStart;
|
|
private float _savedFogEnd;
|
|
|
|
private bool _previewActive = false;
|
|
|
|
private void OnEnable()
|
|
{
|
|
SaveAndApplyFogPreview();
|
|
// Re-apply whenever the scene is repainted (handles inspector value changes).
|
|
EditorApplication.update += OnEditorUpdate;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
EditorApplication.update -= OnEditorUpdate;
|
|
RestoreFog();
|
|
}
|
|
|
|
private void OnEditorUpdate()
|
|
{
|
|
// Keep the preview in sync when the user tweaks values in the inspector.
|
|
if (_previewActive)
|
|
ApplyFogPreview();
|
|
}
|
|
|
|
private void SaveAndApplyFogPreview()
|
|
{
|
|
_savedFog = RenderSettings.fog;
|
|
_savedFogColor = RenderSettings.fogColor;
|
|
_savedFogMode = RenderSettings.fogMode;
|
|
_savedFogStart = RenderSettings.fogStartDistance;
|
|
_savedFogEnd = RenderSettings.fogEndDistance;
|
|
|
|
_previewActive = true;
|
|
ApplyFogPreview();
|
|
}
|
|
|
|
private void ApplyFogPreview()
|
|
{
|
|
var exporter = (PSXSceneExporter)target;
|
|
if (exporter == null) return;
|
|
|
|
if (!exporter.FogEnabled)
|
|
{
|
|
// Fog disabled on the component - turn off the preview.
|
|
RenderSettings.fog = false;
|
|
return;
|
|
}
|
|
|
|
float gteScale = exporter.GTEScaling;
|
|
int density = Mathf.Clamp(exporter.FogDensity, 1, 10);
|
|
|
|
// fogFarSZ in GTE SZ units (20.12 fp); convert to Unity world-space.
|
|
// SZ = (unityDist / GTEScaling) * 4096, so unityDist = SZ * GTEScaling / 4096
|
|
float fogFarSZ = 8000f / density;
|
|
float fogNearSZ = fogFarSZ / 3f;
|
|
|
|
float fogFarUnity = fogFarSZ * gteScale / 4096f;
|
|
float fogNearUnity = fogNearSZ * gteScale / 4096f;
|
|
|
|
RenderSettings.fog = true;
|
|
RenderSettings.fogColor = exporter.FogColor;
|
|
RenderSettings.fogMode = FogMode.Linear;
|
|
RenderSettings.fogStartDistance = fogNearUnity;
|
|
RenderSettings.fogEndDistance = fogFarUnity;
|
|
}
|
|
|
|
private void RestoreFog()
|
|
{
|
|
if (!_previewActive) return;
|
|
_previewActive = false;
|
|
|
|
RenderSettings.fog = _savedFog;
|
|
RenderSettings.fogColor = _savedFogColor;
|
|
RenderSettings.fogMode = _savedFogMode;
|
|
RenderSettings.fogStartDistance = _savedFogStart;
|
|
RenderSettings.fogEndDistance = _savedFogEnd;
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
serializedObject.Update();
|
|
|
|
DrawDefaultInspector();
|
|
|
|
// Show computed fog distances when fog is enabled, so the user
|
|
// can see exactly what range the preview represents.
|
|
var exporter = (PSXSceneExporter)target;
|
|
if (exporter.FogEnabled)
|
|
{
|
|
EditorGUILayout.Space(4);
|
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
|
GUILayout.Label("Fog Preview (active in Scene view)", EditorStyles.boldLabel);
|
|
|
|
float gteScale = exporter.GTEScaling;
|
|
int density = Mathf.Clamp(exporter.FogDensity, 1, 10);
|
|
float fogFarUnity = (8000f / density) * gteScale / 4096f;
|
|
float fogNearUnity = fogFarUnity / 3f;
|
|
|
|
EditorGUILayout.LabelField("Near distance", $"{fogNearUnity:F1} Unity units");
|
|
EditorGUILayout.LabelField("Far distance", $"{fogFarUnity:F1} Unity units");
|
|
EditorGUILayout.LabelField("(PS1 SZ range)", $"{8000f / (density * 3f):F0} - {8000f / density:F0} GTE units");
|
|
EditorGUILayout.EndVertical();
|
|
|
|
// Keep preview applied as values may have changed.
|
|
ApplyFogPreview();
|
|
}
|
|
else
|
|
{
|
|
// Make sure preview is off when fog is disabled.
|
|
RenderSettings.fog = false;
|
|
}
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
}
|
|
}
|