Files
2026-03-04 10:03:45 +08:00

116 lines
3.0 KiB
C#

using System;
using UnityEngine;
namespace UltimateWater
{
public struct WaterWave : IComparable<WaterWave>
{
private readonly ushort _U;
private readonly ushort _V;
private readonly float _Kx;
private readonly float _Kz;
private readonly float _DotOffset;
internal readonly float _Nkx;
internal readonly float _Nky;
internal readonly float _W;
internal readonly byte _ScaleIndex;
internal float _Amplitude;
internal float _CPUPriority;
internal float _Offset;
public float K => Mathf.Sqrt(_Kx * _Kx + _Kz * _Kz);
public int CompareTo(WaterWave other)
{
return other._CPUPriority.CompareTo(_CPUPriority);
}
public float GetHeightAt(float x, float z, float t)
{
float num = _Kx * x + _Kz * z;
return _Amplitude * Mathf.Sin(num + t * _W + _Offset);
}
public void GetForceAndHeightAt(float x, float z, float t, ref Vector4 result)
{
int num = (int)((_Kx * x + _Kz * z + t * _W + _Offset) * 325.949f) & 0x7FF;
float num2 = FastMath.Sines[num];
float num3 = FastMath.Cosines[num];
float num4 = _Amplitude * num2;
float num5 = _Amplitude * num3;
result.x += _Nkx * num4;
result.z += _Nky * num4;
result.y += num5;
result.w += num4;
}
public Vector2 GetRawHorizontalDisplacementAt(float x, float z, float t)
{
float num = _Kx * x + _Kz * z;
float num2 = _Amplitude * Mathf.Cos(num + t * _W + _Offset);
return new Vector2(_Nkx * num2, _Nky * num2);
}
public Vector3 GetDisplacementAt(float x, float z, float t)
{
FastMath.SinCos2048(_Kx * x + _Kz * z + t * _W + _Offset, out var s, out var c);
c *= _Amplitude;
return new Vector3(_Nkx * c, s * _Amplitude, _Nky * c);
}
public WaterWave(byte scaleIndex, float offsetX, float offsetZ, ushort u, ushort v, float kx, float kz, float k, float w, float amplitude)
{
_ScaleIndex = scaleIndex;
_DotOffset = offsetX * kx + offsetZ * kz;
_U = u;
_V = v;
_Kx = kx;
_Kz = kz;
_Nkx = ((k != 0f) ? (kx / k) : 0.707107f);
_Nky = ((k != 0f) ? (kz / k) : 0.707107f);
_Amplitude = 2f * amplitude;
_Offset = 0f;
_W = w;
_CPUPriority = ((amplitude >= 0f) ? amplitude : (0f - amplitude));
}
public void UpdateSpectralValues(Vector3[][] spectrum, Vector2 windDirection, float directionalityInv, int resolution, float horizontalScale)
{
Vector3 vector = spectrum[_ScaleIndex][_U * resolution + _V];
float num = windDirection.x * _Nkx + windDirection.y * _Nky;
float num2 = Mathf.Acos(num * 0.999f);
float num3 = Mathf.Sqrt(1f + vector.z * Mathf.Cos(2f * num2));
if (num < 0f)
{
num3 *= directionalityInv;
}
float num4 = vector.x * num3;
float num5 = vector.y * num3;
_Amplitude = 2f * Mathf.Sqrt(num4 * num4 + num5 * num5);
_Offset = Mathf.Atan2(Mathf.Abs(num4), Mathf.Abs(num5));
if (num5 > 0f)
{
_Amplitude = 0f - _Amplitude;
_Offset = 0f - _Offset;
}
if (num4 < 0f)
{
_Offset = 0f - _Offset;
}
_Offset += _DotOffset;
_CPUPriority = ((_Amplitude >= 0f) ? _Amplitude : (0f - _Amplitude));
}
}
}