387 lines
11 KiB
C#
387 lines
11 KiB
C#
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using UnityEngine;
|
|
|
|
[AddComponentMenu("Modifiers/Curve Sculpt Layered")]
|
|
public class MegaCurveSculptLayered : MegaModifier
|
|
{
|
|
public List<MegaSculptCurve> curves = new List<MegaSculptCurve>();
|
|
|
|
private Vector3 size = Vector3.zero;
|
|
|
|
private static object resourceLock = new object();
|
|
|
|
public override string ModName()
|
|
{
|
|
return "CurveSculpLayered";
|
|
}
|
|
|
|
public override string GetHelpURL()
|
|
{
|
|
return "?page_id=2411";
|
|
}
|
|
|
|
public override void DoWork(MegaModifiers mc, int index, int start, int end, int cores)
|
|
{
|
|
if (selection != null)
|
|
{
|
|
DoWorkWeighted(mc, index, start, end, cores);
|
|
return;
|
|
}
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
sverts[i] = MapMT(i, verts[i]);
|
|
}
|
|
}
|
|
|
|
public override void DoWorkWeighted(MegaModifiers mc, int index, int start, int end, int cores)
|
|
{
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
Vector3 vector = verts[i];
|
|
float num = selection[i];
|
|
if (num > 0.001f)
|
|
{
|
|
Vector3 vector2 = MapMT(i, verts[i]);
|
|
sverts[i].x = vector.x + (vector2.x - vector.x) * num;
|
|
sverts[i].y = vector.y + (vector2.y - vector.y) * num;
|
|
sverts[i].z = vector.z + (vector2.z - vector.z) * num;
|
|
}
|
|
else
|
|
{
|
|
sverts[i] = vector;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Vector3 MapMT(int i, Vector3 p)
|
|
{
|
|
p = tm.MultiplyPoint3x4(p);
|
|
for (int j = 0; j < curves.Count; j++)
|
|
{
|
|
MegaSculptCurve megaSculptCurve = curves[j];
|
|
if (!megaSculptCurve.enabled)
|
|
{
|
|
continue;
|
|
}
|
|
int axis = (int)megaSculptCurve.axis;
|
|
if (megaSculptCurve.uselimits)
|
|
{
|
|
Vector3 vector = p - megaSculptCurve.origin;
|
|
if (!(Mathf.Abs(vector.x) < megaSculptCurve.size.x) || !(Mathf.Abs(vector.y) < megaSculptCurve.size.y) || !(Mathf.Abs(vector.z) < megaSculptCurve.size.z))
|
|
{
|
|
continue;
|
|
}
|
|
float num = 0.5f + vector[axis] / megaSculptCurve.size[axis] * 0.5f;
|
|
if (num >= 0f && num <= 1f)
|
|
{
|
|
Monitor.Enter(resourceLock);
|
|
float num2 = megaSculptCurve.curve.Evaluate(num) * megaSculptCurve.weight;
|
|
Monitor.Exit(resourceLock);
|
|
switch (megaSculptCurve.affectScale)
|
|
{
|
|
case MegaAffect.X:
|
|
p.x += vector.x * (num2 * megaSculptCurve.sclamount.x);
|
|
break;
|
|
case MegaAffect.Y:
|
|
p.y += vector.y * (num2 * megaSculptCurve.sclamount.y);
|
|
break;
|
|
case MegaAffect.Z:
|
|
p.z += vector.z * (num2 * megaSculptCurve.sclamount.z);
|
|
break;
|
|
case MegaAffect.XY:
|
|
p.x += vector.x * (num2 * megaSculptCurve.sclamount.x);
|
|
p.y += vector.y * (num2 * megaSculptCurve.sclamount.y);
|
|
break;
|
|
case MegaAffect.XZ:
|
|
p.x += vector.x * (num2 * megaSculptCurve.sclamount.x);
|
|
p.z += vector.z * (num2 * megaSculptCurve.sclamount.z);
|
|
break;
|
|
case MegaAffect.YZ:
|
|
p.y += vector.y * (num2 * megaSculptCurve.sclamount.y);
|
|
p.z += vector.z * (num2 * megaSculptCurve.sclamount.z);
|
|
break;
|
|
case MegaAffect.XYZ:
|
|
p.x += vector.x * (num2 * megaSculptCurve.sclamount.x);
|
|
p.y += vector.y * (num2 * megaSculptCurve.sclamount.y);
|
|
p.z += vector.z * (num2 * megaSculptCurve.sclamount.z);
|
|
break;
|
|
}
|
|
switch (megaSculptCurve.affectOffset)
|
|
{
|
|
case MegaAffect.X:
|
|
p.x += num2 * megaSculptCurve.offamount.x;
|
|
break;
|
|
case MegaAffect.Y:
|
|
p.y += num2 * megaSculptCurve.offamount.y;
|
|
break;
|
|
case MegaAffect.Z:
|
|
p.z += num2 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.XY:
|
|
p.x += num2 * megaSculptCurve.offamount.x;
|
|
p.y += num2 * megaSculptCurve.offamount.y;
|
|
break;
|
|
case MegaAffect.XZ:
|
|
p.x += num2 * megaSculptCurve.offamount.x;
|
|
p.z += num2 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.YZ:
|
|
p.y += num2 * megaSculptCurve.offamount.y;
|
|
p.z += num2 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.XYZ:
|
|
p.x += num2 * megaSculptCurve.offamount.x;
|
|
p.y += num2 * megaSculptCurve.offamount.y;
|
|
p.z += num2 * megaSculptCurve.offamount.z;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float time = (p[axis] - bbox.min[axis]) / size[axis];
|
|
Monitor.Enter(resourceLock);
|
|
float num3 = megaSculptCurve.curve.Evaluate(time) * megaSculptCurve.weight;
|
|
Monitor.Exit(resourceLock);
|
|
switch (megaSculptCurve.affectScale)
|
|
{
|
|
case MegaAffect.X:
|
|
p.x *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
break;
|
|
case MegaAffect.Y:
|
|
p.y *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
break;
|
|
case MegaAffect.Z:
|
|
p.z *= 1f + num3 * megaSculptCurve.sclamount.z;
|
|
break;
|
|
case MegaAffect.XY:
|
|
p.x *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.y *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
break;
|
|
case MegaAffect.XZ:
|
|
p.x *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.z *= 1f + num3 * megaSculptCurve.sclamount.z;
|
|
break;
|
|
case MegaAffect.YZ:
|
|
p.y *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.z *= 1f + num3 * megaSculptCurve.sclamount.z;
|
|
break;
|
|
case MegaAffect.XYZ:
|
|
p.x *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.y *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.z *= 1f + num3 * megaSculptCurve.sclamount.z;
|
|
break;
|
|
}
|
|
switch (megaSculptCurve.affectOffset)
|
|
{
|
|
case MegaAffect.X:
|
|
p.x += num3 * megaSculptCurve.offamount.x;
|
|
break;
|
|
case MegaAffect.Y:
|
|
p.y += num3 * megaSculptCurve.offamount.y;
|
|
break;
|
|
case MegaAffect.Z:
|
|
p.z += num3 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.XY:
|
|
p.x += num3 * megaSculptCurve.offamount.x;
|
|
p.y += num3 * megaSculptCurve.offamount.y;
|
|
break;
|
|
case MegaAffect.XZ:
|
|
p.x += num3 * megaSculptCurve.offamount.x;
|
|
p.z += num3 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.YZ:
|
|
p.y += num3 * megaSculptCurve.offamount.y;
|
|
p.z += num3 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.XYZ:
|
|
p.x += num3 * megaSculptCurve.offamount.x;
|
|
p.y += num3 * megaSculptCurve.offamount.y;
|
|
p.z += num3 * megaSculptCurve.offamount.z;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return invtm.MultiplyPoint3x4(p);
|
|
}
|
|
|
|
public override Vector3 Map(int i, Vector3 p)
|
|
{
|
|
p = tm.MultiplyPoint3x4(p);
|
|
for (int j = 0; j < curves.Count; j++)
|
|
{
|
|
MegaSculptCurve megaSculptCurve = curves[j];
|
|
if (!megaSculptCurve.enabled)
|
|
{
|
|
continue;
|
|
}
|
|
int axis = (int)megaSculptCurve.axis;
|
|
if (megaSculptCurve.uselimits)
|
|
{
|
|
Vector3 vector = p - megaSculptCurve.origin;
|
|
if (!(Mathf.Abs(vector.x) < megaSculptCurve.size.x) || !(Mathf.Abs(vector.y) < megaSculptCurve.size.y) || !(Mathf.Abs(vector.z) < megaSculptCurve.size.z))
|
|
{
|
|
continue;
|
|
}
|
|
float num = 0.5f + vector[axis] / megaSculptCurve.size[axis] * 0.5f;
|
|
if (num >= 0f && num <= 1f)
|
|
{
|
|
float num2 = megaSculptCurve.curve.Evaluate(num) * megaSculptCurve.weight;
|
|
switch (megaSculptCurve.affectScale)
|
|
{
|
|
case MegaAffect.X:
|
|
p.x += vector.x * (num2 * megaSculptCurve.sclamount.x);
|
|
break;
|
|
case MegaAffect.Y:
|
|
p.y += vector.y * (num2 * megaSculptCurve.sclamount.y);
|
|
break;
|
|
case MegaAffect.Z:
|
|
p.z += vector.z * (num2 * megaSculptCurve.sclamount.z);
|
|
break;
|
|
case MegaAffect.XY:
|
|
p.x += vector.x * (num2 * megaSculptCurve.sclamount.x);
|
|
p.y += vector.y * (num2 * megaSculptCurve.sclamount.y);
|
|
break;
|
|
case MegaAffect.XZ:
|
|
p.x += vector.x * (num2 * megaSculptCurve.sclamount.x);
|
|
p.z += vector.z * (num2 * megaSculptCurve.sclamount.z);
|
|
break;
|
|
case MegaAffect.YZ:
|
|
p.y += vector.y * (num2 * megaSculptCurve.sclamount.y);
|
|
p.z += vector.z * (num2 * megaSculptCurve.sclamount.z);
|
|
break;
|
|
case MegaAffect.XYZ:
|
|
p.x += vector.x * (num2 * megaSculptCurve.sclamount.x);
|
|
p.y += vector.y * (num2 * megaSculptCurve.sclamount.y);
|
|
p.z += vector.z * (num2 * megaSculptCurve.sclamount.z);
|
|
break;
|
|
}
|
|
switch (megaSculptCurve.affectOffset)
|
|
{
|
|
case MegaAffect.X:
|
|
p.x += num2 * megaSculptCurve.offamount.x;
|
|
break;
|
|
case MegaAffect.Y:
|
|
p.y += num2 * megaSculptCurve.offamount.y;
|
|
break;
|
|
case MegaAffect.Z:
|
|
p.z += num2 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.XY:
|
|
p.x += num2 * megaSculptCurve.offamount.x;
|
|
p.y += num2 * megaSculptCurve.offamount.y;
|
|
break;
|
|
case MegaAffect.XZ:
|
|
p.x += num2 * megaSculptCurve.offamount.x;
|
|
p.z += num2 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.YZ:
|
|
p.y += num2 * megaSculptCurve.offamount.y;
|
|
p.z += num2 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.XYZ:
|
|
p.x += num2 * megaSculptCurve.offamount.x;
|
|
p.y += num2 * megaSculptCurve.offamount.y;
|
|
p.z += num2 * megaSculptCurve.offamount.z;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float time = (p[axis] - bbox.min[axis]) / size[axis];
|
|
float num3 = megaSculptCurve.curve.Evaluate(time) * megaSculptCurve.weight;
|
|
switch (megaSculptCurve.affectScale)
|
|
{
|
|
case MegaAffect.X:
|
|
p.x *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
break;
|
|
case MegaAffect.Y:
|
|
p.y *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
break;
|
|
case MegaAffect.Z:
|
|
p.z *= 1f + num3 * megaSculptCurve.sclamount.z;
|
|
break;
|
|
case MegaAffect.XY:
|
|
p.x *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.y *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
break;
|
|
case MegaAffect.XZ:
|
|
p.x *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.z *= 1f + num3 * megaSculptCurve.sclamount.z;
|
|
break;
|
|
case MegaAffect.YZ:
|
|
p.y *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.z *= 1f + num3 * megaSculptCurve.sclamount.z;
|
|
break;
|
|
case MegaAffect.XYZ:
|
|
p.x *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.y *= 1f + num3 * megaSculptCurve.sclamount.y;
|
|
p.z *= 1f + num3 * megaSculptCurve.sclamount.z;
|
|
break;
|
|
}
|
|
switch (megaSculptCurve.affectOffset)
|
|
{
|
|
case MegaAffect.X:
|
|
p.x += num3 * megaSculptCurve.offamount.x;
|
|
break;
|
|
case MegaAffect.Y:
|
|
p.y += num3 * megaSculptCurve.offamount.y;
|
|
break;
|
|
case MegaAffect.Z:
|
|
p.z += num3 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.XY:
|
|
p.x += num3 * megaSculptCurve.offamount.x;
|
|
p.y += num3 * megaSculptCurve.offamount.y;
|
|
break;
|
|
case MegaAffect.XZ:
|
|
p.x += num3 * megaSculptCurve.offamount.x;
|
|
p.z += num3 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.YZ:
|
|
p.y += num3 * megaSculptCurve.offamount.y;
|
|
p.z += num3 * megaSculptCurve.offamount.z;
|
|
break;
|
|
case MegaAffect.XYZ:
|
|
p.x += num3 * megaSculptCurve.offamount.x;
|
|
p.y += num3 * megaSculptCurve.offamount.y;
|
|
p.z += num3 * megaSculptCurve.offamount.z;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return invtm.MultiplyPoint3x4(p);
|
|
}
|
|
|
|
public override bool ModLateUpdate(MegaModContext mc)
|
|
{
|
|
return Prepare(mc);
|
|
}
|
|
|
|
public override bool Prepare(MegaModContext mc)
|
|
{
|
|
size = bbox.max - bbox.min;
|
|
for (int i = 0; i < curves.Count; i++)
|
|
{
|
|
curves[i].size = curves[i].boxsize * 0.5f;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public override void DrawGizmo(MegaModContext context)
|
|
{
|
|
base.DrawGizmo(context);
|
|
for (int i = 0; i < curves.Count; i++)
|
|
{
|
|
if (curves[i].enabled && curves[i].uselimits)
|
|
{
|
|
Gizmos.color = curves[i].regcol;
|
|
Gizmos.DrawWireCube(curves[i].origin, curves[i].boxsize);
|
|
}
|
|
}
|
|
}
|
|
}
|