@aura3d/engine 1.5.0 → 1.5.2
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/README.md +111 -46
- package/dist/engine/agent-api/ApplicationKits.d.ts +307 -0
- package/dist/engine/agent-api/ApplicationKits.d.ts.map +1 -0
- package/dist/engine/agent-api/ApplicationKits.js +650 -0
- package/dist/engine/agent-api/ApplicationKits.js.map +1 -0
- package/dist/engine/agent-api/CombatFrameData.d.ts +210 -0
- package/dist/engine/agent-api/CombatFrameData.d.ts.map +1 -0
- package/dist/engine/agent-api/CombatFrameData.js +324 -0
- package/dist/engine/agent-api/CombatFrameData.js.map +1 -0
- package/dist/engine/agent-api/FocusSelection.d.ts +186 -0
- package/dist/engine/agent-api/FocusSelection.d.ts.map +1 -0
- package/dist/engine/agent-api/FocusSelection.js +436 -0
- package/dist/engine/agent-api/FocusSelection.js.map +1 -0
- package/dist/engine/agent-api/GameGenreKits.d.ts +32 -1
- package/dist/engine/agent-api/GameGenreKits.d.ts.map +1 -1
- package/dist/engine/agent-api/GameGenreKits.js +51 -7
- package/dist/engine/agent-api/GameGenreKits.js.map +1 -1
- package/dist/engine/agent-api/GameSceneGeometryBindings.d.ts +10 -0
- package/dist/engine/agent-api/GameSceneGeometryBindings.d.ts.map +1 -1
- package/dist/engine/agent-api/GameSceneGeometryBindings.js +7 -0
- package/dist/engine/agent-api/GameSceneGeometryBindings.js.map +1 -1
- package/dist/engine/agent-api/PlatformerMotion.d.ts +177 -0
- package/dist/engine/agent-api/PlatformerMotion.d.ts.map +1 -0
- package/dist/engine/agent-api/PlatformerMotion.js +207 -0
- package/dist/engine/agent-api/PlatformerMotion.js.map +1 -0
- package/dist/engine/agent-api/SceneQueries.d.ts +124 -0
- package/dist/engine/agent-api/SceneQueries.d.ts.map +1 -0
- package/dist/engine/agent-api/SceneQueries.js +221 -0
- package/dist/engine/agent-api/SceneQueries.js.map +1 -0
- package/dist/engine/agent-api/SpatialAnchoring.d.ts +279 -0
- package/dist/engine/agent-api/SpatialAnchoring.d.ts.map +1 -0
- package/dist/engine/agent-api/SpatialAnchoring.js +394 -0
- package/dist/engine/agent-api/SpatialAnchoring.js.map +1 -0
- package/dist/engine/agent-api/VehicleChassis.d.ts +192 -0
- package/dist/engine/agent-api/VehicleChassis.d.ts.map +1 -0
- package/dist/engine/agent-api/VehicleChassis.js +322 -0
- package/dist/engine/agent-api/VehicleChassis.js.map +1 -0
- package/dist/engine/agent-api/VehicleDriverAi.d.ts +123 -0
- package/dist/engine/agent-api/VehicleDriverAi.d.ts.map +1 -0
- package/dist/engine/agent-api/VehicleDriverAi.js +217 -0
- package/dist/engine/agent-api/VehicleDriverAi.js.map +1 -0
- package/dist/engine/agent-api/WorldLabelRenderer.d.ts +146 -0
- package/dist/engine/agent-api/WorldLabelRenderer.d.ts.map +1 -0
- package/dist/engine/agent-api/WorldLabelRenderer.js +331 -0
- package/dist/engine/agent-api/WorldLabelRenderer.js.map +1 -0
- package/dist/engine/agent-api/index.d.ts +64 -1
- package/dist/engine/agent-api/index.d.ts.map +1 -1
- package/dist/engine/agent-api/index.js +148 -2
- package/dist/engine/agent-api/index.js.map +1 -1
- package/dist/engine/agent-api/product-viewer-runtime.d.ts.map +1 -1
- package/dist/rendering/CameraFraming.d.ts +77 -0
- package/dist/rendering/CameraFraming.d.ts.map +1 -1
- package/dist/rendering/CameraFraming.js +176 -1
- package/dist/rendering/CameraFraming.js.map +1 -1
- package/dist/rendering/Renderer.d.ts +25 -2
- package/dist/rendering/Renderer.d.ts.map +1 -1
- package/dist/rendering/Renderer.js +11 -3
- package/dist/rendering/Renderer.js.map +1 -1
- package/dist/rendering/index.d.ts +3 -3
- package/dist/rendering/index.d.ts.map +1 -1
- package/dist/rendering/index.js +1 -1
- package/dist/rendering/index.js.map +1 -1
- package/package.json +120 -115
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reusable scene queries: raycasts, shape casts and ground probes.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this exists
|
|
5
|
+
*
|
|
6
|
+
* The physics audit (`tests/reports/aura3d-physics-audit.json`) classified raycasts, shape
|
|
7
|
+
* casts, penetration resolution, friction, restitution, constraints and continuous
|
|
8
|
+
* collision detection as **unused**: implemented in `@aura3d/physics`, covered by its own
|
|
9
|
+
* suites, and unreachable from the public agent API. A route needing to answer "what is
|
|
10
|
+
* under this point" therefore had two options -- reach into a package's internals, or write
|
|
11
|
+
* the query by hand. Both are the same defect class as the hardcoded contact planes this
|
|
12
|
+
* remediation removed.
|
|
13
|
+
*
|
|
14
|
+
* `PhysicsWorld` already implements `raycast`, `raycastAll`, `sphereCast` and
|
|
15
|
+
* `sphereCastAll`. This module is the public surface over them, plus the pure
|
|
16
|
+
* scene-geometry queries a route usually actually wants: a downward ground probe, and a
|
|
17
|
+
* query against declarative scene nodes rather than a constructed physics world.
|
|
18
|
+
*
|
|
19
|
+
* The pure paths are dependency-free and unit-testable; the physics-backed path adapts a
|
|
20
|
+
* `PhysicsWorld` when a route has one.
|
|
21
|
+
*/
|
|
22
|
+
import type { AuraSceneNode, AuraVec3 } from "./index.js";
|
|
23
|
+
import { type PlacedBounds } from "./SpatialAnchoring.js";
|
|
24
|
+
export interface SceneRay {
|
|
25
|
+
readonly origin: AuraVec3;
|
|
26
|
+
/** Direction; normalized internally, so a caller may pass any non-zero vector. */
|
|
27
|
+
readonly direction: AuraVec3;
|
|
28
|
+
readonly maxDistance?: number | undefined;
|
|
29
|
+
}
|
|
30
|
+
export interface SceneQueryHit {
|
|
31
|
+
/** Name of the node that was hit, when the target carries one. */
|
|
32
|
+
readonly nodeName: string | undefined;
|
|
33
|
+
readonly point: AuraVec3;
|
|
34
|
+
readonly normal: AuraVec3;
|
|
35
|
+
readonly distance: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Axis-aligned box a query can test against.
|
|
39
|
+
*
|
|
40
|
+
* Scene nodes are reduced to these, which is exact for boxes and planes and a conservative
|
|
41
|
+
* bound for spheres, cylinders and models. Stated rather than implied: a route needing
|
|
42
|
+
* exact mesh intersection must use a physics world with real colliders.
|
|
43
|
+
*/
|
|
44
|
+
export interface SceneQueryTarget {
|
|
45
|
+
readonly nodeName: string | undefined;
|
|
46
|
+
readonly bounds: PlacedBounds;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Reduce declarative scene nodes to query targets.
|
|
50
|
+
*
|
|
51
|
+
* Only nodes with a resolvable position and scale participate. A model's bounds are its
|
|
52
|
+
* node scale, which is a conservative approximation: the caller is told so by
|
|
53
|
+
* {@link SceneQueryTarget}'s documentation rather than discovering it from a wrong result.
|
|
54
|
+
*/
|
|
55
|
+
export declare function sceneQueryTargets(nodes: readonly AuraSceneNode[]): readonly SceneQueryTarget[];
|
|
56
|
+
/**
|
|
57
|
+
* Cast a ray against query targets, returning the nearest hit.
|
|
58
|
+
*
|
|
59
|
+
* Slab-method AABB intersection: exact for axis-aligned boxes and correct for the
|
|
60
|
+
* conservative bounds of other node kinds.
|
|
61
|
+
*/
|
|
62
|
+
export declare function raycastSceneTargets(targets: readonly SceneQueryTarget[], ray: SceneRay): SceneQueryHit | undefined;
|
|
63
|
+
/** Every hit along a ray, nearest first. */
|
|
64
|
+
export declare function raycastSceneTargetsAll(targets: readonly SceneQueryTarget[], ray: SceneRay): readonly SceneQueryHit[];
|
|
65
|
+
/**
|
|
66
|
+
* Downward ground probe.
|
|
67
|
+
*
|
|
68
|
+
* The query a route asks most often, and the one that was previously answered by a frozen
|
|
69
|
+
* constant. Returns the surface height under a point, or `undefined` when nothing is below
|
|
70
|
+
* it -- which is a meaningful answer, not a reason to substitute zero.
|
|
71
|
+
*/
|
|
72
|
+
export declare function groundProbe(targets: readonly SceneQueryTarget[], x: number, z: number, options?: {
|
|
73
|
+
readonly fromHeight?: number | undefined;
|
|
74
|
+
readonly maxDistance?: number | undefined;
|
|
75
|
+
}): {
|
|
76
|
+
readonly height: number;
|
|
77
|
+
readonly normal: AuraVec3;
|
|
78
|
+
readonly nodeName: string | undefined;
|
|
79
|
+
} | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Sphere cast against query targets.
|
|
82
|
+
*
|
|
83
|
+
* Implemented by inflating each target's bounds by the sphere radius, which is the standard
|
|
84
|
+
* conservative reduction of a sphere sweep to a ray test. Corners are therefore treated as
|
|
85
|
+
* rounded by radius rather than exactly; that over-reports contact slightly near an edge and
|
|
86
|
+
* never under-reports, which is the safe direction for a clearance query.
|
|
87
|
+
*/
|
|
88
|
+
export declare function sphereCastSceneTargets(targets: readonly SceneQueryTarget[], ray: SceneRay, radius: number): SceneQueryHit | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Structural shape of the physics world's query surface.
|
|
91
|
+
*
|
|
92
|
+
* Structural rather than a concrete import so this module does not force `@aura3d/physics`
|
|
93
|
+
* into every consumer's graph, and so a test can supply a fake.
|
|
94
|
+
*/
|
|
95
|
+
export interface PhysicsQueryWorld {
|
|
96
|
+
raycast(origin: AuraVec3, direction: AuraVec3, options?: {
|
|
97
|
+
readonly maxDistance?: number;
|
|
98
|
+
readonly mask?: number;
|
|
99
|
+
}): {
|
|
100
|
+
readonly point: readonly [number, number, number];
|
|
101
|
+
readonly normal: readonly [number, number, number];
|
|
102
|
+
readonly distance: number;
|
|
103
|
+
readonly colliderId: number;
|
|
104
|
+
readonly bodyId: number;
|
|
105
|
+
} | undefined;
|
|
106
|
+
sphereCast?(origin: AuraVec3, radius: number, direction: AuraVec3, options?: {
|
|
107
|
+
readonly maxDistance?: number;
|
|
108
|
+
}): {
|
|
109
|
+
readonly point: readonly [number, number, number];
|
|
110
|
+
readonly normal: readonly [number, number, number];
|
|
111
|
+
readonly distance: number;
|
|
112
|
+
} | undefined;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Public raycast against a physics world.
|
|
116
|
+
*
|
|
117
|
+
* The adapter that makes `PhysicsWorld.raycast` reachable without a route importing
|
|
118
|
+
* `@aura3d/physics` directly. Returns the same {@link SceneQueryHit} shape as the pure
|
|
119
|
+
* paths, so a route can move between them without changing its call sites.
|
|
120
|
+
*/
|
|
121
|
+
export declare function raycastPhysicsWorld(world: PhysicsQueryWorld, ray: SceneRay): SceneQueryHit | undefined;
|
|
122
|
+
/** Public sphere cast against a physics world, when the world supports one. */
|
|
123
|
+
export declare function sphereCastPhysicsWorld(world: PhysicsQueryWorld, ray: SceneRay, radius: number): SceneQueryHit | undefined;
|
|
124
|
+
//# sourceMappingURL=SceneQueries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SceneQueries.d.ts","sourceRoot":"","sources":["../../../../../packages/engine/src/agent-api/SceneQueries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reusable scene queries: raycasts, shape casts and ground probes.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this exists
|
|
5
|
+
*
|
|
6
|
+
* The physics audit (`tests/reports/aura3d-physics-audit.json`) classified raycasts, shape
|
|
7
|
+
* casts, penetration resolution, friction, restitution, constraints and continuous
|
|
8
|
+
* collision detection as **unused**: implemented in `@aura3d/physics`, covered by its own
|
|
9
|
+
* suites, and unreachable from the public agent API. A route needing to answer "what is
|
|
10
|
+
* under this point" therefore had two options -- reach into a package's internals, or write
|
|
11
|
+
* the query by hand. Both are the same defect class as the hardcoded contact planes this
|
|
12
|
+
* remediation removed.
|
|
13
|
+
*
|
|
14
|
+
* `PhysicsWorld` already implements `raycast`, `raycastAll`, `sphereCast` and
|
|
15
|
+
* `sphereCastAll`. This module is the public surface over them, plus the pure
|
|
16
|
+
* scene-geometry queries a route usually actually wants: a downward ground probe, and a
|
|
17
|
+
* query against declarative scene nodes rather than a constructed physics world.
|
|
18
|
+
*
|
|
19
|
+
* The pure paths are dependency-free and unit-testable; the physics-backed path adapts a
|
|
20
|
+
* `PhysicsWorld` when a route has one.
|
|
21
|
+
*/
|
|
22
|
+
import { placedBounds } from "./SpatialAnchoring.js";
|
|
23
|
+
/**
|
|
24
|
+
* Reduce declarative scene nodes to query targets.
|
|
25
|
+
*
|
|
26
|
+
* Only nodes with a resolvable position and scale participate. A model's bounds are its
|
|
27
|
+
* node scale, which is a conservative approximation: the caller is told so by
|
|
28
|
+
* {@link SceneQueryTarget}'s documentation rather than discovering it from a wrong result.
|
|
29
|
+
*/
|
|
30
|
+
export function sceneQueryTargets(nodes) {
|
|
31
|
+
const targets = [];
|
|
32
|
+
for (const node of nodes) {
|
|
33
|
+
if (node.kind !== "primitive" && node.kind !== "model")
|
|
34
|
+
continue;
|
|
35
|
+
const positioned = node;
|
|
36
|
+
const position = positioned.position;
|
|
37
|
+
if (!position)
|
|
38
|
+
continue;
|
|
39
|
+
const scale = positioned.scale;
|
|
40
|
+
const size = scale === undefined
|
|
41
|
+
? [1, 1, 1]
|
|
42
|
+
: typeof scale === "number"
|
|
43
|
+
? [scale, scale, scale]
|
|
44
|
+
: [scale[0], scale[1], scale[2]];
|
|
45
|
+
targets.push({
|
|
46
|
+
nodeName: node.name,
|
|
47
|
+
// Primitive nodes are centred on their position, so the placed bounds' floor is half
|
|
48
|
+
// a height below it.
|
|
49
|
+
bounds: placedBounds({
|
|
50
|
+
position: [position[0], position[1] - size[1] / 2, position[2]],
|
|
51
|
+
size,
|
|
52
|
+
floorY: position[1] - size[1] / 2
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return targets;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Cast a ray against query targets, returning the nearest hit.
|
|
60
|
+
*
|
|
61
|
+
* Slab-method AABB intersection: exact for axis-aligned boxes and correct for the
|
|
62
|
+
* conservative bounds of other node kinds.
|
|
63
|
+
*/
|
|
64
|
+
export function raycastSceneTargets(targets, ray) {
|
|
65
|
+
return raycastSceneTargetsAll(targets, ray)[0];
|
|
66
|
+
}
|
|
67
|
+
/** Every hit along a ray, nearest first. */
|
|
68
|
+
export function raycastSceneTargetsAll(targets, ray) {
|
|
69
|
+
const direction = normalize(ray.direction);
|
|
70
|
+
if (direction === undefined)
|
|
71
|
+
return [];
|
|
72
|
+
const maxDistance = ray.maxDistance ?? Number.POSITIVE_INFINITY;
|
|
73
|
+
const hits = [];
|
|
74
|
+
for (const target of targets) {
|
|
75
|
+
const hit = intersectAabb(ray.origin, direction, target.bounds, maxDistance);
|
|
76
|
+
if (!hit)
|
|
77
|
+
continue;
|
|
78
|
+
hits.push({ nodeName: target.nodeName, point: hit.point, normal: hit.normal, distance: hit.distance });
|
|
79
|
+
}
|
|
80
|
+
return hits.sort((a, b) => a.distance - b.distance);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Downward ground probe.
|
|
84
|
+
*
|
|
85
|
+
* The query a route asks most often, and the one that was previously answered by a frozen
|
|
86
|
+
* constant. Returns the surface height under a point, or `undefined` when nothing is below
|
|
87
|
+
* it -- which is a meaningful answer, not a reason to substitute zero.
|
|
88
|
+
*/
|
|
89
|
+
export function groundProbe(targets, x, z, options = {}) {
|
|
90
|
+
const fromHeight = options.fromHeight ?? 1e4;
|
|
91
|
+
const hit = raycastSceneTargets(targets, {
|
|
92
|
+
origin: [x, fromHeight, z],
|
|
93
|
+
direction: [0, -1, 0],
|
|
94
|
+
maxDistance: options.maxDistance ?? Number.POSITIVE_INFINITY
|
|
95
|
+
});
|
|
96
|
+
if (!hit)
|
|
97
|
+
return undefined;
|
|
98
|
+
return { height: hit.point[1], normal: hit.normal, nodeName: hit.nodeName };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Sphere cast against query targets.
|
|
102
|
+
*
|
|
103
|
+
* Implemented by inflating each target's bounds by the sphere radius, which is the standard
|
|
104
|
+
* conservative reduction of a sphere sweep to a ray test. Corners are therefore treated as
|
|
105
|
+
* rounded by radius rather than exactly; that over-reports contact slightly near an edge and
|
|
106
|
+
* never under-reports, which is the safe direction for a clearance query.
|
|
107
|
+
*/
|
|
108
|
+
export function sphereCastSceneTargets(targets, ray, radius) {
|
|
109
|
+
const inflated = targets.map((target) => ({
|
|
110
|
+
nodeName: target.nodeName,
|
|
111
|
+
bounds: inflateBounds(target.bounds, Math.max(0, radius))
|
|
112
|
+
}));
|
|
113
|
+
return raycastSceneTargets(inflated, ray);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Public raycast against a physics world.
|
|
117
|
+
*
|
|
118
|
+
* The adapter that makes `PhysicsWorld.raycast` reachable without a route importing
|
|
119
|
+
* `@aura3d/physics` directly. Returns the same {@link SceneQueryHit} shape as the pure
|
|
120
|
+
* paths, so a route can move between them without changing its call sites.
|
|
121
|
+
*/
|
|
122
|
+
export function raycastPhysicsWorld(world, ray) {
|
|
123
|
+
const direction = normalize(ray.direction);
|
|
124
|
+
if (direction === undefined)
|
|
125
|
+
return undefined;
|
|
126
|
+
const hit = world.raycast(ray.origin, direction, ray.maxDistance === undefined ? {} : { maxDistance: ray.maxDistance });
|
|
127
|
+
if (!hit)
|
|
128
|
+
return undefined;
|
|
129
|
+
return {
|
|
130
|
+
// A physics hit identifies a collider by id; the caller maps that to a name if it needs one.
|
|
131
|
+
nodeName: `collider-${hit.colliderId}`,
|
|
132
|
+
point: [hit.point[0], hit.point[1], hit.point[2]],
|
|
133
|
+
normal: [hit.normal[0], hit.normal[1], hit.normal[2]],
|
|
134
|
+
distance: hit.distance
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/** Public sphere cast against a physics world, when the world supports one. */
|
|
138
|
+
export function sphereCastPhysicsWorld(world, ray, radius) {
|
|
139
|
+
if (!world.sphereCast)
|
|
140
|
+
return undefined;
|
|
141
|
+
const direction = normalize(ray.direction);
|
|
142
|
+
if (direction === undefined)
|
|
143
|
+
return undefined;
|
|
144
|
+
const hit = world.sphereCast(ray.origin, radius, direction, ray.maxDistance === undefined ? {} : { maxDistance: ray.maxDistance });
|
|
145
|
+
if (!hit)
|
|
146
|
+
return undefined;
|
|
147
|
+
return {
|
|
148
|
+
nodeName: undefined,
|
|
149
|
+
point: [hit.point[0], hit.point[1], hit.point[2]],
|
|
150
|
+
normal: [hit.normal[0], hit.normal[1], hit.normal[2]],
|
|
151
|
+
distance: hit.distance
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function inflateBounds(bounds, amount) {
|
|
155
|
+
return {
|
|
156
|
+
min: [bounds.min[0] - amount, bounds.min[1] - amount, bounds.min[2] - amount],
|
|
157
|
+
max: [bounds.max[0] + amount, bounds.max[1] + amount, bounds.max[2] + amount],
|
|
158
|
+
center: bounds.center,
|
|
159
|
+
size: [bounds.size[0] + amount * 2, bounds.size[1] + amount * 2, bounds.size[2] + amount * 2],
|
|
160
|
+
floorY: bounds.floorY - amount
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/** Slab-method ray/AABB intersection. Returns the entry point and its face normal. */
|
|
164
|
+
function intersectAabb(origin, direction, bounds, maxDistance) {
|
|
165
|
+
let tMin = 0;
|
|
166
|
+
let tMax = maxDistance;
|
|
167
|
+
let hitAxis = 0;
|
|
168
|
+
let hitSign = 1;
|
|
169
|
+
const min = bounds.min;
|
|
170
|
+
const max = bounds.max;
|
|
171
|
+
for (let axis = 0; axis < 3; axis += 1) {
|
|
172
|
+
const o = origin[axis];
|
|
173
|
+
const d = direction[axis];
|
|
174
|
+
if (Math.abs(d) < 1e-12) {
|
|
175
|
+
// Ray is parallel to this slab: it must already be inside it.
|
|
176
|
+
if (o < min[axis] || o > max[axis])
|
|
177
|
+
return undefined;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const inverse = 1 / d;
|
|
181
|
+
let near = (min[axis] - o) * inverse;
|
|
182
|
+
let far = (max[axis] - o) * inverse;
|
|
183
|
+
let sign = -1;
|
|
184
|
+
if (near > far) {
|
|
185
|
+
const swap = near;
|
|
186
|
+
near = far;
|
|
187
|
+
far = swap;
|
|
188
|
+
sign = 1;
|
|
189
|
+
}
|
|
190
|
+
if (near > tMin) {
|
|
191
|
+
tMin = near;
|
|
192
|
+
hitAxis = axis;
|
|
193
|
+
hitSign = sign;
|
|
194
|
+
}
|
|
195
|
+
if (far < tMax)
|
|
196
|
+
tMax = far;
|
|
197
|
+
if (tMin > tMax)
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
if (tMin > maxDistance)
|
|
201
|
+
return undefined;
|
|
202
|
+
const normal = [0, 0, 0];
|
|
203
|
+
const mutable = normal;
|
|
204
|
+
mutable[hitAxis] = hitSign;
|
|
205
|
+
return {
|
|
206
|
+
point: [
|
|
207
|
+
origin[0] + direction[0] * tMin,
|
|
208
|
+
origin[1] + direction[1] * tMin,
|
|
209
|
+
origin[2] + direction[2] * tMin
|
|
210
|
+
],
|
|
211
|
+
normal,
|
|
212
|
+
distance: tMin
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function normalize(vector) {
|
|
216
|
+
const length = Math.hypot(vector[0], vector[1], vector[2]);
|
|
217
|
+
if (!(length > 0) || !Number.isFinite(length))
|
|
218
|
+
return undefined;
|
|
219
|
+
return [vector[0] / length, vector[1] / length, vector[2] / length];
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=SceneQueries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SceneQueries.js","sourceRoot":"","sources":["../../../../../packages/engine/src/agent-api/SceneQueries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset-relative spatial layout and semantic anchoring.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this exists
|
|
5
|
+
*
|
|
6
|
+
* Public routes placed helper geometry -- status markers, control stations,
|
|
7
|
+
* selection rings, callout panels, staging props -- at literal world
|
|
8
|
+
* coordinates chosen by eye against whatever asset was loaded that week. When
|
|
9
|
+
* the asset changed, or its bounds changed, the coordinates did not. The
|
|
10
|
+
* visible result is procedural boxes floating beside the scene rather than
|
|
11
|
+
* attached to the equipment they annotate.
|
|
12
|
+
*
|
|
13
|
+
* `CAR_SCENE_HEIGHT` was the same defect in a single constant: a value correct
|
|
14
|
+
* for one asset, frozen, then wrong. This module removes the reason to write
|
|
15
|
+
* such a constant. A route states intent -- "above this machine", "beside the
|
|
16
|
+
* workcell", "on the floor in front of the product" -- and reads back a world
|
|
17
|
+
* position derived from the asset's own placed bounds.
|
|
18
|
+
*
|
|
19
|
+
* Everything here is pure: no renderer, no asset loading, no DOM. Anchors are
|
|
20
|
+
* resolved from {@link PlacedBounds}, which a route obtains from typed asset
|
|
21
|
+
* bounds plus its intended scale via {@link placedBoundsFromAsset}.
|
|
22
|
+
*/
|
|
23
|
+
import { type SceneAssetLike, type SceneBounds, type Vec3 } from "./SceneGroundingUtils.js";
|
|
24
|
+
/**
|
|
25
|
+
* Bounds of an asset as it actually sits in the scene.
|
|
26
|
+
*
|
|
27
|
+
* Distinct from {@link SceneBounds}, which is in raw asset-local units. Anchors
|
|
28
|
+
* must resolve against placed bounds or they reproduce the defect they exist to
|
|
29
|
+
* prevent: a correct-looking offset in local units lands in the wrong place
|
|
30
|
+
* once the renderer normalizes and scales the model.
|
|
31
|
+
*/
|
|
32
|
+
export interface PlacedBounds {
|
|
33
|
+
readonly min: Vec3;
|
|
34
|
+
readonly max: Vec3;
|
|
35
|
+
readonly center: Vec3;
|
|
36
|
+
readonly size: Vec3;
|
|
37
|
+
/** Y of the surface the subject rests on. */
|
|
38
|
+
readonly floorY: number;
|
|
39
|
+
}
|
|
40
|
+
/** Faces and corners of a placed bounding volume. */
|
|
41
|
+
export type BoundsAnchor = "center" | "top" | "bottom" | "front" | "rear" | "left" | "right" | "top-front" | "top-rear" | "top-left" | "top-right" | "floor-front" | "floor-rear" | "floor-left" | "floor-right" | "corner-front-left" | "corner-front-right" | "corner-rear-left" | "corner-rear-right";
|
|
42
|
+
export interface AnchorOptions {
|
|
43
|
+
/**
|
|
44
|
+
* Distance to push the anchor outward along its own face normal, in world
|
|
45
|
+
* units. Positive moves away from the subject.
|
|
46
|
+
*/
|
|
47
|
+
readonly offset?: number | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Additional world-space nudge applied after the face offset. Reserved for
|
|
50
|
+
* genuine art direction; it is not a place to reintroduce asset-specific
|
|
51
|
+
* corrections.
|
|
52
|
+
*/
|
|
53
|
+
readonly worldOffset?: Vec3 | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Keep the anchor at floor level regardless of the face chosen. Used for
|
|
56
|
+
* ground-standing props beside an asset.
|
|
57
|
+
*/
|
|
58
|
+
readonly onFloor?: boolean | undefined;
|
|
59
|
+
}
|
|
60
|
+
export interface ResolvedAnchor {
|
|
61
|
+
readonly position: Vec3;
|
|
62
|
+
/** Outward normal of the face the anchor was taken from. */
|
|
63
|
+
readonly normal: Vec3;
|
|
64
|
+
readonly anchor: BoundsAnchor;
|
|
65
|
+
/** True when the anchor lies outside the subject's placed bounds. */
|
|
66
|
+
readonly outsideBounds: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build placed bounds from a subject's world position, size and floor.
|
|
70
|
+
*
|
|
71
|
+
* `position` is the subject's floor contact point, matching how Aura3D's safe
|
|
72
|
+
* model renderer grounds a normalized model on its node origin.
|
|
73
|
+
*/
|
|
74
|
+
export declare function placedBounds(options: {
|
|
75
|
+
readonly position: Vec3;
|
|
76
|
+
readonly size: Vec3;
|
|
77
|
+
readonly floorY?: number | undefined;
|
|
78
|
+
}): PlacedBounds;
|
|
79
|
+
/**
|
|
80
|
+
* Placed bounds for a typed asset rendered with `model(asset)`.
|
|
81
|
+
*
|
|
82
|
+
* Mirrors the safe renderer: the asset is normalized to
|
|
83
|
+
* `normalizedMaxDimension`, multiplied by node scale, and grounded so its
|
|
84
|
+
* lowest point rests on `floorY`. A route therefore never needs the asset's raw
|
|
85
|
+
* dimensions to place something relative to it.
|
|
86
|
+
*/
|
|
87
|
+
export declare function placedBoundsFromAsset(asset: SceneAssetLike, options: {
|
|
88
|
+
readonly position?: Vec3 | undefined;
|
|
89
|
+
/** `targetMaxDimension` passed to `model(asset)`, in world units. */
|
|
90
|
+
readonly targetMaxDimension: number;
|
|
91
|
+
readonly floorY?: number | undefined;
|
|
92
|
+
}): PlacedBounds;
|
|
93
|
+
export interface RegionFittedSizeOptions {
|
|
94
|
+
/**
|
|
95
|
+
* Fraction of the region the subject should occupy along its widest
|
|
96
|
+
* horizontal axis, 0..1.
|
|
97
|
+
*/
|
|
98
|
+
readonly occupancy: number;
|
|
99
|
+
/**
|
|
100
|
+
* Which region axes constrain the fit. Defaults to the horizontal axes, which
|
|
101
|
+
* is what "a vehicle inside a city block" means; include `"y"` when vertical
|
|
102
|
+
* headroom is also a real constraint, such as a crate inside a warehouse bay.
|
|
103
|
+
*/
|
|
104
|
+
readonly axes?: readonly ("x" | "y" | "z")[] | undefined;
|
|
105
|
+
/** Never size the subject below this world-unit maximum dimension. */
|
|
106
|
+
readonly minSize?: number | undefined;
|
|
107
|
+
/** Never size the subject above this world-unit maximum dimension. */
|
|
108
|
+
readonly maxSize?: number | undefined;
|
|
109
|
+
}
|
|
110
|
+
export interface RegionFittedSize {
|
|
111
|
+
/**
|
|
112
|
+
* Pass straight to `model(asset, { targetMaxDimension })` so the renderer
|
|
113
|
+
* derives the scale from the asset's own bounds.
|
|
114
|
+
*/
|
|
115
|
+
readonly targetMaxDimension: number;
|
|
116
|
+
/** Fraction of the region actually occupied after clamping. */
|
|
117
|
+
readonly occupancy: number;
|
|
118
|
+
/** Region extents the fit was computed against. */
|
|
119
|
+
readonly regionSize: Vec3;
|
|
120
|
+
/** True when `minSize` or `maxSize` overrode the requested occupancy. */
|
|
121
|
+
readonly clamped: boolean;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Size an asset so it occupies a chosen fraction of a region it sits inside.
|
|
125
|
+
*
|
|
126
|
+
* Placement was already bounds-derived through {@link resolveSemanticRegion},
|
|
127
|
+
* but *sizing* was not: a route that knew where a vehicle belonged still had to
|
|
128
|
+
* invent a multiplier such as `.scale(1.58)` to decide how big it should be.
|
|
129
|
+
* That number carries no relationship to either the asset or its surroundings,
|
|
130
|
+
* so it silently becomes wrong the moment the asset is swapped or the scene
|
|
131
|
+
* resized — which is precisely the "hero fills the frame and occludes the scene"
|
|
132
|
+
* defect class.
|
|
133
|
+
*
|
|
134
|
+
* This returns a `targetMaxDimension` rather than a raw scale factor on purpose.
|
|
135
|
+
* A scale factor is only meaningful relative to an asset's unknown raw
|
|
136
|
+
* dimensions, whereas a target dimension is an absolute statement about world
|
|
137
|
+
* size that the renderer resolves against the asset's real bounds.
|
|
138
|
+
*/
|
|
139
|
+
export declare function fitSizeToRegion(region: ResolvedSemanticRegion | PlacedBounds, options: RegionFittedSizeOptions): RegionFittedSize;
|
|
140
|
+
/** Placed bounds for a raw {@link SceneBounds} already expressed in world units. */
|
|
141
|
+
export declare function placedBoundsFromWorldBounds(bounds: SceneBounds): PlacedBounds;
|
|
142
|
+
/**
|
|
143
|
+
* Resolve a world position on or beside a subject's placed bounds.
|
|
144
|
+
*
|
|
145
|
+
* The returned position is on the named face at `offset` distance outward. This
|
|
146
|
+
* is the replacement for literal helper coordinates: it tracks the asset.
|
|
147
|
+
*/
|
|
148
|
+
export declare function resolveBoundsAnchor(bounds: PlacedBounds, anchor: BoundsAnchor, options?: AnchorOptions): ResolvedAnchor;
|
|
149
|
+
/** True when a world point lies inside the placed bounds (inclusive). */
|
|
150
|
+
export declare function containsPoint(bounds: PlacedBounds, point: Vec3, epsilon?: number): boolean;
|
|
151
|
+
/**
|
|
152
|
+
* A named region inside a subject, expressed in normalized bounds space.
|
|
153
|
+
*
|
|
154
|
+
* This is how a route addresses "the assembly zone" or "the earcups" without
|
|
155
|
+
* hardcoding world coordinates. `u`/`v`/`w` run 0..1 across the subject's X/Y/Z
|
|
156
|
+
* extents, so the region follows the asset when its size or placement changes.
|
|
157
|
+
*/
|
|
158
|
+
export interface SemanticRegion {
|
|
159
|
+
readonly id: string;
|
|
160
|
+
readonly label?: string | undefined;
|
|
161
|
+
/** Normalized centre within the subject's bounds, each component 0..1. */
|
|
162
|
+
readonly u: number;
|
|
163
|
+
readonly v: number;
|
|
164
|
+
readonly w: number;
|
|
165
|
+
/** Normalized extents of the region, each component 0..1. Defaults to a point. */
|
|
166
|
+
readonly extent?: readonly [number, number, number] | undefined;
|
|
167
|
+
}
|
|
168
|
+
export interface ResolvedSemanticRegion {
|
|
169
|
+
readonly id: string;
|
|
170
|
+
readonly label: string | undefined;
|
|
171
|
+
readonly center: Vec3;
|
|
172
|
+
readonly size: Vec3;
|
|
173
|
+
readonly min: Vec3;
|
|
174
|
+
readonly max: Vec3;
|
|
175
|
+
}
|
|
176
|
+
/** Resolve a normalized semantic region to world-space bounds on the subject. */
|
|
177
|
+
export declare function resolveSemanticRegion(bounds: PlacedBounds, region: SemanticRegion): ResolvedSemanticRegion;
|
|
178
|
+
export interface DistributionOptions {
|
|
179
|
+
/** How many items to place. */
|
|
180
|
+
readonly count: number;
|
|
181
|
+
/** Minimum world-space gap between adjacent items. */
|
|
182
|
+
readonly minSpacing?: number | undefined;
|
|
183
|
+
/** Deterministic seed. Distribution is fully determined by this value. */
|
|
184
|
+
readonly seed?: number | undefined;
|
|
185
|
+
/** Keep every item on the floor plane. */
|
|
186
|
+
readonly onFloor?: boolean | undefined;
|
|
187
|
+
/** Jitter as a fraction of available spacing, 0..1. Defaults to 0 (exact grid). */
|
|
188
|
+
readonly jitter?: number | undefined;
|
|
189
|
+
}
|
|
190
|
+
export interface DistributedPlacement {
|
|
191
|
+
readonly index: number;
|
|
192
|
+
readonly position: Vec3;
|
|
193
|
+
/** Distance to the nearest other placement. */
|
|
194
|
+
readonly nearestNeighborDistance: number;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Distribute items evenly across a region, honouring a minimum spacing.
|
|
198
|
+
*
|
|
199
|
+
* Deterministic for a given seed so gameplay and evidence are reproducible.
|
|
200
|
+
* Used instead of `-0.45 + index * 0.17` style literals, which encode both the
|
|
201
|
+
* region and its spacing into one unexplained pair of numbers.
|
|
202
|
+
*/
|
|
203
|
+
export declare function distributeInRegion(region: {
|
|
204
|
+
readonly min: Vec3;
|
|
205
|
+
readonly max: Vec3;
|
|
206
|
+
}, options: DistributionOptions): readonly DistributedPlacement[];
|
|
207
|
+
/** Minimum-spacing check for a set of placements. */
|
|
208
|
+
export declare function validateSpacing(placements: readonly DistributedPlacement[], minSpacing: number): {
|
|
209
|
+
readonly ok: boolean;
|
|
210
|
+
readonly violations: readonly {
|
|
211
|
+
readonly index: number;
|
|
212
|
+
readonly distance: number;
|
|
213
|
+
}[];
|
|
214
|
+
};
|
|
215
|
+
export interface RadialPlacementOptions {
|
|
216
|
+
readonly count: number;
|
|
217
|
+
/** Radius measured from the subject's bounds, not from the origin. */
|
|
218
|
+
readonly radius: number;
|
|
219
|
+
/** Starting angle in radians. Defaults to 0. */
|
|
220
|
+
readonly startAngle?: number | undefined;
|
|
221
|
+
/** Height above the floor. Defaults to the subject's vertical centre. */
|
|
222
|
+
readonly height?: number | undefined;
|
|
223
|
+
/** Sweep in radians. Defaults to a full circle. */
|
|
224
|
+
readonly sweep?: number | undefined;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Place items on a circle around a subject.
|
|
228
|
+
*
|
|
229
|
+
* The radius is added to the subject's own horizontal half-extent, so a ring of
|
|
230
|
+
* markers stays clear of the asset regardless of how large the asset is.
|
|
231
|
+
*/
|
|
232
|
+
export declare function distributeAroundBounds(bounds: PlacedBounds, options: RadialPlacementOptions): readonly DistributedPlacement[];
|
|
233
|
+
/**
|
|
234
|
+
* Spatial invariant report for a set of helper placements.
|
|
235
|
+
*
|
|
236
|
+
* This is the machine-checkable form of "no floating procedural props". A route
|
|
237
|
+
* publishes it; a gate asserts on it. It replaces judging placement by eye or
|
|
238
|
+
* by counting coloured pixels.
|
|
239
|
+
*/
|
|
240
|
+
export interface SpatialInvariantReport {
|
|
241
|
+
readonly schema: "aura3d-spatial-invariants/1.0";
|
|
242
|
+
readonly subjectBounds: PlacedBounds;
|
|
243
|
+
readonly checks: readonly {
|
|
244
|
+
readonly id: string;
|
|
245
|
+
readonly description: string;
|
|
246
|
+
readonly passes: boolean;
|
|
247
|
+
readonly detail: string;
|
|
248
|
+
}[];
|
|
249
|
+
readonly passes: boolean;
|
|
250
|
+
}
|
|
251
|
+
export interface HelperPlacementClaim {
|
|
252
|
+
readonly id: string;
|
|
253
|
+
readonly position: Vec3;
|
|
254
|
+
/**
|
|
255
|
+
* Where this element is meant to sit relative to the subject.
|
|
256
|
+
* `inside` -- within the subject's bounds (a selection ring on a part)
|
|
257
|
+
* `surface` -- on a bounds face, within one tolerance of it
|
|
258
|
+
* `outside` -- deliberately beside the subject (a control station, a panel)
|
|
259
|
+
*/
|
|
260
|
+
readonly relation: "inside" | "surface" | "outside";
|
|
261
|
+
/** Maximum world distance from the subject's bounds for `outside` elements. */
|
|
262
|
+
readonly maxDistance?: number | undefined;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Verify that helper geometry is anchored to its subject.
|
|
266
|
+
*
|
|
267
|
+
* `outside` elements must remain within `maxDistance` of the bounds: that is
|
|
268
|
+
* what separates "a control station beside the workcell" from "a box floating in
|
|
269
|
+
* the void". The default of 2x the subject's largest extent is generous enough
|
|
270
|
+
* for staging and tight enough to catch the digital-twin defect class.
|
|
271
|
+
*/
|
|
272
|
+
export declare function checkSpatialInvariants(bounds: PlacedBounds, claims: readonly HelperPlacementClaim[], options?: {
|
|
273
|
+
readonly surfaceTolerance?: number | undefined;
|
|
274
|
+
}): SpatialInvariantReport;
|
|
275
|
+
/** Shortest distance from a point to the bounds surface (0 when on it). */
|
|
276
|
+
export declare function distanceToBoundsSurface(bounds: PlacedBounds, point: Vec3): number;
|
|
277
|
+
/** Distance from a point to the bounds volume; 0 when inside. */
|
|
278
|
+
export declare function distanceOutsideBounds(bounds: PlacedBounds, point: Vec3): number;
|
|
279
|
+
//# sourceMappingURL=SpatialAnchoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpatialAnchoring.d.ts","sourceRoot":"","sources":["../../../../../packages/engine/src/agent-api/SpatialAnchoring.ts"],"names":[],"mappings":"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"}
|