230 lines
4.7 KiB
C#
230 lines
4.7 KiB
C#
using UnityEngine;
|
|
|
|
[AddComponentMenu("Modifiers/Deformable")]
|
|
public class MegaDeformable : MegaModifier
|
|
{
|
|
public float Hardness = 0.5f;
|
|
|
|
public bool DeformMeshCollider = true;
|
|
|
|
public float UpdateFrequency;
|
|
|
|
public float MaxVertexMov;
|
|
|
|
public Color32 DeformedVertexColor = Color.gray;
|
|
|
|
public Texture2D HardnessMap;
|
|
|
|
public bool usedecay;
|
|
|
|
public float decay = 0.999f;
|
|
|
|
public Color[] baseColors;
|
|
|
|
public float sizeFactor;
|
|
|
|
public float[] map;
|
|
|
|
public Vector3[] offsets;
|
|
|
|
public float impactFactor = 0.1f;
|
|
|
|
public float ColForce = 0.5f;
|
|
|
|
public MegaModifyObject modobj;
|
|
|
|
private ContactPoint[] colpoints;
|
|
|
|
public override string ModName()
|
|
{
|
|
return "Deformable";
|
|
}
|
|
|
|
public override void ModStart(MegaModifiers mc)
|
|
{
|
|
Vector3 size = mc.mesh.bounds.size;
|
|
sizeFactor = Mathf.Min(size.x, size.y, size.z);
|
|
if (mc.mesh.colors != null)
|
|
{
|
|
baseColors = mc.mesh.colors;
|
|
}
|
|
LoadMap(mc);
|
|
}
|
|
|
|
public override bool ModLateUpdate(MegaModContext mc)
|
|
{
|
|
return Prepare(mc);
|
|
}
|
|
|
|
public override bool Prepare(MegaModContext mc)
|
|
{
|
|
if (offsets == null || offsets.Length != mc.mod.verts.Length)
|
|
{
|
|
offsets = new Vector3[mc.mod.verts.Length];
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public override MegaModChannel ChannelsReq()
|
|
{
|
|
return (MegaModChannel)65;
|
|
}
|
|
|
|
public override MegaModChannel ChannelsChanged()
|
|
{
|
|
return (MegaModChannel)65;
|
|
}
|
|
|
|
private void LoadMesh()
|
|
{
|
|
}
|
|
|
|
public void LoadMap()
|
|
{
|
|
MegaModifiers component = GetComponent<MegaModifyObject>();
|
|
if ((bool)component)
|
|
{
|
|
LoadMap(component);
|
|
}
|
|
}
|
|
|
|
private void LoadMap(MegaModifiers mc)
|
|
{
|
|
if ((bool)HardnessMap)
|
|
{
|
|
Vector2[] uv = mc.mesh.uv;
|
|
map = new float[uv.Length];
|
|
for (int i = 0; i < uv.Length; i++)
|
|
{
|
|
Vector2 vector = uv[i];
|
|
map[i] = HardnessMap.GetPixelBilinear(vector.x, vector.y).a;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
map = null;
|
|
}
|
|
}
|
|
|
|
public override void Modify(MegaModifiers mc)
|
|
{
|
|
float colForce = ColForce;
|
|
sizeFactor = mc.bbox.size.magnitude;
|
|
float num = colForce * (sizeFactor * (impactFactor / Mathf.Max(impactFactor, Hardness)));
|
|
if (colpoints != null)
|
|
{
|
|
for (int i = 0; i < colpoints.Length; i++)
|
|
{
|
|
ContactPoint contactPoint = colpoints[i];
|
|
for (int j = 0; j < verts.Length; j++)
|
|
{
|
|
Vector3 vector = verts[j] + offsets[j];
|
|
Vector3 vector2 = base.transform.InverseTransformPoint(contactPoint.point);
|
|
float sqrMagnitude = (vector - vector2).sqrMagnitude;
|
|
if (!(sqrMagnitude <= num))
|
|
{
|
|
continue;
|
|
}
|
|
Vector3 vector3 = base.transform.InverseTransformDirection(contactPoint.normal * (1f - sqrMagnitude / num) * num);
|
|
if (map != null)
|
|
{
|
|
vector3 *= 1f - map[j];
|
|
}
|
|
offsets[j] += vector3;
|
|
if (MaxVertexMov > 0f)
|
|
{
|
|
float maxVertexMov = MaxVertexMov;
|
|
vector3 = offsets[j];
|
|
sqrMagnitude = vector3.magnitude;
|
|
if (sqrMagnitude > maxVertexMov)
|
|
{
|
|
offsets[j] = vector3 * (maxVertexMov / sqrMagnitude);
|
|
}
|
|
if (baseColors.Length > 0)
|
|
{
|
|
sqrMagnitude /= MaxVertexMov;
|
|
mc.cols[j] = Color.Lerp(baseColors[j], DeformedVertexColor, sqrMagnitude);
|
|
}
|
|
}
|
|
else if (mc.cols.Length > 0)
|
|
{
|
|
mc.cols[j] = Color.Lerp(baseColors[j], DeformedVertexColor, offsets[j].magnitude / (num * 10f));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
colpoints = null;
|
|
if (!usedecay)
|
|
{
|
|
for (int k = 0; k < verts.Length; k++)
|
|
{
|
|
sverts[k].x = verts[k].x + offsets[k].x;
|
|
sverts[k].y = verts[k].y + offsets[k].y;
|
|
sverts[k].z = verts[k].z + offsets[k].z;
|
|
}
|
|
return;
|
|
}
|
|
for (int l = 0; l < verts.Length; l++)
|
|
{
|
|
offsets[l].x *= decay;
|
|
offsets[l].y *= decay;
|
|
offsets[l].z *= decay;
|
|
sverts[l].x = verts[l].x + offsets[l].x;
|
|
sverts[l].y = verts[l].y + offsets[l].y;
|
|
sverts[l].z = verts[l].z + offsets[l].z;
|
|
}
|
|
}
|
|
|
|
public void Repair(float repair, MegaModifiers mc)
|
|
{
|
|
Repair(repair, Vector3.zero, 0f, mc);
|
|
}
|
|
|
|
public void Repair(float repair, Vector3 point, float radius, MegaModifiers mc)
|
|
{
|
|
if (!mc.mesh)
|
|
{
|
|
return;
|
|
}
|
|
point = base.transform.InverseTransformPoint(point);
|
|
for (int i = 0; i < mc.verts.Length; i++)
|
|
{
|
|
if (!(radius > 0f) || !((point - mc.sverts[i]).magnitude >= radius))
|
|
{
|
|
Vector3 vector = offsets[i];
|
|
offsets[i] = vector * (1f - repair);
|
|
if (baseColors.Length > 0)
|
|
{
|
|
mc.cols[i] = Color.Lerp(mc.cols[i], baseColors[i], repair);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnCollisionEnter(Collision collision)
|
|
{
|
|
if (modobj == null)
|
|
{
|
|
modobj = GetComponent<MegaModifyObject>();
|
|
}
|
|
if ((bool)modobj)
|
|
{
|
|
modobj.Enabled = true;
|
|
}
|
|
colpoints = collision.contacts;
|
|
}
|
|
|
|
private void OnCollisionStay(Collision collision)
|
|
{
|
|
colpoints = collision.contacts;
|
|
}
|
|
|
|
private void OnCollisionExit(Collision collision)
|
|
{
|
|
if ((bool)modobj && !usedecay)
|
|
{
|
|
modobj.Enabled = false;
|
|
}
|
|
}
|
|
}
|