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

474 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class MegaBezPatch : MonoBehaviour
{
public float Width = 1f;
public float Height = 1f;
public int WidthSegs = 20;
public int HeightSegs = 20;
public bool GenUVs = true;
public bool recalcBounds;
public bool recalcTangents = true;
public bool recalcCollider;
public bool showgizmos = true;
public bool showlatticepoints;
public Color latticecol = Color.white;
public float handlesize = 0.075f;
public bool positionhandles;
public bool showlabels = true;
public Vector2 snap = new Vector2(0.25f, 0.25f);
public List<Warp> warps = new List<Warp>();
public int srcwarp;
public int destwarp;
[HideInInspector]
public Vector3[] verts;
[HideInInspector]
public Vector2[] uvs;
[HideInInspector]
public int[] tris;
[HideInInspector]
public Vector3[] norms;
[HideInInspector]
public bool rebuild = true;
public Vector2 UVOffset = Vector2.zero;
public Vector2 UVScale = Vector2.one;
public int currentwarp;
[HideInInspector]
public Mesh mesh;
public float switchtime = 1f;
public float time = 1000f;
public Vector3 p11;
public Vector3 p21;
public Vector3 p31;
public Vector3 p41;
public Vector3 p12;
public Vector3 p22;
public Vector3 p32;
public Vector3 p42;
public Vector3 p13;
public Vector3 p23;
public Vector3 p33;
public Vector3 p43;
public Vector3 p14;
public Vector3 p24;
public Vector3 p34;
public Vector3 p44;
public Vector3[] lpoints;
private float delay = -1f;
public void AddWarp()
{
Warp warp = new Warp();
warp.SetWarp(this);
warps.Add(warp);
}
public void UpdateWarp(int i)
{
Warp warp = warps[i];
warp.SetWarp(this);
}
public void SetWarp(int i)
{
if (Application.isPlaying)
{
time = 0f;
srcwarp = currentwarp;
destwarp = i;
}
else
{
time = 100f;
currentwarp = i;
warps[i].GetWarp(this);
}
}
private void Start()
{
time = 0f;
}
public void Reset()
{
InitLattice();
Rebuild();
}
public void Rebuild()
{
MeshFilter component = GetComponent<MeshFilter>();
if (component != null)
{
Mesh mesh = component.sharedMesh;
if (mesh == null)
{
mesh = (component.sharedMesh = new Mesh());
}
this.mesh = mesh;
}
}
private void Update()
{
ChangeWarp(srcwarp, destwarp);
if (mesh == null)
{
Rebuild();
}
if (rebuild)
{
BuildMesh(mesh);
}
}
private void MakeQuad1(int f, int a, int b, int c, int d)
{
tris[f++] = a;
tris[f++] = b;
tris[f++] = c;
tris[f++] = c;
tris[f++] = d;
tris[f++] = a;
}
private int MaxComponent(Vector3 v)
{
if (Mathf.Abs(v.x) > Mathf.Abs(v.y))
{
if (Mathf.Abs(v.x) > Mathf.Abs(v.z))
{
return 0;
}
return 2;
}
if (Mathf.Abs(v.y) > Mathf.Abs(v.z))
{
return 1;
}
return 2;
}
private void UpdateSurface()
{
}
private void BuildMesh(Mesh mesh)
{
if (WidthSegs < 1)
{
WidthSegs = 1;
}
if (HeightSegs < 1)
{
HeightSegs = 1;
}
Vector3 zero = Vector3.zero;
int num = (WidthSegs + 1) * (HeightSegs + 1);
if (verts == null)
{
InitLattice();
}
if (verts == null || verts.Length != num)
{
verts = new Vector3[num];
uvs = new Vector2[num];
tris = new int[HeightSegs * WidthSegs * 2 * 3];
norms = new Vector3[num];
for (int i = 0; i < norms.Length; i++)
{
norms[i] = Vector3.back;
}
}
Vector2 zero2 = Vector2.zero;
int num2 = 0;
zero = Vector3.zero;
for (int j = 0; j <= HeightSegs; j++)
{
num2 = j * (WidthSegs + 1);
for (int k = 0; k <= WidthSegs; k++)
{
float num3 = (float)k / (float)WidthSegs;
float num4 = (float)j / (float)HeightSegs;
float num5 = 1f - num3;
float num6 = 1f - num4;
float num7 = num5 * num5 * num5;
float num8 = 3f * num5 * num5 * num3;
float num9 = 3f * num5 * num3 * num3;
float num10 = num3 * num3 * num3;
float num11 = num6 * num6 * num6;
float num12 = 3f * num6 * num6 * num4;
float num13 = 3f * num6 * num4 * num4;
float num14 = num4 * num4 * num4;
zero.x = num7 * p11.x * num11 + num8 * p12.x * num11 + num9 * p13.x * num11 + num10 * p14.x * num11 + num7 * p21.x * num12 + num8 * p22.x * num12 + num9 * p23.x * num12 + num10 * p24.x * num12 + num7 * p31.x * num13 + num8 * p32.x * num13 + num9 * p33.x * num13 + num10 * p34.x * num13 + num7 * p41.x * num14 + num8 * p42.x * num14 + num9 * p43.x * num14 + num10 * p44.x * num14;
zero.y = num7 * p11.y * num11 + num8 * p12.y * num11 + num9 * p13.y * num11 + num10 * p14.y * num11 + num7 * p21.y * num12 + num8 * p22.y * num12 + num9 * p23.y * num12 + num10 * p24.y * num12 + num7 * p31.y * num13 + num8 * p32.y * num13 + num9 * p33.y * num13 + num10 * p34.y * num13 + num7 * p41.y * num14 + num8 * p42.y * num14 + num9 * p43.y * num14 + num10 * p44.y * num14;
verts[num2 + k] = zero;
if (GenUVs)
{
zero2.x = (num3 + UVOffset.x) * UVScale.x;
zero2.y = (num4 + UVOffset.y) * UVScale.y;
uvs[num2 + k] = zero2;
}
}
}
int num15 = 0;
for (int l = 0; l < HeightSegs; l++)
{
int num16 = l * (WidthSegs + 1);
for (int m = 0; m < WidthSegs; m++)
{
tris[num15++] = num16;
tris[num15++] = num16 + WidthSegs + 1;
tris[num15++] = num16 + WidthSegs + 2;
tris[num15++] = num16 + WidthSegs + 2;
tris[num15++] = num16 + 1;
tris[num15++] = num16;
num16++;
}
}
mesh.Clear();
mesh.subMeshCount = 1;
mesh.vertices = verts;
mesh.uv = uvs;
mesh.SetTriangles(tris, 0);
mesh.normals = norms;
mesh.RecalculateBounds();
if (recalcTangents)
{
BuildTangents(mesh, verts, norms, tris, uvs);
}
}
public void InitLattice()
{
float width = Width;
float height = Height;
p11 = new Vector3(-1.5f * width, -1.5f * height, 0f);
p12 = new Vector3(-0.5f * width, -1.5f * height, 0f);
p13 = new Vector3(0.5f * width, -1.5f * height, 0f);
p14 = new Vector3(1.5f * width, -1.5f * height, 0f);
p21 = new Vector3(-1.5f * width, -0.5f * height, 0f);
p22 = new Vector3(-0.5f * width, -0.5f * height, 0f);
p23 = new Vector3(0.5f * width, -0.5f * height, 0f);
p24 = new Vector3(1.5f * width, -0.5f * height, 0f);
p31 = new Vector3(-1.5f * width, 0.5f * height, 0f);
p32 = new Vector3(-0.5f * width, 0.5f * height, 0f);
p33 = new Vector3(0.5f * width, 0.5f * height, 0f);
p34 = new Vector3(1.5f * width, 0.5f * height, 0f);
p41 = new Vector3(-1.5f * width, 1.5f * height, 0f);
p42 = new Vector3(-0.5f * width, 1.5f * height, 0f);
p43 = new Vector3(0.5f * width, 1.5f * height, 0f);
p44 = new Vector3(1.5f * width, 1.5f * height, 0f);
}
public void AdjustLattice(float w, float h)
{
float num = w / Width;
float num2 = h / Height;
Vector3 b = new Vector3(num, num2, 1f);
p11 = Vector3.Scale(p11, b);
p12 = Vector3.Scale(p12, b);
p13 = Vector3.Scale(p13, b);
p14 = Vector3.Scale(p14, b);
p21 = Vector3.Scale(p21, b);
p22 = Vector3.Scale(p22, b);
p23 = Vector3.Scale(p23, b);
p24 = Vector3.Scale(p24, b);
p31 = Vector3.Scale(p31, b);
p32 = Vector3.Scale(p32, b);
p33 = Vector3.Scale(p33, b);
p34 = Vector3.Scale(p34, b);
p41 = Vector3.Scale(p41, b);
p42 = Vector3.Scale(p42, b);
p43 = Vector3.Scale(p43, b);
p44 = Vector3.Scale(p44, b);
for (int i = 0; i < warps.Count; i++)
{
warps[i].AdjustLattice(num, num2);
}
Height = h;
Width = w;
}
public static void BuildTangents(Mesh mesh, Vector3[] verts, Vector3[] norms, int[] tris, Vector2[] uvs)
{
int num = mesh.vertices.Length;
Vector3[] array = new Vector3[num];
Vector3[] array2 = new Vector3[num];
Vector4[] array3 = new Vector4[num];
for (int i = 0; i < tris.Length; i += 3)
{
long num2 = tris[i];
long num3 = tris[i + 1];
long num4 = tris[i + 2];
Vector3 vector = verts[num2];
Vector3 vector2 = verts[num3];
Vector3 vector3 = verts[num4];
Vector2 vector4 = uvs[num2];
Vector2 vector5 = uvs[num3];
Vector2 vector6 = uvs[num4];
float num5 = vector2.x - vector.x;
float num6 = vector3.x - vector.x;
float num7 = vector2.y - vector.y;
float num8 = vector3.y - vector.y;
float num9 = vector2.z - vector.z;
float num10 = vector3.z - vector.z;
float num11 = vector5.x - vector4.x;
float num12 = vector6.x - vector4.x;
float num13 = vector5.y - vector4.y;
float num14 = vector6.y - vector4.y;
float num15 = 1f / (num11 * num14 - num12 * num13);
Vector3 vector7 = new Vector3((num14 * num5 - num13 * num6) * num15, (num14 * num7 - num13 * num8) * num15, (num14 * num9 - num13 * num10) * num15);
Vector3 vector8 = new Vector3((num11 * num6 - num12 * num5) * num15, (num11 * num8 - num12 * num7) * num15, (num11 * num10 - num12 * num9) * num15);
array[num2] += vector7;
array[num3] += vector7;
array[num4] += vector7;
array2[num2] += vector8;
array2[num3] += vector8;
array2[num4] += vector8;
}
for (int j = 0; j < num; j++)
{
Vector3 normal = norms[j];
Vector3 tangent = array[j];
Vector3.OrthoNormalize(ref normal, ref tangent);
array3[j].x = tangent.x;
array3[j].y = tangent.y;
array3[j].z = tangent.z;
array3[j].w = ((!(Vector3.Dot(Vector3.Cross(normal, tangent), array2[j]) < 0f)) ? 1f : (-1f));
}
mesh.tangents = array3;
}
private Vector3 bounce(Vector3 start, Vector3 end, float value)
{
value /= 1f;
end -= start;
if (value < 0.36363637f)
{
return end * (7.5625f * value * value) + start;
}
if (value < 0.72727275f)
{
value -= 0.54545456f;
return end * (7.5625f * value * value + 0.75f) + start;
}
if (value < 0.90909094f)
{
value -= 0.8181818f;
return end * (7.5625f * value * value + 0.9375f) + start;
}
value -= 21f / 22f;
return end * (7.5625f * value * value + 63f / 64f) + start;
}
private Vector3 easeInOutSine(Vector3 start, Vector3 end, float value)
{
end -= start;
return -end / 2f * (Mathf.Cos((float)Math.PI * value / 1f) - 1f) + start;
}
public void ChangeWarp(int f, int t)
{
if (!Application.isPlaying)
{
return;
}
if (delay > 0f)
{
delay -= Time.deltaTime;
}
else
{
if (!(time <= switchtime))
{
return;
}
time += Time.deltaTime;
Warp warp = warps[f];
Warp warp2 = warps[t];
float num = time / switchtime;
if (num > 1f)
{
num = 1f;
currentwarp = t;
t++;
destwarp = t;
if (destwarp >= warps.Count)
{
destwarp = 0;
}
srcwarp = currentwarp;
time = 0f;
delay = 1f;
}
p11 = easeInOutSine(warp.points[0], warp2.points[0], num);
p12 = easeInOutSine(warp.points[1], warp2.points[1], num);
p13 = easeInOutSine(warp.points[2], warp2.points[2], num);
p14 = easeInOutSine(warp.points[3], warp2.points[3], num);
p21 = easeInOutSine(warp.points[4], warp2.points[4], num);
p22 = easeInOutSine(warp.points[5], warp2.points[5], num);
p23 = easeInOutSine(warp.points[6], warp2.points[6], num);
p24 = easeInOutSine(warp.points[7], warp2.points[7], num);
p31 = easeInOutSine(warp.points[8], warp2.points[8], num);
p32 = easeInOutSine(warp.points[9], warp2.points[9], num);
p33 = easeInOutSine(warp.points[10], warp2.points[10], num);
p34 = easeInOutSine(warp.points[11], warp2.points[11], num);
p41 = easeInOutSine(warp.points[12], warp2.points[12], num);
p42 = easeInOutSine(warp.points[13], warp2.points[13], num);
p43 = easeInOutSine(warp.points[14], warp2.points[14], num);
p44 = easeInOutSine(warp.points[15], warp2.points[15], num);
}
}
}