|
|
|
@ -89,9 +89,11 @@ function bvh_find_best_sibling(bvh, leaf_index) {
@@ -89,9 +89,11 @@ function bvh_find_best_sibling(bvh, leaf_index) {
|
|
|
|
|
return best_index; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function bvh_add_stroke(bvh, index, stroke) { |
|
|
|
|
function bvh_add_stroke(state, bvh, index, stroke) { |
|
|
|
|
const leaf_index = bvh_make_leaf(bvh, index, stroke); |
|
|
|
|
|
|
|
|
|
stroke.bvh_node = leaf_index; |
|
|
|
|
|
|
|
|
|
if (bvh.nodes.length === 1) { |
|
|
|
|
bvh.root = leaf_index; |
|
|
|
|
return; |
|
|
|
@ -157,7 +159,22 @@ function bvh_add_stroke(bvh, index, stroke) {
@@ -157,7 +159,22 @@ function bvh_add_stroke(bvh, index, stroke) {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function bvh_intersect_quad(bvh, quad, result_buffer) { |
|
|
|
|
function bvh_delete_stroke(state, stroke) { |
|
|
|
|
let node = state.bvh.nodes[stroke.bvh_node]; |
|
|
|
|
|
|
|
|
|
while (node.parent_index !== null) { |
|
|
|
|
if (node.is_fullnode) { |
|
|
|
|
let index_index = node.stroke_indices.data.indexOf(stroke.index); |
|
|
|
|
node.stroke_indices.data[index_index] = node.stroke_indices.data[node.stroke_indices.size - 1]; |
|
|
|
|
tv_pop(node.stroke_indices); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
node = state.bvh.nodes[node.parent_index]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function bvh_intersect_quad(state, bvh, quad, result_buffer) { |
|
|
|
|
if (bvh.root === null) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -181,7 +198,9 @@ function bvh_intersect_quad(bvh, quad, result_buffer) {
@@ -181,7 +198,9 @@ function bvh_intersect_quad(bvh, quad, result_buffer) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (node.is_leaf) { |
|
|
|
|
if (state.events[node.stroke_index].deleted !== true) { |
|
|
|
|
tv_add(result_buffer, node.stroke_index); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
tv_add(bvh.traverse_stack, node.child1); |
|
|
|
|
tv_add(bvh.traverse_stack, node.child2); |
|
|
|
@ -211,7 +230,7 @@ function bvh_clip(state, context) {
@@ -211,7 +230,7 @@ function bvh_clip(state, context) {
|
|
|
|
|
'y2': screen_bottomright.y |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
bvh_intersect_quad(state.bvh, screen, context.clipped_indices); |
|
|
|
|
bvh_intersect_quad(state, state.bvh, screen, context.clipped_indices); |
|
|
|
|
|
|
|
|
|
tv_data(context.clipped_indices).sort(); // we need to draw back to front still!
|
|
|
|
|
} |
|
|
|
@ -241,7 +260,7 @@ function bvh_point(state, p) {
@@ -241,7 +260,7 @@ function bvh_point(state, p) {
|
|
|
|
|
const ys = state.wasm.buffers['ys'].tv.data.subarray(stroke.coords_from, stroke.coords_to); |
|
|
|
|
const pressures = state.wasm.buffers['pressures'].tv.data.subarray(stroke.coords_from, stroke.coords_to); |
|
|
|
|
|
|
|
|
|
if (point_in_stroke(p, xs, ys, pressures, stroke.width)) { |
|
|
|
|
if (stroke.deleted !== true && point_in_stroke(p, xs, ys, pressures, stroke.width)) { |
|
|
|
|
indices.push(node.stroke_index); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -258,7 +277,7 @@ function bvh_point(state, p) {
@@ -258,7 +277,7 @@ function bvh_point(state, p) {
|
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function bvh_construct_rec(bvh, vertical, strokes, depth) { |
|
|
|
|
function bvh_construct_rec(state, bvh, vertical, strokes, depth) { |
|
|
|
|
if (strokes.length > 1) { |
|
|
|
|
// internal
|
|
|
|
|
let sorted_strokes; |
|
|
|
@ -272,8 +291,8 @@ function bvh_construct_rec(bvh, vertical, strokes, depth) {
@@ -272,8 +291,8 @@ function bvh_construct_rec(bvh, vertical, strokes, depth) {
|
|
|
|
|
const node_index = bvh_make_internal(bvh); |
|
|
|
|
const left_of_split_count = Math.floor(strokes.length / 2); |
|
|
|
|
|
|
|
|
|
const child1 = bvh_construct_rec(bvh, !vertical, sorted_strokes.slice(0, left_of_split_count), depth + 1); |
|
|
|
|
const child2 = bvh_construct_rec(bvh, !vertical, sorted_strokes.slice(left_of_split_count, sorted_strokes.length), depth + 1); |
|
|
|
|
const child1 = bvh_construct_rec(state, bvh, !vertical, sorted_strokes.slice(0, left_of_split_count), depth + 1); |
|
|
|
|
const child2 = bvh_construct_rec(state, bvh, !vertical, sorted_strokes.slice(left_of_split_count, sorted_strokes.length), depth + 1); |
|
|
|
|
|
|
|
|
|
bvh.nodes[child1].parent_index = node_index; |
|
|
|
|
bvh.nodes[child2].parent_index = node_index; |
|
|
|
@ -296,12 +315,15 @@ function bvh_construct_rec(bvh, vertical, strokes, depth) {
@@ -296,12 +315,15 @@ function bvh_construct_rec(bvh, vertical, strokes, depth) {
|
|
|
|
|
return node_index; |
|
|
|
|
} else { |
|
|
|
|
// leaf
|
|
|
|
|
return bvh_make_leaf(bvh, strokes[0].index, strokes[0]); |
|
|
|
|
const leaf_index = bvh_make_leaf(bvh, strokes[0].index, strokes[0]); |
|
|
|
|
state.events[strokes[0].index].bvh_node = leaf_index; |
|
|
|
|
return leaf_index; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function bvh_construct(state) { |
|
|
|
|
if (state.events.length > 0) { |
|
|
|
|
state.bvh.root = bvh_construct_rec(state.bvh, true, state.events, 0); |
|
|
|
|
const strokes = state.events.filter(e => e.type === EVENT.STROKE && e.deleted !== true); |
|
|
|
|
if (strokes.length > 0) { |
|
|
|
|
state.bvh.root = bvh_construct_rec(state, state.bvh, true, strokes, 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|