411 lines
9.7 KiB
C#
411 lines
9.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
[ExecuteInEditMode]
|
|
public class MegaModifyGroup : MegaModifyObject
|
|
{
|
|
public List<MegaModifierTarget> targets = new List<MegaModifierTarget>();
|
|
|
|
private static int CompareOrder(MegaModifier m1, MegaModifier m2)
|
|
{
|
|
return m1.Order - m2.Order;
|
|
}
|
|
|
|
[ContextMenu("Resort")]
|
|
public override void Resort()
|
|
{
|
|
BuildList();
|
|
}
|
|
|
|
[ContextMenu("Help")]
|
|
public override void Help()
|
|
{
|
|
Application.OpenURL("http://www.west-racing.com/mf/?page_id=444");
|
|
}
|
|
|
|
[ContextMenu("Reset Group Info")]
|
|
public void GroupResetMeshInfo()
|
|
{
|
|
for (int i = 0; i < targets.Count; i++)
|
|
{
|
|
if (targets[i].cachedMesh == null)
|
|
{
|
|
targets[i].cachedMesh = UnityEngine.Object.Instantiate(GetMesh(targets[i].go));
|
|
}
|
|
}
|
|
GroupReStart1(false);
|
|
for (int j = 0; j < targets.Count; j++)
|
|
{
|
|
if (targets[j].mesh != null)
|
|
{
|
|
targets[j].mesh.vertices = verts;
|
|
targets[j].mesh.uv = uvs;
|
|
if (recalcnorms)
|
|
{
|
|
targets[j].mesh.RecalculateNormals();
|
|
}
|
|
if (recalcbounds)
|
|
{
|
|
targets[j].mesh.RecalculateBounds();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ResetOld()
|
|
{
|
|
for (int i = 0; i < targets.Count; i++)
|
|
{
|
|
if (targets[i].cachedMesh == null)
|
|
{
|
|
targets[i].cachedMesh = UnityEngine.Object.Instantiate(GetMesh(targets[i].go));
|
|
}
|
|
}
|
|
BuildList();
|
|
GroupReStart1(true);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (UpdateMode == MegaUpdateMode.Update)
|
|
{
|
|
GroupModify();
|
|
}
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
if (UpdateMode == MegaUpdateMode.LateUpdate)
|
|
{
|
|
GroupModify();
|
|
}
|
|
}
|
|
|
|
private void SetTarget(MegaModifierTarget target)
|
|
{
|
|
InitVertSource();
|
|
}
|
|
|
|
public void GroupModify()
|
|
{
|
|
if (!Enabled || mods == null)
|
|
{
|
|
return;
|
|
}
|
|
dirtyChannels = MegaModChannel.None;
|
|
int updateMesh = UpdateMesh;
|
|
modContext.mod = this;
|
|
foreach (MegaModifierTarget target in targets)
|
|
{
|
|
if (!target.go)
|
|
{
|
|
continue;
|
|
}
|
|
modContext.Offset = target.Offset;
|
|
modContext.bbox = target.bbox;
|
|
SetTarget(target);
|
|
UpdateMesh = updateMesh;
|
|
MegaModifier[] array = mods;
|
|
foreach (MegaModifier megaModifier in array)
|
|
{
|
|
if (!(megaModifier != null) || !megaModifier.ModEnabled)
|
|
{
|
|
continue;
|
|
}
|
|
if ((megaModifier.ChannelsReq() & MegaModChannel.Verts) != MegaModChannel.None)
|
|
{
|
|
Debug.Log("set verts");
|
|
megaModifier.verts = GetSourceVerts(target);
|
|
megaModifier.sverts = GetDestVerts(target);
|
|
}
|
|
megaModifier.Offset = target.Offset;
|
|
megaModifier.bbox = target.bbox;
|
|
megaModifier.SetTM(megaModifier.Offset);
|
|
if (megaModifier.ModLateUpdate(modContext))
|
|
{
|
|
if (UpdateMesh < 1)
|
|
{
|
|
Debug.Log("a");
|
|
megaModifier.Modify(this);
|
|
UpdateMesh = 1;
|
|
}
|
|
else
|
|
{
|
|
megaModifier.Modify(this);
|
|
}
|
|
dirtyChannels |= megaModifier.ChannelsChanged();
|
|
megaModifier.ModEnd(this);
|
|
}
|
|
}
|
|
if (UpdateMesh == 1)
|
|
{
|
|
SetMesh(target, ref target.sverts);
|
|
UpdateMesh = 0;
|
|
}
|
|
else if (UpdateMesh == 0)
|
|
{
|
|
SetMesh(target, ref target.verts);
|
|
UpdateMesh = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetMesh(MegaModifierTarget target, ref Vector3[] _verts)
|
|
{
|
|
if ((dirtyChannels & MegaModChannel.Verts) != MegaModChannel.None)
|
|
{
|
|
target.mesh.vertices = _verts;
|
|
}
|
|
if ((dirtyChannels & MegaModChannel.UV) != MegaModChannel.None)
|
|
{
|
|
target.mesh.uv = suvs;
|
|
}
|
|
if (recalcnorms)
|
|
{
|
|
target.mesh.RecalculateNormals();
|
|
}
|
|
if (recalcTangents)
|
|
{
|
|
BuildTangents(target);
|
|
}
|
|
if (recalcbounds)
|
|
{
|
|
target.mesh.RecalculateBounds();
|
|
}
|
|
if (recalcCollider)
|
|
{
|
|
if (target.meshCol == null)
|
|
{
|
|
target.meshCol = GetComponent<MeshCollider>();
|
|
}
|
|
if (target.meshCol != null)
|
|
{
|
|
target.meshCol.sharedMesh = null;
|
|
target.meshCol.sharedMesh = target.mesh;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void BuildTangents(MegaModifierTarget target)
|
|
{
|
|
if (uvs != null)
|
|
{
|
|
int num = target.mesh.triangles.Length;
|
|
int num2 = target.mesh.vertices.Length;
|
|
if (target.tan1 == null || target.tan1.Length != num2)
|
|
{
|
|
target.tan1 = new Vector3[num2];
|
|
}
|
|
if (target.tan2 == null || target.tan2.Length != num2)
|
|
{
|
|
target.tan2 = new Vector3[num2];
|
|
}
|
|
if (target.tangents == null || target.tangents.Length != num2)
|
|
{
|
|
target.tangents = new Vector4[num2];
|
|
}
|
|
Vector3[] normals = target.mesh.normals;
|
|
int[] triangles = target.mesh.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);
|
|
target.tan1[num3] += vector7;
|
|
target.tan1[num4] += vector7;
|
|
target.tan1[num5] += vector7;
|
|
target.tan2[num3] += vector8;
|
|
target.tan2[num4] += vector8;
|
|
target.tan2[num5] += vector8;
|
|
}
|
|
for (int j = 0; j < num2; j++)
|
|
{
|
|
Vector3 normal = normals[j];
|
|
Vector3 tangent = target.tan1[j];
|
|
Vector3.OrthoNormalize(ref normal, ref tangent);
|
|
target.tangents[j].x = tangent.x;
|
|
target.tangents[j].y = tangent.y;
|
|
target.tangents[j].z = tangent.z;
|
|
target.tangents[j].w = ((!(Vector3.Dot(Vector3.Cross(normal, tangent), target.tan2[j]) < 0f)) ? 1f : (-1f));
|
|
}
|
|
target.mesh.tangents = target.tangents;
|
|
}
|
|
}
|
|
|
|
private Mesh GetMesh(GameObject go)
|
|
{
|
|
if ((bool)go)
|
|
{
|
|
MeshFilter componentInChildren = go.GetComponentInChildren<MeshFilter>();
|
|
if (componentInChildren != null)
|
|
{
|
|
return componentInChildren.sharedMesh;
|
|
}
|
|
SkinnedMeshRenderer componentInChildren2 = go.GetComponentInChildren<SkinnedMeshRenderer>();
|
|
if (componentInChildren2 != null)
|
|
{
|
|
return componentInChildren2.sharedMesh;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private Mesh GetMesh1(GameObject go)
|
|
{
|
|
if ((bool)go)
|
|
{
|
|
MeshFilter componentInChildren = go.GetComponentInChildren<MeshFilter>();
|
|
if (componentInChildren != null)
|
|
{
|
|
return componentInChildren.mesh;
|
|
}
|
|
SkinnedMeshRenderer componentInChildren2 = go.GetComponentInChildren<SkinnedMeshRenderer>();
|
|
if (componentInChildren2 != null)
|
|
{
|
|
return componentInChildren2.sharedMesh;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void GroupReStart1(bool force)
|
|
{
|
|
for (int i = 0; i < targets.Count; i++)
|
|
{
|
|
if (force || targets[i].mesh == null)
|
|
{
|
|
targets[i].mesh = GetMesh1(targets[i].go);
|
|
}
|
|
if (targets[i].mesh != null)
|
|
{
|
|
bbox = targets[i].cachedMesh.bounds;
|
|
targets[i].sverts = new Vector3[targets[i].cachedMesh.vertexCount];
|
|
targets[i].verts = targets[i].cachedMesh.vertices;
|
|
targets[i].uvs = targets[i].cachedMesh.uv;
|
|
targets[i].suvs = new Vector2[targets[i].cachedMesh.uv.Length];
|
|
}
|
|
}
|
|
mods = GetComponents<MegaModifier>();
|
|
Array.Sort(mods, CompareOrder);
|
|
MegaModifier[] array = mods;
|
|
foreach (MegaModifier megaModifier in array)
|
|
{
|
|
if (megaModifier != null)
|
|
{
|
|
megaModifier.ModStart(this);
|
|
}
|
|
}
|
|
UpdateMesh = -1;
|
|
}
|
|
|
|
public void AddTarget(GameObject go)
|
|
{
|
|
}
|
|
|
|
public void RemoveTarget(GameObject go)
|
|
{
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
Transform[] componentsInChildren = base.gameObject.GetComponentsInChildren<Transform>(true);
|
|
targets = new List<MegaModifierTarget>(componentsInChildren.Length);
|
|
for (int i = 0; i < componentsInChildren.Length; i++)
|
|
{
|
|
MegaModifierTarget megaModifierTarget = new MegaModifierTarget();
|
|
megaModifierTarget.go = componentsInChildren[i].gameObject;
|
|
Mesh mesh = GetMesh(megaModifierTarget.go);
|
|
if (mesh != null)
|
|
{
|
|
megaModifierTarget.cachedMesh = UnityEngine.Object.Instantiate(mesh);
|
|
}
|
|
targets.Add(megaModifierTarget);
|
|
}
|
|
GroupReStart1(false);
|
|
}
|
|
|
|
[ContextMenu("Recalc Bounds")]
|
|
public void TestBounds()
|
|
{
|
|
for (int i = 0; i < mods.Length; i++)
|
|
{
|
|
GroupModReset(mods[i]);
|
|
}
|
|
}
|
|
|
|
public void GroupModReset(MegaModifier m)
|
|
{
|
|
if (!(m != null))
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < targets.Count; i++)
|
|
{
|
|
GameObject go = targets[i].go;
|
|
Bounds bounds = default(Bounds);
|
|
Mesh mesh = targets[i].cachedMesh;
|
|
if (mesh != null)
|
|
{
|
|
bounds = mesh.bounds;
|
|
}
|
|
for (int j = 0; j < targets.Count; j++)
|
|
{
|
|
Mesh mesh2 = targets[j].cachedMesh;
|
|
if (j != i && mesh2 != null)
|
|
{
|
|
Vector3 position = targets[j].go.transform.position;
|
|
position = go.transform.InverseTransformPoint(position);
|
|
Bounds bounds2 = new Bounds(position, targets[j].cachedMesh.bounds.size);
|
|
bounds.Encapsulate(bounds2);
|
|
}
|
|
}
|
|
targets[i].bbox.min = bounds.min;
|
|
targets[i].bbox.max = bounds.max;
|
|
targets[i].Offset = -bounds.center;
|
|
}
|
|
}
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
modContext.mod = this;
|
|
if (!MegaModifiers.GlobalDisplay || !DrawGizmos || !Enabled)
|
|
{
|
|
return;
|
|
}
|
|
foreach (MegaModifierTarget target in targets)
|
|
{
|
|
modContext.Offset = target.Offset;
|
|
modContext.bbox = target.bbox;
|
|
modContext.go = target.go;
|
|
MegaModifier[] array = mods;
|
|
foreach (MegaModifier megaModifier in array)
|
|
{
|
|
if (megaModifier != null && megaModifier.ModEnabled && megaModifier.DisplayGizmo)
|
|
{
|
|
megaModifier.DrawGizmo(modContext);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|