Ejemplo n.º 1
0
            public SomeCurveData(MyCurveData referenceCurve, string name, Vector3 position, BGCurveBaseMath.Config config)
                : base(new GameObject(name), referenceCurve.LineRendererMaterial, Color.magenta)
            {
                this.referenceCurve = referenceCurve;

                //game object
                GameObject.transform.parent     = referenceCurve.GameObject.transform.parent;
                GameObject.transform.localScale = localScale;
                GameObject.transform.position   = position;
                origin = position;

                //curve
                Curve        = GameObject.AddComponent <BGCurve>();
                Curve.Closed = referenceCurve.Curve.Closed;

                //add points
                for (var i = 0; i < referenceCurve.Curve.PointsCount; i++)
                {
                    Curve.AddPoint(referenceCurve.Curve[i].CloneTo(Curve));
                }

                //init math after points are added
                Math = new BGCurveBaseMath(Curve, config);

                AddObjects(ObjectsCount, referenceCurve.ObjectToMove, referenceCurve.Curve.transform.parent);
            }
Ejemplo n.º 2
0
            public static int CountStraightLines(BGCurveBaseMath math, bool[] straight)
            {
                var curve         = math.Curve;
                var points        = curve.Points;
                var sections      = math.SectionInfos;
                var sectionsCount = sections.Length;


                var straightLinesCount    = 0;
                var previousControlAbsent = points[0].ControlType == BGCurvePoint.ControlTypeEnum.Absent;

                for (var i = 0; i < sectionsCount; i++)
                {
                    var nextPoint         = curve.Closed && i == sectionsCount - 1 ? points[0] : points[i + 1];
                    var nextControlAbsent = nextPoint.ControlType == BGCurvePoint.ControlTypeEnum.Absent;

                    if (previousControlAbsent && nextControlAbsent)
                    {
                        straight[i] = true;
                        straightLinesCount++;
                    }

                    previousControlAbsent = nextControlAbsent;
                }
                return(straightLinesCount);
            }
Ejemplo n.º 3
0
 public virtual void Init(BGCcVisualizationLineRenderer cc)
 {
     this.cc = cc;
     doNotOptimizeStraightLines = cc.doNotOptimizeStraightLines;
     Math         = cc.Math.Math;
     straightBits = cc.straightBits;
 }
    // Use this for initialization
    void Start()
    {
        BGCurveBaseMath.Config cfg = new BGCurveBaseMath.Config(BGCurveBaseMath.Fields.PositionAndTangent);
        cMath = new BGCurveBaseMath(curve, cfg);
        //curveDistance = 1f;

        curveTotal = cMath.GetDistance();
    }
Ejemplo n.º 5
0
 public BGCurvePainterGizmo(BGCurveBaseMath math, bool monitorTransform = false)
 {
     Math = math;
     if (monitorTransform)
     {
         transformMonitor = new BGTransformMonitor(math.Curve);
     }
 }
Ejemplo n.º 6
0
 private static void AdjustMath(BGCurveSettings settings, BGCurveBaseMath math)
 {
     if (settings.Sections != math.Configuration.Parts ||
         (settings.ShowTangents && !math.IsCalculated(BGCurveBaseMath.Field.Tangent)) ||
         (!settings.ShowTangents && math.IsCalculated(BGCurveBaseMath.Field.Tangent)))
     {
         math.Init(NewConfig(settings));
     }
 }
Ejemplo n.º 7
0
        protected override bool Process(Event @event, BGCurveBaseMath math, float sceneViewHeight, ref Vector3 position, ref string message)
        {
            if (BGCurveSettingsForEditor.DisableSceneViewSelectionMenu || !menu.EditorSelection.HasSelected())
            {
                return(false);
            }


            var selectedPos = menu.EditorSelection.GetAveragePosition();

            if (!(DistanceTolerance > (@event.mousePosition - BGEditorUtility.GetSceneViewPosition(selectedPos, sceneViewHeight)).sqrMagnitude))
            {
                return(false);
            }


            //out params
            position = selectedPos;
            message  = SuccessMessage("Selected " + menu.EditorSelection.CountSelected + " point(s).");

            //turn on the menu
            menu.On(position);

            //check if all points share the same control type
            BGCurvePoint.ControlTypeEnum singleType = BGCurvePoint.ControlTypeEnum.Absent;
            bool first = true, single = true;

            menu.EditorSelection.ForEach(point =>
            {
                if (first)
                {
                    first      = false;
                    singleType = point.ControlType;
                }
                else if (singleType != point.ControlType)
                {
                    single = false;
                    return(true);
                }

                return(false);
            });

            if (single)
            {
                menu.Get(0).Current = singleType == BGCurvePoint.ControlTypeEnum.Absent;
                menu.Get(1).Current = singleType == BGCurvePoint.ControlTypeEnum.BezierSymmetrical;
                menu.Get(2).Current = singleType == BGCurvePoint.ControlTypeEnum.BezierIndependant;
            }
            else
            {
                menu.Get(0).Current = menu.Get(1).Current = menu.Get(2).Current = false;
            }


            return(true);
        }
        //check if delay is over
        private bool CheckIfDelayIsOver(BGCurveBaseMath math, BGCcCursor cursor)
        {
            var pointsCountMinusOne = Curve.PointsCount - 1;

            if (adjustByTotalLength)
            {
                oldLength = math.GetDistance();
            }

            //curve is not closed and delayed at last point
            var delayAtLastPoint = !Curve.Closed && currentSectionIndex == pointsCountMinusOne;

            //curve may be changing, so we need to adjust a position anyway
            cursor.Distance = delayAtLastPoint ? math.GetDistance() : math[currentSectionIndex].DistanceFromStartToOrigin;
            var delayValue = GetDelayAtPoint(currentSectionIndex);

            // we are still delayed
            if (!(Time.time - delayStarted > delayValue))
            {
                return(false);
            }

            var currentSpeed = speed;

            if (speedField != null)
            {
                //we need to retrieve speed from a field value
                currentSpeed = Curve[currentSectionIndex].GetFloat(speedField.FieldName);
            }

            // delay is over, start moving
            delayStarted = -1;
            if (speedWasPositiveWhileDelayed)
            {
                //                if (delayAtLastPoint) cursor.Distance = 0;
                //                else cursor.Distance += BGCurve.Epsilon;
                cursor.Distance += Mathf.Abs(currentSpeed * Time.deltaTime);
            }
            else
            {
                if (currentSectionIndex > 0)
                {
                    currentSectionIndex--;
                    cursor.Distance -= Mathf.Abs(currentSpeed * Time.deltaTime);
                }
                else
                {
                    if (!skipZeroPoint)
                    {
                        currentSectionIndex = pointsCountMinusOne;
                        cursor.Distance     = math.GetDistance() - Mathf.Abs(currentSpeed * Time.deltaTime);
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 9
0
        private void Dispose()
        {
//            CurrentCurve = null;
            CurrentGizmoPainter = null;
            AllCurves = null;
            Undo.undoRedoPerformed -= InternalOnUndoRedo;

            if (Math != null) Math.Dispose();
            Math = null;
        }
        //Unity callback
        private void Start()
        {
            curve = GetComponent <BGCurve>();
            var ccMath = GetComponent <BGCcMath>();

            math  = ccMath.Math;
            curve = ccMath.Curve;

            //init arrays
            oldPos    = new Vector3[PointsCount];
            newPos    = new Vector3[PointsCount];
            speed     = new float[ObjectsCount];
            distances = new float[ObjectsCount];
            objects   = new GameObject[ObjectsCount];


            //--------------------------- init from points
            for (var i = 0; i < PointsCount; i++)
            {
                var controlTypeEnum = BGCurvePoint.ControlTypeEnum.BezierIndependant;
                switch (ControlType)
                {
                case ControlTypeForNewPoints.Absent:
                    controlTypeEnum = BGCurvePoint.ControlTypeEnum.Absent;
                    break;

                case ControlTypeForNewPoints.Random:
                    controlTypeEnum = (BGCurvePoint.ControlTypeEnum)Random.Range(0, 3);
                    break;
                }
                curve.AddPoint(new BGCurvePoint(curve, RandomVector(), controlTypeEnum, RandomVector(), RandomVector()));
            }

            //Recalculate manually after points were added (normally you would not do it)
            math.Recalculate();

            //---------------------------- init objects
            if (ObjectToMove != null)
            {
                var totalDistance = oldDistance = math.GetDistance();
                for (var i = 0; i < ObjectsCount; i++)
                {
                    var obj = Instantiate(ObjectToMove, Vector3.zero, Quaternion.identity) as GameObject;
                    obj.transform.parent = transform;
                    objects[i]           = obj;
                    distances[i]         = Random.Range(0, totalDistance);
                }
                ObjectToMove.SetActive(false);
                //--------------------------- init speed
                for (var i = 0; i < ObjectsCount; i++)
                {
                    speed[i] = Random.Range(0, 2) == 0 ? Random.Range(-SpeedRange, -SpeedRange * 0.3f) : Random.Range(SpeedRange * 0.3f, SpeedRange);
                }
            }
        }
Ejemplo n.º 11
0
        // Use this for initialization
        private void Start()
        {
            curve        = GetComponent <BGCurve>();
            lineRenderer = GetComponent <LineRenderer>();

//            curveBaseMath = new BGCurveBaseMath(curve, false, 30);
            curveBaseMath = new BGCurveBaseMath(curve);
            started       = Time.time;

            ResetLineRenderer();
        }
        protected override bool Process(Event @event, BGCurveBaseMath math, float sceneViewHeight, ref Vector3 position, ref string message)
        {
            if (BGCurveSettingsForEditor.DisableSceneViewPointMenu)
            {
                return(false);
            }

            var minDistanceToCamera = float.MaxValue;
            var mousePosition       = @event.mousePosition;
            var cameraPos           = SceneView.currentDrawingSceneView.camera.transform.position;

            var index       = -1;
            var pointsCount = math.Curve.PointsCount;

            for (var i = 0; i < pointsCount; i++)
            {
                var pointPos = math.GetPosition(i);

                var sqrMagnitude = (mousePosition - BGEditorUtility.GetSceneViewPosition(pointPos, sceneViewHeight)).sqrMagnitude;
                if (sqrMagnitude > DistanceTolerance)
                {
                    continue;
                }

                var sqrtMagnitude = Vector3.SqrMagnitude(cameraPos - pointPos);

                if (minDistanceToCamera < sqrtMagnitude)
                {
                    continue;
                }

                //found a target
                minDistanceToCamera = sqrMagnitude;
                index = i;
            }

            if (index < 0)
            {
                return(false);
            }


            //menu active
            var point = math.Curve[index];

            position = math.GetPosition(index);
            message  = SuccessMessage("Point " + index);
            menu.On(point, index);

            //============== Ok
            return(true);
        }
Ejemplo n.º 13
0
        // Use this for initialization
        private void Start()
        {
            curve = GetComponent <BGCurve>();
//            curve.TraceChanges = true;

            lineRenderer = GetComponent <LineRenderer>();

//            curveBaseMath = new BGCurveBaseMath(curve, true);
            curveBaseMath = new BGCurveBaseMath(curve);
            started       = Time.time;

            ResetLineRenderer();
            curve.Changed += (sender, args) => ResetLineRenderer();
        }
Ejemplo n.º 14
0
            public CurveData(TestCurves testCurves, string name, string description, Vector3 position, BGCurveBaseMath.Config config, MathTypeEnum mathType)
                : base(new GameObject(name), testCurves.LineRendererMaterial, Color.magenta)
            {
                this.testCurves  = testCurves;
                this.description = description;

                //game object
                GameObject.transform.position = position;
                origin = position;

                //curve
                Curve        = GameObject.AddComponent <BGCurve>();
                Curve.Closed = testCurves.Curve.Closed;

                //add points
                for (var i = 0; i < testCurves.Curve.PointsCount; i++)
                {
                    var point      = testCurves.Curve[i];
                    var clonePoint = new BGCurvePoint(Curve, point.PositionLocal, point.ControlType, point.ControlFirstLocal, point.ControlSecondLocal);
                    Curve.AddPoint(clonePoint);
                }

                //init math after points are added
                switch (mathType)
                {
                case MathTypeEnum.Base:
                    Math = new BGCurveBaseMath(Curve, config);
                    break;

                case MathTypeEnum.Formula:
#pragma warning disable 0618
                    Math = new BGCurveFormulaMath(Curve, config);
#pragma warning restore 0618

                    break;

                case MathTypeEnum.Adaptive:
                    Math = new BGCurveAdaptiveMath(Curve, (BGCurveAdaptiveMath.ConfigAdaptive)config);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("mathType", mathType, null);
                }

                AddObjects(ObjectsCount, testCurves.ObjectToMove, GameObject.transform);

                //scale down
                GameObject.transform.localScale = originalScale;
            }
Ejemplo n.º 15
0
        private void InitMath(object sender, EventArgs e)
        {
            //New math
            var config = new BGCurveBaseMath.Config(fields)
            {
                Parts = sectionParts,
                UsePointPositionsToCalcTangents = usePositionToCalculateTangents,
                OptimizeStraightLines           = optimizeStraightLines,
                Fields = fields
            };

            if (updateMode != UpdateModeEnum.Always && Application.isPlaying)
            {
                switch (updateMode)
                {
                case UpdateModeEnum.AabbVisible:
                    InitAabbVisibleBefore(config);
                    break;

                case UpdateModeEnum.RendererVisible:
                    InitRendererVisible(config);
                    break;
                }
            }

            if (math == null)
            {
/*
 *              math = mathType == MathTypeEnum.Base
 *                  ? new BGCurveBaseMath(Curve, config)
 *                  : new BGCurveAdaptiveSplitMath(Curve, config);
 */
                math = new BGCurveBaseMath(Curve, config);

                ChangedParams += InitMath;
                math.Changed  += MathWasChanged;
            }
            else
            {
                math.ChangeRequested -= MathOnChangeRequested;
                math.Init(config);
            }

            if (updateMode == UpdateModeEnum.AabbVisible)
            {
                InitAabbVisibleAfter(config);
            }
        }
        //points was passed and we check if delay is required at this point
        private bool CheckDelayAtPoint(BGCurveBaseMath math, BGCcCursor cursor, int pointIndex, bool speedPositive)
        {
            if (IsDelayRequired(pointIndex))
            {
                //we gotta delay at this point
                currentSectionIndex = pointIndex;
                //move cursor straight to the point
                cursor.Distance = Curve.PointsCount - 1 == pointIndex && !Curve.Closed ? math.GetDistance() : math[pointIndex].DistanceFromStartToOrigin;

                // !!!!!!!  start delay
                StartDelay(speedPositive);
                //we does not need to process movement (it will be ignored at any rate, cause we stick to the particular point)
                return(true);
            }
            return(false);
        }
Ejemplo n.º 17
0
        private void Dispose()
        {
//            CurrentCurve = null;
            if (CurrentGizmoPainter != null && CurrentGizmoPainter.Math.Curve == Curve)
            {
                CurrentGizmoPainter = null;
            }
            AllCurves = null;
            Undo.undoRedoPerformed -= InternalOnUndoRedo;

            if (Math != null)
            {
                Math.Dispose();
            }
            Math = null;
        }
Ejemplo n.º 18
0
            public TestCurves(BGCurve curve, BGCurveBaseMath.Config config, MeshRenderer objectToMove, Material lineRendererMaterial)
                : base(curve.gameObject, lineRendererMaterial, Color.green)
            {
                Curve        = curve;
                Math         = new BGCurveBaseMath(curve, config);
                ObjectToMove = objectToMove;

                AddObject(objectToMove.gameObject);
                AddObjects(ObjectsCount - 1, objectToMove, curve.transform);

                const float offset = 1 / (float)ObjectsCount;

                for (var i = 0; i < ObjectsCount; i++)
                {
                    DistanceRatios.Add(i * offset);
                }
            }
    // Use this for initialization
    void Start()
    {
        hp = maxHp;
        BGCurveBaseMath.Config cfg = new BGCurveBaseMath.Config(BGCurveBaseMath.Fields.PositionAndTangent);
        cMath         = new BGCurveBaseMath(curve, cfg);
        curveDistance = 1f;

        curveTotal = cMath.GetDistance();
        animator   = GetComponentInChildren <Animator>();

        rbs     = transform.GetComponentsInChildren <Rigidbody>();
        rbRends = new List <Renderer>();
        foreach (Rigidbody r in rbs)
        {
            rbRends.Add(r.gameObject.GetComponent <Renderer>());
        }
    }
        //checks if cursor passed a point (current section is changed) and if new delay occured. Also fires events if needed
        private bool CheckForNewDelay(BGCurveBaseMath math, float distance, ref int newSectionIndex, bool checkDelay, bool firingEvents)
        {
            if (currentSectionIndex == 0 && skipZeroPoint)
            {
                return(false);
            }
            if (!math.Curve.Closed && currentSectionIndex == math.Curve.PointsCount - 1)
            {
                return(false);
            }

            newSectionIndex = math.CalcSectionIndexByDistance(distance);
            if (currentSectionIndex != newSectionIndex)
            {
                //section is changed (there could be several points between)

                //if speed was positive or negative?
                bool speedPositive;
                if (speedField == null)
                {
                    speedPositive = speed > 0;
                }
                else
                {
                    speedPositive = Curve[currentSectionIndex].GetFloat(speedField.FieldName) > 0;
                    if (speedReversed)
                    {
                        speedPositive = !speedPositive;
                    }
                }

                if (CheckDelayAtSectionChanged(newSectionIndex, checkDelay, firingEvents, speedPositive))
                {
                    return(true);
                }
            }
            //no delay
            delayStarted = -1;

            return(false);
        }
Ejemplo n.º 21
0
 public BGCurveCalculatorClosestPoint(BGCurveBaseMath math)
 {
     this.math = math;
 }
Ejemplo n.º 22
0
 protected abstract bool Process(Event @event, BGCurveBaseMath math, float sceneViewHeight, ref Vector3 position, ref string message);
Ejemplo n.º 23
0
        protected void OnEnable()
        {
            Curve = (BGCurve)target;

            //wth
            if (Curve == null)
            {
                return;
            }

            CurrentCurve     = Curve;
            transformMonitor = BGTransformMonitor.GetMonitor(Curve);


            var settings = BGPrivateField.GetSettings(Curve);


            //painter and math
            if (curve2Painter.ContainsKey(Curve))
            {
                curve2Painter[Curve].Dispose();
                curve2Painter.Remove(Curve);
            }

            Math = NewMath(Curve, settings);
            CurrentGizmoPainter = new BGCurvePainterGizmo(Math);
            AllCurves           = FindObjectsOfType <BGCurve>();

            //overlay
            BGEditorUtility.Assign(ref OverlayMessage, () => new BGOverlayMessage());

            //probably we do not need it for play mode.. probably
            if (!Application.isPlaying)
            {
                //they are not persistent
                Curve.ImmediateChangeEvents = true;
                Curve.BeforeChange         += BeforeCurveChange;
                Curve.Changed += CurveChanged;
            }


            if (!settings.Existing)
            {
                //newly created
                settings.Existing = true;

                var defaultSettings = BGCurveSettingsOperations.LoadDefault();
                if (defaultSettings != null)
                {
                    BGPrivateField.SetSettings(Curve, defaultSettings);
                }
            }

            //load textures
            BGEditorUtility.Assign(ref headerTexture, () => BGEditorUtility.LoadTexture2D(BGEditorUtility.Image.BGCurveLogo123));
            stickerTextureOk      = BGEditorUtility.Texture1X1(new Color32(46, 143, 168, 255));
            stickerTextureError   = BGEditorUtility.Texture1X1(new Color32(255, 0, 0, 255));
            stickerTextureWarning = BGEditorUtility.Texture1X1(new Color32(255, 206, 92, 255));
            stickerTextureActive  = BGEditorUtility.Texture1X1(new Color32(44, 160, 90, 255));

            //selection
            editorSelection = new BGCurveEditorPointsSelection(Curve, this);

            // editors
            editors = new BGCurveEditorTab[]
            {
                new BGCurveEditorPoints(this, serializedObject, editorSelection), new BGCurveEditorComponents(this, serializedObject),
                new BGCurveEditorFields(this, serializedObject, editorSelection), new BGCurveEditorSettings(this, serializedObject)
            };

            headers = editors.Select(editor => editor.Header2D).ToArray();
            foreach (var editor in editors)
            {
                editor.OnEnable();
            }

            //do it every frame
            EditorApplication.update -= OverlayMessage.Check;
            EditorApplication.update += OverlayMessage.Check;

            Undo.undoRedoPerformed -= InternalOnUndoRedo;
            Undo.undoRedoPerformed += InternalOnUndoRedo;
        }
        // overflow occurred
        private void Overflow(BGCurveBaseMath math, ref float newDistance, bool currentSpeedPositive, bool checkDelay, bool firingEvents)
        {
            var lessThanZero   = newDistance < 0;
            var totalDistance  = math.GetDistance();
            var lastPointIndex = Curve.PointsCount - 1;

            //we need to check delays. (all points up to boundary point)
            if (checkDelay || firingEvents)
            {
                if (currentSpeedPositive)
                {
                    //process all passed points
//                    var lastPointIndexToCheck = Curve.Closed ? lastPointIndex : lastPointIndex - 1;
                    var lastPointIndexToCheck = lastPointIndex;
                    if (currentSectionIndex != lastPointIndexToCheck)
                    {
                        if (CheckDelayAtSectionChanged(lastPointIndexToCheck, checkDelay, firingEvents, true))
                        {
                            return;
                        }
                    }
                }
                else
                {
                    if (currentSectionIndex > 0)
                    {
                        if (CheckDelayAtSectionChanged(0, checkDelay, firingEvents, false))
                        {
                            return;
                        }
                    }

                    //this needs to be refactored
                    if (!skipZeroPoint)
                    {
                        if (checkDelay && CheckDelayAtPoint(math, Cursor, 0, false))
                        {
                            if (firingEvents)
                            {
                                FirePointReachedEvent(0);
                            }
                            skipZeroPoint = true;
                            return;
                        }
                    }
                }
            }


            //overflow
            switch (overflowControl)
            {
            case OverflowControlEnum.Stop:
                newDistance = lessThanZero ? 0 : totalDistance;
                Stopped     = true;
                break;

            case OverflowControlEnum.Cycle:
                newDistance = lessThanZero ? totalDistance + newDistance : newDistance - totalDistance;
                break;

            case OverflowControlEnum.PingPong:
                if (speedField == null)
                {
                    speed = -speed;
                }
                speedReversed        = !speedReversed;
                currentSpeedPositive = !currentSpeedPositive;
                newDistance          = lessThanZero ? -newDistance : totalDistance * 2 - newDistance;
                break;
            }

            if (newDistance < 0)
            {
                newDistance = 0;
            }
            else if (newDistance > totalDistance)
            {
                newDistance = totalDistance;
            }


            //ok, we need to check delays.. once again. (single boundary point)
            if (checkDelay || firingEvents)
            {
                if (Curve.Closed)
                {
                    if (skipZeroPoint)
                    {
                        skipZeroPoint = false;
                    }
                    else
                    {
                        if (firingEvents)
                        {
                            FirePointReachedEvent(0);
                        }

                        currentSectionIndex = currentSpeedPositive ? 0 : lastPointIndex;

                        if (checkDelay && CheckDelayAtPoint(math, Cursor, 0, currentSpeedPositive))
                        {
                            return;
                        }
                    }
                }
                else
                {
                    if (lessThanZero)
                    {
                        //original speed was negative
                        if (skipZeroPoint)
                        {
                            skipZeroPoint = false;
                        }
                        else
                        {
                            currentSectionIndex = 0;
                            if (firingEvents)
                            {
                                FirePointReachedEvent(0);
                            }
                            if (checkDelay && CheckDelayAtPoint(math, Cursor, 0, currentSpeedPositive))
                            {
                                return;
                            }
                        }
                    }
                    else
                    {
                        //original speed was positive
                        if (!Curve.Closed)
                        {
                            if (currentSpeedPositive)
                            {
                                //last->first
                                currentSectionIndex = 0;
                                if (firingEvents)
                                {
                                    FirePointReachedEvent(0);
                                }
                                if (checkDelay && CheckDelayAtPoint(math, Cursor, 0, currentSpeedPositive))
                                {
                                    return;
                                }
                            }
                            else
                            {
                                //last->last (pingpong)
                                currentSectionIndex = lastPointIndex - 1;
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 25
0
 public BGCurvePainterHandles(BGCurveBaseMath math)
     : base(math)
 {
 }
Ejemplo n.º 26
0
        //init math with current params
        private void InitMath(object sender, EventArgs e)
        {
            //new config
            var config = mathType == MathTypeEnum.Adaptive
                ? new BGCurveAdaptiveMath.ConfigAdaptive(fields)
            {
                Tolerance = tolerance
            }
                : new BGCurveBaseMath.Config(fields)
            {
                Parts = sectionParts
            };

            config.UsePointPositionsToCalcTangents = usePositionToCalculateTangents;
            config.OptimizeStraightLines           = optimizeStraightLines;
            config.Fields = fields;

            if (updateMode != UpdateModeEnum.Always && Application.isPlaying)
            {
                switch (updateMode)
                {
                case UpdateModeEnum.AabbVisible:
                    InitAabbVisibleBefore(config);
                    break;

                case UpdateModeEnum.RendererVisible:
                    InitRendererVisible(config);
                    break;
                }
            }

            if (NewMathRequired)
            {
                //we need to create new math object

                var mathWasNull = math == null;

                if (mathWasNull)
                {
                    ChangedParams += InitMath;
                }
                else
                {
                    math.ChangeRequested -= MathOnChangeRequested;
                    math.Changed         -= MathWasChanged;
                    math.Dispose();
                }

                switch (MathType)
                {
                case MathTypeEnum.Base:
                    math = new BGCurveBaseMath(Curve, config);
                    break;

                default:
                    //                    case MathTypeEnum.Adaptive:
                    math = new BGCurveAdaptiveMath(Curve, (BGCurveAdaptiveMath.ConfigAdaptive)config);
                    break;
                }


                math.Changed += MathWasChanged;

                if (!mathWasNull)
                {
                    MathWasChanged(this, null);
                }
            }
            else
            {
                //we can reuse existing math object

                math.ChangeRequested -= MathOnChangeRequested;
                //reinit math with new params (it will be recalculated as result)
                math.Init(config);
            }

            //init AABB
            if (updateMode == UpdateModeEnum.AabbVisible)
            {
                InitAabbVisibleAfter();
            }
        }