Refactor Bezier splines drawing and editing to property evaluate value and match curve evaluation
#3051
This commit is contained in:
@@ -66,27 +66,23 @@ namespace AnimationUtils
|
||||
}
|
||||
|
||||
template<class T>
|
||||
FORCE_INLINE static void GetTangent(const T& a, const T& b, float length, T& result)
|
||||
FORCE_INLINE static void GetTangent(const T& value, const T& tangent, float tangentScale, T& result)
|
||||
{
|
||||
const float oneThird = 1.0f / 3.0f;
|
||||
result = a + b * (length * oneThird);
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
template<>
|
||||
FORCE_INLINE void GetTangent<Quaternion>(const Quaternion& a, const Quaternion& b, float length, Quaternion& result)
|
||||
FORCE_INLINE void GetTangent<Quaternion>(const Quaternion& value, const Quaternion& tangent, float tangentScale, Quaternion& result)
|
||||
{
|
||||
const float oneThird = 1.0f / 3.0f;
|
||||
Quaternion::Slerp(a, b, oneThird, result);
|
||||
Quaternion::Slerp(value, tangent, 1.0f / 3.0f, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
FORCE_INLINE void GetTangent<Transform>(const Transform& a, const Transform& b, float length, Transform& result)
|
||||
FORCE_INLINE void GetTangent<Transform>(const Transform& value, const Transform& tangent, float tangentScale, Transform& result)
|
||||
{
|
||||
const float oneThird = 1.0f / 3.0f;
|
||||
const float oneThirdLength = length * oneThird;
|
||||
result.Translation = a.Translation + b.Translation * oneThirdLength;
|
||||
Quaternion::Slerp(a.Orientation, b.Orientation, oneThird, result.Orientation);
|
||||
result.Scale = a.Scale + (b.Scale - a.Scale) * oneThirdLength;
|
||||
GetTangent(value.Translation, tangent.Translation, tangentScale, result.Translation);
|
||||
GetTangent(value.Orientation, tangent.Orientation, tangentScale, result.Orientation);
|
||||
GetTangent(value.Scale, tangent.Scale, tangentScale, result.Scale);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
||||
@@ -24,9 +24,9 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="tangent">The tangent.</param>
|
||||
/// <param name="lengthThird">The length divided by 3.</param>
|
||||
/// <param name="tangentScale">The tangent scale factor.</param>
|
||||
/// <param name="result">The result.</param>
|
||||
void GetTangent(ref U value, ref U tangent, float lengthThird, out U result);
|
||||
void GetTangent(ref U value, ref U tangent, float tangentScale, out U result);
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the linear interpolation at the specified alpha.
|
||||
@@ -67,7 +67,7 @@ namespace FlaxEngine
|
||||
IKeyframeAccess<Color32>,
|
||||
IKeyframeAccess<Color>
|
||||
{
|
||||
public void GetTangent(ref bool value, ref bool tangent, float lengthThird, out bool result)
|
||||
public void GetTangent(ref bool value, ref bool tangent, float tangentScale, out bool result)
|
||||
{
|
||||
result = value;
|
||||
}
|
||||
@@ -82,9 +82,9 @@ namespace FlaxEngine
|
||||
result = p0;
|
||||
}
|
||||
|
||||
public void GetTangent(ref int value, ref int tangent, float lengthThird, out int result)
|
||||
public void GetTangent(ref int value, ref int tangent, float tangentScale, out int result)
|
||||
{
|
||||
result = value + (int)(tangent * lengthThird);
|
||||
result = value + (int)(tangent * tangentScale);
|
||||
}
|
||||
|
||||
public void Linear(ref int a, ref int b, float alpha, out int result)
|
||||
@@ -102,9 +102,9 @@ namespace FlaxEngine
|
||||
result = Mathf.Lerp(p012, p123, alpha);
|
||||
}
|
||||
|
||||
public void GetTangent(ref double value, ref double tangent, float lengthThird, out double result)
|
||||
public void GetTangent(ref double value, ref double tangent, float tangentScale, out double result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref double a, ref double b, float alpha, out double result)
|
||||
@@ -122,9 +122,9 @@ namespace FlaxEngine
|
||||
result = Mathf.Lerp(p012, p123, alpha);
|
||||
}
|
||||
|
||||
public void GetTangent(ref float value, ref float tangent, float lengthThird, out float result)
|
||||
public void GetTangent(ref float value, ref float tangent, float tangentScale, out float result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref float a, ref float b, float alpha, out float result)
|
||||
@@ -142,9 +142,9 @@ namespace FlaxEngine
|
||||
result = Mathf.Lerp(p012, p123, alpha);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Vector2 value, ref Vector2 tangent, float lengthThird, out Vector2 result)
|
||||
public void GetTangent(ref Vector2 value, ref Vector2 tangent, float tangentScale, out Vector2 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Vector2 a, ref Vector2 b, float alpha, out Vector2 result)
|
||||
@@ -162,9 +162,9 @@ namespace FlaxEngine
|
||||
Vector2.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Vector3 value, ref Vector3 tangent, float lengthThird, out Vector3 result)
|
||||
public void GetTangent(ref Vector3 value, ref Vector3 tangent, float tangentScale, out Vector3 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Vector3 a, ref Vector3 b, float alpha, out Vector3 result)
|
||||
@@ -182,9 +182,9 @@ namespace FlaxEngine
|
||||
Vector3.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Vector4 value, ref Vector4 tangent, float lengthThird, out Vector4 result)
|
||||
public void GetTangent(ref Vector4 value, ref Vector4 tangent, float tangentScale, out Vector4 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Vector4 a, ref Vector4 b, float alpha, out Vector4 result)
|
||||
@@ -202,9 +202,9 @@ namespace FlaxEngine
|
||||
Vector4.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Float2 value, ref Float2 tangent, float lengthThird, out Float2 result)
|
||||
public void GetTangent(ref Float2 value, ref Float2 tangent, float tangentScale, out Float2 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Float2 a, ref Float2 b, float alpha, out Float2 result)
|
||||
@@ -222,9 +222,9 @@ namespace FlaxEngine
|
||||
Float2.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Float3 value, ref Float3 tangent, float lengthThird, out Float3 result)
|
||||
public void GetTangent(ref Float3 value, ref Float3 tangent, float tangentScale, out Float3 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Float3 a, ref Float3 b, float alpha, out Float3 result)
|
||||
@@ -242,9 +242,9 @@ namespace FlaxEngine
|
||||
Float3.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Float4 value, ref Float4 tangent, float lengthThird, out Float4 result)
|
||||
public void GetTangent(ref Float4 value, ref Float4 tangent, float tangentScale, out Float4 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Float4 a, ref Float4 b, float alpha, out Float4 result)
|
||||
@@ -262,9 +262,9 @@ namespace FlaxEngine
|
||||
Float4.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Double2 value, ref Double2 tangent, float lengthThird, out Double2 result)
|
||||
public void GetTangent(ref Double2 value, ref Double2 tangent, float tangentScale, out Double2 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Double2 a, ref Double2 b, float alpha, out Double2 result)
|
||||
@@ -282,9 +282,9 @@ namespace FlaxEngine
|
||||
Double2.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Double3 value, ref Double3 tangent, float lengthThird, out Double3 result)
|
||||
public void GetTangent(ref Double3 value, ref Double3 tangent, float tangentScale, out Double3 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Double3 a, ref Double3 b, float alpha, out Double3 result)
|
||||
@@ -302,9 +302,9 @@ namespace FlaxEngine
|
||||
Double3.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Double4 value, ref Double4 tangent, float lengthThird, out Double4 result)
|
||||
public void GetTangent(ref Double4 value, ref Double4 tangent, float tangentScale, out Double4 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Double4 a, ref Double4 b, float alpha, out Double4 result)
|
||||
@@ -322,7 +322,7 @@ namespace FlaxEngine
|
||||
Double4.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Quaternion value, ref Quaternion tangent, float lengthThird, out Quaternion result)
|
||||
public void GetTangent(ref Quaternion value, ref Quaternion tangent, float tangentScale, out Quaternion result)
|
||||
{
|
||||
Quaternion.Slerp(ref value, ref tangent, 1.0f / 3.0f, out result);
|
||||
}
|
||||
@@ -342,9 +342,9 @@ namespace FlaxEngine
|
||||
Quaternion.Slerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Color32 value, ref Color32 tangent, float lengthThird, out Color32 result)
|
||||
public void GetTangent(ref Color32 value, ref Color32 tangent, float tangentScale, out Color32 result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Color32 a, ref Color32 b, float alpha, out Color32 result)
|
||||
@@ -362,9 +362,9 @@ namespace FlaxEngine
|
||||
Color32.Lerp(ref p012, ref p123, alpha, out result);
|
||||
}
|
||||
|
||||
public void GetTangent(ref Color value, ref Color tangent, float lengthThird, out Color result)
|
||||
public void GetTangent(ref Color value, ref Color tangent, float tangentScale, out Color result)
|
||||
{
|
||||
result = value + tangent * lengthThird;
|
||||
result = value + tangent * tangentScale;
|
||||
}
|
||||
|
||||
public void Linear(ref Color a, ref Color b, float alpha, out Color result)
|
||||
@@ -860,9 +860,9 @@ namespace FlaxEngine
|
||||
|
||||
// Evaluate the key at the curve
|
||||
result.Time = leftKey.Time + length * t;
|
||||
float lengthThird = length / 3.0f;
|
||||
_accessor.GetTangent(ref leftKey.Value, ref leftKey.TangentOut, lengthThird, out var leftTangent);
|
||||
_accessor.GetTangent(ref rightKey.Value, ref rightKey.TangentIn, lengthThird, out var rightTangent);
|
||||
float tangentScale = length / 3.0f;
|
||||
_accessor.GetTangent(ref leftKey.Value, ref leftKey.TangentOut, tangentScale, out var leftTangent);
|
||||
_accessor.GetTangent(ref rightKey.Value, ref rightKey.TangentIn, tangentScale, out var rightTangent);
|
||||
_accessor.Bezier(ref leftKey.Value, ref leftTangent, ref rightTangent, ref rightKey.Value, t, out result.Value);
|
||||
result.TangentIn = leftKey.TangentOut;
|
||||
result.TangentOut = rightKey.TangentIn;
|
||||
@@ -895,9 +895,9 @@ namespace FlaxEngine
|
||||
float t = Mathf.NearEqual(length, 0.0f) ? 0.0f : (time - leftKey.Time) / length;
|
||||
|
||||
// Evaluate the value at the curve
|
||||
float lengthThird = length / 3.0f;
|
||||
_accessor.GetTangent(ref leftKey.Value, ref leftKey.TangentOut, lengthThird, out var leftTangent);
|
||||
_accessor.GetTangent(ref rightKey.Value, ref rightKey.TangentIn, lengthThird, out var rightTangent);
|
||||
float tangentScale = length / 3.0f;
|
||||
_accessor.GetTangent(ref leftKey.Value, ref leftKey.TangentOut, tangentScale, out var leftTangent);
|
||||
_accessor.GetTangent(ref rightKey.Value, ref rightKey.TangentIn, tangentScale, out var rightTangent);
|
||||
_accessor.Bezier(ref leftKey.Value, ref leftTangent, ref rightTangent, ref rightKey.Value, t, out result);
|
||||
}
|
||||
|
||||
|
||||
@@ -247,16 +247,18 @@ public:
|
||||
static void Interpolate(const BezierCurveKeyframe& a, const BezierCurveKeyframe& b, float alpha, float length, T& result)
|
||||
{
|
||||
T leftTangent, rightTangent;
|
||||
AnimationUtils::GetTangent(a.Value, a.TangentOut, length, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value, b.TangentIn, length, rightTangent);
|
||||
const float tangentScale = length / 3.0f;
|
||||
AnimationUtils::GetTangent(a.Value, a.TangentOut, tangentScale, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value, b.TangentIn, tangentScale, rightTangent);
|
||||
AnimationUtils::Bezier(a.Value, leftTangent, rightTangent, b.Value, alpha, result);
|
||||
}
|
||||
|
||||
static void InterpolateFirstDerivative(const BezierCurveKeyframe& a, const BezierCurveKeyframe& b, float alpha, float length, T& result)
|
||||
{
|
||||
T leftTangent, rightTangent;
|
||||
AnimationUtils::GetTangent(a.Value, a.TangentOut, length, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value, b.TangentIn, length, rightTangent);
|
||||
const float tangentScale = length / 3.0f;
|
||||
AnimationUtils::GetTangent(a.Value, a.TangentOut, tangentScale, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value, b.TangentIn, tangentScale, rightTangent);
|
||||
AnimationUtils::BezierFirstDerivative(a.Value, leftTangent, rightTangent, b.Value, alpha, result);
|
||||
}
|
||||
|
||||
@@ -264,8 +266,9 @@ public:
|
||||
{
|
||||
result.Time = a.Time + length * alpha;
|
||||
T leftTangent, rightTangent;
|
||||
AnimationUtils::GetTangent(a.Value, a.TangentOut, length, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value, b.TangentIn, length, rightTangent);
|
||||
const float tangentScale = length / 3.0f;
|
||||
AnimationUtils::GetTangent(a.Value, a.TangentOut, tangentScale, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value, b.TangentIn, tangentScale, rightTangent);
|
||||
AnimationUtils::Bezier(a.Value, leftTangent, rightTangent, b.Value, alpha, result.Value);
|
||||
result.TangentIn = a.TangentOut;
|
||||
result.TangentOut = b.TangentIn;
|
||||
|
||||
@@ -158,10 +158,10 @@ float Spline::GetSplineLength() const
|
||||
const auto& b = Curve[i];
|
||||
Vector3 prevPoint = a.Value.Translation * scale;
|
||||
|
||||
const float length = Math::Abs(b.Time - a.Time);
|
||||
const float tangentScale = Math::Abs(b.Time - a.Time) / 3.0f;
|
||||
Vector3 leftTangent, rightTangent;
|
||||
AnimationUtils::GetTangent(a.Value.Translation, a.TangentOut.Translation, length, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value.Translation, b.TangentIn.Translation, length, rightTangent);
|
||||
AnimationUtils::GetTangent(a.Value.Translation, a.TangentOut.Translation, tangentScale, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value.Translation, b.TangentIn.Translation, tangentScale, rightTangent);
|
||||
|
||||
for (int32 slice = 1; slice < slices; slice++)
|
||||
{
|
||||
@@ -189,10 +189,10 @@ float Spline::GetSplineSegmentLength(int32 index) const
|
||||
const Vector3 scale = _transform.Scale;
|
||||
Vector3 prevPoint = a.Value.Translation * scale;
|
||||
{
|
||||
const float length = Math::Abs(b.Time - a.Time);
|
||||
const float tangentScale = Math::Abs(b.Time - a.Time) / 3.0f;
|
||||
Vector3 leftTangent, rightTangent;
|
||||
AnimationUtils::GetTangent(a.Value.Translation, a.TangentOut.Translation, length, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value.Translation, b.TangentIn.Translation, length, rightTangent);
|
||||
AnimationUtils::GetTangent(a.Value.Translation, a.TangentOut.Translation, tangentScale, leftTangent);
|
||||
AnimationUtils::GetTangent(b.Value.Translation, b.TangentIn.Translation, tangentScale, rightTangent);
|
||||
|
||||
for (int32 slice = 1; slice < slices; slice++)
|
||||
{
|
||||
|
||||
@@ -184,9 +184,9 @@ void SplineModel::OnSplineUpdated()
|
||||
auto& instance = _instances[segment];
|
||||
const auto& start = keyframes[segment];
|
||||
const auto& end = keyframes[segment + 1];
|
||||
const float length = end.Time - start.Time;
|
||||
AnimationUtils::GetTangent(start.Value, start.TangentOut, length, leftTangent);
|
||||
AnimationUtils::GetTangent(end.Value, end.TangentIn, length, rightTangent);
|
||||
const float tangentScale = (end.Time - start.Time) / 3.0f;
|
||||
AnimationUtils::GetTangent(start.Value, start.TangentOut, tangentScale, leftTangent);
|
||||
AnimationUtils::GetTangent(end.Value, end.TangentIn, tangentScale, rightTangent);
|
||||
|
||||
// Find maximum scale over the segment spline and collect the segment positions for bounds
|
||||
segmentPoints.Clear();
|
||||
@@ -256,9 +256,9 @@ void SplineModel::UpdateDeformationBuffer()
|
||||
auto& instance = _instances[segment];
|
||||
const auto& start = keyframes[segment];
|
||||
const auto& end = keyframes[segment + 1];
|
||||
const float length = end.Time - start.Time;
|
||||
AnimationUtils::GetTangent(start.Value, start.TangentOut, length, leftTangent);
|
||||
AnimationUtils::GetTangent(end.Value, end.TangentIn, length, rightTangent);
|
||||
const float tangentScale = (end.Time - start.Time) / 3.0f;
|
||||
AnimationUtils::GetTangent(start.Value, start.TangentOut, tangentScale, leftTangent);
|
||||
AnimationUtils::GetTangent(end.Value, end.TangentIn, tangentScale, rightTangent);
|
||||
for (int32 chunk = 0; chunk < chunksPerSegment; chunk++)
|
||||
{
|
||||
const float alpha = (chunk == chunksPerSegment - 1) ? 1.0f : ((float)chunk * chunksPerSegmentInv);
|
||||
@@ -291,10 +291,10 @@ void SplineModel::UpdateDeformationBuffer()
|
||||
{
|
||||
const auto& start = keyframes[segments - 1];
|
||||
const auto& end = keyframes[segments];
|
||||
const float length = end.Time - start.Time;
|
||||
const float tangentScale = (end.Time - start.Time) / 3.0f;
|
||||
const float alpha = 1.0f - ZeroTolerance; // Offset to prevent zero derivative at the end of the curve
|
||||
AnimationUtils::GetTangent(start.Value, start.TangentOut, length, leftTangent);
|
||||
AnimationUtils::GetTangent(end.Value, end.TangentIn, length, rightTangent);
|
||||
AnimationUtils::GetTangent(start.Value, start.TangentOut, tangentScale, leftTangent);
|
||||
AnimationUtils::GetTangent(end.Value, end.TangentIn, tangentScale, rightTangent);
|
||||
AnimationUtils::Bezier(start.Value, leftTangent, rightTangent, end.Value, alpha, transform);
|
||||
Vector3 direction;
|
||||
AnimationUtils::BezierFirstDerivative(start.Value.Translation, leftTangent.Translation, rightTangent.Translation, end.Value.Translation, alpha, direction);
|
||||
|
||||
@@ -214,9 +214,9 @@ void SplineCollider::GetGeometry(CollisionShape& collision)
|
||||
auto offsetIndices = segment * collisionIndices.Count();
|
||||
const auto& start = keyframes[segment];
|
||||
const auto& end = keyframes[segment + 1];
|
||||
const float length = end.Time - start.Time;
|
||||
AnimationUtils::GetTangent(start.Value, start.TangentOut, length, leftTangent);
|
||||
AnimationUtils::GetTangent(end.Value, end.TangentIn, length, rightTangent);
|
||||
const float tangentScale = (end.Time - start.Time) / 3.0f;
|
||||
AnimationUtils::GetTangent(start.Value, start.TangentOut, tangentScale, leftTangent);
|
||||
AnimationUtils::GetTangent(end.Value, end.TangentIn, tangentScale, rightTangent);
|
||||
|
||||
// Vertex buffer is deformed along the spline
|
||||
auto srcVertices = collisionVertices.Get();
|
||||
|
||||
@@ -1882,19 +1882,46 @@ void Render2D::DrawBezier(const Float2& p1, const Float2& p2, const Float2& p3,
|
||||
const Float2 d3 = p4 - p3;
|
||||
const float len = d1.Length() + d2.Length() + d3.Length();
|
||||
const int32 segmentCount = Math::Clamp(Math::CeilToInt(len * 0.05f), 1, 100);
|
||||
const float segmentCountInv = 1.0f / segmentCount;
|
||||
const float segmentCountInv = 1.0f / (float)segmentCount;
|
||||
|
||||
// Draw segmented curve
|
||||
Float2 p;
|
||||
AnimationUtils::Bezier(p1, p2, p3, p4, 0, p);
|
||||
Lines2.Clear();
|
||||
Lines2.Add(p);
|
||||
for (int32 i = 1; i <= segmentCount; i++)
|
||||
Lines2.Add(p1);
|
||||
for (int32 i = 1; i < segmentCount; i++)
|
||||
{
|
||||
const float t = i * segmentCountInv;
|
||||
const float t = (float)i * segmentCountInv;
|
||||
Float2 p;
|
||||
AnimationUtils::Bezier(p1, p2, p3, p4, t, p);
|
||||
Lines2.Add(p);
|
||||
}
|
||||
Lines2.Add(p4);
|
||||
DrawLines(Lines2.Get(), Lines2.Count(), color, color, thickness);
|
||||
}
|
||||
|
||||
void Render2D::DrawSpline(const Float2& p1, const Float2& p2, const Float2& p3, const Float2& p4, const Color& color, float thickness)
|
||||
{
|
||||
RENDER2D_CHECK_RENDERING_STATE;
|
||||
|
||||
// Find amount of segments to use
|
||||
const Float2 d1 = p2 - p1;
|
||||
const Float2 d2 = p3 - p2;
|
||||
const Float2 d3 = p4 - p3;
|
||||
const float len = d1.Length() + d2.Length() + d3.Length();
|
||||
const int32 segmentCount = Math::Clamp(Math::CeilToInt(len * 0.05f), 1, 100);
|
||||
const float segmentCountInv = 1.0f / (float)segmentCount;
|
||||
|
||||
// Draw segmented curve
|
||||
Lines2.Clear();
|
||||
Lines2.Add(p1);
|
||||
for (int32 i = 1; i < segmentCount; i++)
|
||||
{
|
||||
const float t = (float)i * segmentCountInv;
|
||||
Float2 p;
|
||||
p.X = Math::Lerp(p1.X, p4.X, t);
|
||||
AnimationUtils::Bezier(p1.Y, p2.Y, p3.Y, p4.Y, t, p.Y);
|
||||
Lines2.Add(p);
|
||||
}
|
||||
Lines2.Add(p4);
|
||||
DrawLines(Lines2.Get(), Lines2.Count(), color, color, thickness);
|
||||
}
|
||||
|
||||
|
||||
@@ -389,6 +389,17 @@ public:
|
||||
/// <param name="thickness">The line thickness.</param>
|
||||
API_FUNCTION() static void DrawBezier(const Float2& p1, const Float2& p2, const Float2& p3, const Float2& p4, const Color& color, float thickness = 1.0f);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a spline curve (Bezier but X axis represents uniform time).
|
||||
/// </summary>
|
||||
/// <param name="p1">The start point.</param>
|
||||
/// <param name="p2">The first control point.</param>
|
||||
/// <param name="p3">The second control point.</param>
|
||||
/// <param name="p4">The end point.</param>
|
||||
/// <param name="color">The line color</param>
|
||||
/// <param name="thickness">The line thickness.</param>
|
||||
API_FUNCTION() static void DrawSpline(const Float2& p1, const Float2& p2, const Float2& p3, const Float2& p4, const Color& color, float thickness = 1.0f);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the GUI material.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user