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

1313 lines
40 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
public class RealWater : MonoBehaviour, RealWaterInterface
{
public enum Quality
{
VeryLow = 0,
Low = 1,
Medium = 2,
High = 3,
VeryHigh = 4,
Extreme = 5
}
public enum Shape
{
Square = 0,
Rectangular = 1
}
public Quality quality;
public Shape shape;
[Tooltip("If enabled the simulation will stop and start depending on whether the main input is colliding with the plane or not.")]
public AmbientSettings AmbientSettings;
public InputSmoothingSettings InputSmoothingSettings;
public ObstructionSettings ObstructionSettings;
public ObstructionTextureSettings ObstructionTextureSettings;
public IndentTextureSettings IndentTextureSettings;
public RainSettings RainSettings;
public CollisionCullingSettings collisionCullingSettings;
[Tooltip("Whether to recalculate mesh normals every simulation step.")]
public bool CalculateNormals = true;
[Tooltip("Whether to calculate tangents for the mesh (Only enable if needed, big performance hit!).")]
public bool CalculateTangents;
[Tooltip("Wave dissipation multiplier (Higher values-> Less dissipation).")]
[Range(0.9f, 0.999f)]
public float Damping = 0.97f;
[Tooltip("Scaling factor applied to wave height.")]
[Range(-12f, 12f)]
public float WaveHeight = -2f;
[Tooltip("Need to Manually assign these if not using a prefab or if using custom Meshes")]
public Meshes Meshes;
private int[] buffer1;
private int[] buffer2;
private int[] bufferCurrent;
private int[] buffer1Amb;
private int[] buffer2Amb;
private int[] bufferCurrentAmb;
private TextureScanner textureScanner;
private int columns;
private int rows;
private int baseForce = 18000000;
private Mesh waterMesh;
private bool buffer1Current = true;
private int verticesArrayLength;
private RealWaterMouseInput inputManager;
private Vector3[] vertices;
private bool allowInput = true;
private float simulationSpeed;
private float ambientTimer;
private bool visible = true;
private bool ambientStopped;
private bool ready;
private bool indentScanned;
private Renderer rend;
private bool paused = true;
private int[] obstructedPositions;
private int obstructionCounter;
private int[] obstructedTexturePositions;
private int[] obstructionTextureColumns;
private int[] obstructionTextureRows;
private int obstructionTextureCounter;
private bool obstructionsScanned;
private bool obstructionTextuReScanned;
private int[] indentTextureColumns;
private int[] indentTextureRows;
private float[] indentTextureGrayscaleValues;
private int indentTextureCounter;
private float ambientSpeedCurrent;
private float rainSpeedCurrent;
private bool obstructionTexturesEnabledCurrent;
private bool obstructionsEnabledCurrent;
private void Start()
{
AssignMesh();
if (CalculateTangents)
{
TangentSolver(waterMesh);
}
initializeVariables();
if (ObstructionSettings.ObstructionsEnabled)
{
ObstructionDetection();
}
if (ObstructionTextureSettings.ObstructionTexturesEnabled)
{
ProcessObstructionTexture();
}
if (IndentTextureSettings.IndentTextureEnabled)
{
ProcessIndentTexture();
}
if (AmbientSettings.AmbientMode)
{
InitializeAmbientMode();
return;
}
InvokeRepeating("VariableChangeCheck", 0.001f, 1f / 30f);
InvokeRepeating("RainDrops", 0.003f, 1f / RainSettings.RainSpeed);
InvokeRepeating("VisibilityCheck", 0.001f, 0.2f);
}
private void Update()
{
if (ambientTimer < AmbientSettings.AmbientStartRuntime && ready)
{
ambientTimer += Time.deltaTime;
}
}
private void AssignMesh()
{
switch (shape)
{
case Shape.Square:
switch (quality)
{
case Quality.VeryLow:
if (Meshes.VeryLow != null)
{
GetComponent<MeshFilter>().mesh = Meshes.VeryLow;
}
else
{
Debug.LogError("Mesh(Very Low) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.Low:
if (Meshes.Low != null)
{
GetComponent<MeshFilter>().mesh = Meshes.Low;
}
else
{
Debug.LogError("Mesh(Low) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.Medium:
if (Meshes.Medium != null)
{
GetComponent<MeshFilter>().mesh = Meshes.Medium;
}
else
{
Debug.LogError("Mesh(Medium) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.High:
if (Meshes.High != null)
{
GetComponent<MeshFilter>().mesh = Meshes.High;
}
else
{
Debug.LogError("Mesh(High) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.VeryHigh:
if (Meshes.VeryHigh != null)
{
GetComponent<MeshFilter>().mesh = Meshes.VeryHigh;
}
else
{
Debug.LogError("Mesh(VeryHigh) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.Extreme:
if (Meshes.Extreme != null)
{
GetComponent<MeshFilter>().mesh = Meshes.Extreme;
}
else
{
Debug.LogError("Mesh(Extreme) not assigned, please stop the game and assign mesh in the inspector");
}
break;
}
break;
case Shape.Rectangular:
switch (quality)
{
case Quality.VeryLow:
if (Meshes.VeryLow_Rect != null)
{
GetComponent<MeshFilter>().mesh = Meshes.VeryLow_Rect;
}
else
{
Debug.LogError("Mesh(Very Low_Rect) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.Low:
if (Meshes.Low_Rect != null)
{
GetComponent<MeshFilter>().mesh = Meshes.Low_Rect;
}
else
{
Debug.LogError("Mesh(Low_Rect) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.Medium:
if (Meshes.Medium_Rect != null)
{
GetComponent<MeshFilter>().mesh = Meshes.Medium_Rect;
}
else
{
Debug.LogError("Mesh(Medium_Rect) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.High:
if (Meshes.High_Rect != null)
{
GetComponent<MeshFilter>().mesh = Meshes.High_Rect;
}
else
{
Debug.LogError("Mesh(High_Rect) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.VeryHigh:
if (Meshes.VeryHigh_Rect != null)
{
GetComponent<MeshFilter>().mesh = Meshes.VeryHigh_Rect;
}
else
{
Debug.LogError("Mesh(VeryHigh_Rect) not assigned, please stop the game and assign mesh in the inspector");
}
break;
case Quality.Extreme:
if (Meshes.Extreme_Rect != null)
{
GetComponent<MeshFilter>().mesh = Meshes.Extreme_Rect;
}
else
{
Debug.LogError("Mesh(Extreme_Rect) not assigned, please stop the game and assign mesh in the inspector");
}
break;
}
break;
}
string[] array = Regex.Split(GetComponent<MeshFilter>().mesh.name, "\\D+");
int num = 0;
string[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
if (int.TryParse(array2[i], out var result))
{
switch (num)
{
case 0:
columns = result;
break;
case 1:
rows = result;
break;
}
num++;
}
}
waterMesh = ((MeshFilter)GetComponent(typeof(MeshFilter))).mesh;
}
private void initializeVariables()
{
inputManager = Object.FindObjectOfType(typeof(RealWaterMouseInput)) as RealWaterMouseInput;
rend = GetComponent<Renderer>();
vertices = waterMesh.vertices;
verticesArrayLength = vertices.Length;
buffer1 = new int[verticesArrayLength];
buffer2 = new int[verticesArrayLength];
buffer1Amb = new int[verticesArrayLength];
buffer2Amb = new int[verticesArrayLength];
bufferCurrentAmb = buffer1Amb;
bufferCurrent = buffer1;
rainSpeedCurrent = RainSettings.RainSpeed;
obstructionTexturesEnabledCurrent = ObstructionTextureSettings.ObstructionTexturesEnabled;
textureScanner = new TextureScanner(rows, columns);
ambientTimer = 0f;
AmbientSettings.AmbientModeInitial = AmbientSettings.AmbientMode;
visible = true;
}
public void Pause()
{
CancelInvoke("MainLoop");
CancelInvoke("VariableChangeCheck");
CancelInvoke("RainDrops");
CancelInvoke("SetObstructionTexture");
CancelInvoke("SetObstructions");
for (int i = 0; i < verticesArrayLength; i++)
{
buffer1[i] = 0;
buffer2[i] = 0;
vertices[i].y = 0f;
}
waterMesh.vertices = vertices;
if (CalculateNormals)
{
waterMesh.RecalculateNormals();
}
paused = true;
}
public void Play()
{
if (paused)
{
InvokeRepeating("MainLoop", 0.001f, 1f / simulationSpeed);
if (ObstructionTextureSettings.ObstructionTexturesEnabled && ObstructionTextureSettings.SetRate == ObstructionTextureSettings.setRate.Half)
{
InvokeRepeating("SetObstructionTexture", 0.008f, 1f / (simulationSpeed * 0.55f));
}
else if (ObstructionTextureSettings.ObstructionTexturesEnabled && ObstructionTextureSettings.SetRate == ObstructionTextureSettings.setRate.Full)
{
InvokeRepeating("SetObstructionTexture", 0.008f, 1f / simulationSpeed);
}
if (ObstructionSettings.ObstructionsEnabled && ObstructionSettings.SetRate == ObstructionSettings.setRate.Half)
{
InvokeRepeating("SetObstructions", 0.003f, 1f / (simulationSpeed * 0.55f));
}
else if (ObstructionSettings.ObstructionsEnabled && ObstructionSettings.SetRate == ObstructionSettings.setRate.Full)
{
InvokeRepeating("SetObstructions", 0.003f, 1f / simulationSpeed);
}
obstructionsEnabledCurrent = ObstructionSettings.ObstructionsEnabled;
obstructionTexturesEnabledCurrent = ObstructionTextureSettings.ObstructionTexturesEnabled;
InvokeRepeating("VariableChangeCheck", 0.001f, 1f / 30f);
InvokeRepeating("RainDrops", 0.003f, 1f / RainSettings.RainSpeed);
paused = false;
visible = true;
}
}
public void ObstructionDetection()
{
List<int> list = new List<int>();
Vector3 center = rend.bounds.center;
float num = rend.bounds.size.x / 2f;
float num2 = rend.bounds.size.z / 2f;
float num3 = center[0] - num;
float num4 = center[0] + num;
float num5 = center[2] + num2;
float num6 = center[2] - num2;
float num7 = (num4 - num3) / (float)(columns + 1);
float num8 = (num5 - num6) / (float)(rows + 1);
float y = center[1];
for (float num9 = num3; num9 < num4; num9 += num7)
{
for (float num10 = num6; num10 < num5; num10 += num8)
{
Vector3 vector = new Vector3(num9, y, num10);
if (Physics.Raycast(vector + Vector3.up * ObstructionSettings.heightCuttoff, Vector3.down, out var hitInfo, ObstructionSettings.heightCuttoff) && hitInfo.collider.gameObject.name != "RealWater Plane" && hitInfo.collider.gameObject.GetComponent<RealWaterCollider>() == null && !hitInfo.collider.gameObject.name.Contains("RW-NonOb") && hitInfo.collider.gameObject.GetComponent<Camera>() == null && Physics.Raycast(vector + Vector3.up * 0.01f, Vector3.down, out var hitInfo2, 0.01f) && hitInfo2.collider.gameObject.name == "RealWater Plane")
{
int num11 = (int)(hitInfo2.textureCoord.x * (float)columns);
int item = (int)(hitInfo2.textureCoord.y * (float)rows) * (columns + 1) + num11;
list.Add(item);
obstructionCounter++;
}
}
}
obstructedPositions = list.ToArray();
list.Clear();
list.TrimExcess();
obstructionsScanned = true;
}
public void ProcessObstructionTexture()
{
bool flag = true;
if (ObstructionTextureSettings.ObstructionTexture != null)
{
try
{
ObstructionTextureSettings.ObstructionTexture.GetPixel(0, 0);
}
catch (UnityException ex)
{
if (ex.Message.StartsWith("Texture '" + ObstructionTextureSettings.ObstructionTexture.name + "' is not readable"))
{
Debug.LogError("Please enable read/write for Obstruction Texture: [" + ObstructionTextureSettings.ObstructionTexture.name + "]");
flag = false;
}
}
if (flag)
{
textureScanner.setTexture(ObstructionTextureSettings.ObstructionTexture);
textureScanner.setGSCuttOff(ObstructionTextureSettings.GrayScaleCuttoff);
obstructionTextuReScanned = textureScanner.ProcessTexture();
obstructionTextureColumns = textureScanner.getCols();
obstructionTextureRows = textureScanner.getRows();
obstructionTextureCounter = textureScanner.getCount();
obstructedTexturePositions = new int[obstructionTextureCounter];
for (int i = 0; i < obstructionTextureCounter; i++)
{
obstructedTexturePositions[i] = obstructionTextureRows[i] * columns + obstructionTextureColumns[i];
}
}
}
else
{
obstructionTextuReScanned = true;
Debug.LogError("No Obstruction Texture Assigned");
}
}
public void ProcessIndentTexture()
{
bool flag = true;
if (IndentTextureSettings.IndentTexture != null)
{
try
{
IndentTextureSettings.IndentTexture.GetPixel(0, 0);
}
catch (UnityException ex)
{
if (ex.Message.StartsWith("Texture '" + IndentTextureSettings.IndentTexture.name + "' is not readable"))
{
Debug.LogError("Please enable read/write for Indent Texture: [" + IndentTextureSettings.IndentTexture.name + "]");
flag = false;
}
}
if (flag)
{
textureScanner.setTexture(IndentTextureSettings.IndentTexture);
textureScanner.setGSCuttOff(IndentTextureSettings.GrayScaleCuttoff);
indentScanned = textureScanner.ProcessTexture();
indentTextureColumns = textureScanner.getCols();
indentTextureRows = textureScanner.getRows();
indentTextureGrayscaleValues = textureScanner.getGrayscaleValues();
indentTextureCounter = textureScanner.getCount();
}
}
else
{
indentScanned = true;
Debug.LogError("No Indent Texture Assigned");
}
}
private void InitializeAmbientMode()
{
for (int i = 0; i < AmbientSettings.AmbientWaveIntensity; i++)
{
DisturbBufferAt(Random.Range(12, rows - 11), Random.Range(12, columns - 11), baseForce, ambient: true);
}
AmbientSettings.AmbientModeInitial = true;
ambientSpeedCurrent = AmbientSettings.AmbientSpeed;
if (!AmbientSettings.Interactive)
{
InvokeRepeating("AmbientMainLoop", 0.001f, 1f / AmbientSettings.AmbientSpeed);
allowInput = false;
}
else
{
InvokeRepeating("RainDrops", 0.003f, 1f / RainSettings.RainSpeed);
RainDrops();
}
SetPaused(val: false);
InvokeRepeating("VariableChangeCheck", 0.001f, 1f / 30f);
InvokeRepeating("VisibilityCheck", 0.001f, 0.2f);
}
private void VisibilityCheck()
{
if (!GetComponent<Renderer>().isVisible && ready)
{
if (!AmbientSettings.AmbientModeInitial)
{
CancelInvoke("MainLoop");
}
else if (ambientTimer > AmbientSettings.AmbientStartRuntime)
{
if (!AmbientSettings.Interactive)
{
CancelInvoke("AmbientMainLoop");
}
else
{
CancelInvoke("AmbientMainLoopInteractive");
}
ambientStopped = true;
}
CancelInvoke("VariableChangeCheck");
CancelInvoke("RainDrops");
CancelInvoke("SetObstructionTexture");
CancelInvoke("SetObstructions");
visible = false;
}
else
{
if (visible || !GetComponent<Renderer>().isVisible || !ready || paused)
{
return;
}
if (!AmbientSettings.AmbientModeInitial)
{
InvokeRepeating("MainLoop", 0.001f, 1f / simulationSpeed);
}
else if (ambientStopped && AmbientSettings.AmbientModeInitial && AmbientSettings.Interactive)
{
InvokeRepeating("AmbientMainLoopInteractive", 0.001f, 1f / simulationSpeed);
}
else if (ambientStopped && AmbientSettings.AmbientModeInitial && !AmbientSettings.Interactive)
{
InvokeRepeating("AmbientMainLoop", 0.001f, 1f / AmbientSettings.AmbientSpeed);
}
ambientStopped = false;
InvokeRepeating("RainDrops", 0.003f, 1f / RainSettings.RainSpeed);
if (!AmbientSettings.AmbientModeInitial || (AmbientSettings.AmbientModeInitial && AmbientSettings.Interactive))
{
if (ObstructionTextureSettings.ObstructionTexturesEnabled && ObstructionTextureSettings.SetRate == ObstructionTextureSettings.setRate.Half)
{
InvokeRepeating("SetObstructionTexture", 0.008f, 1f / (simulationSpeed * 0.55f));
}
else if (ObstructionTextureSettings.ObstructionTexturesEnabled && ObstructionTextureSettings.SetRate == ObstructionTextureSettings.setRate.Full)
{
InvokeRepeating("SetObstructionTexture", 0.008f, 1f / simulationSpeed);
}
}
else if (ObstructionTextureSettings.ObstructionTexturesEnabled)
{
InvokeRepeating("SetObstructionTexture", 0.003f, 1f / (AmbientSettings.AmbientSpeed * 0.55f));
}
if (ObstructionSettings.ObstructionsEnabled && ObstructionSettings.SetRate == ObstructionSettings.setRate.Half)
{
if (!AmbientSettings.AmbientModeInitial || (AmbientSettings.AmbientModeInitial && AmbientSettings.Interactive))
{
InvokeRepeating("SetObstructions", 0.003f, 1f / (simulationSpeed * 0.55f));
}
}
else if (ObstructionSettings.ObstructionsEnabled && ObstructionSettings.SetRate == ObstructionSettings.setRate.Full && (!AmbientSettings.AmbientModeInitial || (AmbientSettings.AmbientModeInitial && AmbientSettings.Interactive)))
{
InvokeRepeating("SetObstructions", 0.003f, 1f / simulationSpeed);
}
obstructionsEnabledCurrent = ObstructionSettings.ObstructionsEnabled;
obstructionTexturesEnabledCurrent = ObstructionTextureSettings.ObstructionTexturesEnabled;
InvokeRepeating("VariableChangeCheck", 0.001f, 1f / 30f);
visible = true;
}
}
public void MainLoop()
{
if (buffer1Current)
{
HugoEliasFilter(buffer2, buffer1);
bufferCurrent = buffer1;
}
else
{
HugoEliasFilter(buffer1, buffer2);
bufferCurrent = buffer2;
}
for (int i = 0; i < verticesArrayLength; i++)
{
if (InputSmoothingSettings.ClampBuffer && !IndentTextureSettings.IndentTextureEnabled)
{
bufferCurrent[i] = (int)Mathf.Clamp(bufferCurrent[i], (float)(-baseForce) * InputSmoothingSettings.Clamping, (float)baseForce * InputSmoothingSettings.Clamping);
}
else if (InputSmoothingSettings.ClampBuffer && IndentTextureSettings.DepthSettings.IndentDepth < 0f)
{
bufferCurrent[i] = (int)Mathf.Clamp(bufferCurrent[i], (float)baseForce * IndentTextureSettings.DepthSettings.IndentDepth, (float)baseForce * InputSmoothingSettings.Clamping);
}
else if (InputSmoothingSettings.ClampBuffer && IndentTextureSettings.DepthSettings.IndentDepth > 0f)
{
bufferCurrent[i] = (int)Mathf.Clamp(bufferCurrent[i], (float)(-baseForce) * ((float)baseForce * InputSmoothingSettings.Clamping), (float)baseForce * IndentTextureSettings.DepthSettings.IndentDepth);
}
vertices[i].y = (float)bufferCurrent[i] * 1E-07f * WaveHeight;
}
waterMesh.vertices = vertices;
if (CalculateNormals)
{
waterMesh.RecalculateNormals();
}
if (IndentTextureSettings.IndentTextureEnabled)
{
IndentTextureFunct();
}
buffer1Current = !buffer1Current;
}
private void AmbientMainLoop()
{
if (buffer1Current)
{
AmbientHugoEliasFilter(buffer2Amb, buffer1Amb);
bufferCurrentAmb = buffer1Amb;
}
else
{
AmbientHugoEliasFilter(buffer1Amb, buffer2Amb);
bufferCurrentAmb = buffer2Amb;
}
for (int i = 0; i < verticesArrayLength; i++)
{
if (InputSmoothingSettings.ClampBuffer)
{
bufferCurrentAmb[i] = (int)Mathf.Clamp(bufferCurrentAmb[i], (float)(-baseForce) * InputSmoothingSettings.Clamping, (float)baseForce * InputSmoothingSettings.Clamping);
}
vertices[i].y = (float)bufferCurrentAmb[i] * 1E-07f * AmbientSettings.WaveHeight;
}
waterMesh.vertices = vertices;
if (CalculateNormals)
{
waterMesh.RecalculateNormals();
}
buffer1Current = !buffer1Current;
}
private void AmbientMainLoopInteractive()
{
if (buffer1Current)
{
HugoEliasFilter(buffer2, buffer1);
bufferCurrent = buffer1;
AmbientHugoEliasFilter(buffer2Amb, buffer1Amb);
bufferCurrentAmb = buffer1Amb;
}
else
{
HugoEliasFilter(buffer1, buffer2);
bufferCurrent = buffer2;
AmbientHugoEliasFilter(buffer1Amb, buffer2Amb);
bufferCurrentAmb = buffer2Amb;
}
for (int i = 0; i < verticesArrayLength; i++)
{
if (InputSmoothingSettings.ClampBuffer && !IndentTextureSettings.IndentTextureEnabled)
{
bufferCurrent[i] = (int)Mathf.Clamp(bufferCurrent[i], (float)(-baseForce) * InputSmoothingSettings.Clamping, (float)baseForce * InputSmoothingSettings.Clamping);
}
else if (InputSmoothingSettings.ClampBuffer && IndentTextureSettings.DepthSettings.IndentDepth < 0f)
{
bufferCurrent[i] = (int)Mathf.Clamp(bufferCurrent[i], (float)baseForce * IndentTextureSettings.DepthSettings.IndentDepth, (float)baseForce * InputSmoothingSettings.Clamping);
}
else if (InputSmoothingSettings.ClampBuffer && IndentTextureSettings.DepthSettings.IndentDepth > 0f)
{
bufferCurrent[i] = (int)Mathf.Clamp(bufferCurrent[i], (float)(-baseForce) * ((float)baseForce * InputSmoothingSettings.Clamping), (float)baseForce * IndentTextureSettings.DepthSettings.IndentDepth);
}
if (InputSmoothingSettings.ClampBuffer)
{
bufferCurrentAmb[i] = (int)Mathf.Clamp(bufferCurrentAmb[i], (float)(-baseForce) * InputSmoothingSettings.Clamping, (float)baseForce * InputSmoothingSettings.Clamping);
}
vertices[i].y = (float)bufferCurrent[i] * 1E-07f * WaveHeight + (float)bufferCurrentAmb[i] * 1E-07f * AmbientSettings.WaveHeight;
}
waterMesh.vertices = vertices;
if (CalculateNormals)
{
waterMesh.RecalculateNormals();
}
if (IndentTextureSettings.IndentTextureEnabled)
{
IndentTextureFunct();
}
buffer1Current = !buffer1Current;
}
private void VariableChangeCheck()
{
if (rainSpeedCurrent != RainSettings.RainSpeed)
{
CancelInvoke("RainDrops");
InvokeRepeating("RainDrops", 0.0001f, 1f / RainSettings.RainSpeed);
rainSpeedCurrent = RainSettings.RainSpeed;
}
if (obstructionTexturesEnabledCurrent != ObstructionTextureSettings.ObstructionTexturesEnabled)
{
if (!AmbientSettings.AmbientModeInitial || (AmbientSettings.AmbientModeInitial && AmbientSettings.Interactive))
{
if (ObstructionTextureSettings.ObstructionTexturesEnabled && ObstructionTextureSettings.SetRate == ObstructionTextureSettings.setRate.Half)
{
InvokeRepeating("SetObstructionTexture", 0.003f, 1f / (simulationSpeed * 0.55f));
}
else if (ObstructionTextureSettings.ObstructionTexturesEnabled && ObstructionTextureSettings.SetRate == ObstructionTextureSettings.setRate.Full)
{
InvokeRepeating("SetObstructionTexture", 0.003f, 1f / simulationSpeed);
}
}
else if (ObstructionTextureSettings.ObstructionTexturesEnabled)
{
InvokeRepeating("SetObstructionTexture", 0.003f, 1f / (AmbientSettings.AmbientSpeed * 0.55f));
}
if (!ObstructionTextureSettings.ObstructionTexturesEnabled)
{
CancelInvoke("SetObstructionTexture");
}
obstructionTexturesEnabledCurrent = ObstructionTextureSettings.ObstructionTexturesEnabled;
}
if (obstructionsEnabledCurrent != ObstructionSettings.ObstructionsEnabled)
{
if (ObstructionSettings.ObstructionsEnabled && ObstructionSettings.SetRate == ObstructionSettings.setRate.Half)
{
if (!AmbientSettings.AmbientModeInitial || (AmbientSettings.AmbientModeInitial && AmbientSettings.Interactive))
{
InvokeRepeating("SetObstructions", 0.003f, 1f / (simulationSpeed * 0.55f));
}
}
else if (ObstructionSettings.ObstructionsEnabled && ObstructionSettings.SetRate == ObstructionSettings.setRate.Full)
{
if (!AmbientSettings.AmbientModeInitial || (AmbientSettings.AmbientModeInitial && AmbientSettings.Interactive))
{
InvokeRepeating("SetObstructions", 0.003f, 1f / simulationSpeed);
}
}
else if (!ObstructionSettings.ObstructionsEnabled)
{
CancelInvoke("SetObstructions");
}
obstructionsEnabledCurrent = ObstructionSettings.ObstructionsEnabled;
}
if (AmbientSettings.AmbientModeInitial && !AmbientSettings.Interactive && ambientSpeedCurrent != AmbientSettings.AmbientSpeed)
{
CancelInvoke("AmbientMainLoop");
InvokeRepeating("AmbientMainLoop", 0.0001f, 1f / AmbientSettings.AmbientSpeed);
CancelInvoke("SetObstructionTexture");
if (ObstructionTextureSettings.ObstructionTexturesEnabled)
{
InvokeRepeating("SetObstructionTexture", 0.003f, 1f / (AmbientSettings.AmbientSpeed * 0.55f));
}
ambientSpeedCurrent = AmbientSettings.AmbientSpeed;
}
}
private void RainDrops()
{
if (RainSettings.RainEnabled && simulationSpeed != 0f)
{
int row = Random.Range(InputSmoothingSettings.BlurRadius + 2, rows - (InputSmoothingSettings.BlurRadius + 2));
int column = Random.Range(InputSmoothingSettings.BlurRadius + 2, columns - (InputSmoothingSettings.BlurRadius + 1));
if (RainSettings.RandomRainForce)
{
RainSettings.RainForce = Random.Range(0.01f, 1f);
}
DisturbBufferAt(row, column, (int)((float)baseForce * RainSettings.RainForce), ambient: false);
}
}
public void DisturbBufferAt(int row, int column, int force, bool ambient)
{
int num;
int[] array;
if (ambient)
{
num = 10;
array = bufferCurrentAmb;
}
else
{
num = InputSmoothingSettings.BlurRadius;
array = bufferCurrent;
}
if (!allowInput)
{
return;
}
int num2 = row * (columns + 1) + column;
array[num2] = force;
if (!InputSmoothingSettings.SmoothingEnabled)
{
return;
}
for (int i = 0; i < InputSmoothingSettings.SmoothingLevel; i++)
{
for (int j = row - num; j <= row + num; j++)
{
for (int k = column - num; k <= column + num; k++)
{
array[j * (columns + 1) + k] = (array[(j - 2) * (columns + 1) + (k - 2)] + 4 * array[(j - 2) * (columns + 1) + (k - 1)] + 7 * array[(j - 2) * (columns + 1) + k] + 4 * array[(j - 2) * (columns + 1) + (k + 1)] + array[(j - 2) * (columns + 1) + (k + 2)] + 4 * array[(j - 1) * (columns + 1) + (k - 2)] + 16 * array[(j - 1) * (columns + 1) + (k - 1)] + 26 * array[(j - 1) * (columns + 1) + k] + 16 * array[(j - 1) * (columns + 1) + (k + 1)] + 4 * array[(j - 1) * (columns + 1) + (k + 2)] + 7 * array[j * (columns + 1) + (k - 2)] + 26 * array[j * (columns + 1) + (k - 1)] + 41 * array[j * (columns + 1) + k] + 26 * array[j * (columns + 1) + (k + 1)] + 7 * array[j * (columns + 1) + (k + 2)] + 4 * array[(j + 1) * (columns + 1) + (k - 2)] + 16 * array[(j + 1) * (columns + 1) + (k - 1)] + 26 * array[(j + 1) * (columns + 1) + k] + 16 * array[(j + 1) * (columns + 1) + (k + 1)] + 4 * array[(j + 1) * (columns + 1) + (k + 2)] + array[(j + 2) * (columns + 1) + (k - 2)] + 4 * array[(j + 2) * (columns + 1) + (k - 1)] + 7 * array[(j + 2) * (columns + 1) + k] + 4 * array[(j + 2) * (columns + 1) + (k + 1)] + array[(j + 2) * (columns + 1) + (k + 2)]) / 273;
}
}
}
}
private void HugoEliasFilter(int[] previousBuffer, int[] currentBuffer)
{
for (int i = columns + 1; i < verticesArrayLength - (columns + 1); i++)
{
currentBuffer[i] = (previousBuffer[i - 1] + previousBuffer[i + 1] + previousBuffer[i - (columns + 1)] + previousBuffer[i + (columns + 1)]) / 2 - currentBuffer[i];
currentBuffer[i] = (int)((float)currentBuffer[i] * Damping);
}
for (int j = 0; j < rows; j++)
{
int num = j * (columns + 1);
currentBuffer[num] = 0;
}
}
private void AmbientHugoEliasFilter(int[] previousBuffer, int[] currentBuffer)
{
for (int i = columns + 1; i < verticesArrayLength - (columns + 1); i++)
{
currentBuffer[i] = (previousBuffer[i - 1] + previousBuffer[i + 1] + previousBuffer[i - (columns + 1)] + previousBuffer[i + (columns + 1)]) / 2 - currentBuffer[i];
}
}
public void SetObstructions()
{
if (!obstructionsScanned)
{
ObstructionDetection();
}
for (int i = 0; i < obstructionCounter; i++)
{
bufferCurrent[obstructedPositions[i]] = 0;
}
}
public void SetObstructionTexture()
{
if (!obstructionTextuReScanned)
{
ProcessObstructionTexture();
}
if (ObstructionTextureSettings.ReScan)
{
obstructionTextureCounter = 0;
ProcessObstructionTexture();
}
ObstructionTextureSettings.ReScan = false;
if (ObstructionTextureSettings.useAppearanceModifiers)
{
for (int i = 0; i < obstructionTextureCounter; i++)
{
int num;
int num2;
if (ObstructionTextureSettings.Appearance.FlipImage)
{
num = rows - (int)((float)obstructionTextureRows[i] * ObstructionTextureSettings.Appearance.RowScale) + ObstructionTextureSettings.Appearance.RowOffset;
num2 = columns - (int)((float)obstructionTextureColumns[i] * ObstructionTextureSettings.Appearance.ColScale) + ObstructionTextureSettings.Appearance.ColOffset;
}
else
{
num = (int)((float)obstructionTextureRows[i] * ObstructionTextureSettings.Appearance.RowScale) + ObstructionTextureSettings.Appearance.RowOffset;
num2 = (int)((float)obstructionTextureColumns[i] * ObstructionTextureSettings.Appearance.ColScale) + ObstructionTextureSettings.Appearance.ColOffset;
}
if (num2 > 0 && num2 < columns && num > 0 && num < rows)
{
int num3 = num * (columns + 1) + num2;
bufferCurrent[num3] = 0;
if (AmbientSettings.AmbientModeInitial)
{
bufferCurrentAmb[num3] = 0;
}
}
}
}
else
{
for (int j = 0; j < obstructionTextureCounter; j++)
{
bufferCurrent[obstructedTexturePositions[j]] = 0;
}
}
}
public void Reset()
{
RealWaterCollider.reseting = true;
CancelInvoke("MainLoop");
CancelInvoke("AmbientMainLoop");
CancelInvoke("AmbientMainLoopInteractive");
CancelInvoke("SetObstructions");
CancelInvoke("SetObstructionTexture");
CancelInvoke("VisibilityCheck");
CancelInvoke("VariableChangeCheck");
obstructionCounter = 0;
obstructionTextureCounter = 0;
indentTextureCounter = 0;
indentScanned = false;
obstructionsScanned = false;
obstructionTextuReScanned = false;
AssignMesh();
if (CalculateTangents)
{
TangentSolver(waterMesh);
}
initializeVariables();
if (ObstructionSettings.ObstructionsEnabled)
{
ObstructionDetection();
if (ObstructionSettings.ObstructionsEnabled && ObstructionSettings.SetRate == ObstructionSettings.setRate.Half && !AmbientSettings.AmbientModeInitial)
{
InvokeRepeating("SetObstructions", 0.003f, 1f / (simulationSpeed * 0.55f));
}
if (ObstructionSettings.ObstructionsEnabled && ObstructionSettings.SetRate == ObstructionSettings.setRate.Full && !AmbientSettings.AmbientModeInitial)
{
InvokeRepeating("SetObstructions", 0.003f, 1f / simulationSpeed);
}
}
if (ObstructionTextureSettings.ObstructionTexturesEnabled)
{
ProcessObstructionTexture();
if (!AmbientSettings.AmbientModeInitial)
{
if (ObstructionTextureSettings.ObstructionTexturesEnabled && ObstructionTextureSettings.SetRate == ObstructionTextureSettings.setRate.Half)
{
InvokeRepeating("SetObstructionTexture", 0.003f, 1f / (simulationSpeed * 0.55f));
}
if (ObstructionTextureSettings.ObstructionTexturesEnabled && ObstructionTextureSettings.SetRate == ObstructionTextureSettings.setRate.Full)
{
InvokeRepeating("SetObstructionTexture", 0.003f, 1f / simulationSpeed);
}
}
else if (ObstructionTextureSettings.ObstructionTexturesEnabled)
{
InvokeRepeating("SetObstructionTexture", 0.003f, 1f / (AmbientSettings.AmbientSpeed * 0.55f));
}
}
if (IndentTextureSettings.IndentTextureEnabled)
{
ProcessIndentTexture();
}
if (inputManager != null)
{
inputManager.Reset();
}
allowInput = true;
if (AmbientSettings.AmbientMode)
{
ambientStopped = false;
ambientTimer = 0f;
InitializeAmbientMode();
if (AmbientSettings.Interactive)
{
InvokeRepeating("AmbientMainLoopInteractive", 0.001f, 1f / simulationSpeed);
}
}
else
{
InvokeRepeating("MainLoop", 0.001f, 1f / simulationSpeed);
InvokeRepeating("VisibilityCheck", 0.001f, 0.2f);
InvokeRepeating("VariableChangeCheck", 0.001f, 1f / 30f);
}
StartCoroutine("ColliderResetDelay");
}
private IEnumerator ColliderResetDelay()
{
yield return new WaitForSeconds(0.1f);
RealWaterCollider.reseting = false;
}
private void IndentTextureFunct()
{
if (!indentScanned)
{
ProcessIndentTexture();
}
if (IndentTextureSettings.ReScan)
{
indentTextureCounter = 0;
ProcessIndentTexture();
}
IndentTextureSettings.ReScan = false;
int num = baseForce;
for (int i = 0; i < indentTextureCounter; i++)
{
int num2;
int num3;
if (IndentTextureSettings.Appearance.FlipImage)
{
num2 = rows - (int)((float)indentTextureRows[i] * IndentTextureSettings.Appearance.RowScale + (float)IndentTextureSettings.Appearance.RowOffset);
num3 = columns - (int)((float)indentTextureColumns[i] * IndentTextureSettings.Appearance.ColScale + (float)IndentTextureSettings.Appearance.ColOffset);
}
else
{
num2 = (int)((float)indentTextureRows[i] * IndentTextureSettings.Appearance.RowScale + (float)IndentTextureSettings.Appearance.RowOffset);
num3 = (int)((float)indentTextureColumns[i] * IndentTextureSettings.Appearance.ColScale + (float)IndentTextureSettings.Appearance.ColOffset);
}
int num4 = num2 * (columns + 1) + num3;
if (IndentTextureSettings.DepthSettings.Proportionality == DepthSettings.proportionality.None)
{
num = (int)((float)baseForce * IndentTextureSettings.DepthSettings.IndentDepth);
}
else if (IndentTextureSettings.DepthSettings.Proportionality == DepthSettings.proportionality.Normal)
{
num = (int)((float)baseForce * IndentTextureSettings.DepthSettings.IndentDepth * indentTextureGrayscaleValues[i]);
}
else if (IndentTextureSettings.DepthSettings.Proportionality == DepthSettings.proportionality.Inverse)
{
num = (int)((float)baseForce * IndentTextureSettings.DepthSettings.IndentDepth * (1f - indentTextureGrayscaleValues[i]));
}
if (IndentTextureSettings.SmoothingEnabled && num3 > InputSmoothingSettings.BlurRadius + 1 && num3 < columns - InputSmoothingSettings.BlurRadius + 1 && num2 < rows - (InputSmoothingSettings.BlurRadius + 2) && num2 > InputSmoothingSettings.BlurRadius + 1)
{
bufferCurrent[num4] = num;
for (int j = 0; j < 1; j++)
{
for (int k = num2; k <= num2; k++)
{
for (int l = num3; l <= num3; l++)
{
bufferCurrent[k * (columns + 1) + l] = (bufferCurrent[(k - 2) * (columns + 1) + (l - 2)] + 4 * bufferCurrent[(k - 2) * (columns + 1) + (l - 1)] + 7 * bufferCurrent[(k - 2) * (columns + 1) + l] + 4 * bufferCurrent[(k - 2) * (columns + 1) + (l + 1)] + bufferCurrent[(k - 2) * (columns + 1) + (l + 2)] + 4 * bufferCurrent[(k - 1) * (columns + 1) + (l - 2)] + 16 * bufferCurrent[(k - 1) * (columns + 1) + (l - 1)] + 26 * bufferCurrent[(k - 1) * (columns + 1) + l] + 16 * bufferCurrent[(k - 1) * (columns + 1) + (l + 1)] + 4 * bufferCurrent[(k - 1) * (columns + 1) + (l + 2)] + 7 * bufferCurrent[k * (columns + 1) + (l - 2)] + 26 * bufferCurrent[k * (columns + 1) + (l - 1)] + 41 * bufferCurrent[k * (columns + 1) + l] + 26 * bufferCurrent[k * (columns + 1) + (l + 1)] + 7 * bufferCurrent[k * (columns + 1) + (l + 2)] + 4 * bufferCurrent[(k + 1) * (columns + 1) + (l - 2)] + 16 * bufferCurrent[(k + 1) * (columns + 1) + (l - 1)] + 26 * bufferCurrent[(k + 1) * (columns + 1) + l] + 16 * bufferCurrent[(k + 1) * (columns + 1) + (l + 1)] + 4 * bufferCurrent[(k + 1) * (columns + 1) + (l + 2)] + bufferCurrent[(k + 2) * (columns + 1) + (l - 2)] + 4 * bufferCurrent[(k + 2) * (columns + 1) + (l - 1)] + 7 * bufferCurrent[(k + 2) * (columns + 1) + l] + 4 * bufferCurrent[(k + 2) * (columns + 1) + (l + 1)] + bufferCurrent[(k + 2) * (columns + 1) + (l + 2)]) / 273;
}
}
}
}
else if (!IndentTextureSettings.SmoothingEnabled && num3 > 0 && num3 < columns && num2 > 0 && num2 < rows)
{
bufferCurrent[num4] = num;
}
}
if (IndentTextureSettings.RecalculateBounds)
{
waterMesh.RecalculateBounds();
}
}
public void SetSpeed(float s)
{
simulationSpeed = s;
}
public float GetSpeed()
{
return simulationSpeed;
}
public int GetCols()
{
return columns;
}
public int GetRows()
{
return rows;
}
public bool GetVisibility()
{
return visible;
}
public void SetReady(bool val)
{
ready = val;
}
public void SetInputPos(Vector2 pos)
{
}
public ObstructionTextureSettings GetObstructionTextureSettings()
{
return ObstructionTextureSettings;
}
public ObstructionSettings GetObstructionSettings()
{
return ObstructionSettings;
}
public bool GetPaused()
{
return paused;
}
public bool getIsLarge()
{
return false;
}
public float GetExitPauseDelay()
{
return collisionCullingSettings.exitPauseDelay;
}
public float GetInterPlanePauseDelay()
{
return collisionCullingSettings.interPlanePauseDelay;
}
public void SetExitPauseDelay(float val)
{
collisionCullingSettings.exitPauseDelay = val;
}
public void SetInterPlanePauseDelay(float val)
{
collisionCullingSettings.interPlanePauseDelay = val;
}
public bool IsFullPlaneSim()
{
return true;
}
public bool GetCollisionCulling()
{
return collisionCullingSettings.collisionCulling;
}
public void SetCollisionCulling(bool val)
{
collisionCullingSettings.collisionCulling = val;
}
public void SetPaused(bool val)
{
paused = val;
}
public bool GetAmbientMode()
{
return AmbientSettings.AmbientMode;
}
public bool GetInteractiveAmbientMode()
{
return AmbientSettings.Interactive;
}
public void EnableObstructions(bool val)
{
ObstructionSettings.ObstructionsEnabled = val;
}
public ObstructionSettings.setRate GetObstructionSetRate()
{
return ObstructionSettings.SetRate;
}
public void SetObstructionSetRate(ObstructionSettings.setRate rate)
{
ObstructionSettings.SetRate = rate;
}
public void EnableObstructionTexture(bool val)
{
ObstructionTextureSettings.ObstructionTexturesEnabled = val;
}
public void SetObstructionTextureTo(Texture2D img)
{
ObstructionTextureSettings.ObstructionTexture = img;
ObstructionTextureSettings.ReScan = true;
}
public ObstructionTextureSettings.setRate GetObstructionTextureSetRate()
{
return ObstructionTextureSettings.SetRate;
}
public void SetObstructionTextureSetRate(ObstructionTextureSettings.setRate rate)
{
ObstructionTextureSettings.SetRate = rate;
}
public void SetObstructionTextureAppearance(Appearance settings)
{
ObstructionTextureSettings.Appearance = settings;
}
public int GetSmoothingLevel()
{
return InputSmoothingSettings.SmoothingLevel;
}
public void SetSmoothingLevel(int val)
{
InputSmoothingSettings.SmoothingLevel = val;
}
public int GetBR()
{
return InputSmoothingSettings.BlurRadius;
}
public void SetBR(int val)
{
InputSmoothingSettings.BlurRadius = val;
}
public float GetDamping()
{
return Damping;
}
public void SetDamping(float val)
{
Damping = val;
}
private static void TangentSolver(Mesh theMesh)
{
int vertexCount = theMesh.vertexCount;
Vector3[] array = theMesh.vertices;
Vector3[] normals = theMesh.normals;
Vector2[] uv = theMesh.uv;
int[] triangles = theMesh.triangles;
int num = triangles.Length / 3;
Vector4[] array2 = new Vector4[vertexCount];
Vector3[] array3 = new Vector3[vertexCount];
Vector3[] array4 = new Vector3[vertexCount];
int num2 = 0;
for (int i = 0; i < num; i++)
{
int num3 = triangles[num2];
int num4 = triangles[num2 + 1];
int num5 = triangles[num2 + 2];
Vector3 vector = array[num3];
Vector3 vector2 = array[num4];
Vector3 vector3 = array[num5];
Vector2 vector4 = uv[num3];
Vector2 vector5 = uv[num4];
Vector2 vector6 = uv[num5];
float num6 = vector2.x - vector.x;
float num7 = vector3.x - vector.x;
float num8 = vector2.y - vector.y;
float num9 = vector3.y - vector.y;
float num10 = vector2.z - vector.z;
float num11 = vector3.z - vector.z;
float num12 = vector5.x - vector4.x;
float num13 = vector6.x - vector4.x;
float num14 = vector5.y - vector4.y;
float num15 = vector6.y - vector4.y;
float num16 = 1f / (num12 * num15 - num13 * num14);
Vector3 vector7 = new Vector3((num15 * num6 - num14 * num7) * num16, (num15 * num8 - num14 * num9) * num16, (num15 * num10 - num14 * num11) * num16);
Vector3 vector8 = new Vector3((num12 * num7 - num13 * num6) * num16, (num12 * num9 - num13 * num8) * num16, (num12 * num11 - num13 * num10) * num16);
array3[num3] += vector7;
array3[num4] += vector7;
array3[num5] += vector7;
array4[num3] += vector8;
array4[num4] += vector8;
array4[num5] += vector8;
num2 += 3;
}
for (int j = 0; j < vertexCount; j++)
{
Vector3 normal = normals[j];
Vector3 tangent = array3[j];
Vector3.OrthoNormalize(ref normal, ref tangent);
array2[j].x = tangent.x;
array2[j].y = tangent.y;
array2[j].z = tangent.z;
array2[j].w = ((Vector3.Dot(Vector3.Cross(normal, tangent), array4[j]) < 0f) ? (-1f) : 1f);
}
theMesh.tangents = array2;
}
}