@aura3d/engine 1.0.3 → 1.0.5
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 +309 -7
- package/dist/animation/AnimationClipEvents.d.ts +57 -0
- package/dist/animation/AnimationClipEvents.d.ts.map +1 -0
- package/dist/animation/AnimationClipEvents.js +171 -0
- package/dist/animation/AnimationClipEvents.js.map +1 -0
- package/dist/animation/AnimationClipRegistry.d.ts +76 -0
- package/dist/animation/AnimationClipRegistry.d.ts.map +1 -0
- package/dist/animation/AnimationClipRegistry.js +130 -0
- package/dist/animation/AnimationClipRegistry.js.map +1 -0
- package/dist/animation/AnimationController.d.ts +168 -0
- package/dist/animation/AnimationController.d.ts.map +1 -0
- package/dist/animation/AnimationController.js +619 -0
- package/dist/animation/AnimationController.js.map +1 -0
- package/dist/animation/HumanoidRetargeting.d.ts +76 -0
- package/dist/animation/HumanoidRetargeting.d.ts.map +1 -0
- package/dist/animation/HumanoidRetargeting.js +331 -0
- package/dist/animation/HumanoidRetargeting.js.map +1 -0
- package/dist/animation/browser-index.d.ts +18 -0
- package/dist/animation/browser-index.d.ts.map +1 -1
- package/dist/animation/browser-index.js +13 -0
- package/dist/animation/browser-index.js.map +1 -1
- package/dist/animation/index.d.ts +16 -1
- package/dist/animation/index.d.ts.map +1 -1
- package/dist/animation/index.js +11 -1
- package/dist/animation/index.js.map +1 -1
- package/dist/animation/threejs-compatibility/AnimationDiagnostics.d.ts.map +1 -1
- package/dist/animation/threejs-compatibility/AnimationDiagnostics.js +3 -5
- package/dist/animation/threejs-compatibility/AnimationDiagnostics.js.map +1 -1
- package/dist/assets/GLTFAnimationRuntime.js +1 -1
- package/dist/assets/GLTFLoader.js +1 -1
- package/dist/aura3d-cli/cli.js +194 -8
- package/dist/aura3d-cli/cli.js.map +1 -1
- package/dist/aura3d-cli/index.d.ts +280 -3
- package/dist/aura3d-cli/index.d.ts.map +1 -1
- package/dist/aura3d-cli/index.js +886 -4
- package/dist/aura3d-cli/index.js.map +1 -1
- package/dist/aura3d-cli/pull-bridge.d.ts +95 -0
- package/dist/aura3d-cli/pull-bridge.d.ts.map +1 -0
- package/dist/aura3d-cli/pull-bridge.js +247 -0
- package/dist/aura3d-cli/pull-bridge.js.map +1 -0
- package/dist/create-aura3d/index.d.ts +1 -1
- package/dist/create-aura3d/index.d.ts.map +1 -1
- package/dist/create-aura3d/index.js +9 -2
- package/dist/create-aura3d/index.js.map +1 -1
- package/dist/editor-runtime/ProjectSerializer.d.ts +74 -1
- package/dist/editor-runtime/ProjectSerializer.d.ts.map +1 -1
- package/dist/editor-runtime/ProjectSerializer.js +123 -6
- package/dist/editor-runtime/ProjectSerializer.js.map +1 -1
- package/dist/editor-runtime/TimelineModel.d.ts +18 -0
- package/dist/editor-runtime/TimelineModel.d.ts.map +1 -1
- package/dist/editor-runtime/TimelineModel.js +67 -3
- package/dist/editor-runtime/TimelineModel.js.map +1 -1
- package/dist/editor-runtime/TimelineRuntimeBridge.d.ts +98 -0
- package/dist/editor-runtime/TimelineRuntimeBridge.d.ts.map +1 -0
- package/dist/editor-runtime/TimelineRuntimeBridge.js +186 -0
- package/dist/editor-runtime/TimelineRuntimeBridge.js.map +1 -0
- package/dist/editor-runtime/index.d.ts +3 -1
- package/dist/editor-runtime/index.d.ts.map +1 -1
- package/dist/editor-runtime/index.js +1 -0
- package/dist/editor-runtime/index.js.map +1 -1
- package/dist/engine/agent-api/AnimationController.d.ts +607 -0
- package/dist/engine/agent-api/AnimationController.d.ts.map +1 -0
- package/dist/engine/agent-api/AnimationController.js +2192 -0
- package/dist/engine/agent-api/AnimationController.js.map +1 -0
- package/dist/engine/agent-api/AssetEvidence.d.ts +88 -0
- package/dist/engine/agent-api/AssetEvidence.d.ts.map +1 -0
- package/dist/engine/agent-api/AssetEvidence.js +157 -0
- package/dist/engine/agent-api/AssetEvidence.js.map +1 -0
- package/dist/engine/agent-api/AuraAppHandle.d.ts +55 -0
- package/dist/engine/agent-api/AuraAppHandle.d.ts.map +1 -0
- package/dist/engine/agent-api/AuraAppHandle.js +15 -0
- package/dist/engine/agent-api/AuraAppHandle.js.map +1 -0
- package/dist/engine/agent-api/AuraVoiceBridge.d.ts +96 -0
- package/dist/engine/agent-api/AuraVoiceBridge.d.ts.map +1 -0
- package/dist/engine/agent-api/AuraVoiceBridge.js +370 -0
- package/dist/engine/agent-api/AuraVoiceBridge.js.map +1 -0
- package/dist/engine/agent-api/CartoonDirector.d.ts +95 -0
- package/dist/engine/agent-api/CartoonDirector.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonDirector.js +342 -0
- package/dist/engine/agent-api/CartoonDirector.js.map +1 -0
- package/dist/engine/agent-api/CartoonPerformance.d.ts +149 -0
- package/dist/engine/agent-api/CartoonPerformance.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonPerformance.js +317 -0
- package/dist/engine/agent-api/CartoonPerformance.js.map +1 -0
- package/dist/engine/agent-api/CartoonRenderQueue.d.ts +132 -0
- package/dist/engine/agent-api/CartoonRenderQueue.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonRenderQueue.js +385 -0
- package/dist/engine/agent-api/CartoonRenderQueue.js.map +1 -0
- package/dist/engine/agent-api/CharacterAssembly.d.ts +126 -0
- package/dist/engine/agent-api/CharacterAssembly.d.ts.map +1 -0
- package/dist/engine/agent-api/CharacterAssembly.js +280 -0
- package/dist/engine/agent-api/CharacterAssembly.js.map +1 -0
- package/dist/engine/agent-api/DialoguePerformance.d.ts +150 -0
- package/dist/engine/agent-api/DialoguePerformance.d.ts.map +1 -0
- package/dist/engine/agent-api/DialoguePerformance.js +335 -0
- package/dist/engine/agent-api/DialoguePerformance.js.map +1 -0
- package/dist/engine/agent-api/FrameLoop.d.ts +70 -0
- package/dist/engine/agent-api/FrameLoop.d.ts.map +1 -0
- package/dist/engine/agent-api/FrameLoop.js +165 -0
- package/dist/engine/agent-api/FrameLoop.js.map +1 -0
- package/dist/engine/agent-api/GameAssetValidation.d.ts +279 -0
- package/dist/engine/agent-api/GameAssetValidation.d.ts.map +1 -0
- package/dist/engine/agent-api/GameAssetValidation.js +719 -0
- package/dist/engine/agent-api/GameAssetValidation.js.map +1 -0
- package/dist/engine/agent-api/GameEvidence.d.ts +148 -0
- package/dist/engine/agent-api/GameEvidence.d.ts.map +1 -0
- package/dist/engine/agent-api/GameEvidence.js +269 -0
- package/dist/engine/agent-api/GameEvidence.js.map +1 -0
- package/dist/engine/agent-api/GameRuntime.d.ts +931 -0
- package/dist/engine/agent-api/GameRuntime.d.ts.map +1 -0
- package/dist/engine/agent-api/GameRuntime.js +2229 -0
- package/dist/engine/agent-api/GameRuntime.js.map +1 -0
- package/dist/engine/agent-api/GameSceneBridge.d.ts +54 -0
- package/dist/engine/agent-api/GameSceneBridge.d.ts.map +1 -0
- package/dist/engine/agent-api/GameSceneBridge.js +110 -0
- package/dist/engine/agent-api/GameSceneBridge.js.map +1 -0
- package/dist/engine/agent-api/PromptAnimationContract.d.ts +278 -0
- package/dist/engine/agent-api/PromptAnimationContract.d.ts.map +1 -0
- package/dist/engine/agent-api/PromptAnimationContract.js +238 -0
- package/dist/engine/agent-api/PromptAnimationContract.js.map +1 -0
- package/dist/engine/agent-api/PromptAnimationEvidence.d.ts +183 -0
- package/dist/engine/agent-api/PromptAnimationEvidence.d.ts.map +1 -0
- package/dist/engine/agent-api/PromptAnimationEvidence.js +454 -0
- package/dist/engine/agent-api/PromptAnimationEvidence.js.map +1 -0
- package/dist/engine/agent-api/RuntimeNodeHandle.d.ts +100 -0
- package/dist/engine/agent-api/RuntimeNodeHandle.d.ts.map +1 -0
- package/dist/engine/agent-api/RuntimeNodeHandle.js +36 -0
- package/dist/engine/agent-api/RuntimeNodeHandle.js.map +1 -0
- package/dist/engine/agent-api/ShotTimeline.d.ts +179 -0
- package/dist/engine/agent-api/ShotTimeline.d.ts.map +1 -0
- package/dist/engine/agent-api/ShotTimeline.js +264 -0
- package/dist/engine/agent-api/ShotTimeline.js.map +1 -0
- package/dist/engine/agent-api/VisemeController.d.ts +89 -0
- package/dist/engine/agent-api/VisemeController.d.ts.map +1 -0
- package/dist/engine/agent-api/VisemeController.js +207 -0
- package/dist/engine/agent-api/VisemeController.js.map +1 -0
- package/dist/engine/agent-api/game-kits/fighting.d.ts +123 -0
- package/dist/engine/agent-api/game-kits/fighting.d.ts.map +1 -0
- package/dist/engine/agent-api/game-kits/fighting.js +483 -0
- package/dist/engine/agent-api/game-kits/fighting.js.map +1 -0
- package/dist/engine/agent-api/game-kits/index.d.ts +15 -0
- package/dist/engine/agent-api/game-kits/index.d.ts.map +1 -0
- package/dist/engine/agent-api/game-kits/index.js +6 -0
- package/dist/engine/agent-api/game-kits/index.js.map +1 -0
- package/dist/engine/agent-api/humanoid-walk-runtime.d.ts +1 -0
- package/dist/engine/agent-api/humanoid-walk-runtime.d.ts.map +1 -1
- package/dist/engine/agent-api/index.d.ts +487 -1
- package/dist/engine/agent-api/index.d.ts.map +1 -1
- package/dist/engine/agent-api/index.js +740 -6
- 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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/physics/CollisionVolumes.d.ts +57 -0
- package/dist/physics/CollisionVolumes.d.ts.map +1 -0
- package/dist/physics/CollisionVolumes.js +159 -0
- package/dist/physics/CollisionVolumes.js.map +1 -0
- package/dist/physics/HitboxWorld.d.ts +229 -0
- package/dist/physics/HitboxWorld.d.ts.map +1 -0
- package/dist/physics/HitboxWorld.js +640 -0
- package/dist/physics/HitboxWorld.js.map +1 -0
- package/dist/physics/KinematicBody.d.ts +157 -0
- package/dist/physics/KinematicBody.d.ts.map +1 -0
- package/dist/physics/KinematicBody.js +405 -0
- package/dist/physics/KinematicBody.js.map +1 -0
- package/dist/physics/KinematicWorld.d.ts +58 -0
- package/dist/physics/KinematicWorld.d.ts.map +1 -0
- package/dist/physics/KinematicWorld.js +246 -0
- package/dist/physics/KinematicWorld.js.map +1 -0
- package/dist/physics/index.d.ts +4 -0
- package/dist/physics/index.d.ts.map +1 -1
- package/dist/physics/index.js +4 -0
- package/dist/physics/index.js.map +1 -1
- package/dist/rendering/ForwardPass.js +2 -2
- package/dist/rendering/ShaderLibrary.js +2 -2
- package/dist/rendering/SkinnedLitMaterial.js +3 -3
- package/dist/rendering/SkinnedUnlitMaterial.js +3 -3
- package/dist/scene/Renderable.js +2 -2
- package/dist/scripting/VisualGraph.d.ts +2 -1
- package/dist/scripting/VisualGraph.d.ts.map +1 -1
- package/dist/scripting/VisualGraph.js +118 -1
- package/dist/scripting/VisualGraph.js.map +1 -1
- package/dist/scripting/VisualGraphContext.d.ts +123 -0
- package/dist/scripting/VisualGraphContext.d.ts.map +1 -0
- package/dist/scripting/VisualGraphContext.js +2 -0
- package/dist/scripting/VisualGraphContext.js.map +1 -0
- package/dist/scripting/VisualGraphExecutor.d.ts +6 -1
- package/dist/scripting/VisualGraphExecutor.d.ts.map +1 -1
- package/dist/scripting/VisualGraphExecutor.js +364 -7
- package/dist/scripting/VisualGraphExecutor.js.map +1 -1
- package/dist/scripting/VisualNodeCatalog.d.ts +1 -1
- package/dist/scripting/VisualNodeCatalog.d.ts.map +1 -1
- package/dist/scripting/VisualNodeCatalog.js +61 -1
- package/dist/scripting/VisualNodeCatalog.js.map +1 -1
- package/dist/scripting/index.d.ts +1 -0
- package/dist/scripting/index.d.ts.map +1 -1
- package/dist/scripting/index.js.map +1 -1
- package/package.json +192 -118
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
import { PhysicsDebugDraw, PhysicsStepper, PhysicsWorld, ScenePhysicsBridge, Shape as PhysicsShapeFactory } from "../../physics/index.js";
|
|
2
|
+
import { createFrameLoop } from "./FrameLoop.js";
|
|
3
|
+
import { createCombatWorld, createGameCameraDirector, createGameEffects, applyGameCombatEventsToRuntime, createGameAccessibilityFocus, createGameAccessibilityLabel, createGameAccessibilityRuntimeSettings, createGameHighContrastSource, createGameHudBindings, createGameHudComboBinding, createGameHudDebugToggleBinding, createGameHudHealthBinding, createGameHudMeterBinding, createGameHudRoundBinding, createGameHudSnapshot, createGameHudTimerBinding, createGameBoxCollider, createGameCapsuleCollider, createGameColliderDebugGeometry, createGameCombatDebugGeometry, createGameDebugOverlayData, createGameDebugSceneNodes, createGameHitboxDebugGeometry, createGameFighting2DRules, createGameInput, createGameInputReplay, createGameInputReplayDriver, createGameJumpAssist, createGameKinematicBody, createGamePauseControlsSource, createGameRectCollider, createGameReducedFlashSource, createGameReducedMotionSource, createGameSphereCollider, createGameTouchControlLayout, gameColliderAabb, gameColliders, gameEffectPresets, gameGuardboxes, gameHitboxes, gameHurtboxes, gameInputReplayEventsAt, gamePushboxes, gameTriggerVolumes } from "./GameRuntime.js";
|
|
4
|
+
import { collectGameRuntimeEvidence as collectGameRuntimeEvidenceV105 } from "./GameEvidence.js";
|
|
5
|
+
import { calculateRuntimeNodeBounds } from "./RuntimeNodeHandle.js";
|
|
6
|
+
import { createRuntimeNodeSpec } from "./GameSceneBridge.js";
|
|
7
|
+
import { createFightingGameKit, fighting as fightingGameKit } from "./game-kits/fighting.js";
|
|
8
|
+
import { createPromptAnimationEpisodePlan, createPromptAnimationStoryBible, definePromptAnimationStoryboard } from "./PromptAnimationContract.js";
|
|
9
|
+
import { applyShotPlaybackFrame, createShotPlaybackPlan, createShotTimeline, installShotPlayback, sampleShotPlaybackPlan } from "./ShotTimeline.js";
|
|
10
|
+
import { captionCueAtTime, createCaptionTimingProof, deriveCaptionTrackFromDialogue } from "./DialoguePerformance.js";
|
|
11
|
+
import { createAuraVoiceVisemeTrack, createGlbBlendshapeVisemeCue, createPrimitiveMouthVisemeCues, sampleVisemeTrack } from "./VisemeController.js";
|
|
12
|
+
import { createAuraVoiceBridgePackage, createAuraVoiceDubRerenderProof, createAuraVoiceRerenderPlan, sampleAuraVoiceBridgeAtTime } from "./AuraVoiceBridge.js";
|
|
13
|
+
import { createCartoonDirectorPlan } from "./CartoonDirector.js";
|
|
14
|
+
import { createCartoonPerformance } from "./CartoonPerformance.js";
|
|
15
|
+
import { createCartoonRenderOutputPackageMetadata, createCartoonRenderQueue } from "./CartoonRenderQueue.js";
|
|
16
|
+
import { collectPromptAnimationEvidence } from "./PromptAnimationEvidence.js";
|
|
2
17
|
export { Engine } from "../../core/index.js";
|
|
18
|
+
export { asAuraAppHandle, isAuraAppHandle } from "./AuraAppHandle.js";
|
|
19
|
+
export { FrameLoop, createFrameLoop } from "./FrameLoop.js";
|
|
20
|
+
export { createCombatWorld, createGameCameraDirector, createGameEffects, applyGameCombatEventsToRuntime, createGameAccessibilityFocus, createGameAccessibilityLabel, createGameAccessibilityRuntimeSettings, createGameHighContrastSource, createGameHudBindings, createGameHudComboBinding, createGameHudDebugToggleBinding, createGameHudHealthBinding, createGameHudMeterBinding, createGameHudRoundBinding, createGameHudSnapshot, createGameHudTimerBinding, createGameBoxCollider, createGameCapsuleCollider, createGameColliderDebugGeometry, createGameCombatDebugGeometry, createGameDebugOverlayData, createGameDebugSceneNodes, createGameHitboxDebugGeometry, createGameInput, createGameInputReplay, createGameInputReplayDriver, createGameJumpAssist, createGameKinematicBody, createGamePauseControlsSource, createGameRectCollider, createGameReducedFlashSource, createGameReducedMotionSource, createGameSphereCollider, createGameTouchControlLayout, gameColliderAabb, gameColliders, gameInputReplayEventsAt, createGameLoopPlan } from "./GameRuntime.js";
|
|
21
|
+
export { collectGameSceneRuntimeNodes, createGameSceneBridge, createRuntimeNodeSpec } from "./GameSceneBridge.js";
|
|
22
|
+
export { calculateRuntimeNodeBounds, createRuntimeNodeEffectAttachment, runtimeNodeHasTag } from "./RuntimeNodeHandle.js";
|
|
23
|
+
export { createFightingGameKit, fighting, fighterRuntimeNode } from "./game-kits/fighting.js";
|
|
24
|
+
export { gameKits } from "./game-kits/index.js";
|
|
25
|
+
export * from "./GameAssetValidation.js";
|
|
26
|
+
export * from "./CharacterAssembly.js";
|
|
27
|
+
export * from "./AssetEvidence.js";
|
|
28
|
+
export * from "./AnimationController.js";
|
|
29
|
+
export { gameAssetValidation, quaterniusGameReadyFighterValidationContract, validateQuaterniusGameReadyFighterAsset } from "./GameAssetValidation.js";
|
|
30
|
+
export { createAnimationController } from "./AnimationController.js";
|
|
31
|
+
export * from "./PromptAnimationContract.js";
|
|
32
|
+
export * from "./AuraVoiceBridge.js";
|
|
33
|
+
export * from "./ShotTimeline.js";
|
|
34
|
+
export * from "./DialoguePerformance.js";
|
|
35
|
+
export * from "./VisemeController.js";
|
|
36
|
+
export * from "./PromptAnimationEvidence.js";
|
|
37
|
+
export * from "./CartoonDirector.js";
|
|
38
|
+
export * from "./CartoonPerformance.js";
|
|
39
|
+
export * from "./CartoonRenderQueue.js";
|
|
3
40
|
const auraAssetRefBrand = Symbol("AuraAssetRef");
|
|
4
41
|
export function defineAuraAssets(definitions) {
|
|
5
42
|
const refs = {};
|
|
@@ -45,6 +82,9 @@ export class AuraNodeBuilder {
|
|
|
45
82
|
physics(spec) {
|
|
46
83
|
return this.with({ physics: spec });
|
|
47
84
|
}
|
|
85
|
+
runtime(spec) {
|
|
86
|
+
return this.with({ runtime: { mutable: true, ...spec } });
|
|
87
|
+
}
|
|
48
88
|
toJSON() {
|
|
49
89
|
return this.value;
|
|
50
90
|
}
|
|
@@ -2876,6 +2916,8 @@ export const games = {
|
|
|
2876
2916
|
miniGolfCourse: () => prefabs.miniGolfCourse(),
|
|
2877
2917
|
createMiniGolfState: () => createMiniGolfStateController(),
|
|
2878
2918
|
miniGolfPointerShot: miniGolfPointerShotFromDrag,
|
|
2919
|
+
fighting: fightingGameKit,
|
|
2920
|
+
createFightingGameKit,
|
|
2879
2921
|
miniGolfScene: () => scene()
|
|
2880
2922
|
.background("#12321d")
|
|
2881
2923
|
.addMany(prefabs.miniGolfHole())
|
|
@@ -2883,6 +2925,321 @@ export const games = {
|
|
|
2883
2925
|
.camera(camera.follow({ targetNode: "white physics golf ball", distance: 4.2 }))
|
|
2884
2926
|
.timeline(timeline.loop({ seconds: 8 }))
|
|
2885
2927
|
};
|
|
2928
|
+
export function collectGameRuntimeEvidence(app, options = {}) {
|
|
2929
|
+
return collectGameRuntimeEvidenceV105(app, options);
|
|
2930
|
+
}
|
|
2931
|
+
function createGameInputController(options) {
|
|
2932
|
+
const actions = options.actions;
|
|
2933
|
+
const axes = options.axes ?? {};
|
|
2934
|
+
const bufferMs = options.bufferMs ?? 120;
|
|
2935
|
+
const activeBindings = new Set();
|
|
2936
|
+
const activeActionOverrides = new Set();
|
|
2937
|
+
const previousHeld = new Map();
|
|
2938
|
+
const currentHeld = new Map();
|
|
2939
|
+
const pressedEdges = new Set();
|
|
2940
|
+
const releasedEdges = new Set();
|
|
2941
|
+
const lastPressedAt = new Map();
|
|
2942
|
+
const replayEvents = [];
|
|
2943
|
+
let frame = 0;
|
|
2944
|
+
let time = 0;
|
|
2945
|
+
let latestSnapshot = {
|
|
2946
|
+
kind: "aura-game-input-snapshot",
|
|
2947
|
+
frame,
|
|
2948
|
+
time,
|
|
2949
|
+
activeBindings: [],
|
|
2950
|
+
actions: {}
|
|
2951
|
+
};
|
|
2952
|
+
const resolveHeld = (action) => {
|
|
2953
|
+
if (activeActionOverrides.has(action))
|
|
2954
|
+
return true;
|
|
2955
|
+
const bindings = actions[action] ?? [];
|
|
2956
|
+
return bindings.some((binding) => activeBindings.has(binding));
|
|
2957
|
+
};
|
|
2958
|
+
const record = (type, binding) => {
|
|
2959
|
+
replayEvents.push({ frame, time, type, binding });
|
|
2960
|
+
};
|
|
2961
|
+
const pressBinding = (binding, shouldRecord = true) => {
|
|
2962
|
+
activeBindings.add(binding);
|
|
2963
|
+
if (actions[binding])
|
|
2964
|
+
activeActionOverrides.add(binding);
|
|
2965
|
+
if (shouldRecord)
|
|
2966
|
+
record("press", binding);
|
|
2967
|
+
};
|
|
2968
|
+
const releaseBinding = (binding, shouldRecord = true) => {
|
|
2969
|
+
activeBindings.delete(binding);
|
|
2970
|
+
activeActionOverrides.delete(binding);
|
|
2971
|
+
if (shouldRecord)
|
|
2972
|
+
record("release", binding);
|
|
2973
|
+
};
|
|
2974
|
+
const toSnapshot = () => {
|
|
2975
|
+
const actionStates = {};
|
|
2976
|
+
const nowMs = time * 1000;
|
|
2977
|
+
for (const action of Object.keys(actions)) {
|
|
2978
|
+
const held = currentHeld.get(action) ?? false;
|
|
2979
|
+
actionStates[action] = {
|
|
2980
|
+
pressed: pressedEdges.has(action),
|
|
2981
|
+
held,
|
|
2982
|
+
released: releasedEdges.has(action),
|
|
2983
|
+
buffered: pressedEdges.has(action) || nowMs - (lastPressedAt.get(action) ?? Number.NEGATIVE_INFINITY) <= bufferMs,
|
|
2984
|
+
value: held ? 1 : 0
|
|
2985
|
+
};
|
|
2986
|
+
}
|
|
2987
|
+
return {
|
|
2988
|
+
kind: "aura-game-input-snapshot",
|
|
2989
|
+
frame,
|
|
2990
|
+
time,
|
|
2991
|
+
activeBindings: [...activeBindings].sort(),
|
|
2992
|
+
actions: actionStates
|
|
2993
|
+
};
|
|
2994
|
+
};
|
|
2995
|
+
const update = (dt = 1 / 60) => {
|
|
2996
|
+
frame += 1;
|
|
2997
|
+
time += Math.max(0, dt);
|
|
2998
|
+
pressedEdges.clear();
|
|
2999
|
+
releasedEdges.clear();
|
|
3000
|
+
for (const action of Object.keys(actions)) {
|
|
3001
|
+
const held = resolveHeld(action);
|
|
3002
|
+
const wasHeld = previousHeld.get(action) ?? false;
|
|
3003
|
+
currentHeld.set(action, held);
|
|
3004
|
+
if (held && !wasHeld) {
|
|
3005
|
+
pressedEdges.add(action);
|
|
3006
|
+
lastPressedAt.set(action, time * 1000);
|
|
3007
|
+
}
|
|
3008
|
+
if (!held && wasHeld)
|
|
3009
|
+
releasedEdges.add(action);
|
|
3010
|
+
previousHeld.set(action, held);
|
|
3011
|
+
}
|
|
3012
|
+
latestSnapshot = toSnapshot();
|
|
3013
|
+
return latestSnapshot;
|
|
3014
|
+
};
|
|
3015
|
+
const target = options.target ?? (typeof window !== "undefined" ? window : undefined);
|
|
3016
|
+
const onKeyDown = (event) => {
|
|
3017
|
+
const keyboard = event;
|
|
3018
|
+
if (keyboard.repeat)
|
|
3019
|
+
return;
|
|
3020
|
+
if (keyboard.code)
|
|
3021
|
+
pressBinding(keyboard.code);
|
|
3022
|
+
if (keyboard.key && keyboard.key !== keyboard.code)
|
|
3023
|
+
pressBinding(keyboard.key);
|
|
3024
|
+
};
|
|
3025
|
+
const onKeyUp = (event) => {
|
|
3026
|
+
const keyboard = event;
|
|
3027
|
+
if (keyboard.code)
|
|
3028
|
+
releaseBinding(keyboard.code);
|
|
3029
|
+
if (keyboard.key && keyboard.key !== keyboard.code)
|
|
3030
|
+
releaseBinding(keyboard.key);
|
|
3031
|
+
};
|
|
3032
|
+
if (options.autoListen !== false && target?.addEventListener) {
|
|
3033
|
+
target.addEventListener("keydown", onKeyDown);
|
|
3034
|
+
target.addEventListener("keyup", onKeyUp);
|
|
3035
|
+
}
|
|
3036
|
+
return {
|
|
3037
|
+
kind: "aura-game-input-plan",
|
|
3038
|
+
actions,
|
|
3039
|
+
axes,
|
|
3040
|
+
bufferMs,
|
|
3041
|
+
update,
|
|
3042
|
+
snapshot() {
|
|
3043
|
+
return latestSnapshot;
|
|
3044
|
+
},
|
|
3045
|
+
pressed(action) {
|
|
3046
|
+
return pressedEdges.has(action);
|
|
3047
|
+
},
|
|
3048
|
+
held(action) {
|
|
3049
|
+
return currentHeld.get(action) ?? resolveHeld(action);
|
|
3050
|
+
},
|
|
3051
|
+
released(action) {
|
|
3052
|
+
return releasedEdges.has(action);
|
|
3053
|
+
},
|
|
3054
|
+
buffered(action, windowMs = bufferMs) {
|
|
3055
|
+
return pressedEdges.has(action) || time * 1000 - (lastPressedAt.get(action) ?? Number.NEGATIVE_INFINITY) <= windowMs;
|
|
3056
|
+
},
|
|
3057
|
+
axis(name, negativeAction, positiveAction) {
|
|
3058
|
+
const binding = axes[name];
|
|
3059
|
+
const negative = negativeAction ?? binding?.negative;
|
|
3060
|
+
const positive = positiveAction ?? binding?.positive;
|
|
3061
|
+
if (!negative && !positive)
|
|
3062
|
+
return this.held(name) ? 1 : 0;
|
|
3063
|
+
return (positive && this.held(positive) ? 1 : 0) - (negative && this.held(negative) ? 1 : 0);
|
|
3064
|
+
},
|
|
3065
|
+
press(binding) {
|
|
3066
|
+
pressBinding(binding);
|
|
3067
|
+
},
|
|
3068
|
+
release(binding) {
|
|
3069
|
+
releaseBinding(binding);
|
|
3070
|
+
},
|
|
3071
|
+
setAction(action, held) {
|
|
3072
|
+
if (held) {
|
|
3073
|
+
activeActionOverrides.add(action);
|
|
3074
|
+
record("press", action);
|
|
3075
|
+
}
|
|
3076
|
+
else {
|
|
3077
|
+
activeActionOverrides.delete(action);
|
|
3078
|
+
record("release", action);
|
|
3079
|
+
}
|
|
3080
|
+
},
|
|
3081
|
+
recorded() {
|
|
3082
|
+
return [...replayEvents];
|
|
3083
|
+
},
|
|
3084
|
+
replay(events) {
|
|
3085
|
+
activeBindings.clear();
|
|
3086
|
+
activeActionOverrides.clear();
|
|
3087
|
+
for (const event of events) {
|
|
3088
|
+
if (event.type === "press")
|
|
3089
|
+
pressBinding(event.binding, false);
|
|
3090
|
+
else
|
|
3091
|
+
releaseBinding(event.binding, false);
|
|
3092
|
+
}
|
|
3093
|
+
return update(0);
|
|
3094
|
+
},
|
|
3095
|
+
clearReplay() {
|
|
3096
|
+
replayEvents.length = 0;
|
|
3097
|
+
},
|
|
3098
|
+
dispose() {
|
|
3099
|
+
if (target?.removeEventListener) {
|
|
3100
|
+
target.removeEventListener("keydown", onKeyDown);
|
|
3101
|
+
target.removeEventListener("keyup", onKeyUp);
|
|
3102
|
+
}
|
|
3103
|
+
activeBindings.clear();
|
|
3104
|
+
activeActionOverrides.clear();
|
|
3105
|
+
previousHeld.clear();
|
|
3106
|
+
currentHeld.clear();
|
|
3107
|
+
pressedEdges.clear();
|
|
3108
|
+
releasedEdges.clear();
|
|
3109
|
+
}
|
|
3110
|
+
};
|
|
3111
|
+
}
|
|
3112
|
+
export function createAuraGameRules(options = {}) {
|
|
3113
|
+
return {
|
|
3114
|
+
kind: "aura-game-rules",
|
|
3115
|
+
gravity: options.gravity ?? 24,
|
|
3116
|
+
roundSeconds: options.roundSeconds ?? 90,
|
|
3117
|
+
maxHealth: options.maxHealth ?? 100,
|
|
3118
|
+
maxGuard: options.maxGuard ?? 100,
|
|
3119
|
+
maxMeter: options.maxMeter ?? 100,
|
|
3120
|
+
stageBounds: options.stageBounds ?? {
|
|
3121
|
+
minX: -4.5,
|
|
3122
|
+
maxX: 4.5
|
|
3123
|
+
}
|
|
3124
|
+
};
|
|
3125
|
+
}
|
|
3126
|
+
export const gameRules = Object.assign(createAuraGameRules, {
|
|
3127
|
+
fighting2D: createGameFighting2DRules
|
|
3128
|
+
});
|
|
3129
|
+
export function createAuraGameRuntime(options = {}) {
|
|
3130
|
+
return {
|
|
3131
|
+
kind: "aura-game-runtime",
|
|
3132
|
+
loop: {
|
|
3133
|
+
kind: "aura-game-loop-plan",
|
|
3134
|
+
fixedDt: options.loop?.fixedDt ?? 1 / 60,
|
|
3135
|
+
maxSubSteps: options.loop?.maxSubSteps ?? 5,
|
|
3136
|
+
timeScale: options.loop?.timeScale ?? 1
|
|
3137
|
+
},
|
|
3138
|
+
rules: createAuraGameRules(options.rules),
|
|
3139
|
+
input: options.input ? createGameInput(options.input) : undefined,
|
|
3140
|
+
combat: createCombatWorld(),
|
|
3141
|
+
camera: createGameCameraDirector({
|
|
3142
|
+
stageBounds: {
|
|
3143
|
+
minX: options.rules?.stageBounds?.minX ?? -4.5,
|
|
3144
|
+
maxX: options.rules?.stageBounds?.maxX ?? 4.5
|
|
3145
|
+
}
|
|
3146
|
+
}),
|
|
3147
|
+
effects: createGameEffects({ poolSize: options.effectPoolSize }),
|
|
3148
|
+
bodies: []
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
3151
|
+
export const game = {
|
|
3152
|
+
createRuntime: createAuraGameRuntime,
|
|
3153
|
+
rules: gameRules,
|
|
3154
|
+
loop: (options = {}) => ({
|
|
3155
|
+
kind: "aura-game-loop-plan",
|
|
3156
|
+
fixedDt: options.fixedDt ?? 1 / 60,
|
|
3157
|
+
maxSubSteps: options.maxSubSteps ?? 5,
|
|
3158
|
+
timeScale: options.timeScale ?? 1
|
|
3159
|
+
}),
|
|
3160
|
+
frameLoop: createFrameLoop,
|
|
3161
|
+
runtimeNode: createRuntimeNodeSpec,
|
|
3162
|
+
input: createGameInput,
|
|
3163
|
+
inputReplay: createGameInputReplay,
|
|
3164
|
+
inputReplayDriver: createGameInputReplayDriver,
|
|
3165
|
+
inputReplayEventsAt: gameInputReplayEventsAt,
|
|
3166
|
+
touchControls: createGameTouchControlLayout,
|
|
3167
|
+
kinematicBody: createGameKinematicBody,
|
|
3168
|
+
jumpAssist: createGameJumpAssist,
|
|
3169
|
+
collider: {
|
|
3170
|
+
box: createGameBoxCollider,
|
|
3171
|
+
sphere: createGameSphereCollider,
|
|
3172
|
+
capsule: createGameCapsuleCollider,
|
|
3173
|
+
rect: createGameRectCollider,
|
|
3174
|
+
aabb: gameColliderAabb,
|
|
3175
|
+
factories: gameColliders
|
|
3176
|
+
},
|
|
3177
|
+
hitbox: gameHitboxes,
|
|
3178
|
+
hurtbox: gameHurtboxes,
|
|
3179
|
+
guardbox: gameGuardboxes,
|
|
3180
|
+
pushbox: gamePushboxes,
|
|
3181
|
+
trigger: gameTriggerVolumes,
|
|
3182
|
+
combatWorld: createCombatWorld,
|
|
3183
|
+
combatEvents: applyGameCombatEventsToRuntime,
|
|
3184
|
+
cameraDirector: createGameCameraDirector,
|
|
3185
|
+
effects: createGameEffects,
|
|
3186
|
+
effectPresets: gameEffectPresets,
|
|
3187
|
+
debug: {
|
|
3188
|
+
colliders: createGameColliderDebugGeometry,
|
|
3189
|
+
hitboxes: createGameHitboxDebugGeometry,
|
|
3190
|
+
combat: createGameCombatDebugGeometry,
|
|
3191
|
+
overlay: createGameDebugOverlayData,
|
|
3192
|
+
sceneNodes: createGameDebugSceneNodes
|
|
3193
|
+
},
|
|
3194
|
+
hud: {
|
|
3195
|
+
health: createGameHudHealthBinding,
|
|
3196
|
+
meter: createGameHudMeterBinding,
|
|
3197
|
+
timer: createGameHudTimerBinding,
|
|
3198
|
+
combo: createGameHudComboBinding,
|
|
3199
|
+
round: createGameHudRoundBinding,
|
|
3200
|
+
debugToggle: createGameHudDebugToggleBinding,
|
|
3201
|
+
bindings: createGameHudBindings,
|
|
3202
|
+
snapshot: createGameHudSnapshot
|
|
3203
|
+
},
|
|
3204
|
+
accessibility: {
|
|
3205
|
+
label: createGameAccessibilityLabel,
|
|
3206
|
+
focus: createGameAccessibilityFocus,
|
|
3207
|
+
reducedMotion: createGameReducedMotionSource,
|
|
3208
|
+
reducedFlash: createGameReducedFlashSource,
|
|
3209
|
+
highContrast: createGameHighContrastSource,
|
|
3210
|
+
pauseControls: createGamePauseControlsSource,
|
|
3211
|
+
settings: createGameAccessibilityRuntimeSettings
|
|
3212
|
+
},
|
|
3213
|
+
fighting: createFightingGameKit,
|
|
3214
|
+
evidence: collectGameRuntimeEvidence
|
|
3215
|
+
};
|
|
3216
|
+
export const cartoon = {
|
|
3217
|
+
episodePlan: createPromptAnimationEpisodePlan,
|
|
3218
|
+
storyBible: createPromptAnimationStoryBible,
|
|
3219
|
+
storyboard: definePromptAnimationStoryboard,
|
|
3220
|
+
shotTimeline: createShotTimeline,
|
|
3221
|
+
shotPlaybackPlan: createShotPlaybackPlan,
|
|
3222
|
+
sampleShotPlaybackPlan,
|
|
3223
|
+
applyShotPlaybackFrame,
|
|
3224
|
+
installShotPlayback,
|
|
3225
|
+
captionsFromDialogue: deriveCaptionTrackFromDialogue,
|
|
3226
|
+
captionCueAtTime,
|
|
3227
|
+
captionTimingProof: createCaptionTimingProof,
|
|
3228
|
+
visemeTrack: createAuraVoiceVisemeTrack,
|
|
3229
|
+
primitiveMouthVisemes: createPrimitiveMouthVisemeCues,
|
|
3230
|
+
glbBlendshapeViseme: createGlbBlendshapeVisemeCue,
|
|
3231
|
+
sampleVisemeTrack,
|
|
3232
|
+
auraVoiceBridgePackage: createAuraVoiceBridgePackage,
|
|
3233
|
+
sampleAuraVoiceBridgeAtTime,
|
|
3234
|
+
auraVoiceRerenderPlan: createAuraVoiceRerenderPlan,
|
|
3235
|
+
auraVoiceDubRerenderProof: createAuraVoiceDubRerenderProof,
|
|
3236
|
+
director: createCartoonDirectorPlan,
|
|
3237
|
+
performance: createCartoonPerformance,
|
|
3238
|
+
renderQueue: createCartoonRenderQueue,
|
|
3239
|
+
renderOutputPackage: createCartoonRenderOutputPackageMetadata,
|
|
3240
|
+
evidence: collectPromptAnimationEvidence
|
|
3241
|
+
};
|
|
3242
|
+
export const animationStudio = cartoon;
|
|
2886
3243
|
function collectParticleBudgetDiagnostics(nodes) {
|
|
2887
3244
|
const flattened = groups.flatten(nodes);
|
|
2888
3245
|
const particleEffects = flattened.filter((node) => node.kind === "effect" && node.effect === "particles");
|
|
@@ -3500,6 +3857,7 @@ export const character = {
|
|
|
3500
3857
|
lowPolyHumanoid: (options = {}) => createLowPolyHumanoid(options),
|
|
3501
3858
|
authoredHumanoid: (options = {}) => createAuthoredLowPolyHumanoid(options),
|
|
3502
3859
|
primitiveHumanoid: (options = {}) => createHierarchicalPrimitiveHumanoid(options),
|
|
3860
|
+
performance: createCartoonPerformance,
|
|
3503
3861
|
importedRigRuntime: async (options) => {
|
|
3504
3862
|
markAuraLazySystemRequested("character-rig", "character.importedRigRuntime");
|
|
3505
3863
|
const started = performanceNow();
|
|
@@ -4278,17 +4636,46 @@ export const sceneKits = {
|
|
|
4278
4636
|
humanoidWalk: (options = {}) => makeSceneKit("humanoidWalk", options),
|
|
4279
4637
|
productViewer: (asset, options = {}) => makeSceneKit("productViewer", { ...options, asset })
|
|
4280
4638
|
};
|
|
4639
|
+
export function promptSubjectIsResolved(s) {
|
|
4640
|
+
return "asset" in s;
|
|
4641
|
+
}
|
|
4642
|
+
export async function resolvePromptPlanSubject(plan, resolver) {
|
|
4643
|
+
if (promptSubjectIsResolved(plan.subject)) {
|
|
4644
|
+
return plan;
|
|
4645
|
+
}
|
|
4646
|
+
const intent = plan.subject;
|
|
4647
|
+
const result = await resolver.resolve({ text: intent.intent, constraints: intent.constraints });
|
|
4648
|
+
if (!result) {
|
|
4649
|
+
throw new Error(`No auto-pullable asset matched the prompt-plan intent "${intent.intent}". ` +
|
|
4650
|
+
"Refine the intent or constraints (maxTriangles/license/animated), or provide a concrete typed asset " +
|
|
4651
|
+
"(e.g. a file via `assets add` / a typed asset ref) before compiling.");
|
|
4652
|
+
}
|
|
4653
|
+
const resolvedSubject = {
|
|
4654
|
+
asset: result.asset,
|
|
4655
|
+
...(intent.label !== undefined ? { label: intent.label } : {})
|
|
4656
|
+
};
|
|
4657
|
+
return { ...plan, subject: resolvedSubject };
|
|
4658
|
+
}
|
|
4281
4659
|
export function definePromptPlan(plan) {
|
|
4282
4660
|
return plan;
|
|
4283
4661
|
}
|
|
4662
|
+
function requireResolvedPromptSubject(plan) {
|
|
4663
|
+
if (!promptSubjectIsResolved(plan.subject)) {
|
|
4664
|
+
throw new Error(`Cannot compile a prompt plan whose subject is still an unresolved intent ("${plan.subject.intent}"). ` +
|
|
4665
|
+
"Resolve the prompt-plan subject first via resolvePromptPlanSubject(...) or the CLI `assets search`; " +
|
|
4666
|
+
"compile needs a concrete typed asset.");
|
|
4667
|
+
}
|
|
4668
|
+
return plan.subject;
|
|
4669
|
+
}
|
|
4284
4670
|
export function compilePromptPlan(plan) {
|
|
4285
|
-
const
|
|
4671
|
+
const subject = requireResolvedPromptSubject(plan);
|
|
4672
|
+
const sceneBuilder = promptRecipes[plan.sceneType](subject.asset, plan);
|
|
4286
4673
|
return {
|
|
4287
4674
|
scene: sceneBuilder,
|
|
4288
4675
|
report: {
|
|
4289
4676
|
schema: "aura3d-prompt-plan-report/1.0",
|
|
4290
4677
|
sceneType: plan.sceneType,
|
|
4291
|
-
subjectAssetId:
|
|
4678
|
+
subjectAssetId: subject.asset.id,
|
|
4292
4679
|
recipe: plan.sceneType,
|
|
4293
4680
|
cameraPreset: plan.camera?.preset ?? defaultCameraPreset(plan.sceneType),
|
|
4294
4681
|
lightingPreset: plan.lighting?.preset ?? defaultLightingPreset(plan.sceneType),
|
|
@@ -4485,6 +4872,10 @@ function repairHintsForPromptPlan(plan) {
|
|
|
4485
4872
|
function promptPlanWarnings(plan) {
|
|
4486
4873
|
const warnings = [];
|
|
4487
4874
|
const acceptanceCriteria = plan.acceptanceCriteria.map((item) => item.trim()).filter(Boolean);
|
|
4875
|
+
if (!promptSubjectIsResolved(plan.subject)) {
|
|
4876
|
+
warnings.push(`PromptPlan subject is still an unresolved intent ("${plan.subject.intent}"); resolve it via resolvePromptPlanSubject(...) ` +
|
|
4877
|
+
"or the CLI `assets search` to a concrete typed asset before compiling.");
|
|
4878
|
+
}
|
|
4488
4879
|
if (!plan.subject.label?.trim()) {
|
|
4489
4880
|
warnings.push("PromptPlan subject is missing a human-readable label; add one so reports and diagnostics describe the visible subject.");
|
|
4490
4881
|
}
|
|
@@ -4522,6 +4913,217 @@ export class AuraRuntimeError extends Error {
|
|
|
4522
4913
|
this.code = code;
|
|
4523
4914
|
}
|
|
4524
4915
|
}
|
|
4916
|
+
function createAuraRuntimeNodeRegistry(snapshot) {
|
|
4917
|
+
let handles = new Map();
|
|
4918
|
+
const registry = {
|
|
4919
|
+
get(id) {
|
|
4920
|
+
return handles.get(id);
|
|
4921
|
+
},
|
|
4922
|
+
require(id) {
|
|
4923
|
+
const handle = handles.get(id);
|
|
4924
|
+
if (!handle) {
|
|
4925
|
+
throw new AuraRuntimeError("missing-asset", `Aura3D runtime node "${id}" was not found. Suggested fix: add .runtime({ id: "${id}" }) to the model, primitive, group, or label you want to mutate.`);
|
|
4926
|
+
}
|
|
4927
|
+
return handle;
|
|
4928
|
+
},
|
|
4929
|
+
has(id) {
|
|
4930
|
+
return handles.has(id);
|
|
4931
|
+
},
|
|
4932
|
+
ids() {
|
|
4933
|
+
return [...handles.keys()];
|
|
4934
|
+
},
|
|
4935
|
+
all() {
|
|
4936
|
+
return [...handles.values()];
|
|
4937
|
+
},
|
|
4938
|
+
reset(nextSnapshot) {
|
|
4939
|
+
handles = collectRuntimeNodeHandles(nextSnapshot);
|
|
4940
|
+
}
|
|
4941
|
+
};
|
|
4942
|
+
registry.reset(snapshot);
|
|
4943
|
+
return registry;
|
|
4944
|
+
}
|
|
4945
|
+
function collectRuntimeNodeHandles(snapshot) {
|
|
4946
|
+
const next = new Map();
|
|
4947
|
+
for (const node of snapshot.nodes) {
|
|
4948
|
+
const runtime = "runtime" in node ? node.runtime : undefined;
|
|
4949
|
+
if (!runtime?.id)
|
|
4950
|
+
continue;
|
|
4951
|
+
next.set(runtime.id, createRuntimeNodeHandle(node, runtime));
|
|
4952
|
+
}
|
|
4953
|
+
return next;
|
|
4954
|
+
}
|
|
4955
|
+
function createRuntimeNodeHandle(node, runtime) {
|
|
4956
|
+
const tags = runtime.tags ?? [];
|
|
4957
|
+
const attachedEffects = [];
|
|
4958
|
+
const morphTargetWeights = new Map();
|
|
4959
|
+
let animationBinding;
|
|
4960
|
+
let animationPose;
|
|
4961
|
+
let animationPoseBinding;
|
|
4962
|
+
const getVisible = () => node.kind === "model" ? node.visible !== false : node.visible !== false;
|
|
4963
|
+
const getBounds = () => calculateRuntimeNodeBounds({
|
|
4964
|
+
position: node.position,
|
|
4965
|
+
scale: node.scale,
|
|
4966
|
+
size: "size" in node ? node.size : undefined
|
|
4967
|
+
});
|
|
4968
|
+
return {
|
|
4969
|
+
id: runtime.id,
|
|
4970
|
+
kind: node.kind,
|
|
4971
|
+
name: "name" in node ? node.name : undefined,
|
|
4972
|
+
tags,
|
|
4973
|
+
get position() {
|
|
4974
|
+
return node.position ?? [0, 0, 0];
|
|
4975
|
+
},
|
|
4976
|
+
set position(next) {
|
|
4977
|
+
node.position = next;
|
|
4978
|
+
},
|
|
4979
|
+
get rotation() {
|
|
4980
|
+
return node.rotation ?? [0, 0, 0];
|
|
4981
|
+
},
|
|
4982
|
+
set rotation(next) {
|
|
4983
|
+
node.rotation = next;
|
|
4984
|
+
},
|
|
4985
|
+
get scale() {
|
|
4986
|
+
return node.scale ?? 1;
|
|
4987
|
+
},
|
|
4988
|
+
set scale(next) {
|
|
4989
|
+
node.scale = next;
|
|
4990
|
+
},
|
|
4991
|
+
get visible() {
|
|
4992
|
+
return getVisible();
|
|
4993
|
+
},
|
|
4994
|
+
set visible(next) {
|
|
4995
|
+
node.visible = next;
|
|
4996
|
+
},
|
|
4997
|
+
setPosition(x, y, z) {
|
|
4998
|
+
node.position = [x, y, z];
|
|
4999
|
+
return this;
|
|
5000
|
+
},
|
|
5001
|
+
translate(x, y, z) {
|
|
5002
|
+
const current = node.position ?? [0, 0, 0];
|
|
5003
|
+
node.position = [current[0] + x, current[1] + y, current[2] + z];
|
|
5004
|
+
return this;
|
|
5005
|
+
},
|
|
5006
|
+
setRotation(x, y, z) {
|
|
5007
|
+
node.rotation = [x, y, z];
|
|
5008
|
+
return this;
|
|
5009
|
+
},
|
|
5010
|
+
setScale(scale) {
|
|
5011
|
+
node.scale = scale;
|
|
5012
|
+
return this;
|
|
5013
|
+
},
|
|
5014
|
+
setVisible(visible) {
|
|
5015
|
+
node.visible = visible;
|
|
5016
|
+
return this;
|
|
5017
|
+
},
|
|
5018
|
+
setMaterial(nextMaterial) {
|
|
5019
|
+
node.material = nextMaterial;
|
|
5020
|
+
return this;
|
|
5021
|
+
},
|
|
5022
|
+
play(clip, options = {}) {
|
|
5023
|
+
node.animation = { ...options, clip };
|
|
5024
|
+
return this;
|
|
5025
|
+
},
|
|
5026
|
+
setAnimation(animation) {
|
|
5027
|
+
node.animation = animation;
|
|
5028
|
+
return this;
|
|
5029
|
+
},
|
|
5030
|
+
setAnimationBinding(binding) {
|
|
5031
|
+
animationBinding = binding;
|
|
5032
|
+
return this;
|
|
5033
|
+
},
|
|
5034
|
+
setAnimationPose(pose, metadata) {
|
|
5035
|
+
animationPose = pose ? cloneRuntimeAnimationPose(pose) : undefined;
|
|
5036
|
+
animationPoseBinding = pose ? metadata : undefined;
|
|
5037
|
+
if (pose?.morphTargets) {
|
|
5038
|
+
for (const [name, weight] of Object.entries(pose.morphTargets)) {
|
|
5039
|
+
const normalizedName = name.trim();
|
|
5040
|
+
if (normalizedName) {
|
|
5041
|
+
morphTargetWeights.set(normalizedName, sanitizeRuntimeMorphWeight(weight));
|
|
5042
|
+
}
|
|
5043
|
+
}
|
|
5044
|
+
}
|
|
5045
|
+
return this;
|
|
5046
|
+
},
|
|
5047
|
+
animationPose() {
|
|
5048
|
+
return animationPose ? cloneRuntimeAnimationPose(animationPose) : undefined;
|
|
5049
|
+
},
|
|
5050
|
+
setMorphTarget(name, weight) {
|
|
5051
|
+
const normalizedName = name.trim();
|
|
5052
|
+
if (!normalizedName) {
|
|
5053
|
+
throw new AuraRuntimeError("missing-asset", "Aura3D morph target name is required.");
|
|
5054
|
+
}
|
|
5055
|
+
morphTargetWeights.set(normalizedName, sanitizeRuntimeMorphWeight(weight));
|
|
5056
|
+
return this;
|
|
5057
|
+
},
|
|
5058
|
+
setMorphTargets(weights) {
|
|
5059
|
+
morphTargetWeights.clear();
|
|
5060
|
+
for (const [name, weight] of Object.entries(weights)) {
|
|
5061
|
+
const normalizedName = name.trim();
|
|
5062
|
+
if (normalizedName) {
|
|
5063
|
+
morphTargetWeights.set(normalizedName, sanitizeRuntimeMorphWeight(weight));
|
|
5064
|
+
}
|
|
5065
|
+
}
|
|
5066
|
+
return this;
|
|
5067
|
+
},
|
|
5068
|
+
morphTargets() {
|
|
5069
|
+
return Object.fromEntries(morphTargetWeights.entries());
|
|
5070
|
+
},
|
|
5071
|
+
bounds() {
|
|
5072
|
+
return getBounds();
|
|
5073
|
+
},
|
|
5074
|
+
attachEffect(effect) {
|
|
5075
|
+
attachedEffects.push(effect);
|
|
5076
|
+
return this;
|
|
5077
|
+
},
|
|
5078
|
+
effects() {
|
|
5079
|
+
return [...attachedEffects];
|
|
5080
|
+
},
|
|
5081
|
+
snapshot() {
|
|
5082
|
+
return {
|
|
5083
|
+
id: runtime.id,
|
|
5084
|
+
kind: node.kind,
|
|
5085
|
+
name: "name" in node ? node.name : undefined,
|
|
5086
|
+
tags,
|
|
5087
|
+
position: node.position ?? [0, 0, 0],
|
|
5088
|
+
rotation: node.rotation ?? [0, 0, 0],
|
|
5089
|
+
scale: node.scale ?? 1,
|
|
5090
|
+
visible: getVisible(),
|
|
5091
|
+
animation: node.animation,
|
|
5092
|
+
animationBinding,
|
|
5093
|
+
animationPose: animationPose ? cloneRuntimeAnimationPose(animationPose) : undefined,
|
|
5094
|
+
animationPoseBinding,
|
|
5095
|
+
morphTargets: Object.fromEntries(morphTargetWeights.entries()),
|
|
5096
|
+
bounds: getBounds(),
|
|
5097
|
+
effects: [...attachedEffects]
|
|
5098
|
+
};
|
|
5099
|
+
}
|
|
5100
|
+
};
|
|
5101
|
+
}
|
|
5102
|
+
function cloneRuntimeAnimationPose(pose) {
|
|
5103
|
+
return {
|
|
5104
|
+
bones: Object.fromEntries(Object.entries(pose.bones ?? {}).map(([bone, transform]) => [
|
|
5105
|
+
bone,
|
|
5106
|
+
{
|
|
5107
|
+
position: transform.position ? { ...transform.position } : undefined,
|
|
5108
|
+
rotation: transform.rotation ? { ...transform.rotation } : undefined,
|
|
5109
|
+
scale: transform.scale ? { ...transform.scale } : undefined
|
|
5110
|
+
}
|
|
5111
|
+
])),
|
|
5112
|
+
morphTargets: pose.morphTargets ? { ...pose.morphTargets } : undefined,
|
|
5113
|
+
rootMotion: pose.rootMotion
|
|
5114
|
+
? {
|
|
5115
|
+
translation: pose.rootMotion.translation ? { ...pose.rootMotion.translation } : undefined,
|
|
5116
|
+
rotation: pose.rootMotion.rotation ? { ...pose.rootMotion.rotation } : undefined
|
|
5117
|
+
}
|
|
5118
|
+
: undefined,
|
|
5119
|
+
metadata: pose.metadata ? { ...pose.metadata } : undefined
|
|
5120
|
+
};
|
|
5121
|
+
}
|
|
5122
|
+
function sanitizeRuntimeMorphWeight(weight) {
|
|
5123
|
+
if (!Number.isFinite(weight))
|
|
5124
|
+
return 0;
|
|
5125
|
+
return Math.max(0, Math.min(1, weight));
|
|
5126
|
+
}
|
|
4525
5127
|
export function createAuraApp(target, options) {
|
|
4526
5128
|
let snapshot = normalizeSceneSnapshot(options.scene);
|
|
4527
5129
|
let renderSnapshot = flattenSceneSnapshot(snapshot);
|
|
@@ -4537,6 +5139,32 @@ export function createAuraApp(target, options) {
|
|
|
4537
5139
|
let lastTime = 0;
|
|
4538
5140
|
let mountRevision = 0;
|
|
4539
5141
|
let canvasRuntimePhysics;
|
|
5142
|
+
const runtimeNodes = createAuraRuntimeNodeRegistry(renderSnapshot);
|
|
5143
|
+
const frameCallbacks = new Set();
|
|
5144
|
+
let runtimePaused = options.autoStart === false;
|
|
5145
|
+
let runtimeFrame = 0;
|
|
5146
|
+
let runtimeTime = 0;
|
|
5147
|
+
const runtimeFixedDt = 1 / 60;
|
|
5148
|
+
let runtimeAlpha = 0;
|
|
5149
|
+
const ownedInputControllers = new Set();
|
|
5150
|
+
const runRuntimeFrame = (dt, source) => {
|
|
5151
|
+
runtimeFrame += 1;
|
|
5152
|
+
runtimeTime += dt;
|
|
5153
|
+
runtimeAlpha = runtimeFixedDt > 0 ? Math.max(0, Math.min(1, (dt % runtimeFixedDt) / runtimeFixedDt)) : 0;
|
|
5154
|
+
const frame = {
|
|
5155
|
+
dt,
|
|
5156
|
+
fixedDt: runtimeFixedDt,
|
|
5157
|
+
time: runtimeTime,
|
|
5158
|
+
frame: runtimeFrame,
|
|
5159
|
+
alpha: runtimeAlpha,
|
|
5160
|
+
paused: runtimePaused,
|
|
5161
|
+
source,
|
|
5162
|
+
substep: 1,
|
|
5163
|
+
substeps: 1
|
|
5164
|
+
};
|
|
5165
|
+
for (const callback of [...frameCallbacks])
|
|
5166
|
+
callback(frame);
|
|
5167
|
+
};
|
|
4540
5168
|
const shouldUseProductionRendererForCurrentScene = () => Boolean(canvas && renderSnapshot.nodes.some(isWebGLRenderableNode) && typeof window !== "undefined");
|
|
4541
5169
|
const resetDiagnosticsForCurrentScene = (backend) => {
|
|
4542
5170
|
const fresh = createInitialDiagnostics(renderSnapshot);
|
|
@@ -4557,7 +5185,11 @@ export function createAuraApp(target, options) {
|
|
|
4557
5185
|
return;
|
|
4558
5186
|
const delta = lastTime > 0 ? Math.max(1, time - lastTime) : 16.67;
|
|
4559
5187
|
lastTime = time;
|
|
4560
|
-
|
|
5188
|
+
const dt = delta / 1000;
|
|
5189
|
+
if (!runtimePaused) {
|
|
5190
|
+
runRuntimeFrame(dt, "raf");
|
|
5191
|
+
canvasRuntimePhysics?.step(dt);
|
|
5192
|
+
}
|
|
4561
5193
|
diagnosticsState.evidence = collectAuraSceneEvidence(renderSnapshot);
|
|
4562
5194
|
diagnosticsState.fps = Math.round(1000 / delta);
|
|
4563
5195
|
diagnosticsState.drawCalls = renderSceneToCanvas(canvas, renderSnapshot, time);
|
|
@@ -4584,7 +5216,7 @@ export function createAuraApp(target, options) {
|
|
|
4584
5216
|
overlay?.update();
|
|
4585
5217
|
const revision = ++mountRevision;
|
|
4586
5218
|
if (shouldUseProductionRenderer && canvas) {
|
|
4587
|
-
void startProductionRender(canvas, renderSnapshot, diagnosticsState, options, overlay)
|
|
5219
|
+
void startProductionRender(canvas, renderSnapshot, diagnosticsState, options, overlay, runRuntimeFrame, () => runtimePaused)
|
|
4588
5220
|
.then((controller) => {
|
|
4589
5221
|
if (disposed || revision !== mountRevision) {
|
|
4590
5222
|
controller.dispose();
|
|
@@ -4618,11 +5250,71 @@ export function createAuraApp(target, options) {
|
|
|
4618
5250
|
setScene(nextScene) {
|
|
4619
5251
|
snapshot = normalizeSceneSnapshot(nextScene);
|
|
4620
5252
|
renderSnapshot = flattenSceneSnapshot(snapshot);
|
|
5253
|
+
runtimeNodes.reset(renderSnapshot);
|
|
4621
5254
|
mountCurrentScene();
|
|
4622
5255
|
},
|
|
5256
|
+
nodes: runtimeNodes,
|
|
5257
|
+
get runtime() {
|
|
5258
|
+
return {
|
|
5259
|
+
paused: runtimePaused,
|
|
5260
|
+
frame: runtimeFrame,
|
|
5261
|
+
time: runtimeTime,
|
|
5262
|
+
fixedDt: runtimeFixedDt,
|
|
5263
|
+
alpha: runtimeAlpha
|
|
5264
|
+
};
|
|
5265
|
+
},
|
|
5266
|
+
onFrame(callback) {
|
|
5267
|
+
frameCallbacks.add(callback);
|
|
5268
|
+
return () => {
|
|
5269
|
+
frameCallbacks.delete(callback);
|
|
5270
|
+
};
|
|
5271
|
+
},
|
|
5272
|
+
offFrame(callback) {
|
|
5273
|
+
frameCallbacks.delete(callback);
|
|
5274
|
+
},
|
|
5275
|
+
input(inputOptions) {
|
|
5276
|
+
const controller = createGameInput(inputOptions);
|
|
5277
|
+
ownedInputControllers.add(controller);
|
|
5278
|
+
return controller;
|
|
5279
|
+
},
|
|
5280
|
+
pause() {
|
|
5281
|
+
runtimePaused = true;
|
|
5282
|
+
},
|
|
5283
|
+
resume() {
|
|
5284
|
+
runtimePaused = false;
|
|
5285
|
+
if (!animationHandle && !productionController && options.autoStart !== false && typeof requestAnimationFrame !== "undefined") {
|
|
5286
|
+
animationHandle = requestAnimationFrame(render);
|
|
5287
|
+
}
|
|
5288
|
+
},
|
|
5289
|
+
step(dt = 1 / 60) {
|
|
5290
|
+
const seconds = Math.max(0, dt);
|
|
5291
|
+
runRuntimeFrame(seconds, "manual");
|
|
5292
|
+
canvasRuntimePhysics?.step(seconds);
|
|
5293
|
+
const previousPaused = runtimePaused;
|
|
5294
|
+
runtimePaused = true;
|
|
5295
|
+
if (productionController) {
|
|
5296
|
+
productionController.render(performanceNow());
|
|
5297
|
+
}
|
|
5298
|
+
else {
|
|
5299
|
+
render(performanceNow());
|
|
5300
|
+
}
|
|
5301
|
+
runtimePaused = previousPaused;
|
|
5302
|
+
},
|
|
4623
5303
|
diagnostics() {
|
|
4624
5304
|
return snapshotDiagnostics(diagnosticsState);
|
|
4625
5305
|
},
|
|
5306
|
+
evidence(evidenceOptions = {}) {
|
|
5307
|
+
return collectGameRuntimeEvidenceV105({
|
|
5308
|
+
runtime: {
|
|
5309
|
+
paused: runtimePaused,
|
|
5310
|
+
frame: runtimeFrame,
|
|
5311
|
+
time: runtimeTime,
|
|
5312
|
+
fixedDt: runtimeFixedDt,
|
|
5313
|
+
alpha: runtimeAlpha
|
|
5314
|
+
},
|
|
5315
|
+
nodes: runtimeNodes
|
|
5316
|
+
}, evidenceOptions);
|
|
5317
|
+
},
|
|
4626
5318
|
screenshot() {
|
|
4627
5319
|
return captureAuraScreenshot(canvas);
|
|
4628
5320
|
},
|
|
@@ -4630,6 +5322,9 @@ export function createAuraApp(target, options) {
|
|
|
4630
5322
|
disposed = true;
|
|
4631
5323
|
if (animationHandle && typeof cancelAnimationFrame !== "undefined")
|
|
4632
5324
|
cancelAnimationFrame(animationHandle);
|
|
5325
|
+
for (const controller of ownedInputControllers)
|
|
5326
|
+
controller.dispose();
|
|
5327
|
+
ownedInputControllers.clear();
|
|
4633
5328
|
productionController?.dispose();
|
|
4634
5329
|
overlay?.dispose();
|
|
4635
5330
|
}
|
|
@@ -4653,6 +5348,10 @@ export function collectAuraSceneEvidence(sceneValue) {
|
|
|
4653
5348
|
const assetProvenance = snapshot.nodes
|
|
4654
5349
|
.filter((node) => node.kind === "model")
|
|
4655
5350
|
.map((node) => createAssetProvenance(node.asset));
|
|
5351
|
+
const runtimeNodeIds = snapshot.nodes
|
|
5352
|
+
.map((node) => "runtime" in node ? node.runtime?.id : undefined)
|
|
5353
|
+
.filter((id) => Boolean(id));
|
|
5354
|
+
const expectsGameRuntime = runtimeNodeIds.length > 0 || interactionNodes.some((node) => node.mode === "keyboard" || node.mode === "drag-vector" || node.mode === "click-impulse");
|
|
4656
5355
|
return {
|
|
4657
5356
|
physics: {
|
|
4658
5357
|
worldAttached: Boolean(snapshot.physics),
|
|
@@ -4690,6 +5389,31 @@ export function collectAuraSceneEvidence(sceneValue) {
|
|
|
4690
5389
|
collisionAvoidance: labelNodes.filter((node) => node.collisionAvoidance === true).length
|
|
4691
5390
|
},
|
|
4692
5391
|
performance: createPerformanceEvidence(snapshot),
|
|
5392
|
+
gameRuntime: collectGameRuntimeEvidenceV105({
|
|
5393
|
+
runtime: {
|
|
5394
|
+
frame: 0,
|
|
5395
|
+
time: 0,
|
|
5396
|
+
paused: true
|
|
5397
|
+
},
|
|
5398
|
+
nodes: {
|
|
5399
|
+
ids: () => runtimeNodeIds
|
|
5400
|
+
}
|
|
5401
|
+
}, {
|
|
5402
|
+
animation: {
|
|
5403
|
+
controllers: animatedNodes.length,
|
|
5404
|
+
activeClips: clips,
|
|
5405
|
+
eventCount: 0
|
|
5406
|
+
},
|
|
5407
|
+
assets: {
|
|
5408
|
+
typedAssets: assetProvenance.filter((asset) => asset.source === "typed-aura-assets-manifest").length,
|
|
5409
|
+
missingAssets: []
|
|
5410
|
+
},
|
|
5411
|
+
source: {
|
|
5412
|
+
mode: "scene-source",
|
|
5413
|
+
expectsGame: expectsGameRuntime,
|
|
5414
|
+
label: "collectAuraSceneEvidence"
|
|
5415
|
+
}
|
|
5416
|
+
}),
|
|
4693
5417
|
rendering: createRendererDiagnosticReport(snapshot),
|
|
4694
5418
|
assets: assetProvenance
|
|
4695
5419
|
};
|
|
@@ -4810,7 +5534,7 @@ function isRenderableModelNode(node) {
|
|
|
4810
5534
|
function isWebGLRenderableNode(node) {
|
|
4811
5535
|
return isRenderableModelNode(node) || node.kind === "primitive";
|
|
4812
5536
|
}
|
|
4813
|
-
async function startProductionRender(canvas, snapshot, diagnosticsState, options, overlay) {
|
|
5537
|
+
async function startProductionRender(canvas, snapshot, diagnosticsState, options, overlay, beforeRender, isPaused = () => false) {
|
|
4814
5538
|
const renderableNode = snapshot.nodes.find(isWebGLRenderableNode);
|
|
4815
5539
|
if (!renderableNode) {
|
|
4816
5540
|
throw new AuraRuntimeError("missing-asset", "Aura3D production rendering requires at least one typed model asset or primitive. Suggested fix: add model(assets.product), primitives.box(), primitives.sphere(), primitives.cylinder(), or primitives.plane().");
|
|
@@ -4820,9 +5544,14 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
|
|
|
4820
5544
|
const continuousRender = shouldContinuouslyRender(snapshot);
|
|
4821
5545
|
let disposed = false;
|
|
4822
5546
|
let animationHandle = 0;
|
|
5547
|
+
let lastTime = 0;
|
|
4823
5548
|
const renderFrame = (time = performanceNow()) => {
|
|
4824
5549
|
if (disposed)
|
|
4825
5550
|
return;
|
|
5551
|
+
const delta = lastTime > 0 ? Math.max(1, time - lastTime) : 16.67;
|
|
5552
|
+
lastTime = time;
|
|
5553
|
+
if (!isPaused())
|
|
5554
|
+
beforeRender?.(delta / 1000, "raf");
|
|
4826
5555
|
const drawCalls = renderer.render(time);
|
|
4827
5556
|
diagnosticsState.backend = "webgl2";
|
|
4828
5557
|
diagnosticsState.fps = diagnosticsState.fps || 60;
|
|
@@ -4837,6 +5566,9 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
|
|
|
4837
5566
|
};
|
|
4838
5567
|
renderFrame();
|
|
4839
5568
|
return {
|
|
5569
|
+
render(time = performanceNow()) {
|
|
5570
|
+
renderFrame(time);
|
|
5571
|
+
},
|
|
4840
5572
|
dispose() {
|
|
4841
5573
|
disposed = true;
|
|
4842
5574
|
if (animationHandle && typeof cancelAnimationFrame !== "undefined")
|
|
@@ -4851,6 +5583,8 @@ function shouldContinuouslyRender(snapshot) {
|
|
|
4851
5583
|
if (snapshot.camera.mode === "dolly" || snapshot.camera.mode === "follow" || snapshot.camera.mode === "path" || snapshot.camera.mode === "flythrough")
|
|
4852
5584
|
return true;
|
|
4853
5585
|
return snapshot.nodes.some((node) => {
|
|
5586
|
+
if ("runtime" in node && node.runtime?.mutable !== false)
|
|
5587
|
+
return true;
|
|
4854
5588
|
if ((node.kind === "model" || node.kind === "primitive") && node.animation)
|
|
4855
5589
|
return true;
|
|
4856
5590
|
if (node.kind !== "effect")
|
|
@@ -6179,7 +6913,7 @@ function normalizeSceneSnapshot(value) {
|
|
|
6179
6913
|
}
|
|
6180
6914
|
function resolveCanvas(target) {
|
|
6181
6915
|
if (!target) {
|
|
6182
|
-
|
|
6916
|
+
return undefined;
|
|
6183
6917
|
}
|
|
6184
6918
|
if (typeof target === "string") {
|
|
6185
6919
|
if (typeof document === "undefined") {
|