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().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().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().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().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().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().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().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().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().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().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().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().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().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(); 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 list = new List(); 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() == null && !hitInfo.collider.gameObject.name.Contains("RW-NonOb") && hitInfo.collider.gameObject.GetComponent() == 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().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().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; } }