@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
|
@@ -3,6 +3,16 @@ import { createExternalParityEnvironmentLighting, Geometry, IndexBuffer, PBRMate
|
|
|
3
3
|
import { DirectionalLight, PointLight, SpotLight } from "../../scene/index.js";
|
|
4
4
|
import { createTypedGLBActor } from "../production-runtime/TypedGLBActor.js";
|
|
5
5
|
import { AURA_NORMALIZED_MODEL_MAX_DIMENSION, boundsFromAsset, boundsHeight, boundsMaxDimension, boundsSize } from "./SceneGroundingUtils.js";
|
|
6
|
+
import { createWorldLabelLayer } from "./WorldLabelRenderer.js";
|
|
7
|
+
export * from "./SpatialAnchoring.js";
|
|
8
|
+
export * from "./FocusSelection.js";
|
|
9
|
+
export * from "./WorldLabelRenderer.js";
|
|
10
|
+
export * from "./VehicleChassis.js";
|
|
11
|
+
export * from "./VehicleDriverAi.js";
|
|
12
|
+
export * from "./PlatformerMotion.js";
|
|
13
|
+
export * from "./CombatFrameData.js";
|
|
14
|
+
export * from "./SceneQueries.js";
|
|
15
|
+
export * from "./ApplicationKits.js";
|
|
6
16
|
export * from "./FrameEncoder.js";
|
|
7
17
|
export * from "./BrowserFrameCaptureAdapter.js";
|
|
8
18
|
export * from "./MediaRecorderFrameEncoder.js";
|
|
@@ -1052,6 +1062,50 @@ export const camera = {
|
|
|
1052
1062
|
easing: options.easing ?? "easeInOut",
|
|
1053
1063
|
captureTime: options.captureTime
|
|
1054
1064
|
}),
|
|
1065
|
+
/**
|
|
1066
|
+
* A parallel-projection camera: no foreshortening, so equal world lengths
|
|
1067
|
+
* occupy equal screen lengths wherever they sit in depth.
|
|
1068
|
+
*
|
|
1069
|
+
* Reach for this when the projection is part of the meaning rather than a
|
|
1070
|
+
* stylistic choice — CAD and engineering views, floor plans, technical
|
|
1071
|
+
* diagrams, sprite and texture bakes, chart axes, and product shots that must
|
|
1072
|
+
* read as measurable. A long-lens perspective camera approximates it but
|
|
1073
|
+
* still converges, which is visible on long straight edges.
|
|
1074
|
+
*/
|
|
1075
|
+
orthographic: (options = {}) => ({
|
|
1076
|
+
mode: "orthographic",
|
|
1077
|
+
position: options.position ?? [0, 1.4, 4],
|
|
1078
|
+
target: options.target ?? [0, 0.8, 0],
|
|
1079
|
+
orthographicSize: options.orthographicSize ?? 1.4
|
|
1080
|
+
}),
|
|
1081
|
+
/**
|
|
1082
|
+
* The conventional isometric view: an orthographic camera on a 45-degree
|
|
1083
|
+
* azimuth and a ~35.264-degree elevation.
|
|
1084
|
+
*
|
|
1085
|
+
* That elevation is `atan(1 / sqrt(2))`, the angle at which the three world
|
|
1086
|
+
* axes project to equal screen lengths and 120 degrees apart. Authoring it as
|
|
1087
|
+
* a preset matters because the value is not memorable and an approximation
|
|
1088
|
+
* such as 30 or 45 degrees produces the subtly-wrong grid alignment that
|
|
1089
|
+
* isometric tile art immediately reveals.
|
|
1090
|
+
*/
|
|
1091
|
+
isometric: (options = {}) => {
|
|
1092
|
+
const target = options.target ?? [0, 0, 0];
|
|
1093
|
+
const distance = options.distance ?? 12;
|
|
1094
|
+
const elevation = Math.atan(1 / Math.SQRT2);
|
|
1095
|
+
const azimuth = Math.PI / 4;
|
|
1096
|
+
const horizontal = Math.cos(elevation) * distance;
|
|
1097
|
+
return {
|
|
1098
|
+
mode: "isometric",
|
|
1099
|
+
target,
|
|
1100
|
+
distance,
|
|
1101
|
+
orthographicSize: options.orthographicSize ?? 6,
|
|
1102
|
+
position: options.position ?? [
|
|
1103
|
+
target[0] + Math.sin(azimuth) * horizontal,
|
|
1104
|
+
target[1] + Math.sin(elevation) * distance,
|
|
1105
|
+
target[2] + Math.cos(azimuth) * horizontal
|
|
1106
|
+
]
|
|
1107
|
+
};
|
|
1108
|
+
},
|
|
1055
1109
|
autoFrame: (options = {}) => {
|
|
1056
1110
|
const bounds = options.bounds ?? { min: [-1, 0, -1], max: [1, 1.6, 1] };
|
|
1057
1111
|
const center = options.target ?? [
|
|
@@ -7073,6 +7127,66 @@ function isRenderableModelNode(node) {
|
|
|
7073
7127
|
function isWebGLRenderableNode(node) {
|
|
7074
7128
|
return isRenderableModelNode(node) || node.kind === "primitive";
|
|
7075
7129
|
}
|
|
7130
|
+
/**
|
|
7131
|
+
* Translate scene label nodes into world-anchored labels for the label layer.
|
|
7132
|
+
*
|
|
7133
|
+
* `labels.callout(...)` and friends previously reached the scene snapshot and were
|
|
7134
|
+
* counted by evidence but drawn only by the canvas2d fallback. Every route with a
|
|
7135
|
+
* typed GLB takes the production WebGL2 path, so every production callout was
|
|
7136
|
+
* silently dropped. This is the bridge that makes the public label API real in the
|
|
7137
|
+
* path public routes actually use.
|
|
7138
|
+
*/
|
|
7139
|
+
function worldLabelsFromSnapshot(snapshot, runtimeNodes) {
|
|
7140
|
+
const labelNodes = groups.flatten(snapshot.nodes).filter((node) => node.kind === "label");
|
|
7141
|
+
return labelNodes.map((node, index) => {
|
|
7142
|
+
const runtimeId = node.runtime?.id;
|
|
7143
|
+
const runtimeSnapshot = runtimeId ? runtimeNodes?.get(runtimeId)?.snapshot() : undefined;
|
|
7144
|
+
if (runtimeSnapshot?.visible === false) {
|
|
7145
|
+
return {
|
|
7146
|
+
id: node.name ?? `${node.label}-${index + 1}`,
|
|
7147
|
+
text: node.text,
|
|
7148
|
+
anchor: [0, 0, 0],
|
|
7149
|
+
offscreenPolicy: "hide"
|
|
7150
|
+
};
|
|
7151
|
+
}
|
|
7152
|
+
const position = (runtimeSnapshot?.position ?? node.position ?? labelDefaultPosition(node));
|
|
7153
|
+
const anchor = node.anchorWorldPosition ?? position;
|
|
7154
|
+
// Screen offset is derived from the gap between the label box and its anchor,
|
|
7155
|
+
// projected as a vertical nudge. A label that requests no separate anchor sits
|
|
7156
|
+
// directly on its own position.
|
|
7157
|
+
const separated = node.anchorWorldPosition !== undefined;
|
|
7158
|
+
return {
|
|
7159
|
+
id: node.name ?? `${node.label}-${index + 1}`,
|
|
7160
|
+
text: node.text,
|
|
7161
|
+
anchor: [position[0], position[1], position[2]],
|
|
7162
|
+
leaderAnchor: [anchor[0], anchor[1], anchor[2]],
|
|
7163
|
+
screenOffset: separated ? [0, 0] : [0, -26],
|
|
7164
|
+
color: typeof node.color === "string" ? node.color : undefined,
|
|
7165
|
+
background: typeof node.background === "string" ? node.background : undefined,
|
|
7166
|
+
// `size` is authored in world units for scene labels; map it onto a legible
|
|
7167
|
+
// pixel range rather than using it directly as a font size.
|
|
7168
|
+
fontSize: Math.max(11, Math.min(26, Math.round((node.size ?? 0.34) * 46))),
|
|
7169
|
+
leader: node.leader === true,
|
|
7170
|
+
offscreenPolicy: node.offscreenPolicy ?? (node.label === "hud" ? "draw" : "clamp"),
|
|
7171
|
+
...(node.label === "hud" && node.screenAnchor ? { screenAnchor: node.screenAnchor } : {}),
|
|
7172
|
+
...(node.label === "hud" && !node.screenAnchor ? { screenAnchor: "top-left" } : {})
|
|
7173
|
+
};
|
|
7174
|
+
});
|
|
7175
|
+
}
|
|
7176
|
+
/**
|
|
7177
|
+
* Mount the world-label layer for a canvas, if the scene has any label nodes.
|
|
7178
|
+
*
|
|
7179
|
+
* Returns `undefined` in headless or label-free scenes so nothing is created that
|
|
7180
|
+
* would then need disposing.
|
|
7181
|
+
*/
|
|
7182
|
+
function createSceneLabelLayer(canvas, snapshot) {
|
|
7183
|
+
if (!canvas || typeof document === "undefined")
|
|
7184
|
+
return undefined;
|
|
7185
|
+
const hasLabels = groups.flatten(snapshot.nodes).some((node) => node.kind === "label");
|
|
7186
|
+
if (!hasLabels)
|
|
7187
|
+
return undefined;
|
|
7188
|
+
return createWorldLabelLayer({ container: canvas.parentElement ?? document.body, canvas });
|
|
7189
|
+
}
|
|
7076
7190
|
async function startProductionRender(canvas, snapshot, diagnosticsState, options, overlay, beforeRender, isPaused = () => false, runtimeNodes) {
|
|
7077
7191
|
const renderableNode = snapshot.nodes.find(isWebGLRenderableNode);
|
|
7078
7192
|
if (!renderableNode) {
|
|
@@ -7081,6 +7195,7 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
|
|
|
7081
7195
|
const renderer = await createProductionSceneRenderer(canvas, snapshot, options.renderer, runtimeNodes);
|
|
7082
7196
|
diagnosticsState.renderer = renderer.diagnostics;
|
|
7083
7197
|
const continuousRender = shouldContinuouslyRender(snapshot);
|
|
7198
|
+
const labelLayer = createSceneLabelLayer(canvas, snapshot);
|
|
7084
7199
|
let disposed = false;
|
|
7085
7200
|
let animationHandle = 0;
|
|
7086
7201
|
let lastTime = 0;
|
|
@@ -7098,6 +7213,13 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
|
|
|
7098
7213
|
diagnosticsState.renderSize = [canvas.width, canvas.height];
|
|
7099
7214
|
diagnosticsState.evidence = collectAuraSceneEvidence(snapshot);
|
|
7100
7215
|
diagnosticsState.renderer = renderer.diagnostics;
|
|
7216
|
+
if (labelLayer) {
|
|
7217
|
+
// Reproject every frame against the renderer's own camera so labels track
|
|
7218
|
+
// their anchors while the camera moves.
|
|
7219
|
+
labelLayer.setLabels(worldLabelsFromSnapshot(snapshot, runtimeNodes));
|
|
7220
|
+
labelLayer.update(renderer.viewProjection(time));
|
|
7221
|
+
diagnosticsState.labels = labelLayer.snapshot();
|
|
7222
|
+
}
|
|
7101
7223
|
overlay?.update();
|
|
7102
7224
|
if (continuousRender && options.autoStart !== false && typeof requestAnimationFrame !== "undefined") {
|
|
7103
7225
|
animationHandle = requestAnimationFrame(renderFrame);
|
|
@@ -7112,6 +7234,7 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
|
|
|
7112
7234
|
disposed = true;
|
|
7113
7235
|
if (animationHandle && typeof cancelAnimationFrame !== "undefined")
|
|
7114
7236
|
cancelAnimationFrame(animationHandle);
|
|
7237
|
+
labelLayer?.dispose();
|
|
7115
7238
|
renderer.dispose();
|
|
7116
7239
|
}
|
|
7117
7240
|
};
|
|
@@ -7699,6 +7822,9 @@ async function createProductionRuntimeSceneRenderer(canvas, snapshot, rendererOp
|
|
|
7699
7822
|
latestFeatures = result.features;
|
|
7700
7823
|
return latestDeviceDiagnostics.drawCalls;
|
|
7701
7824
|
},
|
|
7825
|
+
viewProjection(time) {
|
|
7826
|
+
return createViewProjection(snapshot, canvas.width / Math.max(1, canvas.height), time, runtimeNodes);
|
|
7827
|
+
},
|
|
7702
7828
|
dispose() {
|
|
7703
7829
|
productionRenderer.dispose();
|
|
7704
7830
|
for (const { actor } of actorEntries)
|
|
@@ -8411,6 +8537,9 @@ async function createWebGLSceneRenderer(canvas, snapshot, rendererOptions, runti
|
|
|
8411
8537
|
}
|
|
8412
8538
|
return drawCalls;
|
|
8413
8539
|
},
|
|
8540
|
+
viewProjection(time) {
|
|
8541
|
+
return createViewProjection(snapshot, canvas.width / Math.max(1, canvas.height), time, runtimeNodes);
|
|
8542
|
+
},
|
|
8414
8543
|
dispose() {
|
|
8415
8544
|
for (const modelEntry of models) {
|
|
8416
8545
|
const textures = new Set();
|
|
@@ -9715,7 +9844,9 @@ function createViewProjection(snapshot, aspect, time, runtimeNodes) {
|
|
|
9715
9844
|
const target = resolveCameraTarget(snapshot, cameraSpec, runtimeNodes);
|
|
9716
9845
|
const eye = resolveCameraEye(snapshot, cameraSpec, time, runtimeNodes);
|
|
9717
9846
|
const view = lookAt(eye, target, [0, 1, 0]);
|
|
9718
|
-
const projection =
|
|
9847
|
+
const projection = isOrthographicCameraMode(cameraSpec.mode)
|
|
9848
|
+
? orthographic(cameraSpec.orthographicSize ?? 1.4, aspect, 0.05, 100)
|
|
9849
|
+
: perspective(((cameraSpec.fov ?? 45) * Math.PI) / 180, aspect, 0.05, 100);
|
|
9719
9850
|
return multiply4(projection, view);
|
|
9720
9851
|
}
|
|
9721
9852
|
function createModelMatrix(node, bounds, normalizeToUnit, time = 0) {
|
|
@@ -9792,6 +9923,20 @@ function primitiveSize(node) {
|
|
|
9792
9923
|
return [node.size, node.size, node.size];
|
|
9793
9924
|
return node.size ?? [1, 1, 1];
|
|
9794
9925
|
}
|
|
9926
|
+
export function isOrthographicCameraMode(mode) {
|
|
9927
|
+
return mode === "orthographic" || mode === "isometric";
|
|
9928
|
+
}
|
|
9929
|
+
function orthographic(halfHeight, aspect, near, far) {
|
|
9930
|
+
const safeHalfHeight = Math.max(1e-4, halfHeight);
|
|
9931
|
+
const halfWidth = Math.max(1e-4, safeHalfHeight * aspect);
|
|
9932
|
+
const nf = 1 / (near - far);
|
|
9933
|
+
return new Float32Array([
|
|
9934
|
+
1 / halfWidth, 0, 0, 0,
|
|
9935
|
+
0, 1 / safeHalfHeight, 0, 0,
|
|
9936
|
+
0, 0, 2 * nf, 0,
|
|
9937
|
+
0, 0, (far + near) * nf, 1
|
|
9938
|
+
]);
|
|
9939
|
+
}
|
|
9795
9940
|
function perspective(fovRadians, aspect, near, far) {
|
|
9796
9941
|
const f = 1 / Math.tan(fovRadians / 2);
|
|
9797
9942
|
const nf = 1 / (near - far);
|
|
@@ -10110,7 +10255,8 @@ function snapshotDiagnostics(value) {
|
|
|
10110
10255
|
evidence: value.evidence,
|
|
10111
10256
|
renderer: value.renderer,
|
|
10112
10257
|
warnings: [...value.warnings],
|
|
10113
|
-
errors: [...value.errors]
|
|
10258
|
+
errors: [...value.errors],
|
|
10259
|
+
...(value.labels ? { labels: value.labels } : {})
|
|
10114
10260
|
};
|
|
10115
10261
|
}
|
|
10116
10262
|
function collectGeneratedCodeWarnings(snapshot) {
|