773 lines
18 KiB
C#
773 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UltimateWater.Internal;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.Serialization;
|
|
|
|
namespace UltimateWater
|
|
{
|
|
[AddComponentMenu("Ultimate Water/Water (Base Component)", -1)]
|
|
public sealed class Water : MonoBehaviour, ISerializationCallbackReceiver
|
|
{
|
|
[Serializable]
|
|
public struct WeightedProfile
|
|
{
|
|
public WaterProfileData Profile;
|
|
|
|
public float Weight;
|
|
|
|
public WeightedProfile(WaterProfile profile, float weight)
|
|
{
|
|
if (profile.Data.Spectrum == null)
|
|
{
|
|
Debug.Log("spectrum not created");
|
|
}
|
|
Profile = new WaterProfileData();
|
|
Profile.Copy(profile.Data);
|
|
Profile.TemplateProfile = profile;
|
|
Weight = weight;
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class WaterEvent : UnityEvent<Water>
|
|
{
|
|
}
|
|
|
|
[Tooltip("Synchronizes dynamic preset with default water profile")]
|
|
public bool Synchronize = true;
|
|
|
|
public River River;
|
|
|
|
public bool AskForWaterCamera = true;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("shaderSet")]
|
|
private ShaderSet _ShaderSet;
|
|
|
|
[Tooltip("Set it to anything else than 0 if your game has multiplayer functionality or you want your water to behave the same way each time your game is played (good for intro etc.).")]
|
|
[SerializeField]
|
|
[FormerlySerializedAs("seed")]
|
|
private int _Seed;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("materials")]
|
|
private WaterMaterials _Materials;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("profilesManager")]
|
|
private ProfilesManager _ProfilesManager;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("geometry")]
|
|
private WaterGeometry _Geometry;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("waterRenderer")]
|
|
private WaterRenderer _WaterRenderer;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("uvAnimator")]
|
|
private WaterUvAnimator _UVAnimator;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("volume")]
|
|
private WaterVolume _Volume;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("subsurfaceScattering")]
|
|
private WaterSubsurfaceScattering _SubsurfaceScattering;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("dynamicWaterData")]
|
|
private DynamicWater.Data _DynamicWaterData;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("foamData")]
|
|
private Foam.Data _FoamData;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("planarReflectionData")]
|
|
private PlanarReflection.Data _PlanarReflectionData;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("windWavesData")]
|
|
private WindWaves.Data _WindWavesData;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("dontRotateUpwards")]
|
|
private bool _DontRotateUpwards;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("fastEnableDisable")]
|
|
private bool _FastEnableDisable;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("version")]
|
|
private float _Version = 0.4f;
|
|
|
|
private readonly List<WaterModule> _Modules = new List<WaterModule>();
|
|
|
|
private bool _ComponentsCreated;
|
|
|
|
private Vector2 _SurfaceOffset = new Vector2(float.NaN, float.NaN);
|
|
|
|
private float _Time = -1f;
|
|
|
|
private bool _RenderingEnabled = true;
|
|
|
|
private int _WaterIdCache = -1;
|
|
|
|
private static bool _IsPlaying;
|
|
|
|
private static readonly Collider[] _CollidersBuffer = new Collider[30];
|
|
|
|
private static readonly List<Water> _PossibleWaters = new List<Water>();
|
|
|
|
private static readonly List<Water> _ExcludedWaters = new List<Water>();
|
|
|
|
private static readonly float[] _CompensationStepWeights = new float[14]
|
|
{
|
|
0.85f, 0.75f, 0.83f, 0.77f, 0.85f, 0.75f, 0.85f, 0.75f, 0.83f, 0.77f,
|
|
0.85f, 0.75f, 0.85f, 0.75f
|
|
};
|
|
|
|
public LayerMask CustomEffectsLayerMask
|
|
{
|
|
get
|
|
{
|
|
return _DynamicWaterData.CustomEffectsLayerMask;
|
|
}
|
|
set
|
|
{
|
|
_DynamicWaterData.CustomEffectsLayerMask = value;
|
|
}
|
|
}
|
|
|
|
public ProfilesManager ProfilesManager => _ProfilesManager;
|
|
|
|
public WaterMaterials Materials => _Materials;
|
|
|
|
public WaterGeometry Geometry => _Geometry;
|
|
|
|
public WaterRenderer Renderer => _WaterRenderer;
|
|
|
|
public WaterVolume Volume
|
|
{
|
|
get
|
|
{
|
|
return _Volume;
|
|
}
|
|
set
|
|
{
|
|
_Volume = value;
|
|
}
|
|
}
|
|
|
|
public WaterUvAnimator UVAnimator => _UVAnimator;
|
|
|
|
public DynamicWater DynamicWater { get; private set; }
|
|
|
|
public Foam Foam { get; private set; }
|
|
|
|
public PlanarReflection PlanarReflection { get; private set; }
|
|
|
|
public WindWaves WindWaves { get; private set; }
|
|
|
|
public WaterSubsurfaceScattering SubsurfaceScattering => _SubsurfaceScattering;
|
|
|
|
public ShaderSet ShaderSet => _ShaderSet;
|
|
|
|
public bool RenderingEnabled
|
|
{
|
|
get
|
|
{
|
|
return _RenderingEnabled;
|
|
}
|
|
set
|
|
{
|
|
if (_RenderingEnabled == value)
|
|
{
|
|
return;
|
|
}
|
|
_RenderingEnabled = value;
|
|
if (_RenderingEnabled)
|
|
{
|
|
if (base.enabled)
|
|
{
|
|
WaterSystem.Register(this);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WaterSystem.Unregister(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
public int ComputedSamplesCount { get; private set; }
|
|
|
|
public float Density { get; private set; }
|
|
|
|
public float Gravity { get; private set; }
|
|
|
|
public float MaxHorizontalDisplacement { get; private set; }
|
|
|
|
public float MaxVerticalDisplacement { get; private set; }
|
|
|
|
public int Seed
|
|
{
|
|
get
|
|
{
|
|
return _Seed;
|
|
}
|
|
set
|
|
{
|
|
_Seed = value;
|
|
}
|
|
}
|
|
|
|
public Vector2 SurfaceOffset
|
|
{
|
|
get
|
|
{
|
|
if (!float.IsNaN(_SurfaceOffset.x))
|
|
{
|
|
return _SurfaceOffset;
|
|
}
|
|
return new Vector2(0f - base.transform.position.x, 0f - base.transform.position.z);
|
|
}
|
|
set
|
|
{
|
|
_SurfaceOffset = value;
|
|
}
|
|
}
|
|
|
|
public float Time
|
|
{
|
|
get
|
|
{
|
|
if (_Time != -1f)
|
|
{
|
|
return _Time;
|
|
}
|
|
return UnityEngine.Time.time;
|
|
}
|
|
set
|
|
{
|
|
_Time = value;
|
|
}
|
|
}
|
|
|
|
public float UniformWaterScale => base.transform.localScale.y;
|
|
|
|
public int WaterId => _WaterId;
|
|
|
|
internal int _WaterId
|
|
{
|
|
get
|
|
{
|
|
return _WaterIdCache;
|
|
}
|
|
set
|
|
{
|
|
if (_WaterIdCache != value)
|
|
{
|
|
_WaterIdCache = value;
|
|
if (this.WaterIdChanged != null)
|
|
{
|
|
this.WaterIdChanged();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public event Action WaterIdChanged;
|
|
|
|
public void ForceStartup()
|
|
{
|
|
CreateWaterComponents();
|
|
}
|
|
|
|
public void OnBeforeSerialize()
|
|
{
|
|
}
|
|
|
|
public void OnAfterDeserialize()
|
|
{
|
|
if (!_IsPlaying)
|
|
{
|
|
_ComponentsCreated = false;
|
|
}
|
|
}
|
|
|
|
public void ResetWater()
|
|
{
|
|
base.enabled = false;
|
|
OnDestroy();
|
|
_ComponentsCreated = false;
|
|
base.enabled = true;
|
|
}
|
|
|
|
public static Water CreateWater(string name, ShaderSet shaderCollection)
|
|
{
|
|
Water water = new GameObject(name).AddComponent<Water>();
|
|
water._ShaderSet = shaderCollection;
|
|
return water;
|
|
}
|
|
|
|
public static Water FindWater(Vector3 position, float radius)
|
|
{
|
|
bool isInsideSubtractiveVolume;
|
|
bool isInsideAdditiveVolume;
|
|
return FindWater(position, radius, null, out isInsideSubtractiveVolume, out isInsideAdditiveVolume);
|
|
}
|
|
|
|
public static Water FindWater(Vector3 position, float radius, out bool isInsideSubtractiveVolume, out bool isInsideAdditiveVolume)
|
|
{
|
|
return FindWater(position, radius, null, out isInsideSubtractiveVolume, out isInsideAdditiveVolume);
|
|
}
|
|
|
|
public static Water FindWater(Vector3 position, float radius, List<Water> allowedWaters, out bool isInsideSubtractiveVolume, out bool isInsideAdditiveVolume)
|
|
{
|
|
isInsideSubtractiveVolume = false;
|
|
isInsideAdditiveVolume = false;
|
|
int num = Physics.OverlapSphereNonAlloc(position, radius, _CollidersBuffer, 1 << WaterProjectSettings.Instance.WaterCollidersLayer, QueryTriggerInteraction.Collide);
|
|
_PossibleWaters.Clear();
|
|
_ExcludedWaters.Clear();
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
WaterVolumeBase waterVolume = WaterVolumeBase.GetWaterVolume(_CollidersBuffer[i]);
|
|
if (!(waterVolume != null))
|
|
{
|
|
continue;
|
|
}
|
|
if (waterVolume is WaterVolumeAdd)
|
|
{
|
|
isInsideAdditiveVolume = true;
|
|
if (allowedWaters == null || allowedWaters.Contains(waterVolume.Water))
|
|
{
|
|
_PossibleWaters.Add(waterVolume.Water);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isInsideSubtractiveVolume = true;
|
|
_ExcludedWaters.Add(waterVolume.Water);
|
|
}
|
|
}
|
|
for (int j = 0; j < _PossibleWaters.Count; j++)
|
|
{
|
|
if (!_ExcludedWaters.Contains(_PossibleWaters[j]))
|
|
{
|
|
return _PossibleWaters[j];
|
|
}
|
|
}
|
|
List<Water> boundlessWaters = ApplicationSingleton<WaterSystem>.Instance.BoundlessWaters;
|
|
int count = boundlessWaters.Count;
|
|
for (int k = 0; k < count; k++)
|
|
{
|
|
Water water = boundlessWaters[k];
|
|
if ((allowedWaters == null || allowedWaters.Contains(water)) && water.Volume.IsPointInsideMainVolume(position, radius) && !_ExcludedWaters.Contains(water))
|
|
{
|
|
return water;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
WaterQualitySettings.Instance.Changed -= OnQualitySettingsChanged;
|
|
WaterQualitySettings.Instance.Changed += OnQualitySettingsChanged;
|
|
_Geometry.Awake(this);
|
|
_WaterRenderer.Awake(this);
|
|
_Materials.Awake(this);
|
|
_ProfilesManager.Awake(this);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (!Application.isPlaying || (_FastEnableDisable && _ComponentsCreated))
|
|
{
|
|
return;
|
|
}
|
|
_IsPlaying = Application.isPlaying;
|
|
CreateWaterComponents();
|
|
if (_ComponentsCreated)
|
|
{
|
|
_ProfilesManager.OnEnable();
|
|
_Geometry.OnEnable();
|
|
_Modules.ForEach(delegate(WaterModule x)
|
|
{
|
|
x.Enable();
|
|
});
|
|
if (_RenderingEnabled)
|
|
{
|
|
WaterSystem.Register(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (Application.isPlaying && !_FastEnableDisable)
|
|
{
|
|
_Modules.ForEach(delegate(WaterModule x)
|
|
{
|
|
x.Disable();
|
|
});
|
|
_Geometry.OnDisable();
|
|
_ProfilesManager.OnDisable();
|
|
WaterSystem.Unregister(this);
|
|
}
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_FastEnableDisable)
|
|
{
|
|
_FastEnableDisable = false;
|
|
OnDisable();
|
|
}
|
|
WaterQualitySettings.Instance.Changed -= OnQualitySettingsChanged;
|
|
_Modules.ForEach(delegate(WaterModule x)
|
|
{
|
|
x.Destroy();
|
|
});
|
|
_Modules.Clear();
|
|
_Materials.OnDestroy();
|
|
_ProfilesManager.OnDestroy();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (Application.isPlaying)
|
|
{
|
|
if (!_DontRotateUpwards)
|
|
{
|
|
base.transform.eulerAngles = new Vector3(0f, base.transform.eulerAngles.y, 0f);
|
|
}
|
|
UpdateStatisticalData();
|
|
_ProfilesManager.Update();
|
|
_Geometry.Update();
|
|
for (int i = 0; i < _Modules.Count; i++)
|
|
{
|
|
_Modules[i].Update();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnValidate()
|
|
{
|
|
if (_ComponentsCreated)
|
|
{
|
|
_Modules.ForEach(delegate(WaterModule x)
|
|
{
|
|
x.Validate();
|
|
});
|
|
_ProfilesManager.OnValidate();
|
|
_Materials.OnValidate();
|
|
_Geometry.OnValidate();
|
|
_WaterRenderer.OnValidate();
|
|
}
|
|
}
|
|
|
|
public void OnDrawGizmos()
|
|
{
|
|
}
|
|
|
|
internal void OnWaterRender(WaterCamera waterCamera)
|
|
{
|
|
if (base.isActiveAndEnabled && (bool)waterCamera)
|
|
{
|
|
_Materials.OnWaterRender(waterCamera);
|
|
for (int i = 0; i < _Modules.Count; i++)
|
|
{
|
|
_Modules[i].OnWaterRender(waterCamera);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void OnWaterPostRender(WaterCamera waterCamera)
|
|
{
|
|
for (int i = 0; i < _Modules.Count; i++)
|
|
{
|
|
_Modules[i].OnWaterPostRender(waterCamera);
|
|
}
|
|
}
|
|
|
|
internal void OnSamplingStarted()
|
|
{
|
|
int computedSamplesCount = ComputedSamplesCount + 1;
|
|
ComputedSamplesCount = computedSamplesCount;
|
|
}
|
|
|
|
internal void OnSamplingStopped()
|
|
{
|
|
int computedSamplesCount = ComputedSamplesCount - 1;
|
|
ComputedSamplesCount = computedSamplesCount;
|
|
}
|
|
|
|
private void CreateWaterComponents()
|
|
{
|
|
if (!_ComponentsCreated)
|
|
{
|
|
_ComponentsCreated = true;
|
|
_Modules.Clear();
|
|
_Modules.AddRange(new List<WaterModule> { _UVAnimator, _Volume, _SubsurfaceScattering });
|
|
for (int i = 0; i < _Modules.Count; i++)
|
|
{
|
|
_Modules[i].Start(this);
|
|
}
|
|
_ProfilesManager.Changed.AddListener(OnProfilesChanged);
|
|
if (_ShaderSet.LocalEffectsSupported)
|
|
{
|
|
DynamicWater = new DynamicWater(this, _DynamicWaterData);
|
|
_Modules.Add(DynamicWater);
|
|
}
|
|
if (_ShaderSet.PlanarReflections != PlanarReflectionsMode.Disabled)
|
|
{
|
|
PlanarReflection = new PlanarReflection(this, _PlanarReflectionData);
|
|
_Modules.Add(PlanarReflection);
|
|
}
|
|
if (_ShaderSet.WindWavesMode != WindWavesRenderMode.Disabled)
|
|
{
|
|
WindWaves = new WindWaves(this, _WindWavesData);
|
|
_Modules.Add(WindWaves);
|
|
}
|
|
if (_ShaderSet.Foam)
|
|
{
|
|
Foam = new Foam(this, _FoamData);
|
|
_Modules.Add(Foam);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void OnProfilesChanged(Water water)
|
|
{
|
|
WeightedProfile[] profiles = water.ProfilesManager.Profiles;
|
|
Density = 0f;
|
|
Gravity = 0f;
|
|
for (int i = 0; i < profiles.Length; i++)
|
|
{
|
|
WaterProfileData profile = profiles[i].Profile;
|
|
float weight = profiles[i].Weight;
|
|
Density += profile.Density * weight;
|
|
Gravity -= profile.Gravity * weight;
|
|
}
|
|
}
|
|
|
|
private void OnQualitySettingsChanged()
|
|
{
|
|
OnValidate();
|
|
}
|
|
|
|
private void UpdateStatisticalData()
|
|
{
|
|
MaxHorizontalDisplacement = 0f;
|
|
MaxVerticalDisplacement = 0f;
|
|
if (WindWaves != null)
|
|
{
|
|
MaxHorizontalDisplacement = WindWaves.MaxHorizontalDisplacement;
|
|
MaxVerticalDisplacement = WindWaves.MaxVerticalDisplacement;
|
|
}
|
|
}
|
|
|
|
public Vector3 GetDisplacementAt(float x, float z)
|
|
{
|
|
Vector3 result = default(Vector3);
|
|
if (WindWaves != null)
|
|
{
|
|
CompensateHorizontalDisplacement(ref x, ref z);
|
|
return WindWaves.SpectrumResolver.GetDisplacementAt(x, z, _Time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public Vector3 GetDisplacementAt(float x, float z, float time)
|
|
{
|
|
Vector3 result = default(Vector3);
|
|
if (WindWaves != null)
|
|
{
|
|
CompensateHorizontalDisplacement(ref x, ref z);
|
|
return WindWaves.SpectrumResolver.GetDisplacementAt(x, z, time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public Vector3 GetUncompensatedDisplacementAt(float x, float z, float time)
|
|
{
|
|
if (WindWaves == null)
|
|
{
|
|
return default(Vector3);
|
|
}
|
|
return WindWaves.SpectrumResolver.GetDisplacementAt(x, z, time);
|
|
}
|
|
|
|
public Vector2 GetHorizontalDisplacementAt(float x, float z)
|
|
{
|
|
Vector2 result = default(Vector2);
|
|
if (WindWaves != null)
|
|
{
|
|
CompensateHorizontalDisplacement(ref x, ref z);
|
|
return WindWaves.SpectrumResolver.GetHorizontalDisplacementAt(x, z, _Time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public Vector2 GetHorizontalDisplacementAt(float x, float z, float time)
|
|
{
|
|
Vector2 result = default(Vector2);
|
|
if (WindWaves != null)
|
|
{
|
|
CompensateHorizontalDisplacement(ref x, ref z);
|
|
return WindWaves.SpectrumResolver.GetHorizontalDisplacementAt(x, z, time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public Vector2 GetUncompensatedHorizontalDisplacementAt(float x, float z, float time)
|
|
{
|
|
if (WindWaves == null)
|
|
{
|
|
return default(Vector2);
|
|
}
|
|
return WindWaves.SpectrumResolver.GetHorizontalDisplacementAt(x, z, time);
|
|
}
|
|
|
|
public float GetHeightAt(float x, float z)
|
|
{
|
|
float result = 0f;
|
|
if (WindWaves != null)
|
|
{
|
|
CompensateHorizontalDisplacement(ref x, ref z);
|
|
result = WindWaves.SpectrumResolver.GetHeightAt(x, z, _Time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public float GetHeightAt(float x, float z, float time)
|
|
{
|
|
float result = 0f;
|
|
if (WindWaves != null)
|
|
{
|
|
CompensateHorizontalDisplacement(ref x, ref z);
|
|
result = WindWaves.SpectrumResolver.GetHeightAt(x, z, time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public float GetUncompensatedHeightAt(float x, float z, float time)
|
|
{
|
|
if (WindWaves == null)
|
|
{
|
|
return 0f;
|
|
}
|
|
return WindWaves.SpectrumResolver.GetHeightAt(x, z, time);
|
|
}
|
|
|
|
public Vector4 GetHeightAndForcesAt(float x, float z)
|
|
{
|
|
Vector4 result = Vector4.zero;
|
|
if (WindWaves != null)
|
|
{
|
|
CompensateHorizontalDisplacement(ref x, ref z);
|
|
result = WindWaves.SpectrumResolver.GetForceAndHeightAt(x, z, _Time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public Vector4 GetHeightAndForcesAt(float x, float z, float time)
|
|
{
|
|
Vector4 result = Vector4.zero;
|
|
if (WindWaves != null)
|
|
{
|
|
CompensateHorizontalDisplacement(ref x, ref z);
|
|
result = WindWaves.SpectrumResolver.GetForceAndHeightAt(x, z, time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public Vector4 GetUncompensatedHeightAndForcesAt(float x, float z, float time)
|
|
{
|
|
if (WindWaves == null)
|
|
{
|
|
return default(Vector4);
|
|
}
|
|
return WindWaves.SpectrumResolver.GetForceAndHeightAt(x, z, time);
|
|
}
|
|
|
|
[Obsolete("Use this overload instead: GetDisplacementAt(float x, float z, float time).")]
|
|
public Vector3 GetDisplacementAt(float x, float z, float spectrumStart, float spectrumEnd, float time)
|
|
{
|
|
Vector3 result = default(Vector3);
|
|
if (WindWaves != null)
|
|
{
|
|
return WindWaves.SpectrumResolver.GetDisplacementAt(x, z, time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
[Obsolete("Use this overload instead: GetHorizontalDisplacementAt(float x, float z, float time).")]
|
|
public Vector2 GetHorizontalDisplacementAt(float x, float z, float spectrumStart, float spectrumEnd, float time)
|
|
{
|
|
Vector2 result = default(Vector2);
|
|
if (WindWaves != null)
|
|
{
|
|
return WindWaves.SpectrumResolver.GetHorizontalDisplacementAt(x, z, time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
[Obsolete("Use this overload instead: GetHeightAt(float x, float z, float time).")]
|
|
public float GetHeightAt(float x, float z, float spectrumStart, float spectrumEnd, float time)
|
|
{
|
|
float result = 0f;
|
|
if (WindWaves != null)
|
|
{
|
|
result = WindWaves.SpectrumResolver.GetHeightAt(x, z, time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
[Obsolete("Use this overload instead: GetHeightAndForcesAt(float x, float z, float time).")]
|
|
public Vector4 GetHeightAndForcesAt(float x, float z, float spectrumStart, float spectrumEnd, float time)
|
|
{
|
|
Vector4 result = Vector4.zero;
|
|
if (WindWaves != null)
|
|
{
|
|
result = WindWaves.SpectrumResolver.GetForceAndHeightAt(x, z, time);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public void CompensateHorizontalDisplacement(ref float x, ref float z, float errorTolerance = 0.045f)
|
|
{
|
|
float num = x;
|
|
float num2 = z;
|
|
SpectrumResolver spectrumResolver = WindWaves.SpectrumResolver;
|
|
Vector2 horizontalDisplacementAt = spectrumResolver.GetHorizontalDisplacementAt(x, z, _Time);
|
|
x -= horizontalDisplacementAt.x;
|
|
z -= horizontalDisplacementAt.y;
|
|
if (!(horizontalDisplacementAt.x > errorTolerance) && !(horizontalDisplacementAt.y > errorTolerance) && !(horizontalDisplacementAt.x < 0f - errorTolerance) && !(horizontalDisplacementAt.y < 0f - errorTolerance))
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < 14; i++)
|
|
{
|
|
horizontalDisplacementAt = spectrumResolver.GetHorizontalDisplacementAt(x, z, _Time);
|
|
float num3 = num - (x + horizontalDisplacementAt.x);
|
|
float num4 = num2 - (z + horizontalDisplacementAt.y);
|
|
x += num3 * _CompensationStepWeights[i];
|
|
z += num4 * _CompensationStepWeights[i];
|
|
if (num3 < errorTolerance && num4 < errorTolerance && num3 > 0f - errorTolerance && num4 > 0f - errorTolerance)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|