using System; using UnityEngine; [RequireComponent(typeof(MegaModifyObject))] public class MegaModifier : MonoBehaviour { [HideInInspector] public bool ModEnabled = true; [HideInInspector] public bool DisplayGizmo = true; [HideInInspector] public int Order = -1; [HideInInspector] public Vector3 Offset = Vector3.zero; [HideInInspector] public Vector3 gizmoPos = Vector3.zero; [HideInInspector] public Vector3 gizmoRot = Vector3.zero; [HideInInspector] public Vector3 gizmoScale = Vector3.one; [HideInInspector] public Color gizCol1 = Color.yellow; [HideInInspector] public Color gizCol2 = Color.green; [NonSerialized] [HideInInspector] public Matrix4x4 tm = default(Matrix4x4); [NonSerialized] public Matrix4x4 invtm = default(Matrix4x4); [HideInInspector] public MegaBox3 bbox = new MegaBox3(); [HideInInspector] public Vector3[] corners = new Vector3[8]; [HideInInspector] public int steps = 50; [HideInInspector] public Vector3[] verts; [HideInInspector] public Vector3[] sverts; [HideInInspector] public bool valid; [HideInInspector] public float[] selection; [HideInInspector] public MegaModifier instance; public bool limitchandisplay; public int startchannel; public int displaychans = 10; public bool useUndo = true; [HideInInspector] public string Label = string.Empty; [HideInInspector] public int MaxLOD; public virtual MegaModChannel ChannelsReq() { return MegaModChannel.Verts; } public virtual MegaModChannel ChannelsChanged() { return MegaModChannel.Verts; } public virtual float GizmoSize() { return bbox.Radius() * 0.05f; } public virtual void ModStart(MegaModifiers ms) { } public virtual void ModUpdate() { } public virtual bool ModLateUpdate(MegaModContext mc) { return true; } public virtual Vector3 Map(int i, Vector3 p) { return p; } public virtual void ShowGUI() { } public virtual string ModName() { return "Missing Name"; } public virtual bool InitMod(MegaModifiers mc) { return true; } public virtual bool Prepare(MegaModContext mc) { return true; } public virtual void ModEnd(MegaModifiers ms) { } public virtual string GetHelpURL() { return "?page_id=377"; } public virtual void PrepareMT(MegaModifiers mc, int cores) { } public virtual void DoneMT(MegaModifiers mc) { } public virtual void SetValues(MegaModifier mod) { } public virtual bool CanThread() { return true; } public virtual void Copy(MegaModifier dst) { dst.Label = Label; dst.MaxLOD = MaxLOD; dst.ModEnabled = ModEnabled; dst.DisplayGizmo = DisplayGizmo; dst.Order = Order; dst.Offset = Offset; dst.gizmoPos = gizmoPos; dst.gizmoRot = gizmoRot; dst.gizmoScale = gizmoScale; dst.gizCol1 = gizCol1; dst.gizCol2 = gizCol2; } public virtual void PostCopy(MegaModifier dst) { } public virtual void DoWork(MegaModifiers mc, int index, int start, int end, int cores) { if (selection != null) { DoWorkWeighted(mc, index, start, end, cores); return; } for (int i = start; i < end; i++) { sverts[i] = Map(i, verts[i]); } } public virtual void DoWorkWeighted(MegaModifiers mc, int index, int start, int end, int cores) { for (int i = start; i < end; i++) { Vector3 vector = verts[i]; float num = selection[i]; if (num > 0.001f) { Vector3 vector2 = Map(i, verts[i]); sverts[i].x = vector.x + (vector2.x - vector.x) * num; sverts[i].y = vector.y + (vector2.y - vector.y) * num; sverts[i].z = vector.z + (vector2.z - vector.z) * num; } else { sverts[i] = vector; } } } private void Awake() { MegaModifyObject component = base.gameObject.GetComponent(); if (component != null) { component.ModReset(this); } } private void Reset() { MegaModifyObject component = base.gameObject.GetComponent(); if (component != null) { component.ModReset(this); } } [ContextMenu("Help")] public void Help() { Application.OpenURL("http://www.west-racing.com/mf/" + GetHelpURL()); } [ContextMenu("Reset Offset")] public void ResetOffset() { Offset = Vector3.zero; } private Vector3 GetCentre() { MegaModifyObject component = base.gameObject.GetComponent(); if (component != null && component.cachedMesh != null) { return component.cachedMesh.bounds.center; } return Vector3.zero; } [ContextMenu("Reset GizmoPos")] public void ResetGizmoPos() { gizmoPos = Vector3.zero; } [ContextMenu("Reset GizmoRot")] public void ResetGizmoRot() { gizmoRot = Vector3.zero; } [ContextMenu("Reset GizmoScale")] public void ResetGizmoScale() { gizmoScale = Vector3.one; } [ContextMenu("Center Offset")] public void CentreOffset() { Offset = -GetCentre(); } [ContextMenu("Center GizmoPos")] public void CentreGizmoPos() { gizmoPos = -GetCentre(); } public void SetModMesh(Mesh ms) { if (ms != null) { Bounds bounds = ms.bounds; bbox.min = bounds.center - bounds.extents; bbox.max = bounds.center + bounds.extents; verts = ms.vertices; MeshChanged(); } } public virtual void MeshChanged() { } public void SetTM() { tm = Matrix4x4.identity; Quaternion q = Quaternion.Euler(-gizmoRot); tm.SetTRS(gizmoPos + Offset, q, gizmoScale); invtm = tm.inverse; } public void SetTM(Vector3 off) { tm = Matrix4x4.identity; Quaternion q = Quaternion.Euler(-gizmoRot); tm.SetTRS(gizmoPos + off, q, gizmoScale); invtm = tm.inverse; } public void SetAxis(Matrix4x4 tmAxis) { Matrix4x4 inverse = tmAxis.inverse; tm = tmAxis * tm; invtm *= inverse; } public virtual void Modify(ref Vector3[] sverts, ref Vector3[] verts) { for (int i = 0; i < verts.Length; i++) { sverts[i] = Map(i, verts[i]); } } public virtual void Modify(Vector3[] sverts, Vector3[] verts) { for (int i = 0; i < verts.Length; i++) { sverts[i] = Map(i, verts[i]); } } public virtual void Modify(MegaModifiers mc) { if (verts != null) { for (int i = 0; i < verts.Length; i++) { sverts[i] = Map(i, verts[i]); } } } public virtual void ModifyWeighted(MegaModifiers mc) { for (int i = 0; i < verts.Length; i++) { Vector3 vector = verts[i]; float num = mc.selection[i]; if (num > 0.001f) { Vector3 vector2 = Map(i, verts[i]); sverts[i].x = vector.x + (vector2.x - vector.x) * num; sverts[i].y = vector.y + (vector2.y - vector.y) * num; sverts[i].z = vector.z + (vector2.z - vector.z) * num; } else { sverts[i] = verts[i]; } } } public void DrawEdge(Vector3 p1, Vector3 p2) { Vector3 vector = Map(-1, p1); Vector3 zero = Vector3.zero; for (int i = 1; i <= steps; i++) { zero = p1 + (p2 - p1) * ((float)i / (float)steps); zero = Map(-1, zero); if ((i & 4) == 0) { Gizmos.color = gizCol1; } else { Gizmos.color = gizCol2; } Gizmos.DrawLine(vector, zero); vector = zero; } Gizmos.color = gizCol1; } public void DrawEdgeCol(Vector3 p1, Vector3 p2) { Vector3 vector = Map(-1, p1); Vector3 zero = Vector3.zero; for (int i = 1; i <= steps; i++) { zero = p1 + (p2 - p1) * ((float)i / (float)steps); zero = Map(-1, zero); Gizmos.DrawLine(vector, zero); vector = zero; } } public virtual void DrawGizmo(MegaModContext context) { tm = Matrix4x4.identity; MegaMatrix.Translate(ref tm, context.Offset); invtm = tm.inverse; if (Prepare(context)) { Vector3 min = context.bbox.min; Vector3 max = context.bbox.max; Matrix4x4 identity = Matrix4x4.identity; Vector3 pos = gizmoPos; pos.x = 0f - pos.x; pos.y = 0f - pos.y; pos.z = 0f - pos.z; Vector3 s = gizmoScale; s.x = 1f - (s.x - 1f); s.y = 1f - (s.y - 1f); identity.SetTRS(pos, Quaternion.Euler(gizmoRot), s); if (context.mod.sourceObj != null) { Gizmos.matrix = context.mod.sourceObj.transform.localToWorldMatrix * identity; } else { Gizmos.matrix = context.go.transform.localToWorldMatrix * identity; } corners[0] = new Vector3(min.x, min.y, min.z); corners[1] = new Vector3(min.x, max.y, min.z); corners[2] = new Vector3(max.x, max.y, min.z); corners[3] = new Vector3(max.x, min.y, min.z); corners[4] = new Vector3(min.x, min.y, max.z); corners[5] = new Vector3(min.x, max.y, max.z); corners[6] = new Vector3(max.x, max.y, max.z); corners[7] = new Vector3(max.x, min.y, max.z); DrawEdge(corners[0], corners[1]); DrawEdge(corners[1], corners[2]); DrawEdge(corners[2], corners[3]); DrawEdge(corners[3], corners[0]); DrawEdge(corners[4], corners[5]); DrawEdge(corners[5], corners[6]); DrawEdge(corners[6], corners[7]); DrawEdge(corners[7], corners[4]); DrawEdge(corners[0], corners[4]); DrawEdge(corners[1], corners[5]); DrawEdge(corners[2], corners[6]); DrawEdge(corners[3], corners[7]); ExtraGizmo(context); } } public virtual void ExtraGizmo(MegaModContext mc) { } public void DrawFromTo(MegaAxis axis, float from, float to, MegaModContext mc) { Vector3 min = mc.bbox.min; Vector3 max = mc.bbox.max; switch (axis) { case MegaAxis.X: corners[0] = new Vector3(0f - from, min.y, min.z); corners[1] = new Vector3(0f - from, max.y, min.z); corners[2] = new Vector3(0f - from, max.y, max.z); corners[3] = new Vector3(0f - from, min.y, max.z); corners[4] = new Vector3(0f - to, min.y, min.z); corners[5] = new Vector3(0f - to, max.y, min.z); corners[6] = new Vector3(0f - to, max.y, max.z); corners[7] = new Vector3(0f - to, min.y, max.z); break; case MegaAxis.Y: corners[0] = new Vector3(min.x, min.y, 0f - from); corners[1] = new Vector3(min.x, max.y, 0f - from); corners[2] = new Vector3(max.x, max.y, 0f - from); corners[3] = new Vector3(max.x, min.y, 0f - from); corners[4] = new Vector3(min.x, min.y, 0f - to); corners[5] = new Vector3(min.x, max.y, 0f - to); corners[6] = new Vector3(max.x, max.y, 0f - to); corners[7] = new Vector3(max.x, min.y, 0f - to); break; case MegaAxis.Z: corners[0] = new Vector3(min.x, from, min.z); corners[1] = new Vector3(min.x, from, max.z); corners[2] = new Vector3(max.x, from, max.z); corners[3] = new Vector3(max.x, from, min.z); corners[4] = new Vector3(min.x, to, min.z); corners[5] = new Vector3(min.x, to, max.z); corners[6] = new Vector3(max.x, to, max.z); corners[7] = new Vector3(max.x, to, min.z); break; } Color red = Color.red; red.a = gizCol1.a; Gizmos.color = red; Vector3 zero = Vector3.zero; DrawEdgeCol(corners[0] - zero, corners[1] - zero); DrawEdgeCol(corners[1] - zero, corners[2] - zero); DrawEdgeCol(corners[2] - zero, corners[3] - zero); DrawEdgeCol(corners[3] - zero, corners[0] - zero); red = Color.green; red.a = gizCol1.a; Gizmos.color = red; DrawEdgeCol(corners[4] - zero, corners[5] - zero); DrawEdgeCol(corners[5] - zero, corners[6] - zero); DrawEdgeCol(corners[6] - zero, corners[7] - zero); DrawEdgeCol(corners[7] - zero, corners[4] - zero); } private void OnDrawGizmosSelected() { } }