From 967e20af509872038fb51d1d42c830854efa70c2 Mon Sep 17 00:00:00 2001 From: Marcus Brummer Date: Tue, 24 Sep 2024 11:37:47 +0200 Subject: [PATCH] Improved brush quality --- lorien/BrushStroke/BrushStroke.gd | 20 +++++++++----------- lorien/BrushStroke/BrushStrokeOptimizer.gd | 7 +++++++ lorien/InfiniteCanvas/Tools/BrushTool.gd | 18 +++++++++--------- lorien/ProjectManager/Serializer.gd | 5 +++-- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/lorien/BrushStroke/BrushStroke.gd b/lorien/BrushStroke/BrushStroke.gd index 52406b20..8f96fabb 100644 --- a/lorien/BrushStroke/BrushStroke.gd +++ b/lorien/BrushStroke/BrushStroke.gd @@ -3,9 +3,9 @@ class_name BrushStroke # ------------------------------------------------------------------------------------------------ const MAX_POINTS := 1000 -const MAX_PRESSURE_VALUE := 255 -const MIN_PRESSURE_VALUE := 30 -const MAX_PRESSURE_DIFF := 20 +const MAX_PRESSURE_DIFF := 0.1 +const MIN_PRESSURE_VALUE := 0.1 +const MAX_PRESSURE_VALUE := 1.0 const COLLIDER_NODE_NAME := "StrokeCollider" const GROUP_ONSCREEN := "onscreen_stroke" @@ -51,18 +51,16 @@ func _to_string() -> String: # ------------------------------------------------------------------------------------------------- func add_point(point: Vector2, pressure: float) -> void: - var converted_pressure := int(floor(pressure * MAX_PRESSURE_VALUE)) - # Smooth out pressure values (on Linux i sometimes get really high pressure spikes) if !pressures.is_empty(): - var last_pressure: int = pressures.back() - var pressure_diff := converted_pressure - last_pressure + var last_pressure: float = pressures.back() + var pressure_diff := pressure - last_pressure if abs(pressure_diff) > MAX_PRESSURE_DIFF: - converted_pressure = last_pressure + sign(pressure_diff) * MAX_PRESSURE_DIFF - converted_pressure = clamp(converted_pressure, MIN_PRESSURE_VALUE, MAX_PRESSURE_VALUE) + pressure = last_pressure + sign(pressure_diff) * MAX_PRESSURE_DIFF + pressure = clamp(pressure, MIN_PRESSURE_VALUE, MAX_PRESSURE_VALUE) points.append(point) - pressures.append(converted_pressure) + pressures.append(pressure) # ------------------------------------------------------------------------------------------------ func remove_last_point() -> void: @@ -124,7 +122,7 @@ func refresh() -> void: # Add the point _line2d.add_point(point) var pressure: float = pressures[p_idx] - _line2d.width_curve.add_point(Vector2(curve_step*p_idx, pressure / max_pressure)) + _line2d.width_curve.add_point(Vector2(curve_step * p_idx, pressure / max_pressure)) p_idx += 1 # Update the extreme values diff --git a/lorien/BrushStroke/BrushStrokeOptimizer.gd b/lorien/BrushStroke/BrushStrokeOptimizer.gd index 3ef1f276..4080a3c4 100644 --- a/lorien/BrushStroke/BrushStrokeOptimizer.gd +++ b/lorien/BrushStroke/BrushStrokeOptimizer.gd @@ -1,6 +1,10 @@ class_name BrushStrokeOptimizer +# NOTE: this implementation is currently too aggressive and has a negative effect on user experience. +# Until it is visually undetectable by the user that the strokes were optimized, this will stay disabled. + # ------------------------------------------------------------------------------------------------- +const ENABLED := false const ANGLE_THRESHOLD := 0.5 const DISTANCE_THRESHOLD := 1.0 @@ -13,6 +17,9 @@ func reset() -> void: # ------------------------------------------------------------------------------------------------- func optimize(s: BrushStroke) -> void: + if !ENABLED: + return + if s.points.size() < 8: return diff --git a/lorien/InfiniteCanvas/Tools/BrushTool.gd b/lorien/InfiniteCanvas/Tools/BrushTool.gd index 60c1dfd7..143231d2 100644 --- a/lorien/InfiniteCanvas/Tools/BrushTool.gd +++ b/lorien/InfiniteCanvas/Tools/BrushTool.gd @@ -3,16 +3,16 @@ extends CanvasTool # ------------------------------------------------------------------------------------------------- const MOVEMENT_THRESHOLD := 1.0 -const MIN_PRESSURE := 0.1 -const DOT_MAX_DISTANCE_THRESHOLD := 4.0 +const MIN_PRESSURE := 0.25 +const DOT_MAX_DISTANCE_THRESHOLD := 6.0 # ------------------------------------------------------------------------------------------------- @export var pressure_curve: Curve # ------------------------------------------------------------------------------------------------- var _current_pressure: float +var _moved := false var _last_accepted_position: Vector2 -var _first_point := false # ------------------------------------------------------------------------------------------------- func tool_event(event: InputEvent) -> void: @@ -21,6 +21,7 @@ func tool_event(event: InputEvent) -> void: if event is InputEventMouseMotion: _current_pressure = event.pressure if performing_stroke: + _moved = true _cursor.set_pressure(event.pressure) if zooming_detected && performing_stroke: end_stroke() @@ -29,7 +30,6 @@ func tool_event(event: InputEvent) -> void: if event.button_index == MOUSE_BUTTON_LEFT: if event.pressed: start_stroke() - _first_point = true elif performing_stroke: if _is_stroke_a_dot(): _canvas.remove_all_stroke_points() @@ -41,10 +41,14 @@ func _process(delta: float) -> void: if performing_stroke: var pos := _cursor.global_position + if !_moved: + return + _moved = false + var diff := pos.distance_squared_to(_last_accepted_position) if diff <= MOVEMENT_THRESHOLD || _current_pressure <= MIN_PRESSURE: return - + # Stabilizer smoothing var stabilizer_strength: float = Settings.get_value( Settings.GENERAL_STABILIZER_STRENGTH, Config.DEFAULT_STABILIZER_STRENGTH @@ -59,16 +63,12 @@ func _process(delta: float) -> void: var t := 0.5 + (1.0 - stabilizer_strength) * 0.5 pos = Utils.cubic_bezier(p3, p2, p1, pos, t) - # Pressure var sensitivity: float = Settings.get_value( Settings.GENERAL_PRESSURE_SENSITIVITY, Config.DEFAULT_PRESSURE_SENSITIVITY ) var point_pressure := pressure_curve.sample(_current_pressure) * sensitivity - if _first_point: - point_pressure *= 1.4 - _first_point = false add_stroke_point(pos, point_pressure) diff --git a/lorien/ProjectManager/Serializer.gd b/lorien/ProjectManager/Serializer.gd index 3dced9ab..bf348f28 100644 --- a/lorien/ProjectManager/Serializer.gd +++ b/lorien/ProjectManager/Serializer.gd @@ -49,7 +49,8 @@ static func save_project(project: Project) -> void: # Add global_position offset which is != 0 when moved by move tool; but mostly it should just add 0 file.store_float(p.x + stroke.global_position.x) file.store_float(p.y + stroke.global_position.y) - file.store_8(stroke.pressures[p_idx]) + var pressure: int = clamp(int(stroke.pressures[p_idx] * 255), 0, 255) + file.store_8(pressure) p_idx += 1 # Done @@ -100,7 +101,7 @@ static func load_project(project: Project) -> void: for i: int in point_count: var x := file.get_float() var y := file.get_float() - var pressure := file.get_8() + var pressure := float(file.get_8()) / 255.0 brush_stroke.points.append(Vector2(x, y)) brush_stroke.pressures.append(pressure)