Browse Source

Add line-line intersection test to the eraser to kinda make it work for faster movement

ssao
A.Olokhtonov 5 months ago
parent
commit
b11c46354f
  1. 6
      README.txt
  2. 2
      client/bvh.js
  3. 13
      client/math.js
  4. 14
      client/webgl_listeners.js

6
README.txt

@ -16,7 +16,6 @@ Release: @@ -16,7 +16,6 @@ Release:
+ Stroke previews get connected when drawn without panning on touch devices
+ Redraw HTML (cursors) on local canvas moves
+ New strokes dissapear on the HMH desk
- Color picker misses on strange line endings
- Debug
- Restore ability to limit event range
* Listeners/events/multiplayer
@ -42,11 +41,12 @@ Release: @@ -42,11 +41,12 @@ Release:
+ EYE DROPPER!
+ Dynamic svg cursor to represent the brush
+ Eraser
- Line drawing
* Line drawing
+ Undo
- Undo for images (add, move, scale)
- Undo for eraser
- Redo
- Snapping to grid
* Polish
+ Use typedvector where appropriate
- Show what's happening while the desk is loading (downloading, processing, uploading to gpu)
@ -54,7 +54,7 @@ Release: @@ -54,7 +54,7 @@ Release:
- Set up VAOs
- We are calling "geometry_prepare_stroke" twice for some reason
- Presentation / "marketing"
- Title (InfiNotes?)
- Title (InfiNotes? MegaDesk?)
- Icon
- Product page (github readme, demo videos)

2
client/bvh.js

@ -164,7 +164,7 @@ function bvh_delete_stroke(state, stroke) { @@ -164,7 +164,7 @@ function bvh_delete_stroke(state, stroke) {
while (node.parent_index !== null) {
if (node.is_fullnode) {
let index_index = node.stroke_indices.data.indexOf(stroke.index);
let index_index = tv_data(node.stroke_indices).indexOf(stroke.index);
if (index_index !== -1) {
node.stroke_indices.data[index_index] = node.stroke_indices.data[node.stroke_indices.size - 1];
tv_pop(node.stroke_indices);

13
client/math.js

@ -436,7 +436,7 @@ function circle_intersects_capsule(ax, ay, bx, by, p1, p2, cx, cy, r) { @@ -436,7 +436,7 @@ function circle_intersects_capsule(ax, ay, bx, by, p1, p2, cx, cy, r) {
return dist <= r;
}
function stroke_intersects_cursor(state, stroke, canvasp, radius) {
function stroke_intersects_capsule(state, stroke, a, b, radius) {
const xs = state.wasm.buffers['xs'].tv.data;
const ys = state.wasm.buffers['ys'].tv.data;
const pressures = state.wasm.buffers['pressures'].tv.data;
@ -449,8 +449,17 @@ function stroke_intersects_cursor(state, stroke, canvasp, radius) { @@ -449,8 +449,17 @@ function stroke_intersects_cursor(state, stroke, canvasp, radius) {
const p1 = pressures[i + 0];
const p2 = pressures[i + 1];
// Test if p1 or p2 overlap the capsule
if (circle_intersects_capsule(x1, y1, x2, y2, p1 * stroke.width / 255, p2 * stroke.width / 255, a.x, a.y, radius)) {
return true;
}
if (circle_intersects_capsule(x1, y1, x2, y2, p1 * stroke.width / 255, p2 * stroke.width / 255, b.x, b.y, radius)) {
return true;
}
if (circle_intersects_capsule(x1, y1, x2, y2, p1 * stroke.width / 255, p2 * stroke.width / 255, canvasp.x, canvasp.y, radius)) {
// Lame test for the quad part, only test for line-line intersection
// TODO: actually test for rotated quad vs circle/rotated quad overlap
if (segments_intersect(a, b, {'x': x1, 'y': y1}, {'x': x2, 'y': y2})) {
return true;
}
}

14
client/webgl_listeners.js

@ -383,23 +383,27 @@ function mousemove(e, state, context) { @@ -383,23 +383,27 @@ function mousemove(e, state, context) {
if (state.erasing) {
const me = state.players[state.me];
const radius = Math.round(me.width / 2);
const last_canvasp = screen_to_canvas(state, state.cursor);
const cursor_bbox = {
'x1': canvasp.x - radius,
'y1': canvasp.y - radius,
'x2': canvasp.x + radius,
'y2': canvasp.y + radius,
'x1': Math.min(canvasp.x, last_canvasp.x) - radius,
'y1': Math.min(canvasp.y, last_canvasp.y) - radius,
'x2': Math.max(canvasp.x, last_canvasp.x) + radius,
'y2': Math.max(canvasp.y, last_canvasp.y) + radius,
};
tv_ensure(state.erase_candidates, round_to_pow2(state.stroke_count, 4096));
tv_clear(state.erase_candidates);
// Rough pass, not all of these might actually need to be erased
bvh_intersect_quad(state, state.bvh, cursor_bbox, state.erase_candidates);
// Fine pass, actually run expensive capsule vs capsule intersection tests
for (let i = 0; i < state.erase_candidates.size; ++i) {
const stroke_id = state.erase_candidates.data[i];
const stroke = state.events[stroke_id];
if (!stroke.deleted && stroke_intersects_cursor(state, stroke, canvasp, radius)) {
if (!stroke.deleted && stroke_intersects_capsule(state, stroke, last_canvasp, canvasp, radius)) {
stroke.deleted = true;
bvh_delete_stroke(state, stroke);
queue_event(state, eraser_event(stroke_id));

Loading…
Cancel
Save