From 3dd930b56f314beda9bbcf151834fe9e73403efb Mon Sep 17 00:00:00 2001 From: Marcus Brummer Date: Sun, 29 Sep 2024 14:41:45 +0200 Subject: [PATCH] Velocity based line thickness --- docs/changelog.md | 1 + lorien/BrushStroke/BrushStroke.gd | 1 - lorien/Config.gd | 6 ++-- lorien/InfiniteCanvas/InfiniteCanvas.gd | 22 +++++++----- lorien/InfiniteCanvas/InfiniteCanvas.tscn | 2 +- lorien/InfiniteCanvas/Tools/BrushTool.gd | 34 +++++++++++++------ .../default_pressure_curve.tres | 5 +-- lorien/Main.gd | 2 +- 8 files changed, 46 insertions(+), 27 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 48a331b6..fe21c98e 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - Brush stroke stabilizer/smoothing - Adaptive frame rate for reduced GPU/CPU load when the user is idle +- Velocity based line thickness (in addition to pen pressure) - File tabs are now responsive and can be scrolled when not enough screen width is availble - File tabs can be moved via drag and drop - Native file dialogs diff --git a/lorien/BrushStroke/BrushStroke.gd b/lorien/BrushStroke/BrushStroke.gd index 8f96fabb..7c060a57 100644 --- a/lorien/BrushStroke/BrushStroke.gd +++ b/lorien/BrushStroke/BrushStroke.gd @@ -131,7 +131,6 @@ func refresh() -> void: bottom_right.x = max(bottom_right.x, point.x) bottom_right.y = max(bottom_right.y, point.y) - _line2d.width_curve.bake() top_left_pos = top_left bottom_right_pos = bottom_right _visibility_notifier.rect = Utils.calculate_rect(top_left, bottom_right) diff --git a/lorien/Config.gd b/lorien/Config.gd index 488e1f62..0a60f264 100644 --- a/lorien/Config.gd +++ b/lorien/Config.gd @@ -5,7 +5,7 @@ const VERSION_MINOR := 7 const VERSION_PATCH := 0 const VERSION_STATUS := "-dev" static var VERSION_STRING := "%d.%d.%d%s" % [VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_STATUS] -const CONFIG_PATH := "user://settings_v3.cfg" +const CONFIG_PATH := "user://settings_v4.cfg" const PALETTES_PATH := "user://palettes.cfg" const STATE_PATH := "user://state.cfg" const MAX_PALETTE_SIZE := 40 @@ -14,8 +14,8 @@ const BACKGROUND_IDLE_TIME_THRESHOLD := 250 # in ms const MIN_WINDOW_SIZE := Vector2(320, 256) const DEFAULT_CANVAS_COLOR := Color("202124") const DEFAULT_BRUSH_COLOR := Color.WHITE -const DEFAULT_BRUSH_SIZE := 12 -const DEFAULT_PRESSURE_SENSITIVITY := 1.5 +const DEFAULT_BRUSH_SIZE := 10 +const DEFAULT_PRESSURE_SENSITIVITY := 1.0 const DEFAULT_CONSTANT_PRESSURE := false const DEFAULT_SELECTION_COLOR := Color("#2a967c") const DEFAULT_FOREGROUND_FPS := 144 diff --git a/lorien/InfiniteCanvas/InfiniteCanvas.gd b/lorien/InfiniteCanvas/InfiniteCanvas.gd index 035dc1ff..bab70818 100644 --- a/lorien/InfiniteCanvas/InfiniteCanvas.gd +++ b/lorien/InfiniteCanvas/InfiniteCanvas.gd @@ -203,15 +203,6 @@ func disable() -> void: func take_screenshot() -> Image: return _viewport.get_texture().get_data() -# ------------------------------------------------------------------------------------------------- -func start_stroke() -> void: - _current_stroke = BRUSH_STROKE.instantiate() - _current_stroke.size = _brush_size - _current_stroke.color = _brush_color - - _strokes_parent.add_child(_current_stroke) - _optimizer.reset() - # ------------------------------------------------------------------------------------------------- func add_stroke(stroke: BrushStroke) -> void: if _current_project != null: @@ -235,6 +226,19 @@ func remove_last_stroke_point() -> void: func remove_all_stroke_points() -> void: _current_stroke.remove_all_points() +# ------------------------------------------------------------------------------------------------- +func is_drawing() -> bool: + return _current_stroke != null + +# ------------------------------------------------------------------------------------------------- +func start_stroke() -> void: + _current_stroke = BRUSH_STROKE.instantiate() + _current_stroke.size = _brush_size + _current_stroke.color = _brush_color + + _strokes_parent.add_child(_current_stroke) + _optimizer.reset() + # ------------------------------------------------------------------------------------------------- func end_stroke() -> void: if _current_stroke != null: diff --git a/lorien/InfiniteCanvas/InfiniteCanvas.tscn b/lorien/InfiniteCanvas/InfiniteCanvas.tscn index b57d180f..c0a94fdb 100644 --- a/lorien/InfiniteCanvas/InfiniteCanvas.tscn +++ b/lorien/InfiniteCanvas/InfiniteCanvas.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" path="res://InfiniteCanvas/InfiniteCanvas.gd" id="1"] [ext_resource type="Script" path="res://InfiniteCanvas/PanZoomCamera.gd" id="2"] -[ext_resource type="Curve" path="res://InfiniteCanvas/default_pressure_curve.tres" id="3"] +[ext_resource type="Curve" uid="uid://bgd7v60kyywsk" path="res://InfiniteCanvas/default_pressure_curve.tres" id="3"] [ext_resource type="PackedScene" uid="uid://cf3j2vavqos04" path="res://InfiniteCanvas/Cursor/BrushCursor/BrushCursor.tscn" id="4"] [ext_resource type="Script" path="res://InfiniteCanvas/Tools/BrushTool.gd" id="5"] [ext_resource type="Script" path="res://InfiniteCanvas/Tools/LineTool.gd" id="6"] diff --git a/lorien/InfiniteCanvas/Tools/BrushTool.gd b/lorien/InfiniteCanvas/Tools/BrushTool.gd index 143231d2..bf556188 100644 --- a/lorien/InfiniteCanvas/Tools/BrushTool.gd +++ b/lorien/InfiniteCanvas/Tools/BrushTool.gd @@ -11,6 +11,7 @@ const DOT_MAX_DISTANCE_THRESHOLD := 6.0 # ------------------------------------------------------------------------------------------------- var _current_pressure: float +var _current_velocity: float var _moved := false var _last_accepted_position: Vector2 @@ -20,6 +21,11 @@ func tool_event(event: InputEvent) -> void: if event is InputEventMouseMotion: _current_pressure = event.pressure + + var screen := DisplayServer.screen_get_size() + var velocity: Vector2 = event.screen_velocity / Vector2(screen.x, screen.y) + _current_velocity = velocity.length() + if performing_stroke: _moved = true _cursor.set_pressure(event.pressure) @@ -54,20 +60,28 @@ func _process(delta: float) -> void: Settings.GENERAL_STABILIZER_STRENGTH, Config.DEFAULT_STABILIZER_STRENGTH ) - var points := get_current_brush_stroke().points - if points.size() > 3: - var p3 := points[-3] - var p2 := points[-2] - var p1 := points[-1] - # t is in [0.5, 1.0] interval depending on stabilizer settings - var t := 0.5 + (1.0 - stabilizer_strength) * 0.5 - pos = Utils.cubic_bezier(p3, p2, p1, pos, t) - - # Pressure + if stabilizer_strength >= 0.01: + var points := get_current_brush_stroke().points + if points.size() > 3: + var p3 := points[-3] + var p2 := points[-2] + var p1 := points[-1] + # t is in [0.5, 1.0] interval depending on stabilizer settings + var t := 0.5 + (1.0 - stabilizer_strength) * 0.5 + pos = Utils.cubic_bezier(p3, p2, p1, pos, t) + #pos = Utils.quadratic_bezier(p2, p1, pos, t) + + + # Pressure & velocity var sensitivity: float = Settings.get_value( Settings.GENERAL_PRESSURE_SENSITIVITY, Config.DEFAULT_PRESSURE_SENSITIVITY ) + if _current_pressure >= 0.99: + _current_pressure -= min(_current_velocity * 1.5, 0.33) + else: + _current_pressure -= min(_current_velocity, 0.33) + var point_pressure := pressure_curve.sample(_current_pressure) * sensitivity add_stroke_point(pos, point_pressure) diff --git a/lorien/InfiniteCanvas/default_pressure_curve.tres b/lorien/InfiniteCanvas/default_pressure_curve.tres index ced00564..66a95c58 100644 --- a/lorien/InfiniteCanvas/default_pressure_curve.tres +++ b/lorien/InfiniteCanvas/default_pressure_curve.tres @@ -1,4 +1,5 @@ -[gd_resource type="Curve" format=2] +[gd_resource type="Curve" format=3 uid="uid://bgd7v60kyywsk"] [resource] -_data = [ Vector2( 0, 0.105263 ), 0.0, 0.210526, 0, 0, Vector2( 0.789286, 0.45614 ), 1.07456, 1.07456, 0, 0, Vector2( 1, 1 ), 3.50877, 0.0, 0, 0 ] +_data = [Vector2(0, 0.252555), 0.0, 0.747445, 0, 1, Vector2(1, 1), 0.747445, 0.0, 1, 0] +point_count = 2 diff --git a/lorien/Main.gd b/lorien/Main.gd index f3b5c966..48ae0409 100644 --- a/lorien/Main.gd +++ b/lorien/Main.gd @@ -128,7 +128,7 @@ func _exit_tree() -> void: # ------------------------------------------------------------------------------------------------- func _process(delta: float) -> void: # Lower fps if user is idle - if (Time.get_ticks_msec() - _last_input_time) > Config.BACKGROUND_IDLE_TIME_THRESHOLD: + if !_canvas.is_drawing() && (Time.get_ticks_msec() - _last_input_time) > Config.BACKGROUND_IDLE_TIME_THRESHOLD: Engine.max_fps = Settings.get_value(Settings.RENDERING_BACKGROUND_FPS, Config.DEFAULT_BACKGROUND_FPS) # Upate statusbar