void CurveGUI(MegaSculptCurve crv)
    {
        crv.enabled = EditorGUILayout.BeginToggleGroup("Enabled", crv.enabled);

        //if ( crv.enabled )
        {
            crv.name  = EditorGUILayout.TextField("Name", crv.name);
            crv.axis  = (MegaAxis)EditorGUILayout.EnumPopup("Axis", crv.axis);
            crv.curve = EditorGUILayout.CurveField("Curve", crv.curve);

            crv.weight = EditorGUILayout.Slider("Weight", crv.weight, 0.0f, 1.0f);

            crv.affectOffset = (MegaAffect)EditorGUILayout.EnumPopup("Affect Off", crv.affectOffset);
            if (crv.affectOffset != MegaAffect.None)
            {
                crv.offamount = EditorGUILayout.Vector3Field("Offset", crv.offamount);
            }

            crv.affectScale = (MegaAffect)EditorGUILayout.EnumPopup("Affect Scl", crv.affectScale);
            if (crv.affectScale != MegaAffect.None)
            {
                crv.sclamount = EditorGUILayout.Vector3Field("Scale", crv.sclamount);
            }

            crv.uselimits = EditorGUILayout.BeginToggleGroup("Limits", crv.uselimits);
            crv.regcol    = EditorGUILayout.ColorField("Col", crv.regcol);
            crv.origin    = EditorGUILayout.Vector3Field("Origin", crv.origin);
            crv.boxsize   = EditorGUILayout.Vector3Field("Boxsize", crv.boxsize);
            EditorGUILayout.EndToggleGroup();
        }

        EditorGUILayout.EndToggleGroup();
    }
    void CurveGUI(MegaSculptCurve crv)
    {
        crv.enabled = EditorGUILayout.BeginToggleGroup("Enabled", crv.enabled);

        //if ( crv.enabled )
        {
            crv.name = EditorGUILayout.TextField("Name", crv.name);
            crv.axis = (MegaAxis)EditorGUILayout.EnumPopup("Axis", crv.axis);
            crv.curve = EditorGUILayout.CurveField("Curve", crv.curve);

            crv.weight = EditorGUILayout.Slider("Weight", crv.weight, 0.0f, 1.0f);

            crv.affectOffset = (MegaAffect)EditorGUILayout.EnumPopup("Affect Off", crv.affectOffset);
            if ( crv.affectOffset != MegaAffect.None )
                crv.offamount = EditorGUILayout.Vector3Field("Offset", crv.offamount);

            crv.affectScale = (MegaAffect)EditorGUILayout.EnumPopup("Affect Scl", crv.affectScale);
            if ( crv.affectScale != MegaAffect.None )
                crv.sclamount = EditorGUILayout.Vector3Field("Scale", crv.sclamount);

            crv.uselimits = EditorGUILayout.BeginToggleGroup("Limits", crv.uselimits);
            crv.regcol = EditorGUILayout.ColorField("Col", crv.regcol);
            crv.origin = EditorGUILayout.Vector3Field("Origin", crv.origin);
            crv.boxsize = EditorGUILayout.Vector3Field("Boxsize", crv.boxsize);
            EditorGUILayout.EndToggleGroup();
        }

        EditorGUILayout.EndToggleGroup();
    }
 void SwapCurves(MegaCurveSculptLayered mod, int t1, int t2)
 {
     if (t1 >= 0 && t1 < mod.curves.Count && t2 >= 0 && t2 < mod.curves.Count && t1 != t2)
     {
         MegaSculptCurve mt1 = mod.curves[t1];
         mod.curves.RemoveAt(t1);
         mod.curves.Insert(t2, mt1);
         EditorUtility.SetDirty(target);
     }
 }
    public override bool Inspector()
    {
        MegaCurveSculptLayered mod = (MegaCurveSculptLayered)target;

#if !UNITY_5 && !UNITY_2017 && !UNITY_2018 && !UNITY_2019 && !UNITY_2020
        EditorGUIUtility.LookLikeControls();
#endif

        if (GUILayout.Button("Add Curve"))
        {
            mod.curves.Add(MegaSculptCurve.Create());
        }

        for (int i = 0; i < mod.curves.Count; i++)
        {
            CurveGUI(mod.curves[i]);

            EditorGUILayout.BeginHorizontal();

            if (GUILayout.Button("Up"))
            {
                if (i > 0)
                {
                    SwapCurves(mod, i, i - 1);
                }
            }

            if (GUILayout.Button("Down"))
            {
                if (i < mod.curves.Count - 1)
                {
                    SwapCurves(mod, i, i + 1);
                }
            }

            if (GUILayout.Button("Delete"))
            {
                mod.curves.RemoveAt(i);
                i--;
            }
            EditorGUILayout.EndHorizontal();
        }

        return(false);
    }
    static public MegaSculptCurve Create()
    {
        MegaSculptCurve crv = new MegaSculptCurve();

        return(crv);
    }
    public override Vector3 Map(int i, Vector3 p)
    {
        p = tm.MultiplyPoint3x4(p);

        for (int c = 0; c < curves.Count; c++)
        {
            MegaSculptCurve crv = curves[c];

            if (crv.enabled)
            {
                int ax = (int)crv.axis;

                if (crv.uselimits)
                {
                    // Is the point in the box
                    Vector3 bp = p - crv.origin;
                    if (Mathf.Abs(bp.x) < crv.size.x && Mathf.Abs(bp.y) < crv.size.y && Mathf.Abs(bp.z) < crv.size.z)
                    {
                        float alpha = 0.5f + ((bp[ax] / crv.size[ax]) * 0.5f);

                        if (alpha >= 0.0f && alpha <= 1.0f)
                        {
                            float a = crv.curve.Evaluate(alpha) * crv.weight;

                            switch (crv.affectScale)
                            {
                            case MegaAffect.X:
                                p.x += bp.x * (a * crv.sclamount.x);
                                //p.x *= 1.0f + (a * crv.sclamount.x);
                                break;

                            case MegaAffect.Y:
                                p.y += bp.y * (a * crv.sclamount.y);
                                //p.y *= 1.0f + (a * crv.sclamount.y);
                                break;

                            case MegaAffect.Z:
                                p.z += bp.z * (a * crv.sclamount.z);
                                //p.z *= 1.0f + (a * crv.sclamount.z);
                                break;

                            case MegaAffect.XY:
                                p.x += bp.x * (a * crv.sclamount.x);
                                p.y += bp.y * (a * crv.sclamount.y);
                                //p.x *= 1.0f + (a * crv.sclamount.x);
                                //p.y *= 1.0f + (a * crv.sclamount.y);
                                break;

                            case MegaAffect.XZ:
                                p.x += bp.x * (a * crv.sclamount.x);
                                p.z += bp.z * (a * crv.sclamount.z);
                                //p.x *= 1.0f + (a * crv.sclamount.y);
                                //p.z *= 1.0f + (a * crv.sclamount.z);
                                break;

                            case MegaAffect.YZ:
                                p.y += bp.y * (a * crv.sclamount.y);
                                p.z += bp.z * (a * crv.sclamount.z);
                                //p.y *= 1.0f + (a * crv.sclamount.y);
                                //p.z *= 1.0f + (a * crv.sclamount.z);
                                break;

                            case MegaAffect.XYZ:
                                p.x += bp.x * (a * crv.sclamount.x);
                                p.y += bp.y * (a * crv.sclamount.y);
                                p.z += bp.z * (a * crv.sclamount.z);

                                //p.x *= 1.0f + (a * crv.sclamount.x);
                                //p.y *= 1.0f + (a * crv.sclamount.y);
                                //p.z *= 1.0f + (a * crv.sclamount.z);
                                break;
                            }

                            switch (crv.affectOffset)
                            {
                            case MegaAffect.X:
                                p.x += a * crv.offamount.x;
                                break;

                            case MegaAffect.Y:
                                p.y += a * crv.offamount.y;
                                break;

                            case MegaAffect.Z:
                                p.z += a * crv.offamount.z;
                                break;

                            case MegaAffect.XY:
                                p.x += a * crv.offamount.x;
                                p.y += a * crv.offamount.y;
                                break;

                            case MegaAffect.XZ:
                                p.x += a * crv.offamount.x;
                                p.z += a * crv.offamount.z;
                                break;

                            case MegaAffect.YZ:
                                p.y += a * crv.offamount.y;
                                p.z += a * crv.offamount.z;
                                break;

                            case MegaAffect.XYZ:
                                p.x += a * crv.offamount.x;
                                p.y += a * crv.offamount.y;
                                p.z += a * crv.offamount.z;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    float alpha = (p[ax] - bbox.min[ax]) / size[ax];
                    float a     = crv.curve.Evaluate(alpha) * crv.weight;

                    switch (crv.affectScale)
                    {
                    case MegaAffect.X:
                        p.x *= 1.0f + (a * crv.sclamount.y);
                        break;

                    case MegaAffect.Y:
                        p.y *= 1.0f + (a * crv.sclamount.y);
                        break;

                    case MegaAffect.Z:
                        p.z *= 1.0f + (a * crv.sclamount.z);
                        break;

                    case MegaAffect.XY:
                        p.x *= 1.0f + (a * crv.sclamount.y);
                        p.y *= 1.0f + (a * crv.sclamount.y);
                        break;

                    case MegaAffect.XZ:
                        p.x *= 1.0f + (a * crv.sclamount.y);
                        p.z *= 1.0f + (a * crv.sclamount.z);
                        break;

                    case MegaAffect.YZ:
                        p.y *= 1.0f + (a * crv.sclamount.y);
                        p.z *= 1.0f + (a * crv.sclamount.z);
                        break;

                    case MegaAffect.XYZ:
                        p.x *= 1.0f + (a * crv.sclamount.y);
                        p.y *= 1.0f + (a * crv.sclamount.y);
                        p.z *= 1.0f + (a * crv.sclamount.z);
                        break;
                    }

                    switch (crv.affectOffset)
                    {
                    case MegaAffect.X:
                        p.x += a * crv.offamount.x;
                        break;

                    case MegaAffect.Y:
                        p.y += a * crv.offamount.y;
                        break;

                    case MegaAffect.Z:
                        p.z += a * crv.offamount.z;
                        break;

                    case MegaAffect.XY:
                        p.x += a * crv.offamount.x;
                        p.y += a * crv.offamount.y;
                        break;

                    case MegaAffect.XZ:
                        p.x += a * crv.offamount.x;
                        p.z += a * crv.offamount.z;
                        break;

                    case MegaAffect.YZ:
                        p.y += a * crv.offamount.y;
                        p.z += a * crv.offamount.z;
                        break;

                    case MegaAffect.XYZ:
                        p.x += a * crv.offamount.x;
                        p.y += a * crv.offamount.y;
                        p.z += a * crv.offamount.z;
                        break;
                    }
                }
            }
        }

        return(invtm.MultiplyPoint3x4(p));
    }
 public static MegaSculptCurve Create()
 {
     MegaSculptCurve crv = new MegaSculptCurve();
     return crv;
 }