Skip to content

Commit 922140f

Browse files
committed
Guard against zero-length input delta and respect spacing parameter when computing blit points.
1 parent dabc440 commit 922140f

2 files changed

Lines changed: 15 additions & 10 deletions

File tree

frontend/src/utility-functions/input.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ export function onPointerMove(e: PointerEvent, editor: EditorWrapper, documentSt
123123

124124
const modifiers = makeKeyboardModifiersBitfield(e);
125125
if (e.pointerType == "pen" && e.isPrimary) {
126+
// "Shake" is not an ergonomic gesture for pen input, so we don't attempt to detect it.
126127
editor.onPointerMove(e.clientX, e.clientY, e.pressure, e.tangentialPressure, e.azimuthAngle, e.altitudeAngle, e.twist, e.buttons, modifiers);
127128
} else {
128129
if (detectShake(e)) editor.onMouseShake(e.clientX, e.clientY, e.buttons, modifiers);

node-graph/nodes/brush/src/brush_stroke.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ use core_types::color::Color;
44
use core_types::math::bbox::AxisAlignedBbox;
55
use dyn_any::DynAny;
66
use glam::DVec2;
7-
use std::{
8-
hash::{Hash, Hasher},
9-
thread::current,
10-
};
7+
use std::hash::{Hash, Hasher};
118

129
/// The style of a brush.
1310
#[derive(Clone, Debug, CacheHash, DynAny, serde::Serialize, serde::Deserialize)]
@@ -97,34 +94,41 @@ impl BrushStroke {
9794
pub fn compute_blit_points(&self) -> Vec<BrushOutputSample> {
9895
// We always travel in a straight line towards the next user input,
9996
// placing a blit point every time we travelled our spacing distance.
100-
let spacing_dist = self.style.spacing / 100. * self.style.diameter;
97+
let spacing_dist = (self.style.spacing / 100.) * self.style.diameter;
10198
if self.trace.is_empty() {
10299
return Vec::new();
103100
};
104101

102+
// We currently treat all input samples as blit points, so capture the very first input
105103
let mut result = vec![BrushOutputSample {
106104
position: self.trace[0].position,
107105
scale: self.trace[0].pressure,
108106
}];
109107

108+
// We iterate over all input points in a sliding pair window. We take uniform
109+
// steps of length equal to our spacing distance between the input points, and
110+
// linearly interpolate pressure.
110111
for samples in self.trace.windows(2) {
111112
let position_delta = (samples[1].position - samples[0].position).length();
112-
let unit_step = (samples[1].position - samples[0].position).normalize();
113+
if position_delta < f64::EPSILON {
114+
continue;
115+
}
116+
let unit_step = (samples[1].position - samples[0].position).normalize() * spacing_dist;
113117
let pressure_delta = samples[1].pressure - samples[0].pressure;
114118
let mut current_position = samples[0].position + unit_step;
115119
loop {
116-
let step = (samples[1].position - current_position).length();
117-
if step < spacing_dist {
120+
let remaining = (samples[1].position - current_position).length();
121+
if remaining < spacing_dist {
118122
break;
119123
}
120-
// let t64 = t as f64;
121124
result.push(BrushOutputSample {
122125
position: current_position,
123-
scale: samples[1].pressure - (step / position_delta) * pressure_delta,
126+
scale: samples[1].pressure - (remaining / position_delta) * pressure_delta,
124127
});
125128
current_position += unit_step;
126129
}
127130

131+
// We currently treat all input samples as blit points, so append the second of each pair
128132
result.push(BrushOutputSample {
129133
position: samples[1].position,
130134
scale: samples[1].pressure,

0 commit comments

Comments
 (0)