1105 lines
24 KiB
C#
1105 lines
24 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using UnityEngine;
|
|
|
|
public class MegaModifiers : MonoBehaviour
|
|
{
|
|
public class MegaPS3Vert
|
|
{
|
|
public int[] indices;
|
|
}
|
|
|
|
[HideInInspector]
|
|
public Bounds bbox = default(Bounds);
|
|
|
|
public bool recalcnorms = true;
|
|
|
|
public MegaNormalMethod NormalMethod = MegaNormalMethod.Mega;
|
|
|
|
public bool recalcbounds;
|
|
|
|
public bool recalcCollider;
|
|
|
|
public bool recalcTangents;
|
|
|
|
public bool dynamicMesh;
|
|
|
|
public bool Enabled = true;
|
|
|
|
public MegaUpdateMode UpdateMode;
|
|
|
|
public bool DrawGizmos = true;
|
|
|
|
[HideInInspector]
|
|
public Vector3[] verts;
|
|
|
|
[HideInInspector]
|
|
public Vector3[] sverts;
|
|
|
|
[HideInInspector]
|
|
public Vector2[] uvs;
|
|
|
|
[HideInInspector]
|
|
public Vector2[] suvs;
|
|
|
|
[HideInInspector]
|
|
public Mesh mesh;
|
|
|
|
[HideInInspector]
|
|
public MegaModifier[] mods;
|
|
|
|
[HideInInspector]
|
|
public int UpdateMesh;
|
|
|
|
[HideInInspector]
|
|
public MegaModChannel dirtyChannels;
|
|
|
|
[HideInInspector]
|
|
public GameObject sourceObj;
|
|
|
|
[HideInInspector]
|
|
public Color[] cols;
|
|
|
|
[HideInInspector]
|
|
public float[] selection;
|
|
|
|
[HideInInspector]
|
|
public List<GameObject> group = new List<GameObject>();
|
|
|
|
public static bool GlobalDisplay = true;
|
|
|
|
private Vector4[] tangents;
|
|
|
|
private Vector3[] tan1;
|
|
|
|
private Vector3[] tan2;
|
|
|
|
public MegaModContext modContext = default(MegaModContext);
|
|
|
|
private bool VertsSource;
|
|
|
|
private bool UVsSource;
|
|
|
|
private MeshCollider meshCol;
|
|
|
|
public static bool ThreadingOn;
|
|
|
|
public bool UseThreading = true;
|
|
|
|
public static int Cores = 0;
|
|
|
|
private static MegaTaskInfo[] tasks;
|
|
|
|
private static bool isRunning = true;
|
|
|
|
public MegaNormMap[] mapping;
|
|
|
|
public int[] tris;
|
|
|
|
public Vector3[] facenorms;
|
|
|
|
public Vector3[] norms;
|
|
|
|
private Vector3[] ps3verts;
|
|
|
|
private MegaPS3Vert[] ps3mapping;
|
|
|
|
private static List<int> matches = new List<int>();
|
|
|
|
public void InitVertSource()
|
|
{
|
|
VertsSource = true;
|
|
UVsSource = true;
|
|
}
|
|
|
|
public Vector3[] GetSourceVerts(MegaModifierTarget target)
|
|
{
|
|
if (VertsSource)
|
|
{
|
|
VertsSource = false;
|
|
return target.verts;
|
|
}
|
|
return target.sverts;
|
|
}
|
|
|
|
public Vector3[] GetDestVerts(MegaModifierTarget target)
|
|
{
|
|
return target.sverts;
|
|
}
|
|
|
|
public Vector3[] GetSourceVerts()
|
|
{
|
|
if (VertsSource)
|
|
{
|
|
VertsSource = false;
|
|
return verts;
|
|
}
|
|
return sverts;
|
|
}
|
|
|
|
public void ChangeSourceVerts()
|
|
{
|
|
if (VertsSource)
|
|
{
|
|
VertsSource = false;
|
|
}
|
|
}
|
|
|
|
public Vector3[] GetDestVerts()
|
|
{
|
|
return sverts;
|
|
}
|
|
|
|
public Vector2[] GetSourceUvs()
|
|
{
|
|
if (UVsSource)
|
|
{
|
|
UVsSource = false;
|
|
return uvs;
|
|
}
|
|
return suvs;
|
|
}
|
|
|
|
public Vector2[] GetDestUvs()
|
|
{
|
|
return suvs;
|
|
}
|
|
|
|
private static int CompareOrder(MegaModifier m1, MegaModifier m2)
|
|
{
|
|
return m1.Order - m2.Order;
|
|
}
|
|
|
|
public void UpdateCols(int first, Color[] newcols)
|
|
{
|
|
if (cols == null || cols.Length == 0)
|
|
{
|
|
cols = new Color[verts.Length];
|
|
}
|
|
int num = first + newcols.Length;
|
|
if (num > cols.Length)
|
|
{
|
|
num = cols.Length;
|
|
}
|
|
int num2 = 0;
|
|
for (int i = first; i < num; i++)
|
|
{
|
|
cols[i] = newcols[num2++];
|
|
}
|
|
}
|
|
|
|
public void UpdateCol(int i, Color col)
|
|
{
|
|
if (cols == null || cols.Length == 0)
|
|
{
|
|
cols = new Color[verts.Length];
|
|
}
|
|
if (i < cols.Length)
|
|
{
|
|
cols[i] = col;
|
|
}
|
|
}
|
|
|
|
public void UpdateCols(Color[] newcols)
|
|
{
|
|
if (cols == null || cols.Length == 0)
|
|
{
|
|
cols = new Color[verts.Length];
|
|
}
|
|
if (newcols.Length != verts.Length)
|
|
{
|
|
Debug.Log("Number of new Colors does not match vertex count for mesh!");
|
|
}
|
|
else
|
|
{
|
|
cols = newcols;
|
|
}
|
|
}
|
|
|
|
public void ModifyObject()
|
|
{
|
|
if (!Enabled || mods == null)
|
|
{
|
|
return;
|
|
}
|
|
dirtyChannels = MegaModChannel.None;
|
|
VertsSource = true;
|
|
UVsSource = true;
|
|
modContext.mod = this;
|
|
selection = null;
|
|
for (int i = 0; i < mods.Length; i++)
|
|
{
|
|
MegaModifier megaModifier = mods[i];
|
|
if (!(megaModifier != null) || !megaModifier.ModEnabled)
|
|
{
|
|
continue;
|
|
}
|
|
if ((bool)megaModifier.instance)
|
|
{
|
|
megaModifier.SetValues(megaModifier.instance);
|
|
}
|
|
if ((megaModifier.ChannelsReq() & MegaModChannel.Verts) != MegaModChannel.None)
|
|
{
|
|
megaModifier.verts = GetSourceVerts();
|
|
megaModifier.sverts = GetDestVerts();
|
|
}
|
|
modContext.Offset = megaModifier.Offset;
|
|
modContext.bbox = megaModifier.bbox;
|
|
megaModifier.SetTM();
|
|
if (!megaModifier.ModLateUpdate(modContext))
|
|
{
|
|
continue;
|
|
}
|
|
if (selection != null)
|
|
{
|
|
megaModifier.ModifyWeighted(this);
|
|
if (UpdateMesh < 1)
|
|
{
|
|
UpdateMesh = 1;
|
|
}
|
|
}
|
|
else if (UpdateMesh < 1)
|
|
{
|
|
megaModifier.Modify(this);
|
|
UpdateMesh = 1;
|
|
}
|
|
else
|
|
{
|
|
megaModifier.Modify(this);
|
|
}
|
|
dirtyChannels |= megaModifier.ChannelsChanged();
|
|
megaModifier.ModEnd(this);
|
|
}
|
|
if (UpdateMesh == 1)
|
|
{
|
|
SetMesh(ref sverts);
|
|
UpdateMesh = 0;
|
|
}
|
|
else if (UpdateMesh == 0)
|
|
{
|
|
SetMesh(ref verts);
|
|
UpdateMesh = -1;
|
|
}
|
|
}
|
|
|
|
public void SetMesh(ref Vector3[] _verts)
|
|
{
|
|
if (mesh == null)
|
|
{
|
|
return;
|
|
}
|
|
if ((dirtyChannels & MegaModChannel.Verts) != MegaModChannel.None)
|
|
{
|
|
mesh.vertices = sverts;
|
|
}
|
|
if ((dirtyChannels & MegaModChannel.UV) != MegaModChannel.None)
|
|
{
|
|
mesh.uv = suvs;
|
|
}
|
|
if (recalcnorms)
|
|
{
|
|
RecalcNormals();
|
|
}
|
|
if (recalcTangents)
|
|
{
|
|
BuildTangents();
|
|
}
|
|
if (recalcbounds)
|
|
{
|
|
mesh.RecalculateBounds();
|
|
}
|
|
if (recalcCollider)
|
|
{
|
|
if (meshCol == null)
|
|
{
|
|
meshCol = GetComponent<MeshCollider>();
|
|
}
|
|
if (meshCol != null)
|
|
{
|
|
meshCol.sharedMesh = null;
|
|
meshCol.sharedMesh = mesh;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void RecalcNormals()
|
|
{
|
|
if (NormalMethod == MegaNormalMethod.Unity || dynamicMesh)
|
|
{
|
|
mesh.RecalculateNormals();
|
|
return;
|
|
}
|
|
if (mapping == null)
|
|
{
|
|
BuildNormalMapping(mesh, false);
|
|
}
|
|
if (!UseThreading || !ThreadingOn || Cores < 1 || !Application.isPlaying)
|
|
{
|
|
RecalcNormals(mesh, sverts);
|
|
}
|
|
else
|
|
{
|
|
RecalcNormalsMT(mesh, sverts);
|
|
}
|
|
}
|
|
|
|
private void BuildTangents()
|
|
{
|
|
if (uvs != null)
|
|
{
|
|
BuildTangents(mesh, sverts);
|
|
}
|
|
}
|
|
|
|
private void BuildTangents(Mesh ms, Vector3[] _verts)
|
|
{
|
|
int num = ms.triangles.Length;
|
|
int num2 = _verts.Length;
|
|
if (tan1 == null || tan1.Length != num2)
|
|
{
|
|
tan1 = new Vector3[num2];
|
|
}
|
|
if (tan2 == null || tan2.Length != num2)
|
|
{
|
|
tan2 = new Vector3[num2];
|
|
}
|
|
if (tangents == null || tangents.Length != num2)
|
|
{
|
|
tangents = new Vector4[num2];
|
|
}
|
|
Vector3[] normals = ms.normals;
|
|
int[] triangles = ms.triangles;
|
|
for (int i = 0; i < num; i += 3)
|
|
{
|
|
long num3 = triangles[i];
|
|
long num4 = triangles[i + 1];
|
|
long num5 = triangles[i + 2];
|
|
Vector3 vector = _verts[num3];
|
|
Vector3 vector2 = _verts[num4];
|
|
Vector3 vector3 = _verts[num5];
|
|
Vector2 vector4 = uvs[num3];
|
|
Vector2 vector5 = uvs[num4];
|
|
Vector2 vector6 = uvs[num5];
|
|
float num6 = vector2.x - vector.x;
|
|
float num7 = vector3.x - vector.x;
|
|
float num8 = vector2.y - vector.y;
|
|
float num9 = vector3.y - vector.y;
|
|
float num10 = vector2.z - vector.z;
|
|
float num11 = vector3.z - vector.z;
|
|
float num12 = vector5.x - vector4.x;
|
|
float num13 = vector6.x - vector4.x;
|
|
float num14 = vector5.y - vector4.y;
|
|
float num15 = vector6.y - vector4.y;
|
|
float num16 = 1f / (num12 * num15 - num13 * num14);
|
|
Vector3 vector7 = new Vector3((num15 * num6 - num14 * num7) * num16, (num15 * num8 - num14 * num9) * num16, (num15 * num10 - num14 * num11) * num16);
|
|
Vector3 vector8 = new Vector3((num12 * num7 - num13 * num6) * num16, (num12 * num9 - num13 * num8) * num16, (num12 * num11 - num13 * num10) * num16);
|
|
tan1[num3].x += vector7.x;
|
|
tan1[num3].y += vector7.y;
|
|
tan1[num3].z += vector7.z;
|
|
tan1[num4].x += vector7.x;
|
|
tan1[num4].y += vector7.y;
|
|
tan1[num4].z += vector7.z;
|
|
tan1[num5].x += vector7.x;
|
|
tan1[num5].y += vector7.y;
|
|
tan1[num5].z += vector7.z;
|
|
tan2[num3].x += vector8.x;
|
|
tan2[num3].y += vector8.y;
|
|
tan2[num3].z += vector8.z;
|
|
tan2[num4].x += vector8.x;
|
|
tan2[num4].y += vector8.y;
|
|
tan2[num4].z += vector8.z;
|
|
tan2[num5].x += vector8.x;
|
|
tan2[num5].y += vector8.y;
|
|
tan2[num5].z += vector8.z;
|
|
}
|
|
for (int j = 0; j < _verts.Length; j++)
|
|
{
|
|
Vector3 normal = normals[j];
|
|
Vector3 tangent = tan1[j];
|
|
Vector3.OrthoNormalize(ref normal, ref tangent);
|
|
tangents[j].x = tangent.x;
|
|
tangents[j].y = tangent.y;
|
|
tangents[j].z = tangent.z;
|
|
tangents[j].w = ((!(Vector3.Dot(Vector3.Cross(normal, tangent), tan2[j]) < 0f)) ? 1f : (-1f));
|
|
}
|
|
ms.tangents = tangents;
|
|
}
|
|
|
|
public void Sort()
|
|
{
|
|
Array.Sort(mods, CompareOrder);
|
|
}
|
|
|
|
public void BuildList()
|
|
{
|
|
mods = GetComponents<MegaModifier>();
|
|
for (int i = 0; i < mods.Length; i++)
|
|
{
|
|
if (mods[i].Order == -1)
|
|
{
|
|
mods[i].Order = i;
|
|
}
|
|
}
|
|
Array.Sort(mods, CompareOrder);
|
|
}
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
modContext.mod = this;
|
|
modContext.go = base.gameObject;
|
|
if (!GlobalDisplay || !DrawGizmos || !Enabled)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < mods.Length; i++)
|
|
{
|
|
MegaModifier megaModifier = mods[i];
|
|
if (megaModifier != null && megaModifier.ModEnabled && megaModifier.DisplayGizmo)
|
|
{
|
|
modContext.Offset = megaModifier.Offset;
|
|
modContext.bbox = megaModifier.bbox;
|
|
megaModifier.DrawGizmo(modContext);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void MakeThreads()
|
|
{
|
|
if (Cores > 0)
|
|
{
|
|
isRunning = true;
|
|
tasks = new MegaTaskInfo[Cores];
|
|
for (int i = 0; i < Cores; i++)
|
|
{
|
|
tasks[i] = new MegaTaskInfo();
|
|
tasks[i].name = "ThreadID " + i;
|
|
tasks[i].pauseevent = new AutoResetEvent(false);
|
|
tasks[i]._thread = new Thread(DoWork);
|
|
tasks[i]._thread.Start(tasks[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ModifyObjectMT()
|
|
{
|
|
if (Cores == 0)
|
|
{
|
|
Cores = SystemInfo.processorCount - 1;
|
|
}
|
|
if (!UseThreading || !ThreadingOn || Cores < 1 || !Application.isPlaying)
|
|
{
|
|
ModifyObject();
|
|
return;
|
|
}
|
|
if (tasks == null)
|
|
{
|
|
MakeThreads();
|
|
}
|
|
if (!Enabled || mods == null)
|
|
{
|
|
return;
|
|
}
|
|
dirtyChannels = MegaModChannel.None;
|
|
VertsSource = true;
|
|
UVsSource = true;
|
|
modContext.mod = this;
|
|
PrepareForMT();
|
|
int num = verts.Length / (Cores + 1);
|
|
if (Cores > 0)
|
|
{
|
|
int num2 = num;
|
|
for (int i = 0; i < tasks.Length; i++)
|
|
{
|
|
tasks[i].jobtype = MegaJobType.Modifier;
|
|
tasks[i].index = i + 1;
|
|
tasks[i].cores = tasks.Length;
|
|
tasks[i].start = num2;
|
|
tasks[i].end = num2 + num;
|
|
tasks[i].modcontext = modContext;
|
|
num2 += num;
|
|
}
|
|
tasks[Cores - 1].end = verts.Length;
|
|
for (int j = 0; j < tasks.Length; j++)
|
|
{
|
|
tasks[j].pauseevent.Set();
|
|
}
|
|
}
|
|
DoWork1(0, num);
|
|
WaitJobs();
|
|
for (int k = 0; k < mods.Length; k++)
|
|
{
|
|
MegaModifier megaModifier = mods[k];
|
|
if (megaModifier.valid)
|
|
{
|
|
megaModifier.DoneMT(this);
|
|
}
|
|
}
|
|
Done();
|
|
if (UpdateMesh == 1)
|
|
{
|
|
SetMesh(ref sverts);
|
|
UpdateMesh = 0;
|
|
}
|
|
else if (UpdateMesh == 0)
|
|
{
|
|
SetMesh(ref verts);
|
|
UpdateMesh = -1;
|
|
}
|
|
}
|
|
|
|
private void PrepareForMT()
|
|
{
|
|
selection = null;
|
|
for (int i = 0; i < mods.Length; i++)
|
|
{
|
|
MegaModifier megaModifier = mods[i];
|
|
megaModifier.valid = false;
|
|
if (!(megaModifier != null) || !megaModifier.ModEnabled)
|
|
{
|
|
continue;
|
|
}
|
|
modContext.Offset = megaModifier.Offset;
|
|
modContext.bbox = megaModifier.bbox;
|
|
megaModifier.SetTM();
|
|
if (megaModifier.ModLateUpdate(modContext))
|
|
{
|
|
megaModifier.valid = true;
|
|
if ((megaModifier.ChannelsReq() & MegaModChannel.Verts) != MegaModChannel.None)
|
|
{
|
|
megaModifier.verts = GetSourceVerts();
|
|
megaModifier.sverts = GetDestVerts();
|
|
}
|
|
if (UpdateMesh < 1)
|
|
{
|
|
UpdateMesh = 1;
|
|
}
|
|
dirtyChannels |= megaModifier.ChannelsChanged();
|
|
}
|
|
megaModifier.selection = selection;
|
|
megaModifier.PrepareMT(this, Cores + 1);
|
|
}
|
|
}
|
|
|
|
private void DoWork(object info)
|
|
{
|
|
MegaTaskInfo megaTaskInfo = (MegaTaskInfo)info;
|
|
while (isRunning)
|
|
{
|
|
megaTaskInfo.pauseevent.WaitOne(-1, false);
|
|
switch (megaTaskInfo.jobtype)
|
|
{
|
|
case MegaJobType.Modifier:
|
|
{
|
|
if (megaTaskInfo.end <= 0)
|
|
{
|
|
break;
|
|
}
|
|
for (int i = 0; i < megaTaskInfo.modcontext.mod.mods.Length; i++)
|
|
{
|
|
MegaModifier megaModifier = megaTaskInfo.modcontext.mod.mods[i];
|
|
if (megaModifier.valid)
|
|
{
|
|
megaModifier.DoWork(this, megaTaskInfo.index, megaTaskInfo.start, megaTaskInfo.end, Cores + 1);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case MegaJobType.FaceNormalCalc:
|
|
RecalcFaceNormalsMT(megaTaskInfo.modcontext.mod, megaTaskInfo.index, Cores + 1);
|
|
break;
|
|
case MegaJobType.VertexNormalCalc:
|
|
RecalcVertexNormalsMT(megaTaskInfo.modcontext.mod, megaTaskInfo.index, Cores + 1);
|
|
break;
|
|
case MegaJobType.FaceTangentCalc:
|
|
BuildFaceTangentsMT(megaTaskInfo.modcontext.mod, megaTaskInfo.index, Cores + 1);
|
|
break;
|
|
case MegaJobType.VertexTangentCalc:
|
|
BuildVertexTangentsMT(megaTaskInfo.modcontext.mod, megaTaskInfo.index, Cores + 1);
|
|
break;
|
|
}
|
|
megaTaskInfo.end = 0;
|
|
}
|
|
}
|
|
|
|
private void DoWork1(int start, int end)
|
|
{
|
|
for (int i = 0; i < mods.Length; i++)
|
|
{
|
|
MegaModifier megaModifier = mods[i];
|
|
if (megaModifier.valid)
|
|
{
|
|
megaModifier.DoWork(this, 0, start, end, Cores + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnApplicationQuit()
|
|
{
|
|
if (!Application.isPlaying)
|
|
{
|
|
return;
|
|
}
|
|
MegaModifiers[] array = (MegaModifiers[])Resources.FindObjectsOfTypeAll(typeof(MegaModifiers));
|
|
if (array.Length != 1)
|
|
{
|
|
return;
|
|
}
|
|
isRunning = false;
|
|
if (tasks != null)
|
|
{
|
|
for (int i = 0; i < tasks.Length; i++)
|
|
{
|
|
tasks[i].pauseevent.Set();
|
|
while (tasks[i]._thread.IsAlive)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
tasks = null;
|
|
}
|
|
|
|
private void Done()
|
|
{
|
|
for (int i = 0; i < mods.Length; i++)
|
|
{
|
|
MegaModifier megaModifier = mods[i];
|
|
if (megaModifier.valid)
|
|
{
|
|
megaModifier.ModEnd(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
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(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;
|
|
}
|
|
|
|
public void RecalcFaceNormalsMT(MegaModifiers mod, int cnum, int cores)
|
|
{
|
|
Vector3 zero = Vector3.zero;
|
|
Vector3 zero2 = Vector3.zero;
|
|
Vector3 zero3 = Vector3.zero;
|
|
Vector3 zero4 = Vector3.zero;
|
|
Vector3 zero5 = Vector3.zero;
|
|
int num = mod.tris.Length / 3 / cores;
|
|
int num2 = cnum * num * 3;
|
|
int num3 = num2 + num * 3;
|
|
if (cnum == cores - 1)
|
|
{
|
|
num3 = mod.tris.Length;
|
|
}
|
|
int num4 = num2 / 3;
|
|
for (int i = num2; i < num3; i += 3)
|
|
{
|
|
zero = mod.sverts[mod.tris[i]];
|
|
zero2 = mod.sverts[mod.tris[i + 1]];
|
|
zero3 = mod.sverts[mod.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;
|
|
mod.facenorms[num4++] = zero;
|
|
}
|
|
}
|
|
|
|
public void RecalcVertexNormalsMT(MegaModifiers mod, int cnum, int cores)
|
|
{
|
|
Vector3 zero = Vector3.zero;
|
|
int num = mod.norms.Length / cores;
|
|
int num2 = cnum * num;
|
|
int num3 = num2 + num;
|
|
if (cnum == cores - 1)
|
|
{
|
|
num3 = mod.norms.Length;
|
|
}
|
|
for (int i = num2; i < num3; i++)
|
|
{
|
|
if (mod.mapping[i].faces.Length > 0)
|
|
{
|
|
Vector3 vector = mod.facenorms[mod.mapping[i].faces[0]];
|
|
for (int j = 1; j < mod.mapping[i].faces.Length; j++)
|
|
{
|
|
zero = mod.facenorms[mod.mapping[i].faces[j]];
|
|
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;
|
|
mod.norms[i] = vector;
|
|
}
|
|
else
|
|
{
|
|
mod.norms[i] = Vector3.up;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void WaitJobs()
|
|
{
|
|
if (Cores <= 0)
|
|
{
|
|
return;
|
|
}
|
|
int num = 0;
|
|
bool flag = false;
|
|
do
|
|
{
|
|
flag = false;
|
|
for (int i = 0; i < tasks.Length; i++)
|
|
{
|
|
if (tasks[i].end > 0)
|
|
{
|
|
flag = true;
|
|
break;
|
|
}
|
|
}
|
|
if (flag)
|
|
{
|
|
num++;
|
|
Thread.Sleep(0);
|
|
}
|
|
}
|
|
while (flag);
|
|
}
|
|
|
|
public void RecalcNormalsMT(Mesh ms, Vector3[] _verts)
|
|
{
|
|
for (int i = 0; i < Cores; i++)
|
|
{
|
|
tasks[i].jobtype = MegaJobType.FaceNormalCalc;
|
|
tasks[i].end = 1;
|
|
tasks[i].pauseevent.Set();
|
|
}
|
|
RecalcFaceNormalsMT(this, 0, Cores + 1);
|
|
WaitJobs();
|
|
for (int j = 0; j < Cores; j++)
|
|
{
|
|
tasks[j].jobtype = MegaJobType.VertexNormalCalc;
|
|
tasks[j].end = 1;
|
|
tasks[j].pauseevent.Set();
|
|
}
|
|
RecalcVertexNormalsMT(this, 0, Cores + 1);
|
|
WaitJobs();
|
|
ms.normals = norms;
|
|
}
|
|
|
|
private void BuildTangentsMT(Mesh ms, Vector3[] _verts)
|
|
{
|
|
if (uvs != null)
|
|
{
|
|
int num = _verts.Length;
|
|
if (tan1 == null || tan1.Length != num)
|
|
{
|
|
tan1 = new Vector3[num];
|
|
}
|
|
if (tan2 == null || tan2.Length != num)
|
|
{
|
|
tan2 = new Vector3[num];
|
|
}
|
|
if (tangents == null || tangents.Length != num)
|
|
{
|
|
tangents = new Vector4[num];
|
|
}
|
|
if (tris == null || tris.Length == 0)
|
|
{
|
|
tris = ms.triangles;
|
|
}
|
|
if (norms == null || norms.Length == 0)
|
|
{
|
|
norms = ms.normals;
|
|
}
|
|
for (int i = 0; i < Cores; i++)
|
|
{
|
|
tasks[i].jobtype = MegaJobType.FaceTangentCalc;
|
|
tasks[i].end = 1;
|
|
tasks[i].pauseevent.Set();
|
|
}
|
|
BuildFaceTangentsMT(this, 0, Cores + 1);
|
|
WaitJobs();
|
|
for (int j = 0; j < Cores; j++)
|
|
{
|
|
tasks[j].jobtype = MegaJobType.VertexTangentCalc;
|
|
tasks[j].end = 1;
|
|
tasks[j].pauseevent.Set();
|
|
}
|
|
BuildVertexTangentsMT(this, 0, Cores + 1);
|
|
WaitJobs();
|
|
mesh.tangents = tangents;
|
|
}
|
|
}
|
|
|
|
private void BuildFaceTangentsMT(MegaModifiers mc, int cnum, int cores)
|
|
{
|
|
int num = mc.tris.Length;
|
|
int num2 = num / 3 / cores;
|
|
int num3 = cnum * num2 * 3;
|
|
int num4 = num3 + num2 * 3;
|
|
if (cnum == cores - 1)
|
|
{
|
|
num4 = num;
|
|
}
|
|
Vector3 zero = Vector3.zero;
|
|
Vector3 zero2 = Vector3.zero;
|
|
Vector3 zero3 = Vector3.zero;
|
|
Vector2 vector = Vector3.zero;
|
|
Vector2 vector2 = Vector3.zero;
|
|
Vector2 vector3 = Vector3.zero;
|
|
for (int i = num3; i < num4; i += 3)
|
|
{
|
|
int num5 = mc.tris[i];
|
|
int num6 = mc.tris[i + 1];
|
|
int num7 = mc.tris[i + 2];
|
|
zero = mc.sverts[num5];
|
|
zero2 = mc.sverts[num6];
|
|
zero3 = mc.sverts[num7];
|
|
vector = mc.uvs[num5];
|
|
vector2 = mc.uvs[num6];
|
|
vector3 = mc.uvs[num7];
|
|
float num8 = zero2.x - zero.x;
|
|
float num9 = zero3.x - zero.x;
|
|
float num10 = zero2.y - zero.y;
|
|
float num11 = zero3.y - zero.y;
|
|
float num12 = zero2.z - zero.z;
|
|
float num13 = zero3.z - zero.z;
|
|
float num14 = vector2.x - vector.x;
|
|
float num15 = vector3.x - vector.x;
|
|
float num16 = vector2.y - vector.y;
|
|
float num17 = vector3.y - vector.y;
|
|
float num18 = 1f / (num14 * num17 - num15 * num16);
|
|
Vector3 vector4 = new Vector3((num17 * num8 - num16 * num9) * num18, (num17 * num10 - num16 * num11) * num18, (num17 * num12 - num16 * num13) * num18);
|
|
Vector3 vector5 = new Vector3((num14 * num9 - num15 * num8) * num18, (num14 * num11 - num15 * num10) * num18, (num14 * num13 - num15 * num12) * num18);
|
|
lock (mc)
|
|
{
|
|
mc.tan1[num5].x += vector4.x;
|
|
mc.tan1[num5].y += vector4.y;
|
|
mc.tan1[num5].z += vector4.z;
|
|
mc.tan1[num6].x += vector4.x;
|
|
mc.tan1[num6].y += vector4.y;
|
|
mc.tan1[num6].z += vector4.z;
|
|
mc.tan1[num7].x += vector4.x;
|
|
mc.tan1[num7].y += vector4.y;
|
|
mc.tan1[num7].z += vector4.z;
|
|
mc.tan2[num5].x += vector5.x;
|
|
mc.tan2[num5].y += vector5.y;
|
|
mc.tan2[num5].z += vector5.z;
|
|
mc.tan2[num6].x += vector5.x;
|
|
mc.tan2[num6].y += vector5.y;
|
|
mc.tan2[num6].z += vector5.z;
|
|
mc.tan2[num7].x += vector5.x;
|
|
mc.tan2[num7].y += vector5.y;
|
|
mc.tan2[num7].z += vector5.z;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void BuildVertexTangentsMT(MegaModifiers mc, int cnum, int cores)
|
|
{
|
|
int num = mc.sverts.Length;
|
|
int num2 = num / cores;
|
|
int num3 = cnum * num2;
|
|
int num4 = num3 + num2;
|
|
if (cnum == cores - 1)
|
|
{
|
|
num4 = num;
|
|
}
|
|
for (int i = num3; i < num4; i++)
|
|
{
|
|
Vector3 normal = mc.norms[i];
|
|
Vector3 tangent = mc.tan1[i];
|
|
Vector3.OrthoNormalize(ref normal, ref tangent);
|
|
mc.tangents[i].x = tangent.x;
|
|
mc.tangents[i].y = tangent.y;
|
|
mc.tangents[i].z = tangent.z;
|
|
mc.tangents[i].w = ((!(Vector3.Dot(Vector3.Cross(normal, tangent), mc.tan2[i]) < 0f)) ? 1f : (-1f));
|
|
}
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (Application.platform == RuntimePlatform.PS3 && !Application.isEditor)
|
|
{
|
|
Mesh mesh = MegaUtils.GetMesh(base.gameObject);
|
|
BuildPS3Mapping(verts, mesh.vertices);
|
|
}
|
|
}
|
|
|
|
private int[] FindMatches(Vector3 p, Vector3[] array)
|
|
{
|
|
matches.Clear();
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (array[i].x == p.x && array[i].y == p.y && array[i].z == p.z)
|
|
{
|
|
matches.Add(i);
|
|
}
|
|
}
|
|
return matches.ToArray();
|
|
}
|
|
|
|
public void BuildPS3Mapping(Vector3[] oldverts, Vector3[] newverts)
|
|
{
|
|
ps3verts = new Vector3[newverts.Length];
|
|
ps3mapping = new MegaPS3Vert[oldverts.Length];
|
|
for (int i = 0; i < oldverts.Length; i++)
|
|
{
|
|
MegaPS3Vert megaPS3Vert = new MegaPS3Vert();
|
|
megaPS3Vert.indices = FindMatches(oldverts[i], newverts);
|
|
ps3mapping[i] = megaPS3Vert;
|
|
}
|
|
}
|
|
|
|
public void SetPS3Mesh()
|
|
{
|
|
if (ps3mapping == null || ps3mapping.Length == 0)
|
|
{
|
|
Mesh mesh = MegaUtils.GetMesh(base.gameObject);
|
|
BuildPS3Mapping(verts, mesh.vertices);
|
|
}
|
|
if ((dirtyChannels & MegaModChannel.Verts) != MegaModChannel.None)
|
|
{
|
|
for (int i = 0; i < sverts.Length; i++)
|
|
{
|
|
for (int j = 0; j < ps3mapping[i].indices.Length; j++)
|
|
{
|
|
ps3verts[ps3mapping[i].indices[j]] = sverts[i];
|
|
}
|
|
}
|
|
this.mesh.vertices = ps3verts;
|
|
}
|
|
if ((dirtyChannels & MegaModChannel.UV) != MegaModChannel.None)
|
|
{
|
|
this.mesh.uv = suvs;
|
|
}
|
|
if (recalcnorms)
|
|
{
|
|
RecalcNormals();
|
|
}
|
|
if (recalcTangents)
|
|
{
|
|
BuildTangents();
|
|
}
|
|
if (recalcbounds)
|
|
{
|
|
this.mesh.RecalculateBounds();
|
|
}
|
|
if (recalcCollider)
|
|
{
|
|
if (meshCol == null)
|
|
{
|
|
meshCol = GetComponent<MeshCollider>();
|
|
}
|
|
if (meshCol != null)
|
|
{
|
|
meshCol.sharedMesh = null;
|
|
meshCol.sharedMesh = this.mesh;
|
|
}
|
|
}
|
|
}
|
|
}
|