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

448 lines
12 KiB
C#

using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class MegaWrapRef : MonoBehaviour
{
public float gap;
public float shrink = 1f;
public Vector3[] skinnedVerts;
public Mesh mesh;
public Vector3 offset = Vector3.zero;
public bool targetIsSkin;
public bool sourceIsSkin;
public int nomapcount;
public Matrix4x4[] bindposes;
public Transform[] bones;
public float size = 0.01f;
public int vertindex;
public Vector3[] verts;
public MegaModifyObject target;
public float maxdist = 0.25f;
public int maxpoints = 4;
public bool WrapEnabled = true;
public MegaWrap source;
public MegaNormalMethod NormalMethod;
[HideInInspector]
public MegaNormMap[] mapping;
[HideInInspector]
public int[] tris;
[HideInInspector]
public Vector3[] facenorms;
[HideInInspector]
public Vector3[] norms;
[ContextMenu("Help")]
public void Help()
{
Application.OpenURL("http://www.west-racing.com/mf/?page_id=3709");
}
private Vector4 Plane(Vector3 v1, Vector3 v2, Vector3 v3)
{
Vector3 vector = Vector4.zero;
vector.x = (v2.y - v1.y) * (v3.z - v1.z) - (v2.z - v1.z) * (v3.y - v1.y);
vector.y = (v2.z - v1.z) * (v3.x - v1.x) - (v2.x - v1.x) * (v3.z - v1.z);
vector.z = (v2.x - v1.x) * (v3.y - v1.y) - (v2.y - v1.y) * (v3.x - v1.x);
vector = vector.normalized;
return new Vector4(vector.x, vector.y, vector.z, 0f - Vector3.Dot(v2, vector));
}
private float PlaneDist(Vector3 p, Vector4 plane)
{
Vector3 lhs = plane;
return Vector3.Dot(lhs, p) + plane.w;
}
private float GetDistance(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
{
return MegaNearestPointTest.DistPoint3Triangle3Dbl(p, p0, p1, p2);
}
private float GetPlaneDistance(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
{
Vector4 plane = Plane(p0, p1, p2);
return PlaneDist(p, plane);
}
public Vector3 MyBary(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
{
Vector3 zero = Vector3.zero;
Vector3 lhs = FaceNormal(p0, p1, p2);
float num = Vector3.Dot(lhs, Vector3.Cross(p1 - p0, p2 - p0));
float num2 = Vector3.Dot(lhs, Vector3.Cross(p1 - p, p2 - p));
float num3 = Vector3.Dot(lhs, Vector3.Cross(p2 - p, p0 - p));
zero.x = num2 / num;
zero.y = num3 / num;
zero.z = 1f - zero.x - zero.y;
return zero;
}
public Vector3 MyBary1(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
{
Vector3 vector = b - a;
Vector3 vector2 = c - a;
Vector3 lhs = p - a;
float num = Vector3.Dot(vector, vector);
float num2 = Vector3.Dot(vector, vector2);
float num3 = Vector3.Dot(vector2, vector2);
float num4 = Vector3.Dot(lhs, vector);
float num5 = Vector3.Dot(lhs, vector2);
float num6 = num * num3 - num2 * num2;
float num7 = (num3 * num4 - num2 * num5) / num6;
float num8 = (num * num5 - num2 * num4) / num6;
float x = 1f - num8 - num7;
return new Vector3(x, num8, num7);
}
public Vector3 CalcBary(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
{
return MyBary(p, p0, p1, p2);
}
public float CalcArea(Vector3 p0, Vector3 p1, Vector3 p2)
{
Vector3 lhs = p1 - p0;
Vector3 rhs = p2 - p0;
return 0.5f * Vector3.Cross(lhs, rhs).magnitude;
}
public Vector3 FaceNormal(Vector3 p0, Vector3 p1, Vector3 p2)
{
Vector3 lhs = p1 - p0;
Vector3 rhs = p2 - p0;
return Vector3.Cross(lhs, rhs);
}
private static void CopyBlendShapes(Mesh mesh1, Mesh clonemesh)
{
}
private Mesh CloneMesh(Mesh m)
{
Mesh mesh = new Mesh();
mesh.vertices = m.vertices;
mesh.uv2 = m.uv2;
mesh.uv2 = m.uv2;
mesh.uv = m.uv;
mesh.normals = m.normals;
mesh.tangents = m.tangents;
mesh.colors = m.colors;
mesh.subMeshCount = m.subMeshCount;
for (int i = 0; i < m.subMeshCount; i++)
{
mesh.SetTriangles(m.GetTriangles(i), i);
}
CopyBlendShapes(m, mesh);
mesh.boneWeights = m.boneWeights;
mesh.bindposes = m.bindposes;
mesh.name = m.name;
mesh.RecalculateBounds();
return mesh;
}
[ContextMenu("Reset Mesh")]
public void ResetMesh()
{
if ((bool)mesh && (bool)source)
{
mesh.vertices = source.startverts;
mesh.RecalculateBounds();
RecalcNormals();
}
target = null;
}
public void Attach(MegaModifyObject modobj)
{
targetIsSkin = false;
sourceIsSkin = false;
nomapcount = 0;
MeshFilter component = GetComponent<MeshFilter>();
Mesh m = null;
if (component != null)
{
m = component.mesh;
}
else
{
SkinnedMeshRenderer skinnedMeshRenderer = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
if (skinnedMeshRenderer != null)
{
m = skinnedMeshRenderer.sharedMesh;
sourceIsSkin = true;
}
}
if (mesh == null)
{
mesh = CloneMesh(m);
}
if ((bool)component)
{
component.mesh = mesh;
}
else
{
SkinnedMeshRenderer skinnedMeshRenderer2 = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
skinnedMeshRenderer2.sharedMesh = mesh;
}
if (!sourceIsSkin)
{
SkinnedMeshRenderer skinnedMeshRenderer3 = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
if (skinnedMeshRenderer3 != null)
{
targetIsSkin = true;
if (!sourceIsSkin)
{
Mesh sharedMesh = skinnedMeshRenderer3.sharedMesh;
bindposes = sharedMesh.bindposes;
bones = skinnedMeshRenderer3.bones;
skinnedVerts = sharedMesh.vertices;
}
}
}
verts = mesh.vertices;
}
private void LateUpdate()
{
DoUpdate();
}
private Vector3 GetSkinPos(MegaWrap src, int i)
{
Vector3 point = target.sverts[i];
Vector3 position = bindposes[src.boneweights[i].boneIndex0].MultiplyPoint(point);
Vector3 vector = bones[src.boneweights[i].boneIndex0].TransformPoint(position) * src.boneweights[i].weight0;
position = bindposes[src.boneweights[i].boneIndex1].MultiplyPoint(point);
vector += bones[src.boneweights[i].boneIndex1].TransformPoint(position) * src.boneweights[i].weight1;
position = bindposes[src.boneweights[i].boneIndex2].MultiplyPoint(point);
vector += bones[src.boneweights[i].boneIndex2].TransformPoint(position) * src.boneweights[i].weight2;
position = bindposes[src.boneweights[i].boneIndex3].MultiplyPoint(point);
return vector + bones[src.boneweights[i].boneIndex3].TransformPoint(position) * src.boneweights[i].weight3;
}
public Vector3 GetCoordMine(Vector3 A, Vector3 B, Vector3 C, Vector3 bary)
{
Vector3 zero = Vector3.zero;
zero.x = bary.x * A.x + bary.y * B.x + bary.z * C.x;
zero.y = bary.x * A.y + bary.y * B.y + bary.z * C.y;
zero.z = bary.x * A.z + bary.y * B.z + bary.z * C.z;
return zero;
}
private void DoUpdate()
{
if (source == null || !WrapEnabled || target == null || source.bindverts == null)
{
return;
}
if (targetIsSkin && source.neededVerts != null && source.neededVerts.Count > 0)
{
if (source.boneweights == null)
{
SkinnedMeshRenderer skinnedMeshRenderer = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
if (skinnedMeshRenderer != null && !sourceIsSkin)
{
Mesh sharedMesh = skinnedMeshRenderer.sharedMesh;
bindposes = sharedMesh.bindposes;
source.boneweights = sharedMesh.boneWeights;
}
}
for (int i = 0; i < source.neededVerts.Count; i++)
{
skinnedVerts[source.neededVerts[i]] = GetSkinPos(source, source.neededVerts[i]);
}
}
Vector3 zero = Vector3.zero;
if (targetIsSkin && !sourceIsSkin)
{
for (int j = 0; j < source.bindverts.Length; j++)
{
if (source.bindverts[j].verts.Count > 0)
{
zero = Vector3.zero;
for (int k = 0; k < source.bindverts[j].verts.Count; k++)
{
MegaBindInf megaBindInf = source.bindverts[j].verts[k];
Vector3 vector = skinnedVerts[megaBindInf.i0];
Vector3 vector2 = skinnedVerts[megaBindInf.i1];
Vector3 vector3 = skinnedVerts[megaBindInf.i2];
Vector3 coordMine = GetCoordMine(vector, vector2, vector3, megaBindInf.bary);
Vector3 vector4 = FaceNormal(vector, vector2, vector3);
coordMine += (megaBindInf.dist * shrink + gap) * vector4.normalized;
zero += coordMine * (megaBindInf.weight / source.bindverts[j].weight);
}
verts[j] = base.transform.InverseTransformPoint(zero) + offset;
}
}
}
else
{
for (int l = 0; l < source.bindverts.Length; l++)
{
if (source.bindverts[l].verts.Count > 0)
{
zero = Vector3.zero;
for (int m = 0; m < source.bindverts[l].verts.Count; m++)
{
MegaBindInf megaBindInf2 = source.bindverts[l].verts[m];
Vector3 vector5 = target.sverts[megaBindInf2.i0];
Vector3 vector6 = target.sverts[megaBindInf2.i1];
Vector3 vector7 = target.sverts[megaBindInf2.i2];
Vector3 coordMine2 = GetCoordMine(vector5, vector6, vector7, megaBindInf2.bary);
Vector3 vector8 = FaceNormal(vector5, vector6, vector7);
coordMine2 += (megaBindInf2.dist * shrink + gap) * vector8.normalized;
zero += coordMine2 * (megaBindInf2.weight / source.bindverts[l].weight);
}
}
else
{
zero = source.freeverts[l];
}
zero = target.transform.TransformPoint(zero);
verts[l] = base.transform.InverseTransformPoint(zero) + offset;
}
}
mesh.vertices = verts;
RecalcNormals();
mesh.RecalculateBounds();
}
private int[] FindFacesUsing(Vector3 p, Vector3 n)
{
List<int> list = new List<int>();
Vector3 zero = Vector3.zero;
for (int i = 0; i < tris.Length; i += 3)
{
zero = verts[tris[i]];
if (zero.x == p.x && zero.y == p.y && zero.z == p.z)
{
if (n.Equals(norms[tris[i]]))
{
list.Add(i / 3);
}
continue;
}
zero = verts[tris[i + 1]];
if (zero.x == p.x && zero.y == p.y && zero.z == p.z)
{
if (n.Equals(norms[tris[i + 1]]))
{
list.Add(i / 3);
}
continue;
}
zero = verts[tris[i + 2]];
if (zero.x == p.x && zero.y == p.y && zero.z == p.z && n.Equals(norms[tris[i + 2]]))
{
list.Add(i / 3);
}
}
return list.ToArray();
}
public void BuildNormalMapping(Mesh mesh, bool force)
{
if (mapping == null || mapping.Length == 0 || force)
{
tris = mesh.triangles;
norms = mesh.normals;
facenorms = new Vector3[tris.Length / 3];
mapping = new MegaNormMap[verts.Length];
for (int i = 0; i < verts.Length; i++)
{
mapping[i] = new MegaNormMap();
mapping[i].faces = FindFacesUsing(verts[i], norms[i]);
}
}
}
public void RecalcNormals()
{
if (NormalMethod == MegaNormalMethod.Unity)
{
mesh.RecalculateNormals();
return;
}
if (mapping == null)
{
BuildNormalMapping(mesh, false);
}
RecalcNormals(mesh, verts);
}
public void RecalcNormals(Mesh ms, Vector3[] _verts)
{
int num = 0;
Vector3 zero = Vector3.zero;
Vector3 zero2 = Vector3.zero;
Vector3 zero3 = Vector3.zero;
Vector3 zero4 = Vector3.zero;
Vector3 zero5 = Vector3.zero;
for (int i = 0; i < tris.Length; i += 3)
{
zero = _verts[tris[i]];
zero2 = _verts[tris[i + 1]];
zero3 = _verts[tris[i + 2]];
zero4.x = zero2.x - zero.x;
zero4.y = zero2.y - zero.y;
zero4.z = zero2.z - zero.z;
zero5.x = zero3.x - zero2.x;
zero5.y = zero3.y - zero2.y;
zero5.z = zero3.z - zero2.z;
zero.x = zero4.y * zero5.z - zero4.z * zero5.y;
zero.y = zero4.z * zero5.x - zero4.x * zero5.z;
zero.z = zero4.x * zero5.y - zero4.y * zero5.x;
facenorms[num++] = zero;
}
for (int j = 0; j < norms.Length; j++)
{
if (mapping[j].faces.Length > 0)
{
Vector3 vector = facenorms[mapping[j].faces[0]];
for (int k = 1; k < mapping[j].faces.Length; k++)
{
zero = facenorms[mapping[j].faces[k]];
vector.x += zero.x;
vector.y += zero.y;
vector.z += zero.z;
}
float f = vector.x * vector.x + vector.y * vector.y + vector.z * vector.z;
f = 1f / Mathf.Sqrt(f);
vector.x *= f;
vector.y *= f;
vector.z *= f;
norms[j] = vector;
}
else
{
norms[j] = Vector3.up;
}
}
ms.normals = norms;
}
}