/// <summary>Get the tangent of the curve at a point along the path.</summary> /// <param name="pos">Postion along the path. Need not be normalized.</param> /// <returns>World-space direction of the path tangent. /// Length of the vector represents the tangent strength</returns> public override Vector3 EvaluateTangent(float pos) { Vector3 result = new Vector3(); if (Waypoints.Length == 0) { result = transform.rotation * Vector3.forward; } else { int indexA, indexB; pos = GetBoundingIndices(pos, out indexA, out indexB); if (indexA == indexB) { result = Waypoints[indexA].Tangent; } else { Waypoint wpA = Waypoints[indexA]; Waypoint wpB = Waypoints[indexB]; result = ExtSpline.BezierTangent3(pos - indexA, Waypoints[indexA].Position, wpA.Position + wpA.Tangent, wpB.Position - wpB.Tangent, wpB.Position); } } return(transform.TransformDirection(result)); }
/// <summary>Get a worldspace position of a point along the path</summary> /// <param name="pos">Postion along the path. Need not be normalized.</param> /// <returns>World-space position of the point along at path at pos</returns> public override Vector3 EvaluatePosition(float pos) { Vector3 result = new Vector3(); if (Waypoints.Length == 0) { result = transform.position; } else { int indexA, indexB; pos = GetBoundingIndices(pos, out indexA, out indexB); if (indexA == indexB) { result = Waypoints[indexA].Position; } else { // interpolate Waypoint wpA = Waypoints[indexA]; Waypoint wpB = Waypoints[indexB]; result = ExtSpline.Bezier3(pos - indexA, Waypoints[indexA].Position, wpA.Position + wpA.Tangent, wpB.Position - wpB.Tangent, wpB.Position); } } return(transform.TransformPoint(result)); }
/// <summary>Get the orientation the curve at a point along the path.</summary> /// <param name="pos">Position along the path. Need not be normalized.</param> /// <returns>World-space orientation of the path, as defined by tangent, up, and roll.</returns> public override Quaternion EvaluateOrientation(float pos) { Quaternion result = transform.rotation; if (Waypoints.Length > 0) { float roll = 0; int indexA, indexB; pos = GetBoundingIndices(pos, out indexA, out indexB); if (indexA == indexB) { roll = Waypoints[indexA].Roll; } else { UpdateControlPoints(); roll = ExtSpline.Bezier1(pos - indexA, Waypoints[indexA].Roll, m_ControlPoints1[indexA].Roll, m_ControlPoints2[indexA].Roll, Waypoints[indexB].Roll); } Vector3 fwd = EvaluateTangent(pos); if (!fwd.AlmostZero()) { Vector3 up = transform.rotation * Vector3.up; Quaternion q = Quaternion.LookRotation(fwd, up); result = q * Quaternion.AngleAxis(roll, Vector3.forward); } } return(result); }
protected void UpdateControlPoints() { int numPoints = (Waypoints == null) ? 0 : Waypoints.Length; if (numPoints > 1 && (Looped != m_IsLoopedCache || m_ControlPoints1 == null || m_ControlPoints1.Length != numPoints || m_ControlPoints2 == null || m_ControlPoints2.Length != numPoints)) { Vector4[] p1 = new Vector4[numPoints]; Vector4[] p2 = new Vector4[numPoints]; Vector4[] K = new Vector4[numPoints]; for (int i = 0; i < numPoints; ++i) { K[i] = Waypoints[i].AsVector4; } if (Looped) { ExtSpline.ComputeSmoothControlPointsLooped(ref K, ref p1, ref p2); } else { ExtSpline.ComputeSmoothControlPoints(ref K, ref p1, ref p2); } m_ControlPoints1 = new Waypoint[numPoints]; m_ControlPoints2 = new Waypoint[numPoints]; for (int i = 0; i < numPoints; ++i) { m_ControlPoints1[i] = Waypoint.FromVector4(p1[i]); m_ControlPoints2[i] = Waypoint.FromVector4(p2[i]); } m_IsLoopedCache = Looped; } }
/// <summary>Get the tangent of the curve at a point along the path.</summary> /// <param name="pos">Position along the path. Need not be normalized.</param> /// <returns>World-space direction of the path tangent. /// Length of the vector represents the tangent strength</returns> public override Vector3 EvaluateTangent(float pos) { Vector3 result = transform.rotation * Vector3.forward; if (Waypoints.Length > 1) { UpdateControlPoints(); int indexA, indexB; pos = GetBoundingIndices(pos, out indexA, out indexB); if (!Looped && indexA == Waypoints.Length - 1) { --indexA; } result = ExtSpline.BezierTangent3(pos - indexA, Waypoints[indexA].Position, m_ControlPoints1[indexA].Position, m_ControlPoints2[indexA].Position, Waypoints[indexB].Position); } return(transform.TransformDirection(result)); }
/// <summary>Get a worldspace position of a point along the path</summary> /// <param name="pos">Position along the path. Need not be normalized.</param> /// <returns>World-space position of the point along at path at pos</returns> public override Vector3 EvaluatePosition(float pos) { Vector3 result = Vector3.zero; if (Waypoints.Length > 0) { UpdateControlPoints(); int indexA, indexB; pos = GetBoundingIndices(pos, out indexA, out indexB); if (indexA == indexB) { result = Waypoints[indexA].Position; } else { result = ExtSpline.Bezier3(pos - indexA, Waypoints[indexA].Position, m_ControlPoints1[indexA].Position, m_ControlPoints2[indexA].Position, Waypoints[indexB].Position); } } return(transform.TransformPoint(result)); }