Beispiel #1
0
        public override CurvePoint[] GetCurvePoints()
        {
            // avoids rebuilding entire curve on every call, should be cleared if we wanted to rebuild the curve (if control points move for example)
            if (_curvePoints != null)
            {
                return(_curvePoints);
            }

            // First for loop goes through each control point, the second subdivides the path between CPs based on resolution
            var distanceOnCurve = 0f;
            var prevPoint       = new CurvePoint {
                Position = ControlPoints[0]
            };
            var nbPoints = ControlPoints.Length * Resolution;
            var points   = new CurvePoint[nbPoints];
            var step     = 1f / (nbPoints - 1);

            for (var i = 0; i < nbPoints; i++)
            {
                var t     = i * step;
                var point = new CurvePoint();
                point.Position = Evaluate(t, out point.Tangent, out point.Curvature);
                point.Bank     = GetBankAngle(point.Tangent, point.Curvature, MaxBankAngle);

                // Currently breaks if 3 consecutive points are colinear, to be improved with second pass on curve
                point.Normal = Vector3.Cross(point.Curvature, point.Tangent).normalized;
                if (Vector3.Dot(point.Normal, prevPoint.Normal) < 0)
                {
                    point.Normal *= -1;
                }

                distanceOnCurve      += Vector3.Distance(point.Position, prevPoint.Position);
                point.DistanceOnCurve = distanceOnCurve;
                points[i]             = point;
                prevPoint             = point;
            }
            FixNormals(ref points);
            _curvePoints = points;
            return(points);
        }
Beispiel #2
0
        public override CurvePoint[] GetCurvePoints()
        {
            // avoids rebuilding entire curve on every call, should be cleared if we wanted to rebuild the curve (if control points move for example)
            if (_curvePoints != null)
            {
                return(_curvePoints);
            }

            // First for loop goes through each control point, the second subdivides the path between CPs based on resolution
            var distanceOnCurve = 0f;
            var prevPoint       = new CurvePoint {
                Position = ControlPoints[0]
            };
            // If we are looping, we are adding an extra segment, so we need an extra point
            var     nbPoints = CloseLoop ? ControlPoints.Length : ControlPoints.Length - 1;
            var     points = new CurvePoint[nbPoints * Resolution + 1];
            Vector3 p0 = Vector3.zero, p1 = Vector3.zero, m0 = Vector3.zero, m1 = Vector3.zero;

            for (var i = 0; i < nbPoints; i++)
            {
                p0 = ControlPoints[i];
                p1 = ControlPoints[GetClampedPointIdx(i + 1)];
                m0 = 0.5f * (p1 - ControlPoints[GetClampedPointIdx(i - 1)]);
                m1 = 0.5f * (ControlPoints[GetClampedPointIdx(i + 2)] - p0);
                // Second for loop actually creates the spline for this particular segment
                for (var j = 0; j < Resolution; j++)
                {
                    points[i * Resolution + j] = GetPointOnCurve(p0, p1, m0, m1, (float)j / Resolution, ref distanceOnCurve, ref prevPoint);
                }
            }
            // we have to manually add the last point on the spline
            points[nbPoints * Resolution] = GetPointOnCurve(p0, p1, m0, m1, 1f, ref distanceOnCurve, ref prevPoint);
            FixNormals(ref points);
            _curvePoints = points;
            return(points);
        }
Beispiel #3
0
        private static CurvePoint GetPointOnCurve(Vector3 p0, Vector3 p1, Vector3 m0, Vector3 m1, float t, ref float distanceOnCurve, ref CurvePoint prevPoint)
        {
            var point = new CurvePoint();
            point.Position = Evaluate(p0, p1, m0, m1, t, out point.Tangent, out point.Curvature);
            point.Bank = GetBankAngle(point.Tangent, point.Curvature, MaxBankAngle);

            // Currently breaks if 3 consecutive points are colinear, to be improved with second pass on curve
            point.Normal = Vector3.Cross(point.Curvature, point.Tangent).normalized;
            if (Vector3.Dot(point.Normal, prevPoint.Normal) < 0)
                point.Normal *= -1;

            distanceOnCurve += Vector3.Distance(point.Position, prevPoint.Position);
            point.DistanceOnCurve = distanceOnCurve;
            prevPoint = point;
            return point;
        }
Beispiel #4
0
        public override CurvePoint[] GetCurvePoints()
        {
            // avoids rebuilding entire curve on every call, should be cleared if we wanted to rebuild the curve (if control points move for example)
            if (_curvePoints != null)
                return _curvePoints;

            // First for loop goes through each control point, the second subdivides the path between CPs based on resolution
            var distanceOnCurve = 0f;
            var prevPoint = new CurvePoint { Position = ControlPoints[0] };
            // If we are looping, we are adding an extra segment, so we need an extra point
            var nbPoints = CloseLoop ? ControlPoints.Length : ControlPoints.Length - 1;
            var points = new CurvePoint[nbPoints * Resolution + 1];
            Vector3 p0 = Vector3.zero, p1 = Vector3.zero, m0 = Vector3.zero, m1 = Vector3.zero;
            for (var i = 0; i < nbPoints; i++)
            {
                p0 = ControlPoints[i];
                p1 = ControlPoints[GetClampedPointIdx(i + 1)];
                m0 = 0.5f * (p1 - ControlPoints[GetClampedPointIdx(i - 1)]);
                m1 = 0.5f * (ControlPoints[GetClampedPointIdx(i + 2)] - p0);
                // Second for loop actually creates the spline for this particular segment
                for (var j = 0; j < Resolution; j++)
                    points[i * Resolution + j] = GetPointOnCurve(p0, p1, m0, m1, (float)j / Resolution, ref distanceOnCurve, ref prevPoint);
            }
            // we have to manually add the last point on the spline
            points[nbPoints * Resolution] = GetPointOnCurve(p0, p1, m0, m1, 1f, ref distanceOnCurve, ref prevPoint);
            FixNormals(ref points);
            _curvePoints = points;
            return points;
        }
Beispiel #5
0
        public override CurvePoint[] GetCurvePoints()
        {
            // avoids rebuilding entire curve on every call, should be cleared if we wanted to rebuild the curve (if control points move for example)
            if(_curvePoints != null)
                return _curvePoints;

            // First for loop goes through each control point, the second subdivides the path between CPs based on resolution
            var distanceOnCurve = 0f;
            var prevPoint = new CurvePoint { Position = ControlPoints[0] };
            var nbPoints = ControlPoints.Length * Resolution;
            var points = new CurvePoint[nbPoints];
            var step = 1f / (nbPoints - 1);
            for (var i = 0; i < nbPoints; i++)
            {
                var t = i * step;
                var point = new CurvePoint();
                point.Position = Evaluate(t, out point.Tangent, out point.Curvature);
                point.Bank = GetBankAngle(point.Tangent, point.Curvature, MaxBankAngle);

                // Currently breaks if 3 consecutive points are colinear, to be improved with second pass on curve
                point.Normal = Vector3.Cross(point.Curvature, point.Tangent).normalized;
                if (Vector3.Dot(point.Normal, prevPoint.Normal) < 0)
                    point.Normal *= -1;

                distanceOnCurve += Vector3.Distance(point.Position, prevPoint.Position);
                point.DistanceOnCurve = distanceOnCurve;
                points[i] = point;
                prevPoint = point;
            }
            FixNormals(ref points);
            _curvePoints = points;
            return points;
        }
Beispiel #6
0
        protected static void FixNormals(ref CurvePoint[] curvePoints)
        {
            for (var i = 0; i < curvePoints.Length; i++)
            {
                var point = curvePoints[i];
                if (point.Normal == Vector3.zero)
                {
                    // look forward until we find a non zero normal
                    var j = i;
                    while (j < curvePoints.Length)
                    {
                        if (curvePoints[j].Normal != Vector3.zero)
                            break;
                        j++;
                    }

                    if (j < curvePoints.Length)
                    {
                        while (i < j)
                        {
                            curvePoints[i].Normal = curvePoints[j].Normal;
                            i++;
                        }
                    }
                }
            }
        }
Beispiel #7
0
        private static CurvePoint GetPointOnCurve(Vector3 p0, Vector3 p1, Vector3 m0, Vector3 m1, float t, ref float distanceOnCurve, ref CurvePoint prevPoint)
        {
            var point = new CurvePoint();

            point.Position = Evaluate(p0, p1, m0, m1, t, out point.Tangent, out point.Curvature);
            point.Bank     = GetBankAngle(point.Tangent, point.Curvature, MaxBankAngle);

            // Currently breaks if 3 consecutive points are colinear, to be improved with second pass on curve
            point.Normal = Vector3.Cross(point.Curvature, point.Tangent).normalized;
            if (Vector3.Dot(point.Normal, prevPoint.Normal) < 0)
            {
                point.Normal *= -1;
            }

            distanceOnCurve      += Vector3.Distance(point.Position, prevPoint.Position);
            point.DistanceOnCurve = distanceOnCurve;
            prevPoint             = point;
            return(point);
        }