diff --git a/Source/Editor/CustomEditors/Dedicated/SplineEditor.cs b/Source/Editor/CustomEditors/Dedicated/SplineEditor.cs
index 4df665b15..8c3d03b2b 100644
--- a/Source/Editor/CustomEditors/Dedicated/SplineEditor.cs
+++ b/Source/Editor/CustomEditors/Dedicated/SplineEditor.cs
@@ -182,11 +182,100 @@ namespace FlaxEditor.CustomEditors.Dedicated
}
}
+ ///
+ /// Edit curve options manipulate the curve setting selected point
+ /// tangent in as smoothed but tangent out as linear
+ ///
+ private sealed class SmoothInTangentMode : EditTangentOptionBase
+ {
+ ///
+ public override void OnSetMode(Spline spline, int index)
+ {
+ var keyframe = spline.GetSplineKeyframe(index);
+
+ // auto smooth tangent if's linear
+ if (keyframe.TangentIn.Translation.Length == 0)
+ {
+ var isLastKeyframe = index == spline.SplinePointsCount - 1;
+ var isFirstKeyframe = index == 0;
+
+ if (!isLastKeyframe)
+ {
+ var nexKeyframe = spline.GetSplineKeyframe(index + 1);
+ var directionToNextKeyframe = keyframe.Value.WorldToLocalVector(keyframe.Value.Translation - nexKeyframe.Value.Translation);
+ directionToNextKeyframe = directionToNextKeyframe.Normalized * 100f;
+ keyframe.TangentIn.Translation = directionToNextKeyframe;
+ }
+ }
+
+ keyframe.TangentOut.Translation = Vector3.Zero;
+
+ spline.SetSplineKeyframe(index, keyframe);
+ }
+
+ ///
+ public override void OnMoveTangentIn(Spline spline, int index) { }
+
+ ///
+ public override void OnMoveTangentOut(Spline spline, int index) { }
+
+ ///
+ public override void OnSelectKeyframe(Spline spline, int index) { }
+
+ ///
+ public override void OnSelectTangent(Spline spline, int index) { }
+ }
+
+ ///
+ /// Edit curve options manipulate the curve setting selected point
+ /// tangent in as linear but tangent out as smoothed
+ ///
+ private sealed class SmoothOutTangentMode : EditTangentOptionBase
+ {
+ ///
+ public override void OnSetMode(Spline spline, int index)
+ {
+ var keyframe = spline.GetSplineKeyframe(index);
+
+ // auto smooth tangent if's linear
+ if (keyframe.TangentOut.Translation.Length == 0)
+ {
+ var isFirstKeyframe = index == 0;
+
+ if (!isFirstKeyframe)
+ {
+ var previousKeyframe = spline.GetSplineKeyframe(index - 1);
+ var directionToPreviousKeyframe = keyframe.Value.WorldToLocalVector(keyframe.Value.Translation - previousKeyframe.Value.Translation);
+ directionToPreviousKeyframe = directionToPreviousKeyframe.Normalized * 100f;
+ keyframe.TangentOut.Translation = directionToPreviousKeyframe;
+ }
+ }
+
+ keyframe.TangentIn.Translation = Vector3.Zero;
+
+ spline.SetSplineKeyframe(index, keyframe);
+ }
+
+ ///
+ public override void OnMoveTangentIn(Spline spline, int index) { }
+
+ ///
+ public override void OnMoveTangentOut(Spline spline, int index) { }
+
+ ///
+ public override void OnSelectKeyframe(Spline spline, int index) { }
+
+ ///
+ public override void OnSelectTangent(Spline spline, int index) { }
+ }
+
private EditTangentOptionBase _currentTangentMode;
private ButtonElement _freeTangentButton;
private ButtonElement _linearTangentButton;
private ButtonElement _alignedTangentButton;
+ private ButtonElement _smoothInTangentButton;
+ private ButtonElement _smoothOutTangentButton;
private bool _tanInChanged;
private bool _tanOutChanged;
@@ -231,19 +320,25 @@ namespace FlaxEditor.CustomEditors.Dedicated
layout.Header("Selected spline point");
var selectedPointsGrid = layout.CustomContainer();
selectedPointsGrid.CustomControl.SlotsHorizontally = 3;
- selectedPointsGrid.CustomControl.SlotsVertically = 1;
+ selectedPointsGrid.CustomControl.SlotsVertically = 2;
_linearTangentButton = selectedPointsGrid.Button("Linear");
_freeTangentButton = selectedPointsGrid.Button("Free");
_alignedTangentButton = selectedPointsGrid.Button("Aligned");
+ _smoothInTangentButton = selectedPointsGrid.Button("Smooth In");
+ _smoothOutTangentButton = selectedPointsGrid.Button("Smooth Out");
_linearTangentButton.Button.Clicked += SetModeLinear;
_freeTangentButton.Button.Clicked += SetModeFree;
_alignedTangentButton.Button.Clicked += SetModeAligned;
+ _smoothInTangentButton.Button.Clicked += SetModeSmoothIn;
+ _smoothOutTangentButton.Button.Clicked += SetModeSmoothOut;
_linearTangentButton.Button.Clicked += UpdateButtonsColors;
_freeTangentButton.Button.Clicked += UpdateButtonsColors;
_alignedTangentButton.Button.Clicked += UpdateButtonsColors;
+ _smoothInTangentButton.Button.Clicked += UpdateButtonsColors;
+ _smoothOutTangentButton.Button.Clicked += UpdateButtonsColors;
layout.Header("All spline points");
var grid = layout.CustomContainer();
@@ -265,6 +360,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
_freeTangentButton.Button.Enabled = CanSetTangentMode;
_linearTangentButton.Button.Enabled = CanSetTangentMode;
_alignedTangentButton.Button.Enabled = CanSetTangentMode;
+ _smoothInTangentButton.Button.Enabled = CanSetTangentMode;
+ _smoothOutTangentButton.Button.Enabled = CanSetTangentMode;
if (_lastPointSelected == null)
{
@@ -318,6 +415,18 @@ namespace FlaxEditor.CustomEditors.Dedicated
_currentTangentMode.OnSetMode(SelectedSpline, _lastPointSelected.Index);
}
+ private void SetModeSmoothIn()
+ {
+ _currentTangentMode = new SmoothInTangentMode();
+ _currentTangentMode.OnSetMode(SelectedSpline, _lastPointSelected.Index);
+ }
+
+ private void SetModeSmoothOut()
+ {
+ _currentTangentMode = new SmoothOutTangentMode();
+ _currentTangentMode.OnSetMode(SelectedSpline, _lastPointSelected.Index);
+ }
+
private void UpdateSelectedPoint()
{
// works only if select one spline
@@ -373,10 +482,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
var isFree = _currentTangentMode is FreeTangentMode;
var isLinear = _currentTangentMode is LinearTangentMode;
var isAligned = _currentTangentMode is AlignedTangentMode;
+ var isSmoothIn = _currentTangentMode is SmoothInTangentMode;
+ var isSmoothOut = _currentTangentMode is SmoothOutTangentMode;
_linearTangentButton.Button.BackgroundColor = isLinear ? SelectedButtonColor : NormalButtonColor;
_freeTangentButton.Button.BackgroundColor = isFree ? SelectedButtonColor : NormalButtonColor;
_alignedTangentButton.Button.BackgroundColor = isAligned ? SelectedButtonColor : NormalButtonColor;
+ _smoothInTangentButton.Button.BackgroundColor = isSmoothIn ? SelectedButtonColor : NormalButtonColor;
+ _smoothOutTangentButton.Button.BackgroundColor = isSmoothOut ? SelectedButtonColor : NormalButtonColor;
}
private void SetSelectedTangentTypeAsCurrent()
@@ -384,10 +497,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
var isFree = IsFreeTangentMode(SelectedSpline, _lastPointSelected.Index);
var isLinear = IsLinearTangentMode(SelectedSpline, _lastPointSelected.Index);
var isAligned = IsAlignedTangentMode(SelectedSpline, _lastPointSelected.Index);
+ var isSmoothIn = IsSmoothInTangentMode(SelectedSpline, _lastPointSelected.Index);
+ var isSmoothOut = IsSmoothOutTangentMode(SelectedSpline, _lastPointSelected.Index);
if (isFree) SetModeFree();
else if (isLinear) SetModeLinear();
else if (isAligned) SetModeAligned();
+ else if (isSmoothIn) SetModeSmoothIn();
+ else if (isSmoothOut) SetModeSmoothIn();
}
private void OnSetTangentsLinear()
@@ -426,7 +543,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
private static bool IsFreeTangentMode(Spline spline, int index)
{
- if (IsLinearTangentMode(spline, index) || IsAlignedTangentMode(spline, index))
+ if (IsLinearTangentMode(spline, index) ||
+ IsAlignedTangentMode(spline, index) ||
+ IsSmoothInTangentMode(spline, index) ||
+ IsSmoothOutTangentMode(spline, index))
{
return false;
}
@@ -461,6 +581,18 @@ namespace FlaxEditor.CustomEditors.Dedicated
return false;
}
+ private static bool IsSmoothInTangentMode(Spline spline, int index)
+ {
+ var keyframe = spline.GetSplineKeyframe(index);
+ return keyframe.TangentIn.Translation.Length > 0 && keyframe.TangentOut.Translation.Length == 0;
+ }
+
+ private static bool IsSmoothOutTangentMode(Spline spline, int index)
+ {
+ var keyframe = spline.GetSplineKeyframe(index);
+ return keyframe.TangentOut.Translation.Length > 0 && keyframe.TangentIn.Translation.Length == 0;
+ }
+
private static void SetPointSmooth(Spline spline, int index)
{
var keyframe = spline.GetSplineKeyframe(index);