using System.Collections.Generic; using System.Threading; using UnityEngine; [AddComponentMenu("Modifiers/Curve Sculpt Layered")] public class MegaCurveSculptLayered : MegaModifier { public List curves = new List(); 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); } } } }