123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762 |
- using UnityEngine;
- using System;
- using System.Collections.Generic;
- /// <summary>
- /// Collection of methods for working with splines.
- /// This is based on the great learning tutorial Curves and Splines by Jasper Flick.
- ///
- /// References:
- /// http://catlikecoding.com/unity/tutorials/curves-and-splines/
- /// http://answers.unity3d.com/questions/374333/positioning-an-object-on-a-spline-relative-to-play.html
- /// </summary>
- namespace PlaygroundSplines {
- /// <summary>
- /// Holds information about a spline and contains functions for working with the nodes and bezier handles.
- /// </summary>
- [ExecuteInEditMode()]
- public class PlaygroundSpline : MonoBehaviour {
- /// <summary>
- /// The list of nodes and bezier handles making the spline.
- /// </summary>
- [SerializeField]
- private List<Vector3> points = new List<Vector3>();
- /// <summary>
- /// The modes of the bezier handles.
- /// </summary>
- [SerializeField]
- private List<BezierControlPointMode> modes = new List<BezierControlPointMode>();
- /// <summary>
- /// Determines if the spline is looping.
- /// </summary>
- [SerializeField]
- private bool loop;
- /// <summary>
- /// The list of transform nodes to set positions live of an existing node.
- /// </summary>
- [HideInInspector] public List<TransformNode> transformNodes = new List<TransformNode>();
- /// <summary>
- /// Determines if the spline time should be reversed. If you'd like to physically reverse the arrays making the spline then call ReverseAllNodes().
- /// </summary>
- [HideInInspector] public bool reverse;
- /// <summary>
- /// The time offset of the spline.
- /// </summary>
- [HideInInspector] public float timeOffset;
- /// <summary>
- /// The position offset of the spline in relation to its transform.
- /// </summary>
- [HideInInspector] public Vector3 positionOffset;
- [HideInInspector] public Transform splineTransform;
- [HideInInspector] public Matrix4x4 splineTransformMx;
- [HideInInspector] public List<Transform> usedBy = new List<Transform>();
- [HideInInspector] public float fixedVelocityOnNewNode = .5f;
- [HideInInspector] public bool moveTransformsAsBeziers = false;
- [HideInInspector] public bool exportWithNodeStructure = false;
- // Gizmos
- public static bool drawSplinePreviews = true;
- [HideInInspector] public bool drawGizmo = true;
- [HideInInspector] public float bezierWidth = 2f;
- #if UNITY_EDITOR
- void OnDrawGizmos () {
- if (drawSplinePreviews && drawGizmo) {
- Color innerBezier = new Color(1f,1f,1f,1f);
- Color outerBezier = new Color(.5f,.5f,0,.2f);
- Vector3 p0 = ShowPoint(0);
- for (int i = 1; i < ControlPointCount; i += 3) {
- Vector3 p1 = ShowPoint(i);
- Vector3 p2 = ShowPoint(i + 1);
- Vector3 p3 = ShowPoint(i + 2);
- UnityEditor.Handles.DrawBezier(p0, p3, p1, p2, innerBezier, null, bezierWidth);
- UnityEditor.Handles.DrawBezier(p0, p3, p1, p2, outerBezier, null, bezierWidth*10f);
- p0 = p3;
- }
- }
- }
- Vector3 ShowPoint (int index) {
- return transformNodes[index].IsAvailable()? GetPoint(index)+positionOffset : splineTransform.TransformPoint(GetInversePoint(index)+positionOffset);
- }
- #endif
- Vector3 previousPosition;
- Quaternion previousRotation;
- Vector3 previousScale;
- bool isReady;
- public bool IsReady () {
- return isReady;
- }
- /// <summary>
- /// Adds a user to the spline. This helps keeping track of which objects are using the spline.
- /// </summary>
- /// <returns><c>true</c>, if user was added, <c>false</c> otherwise.</returns>
- /// <param name="">.</param>
- public bool AddUser (Transform thisTransform) {
- if (!usedBy.Contains(thisTransform)) {
- usedBy.Add (thisTransform);
- return true;
- }
- return false;
- }
- /// <summary>
- /// Removes a user from the spline. This helps keeping track of which objects are using the spline.
- /// </summary>
- /// <returns><c>true</c>, if user was removed, <c>false</c> otherwise.</returns>
- /// <param name="">.</param>
- public bool RemoveUser (Transform thisTransform) {
- if (usedBy.Contains(thisTransform)) {
- usedBy.Remove (thisTransform);
- return true;
- }
- return false;
- }
- /// <summary>
- /// Determines whether this spline has the user of passed in transform.
- /// </summary>
- /// <returns><c>true</c> if this spline has the user of the passed in transform; otherwise, <c>false</c>.</returns>
- /// <param name="thisTransform">This transform.</param>
- public bool HasUser (Transform thisTransform) {
- return usedBy.Contains (thisTransform);
- }
- /// <summary>
- /// Gets or sets a value indicating whether this <see cref="PlaygroundSplines.PlaygroundSpline"/> is set to loop.
- /// </summary>
- /// <value><c>true</c> if set to loop; otherwise, <c>false</c>.</value>
- public bool Loop {
- get {
- return loop;
- }
- set {
- loop = value;
- if (value == true && NodeCount>1) {
- modes[modes.Count - 1] = modes[0];
- SetControlPoint(0, points[0]);
- }
- }
- }
- /// <summary>
- /// Gets the control point count.
- /// </summary>
- /// <value>The control point count.</value>
- public int ControlPointCount {
- get {
- return points.Count;
- }
- }
- /// <summary>
- /// Gets the control point.
- /// </summary>
- /// <returns>The control point.</returns>
- /// <param name="index">Index.</param>
- public Vector3 GetControlPoint (int index) {
- return GetPoint(index);
- }
- /// <summary>
- /// Sets the control point and withdraws the offset.
- /// </summary>
- /// <param name="index">Index.</param>
- /// <param name="point">Point.</param>
- /// <param name="offset">Offset.</param>
- public void SetControlPoint (int index, Vector3 point, Vector3 offset) {
- SetControlPoint(index, point-offset);
- }
- /// <summary>
- /// Sets the control point.
- /// </summary>
- /// <param name="index">Index.</param>
- /// <param name="point">Position.</param>
- public void SetControlPoint (int index, Vector3 point) {
- if (index<0) index = 0;
- if (index % 3 == 0) {
- Vector3 delta = (point - GetPoint(index));
- Vector3 v;
- if (loop) {
- if (index == 0) {
- //if (!PointHasTransform(1))
- {v = GetPoint(1); SetPoint(1, v+delta);}
- //if (!PointHasTransform(points.Count-2))
- {v = GetPoint(points.Count-2); SetPoint(points.Count-2, v+delta);}
- if (moveTransformsAsBeziers || !PointHasTransform(points.Count-1))
- {SetPoint(points.Count-1, point);}
- } else
- if (index == points.Count - 1) {
- //if (!PointHasTransform(0))
- {SetPoint(0, point);}
- //if (!PointHasTransform(1))
- {v = GetPoint(1); SetPoint(1, v+delta);}
- //if (!PointHasTransform(index-1))
- {v = GetPoint(index-1); SetPoint(index-1, v+delta);}
- } else {
- //if (!PointHasTransform(index-1))
- {v = GetPoint(index-1); SetPoint(index-1, v+delta);}
- //if (!PointHasTransform(index+1))
- {v = GetPoint(index+1); SetPoint(index+1, v+delta);}
- }
- } else {
- if (index > 0) {
- if (moveTransformsAsBeziers || !PointHasTransform(index-1))
- {v = GetPoint(index-1); SetPoint(index-1, v+delta);}
- }
- if (index + 1 < points.Count) {
- if (moveTransformsAsBeziers || !PointHasTransform(index+1))
- {v = GetPoint(index+1); SetPoint(index+1, v+delta);}
- }
- }
- }
- SetPoint(index, point);
- EnforceMode(index);
- }
- /// <summary>
- /// Sets all points from an array. Please ensure the same length of your passed in vectors as PlaygroundSpline.ControlPointCount.
- /// </summary>
- /// <param name="vectors">Vectors.</param>
- public void SetPoints (Vector3[] vectors) {
- if (vectors.Length!=points.Count) {
- Debug.Log ("Please ensure the same length of your passed in vectors ("+vectors.Length+") as the current points ("+points.Count+"). Use PlaygroundSpline.ControlPointCount to get the current count.");
- return;
- }
- for (int i = 0; i<points.Count; i++) {
- points[i] = vectors[i];
- }
- }
- public bool PointHasTransform (int index) {
- return transformNodes[index].IsAvailable();
- }
- /// <summary>
- /// Moves the entire spline separate from its transform component. Use this if you'd like to offset the spline from its transform separately from the positionOffset.
- /// </summary>
- /// <param name="translation">The amount to move the spline in Units.</param>
- public void TranslateSpline (Vector3 translation) {
- for (int i = 0; i<points.Count; i++) {
- points[i] += translation;
- }
- }
- public Vector3 GetTransformPosition () {
- return previousPosition;
- }
- public Quaternion GetTransformRotation () {
- return previousRotation;
- }
- public Vector3 GetTransformScale () {
- return previousScale;
- }
-
- public BezierControlPointMode GetControlPointMode (int index) {
- return modes[(index + 1) / 3];
- }
-
- public void SetControlPointMode (int index, BezierControlPointMode mode) {
- int modeIndex = (index + 1) / 3;
- modes[modeIndex] = mode;
- if (loop) {
- if (modeIndex == 0) {
- modes[modes.Count - 1] = mode;
- }
- else if (modeIndex == modes.Count - 1) {
- modes[0] = mode;
- }
- }
- EnforceMode(index);
- }
-
- private void EnforceMode (int index) {
- int modeIndex = (index+1) / 3;
- BezierControlPointMode mode = modes[modeIndex];
- if (mode == BezierControlPointMode.Free || !loop && (modeIndex == 0 || modeIndex == modes.Count - 1)) {
- return;
- }
-
- int middleIndex = modeIndex * 3;
- int fixedIndex, enforcedIndex;
- if (index <= middleIndex) {
- fixedIndex = middleIndex - 1;
- if (fixedIndex < 0) {
- fixedIndex = points.Count - 2;
- }
- enforcedIndex = middleIndex + 1;
- if (enforcedIndex >= points.Count) {
- enforcedIndex = 1;
- }
- }
- else {
- fixedIndex = middleIndex + 1;
- if (fixedIndex >= points.Count) {
- fixedIndex = 1;
- }
- enforcedIndex = middleIndex - 1;
- if (enforcedIndex < 0) {
- enforcedIndex = points.Count - 2;
- }
- }
-
- Vector3 middle = GetPoint(middleIndex);
- Vector3 enforcedTangent = middle - GetPoint(fixedIndex);
- if (mode == BezierControlPointMode.Aligned) {
- enforcedTangent = enforcedTangent.normalized * Vector3.Distance(middle, GetPoint(enforcedIndex));
- }
- if (moveTransformsAsBeziers || !PointHasTransform(enforcedIndex))
- SetPoint(enforcedIndex, middle + enforcedTangent);
- }
-
- public int NodeCount {
- get {
- return (points.Count - 1) / 3;
- }
- }
- /// <summary>
- /// Get position from time.
- /// </summary>
- /// <returns>The point in world space.</returns>
- /// <param name="t">Time.</param>
- public Vector3 GetPoint (float t) {
- int i;
- if (reverse) {
- t = 1f-t;
- t = (t-timeOffset)%1f;
- if (t<0)
- t = 1f+t;
- } else t = (t+timeOffset)%1f;
- if (t >= 1f) {
- //t = 1f;
- i = points.Count - 4;
- }
- else {
- t = Mathf.Clamp01(t) * NodeCount;
- i = (int)t;
- t -= i;
- i *= 3;
- }
- return splineTransformMx.MultiplyPoint3x4(Bezier.GetPoint(GetInversePoint(i), GetInversePoint(i + 1), GetInversePoint(i + 2), GetInversePoint(i + 3), t)+positionOffset);
- }
- public Vector3 GetVelocity (float t) {
- int i;
- if (reverse)
- t = 1f-t;
- t = (t+timeOffset)%1f;
- if (t >= 1f) {
- t = 1f;
- i = points.Count - 4;
- }
- else {
- t = Mathf.Clamp01(t) * NodeCount;
- i = (int)t;
- t -= i;
- i *= 3;
- }
- return splineTransformMx.MultiplyPoint3x4(Bezier.GetFirstDerivative(GetInversePoint(i), GetInversePoint(i + 1), GetInversePoint(i + 2), GetInversePoint(i + 3), t)+positionOffset) - previousPosition;
- }
- /// <summary>
- /// Get position from node index in the spline. If the node consists of an available transform its position will be returned, otherwise the user-specified Vector3 position.
- /// </summary>
- /// <returns>The point in world space.</returns>
- /// <param name="index">Index.</param>
- public Vector3 GetPoint (int index) {
- if (transformNodes[index].IsAvailable())
- return transformNodes[index].GetPosition();
- else return points[index];
- }
- public Vector3 GetInversePoint (int index) {
- if (transformNodes[index].IsAvailable())
- return transformNodes[index].GetInvsersePosition();
- else return points[index];
- }
- public Vector3 GetPointWorldSpace (int index) {
- if (transformNodes[index].IsAvailable())
- return transformNodes[index].GetPosition();
- else return splineTransformMx.MultiplyPoint3x4(points[index]+positionOffset);
- }
- /// <summary>
- /// Sets a point to specified position.
- /// </summary>
- /// <param name="index">Index.</param>
- /// <param name="position">Position.</param>
- void SetPoint (int index, Vector3 position) {
- if (transformNodes[index].IsAvailable())
- transformNodes[index].SetPosition(position);
- else points[index] = position;
- }
- /// <summary>
- /// Translates a point.
- /// </summary>
- /// <param name="index">Index.</param>
- /// <param name="translation">Translation.</param>
- void TranslatePoint (int index, Vector3 translation) {
- if (transformNodes[index].IsAvailable())
- transformNodes[index].Translate(translation);
- else points[index] += translation;
- }
- // Calculates the best fitting time in the given interval
- private float CPOB(Vector3 aP, float aStart, float aEnd, int aSteps)
- {
- aStart = Mathf.Clamp01(aStart);
- aEnd = Mathf.Clamp01(aEnd);
- float step = (aEnd-aStart) / (float)aSteps;
- float Res = 0;
- float Ref = float.MaxValue;
- for (int i = 0; i < aSteps; i++)
- {
- float t = aStart + step*i;
- float L = (GetPoint(t)-aP).sqrMagnitude;
- if (L < Ref)
- {
- Ref = L;
- Res = t;
- }
- }
- return Res;
- }
-
- public float ClosestTimeFromPoint (Vector3 aP) {
- float t = CPOB(aP, 0, 1, 10);
- float delta = 1.0f / 10.0f;
- for (int i = 0; i < 4; i++)
- {
- t = CPOB(aP, t - delta, t + delta, 10);
- delta /= 9;
- }
- return t;
- }
-
- public Vector3 ClosestPointFromPosition (Vector3 aP) {
- return GetPoint(ClosestTimeFromPoint(aP));
- }
- public Vector3 GetDirection (float t) {
- return (GetPoint(t+.001f)-GetPoint(t)).normalized;
- }
- /// <summary>
- /// Adds a node at the last position of the node index.
- /// </summary>
- public void AddNode () {
- AddNode ((points.Count-1)/3);
- }
- /// <summary>
- /// Adds a node at specified node index.
- /// </summary>
- /// <param name="index">Index.</param>
- public void AddNode (int index) {
- int nodeIndex = index*3;
- Vector3 point = GetPoint(nodeIndex);
- Vector3 direction;
- if (index>0) {
- direction = GetPoint(nodeIndex)-GetPoint(nodeIndex-1);
- } else direction = GetPoint(nodeIndex+1)-GetPoint(nodeIndex);
- direction*=fixedVelocityOnNewNode;
- points.InsertRange(nodeIndex+1, new Vector3[3]);
- point += direction;
- points[nodeIndex+2] = point;
- point += direction;
- points[nodeIndex+1] = point;
- point += direction;
- points[nodeIndex+3] = point;
- transformNodes.InsertRange(nodeIndex+1, new TransformNode[]{new TransformNode(), new TransformNode(), new TransformNode()});
- BezierControlPointMode currentIndexMode = modes[index];
- modes.Insert (index, new BezierControlPointMode());
- modes[index] = currentIndexMode;
- EnforceMode(index);
- SetControlPoint((index+1)*3, GetPoint((index+1)*3));
-
- if (loop) {
- points[points.Count - 1] = points[0];
- modes[modes.Count - 1] = modes[0];
- EnforceMode(0);
- }
- }
- /// <summary>
- /// Removes the first node in the node index.
- /// </summary>
- public void RemoveFirst () {
- RemoveNode(0);
- }
- /// <summary>
- /// Removes the last node in the node index.
- /// </summary>
- public void RemoveLast () {
- RemoveNode((points.Count-1)/3);
- }
- /// <summary>
- /// Removes a node at specified node index.
- /// </summary>
- /// <param name="index">Index.</param>
- public void RemoveNode (int index) {
- index = Mathf.Clamp (index, 0, points.Count-1);
- int pointIndex = index*3;
- if (points.Count<=4) return;
- if (pointIndex<points.Count-1) {
- points.RemoveRange(pointIndex, 3);
- transformNodes.RemoveRange(pointIndex, 3);
- } else {
- points.RemoveRange(pointIndex-2, 3);
- transformNodes.RemoveRange(pointIndex-2, 3);
- }
- modes.RemoveAt (index);
- EnforceMode (index-1);
- if (index>0)
- SetControlPoint((index-1)*3, GetPoint((index-1)*3));
- else
- SetControlPoint(0, GetPoint(0));
- }
- /// <summary>
- /// Reverses all nodes in the node index.
- /// </summary>
- public void ReverseAllNodes () {
- points.Reverse();
- transformNodes.Reverse();
- modes.Reverse();
- }
- public void SwapNodes (int from, int to) {
- Vector3[] fromPoints = points.GetRange (from, 3).ToArray();
- Vector3[] toPoints = points.GetRange (to, 3).ToArray();
- TransformNode[] fromTnode = transformNodes.GetRange (from, 3).ToArray();
- TransformNode[] toTnode = transformNodes.GetRange (to, 3).ToArray();
- BezierControlPointMode fromMode = modes[from];
- BezierControlPointMode toMode = modes[to];
- for (int i = from; i<3; i++) {
- points[i] = toPoints[i];
- transformNodes[i] = toTnode[i];
- }
- for (int i = to; i<3; i++) {
- points[i] = fromPoints[i];
- transformNodes[i] = fromTnode[i];
- }
- modes[from] = toMode;
- modes[to] = fromMode;
- }
- /// <summary>
- /// Exports all nodes to Transform[]. Enable exportWithNodeStructure to parent each bezier handle to their node.
- /// </summary>
- /// <returns>A built-in array of Transforms.</returns>
- public Transform[] ExportToTransforms () {
- Transform[] transforms = new Transform[points.Count];
- for (int i = 0; i<points.Count; i++) {
- int iNode = (i+1)/3;
- int iBezier = i<3?0:(((i)%3))%2;
- bool iIsNode = i==0||i%3==0;
- transforms[i] = new GameObject(iIsNode?"Node "+iNode:"Node "+iNode+" - Bezier "+iBezier).transform;
- transforms[i].parent = splineTransform;
- transforms[i].position = splineTransform.TransformPoint(GetInversePoint(i)+positionOffset);
- }
- if (exportWithNodeStructure) {
- for (int i = 2; i<transforms.Length; i++) {
- int iBezier = i<3?0:(((i)%3))%2;
- bool iIsNode = i==0||i%3==0;
- if (!iIsNode)
- transforms[i].parent = transforms[iBezier==0?i+1:i-1];
- }
- transforms[1].parent = transforms[0];
- }
- return transforms;
- }
- /// <summary>
- /// Exports all nodes to Vector3[].
- /// </summary>
- /// <returns>A built-in array of Vector3</returns>
- public Vector3[] ExportToVector3 () {
- Vector3[] vectors = new Vector3[points.Count];
- for (int i = 0; i<points.Count; i++) {
- vectors[i] = GetPoint(i)+positionOffset;
- }
- return vectors;
- }
- /// <summary>
- /// Reset this Playground Spline. Two nodes and two bezier handles will be created.
- /// </summary>
- public void Reset () {
- points = new List<Vector3> {
- new Vector3(1f, 0f, 0f),
- new Vector3(2f, 0f, 0f),
- new Vector3(3f, 0f, 0f),
- new Vector3(4f, 0f, 0f)
- };
- modes = new List<BezierControlPointMode> {
- BezierControlPointMode.Aligned,
- BezierControlPointMode.Aligned
- };
- transformNodes = new List<TransformNode> {
- new TransformNode(),
- new TransformNode(),
- new TransformNode(),
- new TransformNode()
- };
- }
- /*************************************************************************************************************************************************
- MonoBehaviours
- *************************************************************************************************************************************************/
- void OnEnable () {
- isReady = false;
- splineTransform = transform;
- SetMatrix();
- }
- void Update () {
- SetMatrix();
- for (int i = 0; i<transformNodes.Count; i++)
- transformNodes[i].Update(splineTransform);
- }
- void SetMatrix () {
- if (previousPosition!=splineTransform.position || previousRotation!=splineTransform.rotation || previousScale!=splineTransform.localScale)
- splineTransformMx.SetTRS(splineTransform.position, splineTransform.rotation, splineTransform.localScale);
- previousPosition = splineTransform.position;
- previousRotation = splineTransform.rotation;
- previousScale = splineTransform.localScale;
- isReady = true;
- }
- }
- /// <summary>
- /// Class for common bezier operations on a spline.
- /// </summary>
- public static class Bezier {
-
- public static Vector3 GetPoint (Vector3 p0, Vector3 p1, Vector3 p2, float t) {
- t = Mathf.Clamp01(t);
- float oneMinusT = 1f - t;
- return
- oneMinusT * oneMinusT * p0 +
- 2f * oneMinusT * t * p1 +
- t * t * p2;
- }
-
- public static Vector3 GetFirstDerivative (Vector3 p0, Vector3 p1, Vector3 p2, float t) {
- return
- 2f * (1f - t) * (p1 - p0) +
- 2f * t * (p2 - p1);
- }
-
- public static Vector3 GetPoint (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) {
- t = Mathf.Clamp01(t);
- float OneMinusT = 1f - t;
- return
- OneMinusT * OneMinusT * OneMinusT * p0 +
- 3f * OneMinusT * OneMinusT * t * p1 +
- 3f * OneMinusT * t * t * p2 +
- t * t * t * p3;
- }
-
- public static Vector3 GetFirstDerivative (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) {
- t = Mathf.Clamp01(t);
- float oneMinusT = 1f - t;
- return
- 3f * oneMinusT * oneMinusT * (p1 - p0) +
- 6f * oneMinusT * t * (p2 - p1) +
- 3f * t * t * (p3 - p2);
- }
- }
- [Serializable]
- public class TransformNode {
- public bool enabled;
- public Transform transform;
- bool isAvailable;
- Vector3 position;
- Vector3 inversePosition;
- Vector3 previousPosition;
- public bool Update (Transform splineTransform) {
- if (enabled && transform!=null) {
- previousPosition = position;
- position = transform.position;
- inversePosition = splineTransform.InverseTransformPoint(transform.position);
- isAvailable = true;
- return true;
- }
- isAvailable = false;
- return false;
- }
- public bool IsAvailable () {
- return enabled&&isAvailable;
- }
- public Vector3 GetPosition () {
- return position;
- }
- public Vector3 GetInvsersePosition () {
- return inversePosition;
- }
- public void SetPosition (Vector3 newPosition) {
- if (transform==null) return;
- transform.position = newPosition;
- }
- public void Translate (Vector3 translation) {
- if (transform==null) return;
- transform.position += translation;
- }
- public Vector3 GetPositionDelta () {
- return previousPosition-position;
- }
- }
- public enum SplineMode {
- Vector3,
- Transform
- }
- /// <summary>
- /// The bezier mode for a spline node. This controls how one bezier handle acts in relation to the other.
- /// </summary>
- public enum BezierControlPointMode {
- /// <summary>
- /// Align the angle between the two bezier handles but keep individual lengths. Has a differential smooth in and out angle.
- /// </summary>
- Aligned,
- /// <summary>
- /// Align the angle and length between the two bezier handles. Has an equally smooth in and out angle.
- /// </summary>
- Mirrored,
- /// <summary>
- /// Bezier handles are freely aligned without consideration to the other. Ables you to have sharp angles.
- /// </summary>
- Free
- }
- }
|