mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 03:14: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
|
||||
// hover, drill and synchronous pick, the fake engine): projected positions
|
||||
// within the drawn size (+3 px, Navara's PICK_RADIUS), lines within half
|
||||
// their width (+3 px), hidden behind the globe excluded, nearest to the
|
||||
// within the drawn size (+3 px, Navara's PICK_RADIUS), lines within 8 px
|
||||
// (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.
|
||||
|
||||
import * as geo from '../geo/index.js';
|
||||
@@ -12,6 +12,8 @@ const scratchScreen = { x: 0, y: 0 };
|
||||
const scratchScreenB = { x: 0, y: 0 };
|
||||
|
||||
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). */
|
||||
export function distanceToSegment(p, a, b) {
|
||||
@@ -102,7 +104,10 @@ export function createCpuPicker({ projector, camera, movers, lines }) {
|
||||
function lineHits(at, hits) {
|
||||
for (const { options, flat, modelMatrix } of lines()) {
|
||||
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;
|
||||
for (let index = 0; index + 1 < flat.length / 3; index++) {
|
||||
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(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