@flighthq/picking 0.2.1-next.738.07b221d → 0.2.1-next.841.373388f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pickScene3D.d.ts +7 -0
- package/dist/pickScene3D.d.ts.map +1 -0
- package/dist/{pickScene.js → pickScene3D.js} +28 -28
- package/dist/pickScene3D.js.map +1 -0
- package/dist/sceneHitAttributes.d.ts +8 -8
- package/dist/sceneHitAttributes.d.ts.map +1 -1
- package/dist/sceneHitAttributes.js +9 -9
- package/dist/sceneHitAttributes.js.map +1 -1
- package/package.json +8 -8
- package/src/{pickScene.test.ts → pickScene3D.test.ts} +84 -78
- package/src/sceneHitAttributes.test.ts +31 -31
- package/dist/pickScene.d.ts +0 -7
- package/dist/pickScene.d.ts.map +0 -1
- package/dist/pickScene.js.map +0 -1
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Camera3D, Ray3D, Scene3DHit, Node3D, Scene3DPickOptions } from '@flighthq/types';
|
|
2
|
+
export declare function createScene3DHit(): Scene3DHit;
|
|
3
|
+
export declare function pickScene3D(scene: Readonly<Node3D>, camera: Readonly<Camera3D>, screenX: number, screenY: number, out: Scene3DHit, options?: Readonly<Scene3DPickOptions>): Scene3DHit | null;
|
|
4
|
+
export declare function pickScene3DAll(scene: Readonly<Node3D>, camera: Readonly<Camera3D>, screenX: number, screenY: number, outArray: Scene3DHit[], options?: Readonly<Scene3DPickOptions>): Scene3DHit[];
|
|
5
|
+
export declare function pickScene3DAllWithRay3D(scene: Readonly<Node3D>, ray: Readonly<Ray3D>, outArray: Scene3DHit[], options?: Readonly<Scene3DPickOptions>): Scene3DHit[];
|
|
6
|
+
export declare function pickScene3DWithRay3D(scene: Readonly<Node3D>, ray: Readonly<Ray3D>, out: Scene3DHit, options?: Readonly<Scene3DPickOptions>): Scene3DHit | null;
|
|
7
|
+
//# sourceMappingURL=pickScene3D.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickScene3D.d.ts","sourceRoot":"","sources":["../src/pickScene3D.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,QAAQ,EAIR,KAAK,EACL,UAAU,EACV,MAAM,EACN,kBAAkB,EAEnB,MAAM,iBAAiB,CAAC;AAIzB,wBAAgB,gBAAgB,IAAI,UAAU,CAe7C;AAQD,wBAAgB,WAAW,CACzB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,UAAU,EACf,OAAO,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GACrC,UAAU,GAAG,IAAI,CAGnB;AAKD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,UAAU,EAAE,EACtB,OAAO,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GACrC,UAAU,EAAE,CAMd;AAMD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,EACpB,QAAQ,EAAE,UAAU,EAAE,EACtB,OAAO,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GACrC,UAAU,EAAE,CAcd;AAcD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,EACpB,GAAG,EAAE,UAAU,EACf,OAAO,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GACrC,UAAU,GAAG,IAAI,CAUnB"}
|
|
@@ -3,10 +3,10 @@ import { createEntity } from '@flighthq/entity';
|
|
|
3
3
|
import { createAabb, createMatrix4, createRay3D, createVector3, getRay3DPointAt, intersectRay3DAabb, intersectRay3DTriangle, inverseMatrix4, transformAabbByMatrix4, } from '@flighthq/geometry';
|
|
4
4
|
import { getMeshGeometryTriangleCount, getMeshGeometryTriangleVertexIndices, getMeshGeometryVertexPosition, } from '@flighthq/mesh';
|
|
5
5
|
import { ensureNodeWorldMatrix4, getNodeRuntime, getNodeWorldMatrix4 } from '@flighthq/node';
|
|
6
|
-
import {
|
|
7
|
-
// Allocates a zeroed
|
|
6
|
+
import { getNode3DWorldBounds, isMesh } from '@flighthq/scene3d';
|
|
7
|
+
// Allocates a zeroed Scene3DHit. Handy for the `out` of `pickScene3D`/`pickScene3DWithRay3D` and for
|
|
8
8
|
// growing the `outArray` of the multi-hit queries. `node` is null until a pick fills it.
|
|
9
|
-
export function
|
|
9
|
+
export function createScene3DHit() {
|
|
10
10
|
return createEntity({
|
|
11
11
|
distance: 0,
|
|
12
12
|
node: null,
|
|
@@ -25,45 +25,45 @@ export function createSceneHit() {
|
|
|
25
25
|
// Resolves the nearest Mesh hit by a camera pick ray through a scene, filling `out` and returning it,
|
|
26
26
|
// or `null` on a miss (sentinel, not a throw). `screenX`/`screenY` are normalized device coordinates
|
|
27
27
|
// in [-1, 1] (the viewport→NDC mapping is the caller's responsibility, mirroring the camera unproject).
|
|
28
|
-
// A thin wrapper: it unprojects the camera ray, then delegates to `
|
|
28
|
+
// A thin wrapper: it unprojects the camera ray, then delegates to `pickScene3DWithRay3D`.
|
|
29
29
|
//
|
|
30
30
|
// Alias-safe: `out` is only written when a hit is found; on a miss `out` is untouched.
|
|
31
|
-
export function
|
|
31
|
+
export function pickScene3D(scene, camera, screenX, screenY, out, options) {
|
|
32
32
|
if (!buildCameraPickRay(_cameraRay, camera, screenX, screenY))
|
|
33
33
|
return null;
|
|
34
|
-
return
|
|
34
|
+
return pickScene3DWithRay3D(scene, _cameraRay, out, options);
|
|
35
35
|
}
|
|
36
36
|
// Collects every Mesh hit by a camera pick ray into `outArray`, sorted by ascending distance, and
|
|
37
|
-
// returns `outArray`. A thin wrapper over `
|
|
37
|
+
// returns `outArray`. A thin wrapper over `pickScene3DAllWithRay3D` that first unprojects the camera
|
|
38
38
|
// ray; on an unprojectable camera the array is emptied and returned.
|
|
39
|
-
export function
|
|
39
|
+
export function pickScene3DAll(scene, camera, screenX, screenY, outArray, options) {
|
|
40
40
|
if (!buildCameraPickRay(_cameraRay, camera, screenX, screenY)) {
|
|
41
41
|
outArray.length = 0;
|
|
42
42
|
return outArray;
|
|
43
43
|
}
|
|
44
|
-
return
|
|
44
|
+
return pickScene3DAllWithRay3D(scene, _cameraRay, outArray, options);
|
|
45
45
|
}
|
|
46
46
|
// Collects every Mesh hit by a world-space `ray` into `outArray`, sorted by ascending distance, and
|
|
47
47
|
// returns `outArray` (its `length` is set to the hit count; empty on a miss). Existing slots are
|
|
48
48
|
// reused and new ones allocated as needed, so the array can be kept and refilled across picks. The
|
|
49
|
-
// general primitive behind `
|
|
50
|
-
export function
|
|
49
|
+
// general primitive behind `pickScene3DAll`; the ray need not be unit-length (see `Scene3DPickOptions`).
|
|
50
|
+
export function pickScene3DAllWithRay3D(scene, ray, outArray, options) {
|
|
51
51
|
let count = 0;
|
|
52
|
-
|
|
52
|
+
forEachScene3DRayHit(scene, ray, options, (hit) => {
|
|
53
53
|
let slot = outArray[count];
|
|
54
54
|
if (slot === undefined) {
|
|
55
|
-
slot =
|
|
55
|
+
slot = createScene3DHit();
|
|
56
56
|
outArray[count] = slot;
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
copyScene3DHit(slot, hit);
|
|
59
59
|
count++;
|
|
60
60
|
});
|
|
61
61
|
outArray.length = count;
|
|
62
|
-
outArray.sort(
|
|
62
|
+
outArray.sort(compareScene3DHitByDistance);
|
|
63
63
|
return outArray;
|
|
64
64
|
}
|
|
65
65
|
// Resolves the nearest Mesh hit by a world-space `ray` through a scene, filling `out` and returning
|
|
66
|
-
// it, or `null` on a miss. The general primitive behind `
|
|
66
|
+
// it, or `null` on a miss. The general primitive behind `pickScene3D`: `pickScene3D` builds the ray from
|
|
67
67
|
// a camera and delegates here. The ray direction need not be unit-length; `t` (and `out.distance`)
|
|
68
68
|
// is in direction-length units.
|
|
69
69
|
//
|
|
@@ -74,15 +74,15 @@ export function pickSceneAllWithRay3D(scene, ray, outArray, options) {
|
|
|
74
74
|
// `t` stays in world-ray units and is comparable across meshes.
|
|
75
75
|
//
|
|
76
76
|
// Alias-safe: `out` is only written when a nearer hit is found; on a miss `out` is untouched.
|
|
77
|
-
export function
|
|
77
|
+
export function pickScene3DWithRay3D(scene, ray, out, options) {
|
|
78
78
|
let found = false;
|
|
79
79
|
let bestT = Infinity;
|
|
80
|
-
|
|
80
|
+
forEachScene3DRayHit(scene, ray, options, (hit) => {
|
|
81
81
|
if (hit.distance >= bestT)
|
|
82
82
|
return;
|
|
83
83
|
bestT = hit.distance;
|
|
84
84
|
found = true;
|
|
85
|
-
|
|
85
|
+
copyScene3DHit(out, hit);
|
|
86
86
|
});
|
|
87
87
|
return found ? out : null;
|
|
88
88
|
}
|
|
@@ -93,9 +93,9 @@ function buildCameraPickRay(out, camera, screenX, screenY) {
|
|
|
93
93
|
const aspect = camera.projection.kind === 'perspective' ? camera.projection.aspect : 1;
|
|
94
94
|
return getCamera3DScreenToWorldRay(out, camera, screenX, screenY, aspect);
|
|
95
95
|
}
|
|
96
|
-
// Field-copies `src` into `out`.
|
|
96
|
+
// Field-copies `src` into `out`. Scene3DHit is a plain result struct (no runtime identity), so a shallow
|
|
97
97
|
// field copy is a full copy.
|
|
98
|
-
function
|
|
98
|
+
function copyScene3DHit(out, src) {
|
|
99
99
|
out.node = src.node;
|
|
100
100
|
out.distance = src.distance;
|
|
101
101
|
out.triangleIndex = src.triangleIndex;
|
|
@@ -109,8 +109,8 @@ function copySceneHit(out, src) {
|
|
|
109
109
|
out.normalY = src.normalY;
|
|
110
110
|
out.normalZ = src.normalZ;
|
|
111
111
|
}
|
|
112
|
-
// Ascending-distance comparator for `Array.sort` over
|
|
113
|
-
function
|
|
112
|
+
// Ascending-distance comparator for `Array.sort` over Scene3DHit results.
|
|
113
|
+
function compareScene3DHitByDistance(a, b) {
|
|
114
114
|
return a.distance - b.distance;
|
|
115
115
|
}
|
|
116
116
|
// Walks every enabled Mesh in the scene, tests `ray` against its triangles under `options`, and calls
|
|
@@ -123,7 +123,7 @@ function compareSceneHitByDistance(a, b) {
|
|
|
123
123
|
// (`_hit`, `_localRay`, the vertex/point/normal temporaries, and the shared `_cameraRay` filled by the
|
|
124
124
|
// camera wrappers). It must not be called re-entrantly, and `onHit` must not itself start another
|
|
125
125
|
// pick. A native port replaces this shared scratch with per-call stack storage.
|
|
126
|
-
function
|
|
126
|
+
function forEachScene3DRayHit(scene, ray, options, onHit) {
|
|
127
127
|
const predicate = options?.predicate;
|
|
128
128
|
const maxDistance = options?.maxDistance ?? Infinity;
|
|
129
129
|
const cullBackfaces = options?.cullBackfaces ?? false;
|
|
@@ -164,7 +164,7 @@ function intersectMeshTriangles(mesh, ray, maxDistance, cullBackfaces, onHit) {
|
|
|
164
164
|
transformAabbByMatrix4(_worldBounds, posedLocalBounds, getNodeWorldMatrix4(mesh));
|
|
165
165
|
}
|
|
166
166
|
else {
|
|
167
|
-
|
|
167
|
+
getNode3DWorldBounds(_worldBounds, mesh);
|
|
168
168
|
}
|
|
169
169
|
if (intersectRay3DAabb(ray, _worldBounds) < 0)
|
|
170
170
|
return;
|
|
@@ -272,7 +272,7 @@ function transformDirectionByMatrix4(out, d, m) {
|
|
|
272
272
|
out.y = m[1] * x + m[5] * y + m[9] * z;
|
|
273
273
|
out.z = m[2] * x + m[6] * y + m[10] * z;
|
|
274
274
|
}
|
|
275
|
-
// Module-level scratch. This makes the pick pass non-reentrant (see
|
|
275
|
+
// Module-level scratch. This makes the pick pass non-reentrant (see forEachScene3DRayHit) — a C/C++
|
|
276
276
|
// port moves these to per-call stack storage.
|
|
277
277
|
const _cameraRay = createRay3D();
|
|
278
278
|
const _localRay = createRay3D();
|
|
@@ -287,6 +287,6 @@ const _wc = createVector3();
|
|
|
287
287
|
const _worldNormal = createVector3();
|
|
288
288
|
const _localPoint = createVector3();
|
|
289
289
|
const _worldPoint = createVector3();
|
|
290
|
-
const _hit =
|
|
290
|
+
const _hit = createScene3DHit();
|
|
291
291
|
const _triangle = { i0: 0, i1: 0, i2: 0 };
|
|
292
|
-
//# sourceMappingURL=
|
|
292
|
+
//# sourceMappingURL=pickScene3D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickScene3D.js","sourceRoot":"","sources":["../src/pickScene3D.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type { Material, Ray3D,
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
1
|
+
import type { Material, Ray3D, Scene3DHit, Vector2Like, Vector3Like } from '@flighthq/types';
|
|
2
|
+
export declare function getScene3DHitMaterial(hit: Readonly<Scene3DHit>): Material | null;
|
|
3
|
+
export declare function getScene3DHitSubsetIndex(hit: Readonly<Scene3DHit>): number;
|
|
4
|
+
export declare function getScene3DHitUv0(out: Vector2Like, hit: Readonly<Scene3DHit>): boolean;
|
|
5
|
+
export declare function getScene3DHitVertexNormal(out: Vector3Like, hit: Readonly<Scene3DHit>): boolean;
|
|
6
|
+
export declare function getScene3DHitVertexTangent(out: {
|
|
7
7
|
w: number;
|
|
8
8
|
x: number;
|
|
9
9
|
y: number;
|
|
10
10
|
z: number;
|
|
11
|
-
}, hit: Readonly<
|
|
12
|
-
export declare function
|
|
11
|
+
}, hit: Readonly<Scene3DHit>): boolean;
|
|
12
|
+
export declare function isScene3DHitFrontFacing(hit: Readonly<Scene3DHit>, ray: Readonly<Ray3D>): boolean;
|
|
13
13
|
//# sourceMappingURL=sceneHitAttributes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sceneHitAttributes.d.ts","sourceRoot":"","sources":["../src/sceneHitAttributes.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"sceneHitAttributes.d.ts","sourceRoot":"","sources":["../src/sceneHitAttributes.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG7F,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,IAAI,CAGhF;AAID,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,CAE1E;AAID,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,OAAO,CASrF;AAKD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,OAAO,CAmB9F;AAKD,wBAAgB,0BAA0B,CACxC,GAAG,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACnD,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,GACxB,OAAO,CA8BT;AAID,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,OAAO,CAEhG"}
|
|
@@ -2,18 +2,18 @@ import { createMatrix4, createVector3, inverseMatrix4 } from '@flighthq/geometry
|
|
|
2
2
|
import { getMeshGeometryTriangleSubsetIndex, getMeshGeometryTriangleVertexIndices, getMeshGeometryVertexNormal, getMeshGeometryVertexTangent, getMeshGeometryVertexUv0, } from '@flighthq/mesh';
|
|
3
3
|
import { ensureNodeWorldMatrix4, getNodeWorldMatrix4 } from '@flighthq/node';
|
|
4
4
|
// Returns the authored material at the hit subset, or null for an absent/out-of-range/default slot.
|
|
5
|
-
export function
|
|
6
|
-
const subsetIndex =
|
|
5
|
+
export function getScene3DHitMaterial(hit) {
|
|
6
|
+
const subsetIndex = getScene3DHitSubsetIndex(hit);
|
|
7
7
|
return subsetIndex < 0 ? null : (hit.node.materials[subsetIndex] ?? null);
|
|
8
8
|
}
|
|
9
9
|
// Returns the material/subset slot owning the hit triangle, or -1 when no declared subset contains
|
|
10
10
|
// it. This is computed on demand so the nearest-hit core remains flat and small.
|
|
11
|
-
export function
|
|
11
|
+
export function getScene3DHitSubsetIndex(hit) {
|
|
12
12
|
return getMeshGeometryTriangleSubsetIndex(hit.node.geometry, hit.triangleIndex);
|
|
13
13
|
}
|
|
14
14
|
// Interpolates uv0 from the hit triangle's current geometry. Returns false without changing `out`
|
|
15
15
|
// when the triangle or channel is unavailable.
|
|
16
|
-
export function
|
|
16
|
+
export function getScene3DHitUv0(out, hit) {
|
|
17
17
|
const geometry = hit.node.geometry;
|
|
18
18
|
if (!getMeshGeometryTriangleVertexIndices(_triangle, geometry, hit.triangleIndex))
|
|
19
19
|
return false;
|
|
@@ -28,9 +28,9 @@ export function getSceneHitUv0(out, hit) {
|
|
|
28
28
|
return true;
|
|
29
29
|
}
|
|
30
30
|
// Interpolates the vertex normal and transforms it to world space with inverse-transpose, so
|
|
31
|
-
// non-uniform scale remains correct. This is distinct from
|
|
31
|
+
// non-uniform scale remains correct. This is distinct from Scene3DHit.normal*, the geometric face
|
|
32
32
|
// normal used for culling. Returns false without changing `out` when unavailable or degenerate.
|
|
33
|
-
export function
|
|
33
|
+
export function getScene3DHitVertexNormal(out, hit) {
|
|
34
34
|
const geometry = hit.node.geometry;
|
|
35
35
|
if (!getMeshGeometryTriangleVertexIndices(_triangle, geometry, hit.triangleIndex))
|
|
36
36
|
return false;
|
|
@@ -52,7 +52,7 @@ export function getSceneHitVertexNormal(out, hit) {
|
|
|
52
52
|
// Interpolates tangent xyz/w, transforms the direction to world space, orthogonalizes it against the
|
|
53
53
|
// interpolated world normal, and flips handedness under a mirrored world transform. Returns false
|
|
54
54
|
// without changing `out` when normal/tangent data is unavailable or degenerate.
|
|
55
|
-
export function
|
|
55
|
+
export function getScene3DHitVertexTangent(out, hit) {
|
|
56
56
|
const geometry = hit.node.geometry;
|
|
57
57
|
if (!getMeshGeometryTriangleVertexIndices(_triangle, geometry, hit.triangleIndex))
|
|
58
58
|
return false;
|
|
@@ -62,7 +62,7 @@ export function getSceneHitVertexTangent(out, hit) {
|
|
|
62
62
|
return false;
|
|
63
63
|
if (!getMeshGeometryVertexTangent(_tangent2, geometry, _triangle.i2))
|
|
64
64
|
return false;
|
|
65
|
-
if (!
|
|
65
|
+
if (!getScene3DHitVertexNormal(_worldNormal, hit))
|
|
66
66
|
return false;
|
|
67
67
|
const tx = hit.u * _tangent0.x + hit.v * _tangent1.x + hit.w * _tangent2.x;
|
|
68
68
|
const ty = hit.u * _tangent0.y + hit.v * _tangent1.y + hit.w * _tangent2.y;
|
|
@@ -89,7 +89,7 @@ export function getSceneHitVertexTangent(out, hit) {
|
|
|
89
89
|
}
|
|
90
90
|
// True when the world ray meets the front side of the hit's geometric face normal. Perpendicular
|
|
91
91
|
// rays are treated as front-facing; the ray direction need not be normalized.
|
|
92
|
-
export function
|
|
92
|
+
export function isScene3DHitFrontFacing(hit, ray) {
|
|
93
93
|
return ray.direction.x * hit.normalX + ray.direction.y * hit.normalY + ray.direction.z * hit.normalZ <= 0;
|
|
94
94
|
}
|
|
95
95
|
function writeNormalized(out, x, y, z) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sceneHitAttributes.js","sourceRoot":"","sources":["../src/sceneHitAttributes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,kCAAkC,EAClC,oCAAoC,EACpC,2BAA2B,EAC3B,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG7E,oGAAoG;AACpG,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"sceneHitAttributes.js","sourceRoot":"","sources":["../src/sceneHitAttributes.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/picking",
|
|
3
|
-
"version": "0.2.1-next.
|
|
3
|
+
"version": "0.2.1-next.841.373388f",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/flighthq/flight.git",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@flighthq/camera": "0.2.1-next.
|
|
36
|
-
"@flighthq/entity": "0.2.1-next.
|
|
37
|
-
"@flighthq/geometry": "0.2.1-next.
|
|
38
|
-
"@flighthq/mesh": "0.2.1-next.
|
|
39
|
-
"@flighthq/node": "0.2.1-next.
|
|
40
|
-
"@flighthq/
|
|
41
|
-
"@flighthq/types": "0.2.1-next.
|
|
35
|
+
"@flighthq/camera": "0.2.1-next.841.373388f",
|
|
36
|
+
"@flighthq/entity": "0.2.1-next.841.373388f",
|
|
37
|
+
"@flighthq/geometry": "0.2.1-next.841.373388f",
|
|
38
|
+
"@flighthq/mesh": "0.2.1-next.841.373388f",
|
|
39
|
+
"@flighthq/node": "0.2.1-next.841.373388f",
|
|
40
|
+
"@flighthq/scene3d": "0.2.1-next.841.373388f",
|
|
41
|
+
"@flighthq/types": "0.2.1-next.841.373388f"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"typescript": "^5.3.0"
|
|
@@ -17,11 +17,17 @@ import {
|
|
|
17
17
|
import { createBoxMeshGeometry, createMeshGeometryFromAttributes } from '@flighthq/mesh';
|
|
18
18
|
import { ensureMeshGeometryBounds, updateMeshMorph } from '@flighthq/mesh';
|
|
19
19
|
import { addNodeChild, getNodeRuntime, invalidateNodeLocalTransform } from '@flighthq/node';
|
|
20
|
-
import { createMesh,
|
|
21
|
-
import type { Camera3D, Mesh, MeshMorph, MeshRuntime, Ray3D,
|
|
20
|
+
import { createMesh, createNode3D, Node3DKind } from '@flighthq/scene3d';
|
|
21
|
+
import type { Camera3D, Mesh, MeshMorph, MeshRuntime, Ray3D, Scene3DHit, Node3D } from '@flighthq/types';
|
|
22
22
|
import { EntityRuntimeKey } from '@flighthq/types';
|
|
23
23
|
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
createScene3DHit,
|
|
26
|
+
pickScene3D,
|
|
27
|
+
pickScene3DAll,
|
|
28
|
+
pickScene3DAllWithRay3D,
|
|
29
|
+
pickScene3DWithRay3D,
|
|
30
|
+
} from './pickScene3D';
|
|
25
31
|
|
|
26
32
|
function makeCamera(): Camera3D {
|
|
27
33
|
const camera = createCamera3D({
|
|
@@ -63,16 +69,16 @@ function triangleMesh(frontFacing: boolean): Mesh {
|
|
|
63
69
|
return createMesh(geometry, []);
|
|
64
70
|
}
|
|
65
71
|
|
|
66
|
-
function sceneWithCenteredBox(): { scene:
|
|
67
|
-
const scene =
|
|
72
|
+
function sceneWithCenteredBox(): { scene: Node3D; mesh: Mesh } {
|
|
73
|
+
const scene = createNode3D(Node3DKind);
|
|
68
74
|
const mesh = createMesh(createBoxMeshGeometry(2, 2, 2), []);
|
|
69
75
|
addNodeChild(scene, mesh);
|
|
70
76
|
return { scene, mesh };
|
|
71
77
|
}
|
|
72
78
|
|
|
73
|
-
describe('
|
|
79
|
+
describe('createScene3DHit', () => {
|
|
74
80
|
it('allocates a zeroed hit with a sentinel triangle index', () => {
|
|
75
|
-
const hit =
|
|
81
|
+
const hit = createScene3DHit();
|
|
76
82
|
|
|
77
83
|
expect(EntityRuntimeKey in hit).toBe(true);
|
|
78
84
|
expect(hit.triangleIndex).toBe(-1);
|
|
@@ -83,13 +89,13 @@ describe('createSceneHit', () => {
|
|
|
83
89
|
});
|
|
84
90
|
});
|
|
85
91
|
|
|
86
|
-
describe('
|
|
92
|
+
describe('pickScene3D', () => {
|
|
87
93
|
it('fills barycentric weights that sum to one', () => {
|
|
88
94
|
const camera = makeCamera();
|
|
89
95
|
const { scene } = sceneWithCenteredBox();
|
|
90
|
-
const out =
|
|
96
|
+
const out = createScene3DHit();
|
|
91
97
|
|
|
92
|
-
const hit =
|
|
98
|
+
const hit = pickScene3D(scene, camera, 0, 0, out);
|
|
93
99
|
|
|
94
100
|
expect(hit).not.toBeNull();
|
|
95
101
|
expect((hit?.u ?? 0) + (hit?.v ?? 0) + (hit?.w ?? 0)).toBeCloseTo(1, 5);
|
|
@@ -98,9 +104,9 @@ describe('pickScene', () => {
|
|
|
98
104
|
it('fills the world face normal and triangle index of the hit', () => {
|
|
99
105
|
const camera = makeCamera();
|
|
100
106
|
const { scene } = sceneWithCenteredBox();
|
|
101
|
-
const out =
|
|
107
|
+
const out = createScene3DHit();
|
|
102
108
|
|
|
103
|
-
const hit =
|
|
109
|
+
const hit = pickScene3D(scene, camera, 0, 0, out);
|
|
104
110
|
|
|
105
111
|
// Front face of the box points at +Z (toward the camera at z = 5).
|
|
106
112
|
expect(hit?.normalZ).toBeCloseTo(1, 5);
|
|
@@ -111,38 +117,38 @@ describe('pickScene', () => {
|
|
|
111
117
|
|
|
112
118
|
it('returns null for a scene containing only non-mesh nodes', () => {
|
|
113
119
|
const camera = makeCamera();
|
|
114
|
-
const scene =
|
|
115
|
-
// A plain
|
|
116
|
-
const node =
|
|
120
|
+
const scene = createNode3D(Node3DKind);
|
|
121
|
+
// A plain Node3D is not a Mesh; isMesh() returns false for it.
|
|
122
|
+
const node = createNode3D();
|
|
117
123
|
addNodeChild(scene, node);
|
|
118
|
-
const out =
|
|
124
|
+
const out = createScene3DHit();
|
|
119
125
|
|
|
120
|
-
expect(
|
|
126
|
+
expect(pickScene3D(scene, camera, 0, 0, out)).toBeNull();
|
|
121
127
|
});
|
|
122
128
|
|
|
123
129
|
it('returns null when the ray misses every mesh', () => {
|
|
124
130
|
const camera = makeCamera();
|
|
125
131
|
const { scene } = sceneWithCenteredBox();
|
|
126
|
-
const out =
|
|
132
|
+
const out = createScene3DHit();
|
|
127
133
|
|
|
128
134
|
// Far corner of the viewport points away from the small centred box.
|
|
129
|
-
expect(
|
|
135
|
+
expect(pickScene3D(scene, camera, 0.99, 0.99, out)).toBeNull();
|
|
130
136
|
});
|
|
131
137
|
|
|
132
138
|
it('returns null when the scene has no meshes', () => {
|
|
133
139
|
const camera = makeCamera();
|
|
134
|
-
const scene =
|
|
135
|
-
const out =
|
|
140
|
+
const scene = createNode3D(Node3DKind);
|
|
141
|
+
const out = createScene3DHit();
|
|
136
142
|
|
|
137
|
-
expect(
|
|
143
|
+
expect(pickScene3D(scene, camera, 0, 0, out)).toBeNull();
|
|
138
144
|
});
|
|
139
145
|
|
|
140
146
|
it('returns the mesh hit by the center ray', () => {
|
|
141
147
|
const camera = makeCamera();
|
|
142
148
|
const { scene, mesh } = sceneWithCenteredBox();
|
|
143
|
-
const out =
|
|
149
|
+
const out = createScene3DHit();
|
|
144
150
|
|
|
145
|
-
const hit =
|
|
151
|
+
const hit = pickScene3D(scene, camera, 0, 0, out);
|
|
146
152
|
|
|
147
153
|
expect(hit).toBe(out);
|
|
148
154
|
expect(hit?.node).toBe(mesh);
|
|
@@ -156,7 +162,7 @@ describe('pickScene', () => {
|
|
|
156
162
|
it('returns the nearer of two overlapping meshes', () => {
|
|
157
163
|
// Camera3D is at z = 5 looking toward the origin in the -Z direction.
|
|
158
164
|
const camera = makeCamera();
|
|
159
|
-
const scene =
|
|
165
|
+
const scene = createNode3D(Node3DKind);
|
|
160
166
|
|
|
161
167
|
// meshFar is centred at the origin: front face at z = 1, back face at z = -1.
|
|
162
168
|
const meshFar = createMesh(createBoxMeshGeometry(2, 2, 2), []);
|
|
@@ -169,8 +175,8 @@ describe('pickScene', () => {
|
|
|
169
175
|
invalidateNodeLocalTransform(meshNear);
|
|
170
176
|
addNodeChild(scene, meshNear);
|
|
171
177
|
|
|
172
|
-
const out =
|
|
173
|
-
const hit =
|
|
178
|
+
const out = createScene3DHit();
|
|
179
|
+
const hit = pickScene3D(scene, camera, 0, 0, out);
|
|
174
180
|
|
|
175
181
|
expect(hit).toBe(out);
|
|
176
182
|
expect(hit?.node).toBe(meshNear);
|
|
@@ -184,36 +190,36 @@ describe('pickScene', () => {
|
|
|
184
190
|
const camera = makeCamera();
|
|
185
191
|
const { scene, mesh } = sceneWithCenteredBox();
|
|
186
192
|
mesh.enabled = false;
|
|
187
|
-
const out =
|
|
193
|
+
const out = createScene3DHit();
|
|
188
194
|
|
|
189
|
-
expect(
|
|
195
|
+
expect(pickScene3D(scene, camera, 0, 0, out)).toBeNull();
|
|
190
196
|
});
|
|
191
197
|
|
|
192
198
|
it('prunes the subtree of a disabled group node', () => {
|
|
193
199
|
const camera = makeCamera();
|
|
194
|
-
const scene =
|
|
195
|
-
const group =
|
|
200
|
+
const scene = createNode3D(Node3DKind);
|
|
201
|
+
const group = createNode3D();
|
|
196
202
|
group.enabled = false;
|
|
197
203
|
const mesh = createMesh(createBoxMeshGeometry(2, 2, 2), []);
|
|
198
204
|
addNodeChild(group, mesh);
|
|
199
205
|
addNodeChild(scene, group);
|
|
200
|
-
const out =
|
|
206
|
+
const out = createScene3DHit();
|
|
201
207
|
|
|
202
|
-
expect(
|
|
208
|
+
expect(pickScene3D(scene, camera, 0, 0, out)).toBeNull();
|
|
203
209
|
});
|
|
204
210
|
|
|
205
211
|
it('excludes a mesh rejected by the predicate option', () => {
|
|
206
212
|
const camera = makeCamera();
|
|
207
|
-
const scene =
|
|
213
|
+
const scene = createNode3D(Node3DKind);
|
|
208
214
|
const meshFar = createMesh(createBoxMeshGeometry(2, 2, 2), []);
|
|
209
215
|
addNodeChild(scene, meshFar);
|
|
210
216
|
const meshNear = createMesh(createBoxMeshGeometry(2, 2, 2), []);
|
|
211
217
|
setVector3(meshNear.position, 0, 0, 2);
|
|
212
218
|
invalidateNodeLocalTransform(meshNear);
|
|
213
219
|
addNodeChild(scene, meshNear);
|
|
214
|
-
const out =
|
|
220
|
+
const out = createScene3DHit();
|
|
215
221
|
|
|
216
|
-
const hit =
|
|
222
|
+
const hit = pickScene3D(scene, camera, 0, 0, out, { predicate: (m) => m === meshFar });
|
|
217
223
|
|
|
218
224
|
expect(hit?.node).toBe(meshFar);
|
|
219
225
|
});
|
|
@@ -221,38 +227,38 @@ describe('pickScene', () => {
|
|
|
221
227
|
it('rejects hits beyond maxDistance', () => {
|
|
222
228
|
const camera = makeCamera();
|
|
223
229
|
const { scene } = sceneWithCenteredBox();
|
|
224
|
-
const out =
|
|
230
|
+
const out = createScene3DHit();
|
|
225
231
|
|
|
226
232
|
// Front face is ~4 world units from the camera at z = 5.
|
|
227
|
-
expect(
|
|
228
|
-
expect(
|
|
233
|
+
expect(pickScene3D(scene, camera, 0, 0, out, { maxDistance: 3 })).toBeNull();
|
|
234
|
+
expect(pickScene3D(scene, camera, 0, 0, out, { maxDistance: 4.5 })).not.toBeNull();
|
|
229
235
|
});
|
|
230
236
|
|
|
231
237
|
it('maps a non-square orthographic viewport without an aspect mismap', () => {
|
|
232
238
|
// View volume is 8 wide (halfWidth 4) but only 2 tall (halfHeight 1).
|
|
233
239
|
const camera = makeOrthoCamera(4, 1);
|
|
234
|
-
const scene =
|
|
240
|
+
const scene = createNode3D(Node3DKind);
|
|
235
241
|
// A 2x2x2 box centred at x = 3 spans x in [2, 4], within the horizontal extent but well outside
|
|
236
242
|
// the vertical one — so a square (aspect = 1) mismap of screenX would miss it.
|
|
237
243
|
const mesh = createMesh(createBoxMeshGeometry(2, 2, 2), []);
|
|
238
244
|
setVector3(mesh.position, 3, 0, 0);
|
|
239
245
|
invalidateNodeLocalTransform(mesh);
|
|
240
246
|
addNodeChild(scene, mesh);
|
|
241
|
-
const out =
|
|
247
|
+
const out = createScene3DHit();
|
|
242
248
|
|
|
243
249
|
// screenX = 0.75 → world x = 0.75 * halfWidth(4) = 3.
|
|
244
|
-
const hit =
|
|
250
|
+
const hit = pickScene3D(scene, camera, 0.75, 0, out);
|
|
245
251
|
|
|
246
252
|
expect(hit?.node).toBe(mesh);
|
|
247
253
|
expect(hit?.pointX).toBeCloseTo(3, 3);
|
|
248
254
|
expect(hit?.pointZ).toBeCloseTo(1, 3);
|
|
249
255
|
// A pick past the horizontal extent misses.
|
|
250
|
-
expect(
|
|
256
|
+
expect(pickScene3D(scene, camera, 1.1, 0, out)).toBeNull();
|
|
251
257
|
});
|
|
252
258
|
|
|
253
259
|
it('hits a rotated and scaled mesh through the local-space path', () => {
|
|
254
260
|
const camera = makeCamera();
|
|
255
|
-
const scene =
|
|
261
|
+
const scene = createNode3D(Node3DKind);
|
|
256
262
|
const mesh = createMesh(createBoxMeshGeometry(2, 2, 2), []);
|
|
257
263
|
// Non-uniform scale (z doubled) plus a rotation about the Z axis. The +Z face stays on-axis, so
|
|
258
264
|
// its world position is z = 1 * 2 = 2 while the surrounding geometry is rotated — exercising the
|
|
@@ -264,9 +270,9 @@ describe('pickScene', () => {
|
|
|
264
270
|
copyQuaternion(mesh.rotation, q);
|
|
265
271
|
invalidateNodeLocalTransform(mesh);
|
|
266
272
|
addNodeChild(scene, mesh);
|
|
267
|
-
const out =
|
|
273
|
+
const out = createScene3DHit();
|
|
268
274
|
|
|
269
|
-
const hit =
|
|
275
|
+
const hit = pickScene3D(scene, camera, 0, 0, out);
|
|
270
276
|
|
|
271
277
|
expect(hit?.node).toBe(mesh);
|
|
272
278
|
expect(hit?.pointZ).toBeCloseTo(2, 3);
|
|
@@ -276,19 +282,19 @@ describe('pickScene', () => {
|
|
|
276
282
|
});
|
|
277
283
|
});
|
|
278
284
|
|
|
279
|
-
describe('
|
|
285
|
+
describe('pickScene3DAll', () => {
|
|
280
286
|
it('collects both overlapping meshes sorted by ascending distance', () => {
|
|
281
287
|
const camera = makeCamera();
|
|
282
|
-
const scene =
|
|
288
|
+
const scene = createNode3D(Node3DKind);
|
|
283
289
|
const meshFar = createMesh(createBoxMeshGeometry(2, 2, 2), []);
|
|
284
290
|
addNodeChild(scene, meshFar);
|
|
285
291
|
const meshNear = createMesh(createBoxMeshGeometry(2, 2, 2), []);
|
|
286
292
|
setVector3(meshNear.position, 0, 0, 2);
|
|
287
293
|
invalidateNodeLocalTransform(meshNear);
|
|
288
294
|
addNodeChild(scene, meshNear);
|
|
289
|
-
const outArray:
|
|
295
|
+
const outArray: Scene3DHit[] = [];
|
|
290
296
|
|
|
291
|
-
const hits =
|
|
297
|
+
const hits = pickScene3DAll(scene, camera, 0, 0, outArray);
|
|
292
298
|
|
|
293
299
|
expect(hits).toBe(outArray);
|
|
294
300
|
// Each box contributes a front-face hit (a 2x2x2 box's front quad is two triangles, but the
|
|
@@ -303,22 +309,22 @@ describe('pickSceneAll', () => {
|
|
|
303
309
|
it('empties the array on a miss', () => {
|
|
304
310
|
const camera = makeCamera();
|
|
305
311
|
const { scene } = sceneWithCenteredBox();
|
|
306
|
-
const outArray:
|
|
312
|
+
const outArray: Scene3DHit[] = [createScene3DHit(), createScene3DHit()];
|
|
307
313
|
|
|
308
|
-
const hits =
|
|
314
|
+
const hits = pickScene3DAll(scene, camera, 0.99, 0.99, outArray);
|
|
309
315
|
|
|
310
316
|
expect(hits).toBe(outArray);
|
|
311
317
|
expect(hits.length).toBe(0);
|
|
312
318
|
});
|
|
313
319
|
});
|
|
314
320
|
|
|
315
|
-
describe('
|
|
321
|
+
describe('pickScene3DAllWithRay3D', () => {
|
|
316
322
|
it('collects every triangle a world ray crosses, front and back faces', () => {
|
|
317
323
|
const { scene } = sceneWithCenteredBox();
|
|
318
324
|
const ray = makeCenterRay();
|
|
319
|
-
const outArray:
|
|
325
|
+
const outArray: Scene3DHit[] = [];
|
|
320
326
|
|
|
321
|
-
const hits =
|
|
327
|
+
const hits = pickScene3DAllWithRay3D(scene, ray, outArray);
|
|
322
328
|
|
|
323
329
|
// The center ray runs along the shared diagonal of each quad, so it grazes both triangles of the
|
|
324
330
|
// front face (z = 1) and both of the back face (z = -1): four hits, sorted near-to-far.
|
|
@@ -333,9 +339,9 @@ describe('pickSceneAllWithRay3D', () => {
|
|
|
333
339
|
it('keeps only front faces when cullBackfaces is set', () => {
|
|
334
340
|
const { scene } = sceneWithCenteredBox();
|
|
335
341
|
const ray = makeCenterRay();
|
|
336
|
-
const outArray:
|
|
342
|
+
const outArray: Scene3DHit[] = [];
|
|
337
343
|
|
|
338
|
-
const hits =
|
|
344
|
+
const hits = pickScene3DAllWithRay3D(scene, ray, outArray, { cullBackfaces: true });
|
|
339
345
|
|
|
340
346
|
// Only the two front-face triangles survive; both point at +Z (toward the ray origin).
|
|
341
347
|
expect(hits.length).toBe(2);
|
|
@@ -346,13 +352,13 @@ describe('pickSceneAllWithRay3D', () => {
|
|
|
346
352
|
});
|
|
347
353
|
});
|
|
348
354
|
|
|
349
|
-
describe('
|
|
355
|
+
describe('pickScene3DWithRay3D', () => {
|
|
350
356
|
it('resolves the nearest hit for a world-space ray', () => {
|
|
351
357
|
const { scene, mesh } = sceneWithCenteredBox();
|
|
352
358
|
const ray = makeCenterRay();
|
|
353
|
-
const out =
|
|
359
|
+
const out = createScene3DHit();
|
|
354
360
|
|
|
355
|
-
const hit =
|
|
361
|
+
const hit = pickScene3DWithRay3D(scene, ray, out, {});
|
|
356
362
|
|
|
357
363
|
expect(hit).toBe(out);
|
|
358
364
|
expect(hit?.node).toBe(mesh);
|
|
@@ -360,16 +366,16 @@ describe('pickSceneWithRay3D', () => {
|
|
|
360
366
|
});
|
|
361
367
|
|
|
362
368
|
it('culls a back-facing triangle but keeps a front-facing one', () => {
|
|
363
|
-
const front =
|
|
369
|
+
const front = createNode3D(Node3DKind);
|
|
364
370
|
addNodeChild(front, triangleMesh(true));
|
|
365
|
-
const back =
|
|
371
|
+
const back = createNode3D(Node3DKind);
|
|
366
372
|
addNodeChild(back, triangleMesh(false));
|
|
367
|
-
const out =
|
|
373
|
+
const out = createScene3DHit();
|
|
368
374
|
|
|
369
|
-
expect(
|
|
370
|
-
expect(
|
|
375
|
+
expect(pickScene3DWithRay3D(front, makeCenterRay(), out, { cullBackfaces: true })).not.toBeNull();
|
|
376
|
+
expect(pickScene3DWithRay3D(back, makeCenterRay(), out, { cullBackfaces: true })).toBeNull();
|
|
371
377
|
// Double-sided (default) hits either winding.
|
|
372
|
-
expect(
|
|
378
|
+
expect(pickScene3DWithRay3D(back, makeCenterRay(), out)).not.toBeNull();
|
|
373
379
|
});
|
|
374
380
|
|
|
375
381
|
it('picks the second triangle of an indexed strip with its CCW winding', () => {
|
|
@@ -378,12 +384,12 @@ describe('pickSceneWithRay3D', () => {
|
|
|
378
384
|
positions: [-1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0],
|
|
379
385
|
});
|
|
380
386
|
geometry.topology = 'triangle-strip';
|
|
381
|
-
const scene =
|
|
387
|
+
const scene = createNode3D(Node3DKind);
|
|
382
388
|
addNodeChild(scene, createMesh(geometry, []));
|
|
383
389
|
const ray = createRay3D();
|
|
384
390
|
setRay3D(ray, createVector3(0.5, 0.5, 1), createVector3(0, 0, -1));
|
|
385
391
|
|
|
386
|
-
const hit =
|
|
392
|
+
const hit = pickScene3DWithRay3D(scene, ray, createScene3DHit(), { cullBackfaces: true });
|
|
387
393
|
|
|
388
394
|
expect(hit?.triangleIndex).toBe(1);
|
|
389
395
|
expect(hit?.normalZ).toBeCloseTo(1);
|
|
@@ -405,12 +411,12 @@ describe('pickSceneWithRay3D', () => {
|
|
|
405
411
|
weights: new Float32Array([1]),
|
|
406
412
|
};
|
|
407
413
|
mesh.morph = morph;
|
|
408
|
-
const scene =
|
|
414
|
+
const scene = createNode3D(Node3DKind);
|
|
409
415
|
addNodeChild(scene, mesh);
|
|
410
416
|
const ray = makeCenterRay();
|
|
411
|
-
const out =
|
|
417
|
+
const out = createScene3DHit();
|
|
412
418
|
|
|
413
|
-
expect(
|
|
419
|
+
expect(pickScene3DWithRay3D(scene, ray, out)).toBeNull();
|
|
414
420
|
updateMeshMorph(mesh);
|
|
415
421
|
|
|
416
422
|
// Bounds are a dirty-gated cache; the morph marks them stale and the ensure recomputes them —
|
|
@@ -418,28 +424,28 @@ describe('pickSceneWithRay3D', () => {
|
|
|
418
424
|
const bounds = ensureMeshGeometryBounds(mesh.geometry);
|
|
419
425
|
expect(bounds?.min.x).toBe(-1);
|
|
420
426
|
expect(bounds?.max.x).toBe(1);
|
|
421
|
-
expect(
|
|
427
|
+
expect(pickScene3DWithRay3D(scene, ray, out)?.node).toBe(mesh);
|
|
422
428
|
});
|
|
423
429
|
|
|
424
430
|
it('broad-phases against the posed deformedLocalBounds slot when a deform pass wrote one', () => {
|
|
425
431
|
// A triangle at the origin that the center ray hits head-on. Its bind-pose bounds admit the ray,
|
|
426
432
|
// so with no posed slot the pick lands.
|
|
427
433
|
const mesh = triangleMesh(true);
|
|
428
|
-
const scene =
|
|
434
|
+
const scene = createNode3D(Node3DKind);
|
|
429
435
|
addNodeChild(scene, mesh);
|
|
430
436
|
const ray = makeCenterRay();
|
|
431
|
-
const out =
|
|
437
|
+
const out = createScene3DHit();
|
|
432
438
|
|
|
433
|
-
expect(
|
|
439
|
+
expect(pickScene3DWithRay3D(scene, ray, out)?.node).toBe(mesh);
|
|
434
440
|
|
|
435
|
-
// Simulate a deform pass (
|
|
441
|
+
// Simulate a deform pass (prepareScene3DSkinning) writing a posed local box far off the ray. The
|
|
436
442
|
// broad-phase must read that slot as data and reject the mesh before the triangle test — proving it
|
|
437
443
|
// no longer uses the bind-pose bounds for a posed mesh.
|
|
438
444
|
(getNodeRuntime(mesh) as MeshRuntime).deformedLocalBounds = createAabb(100, 100, 100, 102, 102, 102);
|
|
439
|
-
expect(
|
|
445
|
+
expect(pickScene3DWithRay3D(scene, ray, out)).toBeNull();
|
|
440
446
|
|
|
441
447
|
// Clearing the slot falls back to the bind-pose world bounds, and the pick lands again.
|
|
442
448
|
(getNodeRuntime(mesh) as MeshRuntime).deformedLocalBounds = null;
|
|
443
|
-
expect(
|
|
449
|
+
expect(pickScene3DWithRay3D(scene, ray, out)?.node).toBe(mesh);
|
|
444
450
|
});
|
|
445
451
|
});
|
|
@@ -2,28 +2,28 @@ import { createEntity } from '@flighthq/entity';
|
|
|
2
2
|
import { createRay3D, createVector3, setRay3D, setVector3 } from '@flighthq/geometry';
|
|
3
3
|
import { createMeshGeometry, createMeshGeometryFromAttributes, setMeshGeometrySubsets } from '@flighthq/mesh';
|
|
4
4
|
import { invalidateNodeLocalTransform } from '@flighthq/node';
|
|
5
|
-
import { createMesh } from '@flighthq/
|
|
6
|
-
import type {
|
|
5
|
+
import { createMesh } from '@flighthq/scene3d';
|
|
6
|
+
import type { Scene3DHit, VertexAttributeLayout } from '@flighthq/types';
|
|
7
7
|
import { describe, expect, it } from 'vitest';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { createScene3DHit } from './pickScene3D';
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
getScene3DHitMaterial,
|
|
12
|
+
getScene3DHitSubsetIndex,
|
|
13
|
+
getScene3DHitUv0,
|
|
14
|
+
getScene3DHitVertexNormal,
|
|
15
|
+
getScene3DHitVertexTangent,
|
|
16
|
+
isScene3DHitFrontFacing,
|
|
17
17
|
} from './sceneHitAttributes';
|
|
18
18
|
|
|
19
|
-
function attributedHit():
|
|
19
|
+
function attributedHit(): Scene3DHit {
|
|
20
20
|
const geometry = createMeshGeometryFromAttributes({
|
|
21
21
|
indices: [0, 1, 2],
|
|
22
22
|
normals: [0, 0, 1, 0, 0, 1, 0, 0, 1],
|
|
23
23
|
positions: [0, 0, 0, 1, 0, 0, 0, 1, 0],
|
|
24
24
|
uvs: [0, 0, 1, 0, 0, 1],
|
|
25
25
|
});
|
|
26
|
-
const hit =
|
|
26
|
+
const hit = createScene3DHit();
|
|
27
27
|
hit.node = createMesh(geometry, []);
|
|
28
28
|
hit.triangleIndex = 0;
|
|
29
29
|
hit.u = 0.25;
|
|
@@ -33,31 +33,31 @@ function attributedHit(): SceneHit {
|
|
|
33
33
|
return hit;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
describe('
|
|
36
|
+
describe('getScene3DHitMaterial', () => {
|
|
37
37
|
it('returns the subset material or null for the default slot', () => {
|
|
38
38
|
const hit = attributedHit();
|
|
39
39
|
const material = createEntity({ kind: 'TestMaterial' });
|
|
40
40
|
hit.node.materials = [material];
|
|
41
|
-
expect(
|
|
41
|
+
expect(getScene3DHitMaterial(hit)).toBe(material);
|
|
42
42
|
hit.node.materials[0] = null;
|
|
43
|
-
expect(
|
|
43
|
+
expect(getScene3DHitMaterial(hit)).toBeNull();
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
describe('
|
|
47
|
+
describe('getScene3DHitSubsetIndex', () => {
|
|
48
48
|
it('resolves the subset owning the hit triangle', () => {
|
|
49
49
|
const hit = attributedHit();
|
|
50
50
|
setMeshGeometrySubsets(hit.node.geometry, [{ indexCount: 3, indexOffset: 0 }]);
|
|
51
|
-
expect(
|
|
51
|
+
expect(getScene3DHitSubsetIndex(hit)).toBe(0);
|
|
52
52
|
hit.triangleIndex = 2;
|
|
53
|
-
expect(
|
|
53
|
+
expect(getScene3DHitSubsetIndex(hit)).toBe(-1);
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
describe('
|
|
57
|
+
describe('getScene3DHitUv0', () => {
|
|
58
58
|
it('barycentrically interpolates the current triangle uv', () => {
|
|
59
59
|
const out = { x: 0, y: 0 };
|
|
60
|
-
expect(
|
|
60
|
+
expect(getScene3DHitUv0(out, attributedHit())).toBe(true);
|
|
61
61
|
expect(out.x).toBeCloseTo(0.25);
|
|
62
62
|
expect(out.y).toBeCloseTo(0.5);
|
|
63
63
|
});
|
|
@@ -65,12 +65,12 @@ describe('getSceneHitUv0', () => {
|
|
|
65
65
|
it('leaves out unchanged when uv0 is absent', () => {
|
|
66
66
|
const hit = positionOnlyHit();
|
|
67
67
|
const out = { x: 7, y: 8 };
|
|
68
|
-
expect(
|
|
68
|
+
expect(getScene3DHitUv0(out, hit)).toBe(false);
|
|
69
69
|
expect(out).toEqual({ x: 7, y: 8 });
|
|
70
70
|
});
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
describe('
|
|
73
|
+
describe('getScene3DHitVertexNormal', () => {
|
|
74
74
|
it('uses inverse-transpose under non-uniform scale', () => {
|
|
75
75
|
const hit = attributedHit();
|
|
76
76
|
const vertices = hit.node.geometry.vertices;
|
|
@@ -82,7 +82,7 @@ describe('getSceneHitVertexNormal', () => {
|
|
|
82
82
|
setVector3(hit.node.scale, 2, 1, 1);
|
|
83
83
|
invalidateNodeLocalTransform(hit.node);
|
|
84
84
|
const out = createVector3();
|
|
85
|
-
expect(
|
|
85
|
+
expect(getScene3DHitVertexNormal(out, hit)).toBe(true);
|
|
86
86
|
const inverseLength = 1 / Math.sqrt(1.25);
|
|
87
87
|
expect(out.x).toBeCloseTo(0.5 * inverseLength);
|
|
88
88
|
expect(out.y).toBeCloseTo(inverseLength);
|
|
@@ -91,18 +91,18 @@ describe('getSceneHitVertexNormal', () => {
|
|
|
91
91
|
|
|
92
92
|
it('leaves out unchanged when normals are absent', () => {
|
|
93
93
|
const out = createVector3(7, 8, 9);
|
|
94
|
-
expect(
|
|
94
|
+
expect(getScene3DHitVertexNormal(out, positionOnlyHit())).toBe(false);
|
|
95
95
|
expect(out).toMatchObject({ x: 7, y: 8, z: 9 });
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
describe('
|
|
99
|
+
describe('getScene3DHitVertexTangent', () => {
|
|
100
100
|
it('transforms tangent and flips handedness under mirroring', () => {
|
|
101
101
|
const hit = attributedHit();
|
|
102
102
|
setVector3(hit.node.scale, -1, 1, 1);
|
|
103
103
|
invalidateNodeLocalTransform(hit.node);
|
|
104
104
|
const out = { w: 0, x: 0, y: 0, z: 0 };
|
|
105
|
-
expect(
|
|
105
|
+
expect(getScene3DHitVertexTangent(out, hit)).toBe(true);
|
|
106
106
|
expect(out.x).toBeCloseTo(-1);
|
|
107
107
|
expect(out.y).toBeCloseTo(0);
|
|
108
108
|
expect(out.z).toBeCloseTo(0);
|
|
@@ -111,29 +111,29 @@ describe('getSceneHitVertexTangent', () => {
|
|
|
111
111
|
|
|
112
112
|
it('leaves out unchanged when tangents are absent', () => {
|
|
113
113
|
const out = { w: 4, x: 1, y: 2, z: 3 };
|
|
114
|
-
expect(
|
|
114
|
+
expect(getScene3DHitVertexTangent(out, positionOnlyHit())).toBe(false);
|
|
115
115
|
expect(out).toEqual({ w: 4, x: 1, y: 2, z: 3 });
|
|
116
116
|
});
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
describe('
|
|
119
|
+
describe('isScene3DHitFrontFacing', () => {
|
|
120
120
|
it('compares the world ray direction with the geometric face normal', () => {
|
|
121
121
|
const hit = attributedHit();
|
|
122
122
|
const ray = createRay3D();
|
|
123
123
|
setRay3D(ray, createVector3(0, 0, 1), createVector3(0, 0, -2));
|
|
124
|
-
expect(
|
|
124
|
+
expect(isScene3DHitFrontFacing(hit, ray)).toBe(true);
|
|
125
125
|
ray.direction.z = 2;
|
|
126
|
-
expect(
|
|
126
|
+
expect(isScene3DHitFrontFacing(hit, ray)).toBe(false);
|
|
127
127
|
});
|
|
128
128
|
});
|
|
129
129
|
|
|
130
|
-
function positionOnlyHit():
|
|
130
|
+
function positionOnlyHit(): Scene3DHit {
|
|
131
131
|
const layout: VertexAttributeLayout = {
|
|
132
132
|
attributes: [{ byteOffset: 0, format: 'float32x3', semantic: 'position' }],
|
|
133
133
|
stride: 12,
|
|
134
134
|
};
|
|
135
135
|
const geometry = createMeshGeometry({ layout, vertices: new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]) });
|
|
136
|
-
const hit =
|
|
136
|
+
const hit = createScene3DHit();
|
|
137
137
|
hit.node = createMesh(geometry, []);
|
|
138
138
|
hit.triangleIndex = 0;
|
|
139
139
|
hit.u = 1;
|
package/dist/pickScene.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Camera3D, Ray3D, SceneHit, SceneNode, ScenePickOptions } from '@flighthq/types';
|
|
2
|
-
export declare function createSceneHit(): SceneHit;
|
|
3
|
-
export declare function pickScene(scene: Readonly<SceneNode>, camera: Readonly<Camera3D>, screenX: number, screenY: number, out: SceneHit, options?: Readonly<ScenePickOptions>): SceneHit | null;
|
|
4
|
-
export declare function pickSceneAll(scene: Readonly<SceneNode>, camera: Readonly<Camera3D>, screenX: number, screenY: number, outArray: SceneHit[], options?: Readonly<ScenePickOptions>): SceneHit[];
|
|
5
|
-
export declare function pickSceneAllWithRay3D(scene: Readonly<SceneNode>, ray: Readonly<Ray3D>, outArray: SceneHit[], options?: Readonly<ScenePickOptions>): SceneHit[];
|
|
6
|
-
export declare function pickSceneWithRay3D(scene: Readonly<SceneNode>, ray: Readonly<Ray3D>, out: SceneHit, options?: Readonly<ScenePickOptions>): SceneHit | null;
|
|
7
|
-
//# sourceMappingURL=pickScene.d.ts.map
|
package/dist/pickScene.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pickScene.d.ts","sourceRoot":"","sources":["../src/pickScene.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,QAAQ,EAIR,KAAK,EACL,QAAQ,EACR,SAAS,EACT,gBAAgB,EAEjB,MAAM,iBAAiB,CAAC;AAIzB,wBAAgB,cAAc,IAAI,QAAQ,CAezC;AAQD,wBAAgB,SAAS,CACvB,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC1B,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,QAAQ,EACb,OAAO,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GACnC,QAAQ,GAAG,IAAI,CAGjB;AAKD,wBAAgB,YAAY,CAC1B,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC1B,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAAE,EACpB,OAAO,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GACnC,QAAQ,EAAE,CAMZ;AAMD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC1B,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,EACpB,QAAQ,EAAE,QAAQ,EAAE,EACpB,OAAO,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GACnC,QAAQ,EAAE,CAcZ;AAcD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC1B,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,EACpB,GAAG,EAAE,QAAQ,EACb,OAAO,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GACnC,QAAQ,GAAG,IAAI,CAUjB"}
|
package/dist/pickScene.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pickScene.js","sourceRoot":"","sources":["../src/pickScene.ts"],"names":[],"mappings":"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"}
|