/// <summary> /// Add a key point at a specified index /// </summary> /// <param name="index">The index at which the key point will be added</param> /// <returns>The new key point</returns> public BezierPoint3D AddKeyPointAt(int index) { BezierPoint3D newPoint = new GameObject("Point " + this.KeyPoints.Count, typeof(BezierPoint3D)).GetComponent <BezierPoint3D>(); newPoint.Curve = this; newPoint.transform.parent = this.transform; newPoint.transform.localRotation = Quaternion.identity; if (this.KeyPointsCount == 0 || this.KeyPointsCount == 1) { newPoint.LocalPosition = Vector3.zero; } else { if (index == 0) { newPoint.Position = (this.KeyPoints[0].Position - this.KeyPoints[1].Position).normalized + this.KeyPoints[0].Position; } else if (index == this.KeyPointsCount) { newPoint.Position = (this.KeyPoints[index - 1].Position - this.KeyPoints[index - 2].Position).normalized + this.KeyPoints[index - 1].Position; } else { newPoint.Position = BezierCurve3D.GetPointOnCubicCurve(0.5f, this.KeyPoints[index - 1], this.KeyPoints[index]); } } this.KeyPoints.Insert(index, newPoint); return(newPoint); }
public Vector3 GetNormal(float time, Vector3 up) { BezierPoint3D startPoint; BezierPoint3D endPoint; float timeRelativeToSegment; this.GetCubicSegment(time, out startPoint, out endPoint, out timeRelativeToSegment); return(BezierCurve3D.GetNormalOnCubicCurve(timeRelativeToSegment, up, startPoint, endPoint)); }
public Quaternion GetRotation(float time, Vector3 up) { BezierPoint3D startPoint; BezierPoint3D endPoint; float timeRelativeToSegment; this.GetCubicSegment(time, out startPoint, out endPoint, out timeRelativeToSegment); return(BezierCurve3D.GetRotationOnCubicCurve(timeRelativeToSegment, up, startPoint, endPoint)); }
/// <summary> /// Evaluates a position along the curve at a specified normalized time [0, 1] /// </summary> /// <param name="time">The normalized length at which we want to get a position [0, 1]</param> /// <returns>The evaluated Vector3 position</returns> public Vector3 GetPoint(float time) { // The evaluated points is between these two points BezierPoint3D startPoint; BezierPoint3D endPoint; float timeRelativeToSegment; this.GetCubicSegment(time, out startPoint, out endPoint, out timeRelativeToSegment); return(BezierCurve3D.GetPointOnCubicCurve(timeRelativeToSegment, startPoint, endPoint)); }
public float GetApproximateLength() { float length = 0; int subCurveSampling = (this.Sampling / (this.KeyPointsCount - 1)) + 1; for (int i = 0; i < this.KeyPointsCount - 1; i++) { length += BezierCurve3D.GetApproximateLengthOfCubicCurve(this.KeyPoints[i], this.KeyPoints[i + 1], subCurveSampling); } return(length); }
public void GetCubicSegment(float time, out BezierPoint3D startPoint, out BezierPoint3D endPoint, out float timeRelativeToSegment) { startPoint = null; endPoint = null; timeRelativeToSegment = 0f; float subCurvePercent = 0f; float totalPercent = 0f; float approximateLength = this.GetApproximateLength(); int subCurveSampling = (this.Sampling / (this.KeyPointsCount - 1)) + 1; for (int i = 0; i < this.KeyPointsCount - 1; i++) { subCurvePercent = BezierCurve3D.GetApproximateLengthOfCubicCurve(this.KeyPoints[i], this.KeyPoints[i + 1], subCurveSampling) / approximateLength; if (subCurvePercent + totalPercent > time) { startPoint = this.KeyPoints[i]; endPoint = this.KeyPoints[i + 1]; break; } totalPercent += subCurvePercent; } if (endPoint == null) { // If the evaluated point is very near to the end of the curve we are in the last segment startPoint = this.KeyPoints[this.KeyPointsCount - 2]; endPoint = this.KeyPoints[this.KeyPointsCount - 1]; // We remove the percentage of the last sub-curve totalPercent -= subCurvePercent; } timeRelativeToSegment = (time - totalPercent) / subCurvePercent; }