mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
fix(globe): Navara lines are picked within 8 px of their segments
Review of Task 4: the CPU line pick (shared with the sprite drill, hover and the synchronous pick) took half the drawn width + 3 px, so a 1-2 px trail needed a 3.5-4 px aim. Now within 8 px of the projected segments, or half the width + 3 px for wider lines. Tested at 7.5 and 8.5 px from a 1 px line; the contract suite's line click passes on both engines.
This commit is contained in:
1 parent
e804351205
commit
93866c42fc
2 files changed
+31
-3
No files matched your search
@@ -1,7 +1,7 @@
|
|||||||
// CPU picks of movers and lines for every engine that needs them (Navara's
|
// CPU picks of movers and lines for every engine that needs them (Navara's
|
||||||
// hover, drill and synchronous pick, the fake engine): projected positions
|
// hover, drill and synchronous pick, the fake engine): projected positions
|
||||||
// within the drawn size (+3 px, Navara's PICK_RADIUS), lines within half
|
// within the drawn size (+3 px, Navara's PICK_RADIUS), lines within 8 px
|
||||||
// their width (+3 px), hidden behind the globe excluded, nearest to the
|
// (or half their width + 3 px when wider), hidden behind the globe excluded, nearest to the
|
||||||
// camera first. Pure: src/geo and the engine's projector only.
|
// camera first. Pure: src/geo and the engine's projector only.
|
||||||
|
|
||||||
import * as geo from '../geo/index.js';
|
import * as geo from '../geo/index.js';
|
||||||
@@ -12,6 +12,8 @@ const scratchScreen = { x: 0, y: 0 };
|
|||||||
const scratchScreenB = { x: 0, y: 0 };
|
const scratchScreenB = { x: 0, y: 0 };
|
||||||
|
|
||||||
export const PICK_RADIUS_PX = 3;
|
export const PICK_RADIUS_PX = 3;
|
||||||
|
/** A line is picked within 8 px of its drawn segments (thin trails too). */
|
||||||
|
export const LINE_PICK_PX = 8;
|
||||||
|
|
||||||
/** Distance from point p to segment ab (2D). */
|
/** Distance from point p to segment ab (2D). */
|
||||||
export function distanceToSegment(p, a, b) {
|
export function distanceToSegment(p, a, b) {
|
||||||
@@ -102,7 +104,10 @@ export function createCpuPicker({ projector, camera, movers, lines }) {
|
|||||||
function lineHits(at, hits) {
|
function lineHits(at, hits) {
|
||||||
for (const { options, flat, modelMatrix } of lines()) {
|
for (const { options, flat, modelMatrix } of lines()) {
|
||||||
if (options.pickId === undefined) continue;
|
if (options.pickId === undefined) continue;
|
||||||
const limit = options.widthPx / 2 + PICK_RADIUS_PX;
|
const limit = Math.max(
|
||||||
|
LINE_PICK_PX,
|
||||||
|
options.widthPx / 2 + PICK_RADIUS_PX,
|
||||||
|
);
|
||||||
let best = null;
|
let best = null;
|
||||||
for (let index = 0; index + 1 < flat.length / 3; index++) {
|
for (let index = 0; index + 1 < flat.length / 3; index++) {
|
||||||
const a = transformed(modelMatrix, flat, index, scratch);
|
const a = transformed(modelMatrix, flat, index, scratch);
|
||||||
|
|||||||
@@ -249,3 +249,26 @@ test('a GPU answer naming an instance drawn far from the click is stale', async
|
|||||||
assert.equal((await answer).id, 'drawn-here');
|
assert.equal((await answer).id, 'drawn-here');
|
||||||
assert.equal(picking.clickStats().stale, 1);
|
assert.equal(picking.clickStats().stale, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('a thin line is picked within 8 px of its segments', () => {
|
||||||
|
const line = {
|
||||||
|
options: normalizeLineOptions({
|
||||||
|
id: 'trail',
|
||||||
|
widthPx: 1,
|
||||||
|
color: [1, 1, 1, 1],
|
||||||
|
pickId: 'trail-1',
|
||||||
|
}),
|
||||||
|
flat: new Float64Array([0, 50, 100, 200, 50, 100]),
|
||||||
|
modelMatrix: null,
|
||||||
|
};
|
||||||
|
const picking = createNavaraPicking({
|
||||||
|
view: fakeView(),
|
||||||
|
projector,
|
||||||
|
camera,
|
||||||
|
movers: () => [],
|
||||||
|
lines: () => [line],
|
||||||
|
resolveBatch: () => null,
|
||||||
|
});
|
||||||
|
assert.equal(picking.pick({ x: 100, y: 57.5 })?.id, 'trail-1');
|
||||||
|
assert.equal(picking.pick({ x: 100, y: 58.5 }), undefined);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user