Example #1
0
        /// <summary>
        /// Gets the length of the get curve.
        /// </summary>
        /// <param name="curveIndex">The curve index.</param>
        /// <returns>The curve length.</returns>
        private float _GetCurveLength(int curveIndex)
        {
            int i = curveIndex * 3;

            return(Bezier.Integrate(_points[i], _points[i + 1], _points[i + 2], _points[i + 3], 0, 1));
        }
Example #2
0
        /// <summary>
        /// Add a point to the spline.
        /// </summary>
        /// <remarks>
        /// Depending on the current selected point, the new point will be added between two points, or at the end of the curve.
        /// If there's no point selected, or the selected point is the last point, the new point will be added at the end of the curve, at a distance of 1 in the direction of the last point of the spline.
        /// If the selected point is not the last point, the new point will be created between previous and next point. The bezier handles of the new, of the previous and of the next point will be created/modified in order to maintain the same spline shape.
        /// </remarks>
        /// <param name="selectedIndex">The current selected control point index.</param>
        public void AddPoint(int selectedIndex)
        {
            // Add point to the end of the spline
            if (selectedIndex == -1 || selectedIndex == _points.Length - 1 || selectedIndex % 3 != 0)
            {
                Vector3 direction = GetDirection(1f);

                Vector3 point = _points[_points.Length - 1];
                Array.Resize(ref _points, _points.Length + 3);

                point += direction;
                _points[_points.Length - 3] = point;
                point += direction;
                _points[_points.Length - 2] = point;
                point += direction;
                _points[_points.Length - 1] = point;

                Array.Resize(ref _modes, _modes.Length + 1);
                _modes[_modes.Length - 1] = BezierControlPointMode.Corner;
                _modes[_modes.Length - 2] = BezierControlPointMode.Aligned;
                _EnforceMode(_points.Length - 4);

                if (_loop)
                {
                    _points[_points.Length - 1] = _points[0];
                    _modes[_modes.Length - 1]   = _modes[0];
                    _EnforceMode(0);
                }
            }
            // Add point between two points
            else if (selectedIndex % 3 == 0)
            {
                float s = 0;
                for (int i = 0; i < selectedIndex / 3; i++)
                {
                    s += _CurveLength(i);
                }
                s += _CurveLength(selectedIndex / 3) / 2;

                float t0 = GetArcLengthParameter(s) * curveCount - selectedIndex / 3;

                Vector3 point     = Bezier.GetPoint(_points[selectedIndex], _points[selectedIndex + 1], _points[selectedIndex + 2], _points[selectedIndex + 3], t0);
                Vector3 direction = Bezier.GetFirstDerivative(_points[selectedIndex], _points[selectedIndex + 1], _points[selectedIndex + 2], _points[selectedIndex + 3], t0);

                Array.Resize(ref _points, _points.Length + 3);
                for (int i = _points.Length - 1; i >= selectedIndex + 5; i--)
                {
                    _points[i] = _points[i - 3];
                }

                int newIndex = selectedIndex + 3;

                _points[newIndex]     = point;
                _points[newIndex - 1] = point - direction * t0 / 3;
                _points[newIndex - 2] = _points[newIndex - 3] + (_points[newIndex - 2] - _points[newIndex - 3]) * t0;

                _points[newIndex + 1] = point + direction * (1 - t0) / 3;
                _points[newIndex + 2] = _points[newIndex + 3] + (_points[newIndex + 2] - _points[newIndex + 3]) * (1 - t0);

                Array.Resize(ref _modes, _modes.Length + 1);
                for (int i = _modes.Length - 1; i >= selectedIndex / 3 + 1; i--)
                {
                    _modes[i] = _modes[i - 1];
                }

                _modes[selectedIndex / 3]     = BezierControlPointMode.Corner;
                _modes[selectedIndex / 3 + 1] = BezierControlPointMode.Aligned;
                _modes[selectedIndex / 3 + 2] = BezierControlPointMode.Corner;
            }

            SetDirty();
        }