193 lines
4.0 KiB
C#
193 lines
4.0 KiB
C#
using UnityEngine;
|
|
|
|
[AddComponentMenu("Modifiers/Conform")]
|
|
public class MegaConformMod : MegaModifier
|
|
{
|
|
public GameObject target;
|
|
|
|
public float[] offsets;
|
|
|
|
public Collider conformCollider;
|
|
|
|
public Bounds bounds;
|
|
|
|
public float[] last;
|
|
|
|
public Vector3[] last1;
|
|
|
|
public Vector3[] conformedVerts;
|
|
|
|
public float conformAmount = 1f;
|
|
|
|
public float raystartoff;
|
|
|
|
public float offset;
|
|
|
|
public float raydist = 100f;
|
|
|
|
public MegaAxis axis = MegaAxis.Y;
|
|
|
|
private Matrix4x4 loctoworld;
|
|
|
|
private Matrix4x4 ctm;
|
|
|
|
private Matrix4x4 cinvtm;
|
|
|
|
private Ray ray = default(Ray);
|
|
|
|
private RaycastHit hit;
|
|
|
|
public bool useLocalDown;
|
|
|
|
public bool flipDown = true;
|
|
|
|
public MegaAxis downAxis = MegaAxis.Y;
|
|
|
|
public override string ModName()
|
|
{
|
|
return "Conform";
|
|
}
|
|
|
|
public override string GetHelpURL()
|
|
{
|
|
return "?page_id=4547";
|
|
}
|
|
|
|
public void SetTarget(GameObject targ)
|
|
{
|
|
target = targ;
|
|
if ((bool)target)
|
|
{
|
|
conformCollider = target.GetComponent<Collider>();
|
|
}
|
|
}
|
|
|
|
public override Vector3 Map(int i, Vector3 p)
|
|
{
|
|
return p;
|
|
}
|
|
|
|
public override void Modify(MegaModifiers mc)
|
|
{
|
|
if ((bool)conformCollider)
|
|
{
|
|
if (useLocalDown)
|
|
{
|
|
Vector3 vector = Vector3.down;
|
|
switch (downAxis)
|
|
{
|
|
case MegaAxis.X:
|
|
vector = base.transform.right;
|
|
break;
|
|
case MegaAxis.Y:
|
|
vector = base.transform.up;
|
|
break;
|
|
case MegaAxis.Z:
|
|
vector = base.transform.forward;
|
|
break;
|
|
}
|
|
if (flipDown)
|
|
{
|
|
vector = -vector;
|
|
}
|
|
ray.direction = vector;
|
|
Vector3 vector2 = -vector * raystartoff;
|
|
Vector3 direction = ray.direction;
|
|
Vector3 vector3 = -base.transform.InverseTransformDirection(direction);
|
|
for (int i = 0; i < verts.Length; i++)
|
|
{
|
|
Vector3 origin = ctm.MultiplyPoint(verts[i]) - vector2;
|
|
ray.origin = origin;
|
|
sverts[i] = verts[i];
|
|
if (conformCollider.Raycast(ray, out hit, raydist))
|
|
{
|
|
Vector3 vector4 = cinvtm.MultiplyPoint(hit.point);
|
|
sverts[i] = Vector3.Lerp(verts[i], vector4 + vector3 * (offsets[i] + offset), conformAmount);
|
|
last1[i] = sverts[i];
|
|
}
|
|
else
|
|
{
|
|
sverts[i] = last1[i];
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
int index = (int)axis;
|
|
for (int j = 0; j < verts.Length; j++)
|
|
{
|
|
Vector3 origin2 = ctm.MultiplyPoint(verts[j]);
|
|
origin2.y += raystartoff;
|
|
ray.origin = origin2;
|
|
ray.direction = Vector3.down;
|
|
sverts[j] = verts[j];
|
|
if (conformCollider.Raycast(ray, out hit, raydist))
|
|
{
|
|
Vector3 vector5 = cinvtm.MultiplyPoint(hit.point);
|
|
sverts[j][index] = Mathf.Lerp(verts[j][index], vector5[index] + offsets[j] + offset, conformAmount);
|
|
last[j] = sverts[j][index];
|
|
}
|
|
else
|
|
{
|
|
sverts[j][index] = last[j];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
verts.CopyTo(sverts, 0);
|
|
}
|
|
}
|
|
|
|
public override bool ModLateUpdate(MegaModContext mc)
|
|
{
|
|
return Prepare(mc);
|
|
}
|
|
|
|
public override bool Prepare(MegaModContext mc)
|
|
{
|
|
if ((bool)target)
|
|
{
|
|
if (conformCollider != target.GetComponent<Collider>())
|
|
{
|
|
conformCollider = target.GetComponent<Collider>();
|
|
}
|
|
if (conformCollider == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (conformedVerts == null || conformedVerts.Length != mc.mod.verts.Length)
|
|
{
|
|
conformedVerts = new Vector3[mc.mod.verts.Length];
|
|
offsets = new float[mc.mod.verts.Length];
|
|
last = new float[mc.mod.verts.Length];
|
|
for (int i = 0; i < mc.mod.verts.Length; i++)
|
|
{
|
|
offsets[i] = mc.mod.verts[i][(int)axis] - mc.bbox.min[(int)axis];
|
|
}
|
|
}
|
|
if (useLocalDown && (last1 == null || last1.Length != last.Length))
|
|
{
|
|
last1 = new Vector3[last.Length];
|
|
}
|
|
loctoworld = base.transform.localToWorldMatrix;
|
|
ctm = loctoworld;
|
|
cinvtm = base.transform.worldToLocalMatrix;
|
|
return true;
|
|
}
|
|
conformCollider = null;
|
|
return true;
|
|
}
|
|
|
|
public void ChangeAxis()
|
|
{
|
|
MegaModifyObject component = GetComponent<MegaModifyObject>();
|
|
if ((bool)component)
|
|
{
|
|
for (int i = 0; i < component.verts.Length; i++)
|
|
{
|
|
offsets[i] = component.verts[i][(int)axis] - component.bbox.min[(int)axis];
|
|
}
|
|
}
|
|
}
|
|
}
|