699 lines
18 KiB
C#
699 lines
18 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
[ExecuteInEditMode]
|
|
public class MegaWrap : MonoBehaviour
|
|
{
|
|
public float gap;
|
|
|
|
public float shrink = 1f;
|
|
|
|
public List<int> neededVerts = new List<int>();
|
|
|
|
public Vector3[] skinnedVerts;
|
|
|
|
public Mesh mesh;
|
|
|
|
public Vector3 offset = Vector3.zero;
|
|
|
|
public bool targetIsSkin;
|
|
|
|
public bool sourceIsSkin;
|
|
|
|
public int nomapcount;
|
|
|
|
public Matrix4x4[] bindposes;
|
|
|
|
public BoneWeight[] boneweights;
|
|
|
|
public Transform[] bones;
|
|
|
|
public float size = 0.01f;
|
|
|
|
public int vertindex;
|
|
|
|
public Vector3[] freeverts;
|
|
|
|
public Vector3[] startverts;
|
|
|
|
public Vector3[] verts;
|
|
|
|
public MegaBindVert[] bindverts;
|
|
|
|
public MegaModifyObject target;
|
|
|
|
public float maxdist = 0.25f;
|
|
|
|
public int maxpoints = 4;
|
|
|
|
public bool WrapEnabled = true;
|
|
|
|
public MegaNormalMethod NormalMethod;
|
|
|
|
private Vector3 e11 = Vector3.zero;
|
|
|
|
private Vector3 e22 = Vector3.zero;
|
|
|
|
private Vector3 cr = Vector3.zero;
|
|
|
|
private Vector3 gcp = Vector3.zero;
|
|
|
|
private SkinnedMeshRenderer tmesh;
|
|
|
|
public MegaNormMap[] mapping;
|
|
|
|
public int[] tris;
|
|
|
|
public Vector3[] facenorms;
|
|
|
|
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;
|
|
}
|
|
|
|
public float GetDistance(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
|
|
{
|
|
return MegaNearestPointTest.DistPoint3Triangle3Dbl(p, p0, p1, p2);
|
|
}
|
|
|
|
public 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)
|
|
{
|
|
e11.x = p1.x - p0.x;
|
|
e11.y = p1.y - p0.y;
|
|
e11.z = p1.z - p0.z;
|
|
e22.x = p2.x - p0.x;
|
|
e22.y = p2.y - p0.y;
|
|
e22.z = p2.z - p0.z;
|
|
cr.x = e11.y * e22.z - e22.y * e11.z;
|
|
cr.y = 0f - (e11.x * e22.z - e22.x * e11.z);
|
|
cr.z = e11.x * e22.y - e22.x * e11.y;
|
|
return cr;
|
|
}
|
|
|
|
private static void CopyBlendShapes(Mesh mesh1, Mesh clonemesh)
|
|
{
|
|
}
|
|
|
|
public 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)
|
|
{
|
|
mesh.vertices = startverts;
|
|
mesh.RecalculateBounds();
|
|
RecalcNormals();
|
|
}
|
|
target = null;
|
|
bindverts = null;
|
|
}
|
|
|
|
public void SetMesh()
|
|
{
|
|
MeshFilter component = GetComponent<MeshFilter>();
|
|
Mesh mesh = null;
|
|
if (component != null)
|
|
{
|
|
mesh = component.sharedMesh;
|
|
}
|
|
else
|
|
{
|
|
SkinnedMeshRenderer skinnedMeshRenderer = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
|
|
if (skinnedMeshRenderer != null)
|
|
{
|
|
mesh = skinnedMeshRenderer.sharedMesh;
|
|
}
|
|
}
|
|
if (mesh != null)
|
|
{
|
|
this.mesh = CloneMesh(mesh);
|
|
if ((bool)component)
|
|
{
|
|
component.sharedMesh = this.mesh;
|
|
return;
|
|
}
|
|
SkinnedMeshRenderer skinnedMeshRenderer2 = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
|
|
skinnedMeshRenderer2.sharedMesh = this.mesh;
|
|
}
|
|
}
|
|
|
|
public void Attach(MegaModifyObject modobj)
|
|
{
|
|
targetIsSkin = false;
|
|
sourceIsSkin = false;
|
|
if ((bool)this.mesh && startverts != null)
|
|
{
|
|
this.mesh.vertices = startverts;
|
|
}
|
|
if (modobj == null)
|
|
{
|
|
bindverts = null;
|
|
return;
|
|
}
|
|
nomapcount = 0;
|
|
if ((bool)this.mesh)
|
|
{
|
|
this.mesh.vertices = startverts;
|
|
}
|
|
MeshFilter component = GetComponent<MeshFilter>();
|
|
Mesh mesh = null;
|
|
if (component != null)
|
|
{
|
|
mesh = component.mesh;
|
|
}
|
|
else
|
|
{
|
|
SkinnedMeshRenderer skinnedMeshRenderer = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
|
|
if (skinnedMeshRenderer != null)
|
|
{
|
|
mesh = skinnedMeshRenderer.sharedMesh;
|
|
sourceIsSkin = true;
|
|
}
|
|
}
|
|
if (mesh == null)
|
|
{
|
|
Debug.LogWarning("No Mesh found on the target object, make sure target has a mesh and MegaFiers modifier attached!");
|
|
return;
|
|
}
|
|
if (this.mesh == null)
|
|
{
|
|
this.mesh = CloneMesh(mesh);
|
|
}
|
|
if ((bool)component)
|
|
{
|
|
component.mesh = this.mesh;
|
|
}
|
|
else
|
|
{
|
|
SkinnedMeshRenderer skinnedMeshRenderer2 = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
|
|
skinnedMeshRenderer2.sharedMesh = this.mesh;
|
|
}
|
|
if (!sourceIsSkin)
|
|
{
|
|
SkinnedMeshRenderer skinnedMeshRenderer3 = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
|
|
if (skinnedMeshRenderer3 != null)
|
|
{
|
|
targetIsSkin = true;
|
|
if (!sourceIsSkin)
|
|
{
|
|
Mesh sharedMesh = skinnedMeshRenderer3.sharedMesh;
|
|
bindposes = sharedMesh.bindposes;
|
|
boneweights = sharedMesh.boneWeights;
|
|
bones = skinnedMeshRenderer3.bones;
|
|
skinnedVerts = sharedMesh.vertices;
|
|
}
|
|
}
|
|
}
|
|
if (targetIsSkin && (boneweights == null || boneweights.Length == 0))
|
|
{
|
|
targetIsSkin = false;
|
|
}
|
|
neededVerts.Clear();
|
|
verts = this.mesh.vertices;
|
|
startverts = this.mesh.vertices;
|
|
freeverts = new Vector3[startverts.Length];
|
|
Vector3[] array = modobj.verts;
|
|
int[] array2 = modobj.tris;
|
|
bindverts = new MegaBindVert[verts.Length];
|
|
Matrix4x4 matrix4x = base.transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;
|
|
List<MegaCloseFace> list = new List<MegaCloseFace>();
|
|
Vector3 zero = Vector3.zero;
|
|
Vector3 zero2 = Vector3.zero;
|
|
Vector3 zero3 = Vector3.zero;
|
|
for (int i = 0; i < verts.Length; i++)
|
|
{
|
|
MegaBindVert megaBindVert = new MegaBindVert();
|
|
bindverts[i] = megaBindVert;
|
|
Vector3 vector = matrix4x.MultiplyPoint(verts[i]);
|
|
vector = base.transform.TransformPoint(verts[i]);
|
|
vector = modobj.transform.InverseTransformPoint(vector);
|
|
freeverts[i] = vector;
|
|
list.Clear();
|
|
for (int j = 0; j < array2.Length; j += 3)
|
|
{
|
|
if (targetIsSkin && !sourceIsSkin)
|
|
{
|
|
zero = modobj.transform.InverseTransformPoint(GetSkinPos(array2[j]));
|
|
zero2 = modobj.transform.InverseTransformPoint(GetSkinPos(array2[j + 1]));
|
|
zero3 = modobj.transform.InverseTransformPoint(GetSkinPos(array2[j + 2]));
|
|
}
|
|
else
|
|
{
|
|
zero = array[array2[j]];
|
|
zero2 = array[array2[j + 1]];
|
|
zero3 = array[array2[j + 2]];
|
|
}
|
|
float distance = GetDistance(vector, zero, zero2, zero3);
|
|
if (!(Mathf.Abs(distance) < maxdist))
|
|
{
|
|
continue;
|
|
}
|
|
MegaCloseFace item = new MegaCloseFace
|
|
{
|
|
dist = Mathf.Abs(distance),
|
|
face = j
|
|
};
|
|
bool flag = false;
|
|
for (int k = 0; k < list.Count; k++)
|
|
{
|
|
if (item.dist < list[k].dist)
|
|
{
|
|
list.Insert(k, item);
|
|
flag = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
list.Add(item);
|
|
}
|
|
}
|
|
float num = 0f;
|
|
int count = maxpoints;
|
|
if (count == 0)
|
|
{
|
|
count = list.Count;
|
|
}
|
|
for (int l = 0; l < count; l++)
|
|
{
|
|
if (l < list.Count)
|
|
{
|
|
int face = list[l].face;
|
|
if (targetIsSkin && !sourceIsSkin)
|
|
{
|
|
zero = modobj.transform.InverseTransformPoint(GetSkinPos(array2[face]));
|
|
zero2 = modobj.transform.InverseTransformPoint(GetSkinPos(array2[face + 1]));
|
|
zero3 = modobj.transform.InverseTransformPoint(GetSkinPos(array2[face + 2]));
|
|
}
|
|
else
|
|
{
|
|
zero = array[array2[face]];
|
|
zero2 = array[array2[face + 1]];
|
|
zero3 = array[array2[face + 2]];
|
|
}
|
|
Vector3 vector2 = FaceNormal(zero, zero2, zero3);
|
|
float dist = list[l].dist;
|
|
MegaBindInf megaBindInf = new MegaBindInf();
|
|
megaBindInf.dist = GetPlaneDistance(vector, zero, zero2, zero3);
|
|
megaBindInf.face = face;
|
|
megaBindInf.i0 = array2[face];
|
|
megaBindInf.i1 = array2[face + 1];
|
|
megaBindInf.i2 = array2[face + 2];
|
|
megaBindInf.bary = CalcBary(vector, zero, zero2, zero3);
|
|
megaBindInf.weight = 1f / (1f + dist);
|
|
megaBindInf.area = vector2.magnitude * 0.5f;
|
|
num += megaBindInf.weight;
|
|
megaBindVert.verts.Add(megaBindInf);
|
|
}
|
|
}
|
|
if (maxpoints > 0 && maxpoints < megaBindVert.verts.Count)
|
|
{
|
|
megaBindVert.verts.RemoveRange(maxpoints, megaBindVert.verts.Count - maxpoints);
|
|
}
|
|
if (!sourceIsSkin && targetIsSkin)
|
|
{
|
|
for (int m = 0; m < megaBindVert.verts.Count; m++)
|
|
{
|
|
if (!neededVerts.Contains(megaBindVert.verts[m].i0))
|
|
{
|
|
neededVerts.Add(megaBindVert.verts[m].i0);
|
|
}
|
|
if (!neededVerts.Contains(megaBindVert.verts[m].i1))
|
|
{
|
|
neededVerts.Add(megaBindVert.verts[m].i1);
|
|
}
|
|
if (!neededVerts.Contains(megaBindVert.verts[m].i2))
|
|
{
|
|
neededVerts.Add(megaBindVert.verts[m].i2);
|
|
}
|
|
}
|
|
}
|
|
if (num == 0f)
|
|
{
|
|
nomapcount++;
|
|
}
|
|
megaBindVert.weight = num;
|
|
}
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
DoUpdate();
|
|
}
|
|
|
|
public Vector3 GetSkinPos(int i)
|
|
{
|
|
Vector3 point = target.sverts[i];
|
|
Vector3 position = bindposes[boneweights[i].boneIndex0].MultiplyPoint(point);
|
|
Vector3 vector = bones[boneweights[i].boneIndex0].TransformPoint(position) * boneweights[i].weight0;
|
|
position = bindposes[boneweights[i].boneIndex1].MultiplyPoint(point);
|
|
vector += bones[boneweights[i].boneIndex1].TransformPoint(position) * boneweights[i].weight1;
|
|
position = bindposes[boneweights[i].boneIndex2].MultiplyPoint(point);
|
|
vector += bones[boneweights[i].boneIndex2].TransformPoint(position) * boneweights[i].weight2;
|
|
position = bindposes[boneweights[i].boneIndex3].MultiplyPoint(point);
|
|
return vector + bones[boneweights[i].boneIndex3].TransformPoint(position) * boneweights[i].weight3;
|
|
}
|
|
|
|
public Vector3 GetCoordMine(Vector3 A, Vector3 B, Vector3 C, Vector3 bary)
|
|
{
|
|
gcp.x = bary.x * A.x + bary.y * B.x + bary.z * C.x;
|
|
gcp.y = bary.x * A.y + bary.y * B.y + bary.z * C.y;
|
|
gcp.z = bary.x * A.z + bary.y * B.z + bary.z * C.z;
|
|
return gcp;
|
|
}
|
|
|
|
private void DoUpdate()
|
|
{
|
|
if (!WrapEnabled || target == null || bindverts == null)
|
|
{
|
|
return;
|
|
}
|
|
if (mesh == null)
|
|
{
|
|
SetMesh();
|
|
}
|
|
if (mesh == null)
|
|
{
|
|
return;
|
|
}
|
|
if (targetIsSkin && neededVerts != null && neededVerts.Count > 0)
|
|
{
|
|
if (boneweights == null || tmesh == null)
|
|
{
|
|
tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
|
|
if (tmesh != null && !sourceIsSkin)
|
|
{
|
|
Mesh sharedMesh = tmesh.sharedMesh;
|
|
bindposes = sharedMesh.bindposes;
|
|
bones = tmesh.bones;
|
|
boneweights = sharedMesh.boneWeights;
|
|
}
|
|
}
|
|
for (int i = 0; i < neededVerts.Count; i++)
|
|
{
|
|
skinnedVerts[neededVerts[i]] = GetSkinPos(neededVerts[i]);
|
|
}
|
|
}
|
|
Matrix4x4 identity = Matrix4x4.identity;
|
|
Vector3 zero = Vector3.zero;
|
|
if (targetIsSkin && !sourceIsSkin)
|
|
{
|
|
identity = base.transform.worldToLocalMatrix;
|
|
for (int j = 0; j < bindverts.Length; j++)
|
|
{
|
|
if (bindverts[j].verts.Count <= 0)
|
|
{
|
|
continue;
|
|
}
|
|
zero = Vector3.zero;
|
|
float num = 1f / bindverts[j].weight;
|
|
int count = bindverts[j].verts.Count;
|
|
for (int k = 0; k < count; k++)
|
|
{
|
|
MegaBindInf megaBindInf = 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);
|
|
float num2 = 1f / Mathf.Sqrt(vector4.x * vector4.x + vector4.y * vector4.y + vector4.z * vector4.z);
|
|
float num3 = megaBindInf.dist * shrink + gap;
|
|
coordMine.x += num3 * vector4.x * num2;
|
|
coordMine.y += num3 * vector4.y * num2;
|
|
coordMine.z += num3 * vector4.z * num2;
|
|
float num4 = megaBindInf.weight * num;
|
|
if (k == 0)
|
|
{
|
|
zero.x = coordMine.x * num4;
|
|
zero.y = coordMine.y * num4;
|
|
zero.z = coordMine.z * num4;
|
|
}
|
|
else
|
|
{
|
|
zero.x += coordMine.x * num4;
|
|
zero.y += coordMine.y * num4;
|
|
zero.z += coordMine.z * num4;
|
|
}
|
|
}
|
|
Vector3 vector5 = identity.MultiplyPoint3x4(zero);
|
|
verts[j].x = vector5.x + offset.x;
|
|
verts[j].y = vector5.y + offset.y;
|
|
verts[j].z = vector5.z + offset.z;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
identity = base.transform.worldToLocalMatrix * target.transform.localToWorldMatrix;
|
|
for (int l = 0; l < bindverts.Length; l++)
|
|
{
|
|
if (bindverts[l].verts.Count > 0)
|
|
{
|
|
zero = Vector3.zero;
|
|
float num5 = 1f / bindverts[l].weight;
|
|
for (int m = 0; m < bindverts[l].verts.Count; m++)
|
|
{
|
|
MegaBindInf megaBindInf2 = bindverts[l].verts[m];
|
|
Vector3 vector6 = target.sverts[megaBindInf2.i0];
|
|
Vector3 vector7 = target.sverts[megaBindInf2.i1];
|
|
Vector3 vector8 = target.sverts[megaBindInf2.i2];
|
|
Vector3 coordMine2 = GetCoordMine(vector6, vector7, vector8, megaBindInf2.bary);
|
|
Vector3 vector9 = FaceNormal(vector6, vector7, vector8);
|
|
float num6 = 1f / Mathf.Sqrt(vector9.x * vector9.x + vector9.y * vector9.y + vector9.z * vector9.z);
|
|
float num7 = megaBindInf2.dist * shrink + gap;
|
|
coordMine2.x += num7 * vector9.x * num6;
|
|
coordMine2.y += num7 * vector9.y * num6;
|
|
coordMine2.z += num7 * vector9.z * num6;
|
|
float num8 = megaBindInf2.weight * num5;
|
|
if (m == 0)
|
|
{
|
|
zero.x = coordMine2.x * num8;
|
|
zero.y = coordMine2.y * num8;
|
|
zero.z = coordMine2.z * num8;
|
|
}
|
|
else
|
|
{
|
|
zero.x += coordMine2.x * num8;
|
|
zero.y += coordMine2.y * num8;
|
|
zero.z += coordMine2.z * num8;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
zero = freeverts[l];
|
|
}
|
|
Vector3 vector10 = identity.MultiplyPoint3x4(zero);
|
|
verts[l].x = vector10.x + offset.x;
|
|
verts[l].y = vector10.y + offset.y;
|
|
verts[l].z = vector10.z + offset.z;
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
}
|