public override Vector3 GetInterpolatedPoint(SplineDirection direction, float p, List <SplinePoint> points) { if (direction == SplineDirection.Forward) { for (int i = (int)BottomIndex; i <= TopIndex; i++) { if (p <= points[i].Length) { float t = p / points[i].Length; return(GetInterpolatedPoint(t, points[i - 1], points[i], points[i + 1], points[i + 2])); } p -= points[i].Length; } } else { for (int i = (int)BottomReverseIndex; i >= TopReverseIndex; i--) { if (p <= points[i - 1].Length) { float t = p / points[i - 1].Length; return(GetInterpolatedPoint(1f - t, points[i - 2], points[i - 1], points[i], points[i + 1])); } p -= points[i - 1].Length; } } return(Vector3.Zero); }
/// <summary> /// Gets the next spline point, if false is returned the spline has finished. /// </summary> private bool GetNextPoint() { (SplineDirection Direction, uint Point)? nextPoint = spline.GetNextPoint(direction, point); if (nextPoint == null) { return(false); } direction = nextPoint.Value.Direction; point = nextPoint.Value.Point; remaining = spline.GetNextLength(direction, point); return(true); }
/// <summary> /// Create a new single spline <see cref="SplinePath"/> with supplied <see cref="SplineMode"/> and speed. /// </summary> public SplinePath(ushort splineId, SplineMode mode, float speed) { Type = SplineType.CatmullRom; Mode = mode; Speed = speed; SplineTypeBase splineType = new SplineTypeCatmullRomTbl(); ISplineMode splineMode = GlobalMovementManager.Instance.NewSplineMode(mode); if (splineMode == null) { throw new ArgumentOutOfRangeException(); } spline = new Spline(); spline.Initialise(splineId, splineType, splineMode); direction = splineMode.InitialDirection; point = direction == SplineDirection.Forward ? splineType.BottomIndex : splineType.BottomReverseIndex; remaining = spline.GetNextLength(direction, point); }
/// <summary> /// Create a new custom spline <see cref="SplinePath"/> with supplied <see cref="SplineType"/>, <see cref="SplineMode"/> and speed. /// </summary> public SplinePath(List <Vector3> nodes, SplineType type, SplineMode mode, float speed) { Type = type; Mode = mode; Speed = speed; SplineTypeBase splineType; switch (type) { case SplineType.Linear: splineType = new SplineTypeLinear(); break; case SplineType.CatmullRom: splineType = new SplineTypeCatmullRom(); break; default: throw new ArgumentOutOfRangeException(); } ISplineMode splineMode = GlobalMovementManager.Instance.NewSplineMode(mode); if (splineMode == null) { throw new ArgumentException(); } spline = new Spline(); spline.Initialise(nodes, splineType, splineMode); direction = splineMode.InitialDirection; point = direction == SplineDirection.Forward ? splineType.BottomIndex : splineType.BottomReverseIndex; remaining = spline.GetNextLength(direction, point); }
/// <summary> /// Makes a spline longer. /// </summary> public GameObject[] AddAnchors(int count) { //refs: GameObject anchorTemplate = Resources.Load("Anchor") as GameObject; //if we have no anchors let's make sure we create a spline segment and not just a single anchor: if (Anchors.Length == 0) { count = 2; } //create return array: GameObject[] returnObjects = new GameObject[count]; for (int i = 0; i < count; i++) { //previous anchor refs: Transform previousPreviousAnchor = null; Transform previousAnchor = null; if (Anchors.Length == 1) { previousPreviousAnchor = transform; previousAnchor = Anchors[0].transform; } else if (Anchors.Length > 1) { previousPreviousAnchor = Anchors[Anchors.Length - 2].transform; previousAnchor = Anchors[Anchors.Length - 1].transform; } //create a new anchor: GameObject newAnchor = Instantiate <GameObject>(anchorTemplate); newAnchor.name = newAnchor.name.Replace("(Clone)", ""); SplineAnchor anchor = newAnchor.GetComponent <SplineAnchor>(); anchor.tangentMode = defaultTangentMode; newAnchor.transform.parent = transform; newAnchor.transform.rotation = Quaternion.LookRotation(transform.forward); //tilt tangents for variety as we add new anchors: //anchor.Tilt (new Vector3 (0, 0, 0)); anchor.InTangent.Translate(Vector3.up * .5f); anchor.OutTangent.Translate(Vector3.up * -.5f); //position new anchor: if (previousPreviousAnchor != null && previousAnchor != null) { //determine direction for next placement: Vector3 direction = (previousAnchor.position - previousPreviousAnchor.position).normalized; if (direction == Vector3.zero) { direction = transform.forward; } //place from the previous anchor in the correct direction: newAnchor.transform.position = previousAnchor.transform.position + (direction * 1.5f); } else { newAnchor.transform.localPosition = Vector3.zero; } //catalog this new anchor for return: returnObjects[i] = newAnchor; } return(returnObjects); }
//Loop: void Update() { //place followers (if supplied and something relavent changed): if (followers != null && followers.Length > 0 && Anchors.Length >= 2) { bool needToUpdate = false; //was anything else changed? if (_anchorsChanged || _previousChildCount != transform.childCount || direction != _previousDirection || loop != _previousLoopChoice) { _previousChildCount = transform.childCount; _previousLoopChoice = loop; _previousDirection = direction; _anchorsChanged = false; needToUpdate = true; } //were any followers moved? for (int i = 0; i < followers.Length; i++) { if (followers[i].WasMoved || needToUpdate) { followers[i].UpdateOrientation(this); } } } //manage anchors: if (Anchors.Length > 1) { for (int i = 0; i < Anchors.Length; i++) { //if this spline has changed notify and wipe cached percentage: if (Anchors[i].Changed) { if (OnSplineShapeChanged != null) { OnSplineShapeChanged(); } Anchors[i].Changed = false; _anchorsChanged = true; } //if this isn't a loop then the first and last tangents are unnecessary: if (!loop) { //turn first tangent off: if (i == 0) { Anchors[i].SetTangentStatus(false, true); continue; } //turn last tangent off: if (i == Anchors.Length - 1) { Anchors[i].SetTangentStatus(true, false); continue; } //turn both tangents on: Anchors[i].SetTangentStatus(true, true); } else { //all tangents are needed in a loop: Anchors[i].SetTangentStatus(true, true); } } } }
public (SplineDirection Direction, uint Point)? GetNextPoint(SplineTypeBase type, SplineDirection direction, uint point) { if (point == type.TopReverseIndex) { return(null); } return(direction, point - 1u); }
void Update() { if (followers != null && followers.Length > 0 && Anchors.Length >= 2) { bool needToUpdate = false; if (_anchorsChanged || _previousChildCount != transform.childCount || direction != _previousDirection || loop != _previousLoopChoice) { _previousChildCount = transform.childCount; _previousLoopChoice = loop; _previousDirection = direction; _anchorsChanged = false; needToUpdate = true; } for (int i = 0; i < followers.Length; i++) { if (followers[i].WasMoved || needToUpdate) { followers[i].UpdateOrientation(this); } } } bool anchorChanged = false; if (Anchors.Length > 1) { for (int i = 0; i < Anchors.Length; i++) { if (Anchors[i].Changed) { anchorChanged = true; Anchors[i].Changed = false; _anchorsChanged = true; } if (!loop) { if (i == 0) { Anchors[i].SetTangentStatus(false, true); continue; } if (i == Anchors.Length - 1) { Anchors[i].SetTangentStatus(true, false); continue; } Anchors[i].SetTangentStatus(true, true); } else { Anchors[i].SetTangentStatus(true, true); } } } if (_previousLength != Anchors.Length || anchorChanged) { HangleLengthChange(); _previousLength = Anchors.Length; } }
/// <summary> /// Get the length of the next segment from the specified <see cref="SplineDirection"/> and index. /// </summary> public float GetNextLength(SplineDirection direction, uint point) { SplinePoint p = points[(int)(direction == SplineDirection.Forward ? point : point - 1)]; return(p.Length); }
/// <summary> /// Get the <see cref="SplineDirection"/> and index of the next point from the specified <see cref="SplineDirection"/> and index. /// </summary> public (SplineDirection Direction, uint Point)? GetNextPoint(SplineDirection direction, uint point) { return(mode.GetNextPoint(type, direction, point)); }
/// <summary> /// Get the final point position in the supplied <see cref="SplineDirection"/>. /// </summary> public Vector3 GetFinalPoint(SplineDirection direction) { SplinePoint p = points[(int)(direction == SplineDirection.Forward ? type.TopIndex + 1 : type.TopReverseIndex - 1)]; return(p.Position); }
/// <summary> /// Get the interpolated <see cref="Vector3"/> position in the specified <see cref="SplineDirection"/> at p. /// </summary> public Vector3 GetPosition(SplineDirection direction, float p) { return(type.GetInterpolatedPoint(direction, p, points)); }
public (SplineDirection Direction, uint Point)? GetNextPoint(SplineTypeBase type, SplineDirection direction, uint point) { if (direction == SplineDirection.Forward && point == type.TopIndex) { return(SplineDirection.Backward, type.BottomReverseIndex); } if (direction == SplineDirection.Backward && point == type.TopReverseIndex) { return(SplineDirection.Forward, type.BottomIndex); } return(direction, direction == SplineDirection.Forward ? point + 1 : point - 1); }
/// <summary> /// Get the interpolated <see cref="Vector3"/> between supplied points in <see cref="SplineDirection"/> at normalised (0 - totalLength) position p. /// </summary> public abstract Vector3 GetInterpolatedPoint(SplineDirection direction, float p, List <SplinePoint> points);
public (SplineDirection Direction, uint Point)? GetNextPoint(SplineTypeBase type, SplineDirection direction, uint point) { if (point == type.TopIndex) { return(direction, type.BottomIndex); } return(direction, point + 1u); }