private void OnDrawGizmos() { // If all points are invalid exit if (m_Points == null || m_Points.Count == 0) { return; } SplinePoint previousPoint = m_Points[0]; for (int p = 1; p < m_Points.Count; p++) { // If next point is null end if (m_Points[p] == null) { return; } // Draw Spline segment Vector3 previousPosition = previousPoint.transform.position; for (int i = 1; i <= s_DebugSegments; i++) { var t = i / (float)s_DebugSegments; var position = SplineUtil.EvaluateSplineSegment(previousPoint, m_Points[p], t); UnityEditor.Handles.color = DebugColors.spline.wire; UnityEditor.Handles.DrawLine(previousPosition, position); previousPosition = position; } // Store previous point for next iteration previousPoint = m_Points[p]; } }
/// <summary> /// Evaluates the Spline at a given position t, and returns values at that position. /// </summary> /// <param name="t">Position along the Spline to evaluate.</param> /// <param name="loop">Allow the t value to loop for values above 1.</param> public SplineValue Evaluate(float t, bool loop = false) { // Validate points if (m_Points == null || m_Points.Count == 0) { Debug.LogError("Invalid point list"); return(new SplineValue()); } // Use fractional part for looping if (loop) { t = t % 1; } // Get segment count var segmentCount = m_Points.Count - 1; // Get length data for Spline void GetLengthData(out float[] segments, out float spline) { segments = new float[segmentCount]; spline = 0; for (int i = 0; i < segmentCount; i++) { segments[i] = SplineUtil.GetSplineSegmentLength(m_Points[i], m_Points[i + 1]); spline += segments[i]; } } // Get length data and t position in Spline float[] segmentLengths; float splineLength; GetLengthData(out segmentLengths, out splineLength); float positionInSpline = Mathf.Lerp(0, splineLength, t); // Get segment count // Get current segment index and T value within it var segment = 0; var segmentT = 0.0f; var minLength = 0.0f; for (int i = 0; i < segmentLengths.Length; i++) { if (positionInSpline > minLength + segmentLengths[i]) { minLength += segmentLengths[i]; continue; } segment = i; segmentT = (positionInSpline - minLength) / segmentLengths[i]; break; } // Reached end of Spline if (segment == segmentCount) { return(new SplineValue() { position = m_Points[segment].transform.position, normal = SplineUtil.EvaluateSplineSegmentNormal(m_Points[segment], m_Points[segment], segmentT), segment = segment, }); } // Evaluate Spline segment return(new SplineValue() { position = SplineUtil.EvaluateSplineSegment(m_Points[segment], m_Points[segment + 1], segmentT), normal = SplineUtil.EvaluateSplineSegmentNormal(m_Points[segment], m_Points[segment + 1], segmentT), segment = segment, }); }