diff --git a/Source/Editor/GUI/CurveEditor.cs b/Source/Editor/GUI/CurveEditor.cs index 141b3aa60..bc96cf3bc 100644 --- a/Source/Editor/GUI/CurveEditor.cs +++ b/Source/Editor/GUI/CurveEditor.cs @@ -431,7 +431,6 @@ namespace FlaxEditor.GUI /// protected CurveEditor() { - _tickStrengths = new float[TickSteps.Length]; Accessor.GetDefaultValue(out DefaultValue); var style = Style.Current; @@ -780,75 +779,31 @@ namespace FlaxEditor.GUI return _mainPanel.PointToParent(point); } - private void DrawAxis(Float2 axis, ref Rectangle viewRect, float min, float max, float pixelRange) + private void DrawAxis(Float2 axis, Rectangle viewRect, float min, float max, float pixelRange) { - int minDistanceBetweenTicks = 20; - int maxDistanceBetweenTicks = 60; - var range = max - min; - - // Find the strength for each modulo number tick marker - int smallestTick = 0; - int biggestTick = TickSteps.Length - 1; - for (int i = TickSteps.Length - 1; i >= 0; i--) + Utilities.Utils.DrawCurveTicks((float tick, float strength) => { - // Calculate how far apart these modulo tick steps are spaced - float tickSpacing = TickSteps[i] * pixelRange / range; + var p = PointFromKeyframes(axis * tick, ref viewRect); - // Calculate the strength of the tick markers based on the spacing - _tickStrengths[i] = Mathf.Saturate((tickSpacing - minDistanceBetweenTicks) / (maxDistanceBetweenTicks - minDistanceBetweenTicks)); + // Draw line + var lineRect = new Rectangle + ( + viewRect.Location + (p - 0.5f) * axis, + Float2.Lerp(viewRect.Size, Float2.One, axis) + ); + Render2D.FillRectangle(lineRect, _linesColor.AlphaMultiplied(strength)); - // Beyond threshold the ticks don't get any bigger or fatter - if (_tickStrengths[i] >= 1) - biggestTick = i; - - // Do not show small tick markers - if (tickSpacing <= minDistanceBetweenTicks) - { - smallestTick = i; - break; - } - } - - // Draw all tick levels - int tickLevels = biggestTick - smallestTick + 1; - for (int level = 0; level < tickLevels; level++) - { - float strength = _tickStrengths[smallestTick + level]; - if (strength <= Mathf.Epsilon) - continue; - - // Draw all ticks - int l = Mathf.Clamp(smallestTick + level, 0, TickSteps.Length - 1); - int startTick = Mathf.FloorToInt(min / TickSteps[l]); - int endTick = Mathf.CeilToInt(max / TickSteps[l]); - for (int i = startTick; i <= endTick; i++) - { - if (l < biggestTick && (i % Mathf.RoundToInt(TickSteps[l + 1] / TickSteps[l]) == 0)) - continue; - - var tick = i * TickSteps[l]; - var p = PointFromKeyframes(axis * tick, ref viewRect); - - // Draw line - var lineRect = new Rectangle - ( - viewRect.Location + (p - 0.5f) * axis, - Float2.Lerp(viewRect.Size, Float2.One, axis) - ); - Render2D.FillRectangle(lineRect, _linesColor.AlphaMultiplied(strength)); - - // Draw label - string label = tick.ToString(CultureInfo.InvariantCulture); - var labelRect = new Rectangle - ( - viewRect.X + 4.0f + (p.X * axis.X), - viewRect.Y - LabelsSize + (p.Y * axis.Y) + (viewRect.Size.Y * axis.X), - 50, - LabelsSize - ); - Render2D.DrawText(_labelsFont, label, labelRect, _labelsColor.AlphaMultiplied(strength), TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, 0.7f); - } - } + // Draw label + string label = tick.ToString(CultureInfo.InvariantCulture); + var labelRect = new Rectangle + ( + viewRect.X + 4.0f + (p.X * axis.X), + viewRect.Y - LabelsSize + (p.Y * axis.Y) + (viewRect.Size.Y * axis.X), + 50, + LabelsSize + ); + Render2D.DrawText(_labelsFont, label, labelRect, _labelsColor.AlphaMultiplied(strength), TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, 0.7f); + }, TickSteps, ref _tickStrengths, min, max, pixelRange); } /// @@ -890,9 +845,9 @@ namespace FlaxEditor.GUI Render2D.PushClip(ref viewRect); if ((ShowAxes & UseMode.Vertical) == UseMode.Vertical) - DrawAxis(Float2.UnitX, ref viewRect, min.X, max.X, pixelRange.X); + DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X); if ((ShowAxes & UseMode.Horizontal) == UseMode.Horizontal) - DrawAxis(Float2.UnitY, ref viewRect, min.Y, max.Y, pixelRange.Y); + DrawAxis(Float2.UnitY, viewRect, min.Y, max.Y, pixelRange.Y); Render2D.PopClip(); } diff --git a/Source/Editor/GUI/Timeline/GUI/Background.cs b/Source/Editor/GUI/Timeline/GUI/Background.cs index 4ec634a0b..7bda8f4c0 100644 --- a/Source/Editor/GUI/Timeline/GUI/Background.cs +++ b/Source/Editor/GUI/Timeline/GUI/Background.cs @@ -28,7 +28,6 @@ namespace FlaxEditor.GUI.Timeline.GUI { _timeline = timeline; _tickSteps = Utilities.Utils.CurveTickSteps; - _tickStrengths = new float[_tickSteps.Length]; } private void UpdateSelectionRectangle() @@ -173,55 +172,20 @@ namespace FlaxEditor.GUI.Timeline.GUI var rightFrame = Mathf.Ceil((right - Timeline.StartOffset) / zoom) * _timeline.FramesPerSecond; var min = leftFrame; var max = rightFrame; - int smallestTick = 0; - int biggestTick = _tickSteps.Length - 1; - for (int i = _tickSteps.Length - 1; i >= 0; i--) - { - // Calculate how far apart these modulo tick steps are spaced - float tickSpacing = _tickSteps[i] * _timeline.Zoom; - - // Calculate the strength of the tick markers based on the spacing - _tickStrengths[i] = Mathf.Saturate((tickSpacing - minDistanceBetweenTicks) / (maxDistanceBetweenTicks - minDistanceBetweenTicks)); - - // Beyond threshold the ticks don't get any bigger or fatter - if (_tickStrengths[i] >= 1) - biggestTick = i; - - // Do not show small tick markers - if (tickSpacing <= minDistanceBetweenTicks) - { - smallestTick = i; - break; - } - } - int tickLevels = biggestTick - smallestTick + 1; // Draw vertical lines for time axis - for (int level = 0; level < tickLevels; level++) + var pixelsInRange = _timeline.Zoom; + var pixelRange = pixelsInRange * (max - min); + var tickRange = Utilities.Utils.DrawCurveTicks((float tick, float strength) => { - float strength = _tickStrengths[smallestTick + level]; - if (strength <= Mathf.Epsilon) - continue; - - // Draw all ticks - int l = Mathf.Clamp(smallestTick + level, 0, _tickSteps.Length - 1); - var lStep = _tickSteps[l]; - var lNextStep = _tickSteps[l + 1]; - int startTick = Mathf.FloorToInt(min / lStep); - int endTick = Mathf.CeilToInt(max / lStep); - Color lineColor = style.ForegroundDisabled.RGBMultiplied(0.7f).AlphaMultiplied(strength); - for (int i = startTick; i <= endTick; i++) - { - if (l < biggestTick && (i % Mathf.RoundToInt(lNextStep / lStep) == 0)) - continue; - var tick = i * lStep; - var time = tick / _timeline.FramesPerSecond; - var x = time * zoom + Timeline.StartOffset; - - // Draw line - Render2D.FillRectangle(new Rectangle(x - 0.5f, 0, 1.0f, height), lineColor); - } - } + var time = tick / _timeline.FramesPerSecond; + var x = time * zoom + Timeline.StartOffset; + var lineColor = style.ForegroundDisabled.RGBMultiplied(0.7f).AlphaMultiplied(strength); + Render2D.FillRectangle(new Rectangle(x - 0.5f, 0, 1.0f, height), lineColor); + }, _tickSteps, ref _tickStrengths, min, max, pixelRange, minDistanceBetweenTicks, maxDistanceBetweenTicks); + var smallestTick = tickRange.X; + var biggestTick = tickRange.Y; + var tickLevels = biggestTick - smallestTick + 1; // Draw selection rectangle if (_isSelecting) diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index b403c1489..576c30f89 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -243,6 +243,63 @@ namespace FlaxEditor.Utilities 500000, 1000000, 5000000, 10000000, 100000000 }; + internal delegate void DrawCurveTick(float tick, float strength); + + internal static Int2 DrawCurveTicks(DrawCurveTick drawTick, float[] tickSteps, ref float[] tickStrengths, float min, float max, float pixelRange, float minDistanceBetweenTicks = 20, float maxDistanceBetweenTicks = 60) + { + if (tickStrengths == null || tickStrengths.Length != tickSteps.Length) + tickStrengths = new float[tickSteps.Length]; + + // Find the strength for each modulo number tick marker + var pixelsInRange = pixelRange / (max - min); + var smallestTick = 0; + var biggestTick = tickSteps.Length - 1; + for (int i = tickSteps.Length - 1; i >= 0; i--) + { + // Calculate how far apart these modulo tick steps are spaced + float tickSpacing = tickSteps[i] * pixelsInRange; + + // Calculate the strength of the tick markers based on the spacing + tickStrengths[i] = Mathf.Saturate((tickSpacing - minDistanceBetweenTicks) / (maxDistanceBetweenTicks - minDistanceBetweenTicks)); + + // Beyond threshold the ticks don't get any bigger or fatter + if (tickStrengths[i] >= 1) + biggestTick = i; + + // Do not show small tick markers + if (tickSpacing <= minDistanceBetweenTicks) + { + smallestTick = i; + break; + } + } + var tickLevels = biggestTick - smallestTick + 1; + + // Draw all tick levels + for (int level = 0; level < tickLevels; level++) + { + float strength = tickStrengths[smallestTick + level]; + if (strength <= Mathf.Epsilon) + continue; + + // Draw all ticks + int l = Mathf.Clamp(smallestTick + level, 0, tickSteps.Length - 1); + var lStep = tickSteps[l]; + var lNextStep = tickSteps[l + 1]; + int startTick = Mathf.FloorToInt(min / lStep); + int endTick = Mathf.CeilToInt(max / lStep); + for (int i = startTick; i <= endTick; i++) + { + if (l < biggestTick && (i % Mathf.RoundToInt(lNextStep / lStep) == 0)) + continue; + var tick = i * lStep; + drawTick(tick, strength); + } + } + + return new Int2(smallestTick, biggestTick); + } + /// /// Determines whether the specified path string contains any invalid character. ///