Files
2026-02-21 16:45:37 +08:00

126 lines
3.1 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
{
get
{
return Mathf.Sqrt(_Kx * _Kx + _Kz * _Kz);
}
}
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) ? 0.707107f : (kx / k));
_Nky = ((k == 0f) ? 0.707107f : (kz / k));
_Amplitude = 2f * amplitude;
_Offset = 0f;
_W = w;
_CPUPriority = ((!(amplitude >= 0f)) ? (0f - amplitude) : amplitude);
}
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)
{
float num = _Kx * x + _Kz * z;
int num2 = (int)((num + t * _W + _Offset) * 325.949f) & 0x7FF;
float num3 = FastMath.Sines[num2];
float num4 = FastMath.Cosines[num2];
float num5 = _Amplitude * num3;
float num6 = _Amplitude * num4;
result.x += _Nkx * num5;
result.z += _Nky * num5;
result.y += num6;
result.w += num5;
}
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)
{
float num = _Kx * x + _Kz * z;
float s;
float c;
FastMath.SinCos2048(num + t * _W + _Offset, out s, out c);
c *= _Amplitude;
return new Vector3(_Nkx * c, s * _Amplitude, _Nky * c);
}
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)) ? (0f - _Amplitude) : _Amplitude);
}
}
}