270 lines
5.2 KiB
C#
270 lines
5.2 KiB
C#
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<MegaModifyObject>();
|
|
if (component != null)
|
|
{
|
|
component.ModReset(this);
|
|
}
|
|
Renderer component2 = GetComponent<Renderer>();
|
|
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<Renderer>();
|
|
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<MegaFFD2x2x2>();
|
|
case 1:
|
|
return go.AddComponent<MegaFFD3x3x3>();
|
|
case 2:
|
|
return go.AddComponent<MegaFFD4x4x4>();
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public override void DrawGizmo(MegaModContext context)
|
|
{
|
|
}
|
|
}
|