164 lines
3.3 KiB
C#
164 lines
3.3 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
[AddComponentMenu("Modifiers/Conform Multi")]
|
|
public class MegaConformMulti : MegaModifier
|
|
{
|
|
public List<MegaConformTarget> targets = new List<MegaConformTarget>();
|
|
|
|
public List<Collider> conformColliders = new List<Collider>();
|
|
|
|
public float[] offsets;
|
|
|
|
public Bounds bounds;
|
|
|
|
public float[] last;
|
|
|
|
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 override string ModName()
|
|
{
|
|
return "Conform Multi";
|
|
}
|
|
|
|
public override string GetHelpURL()
|
|
{
|
|
return "?page_id=4547";
|
|
}
|
|
|
|
public void BuildColliderList()
|
|
{
|
|
conformColliders.Clear();
|
|
for (int i = 0; i < targets.Count; i++)
|
|
{
|
|
if (!targets[i].target)
|
|
{
|
|
continue;
|
|
}
|
|
if (targets[i].children)
|
|
{
|
|
Collider[] componentsInChildren = targets[i].target.GetComponentsInChildren<Collider>();
|
|
for (int j = 0; j < componentsInChildren.Length; j++)
|
|
{
|
|
conformColliders.Add(componentsInChildren[j]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Collider component = targets[i].target.GetComponent<Collider>();
|
|
if ((bool)component)
|
|
{
|
|
conformColliders.Add(component);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override Vector3 Map(int i, Vector3 p)
|
|
{
|
|
return p;
|
|
}
|
|
|
|
private bool DoRayCast(Ray ray, ref Vector3 pos, float raydist)
|
|
{
|
|
bool result = false;
|
|
float num = float.MaxValue;
|
|
for (int i = 0; i < conformColliders.Count; i++)
|
|
{
|
|
if (conformColliders[i].Raycast(ray, out hit, raydist))
|
|
{
|
|
result = true;
|
|
if (hit.distance < num)
|
|
{
|
|
num = hit.distance;
|
|
pos = hit.point;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public override void Modify(MegaModifiers mc)
|
|
{
|
|
if (conformColliders.Count > 0)
|
|
{
|
|
int index = (int)axis;
|
|
Vector3 pos = Vector3.zero;
|
|
for (int i = 0; i < verts.Length; i++)
|
|
{
|
|
Vector3 origin = ctm.MultiplyPoint(verts[i]);
|
|
origin.y += raystartoff;
|
|
ray.origin = origin;
|
|
ray.direction = Vector3.down;
|
|
sverts[i] = verts[i];
|
|
if (DoRayCast(ray, ref pos, raydist))
|
|
{
|
|
Vector3 vector = cinvtm.MultiplyPoint(pos);
|
|
sverts[i][index] = Mathf.Lerp(verts[i][index], vector[index] + offsets[i] + offset, conformAmount);
|
|
last[i] = sverts[i][index];
|
|
}
|
|
else
|
|
{
|
|
Vector3 origin2 = ray.origin;
|
|
origin2.y -= raydist;
|
|
sverts[i][index] = last[i];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
verts.CopyTo(sverts, 0);
|
|
}
|
|
}
|
|
|
|
public override bool ModLateUpdate(MegaModContext mc)
|
|
{
|
|
return Prepare(mc);
|
|
}
|
|
|
|
public override bool Prepare(MegaModContext mc)
|
|
{
|
|
if (targets.Count > 0)
|
|
{
|
|
if (conformColliders.Count == 0)
|
|
{
|
|
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];
|
|
}
|
|
}
|
|
loctoworld = base.transform.localToWorldMatrix;
|
|
ctm = loctoworld;
|
|
cinvtm = base.transform.worldToLocalMatrix;
|
|
}
|
|
return true;
|
|
}
|
|
}
|