2 using UnityEngine
.Assertions
;
4 namespace UnityEngine
.Rendering
.PostProcessing
7 /// A wrapper on top of <see cref="AnimationCurve"/> to handle zero-key curves and keyframe
11 public sealed class Spline
14 /// Precision of the curve.
16 public const int k_Precision
= 128;
19 /// The inverse of the precision of the curve.
21 public const float k_Step
= 1f
/ k_Precision
;
24 /// The underlying animation curve instance.
26 public AnimationCurve curve
;
37 AnimationCurve m_InternalLoopingCurve
;
39 // Used to track frame changes for data caching
43 /// An array holding pre-computed curve values.
45 public float[] cachedData
;
48 /// Creates a new spline.
50 /// <param name="curve">The animation curve to base this spline off</param>
51 /// <param name="zeroValue">The value to return when the curve has no keyframe</param>
52 /// <param name="loop">Should this curve loop?</param>
53 /// <param name="bounds">The curve bounds</param>
54 public Spline(AnimationCurve curve
, float zeroValue
, bool loop
, Vector2 bounds
)
56 Assert
.IsNotNull(curve
);
58 m_ZeroValue
= zeroValue
;
60 m_Range
= bounds
.magnitude
;
61 cachedData
= new float[k_Precision
];
65 /// Caches the curve data at a given frame. The curve data will only be cached once per
68 /// <param name="frame">A frame number</param>
69 public void Cache(int frame
)
71 // Note: it would be nice to have a way to check if a curve has changed in any way, that
72 // would save quite a few CPU cycles instead of having to force cache it once per frame :/
74 // Only cache once per frame
75 if (frame
== frameCount
)
78 var length
= curve
.length
;
80 if (m_Loop
&& length
> 1)
82 if (m_InternalLoopingCurve
== null)
83 m_InternalLoopingCurve
= new AnimationCurve();
85 var prev
= curve
[length
- 1];
89 m_InternalLoopingCurve
.keys
= curve
.keys
;
90 m_InternalLoopingCurve
.AddKey(prev
);
91 m_InternalLoopingCurve
.AddKey(next
);
94 for (int i
= 0; i
< k_Precision
; i
++)
95 cachedData
[i
] = Evaluate((float)i
* k_Step
, length
);
97 frameCount
= Time
.renderedFrameCount
;
101 /// Evaluates the curve at a point in time.
103 /// <param name="t">The time to evaluate</param>
104 /// <param name="length">The number of keyframes in the curve</param>
105 /// <returns>The value of the curve at time <paramref name="t"/></returns>
106 public float Evaluate(float t
, int length
)
111 if (!m_Loop
|| length
== 1)
112 return curve
.Evaluate(t
);
114 return m_InternalLoopingCurve
.Evaluate(t
);
118 /// Evaluates the curve at a point in time.
120 /// <param name="t">The time to evaluate</param>
121 /// <returns>The value of the curve at time <paramref name="t"/></returns>
123 /// Calling the length getter on a curve is expensive to it's better to cache its length and
124 /// call <see cref="Evaluate(float,int)"/> instead of getting the length for every call.
126 public float Evaluate(float t
)
128 // Calling the length getter on a curve is expensive (!?) so it's better to cache its
129 // length and call Evaluate(t, length) instead of getting the length for every call to
131 return Evaluate(t
, curve
.length
);
135 /// Returns the computed hash code for this parameter.
137 /// <returns>A computed hash code</returns>
138 public override int GetHashCode()
143 hash
= hash
* 23 + curve
.GetHashCode(); // Not implemented in Unity, so it'll always return the same value :(