474 lines
11 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|