using UnityEngine; public class MegaFFD : MegaModifier { public float KnotSize = 0.1f; public bool inVol; public Vector3[] pt = new Vector3[64]; [HideInInspector] public float EPSILON = 0.001f; [HideInInspector] public Vector3 lsize = Vector3.one; [HideInInspector] public Vector3 bsize = default(Vector3); [HideInInspector] public Vector3 bcenter = default(Vector3); public virtual int GridSize() { return 1; } public virtual int GridIndex(int i, int j, int k) { return 0; } public override string GetHelpURL() { return "?page_id=199"; } public override void PostCopy(MegaModifier src) { MegaFFD megaFFD = (MegaFFD)src; pt = new Vector3[64]; for (int i = 0; i < 64; i++) { pt[i] = megaFFD.pt[i]; } } public Vector3 LatticeSize() { Vector3 result = bsize; if (result.x == 0f) { result.x = 0.001f; } if (result.y == 0f) { result.y = 0.001f; } if (result.z == 0f) { result.z = 0.001f; } return result; } private void Init() { lsize = LatticeSize(); int num = GridSize(); float num2 = (float)num - 1f; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { for (int k = 0; k < num; k++) { int num3 = GridIndex(i, j, k); pt[num3].x = (float)i / num2; pt[num3].y = (float)j / num2; pt[num3].z = (float)k / num2; } } } } public override bool ModLateUpdate(MegaModContext mc) { return Prepare(mc); } public override bool Prepare(MegaModContext mc) { Vector3 s = LatticeSize(); for (int i = 0; i < 3; i++) { if (s[i] == 0f) { s[i] = 1f; } else { s[i] = 1f / s[i]; } } Vector3 trans = MegaMatrix.GetTrans(ref tm); MegaMatrix.SetTrans(ref tm, trans - bbox.min - Offset); MegaMatrix.Scale(ref tm, s, false); invtm = tm.inverse; return true; } public Vector3 GetPoint(int i) { Vector3 a = pt[i]; a.x -= 0.5f; a.y -= 0.5f; a.z -= 0.5f; return Vector3.Scale(a, lsize) + bcenter; } public Vector3 GetPoint(int i, int j, int k) { Vector3 a = pt[GridIndex(i, j, k)]; a.x -= 0.5f; a.y -= 0.5f; a.z -= 0.5f; return Vector3.Scale(a, lsize) + bcenter; } public void SetPoint(int i, int j, int k, Vector3 pos) { Vector3 lpos = base.transform.worldToLocalMatrix.MultiplyPoint(pos); SetPointLocal(i, j, k, lpos); } public void SetPointLocal(int i, int j, int k, Vector3 lpos) { Vector3 vector = lsize; Vector3 b = lsize; b.x = 1f / vector.x; b.y = 1f / vector.y; b.z = 1f / vector.z; lpos -= bcenter; Vector3 vector2 = Vector3.Scale(lpos, b); vector2.x += 0.5f; vector2.y += 0.5f; vector2.z += 0.5f; pt[GridIndex(i, j, k)] = vector2; } public void SetPoint(int index, Vector3 pos) { Vector3 lpos = base.transform.worldToLocalMatrix.MultiplyPoint(pos); SetPointLocal(index, lpos); } public void SetPointLocal(int index, Vector3 lpos) { Vector3 vector = lsize; Vector3 b = lsize; b.x = 1f / vector.x; b.y = 1f / vector.y; b.z = 1f / vector.z; lpos -= bcenter; Vector3 vector2 = Vector3.Scale(lpos, b); vector2.x += 0.5f; vector2.y += 0.5f; vector2.z += 0.5f; pt[index] = vector2; } public void MovePoint(int x, int y, int z, Vector3 localmove) { Vector3 point = GetPoint(x, y, z); point += localmove; SetPointLocal(x, y, z, point); } private void Reset() { MegaModifyObject component = base.gameObject.GetComponent(); if (component != null) { component.ModReset(this); } Renderer component2 = GetComponent(); if (component2 != null) { Mesh sharedMesh = MegaUtils.GetSharedMesh(base.gameObject); if (sharedMesh != null) { Bounds bounds = sharedMesh.bounds; Offset = -bounds.center; bbox.min = bounds.center - bounds.extents; bbox.max = bounds.center + bounds.extents; } } if (component.selection != null) { Bounds bounds2 = default(Bounds); for (int i = 0; i < component.verts.Length; i++) { if (component.selection[i] > 0.001f) { bounds2.Encapsulate(component.verts[i]); } } Offset = -bounds2.center; bbox.min = bounds2.center - bounds2.extents; bbox.max = bounds2.center + bounds2.extents; } bsize = bbox.Size(); bcenter = bbox.center; Init(); } [ContextMenu("Fit FFD to Selection")] public void FitFFD() { Reset(); } [ContextMenu("Fit FFD to Mesh")] public void FitFFDToMesh() { Renderer component = GetComponent(); if (component != null) { Mesh sharedMesh = MegaUtils.GetSharedMesh(base.gameObject); if (sharedMesh != null) { Bounds bounds = sharedMesh.bounds; Offset = -bounds.center; bbox.min = bounds.center - bounds.extents; bbox.max = bounds.center + bounds.extents; } } bsize = bbox.Size(); bcenter = bbox.center; Init(); } public override bool InitMod(MegaModifiers mc) { bsize = mc.bbox.size; bcenter = mc.bbox.center; Init(); return true; } private static MegaFFD Create(GameObject go, int type) { switch (type) { case 0: return go.AddComponent(); case 1: return go.AddComponent(); case 2: return go.AddComponent(); default: return null; } } public override void DrawGizmo(MegaModContext context) { } }