diff --git a/Flax.flaxproj b/Flax.flaxproj index 33dc6e45b..15b925c0d 100644 --- a/Flax.flaxproj +++ b/Flax.flaxproj @@ -4,7 +4,7 @@ "Major": 1, "Minor": 9, "Revision": 0, - "Build": 6605 + "Build": 6606 }, "Company": "Flax", "Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.", diff --git a/Source/Editor/GUI/CurveEditor.Contents.cs b/Source/Editor/GUI/CurveEditor.Contents.cs index fd51be3fd..25954abfa 100644 --- a/Source/Editor/GUI/CurveEditor.Contents.cs +++ b/Source/Editor/GUI/CurveEditor.Contents.cs @@ -231,11 +231,10 @@ namespace FlaxEditor.GUI else if (_isMovingTangent) { var viewRect = _editor._mainPanel.GetClientArea(); - var direction = _movingTangent.IsIn ? -1.0f : 1.0f; var k = _editor.GetKeyframe(_movingTangent.Index); var kv = _editor.GetKeyframeValue(k); var value = _editor.Accessor.GetCurveValue(ref kv, _movingTangent.Component); - _movingTangent.TangentValue = direction * (PointToKeyframes(location, ref viewRect).Y - value); + _movingTangent.TangentValue = PointToKeyframes(location, ref viewRect).Y - value; _editor.UpdateTangents(); Cursor = CursorType.SizeNS; _movedKeyframes = true; diff --git a/Source/Editor/GUI/CurveEditor.cs b/Source/Editor/GUI/CurveEditor.cs index 837106c6f..ed0885afd 100644 --- a/Source/Editor/GUI/CurveEditor.cs +++ b/Source/Editor/GUI/CurveEditor.cs @@ -682,9 +682,9 @@ namespace FlaxEditor.GUI var minPosPoint = _contents.PointToParent(ref minPos); var scroll = new Float2(_mainPanel.HScrollBar?.TargetValue ?? 0, _mainPanel.VScrollBar?.TargetValue ?? 0); scroll = ApplyUseModeMask(EnablePanning, minPosPoint, scroll); - if (_mainPanel.HScrollBar != null && _mainPanel.HScrollBar.Enabled) + if (_mainPanel.HScrollBar != null) _mainPanel.HScrollBar.TargetValue = scroll.X; - if (_mainPanel.VScrollBar != null && _mainPanel.VScrollBar.Enabled) + if (_mainPanel.VScrollBar != null) _mainPanel.VScrollBar.TargetValue = scroll.Y; UpdateKeyframes(); @@ -1649,6 +1649,7 @@ namespace FlaxEditor.GUI var o = _keyframes[p.Index - 1]; var oValue = Accessor.GetCurveValue(ref o.Value, p.Component); var slope = (value - oValue) / (k.Time - o.Time); + slope = -slope; Accessor.SetCurveValue(slope, ref k.TangentIn, p.Component); } @@ -2199,12 +2200,12 @@ namespace FlaxEditor.GUI var tangent = t.TangentValue; var direction = t.IsIn ? -1.0f : 1.0f; - var offset = 30.0f * direction; + var offset = 30.0f; var location = GetKeyframePoint(ref k, selectedComponent); t.Size = KeyframesSize / ViewScale; t.Location = new Float2 ( - location.X * UnitsPerSecond - t.Width * 0.5f + offset, + location.X * UnitsPerSecond - t.Width * 0.5f + offset * direction, location.Y * -UnitsPerSecond - t.Height * 0.5f + curveContentAreaBounds.Height - offset * tangent ); @@ -2280,14 +2281,13 @@ namespace FlaxEditor.GUI var startTangent = Accessor.GetCurveValue(ref startK.TangentOut, component); var endTangent = Accessor.GetCurveValue(ref endK.TangentIn, component); - var offset = (end.X - start.X) * 0.5f; - + var tangentScale = (endK.Time - startK.Time) / 3.0f; var p1 = PointFromKeyframes(start, ref viewRect); - var p2 = PointFromKeyframes(start + new Float2(offset, startTangent * offset), ref viewRect); - var p3 = PointFromKeyframes(end - new Float2(offset, endTangent * offset), ref viewRect); + var p2 = PointFromKeyframes(start + new Float2(0, startTangent * tangentScale), ref viewRect); + var p3 = PointFromKeyframes(end + new Float2(0, endTangent * tangentScale), ref viewRect); var p4 = PointFromKeyframes(end, ref viewRect); - Render2D.DrawBezier(p1, p2, p3, p4, color); + Render2D.DrawSpline(p1, p2, p3, p4, color); } } } diff --git a/Source/Editor/GUI/Timeline/GUI/Background.cs b/Source/Editor/GUI/Timeline/GUI/Background.cs index 7bda8f4c0..57b09324e 100644 --- a/Source/Editor/GUI/Timeline/GUI/Background.cs +++ b/Source/Editor/GUI/Timeline/GUI/Background.cs @@ -230,7 +230,7 @@ namespace FlaxEditor.GUI.Timeline.GUI continue; // Draw all ticks - int l = Mathf.Clamp(smallestTick + level, 0, _tickSteps.Length - 1); + int l = Mathf.Clamp(smallestTick + level, 0, _tickSteps.Length - 2); var lStep = _tickSteps[l]; var lNextStep = _tickSteps[l + 1]; int startTick = Mathf.FloorToInt(min / lStep); diff --git a/Source/Engine/Animations/AnimationUtils.h b/Source/Engine/Animations/AnimationUtils.h index d801443ab..4f697a2d0 100644 --- a/Source/Engine/Animations/AnimationUtils.h +++ b/Source/Engine/Animations/AnimationUtils.h @@ -66,27 +66,23 @@ namespace AnimationUtils } template - 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(const Quaternion& a, const Quaternion& b, float length, Quaternion& result) + FORCE_INLINE void GetTangent(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(const Transform& a, const Transform& b, float length, Transform& result) + FORCE_INLINE void GetTangent(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 diff --git a/Source/Engine/Animations/Curve.cs b/Source/Engine/Animations/Curve.cs index a0d911141..7632653bc 100644 --- a/Source/Engine/Animations/Curve.cs +++ b/Source/Engine/Animations/Curve.cs @@ -24,9 +24,9 @@ namespace FlaxEngine /// /// The value. /// The tangent. - /// The length divided by 3. + /// The tangent scale factor. /// The result. - 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); /// /// Calculates the linear interpolation at the specified alpha. @@ -67,7 +67,7 @@ namespace FlaxEngine IKeyframeAccess, IKeyframeAccess { - 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); } diff --git a/Source/Engine/Animations/Curve.h b/Source/Engine/Animations/Curve.h index 40dfc8add..b259dae66 100644 --- a/Source/Engine/Animations/Curve.h +++ b/Source/Engine/Animations/Curve.h @@ -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; diff --git a/Source/Engine/Level/Actors/Spline.cpp b/Source/Engine/Level/Actors/Spline.cpp index 01b4248ec..8dd79c8ae 100644 --- a/Source/Engine/Level/Actors/Spline.cpp +++ b/Source/Engine/Level/Actors/Spline.cpp @@ -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++) { diff --git a/Source/Engine/Level/Actors/SplineModel.cpp b/Source/Engine/Level/Actors/SplineModel.cpp index 29c14f035..71b618384 100644 --- a/Source/Engine/Level/Actors/SplineModel.cpp +++ b/Source/Engine/Level/Actors/SplineModel.cpp @@ -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); diff --git a/Source/Engine/Physics/Colliders/SplineCollider.cpp b/Source/Engine/Physics/Colliders/SplineCollider.cpp index 94e35aae5..226b6fa27 100644 --- a/Source/Engine/Physics/Colliders/SplineCollider.cpp +++ b/Source/Engine/Physics/Colliders/SplineCollider.cpp @@ -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(); diff --git a/Source/Engine/Render2D/Render2D.cpp b/Source/Engine/Render2D/Render2D.cpp index 877b6bb16..6f7c7043e 100644 --- a/Source/Engine/Render2D/Render2D.cpp +++ b/Source/Engine/Render2D/Render2D.cpp @@ -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); } diff --git a/Source/Engine/Render2D/Render2D.h b/Source/Engine/Render2D/Render2D.h index 5eda59e7e..5905fa434 100644 --- a/Source/Engine/Render2D/Render2D.h +++ b/Source/Engine/Render2D/Render2D.h @@ -389,6 +389,17 @@ public: /// The line thickness. API_FUNCTION() static void DrawBezier(const Float2& p1, const Float2& p2, const Float2& p3, const Float2& p4, const Color& color, float thickness = 1.0f); + /// + /// Draws a spline curve (Bezier but X axis represents uniform time). + /// + /// The start point. + /// The first control point. + /// The second control point. + /// The end point. + /// The line color + /// The line thickness. + API_FUNCTION() static void DrawSpline(const Float2& p1, const Float2& p2, const Float2& p3, const Float2& p4, const Color& color, float thickness = 1.0f); + /// /// Draws the GUI material. ///