Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/MegaDynamicRipple.cs
2026-02-21 16:45:37 +08:00

842 lines
17 KiB
C#

using System;
using UnityEngine;
[AddComponentMenu("Modifiers/Dynamic Ripple")]
public class MegaDynamicRipple : MegaModifier
{
public MegaAxis axis = MegaAxis.Y;
public int cols = 8;
public int rows = 8;
[HideInInspector]
public float[] buffer1;
[HideInInspector]
public float[] buffer2;
[HideInInspector]
public int[] vertexIndices;
public float damping = 0.999f;
public float WaveHeight = 2f;
public float Force = 1f;
public float DropsPerSec = 1f;
public float speed = 0.5f;
public float[] input;
public float inputdamp = 0.99f;
public float InputForce = 0.1f;
public bool Obstructions;
public float[] blockers;
private float time;
public float scale = 1f;
private bool swapMe = true;
public bool bilinearSample;
public Texture2D obTexture;
private Collider mycollider;
private float[] currentBuffer;
public int vertcomponent = 1;
public int wakesize = 1;
public float wakefalloff = 1f;
public float wakeforce = 1f;
private float lastcol = -1f;
private float lastrow = -1f;
private bool lastdown;
private int xc;
private int yc;
public override string ModName()
{
return "Dynamic Ripple";
}
public override string GetHelpURL()
{
return "?page_id=2395";
}
[ContextMenu("Reset Sim")]
public void ResetGrid()
{
Setup();
}
public void SetObstructions(Texture2D obtex)
{
obTexture = obtex;
if (blockers == null || blockers.Length != buffer1.Length)
{
blockers = new float[buffer1.Length];
}
if ((bool)obTexture)
{
for (int i = 0; i < rows; i++)
{
int num = i * cols;
float v = (float)i / (float)rows;
for (int j = 0; j < cols; j++)
{
float u = (float)j / (float)cols;
if (bilinearSample)
{
blockers[num + j] = obTexture.GetPixelBilinear(u, v).grayscale;
}
else
{
blockers[num + j] = obTexture.GetPixel(j, i).grayscale;
}
}
}
}
else
{
for (int k = 0; k < blockers.Length; k++)
{
blockers[k] = 1f;
}
}
}
public override void Modify(MegaModifiers mc)
{
for (int i = 0; i < verts.Length; i++)
{
Vector3 vector = verts[i];
int num = vertexIndices[i];
vector[vertcomponent] += currentBuffer[num] * scale;
sverts[i] = vector;
}
}
public override Vector3 Map(int i, Vector3 p)
{
p = tm.MultiplyPoint3x4(p);
if (i >= 0)
{
int num = vertexIndices[i];
p[vertcomponent] += currentBuffer[num] * scale;
}
return invtm.MultiplyPoint3x4(p);
}
public override bool ModLateUpdate(MegaModContext mc)
{
if (buffer1 == null || rows * cols != buffer1.Length)
{
Setup();
swapMe = false;
currentBuffer = buffer2;
return false;
}
if (swapMe)
{
processRipples(buffer1, buffer2);
currentBuffer = buffer2;
}
else
{
processRipples(buffer2, buffer1);
currentBuffer = buffer2;
}
swapMe = !swapMe;
return Prepare(mc);
}
public override bool Prepare(MegaModContext mc)
{
if (mycollider == null)
{
mycollider = GetComponent<Collider>();
}
return true;
}
private void Setup()
{
int num = rows * cols;
buffer1 = new float[num];
buffer2 = new float[num];
input = new float[num];
swapMe = false;
currentBuffer = buffer2;
vertexIndices = new int[verts.Length];
SetObstructions(obTexture);
for (int i = 0; i < num; i++)
{
buffer1[i] = 0f;
buffer2[i] = 0f;
}
int index = 0;
int index2 = 1;
Vector3 vector = bbox.Size();
if (vector.x == 0f)
{
axis = MegaAxis.X;
}
if (vector.y == 0f)
{
axis = MegaAxis.Y;
}
if (vector.z == 0f)
{
axis = MegaAxis.Z;
}
switch (axis)
{
case MegaAxis.X:
vertcomponent = 0;
index = 1;
index2 = 2;
break;
case MegaAxis.Y:
vertcomponent = 1;
index = 0;
index2 = 2;
break;
case MegaAxis.Z:
vertcomponent = 2;
index = 0;
index2 = 1;
break;
}
for (int j = 0; j < verts.Length; j++)
{
float num2 = (verts[j][index] - bbox.min[index]) / vector[index];
float num3 = (verts[j][index2] - bbox.min[index2]) / vector[index2];
if (num2 >= 1f)
{
num2 = 0.999f;
}
if (num3 >= 1f)
{
num3 = 0.999f;
}
int num4 = (int)(num2 * (float)cols);
int num5 = (int)(num3 * (float)rows);
float num6 = num5 * cols + num4;
vertexIndices[j] = (int)num6;
}
}
private void splashAtPoint(int x, int y, float force)
{
int num = y * cols + x;
buffer1[num] = force;
buffer1[num - 1] = force * 0.5f;
buffer1[num + 1] = force * 0.5f;
buffer1[num + cols] = force * 0.5f;
buffer1[num + cols + 1] = force * 0.45f;
buffer1[num + cols - 1] = force * 0.45f;
buffer1[num - cols] = force * 0.5f;
buffer1[num - cols + 1] = force * 0.45f;
buffer1[num - cols - 1] = force * 0.45f;
}
private void splashAtPoint1(int x, int y, float force)
{
int num = y * cols + x;
buffer1[num] = force;
buffer1[num - 1] = force * 0.5f;
buffer1[num + 1] = force * 0.5f;
buffer1[num + cols] = force * 0.5f;
buffer1[num + cols + 1] = force * 0.45f;
buffer1[num + cols - 1] = force * 0.45f;
buffer1[num - cols] = force * 0.5f;
buffer1[num - cols + 1] = force * 0.45f;
buffer1[num - cols - 1] = force * 0.45f;
buffer2[num] = force;
buffer2[num - 1] = force * 0.5f;
buffer2[num + 1] = force * 0.5f;
buffer2[num + cols] = force * 0.5f;
buffer2[num + cols + 1] = force * 0.45f;
buffer2[num + cols - 1] = force * 0.45f;
buffer2[num - cols] = force * 0.5f;
buffer2[num - cols + 1] = force * 0.45f;
buffer2[num - cols - 1] = force * 0.45f;
}
private int ipart(float x)
{
return (int)x;
}
private int round(float x)
{
return ipart(x + 0.5f);
}
private float fpart(float x)
{
return x - (float)(int)x;
}
private float rfpart(float x)
{
return 1f - fpart(x);
}
private void swap(ref float v1, ref float v2)
{
float num = v1;
v1 = v2;
v2 = num;
}
private void plot(int x, int y, float force)
{
input[x + y * cols] = force;
}
private void drawLine(float x1, float y1, float x2, float y2, float force)
{
float v = x2 - x1;
float v2 = y2 - y1;
if (Mathf.Abs(v) < Mathf.Abs(v2))
{
swap(ref x1, ref y1);
swap(ref x2, ref y2);
swap(ref v, ref v2);
}
if (x2 < x1)
{
swap(ref x1, ref x2);
swap(ref y1, ref y2);
}
float num = v2 / v;
float num2 = round(x1);
float num3 = y1 + num * (num2 - x1);
float num4 = rfpart(x1 + 0.5f);
int num5 = (int)num2;
int num6 = ipart(num3);
plot(num5, num6, rfpart(num3) * num4 * force);
plot(num5, num6 + 1, fpart(num3) * num4 * force);
float num7 = num3 + num;
num2 = round(x2);
num3 = y2 + num * (num2 - x2);
num4 = fpart(x2 + 0.5f);
int num8 = (int)num2;
int num9 = ipart(num3);
plot(num8, num9, rfpart(num3) * num4 * force);
plot(num8, num9 + 1, fpart(num3) * num4 * force);
for (int i = num5 + 1; i < num8 - 1; i++)
{
plot(i, ipart(num7), rfpart(num7) * force);
plot(i, ipart(num7) + 1, fpart(num7) * force);
num7 += num;
}
}
private void wakeAtPointWu(float x, float y, float force)
{
}
public void wakeAtPointAdd1(float x, float y, float force)
{
int num = Mathf.RoundToInt(x) - 1;
int num2 = Mathf.RoundToInt(y) - 1;
float[] array = new float[4];
int num3 = 0;
int num4 = 0;
float num5 = 0f;
for (int i = num2; i < num2 + 2; i++)
{
for (int j = num; j < num + 2; j++)
{
float num6 = (float)j + 0.5f - x;
float num7 = (float)i + 0.5f - y;
float num8 = Mathf.Sqrt(num6 * num6 + num7 * num7);
if (num8 < 1f)
{
num5 += num8;
array[num3] = num8;
num4++;
}
else
{
array[num3] = 1f;
}
num3++;
}
}
num3 = 0;
for (int k = num2; k < num2 + 2; k++)
{
for (int l = num; l < num + 2; l++)
{
if (k >= 0 && k < rows && l >= 0 && l < cols && array[num3] < 1f)
{
input[l + k * cols] = force * (array[num3] / num5);
}
num3++;
}
}
}
private void wakeAtPointAdd(int x, int y, float force)
{
int num = y * cols + x;
input[num] = force;
}
private void wakeAtPoint(int x, int y, float force)
{
int num = y * cols + x;
input[num] = force;
input[num - 1] = force * 0.5f;
input[num + 1] = force * 0.5f;
input[num + cols] = force * 0.5f;
input[num + cols + 1] = force * 0.45f;
input[num + cols - 1] = force * 0.45f;
input[num - cols] = force * 0.5f;
input[num - cols + 1] = force * 0.45f;
input[num - cols - 1] = force * 0.45f;
}
private void processRipples(float[] source, float[] dest)
{
for (int i = 1; i < rows - 1; i++)
{
int num = i * cols;
for (int j = 1; j < cols - 1; j++)
{
input[num + j] *= inputdamp;
}
}
if (Obstructions)
{
for (int k = 1; k < rows - 1; k++)
{
int num2 = k * cols;
for (int l = 1; l < cols - 1; l++)
{
int num3 = num2 + l;
dest[num3] = input[num3] + ((source[num3 - 1] + source[num3 + 1] + source[num3 - cols] + source[num3 + cols]) * speed - dest[num3]);
dest[num3] = dest[num3] * damping * blockers[num3];
}
}
return;
}
for (int m = 1; m < rows - 1; m++)
{
int num4 = m * cols;
for (int n = 1; n < cols - 1; n++)
{
int num5 = num4 + n;
dest[num5] = input[num5] + ((source[num5 - 1] + source[num5 + 1] + source[num5 - cols] + source[num5 + cols]) * speed - dest[num5]);
dest[num5] *= damping;
}
}
}
private void Update()
{
if (buffer1 == null || rows * cols != buffer1.Length)
{
return;
}
time += Time.deltaTime;
int num = (int)(time * DropsPerSec);
if (num > 0)
{
time = 0f;
if (rows > 8 && cols > 8)
{
for (int i = 0; i < num; i++)
{
int x = UnityEngine.Random.Range(8, cols - 8);
int y = UnityEngine.Random.Range(8, rows - 8);
splashAtPoint(x, y, Force * UnityEngine.Random.Range(0.1f, 1f));
}
}
}
checkInput();
}
public float GetWaterHeight(Vector3 lpos)
{
if (currentBuffer == null)
{
return 0f;
}
float num = (lpos.x - bbox.min.x) / (bbox.max.x - bbox.min.x);
float num2 = (lpos.y - bbox.min.y) / (bbox.max.y - bbox.min.y);
int num3 = (int)(num * (float)cols);
int num4 = (int)(num2 * (float)rows);
if (num3 < 0 || num3 >= cols)
{
return 0f;
}
if (num4 < 0 || num4 >= rows)
{
return 0f;
}
return currentBuffer[num4 * cols + num3];
}
private void checkInput()
{
if (Input.GetMouseButton(0))
{
RaycastHit[] array = Physics.RaycastAll(Camera.main.ScreenPointToRay(Input.mousePosition));
for (int i = 0; i < array.Length; i++)
{
if (!(array[i].collider.gameObject == base.gameObject))
{
continue;
}
if (array[i].collider is BoxCollider)
{
Vector3 vector = base.gameObject.transform.worldToLocalMatrix.MultiplyPoint(array[i].point);
BoxCollider boxCollider = (BoxCollider)array[i].collider;
vector -= boxCollider.center;
if (boxCollider.size.x != 0f)
{
vector.x /= boxCollider.size.x;
}
if (boxCollider.size.y != 0f)
{
vector.y /= boxCollider.size.y;
}
if (boxCollider.size.z != 0f)
{
vector.z /= boxCollider.size.z;
}
vector.x += 0.5f;
vector.y += 0.5f;
vector.z += 0.5f;
float num = 0f;
float num2 = 0f;
switch (axis)
{
case MegaAxis.X:
vertcomponent = 0;
num = vector.y * (float)(cols - 1);
num2 = vector.z * (float)(rows - 1);
break;
case MegaAxis.Y:
num = vector.x * (float)(cols - 1);
num2 = vector.z * (float)(rows - 1);
break;
case MegaAxis.Z:
num = vector.x * (float)(cols - 1);
num2 = vector.y * (float)(rows - 1);
break;
}
if (lastdown)
{
Line(lastcol, lastrow, num, num2);
}
else
{
wakeAtPointAdd1((int)num, (int)num2, 0f - InputForce);
}
lastdown = true;
lastrow = num2;
lastcol = num;
}
else
{
float num3 = (1f - array[i].textureCoord.x) * (float)(cols - 1);
float num4 = array[i].textureCoord.y * (float)(rows - 1);
if (lastdown)
{
Line(lastcol, lastrow, num3, num4);
}
else
{
wakeAtPointAdd1((int)num3, (int)num4, 0f - InputForce);
}
lastdown = true;
lastrow = num4;
lastcol = num3;
}
break;
}
}
else
{
lastdown = false;
}
}
private void checkInput1()
{
if (Input.GetMouseButton(0))
{
RaycastHit hitInfo;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo) && !(hitInfo.collider.gameObject != base.gameObject))
{
float num = (1f - hitInfo.textureCoord.x) * (float)(cols - 1);
float num2 = hitInfo.textureCoord.y * (float)(rows - 1);
if (lastdown)
{
Line(lastcol, lastrow, num, num2);
}
else
{
wakeAtPointAdd1((int)num, (int)num2, 0f - InputForce);
}
lastdown = true;
lastrow = num2;
lastcol = num;
}
}
else
{
lastdown = false;
}
}
private void Line(float x0, float y0, float x1, float y1)
{
if (Mathf.Abs(y1 - y0) > Mathf.Abs(x1 - x0))
{
int num = (int)Mathf.Abs(y0 - y1);
float num2 = 1f;
if (y1 < y0)
{
num2 = -1f;
}
float num3 = x1 - x0;
if (num > 0)
{
num3 /= (float)num;
}
for (int i = 0; i <= num; i++)
{
wakeAtPointAdd1(x0, y0, 0f - InputForce);
x0 += num3;
y0 += num2;
}
}
else
{
int num4 = (int)Mathf.Abs(x0 - x1);
float num5 = 1f;
if (x1 < x0)
{
num5 = -1f;
}
float num6 = y1 - y0;
if (num4 > 0)
{
num6 /= (float)num4;
}
for (int j = 0; j <= num4; j++)
{
wakeAtPointAdd1(x0, y0, 0f - InputForce);
x0 += num5;
y0 += num6;
}
}
}
public void Line(float x0, float y0, float x1, float y1, float force)
{
if (Mathf.Abs(y1 - y0) > Mathf.Abs(x1 - x0))
{
int num = (int)Mathf.Abs(y0 - y1);
float num2 = 1f;
if (y1 < y0)
{
num2 = -1f;
}
float num3 = x1 - x0;
if (num > 0)
{
num3 /= (float)num;
}
for (int i = 0; i <= num; i++)
{
wakeAtPointAdd1(x0, y0, force);
x0 += num3;
y0 += num2;
}
}
else
{
int num4 = (int)Mathf.Abs(x0 - x1);
float num5 = 1f;
if (x1 < x0)
{
num5 = -1f;
}
float num6 = y1 - y0;
if (num4 > 0)
{
num6 /= (float)num4;
}
for (int j = 0; j <= num4; j++)
{
wakeAtPointAdd1(x0, y0, force);
x0 += num5;
y0 += num6;
}
}
}
public void ForceAt(float x, float y, float force)
{
Vector3 zero = Vector3.zero;
zero.x = x;
zero.z = y;
zero = base.transform.worldToLocalMatrix.MultiplyPoint(zero);
x = (zero.x - bbox.min[xc]) / (bbox.max[xc] - bbox.min[xc]);
y = (zero.y - bbox.min[yc]) / (bbox.max[yc] - bbox.min[yc]);
int num = (int)(x * (float)cols);
int num2 = (int)(y * (float)rows);
if (num >= 0 && num < cols && num2 >= 0 && num2 < rows)
{
input[num2 * cols + num] = force;
}
}
public void ForceAt(Vector3 p, float force)
{
p = base.transform.worldToLocalMatrix.MultiplyPoint(p);
BoxCollider boxCollider = (BoxCollider)mycollider;
if (boxCollider.size.x != 0f)
{
p.x /= boxCollider.size.x;
}
if (boxCollider.size.y != 0f)
{
p.y /= boxCollider.size.y;
}
if (boxCollider.size.z != 0f)
{
p.z /= boxCollider.size.z;
}
p.x += 0.5f;
p.y += 0.5f;
p.z += 0.5f;
float num = 0f;
float num2 = 0f;
switch (axis)
{
case MegaAxis.X:
vertcomponent = 0;
num = p.y * (float)(cols - 1);
num2 = p.z * (float)(rows - 1);
break;
case MegaAxis.Y:
num = p.x * (float)(cols - 1);
num2 = p.z * (float)(rows - 1);
break;
case MegaAxis.Z:
num = p.x * (float)(cols - 1);
num2 = p.y * (float)(rows - 1);
break;
}
int num3 = (int)num;
int num4 = (int)num2;
if (num3 >= 0 && num3 < cols && num4 >= 0 && num4 < rows)
{
input[num4 * cols + num3] = force;
}
}
private void BuildMesh()
{
Vector3 zero = Vector3.zero;
Vector3 vector = Vector3.zero;
xc = 0;
yc = 0;
switch (axis)
{
case MegaAxis.X:
xc = 1;
yc = 2;
break;
case MegaAxis.Y:
xc = 0;
yc = 2;
break;
case MegaAxis.Z:
xc = 0;
yc = 1;
break;
}
for (int i = 0; i < rows; i++)
{
zero.z = bbox.min[yc] + (bbox.max[yc] - bbox.min[yc]) * ((float)i / (float)rows);
for (int j = 0; j < cols; j++)
{
zero.x = bbox.min[xc] + (bbox.max[xc] - bbox.min[xc]) * ((float)j / (float)cols);
zero.y = currentBuffer[i * cols + j];
if (j > 0)
{
Gizmos.DrawLine(vector, zero);
}
vector = zero;
}
}
for (int k = 0; k < cols; k++)
{
zero.x = bbox.min[xc] + (bbox.max[xc] - bbox.min[xc]) * ((float)k / (float)cols);
for (int l = 0; l < rows; l++)
{
zero.z = bbox.min[yc] + (bbox.max[yc] - bbox.min[yc]) * ((float)l / (float)rows);
zero.y = currentBuffer[l * cols + k];
if (l > 0)
{
Gizmos.DrawLine(vector, zero);
}
vector = zero;
}
}
}
public override void DrawGizmo(MegaModContext context)
{
Gizmos.color = Color.yellow;
Matrix4x4 identity = Matrix4x4.identity;
Vector3 pos = gizmoPos;
pos.x = 0f - pos.x;
pos.y = 0f - pos.y;
pos.z = 0f - pos.z;
Vector3 s = gizmoScale;
s.x = 1f - (s.x - 1f);
s.y = 1f - (s.y - 1f);
identity.SetTRS(pos, Quaternion.Euler(gizmoRot), s);
Matrix4x4 mat = Matrix4x4.identity;
switch (axis)
{
case MegaAxis.X:
MegaMatrix.RotateZ(ref mat, (float)Math.PI / 2f);
break;
case MegaAxis.Z:
MegaMatrix.RotateX(ref mat, (float)Math.PI / 2f);
break;
}
Gizmos.matrix = base.transform.localToWorldMatrix * identity * mat;
BuildMesh();
}
}