升级6.4.升级水,升级天气

This commit is contained in:
2026-04-05 00:26:54 +08:00
parent 63bc9b5536
commit 5f7cbfb713
635 changed files with 34718 additions and 22567 deletions

View File

@@ -14,11 +14,6 @@ namespace WaveHarmonic.Crest
[AddComponentMenu(Constants.k_MenuPrefixDebug + "Collision Area Visualizer")]
sealed class CollisionAreaVisualizer : ManagedBehaviour<WaterRenderer>
{
[SerializeField, HideInInspector]
#pragma warning disable 414
int _Version = 0;
#pragma warning restore 414
[Tooltip(ICollisionProvider.k_LayerTooltip)]
[SerializeField]
internal CollisionLayer _Layer;

View File

@@ -38,12 +38,17 @@ namespace WaveHarmonic.Crest
internal static NoneProvider None { get; } = new();
internal static ICollisionProvider Create(WaterRenderer water)
{
return water.IsMultipleViewpointMode ? new CollisionQueryPerCamera(water) : new CollisionQueryWithPasses(water);
}
/// <summary>
/// Gives a flat, still water.
/// </summary>
internal sealed class NoneProvider : ICollisionProvider
{
public int Query(int _0, float _1, Vector3[] _2, Vector3[] result0, Vector3[] result1, Vector3[] result2, CollisionLayer _3 = CollisionLayer.Everything)
public int Query(int _0, float _1, Vector3[] _2, Vector3[] result0, Vector3[] result1, Vector3[] result2, CollisionLayer _3 = CollisionLayer.Everything, Vector3? _4 = null)
{
if (result0 != null) System.Array.Fill(result0, Vector3.zero);
if (result1 != null) System.Array.Fill(result1, Vector3.up);
@@ -51,7 +56,7 @@ namespace WaveHarmonic.Crest
return 0;
}
public int Query(int _0, float _1, Vector3[] _2, float[] result0, Vector3[] result1, Vector3[] result2, CollisionLayer _3 = CollisionLayer.Everything)
public int Query(int _0, float _1, Vector3[] _2, float[] result0, Vector3[] result1, Vector3[] result2, CollisionLayer _3 = CollisionLayer.Everything, Vector3? _4 = null)
{
if (result0 != null) System.Array.Fill(result0, WaterRenderer.Instance.SeaLevel);
if (result1 != null) System.Array.Fill(result1, Vector3.up);
@@ -66,12 +71,11 @@ namespace WaveHarmonic.Crest
/// <param name="heights">Resulting heights (displacement Y + sea level) at the query positions. Pass null if this information is not required.</param>
/// <param name="normals">Resulting normals at the query positions. Pass null if this information is not required.</param>
/// <param name="velocities">Resulting velocities at the query positions. Pass null if this information is not required.</param>
/// <inheritdoc cref="IQueryProvider.Query(int, float, Vector3[], int)" />
int Query(int hash, float minimumLength, Vector3[] points, float[] heights, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything);
/// <inheritdoc cref="IQueryProvider.Query(int, float, Vector3[], int, Vector3?)" />
int Query(int hash, float minimumLength, Vector3[] points, float[] heights, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything, Vector3? center = null);
/// <param name="displacements">Resulting displacement vectors at the query positions. Add sea level to Y to get world space height.</param>
/// <inheritdoc cref="IQueryProvider.Query(int, float, Vector3[], int)" />
/// <inheritdoc cref="Query(int, float, Vector3[], float[], Vector3[], Vector3[], CollisionLayer)" />
int Query(int hash, float minimumLength, Vector3[] points, Vector3[] displacements, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything);
/// <inheritdoc cref="Query(int, float, Vector3[], float[], Vector3[], Vector3[], CollisionLayer, Vector3?)" />
int Query(int hash, float minimumLength, Vector3[] points, Vector3[] displacements, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything, Vector3? center = null);
}
}

View File

@@ -2,6 +2,7 @@
// Copyright © 2024 Wave Harmonic. All rights reserved.
using UnityEngine;
using WaveHarmonic.Crest.Internal;
namespace WaveHarmonic.Crest
{
@@ -10,10 +11,10 @@ namespace WaveHarmonic.Crest
/// </summary>
sealed class CollisionQuery : QueryBase, ICollisionProvider
{
public CollisionQuery(WaterRenderer water) : base(water) { }
public CollisionQuery(WaterRenderer water) : base(water.AnimatedWavesLod) { }
protected override int Kernel => 0;
public int Query(int ownerHash, float minSpatialLength, Vector3[] queryPoints, Vector3[] resultDisplacements, Vector3[] resultNormals, Vector3[] resultVelocities, CollisionLayer layer = CollisionLayer.Everything)
public int Query(int ownerHash, float minSpatialLength, Vector3[] queryPoints, Vector3[] resultDisplacements, Vector3[] resultNormals, Vector3[] resultVelocities, CollisionLayer layer = CollisionLayer.Everything, Vector3? center = null)
{
var result = (int)QueryStatus.OK;
@@ -35,7 +36,7 @@ namespace WaveHarmonic.Crest
return result;
}
public int Query(int ownerHash, float minimumSpatialLength, Vector3[] queryPoints, float[] resultHeights, Vector3[] resultNormals, Vector3[] resultVelocities, CollisionLayer layer = CollisionLayer.Everything)
public int Query(int ownerHash, float minimumSpatialLength, Vector3[] queryPoints, float[] resultHeights, Vector3[] resultNormals, Vector3[] resultVelocities, CollisionLayer layer = CollisionLayer.Everything, Vector3? center = null)
{
var result = (int)QueryStatus.OK;
@@ -58,6 +59,102 @@ namespace WaveHarmonic.Crest
}
}
sealed class CollisionQueryPerCamera : QueryPerCamera<CollisionQueryWithPasses>, ICollisionProvider
{
public CollisionQueryPerCamera() : base(WaterRenderer.Instance) { }
public CollisionQueryPerCamera(WaterRenderer water) : base(water) { }
public int Query(int hash, float minimumLength, Vector3[] points, float[] heights, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything, Vector3? center = null)
{
if (_Water.IsSeparateViewpointCameraLoop)
{
return _Providers[_Water.CurrentCamera].Query(hash, minimumLength, points, heights, normals, velocities, layer, center);
}
var lastStatus = -1;
var lastDistance = Mathf.Infinity;
var newCenter = FindCenter(points, center);
foreach (var provider in _Providers)
{
var camera = provider.Key;
if (!_Water.ShouldExecuteQueries(camera))
{
continue;
}
var distance = (newCenter - camera.transform.position.XZ()).sqrMagnitude;
if (lastStatus == (int)QueryBase.QueryStatus.OK && lastDistance < distance)
{
continue;
}
var status = provider.Value.Query(hash, minimumLength, points, heights, normals, velocities, layer, center);
if (lastStatus < 0 || status == (int)QueryBase.QueryStatus.OK)
{
lastStatus = status;
lastDistance = distance;
}
}
return lastStatus;
}
public int Query(int hash, float minimumLength, Vector3[] points, Vector3[] displacements, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything, Vector3? center = null)
{
if (_Water.IsSeparateViewpointCameraLoop)
{
return _Providers[_Water.CurrentCamera].Query(hash, minimumLength, points, displacements, normals, velocities, layer, center);
}
var lastStatus = -1;
var lastDistance = Mathf.Infinity;
var newCenter = FindCenter(points, center);
foreach (var provider in _Providers)
{
var camera = provider.Key;
if (!_Water.ShouldExecuteQueries(camera))
{
continue;
}
var distance = (newCenter - camera.transform.position.XZ()).sqrMagnitude;
if (lastStatus == (int)QueryBase.QueryStatus.OK && lastDistance < distance)
{
continue;
}
var status = provider.Value.Query(hash, minimumLength, points, displacements, normals, velocities, layer, center);
if (lastStatus < 0 || status == (int)QueryBase.QueryStatus.OK)
{
lastStatus = status;
lastDistance = distance;
}
}
return lastStatus;
}
public void SendReadBack(WaterRenderer water, CollisionLayers layers)
{
_Providers[water.CurrentCamera].SendReadBack(water, layers);
}
public void UpdateQueries(WaterRenderer water, CollisionLayer layer)
{
_Providers[water.CurrentCamera].UpdateQueries(water, layer);
}
}
sealed class CollisionQueryWithPasses : ICollisionProvider, IQueryable
{
readonly CollisionQuery _AnimatedWaves;
@@ -69,6 +166,14 @@ namespace WaveHarmonic.Crest
public int RequestCount => _AnimatedWaves.RequestCount + _DynamicWaves.RequestCount + _Displacement.RequestCount;
public int QueryCount => _AnimatedWaves.QueryCount + _DynamicWaves.QueryCount + _Displacement.QueryCount;
public CollisionQueryWithPasses()
{
_Water = WaterRenderer.Instance;
_AnimatedWaves = new(_Water);
_DynamicWaves = new(_Water);
_Displacement = new(_Water);
}
public CollisionQueryWithPasses(WaterRenderer water)
{
_Water = water;
@@ -107,12 +212,12 @@ namespace WaveHarmonic.Crest
return _AnimatedWaves;
}
public int Query(int hash, float minimumLength, Vector3[] points, float[] heights, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything)
public int Query(int hash, float minimumLength, Vector3[] points, float[] heights, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything, Vector3? center = null)
{
return GetProvider(layer).Query(hash, minimumLength, points, heights, normals, velocities);
}
public int Query(int hash, float minimumLength, Vector3[] points, Vector3[] displacements, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything)
public int Query(int hash, float minimumLength, Vector3[] points, Vector3[] displacements, Vector3[] normals, Vector3[] velocities, CollisionLayer layer = CollisionLayer.Everything, Vector3? center = null)
{
return GetProvider(layer).Query(hash, minimumLength, points, displacements, normals, velocities);
}
@@ -151,13 +256,55 @@ namespace WaveHarmonic.Crest
_DynamicWaves.CleanUp();
_Displacement.CleanUp();
}
public void Initialize(WaterRenderer water)
{
}
}
// These are required because of collision layer.
static partial class Extensions
{
public static void UpdateQueries(this ICollisionProvider self, WaterRenderer water, CollisionLayer layer) => (self as CollisionQueryWithPasses)?.UpdateQueries(water, layer);
public static void UpdateQueries(this ICollisionProvider self, WaterRenderer water, CollisionLayer layer)
{
if (self is CollisionQueryPerCamera a)
{
a.UpdateQueries(water, layer);
}
else if (self is CollisionQueryWithPasses b)
{
b.UpdateQueries(water, layer);
}
else if (self is ICollisionProvider.NoneProvider c)
{
}
else
{
Debug.LogError("Crest: no valid query provider. Report this to developers!");
}
}
public static void UpdateQueries(this ICollisionProvider self, WaterRenderer water) => (self as IQueryable)?.UpdateQueries(water);
public static void SendReadBack(this ICollisionProvider self, WaterRenderer water, CollisionLayers layer) => (self as CollisionQueryWithPasses)?.SendReadBack(water, layer);
public static void SendReadBack(this ICollisionProvider self, WaterRenderer water, CollisionLayers layer)
{
if (self is CollisionQueryPerCamera a)
{
a.SendReadBack(water, layer);
}
else if (self is CollisionQueryWithPasses b)
{
b.SendReadBack(water, layer);
}
else if (self is ICollisionProvider.NoneProvider c)
{
}
else
{
Debug.LogError("Crest: no valid query provider. Report this to developers!");
}
}
public static void CleanUp(this ICollisionProvider self) => (self as IQueryable)?.CleanUp();
}
}

View File

@@ -59,7 +59,9 @@ namespace WaveHarmonic.Crest
{
distance = -1f;
Validate(allowMultipleCallsPerFrame: false);
var id = GetHashCode();
Validate(allowMultipleCallsPerFrame: false, id);
var water = WaterRenderer.Instance;
var provider = water == null ? null : water.AnimatedWavesLod.Provider;
@@ -70,7 +72,7 @@ namespace WaveHarmonic.Crest
_QueryPosition[i] = origin + i * _RayStepSize * direction;
}
var status = provider.Query(GetHashCode(), _MinimumLength, _QueryPosition, _QueryResult, null, null, layer);
var status = provider.Query(id, _MinimumLength, _QueryPosition, _QueryResult, null, null, layer);
if (!provider.RetrieveSucceeded(status))
{

View File

@@ -14,11 +14,6 @@ namespace WaveHarmonic.Crest
[AddComponentMenu(Constants.k_MenuPrefixDebug + "Ray Cast Visualizer")]
sealed class RayTraceVisualizer : ManagedBehaviour<WaterRenderer>
{
[SerializeField, HideInInspector]
#pragma warning disable 414
int _Version = 0;
#pragma warning restore 414
readonly RayCastHelper _RayCast = new(50f, 2f);
private protected override System.Action<WaterRenderer> OnUpdateMethod => OnUpdate;