This commit is contained in:
zhangjiajia
2026-05-06 16:56:59 +08:00
parent 575626d3e1
commit 81ffaaeca6
1373 changed files with 145920 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#if !d_CrestValid
#error "Your Crest package needs to be updated to be compatible with this version of <i>Crest - Shallow Water</i>."
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f038cfdad5c0c467f8fab1505c7342b8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
using UnityEditor;
using UnityEngine;
using WaveHarmonic.Crest.Editor;
namespace WaveHarmonic.Crest.ShallowWater.Editor
{
[CustomEditor(typeof(ShallowWaterSimulation))]
sealed class ShallowWaterSimulationEditor : Inspector
{
const string k_SwitchToBaked = "Switch to Baked";
const string k_SwitchToRealTime = "Switch to Real-Time";
protected override void RenderInspectorGUI()
{
base.RenderInspectorGUI();
EditorGUILayout.Space();
var target = this.target as ShallowWaterSimulation;
var padding = GUI.skin.GetStyle("HelpBox").padding;
GUI.skin.GetStyle("HelpBox").padding = new(10, 10, 10, 10);
EditorGUILayout.HelpBox($"Resolution: {target.Resolution}", MessageType.None);
GUI.skin.GetStyle("HelpBox").padding = padding;
}
protected override void RenderAfterInspectorGUI()
{
base.RenderAfterInspectorGUI();
var target = this.target as ShallowWaterSimulation;
EditorGUILayout.Space();
if (target.Mode == ShallowWaterSimulationMode.RealTime)
{
if (target._SampleDepthProbeDirectly && target._DepthProbe == null && !target.TryGetComponent(out target._DepthProbe) && GUILayout.Button("Add Depth Probe"))
{
var probe = Undo.AddComponent<DepthProbe>(target.gameObject);
probe.Managed = true;
probe.Scale = new(target._Width, target._Width);
probe.OverridePosition = target.Movable;
}
if (target.DisplacementTarget == ShallowWaterSimulationInjection.Level && target.LevelTexture != null && GUILayout.Button(k_SwitchToBaked))
{
Undo.RecordObject(target, k_SwitchToBaked);
target._Mode = ShallowWaterSimulationMode.Baked;
EditorUtility.SetDirty(target);
}
if (target.DisplacementTarget == ShallowWaterSimulationInjection.Level && GUILayout.Button("Bake Output"))
{
target.Bake();
}
if (GUILayout.Button("Reset Simulation"))
{
target.ResetSimulation();
}
if (target._DepthProbe != null && GUILayout.Button("Populate Depth Probe & Reset Simulation"))
{
target._DepthProbe.Populate();
target.ResetSimulation();
}
}
else
{
if (GUILayout.Button(k_SwitchToRealTime))
{
Undo.RecordObject(target, k_SwitchToRealTime);
target._Mode = ShallowWaterSimulationMode.RealTime;
EditorUtility.SetDirty(target);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31bee5158a29c43d1a818204ec82bd7a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,107 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
using UnityEditor;
using UnityEngine;
using WaveHarmonic.Crest.Internal;
namespace WaveHarmonic.Crest.ShallowWater.Editor
{
static class Visualizers
{
#if CREST_DEBUG
internal static Material s_VisualizeMaterial;
#endif
[DrawGizmo(GizmoType.Selected | GizmoType.NonSelected)]
static void DrawGizmos(ShallowWaterSimulation target, GizmoType type)
{
var rect = target.Rect;
if (rect != Rect.zero && type.HasFlag(GizmoType.Selected))
{
var height = target.Origin.y;
Gizmos.color = Color.magenta;
Gizmos.DrawWireCube
(
new(rect.center.x, height, rect.center.y),
new(rect.size.x, 0, rect.size.y)
);
if (target.InjectShape == ShallowWaterSimulationInjection.Level)
{
Gizmos.DrawCube
(
new(rect.center.x - rect.size.x * 0.5f + target.PaddingWidth * 0.5f, height, rect.center.y),
new(target.PaddingWidth, 0, rect.size.y)
);
Gizmos.DrawCube
(
new(rect.center.x + rect.size.x * 0.5f - target.PaddingWidth * 0.5f, height, rect.center.y),
new(target.PaddingWidth, 0, rect.size.y)
);
Gizmos.DrawCube
(
new(rect.center.x, height, rect.center.y + rect.size.y * 0.5f - target.PaddingWidth * 0.5f),
new(rect.size.x - target.PaddingWidth * 2f, 0, target.PaddingWidth)
);
Gizmos.DrawCube
(
new(rect.center.x, height, rect.center.y - rect.size.y * 0.5f + target.PaddingWidth * 0.5f),
new(rect.size.x - target.PaddingWidth * 2f, 0, target.PaddingWidth)
);
Gizmos.DrawWireCube
(
new(rect.center.x, height, rect.center.y),
new(rect.size.x - target.PaddingWidth * 2f, 0, rect.size.y - target.PaddingWidth * 2f)
);
}
}
#if CREST_DEBUG
if (target._Debug._ShowSimulationDataInScene != ShallowWaterSimulation.DebugFields.SimulationData.None)
{
var water = WaterRenderer.Instance;
if (water == null)
{
return;
}
if (s_VisualizeMaterial == null)
{
s_VisualizeMaterial = new(Shader.Find("Hidden/Crest/Debug/Visualize Texture"));
}
s_VisualizeMaterial.mainTexture = target._Debug._ShowSimulationDataInScene switch
{
ShallowWaterSimulation.DebugFields.SimulationData.Height => target._Height0,
ShallowWaterSimulation.DebugFields.SimulationData.Ground => target._GroundHeight,
ShallowWaterSimulation.DebugFields.SimulationData.VelocityX => target._VelocityX,
ShallowWaterSimulation.DebugFields.SimulationData.VelocityY => target._VelocityY,
ShallowWaterSimulation.DebugFields.SimulationData.Mask => target._Mask,
ShallowWaterSimulation.DebugFields.SimulationData.WaterLevel => target._WaterLevel,
_ => throw new System.NotImplementedException(),
};
if (s_VisualizeMaterial.mainTexture == null)
{
return;
}
s_VisualizeMaterial.SetPass(0);
Graphics.DrawMeshNow
(
Helpers.QuadMesh,
Matrix4x4.TRS(target.Origin.XNZ(water.SeaLevel) + Vector3.up, Quaternion.Euler(90f, 0, 0), Vector3.one * target._Width)
);
}
#endif
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f84a244b0410149688a75a2e39c545ff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,73 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using WaveHarmonic.Crest.Editor;
namespace WaveHarmonic.Crest.ShallowWater.Editor
{
[CustomPreview(typeof(ShallowWaterSimulation))]
sealed class Preview : TexturePreview
{
RenderTexture _TemporaryRenderTexture;
public override GUIContent GetPreviewTitle() => new("Shallow Water Simulation");
protected override Texture OriginalTexture
{
get
{
if (_TemporaryRenderTexture != null) return _TemporaryRenderTexture;
// Return on of the textures to prove initialization.
var target = this.target as ShallowWaterSimulation;
return target._GroundHeight;
}
}
public override void OnPreviewSettings()
{
base.OnPreviewSettings();
// OnPreviewSettings is called after OnPreviewGUI so release here.
RenderTexture.ReleaseTemporary(_TemporaryRenderTexture);
_TemporaryRenderTexture = null;
}
public override void Cleanup()
{
base.Cleanup();
RenderTexture.ReleaseTemporary(_TemporaryRenderTexture);
}
public override void OnPreviewGUI(Rect rect, GUIStyle background)
{
var target = this.target as ShallowWaterSimulation;
var descriptor = target._GroundHeight.descriptor;
descriptor.dimension = TextureDimension.Tex2DArray;
descriptor.volumeDepth = target._WaterLevel != null ? 6 : 5;
descriptor.useMipMap = false;
// Copy textures to a single texture array.
_TemporaryRenderTexture = RenderTexture.GetTemporary(descriptor);
Graphics.CopyTexture(target._GroundHeight, 0, _TemporaryRenderTexture, 0);
Graphics.CopyTexture(target._Height1, 0, _TemporaryRenderTexture, 1);
Graphics.CopyTexture(target._VelocityX, 0, 0, _TemporaryRenderTexture, 2, 0);
Graphics.CopyTexture(target._VelocityY, 0, 0, _TemporaryRenderTexture, 3, 0);
Graphics.CopyTexture(target._Mask, 0, _TemporaryRenderTexture, 4);
if (target._WaterLevel != null) Graphics.CopyTexture(target._WaterLevel, 0, _TemporaryRenderTexture, 5);
_TemporaryRenderTexture.name = _Slice switch
{
0 => "Ground Height",
1 => "Height",
2 => "Velocity X",
3 => "Velocity Y",
4 => "Mask",
5 => "Water Level",
_ => throw new System.NotImplementedException(),
};
base.OnPreviewGUI(rect, background);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5da89db269e744232b9c777ae18c3b59
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,184 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
using UnityEditor;
using UnityEngine;
using WaveHarmonic.Crest.Editor;
namespace WaveHarmonic.Crest.ShallowWater.Editor
{
static class Validators
{
static readonly string s_TransformName = $"<i>{nameof(Transform)}</i>";
static readonly string s_DepthProbeName = $"<i>{nameof(DepthProbe)}</i>";
static readonly string s_ShallowWaterSimulationName = $"<i>{nameof(ShallowWaterSimulation)}</i>";
static void FixSetFeatureEnabled(SerializedObject so, string paramName, bool enabled)
{
var property = so.FindProperty(paramName);
var oldValue = property.boolValue;
property.boolValue = enabled;
DecoratedDrawer.OnChange(property, oldValue);
}
[Validator(typeof(ShallowWaterSimulation))]
static bool Validate(ShallowWaterSimulation target, ValidatedHelper.ShowMessage messenger)
{
var isValid = true;
var water = Crest.Editor.Validators.Water;
if (target._InjectShape == ShallowWaterSimulationInjection.Level)
{
isValid &= Crest.Editor.Validators.ValidateLod
(
OptionalLod.Get(typeof(LevelLod)),
messenger,
water
);
}
else if (target._InjectShape == ShallowWaterSimulationInjection.Waves)
{
isValid &= Crest.Editor.Validators.ValidateLod
(
OptionalLod.Get(typeof(AnimatedWavesLod)),
messenger,
water
);
}
if (target._InjectFlow)
{
isValid &= Crest.Editor.Validators.ValidateLod
(
OptionalLod.Get(typeof(FlowLod)),
messenger,
water
);
}
if (target._InjectFoam)
{
isValid &= Crest.Editor.Validators.ValidateLod
(
OptionalLod.Get(typeof(FoamLod)),
messenger,
water
);
}
if (!target._SampleDepthProbeDirectly && target._Mode != ShallowWaterSimulationMode.Baked)
{
isValid &= Crest.Editor.Validators.ValidateLod
(
OptionalLod.Get(typeof(DepthLod)),
messenger,
water
);
}
if (target._SampleDepthProbeDirectly && target._Mode != ShallowWaterSimulationMode.Baked)
{
if (target._DepthProbe == null)
{
messenger
(
$"There is no {s_DepthProbeName} present on this <i>{nameof(GameObject)}</i>. " +
$"A {s_DepthProbeName} is often needed other than for simple cases like pools.",
$"Add a {s_DepthProbeName}.",
ValidatedHelper.MessageType.Info, target,
(x, _) =>
{
var probe = ValidatedHelper.FixAttachComponent<DepthProbe>(x);
probe.Managed = true;
probe.Scale = new(target._Width, target._Width);
probe.OverridePosition = target.Movable;
}
);
}
}
if (target.Placement != Placement.Fixed && target.SampleDepthProbeDirectly && target._DepthProbe != null && target._DepthProbe.Type == DepthProbeMode.Baked)
{
messenger
(
$"The attached {nameof(DepthProbe)} is baked, but {nameof(ShallowWaterSimulation.Placement)} is not set to {nameof(Placement.Fixed)}. " +
$"{nameof(DepthProbe)} cannot be baked at runtime, so these are incompatible.",
$"Either set the {nameof(DepthProbe)} to {nameof(DepthProbeMode.RealTime)} or set the {nameof(ShallowWaterSimulation)} to {nameof(Placement.Fixed)}.",
ValidatedHelper.MessageType.Error, target
);
}
if (target._Debug != null)
{
var isDebugging = target._Debug._SkipUpdate
|| target._Debug._SkipAdvect
|| target._Debug._SkipAdvectHeights
|| target._Debug._SkipUpdateHeight
|| target._Debug._SkipUpdateVelocities;
if (isDebugging)
{
messenger
(
"Debug options currently disable one or more stages of the simulation.",
"Enable all simulation stages.",
ValidatedHelper.MessageType.Warning, target,
(so, _) =>
{
FixSetFeatureEnabled(so, $"{nameof(ShallowWaterSimulation._Debug)}.{nameof(ShallowWaterSimulation._Debug._SkipUpdate)}", false);
FixSetFeatureEnabled(so, $"{nameof(ShallowWaterSimulation._Debug)}.{nameof(ShallowWaterSimulation._Debug._SkipUpdateHeight)}", false);
FixSetFeatureEnabled(so, $"{nameof(ShallowWaterSimulation._Debug)}.{nameof(ShallowWaterSimulation._Debug._SkipAdvect)}", false);
FixSetFeatureEnabled(so, $"{nameof(ShallowWaterSimulation._Debug)}.{nameof(ShallowWaterSimulation._Debug._SkipAdvectHeights)}", false);
FixSetFeatureEnabled(so, $"{nameof(ShallowWaterSimulation._Debug)}.{nameof(ShallowWaterSimulation._Debug._SkipUpdateVelocities)}", false);
}
);
}
if (target._Debug._ShowSimulationData)
{
messenger
(
"Debug drawing of simulation data currently active.",
"Disable debug drawing when debugging is done to hide the overlay.",
ValidatedHelper.MessageType.Info, target,
(_, property) => property.boolValue = false,
$"{nameof(ShallowWaterSimulation._Debug)}.{nameof(ShallowWaterSimulation._Debug._ShowSimulationData)}"
);
}
}
if (!target._SampleDepthProbeDirectly && target.Placement == Placement.Transform && target.TryGetComponent<DepthProbe>(out var probe) && probe.isActiveAndEnabled)
{
messenger
(
$"There is an active {nameof(DepthProbe)} on this game object, with both {nameof(ShallowWaterSimulation.SampleDepthProbeDirectly)} disabled and {nameof(ShallowWaterSimulation.Placement)} set to {Placement.Transform}. " +
"This will break the movement procedure.",
$"Either disable/remove the {nameof(DepthProbe)} or change one of those settings.",
ValidatedHelper.MessageType.Error, target
);
}
if (water == null)
{
return isValid;
}
var layers = water.AnimatedWavesLod._CollisionLayers;
var flag = CollisionLayers.DynamicWaves;
if (target._Mode == ShallowWaterSimulationMode.RealTime && water.DynamicWavesLod.Enabled && !layers.HasFlag(flag))
{
messenger
(
$"It is recommended to enable the {flag} collision layer, " +
"as this will solve a feedback loop where the water level grows perpetually.",
$"Enable {flag} collision layer",
ValidatedHelper.MessageType.Info, water,
(_, y) => y.intValue = (int)(layers | flag),
$"{nameof(WaterRenderer._AnimatedWavesLod)}.{nameof(WaterRenderer._AnimatedWavesLod._CollisionLayers)}"
);
}
return isValid;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d68ceb75915cb474e80405e20ec44df7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
{
"name": "WaveHarmonic.Crest.ShallowWater.Editor",
"rootNamespace": "",
"references": [
"GUID:7c347618730f5467f86a58f333ce21df",
"GUID:125c216bac85c4443bfd4de6bc7eda99",
"GUID:056ff2a5b2f124d468c6655552acdca5",
"GUID:1ab2a6c2a51cd4b43867788dbaee1a55",
"GUID:98db37baed0fc4b73a47a9d66f791aae"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": false,
"defineConstraints": [
"UNITY_2022_3_OR_NEWER",
"d_Crest"
],
"versionDefines": [
{
"name": "com.waveharmonic.crest",
"expression": "",
"define": "d_Crest"
},
{
"name": "com.waveharmonic.crest",
"expression": "5.6.0",
"define": "d_CrestValid"
}
],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7aedaf24b93474a0e9e30d5581dea238
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: