From e5e7c26f3953ddc05b0d7a128ec97585978d4508 Mon Sep 17 00:00:00 2001 From: Marcus Brummer Date: Thu, 29 Aug 2024 21:39:11 +0200 Subject: [PATCH] Brush stroke smoothing using cubic bezier curves It feels so much better! --- lorien/BrushStroke/BrushStrokeOptimizer.gd | 4 ++-- lorien/InfiniteCanvas/Tools/BrushTool.gd | 13 +++++++++++-- lorien/Misc/Utils.gd | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lorien/BrushStroke/BrushStrokeOptimizer.gd b/lorien/BrushStroke/BrushStrokeOptimizer.gd index 8d79491e..3ef1f276 100644 --- a/lorien/BrushStroke/BrushStrokeOptimizer.gd +++ b/lorien/BrushStroke/BrushStrokeOptimizer.gd @@ -1,8 +1,8 @@ class_name BrushStrokeOptimizer # ------------------------------------------------------------------------------------------------- -const ANGLE_THRESHOLD := 1.0 -const DISTANCE_THRESHOLD := 2.0 +const ANGLE_THRESHOLD := 0.5 +const DISTANCE_THRESHOLD := 1.0 # ------------------------------------------------------------------------------------------------- var points_removed := 0 diff --git a/lorien/InfiniteCanvas/Tools/BrushTool.gd b/lorien/InfiniteCanvas/Tools/BrushTool.gd index 3f637d47..a15a03a6 100644 --- a/lorien/InfiniteCanvas/Tools/BrushTool.gd +++ b/lorien/InfiniteCanvas/Tools/BrushTool.gd @@ -39,15 +39,24 @@ func _process(delta: float) -> void: if performing_stroke: var pos := _cursor.global_position - # Basic smoothing + # Smoothing var diff := pos.distance_squared_to(_last_accepted_position) if diff <= MOVEMENT_THRESHOLD || _current_pressure <= MIN_PRESSURE: return - + + var points := get_current_brush_stroke().points + if points.size() > 3: + var p3 := points[-3] + var p2 := points[-2] + var p1 := points[-1] + # TODO: expose the smoothing factor in the settings + pos = Utils.cubic_bezier(p3, p2, p1, pos, 0.75) + var sensitivity: float = Settings.get_general_value( Settings.GENERAL_PRESSURE_SENSITIVITY, Config.DEFAULT_PRESSURE_SENSITIVITY ) + # Pressure var point_pressure := pressure_curve.sample(_current_pressure) * sensitivity if _first_point: point_pressure *= 1.4 diff --git a/lorien/Misc/Utils.gd b/lorien/Misc/Utils.gd index cae924fb..bac3e5f7 100644 --- a/lorien/Misc/Utils.gd +++ b/lorien/Misc/Utils.gd @@ -85,3 +85,18 @@ func translate_action(action_name: String) -> String: # Does an _exact_ match for the given key stroke. func event_pressed_bug_workaround(action_name: String, event: InputEvent) -> bool: return InputMap.action_has_event(action_name, event) && event.is_pressed() && !event.is_echo() + +# ------------------------------------------------------------------------------------------------- +func cubic_bezier(p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2, t: float) -> Vector2: + var q0 := p0.lerp(p1, t) + var q1 := p1.lerp(p2, t) + var q2 := p2.lerp(p3, t) + var r0 := q0.lerp(q1, t) + var r1 := q1.lerp(q2, t) + return r0.lerp(r1, t) + +# ------------------------------------------------------------------------------------------------- +func quadratic_bezier(p0: Vector2, p1: Vector2, p2: Vector2, t: float) -> Vector2: + var q0 := p0.lerp(p1, t) + var q1 := p1.lerp(p2, t) + return q0.lerp(q1, t)