create-aura3d 1.3.2 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +10 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/showcase-spec-artifacts.d.ts +104 -0
- package/dist/showcase-spec-artifacts.d.ts.map +1 -0
- package/dist/showcase-spec-artifacts.js +142 -0
- package/dist/showcase-spec-artifacts.js.map +1 -0
- package/dist/showcase-spec-category-plan.d.ts +15 -0
- package/dist/showcase-spec-category-plan.d.ts.map +1 -0
- package/dist/showcase-spec-category-plan.js +45 -0
- package/dist/showcase-spec-category-plan.js.map +1 -0
- package/dist/showcase-spec-compiler.d.ts +5 -0
- package/dist/showcase-spec-compiler.d.ts.map +1 -0
- package/dist/showcase-spec-compiler.js +240 -0
- package/dist/showcase-spec-compiler.js.map +1 -0
- package/dist/showcase-spec-evidence.d.ts +7 -0
- package/dist/showcase-spec-evidence.d.ts.map +1 -0
- package/dist/showcase-spec-evidence.js +815 -0
- package/dist/showcase-spec-evidence.js.map +1 -0
- package/dist/showcase-spec-game-geometry-extractor.d.ts +21 -0
- package/dist/showcase-spec-game-geometry-extractor.d.ts.map +1 -0
- package/dist/showcase-spec-game-geometry-extractor.js +725 -0
- package/dist/showcase-spec-game-geometry-extractor.js.map +1 -0
- package/dist/showcase-spec-game-replacement-evidence.d.ts +14 -0
- package/dist/showcase-spec-game-replacement-evidence.d.ts.map +1 -0
- package/dist/showcase-spec-game-replacement-evidence.js +219 -0
- package/dist/showcase-spec-game-replacement-evidence.js.map +1 -0
- package/dist/showcase-spec-game-template-evidence.d.ts +72 -0
- package/dist/showcase-spec-game-template-evidence.d.ts.map +1 -0
- package/dist/showcase-spec-game-template-evidence.js +435 -0
- package/dist/showcase-spec-game-template-evidence.js.map +1 -0
- package/dist/showcase-spec-gameplay-evidence.d.ts +3 -0
- package/dist/showcase-spec-gameplay-evidence.d.ts.map +1 -0
- package/dist/showcase-spec-gameplay-evidence.js +108 -0
- package/dist/showcase-spec-gameplay-evidence.js.map +1 -0
- package/dist/showcase-spec-parser.d.ts +3 -0
- package/dist/showcase-spec-parser.d.ts.map +1 -0
- package/dist/showcase-spec-parser.js +662 -0
- package/dist/showcase-spec-parser.js.map +1 -0
- package/dist/showcase-spec-platformer-artifacts.d.ts +3 -0
- package/dist/showcase-spec-platformer-artifacts.d.ts.map +1 -0
- package/dist/showcase-spec-platformer-artifacts.js +276 -0
- package/dist/showcase-spec-platformer-artifacts.js.map +1 -0
- package/dist/showcase-spec-racing-artifacts.d.ts +3 -0
- package/dist/showcase-spec-racing-artifacts.d.ts.map +1 -0
- package/dist/showcase-spec-racing-artifacts.js +273 -0
- package/dist/showcase-spec-racing-artifacts.js.map +1 -0
- package/dist/showcase-spec-replacement-apply.d.ts +10 -0
- package/dist/showcase-spec-replacement-apply.d.ts.map +1 -0
- package/dist/showcase-spec-replacement-apply.js +166 -0
- package/dist/showcase-spec-replacement-apply.js.map +1 -0
- package/dist/showcase-spec-replacement-candidates.d.ts +16 -0
- package/dist/showcase-spec-replacement-candidates.d.ts.map +1 -0
- package/dist/showcase-spec-replacement-candidates.js +244 -0
- package/dist/showcase-spec-replacement-candidates.js.map +1 -0
- package/dist/showcase-spec-replacement-game-geometry.d.ts +4 -0
- package/dist/showcase-spec-replacement-game-geometry.d.ts.map +1 -0
- package/dist/showcase-spec-replacement-game-geometry.js +175 -0
- package/dist/showcase-spec-replacement-game-geometry.js.map +1 -0
- package/dist/showcase-spec-replacement-manifest.d.ts +41 -0
- package/dist/showcase-spec-replacement-manifest.d.ts.map +1 -0
- package/dist/showcase-spec-replacement-manifest.js +62 -0
- package/dist/showcase-spec-replacement-manifest.js.map +1 -0
- package/dist/showcase-spec-replacement-values.d.ts +9 -0
- package/dist/showcase-spec-replacement-values.d.ts.map +1 -0
- package/dist/showcase-spec-replacement-values.js +41 -0
- package/dist/showcase-spec-replacement-values.js.map +1 -0
- package/dist/showcase-spec-replacement.d.ts +13 -0
- package/dist/showcase-spec-replacement.d.ts.map +1 -0
- package/dist/showcase-spec-replacement.js +144 -0
- package/dist/showcase-spec-replacement.js.map +1 -0
- package/dist/showcase-spec-types.d.ts +304 -0
- package/dist/showcase-spec-types.d.ts.map +1 -0
- package/dist/showcase-spec-types.js +2 -0
- package/dist/showcase-spec-types.js.map +1 -0
- package/package.json +21 -2
- package/templates/animation-channel/package.json +1 -1
- package/templates/animation-channel/tests/screenshot.spec.ts +16 -0
- package/templates/animation-studio/index.html +12 -0
- package/templates/animation-studio/node_modules.publish-aside/.vite/deps/_metadata.json +8 -0
- package/templates/animation-studio/node_modules.publish-aside/.vite/deps/package.json +3 -0
- package/templates/animation-studio/package.json +1 -1
- package/templates/animation-studio/scripts/animation-scene.ts +1 -1
- package/templates/animation-studio/scripts/asset-motion-probe.ts +7 -1
- package/templates/animation-studio/scripts/author-office-scene.ts +1 -1
- package/templates/animation-studio/scripts/build-characters.ts +1 -1
- package/templates/animation-studio/scripts/render-live.ts +24 -0
- package/templates/animation-studio/src/director/director-heuristics.ts +2 -2
- package/templates/animation-studio/src/director/{prompt-to-scene.ts → prompt-scene.ts} +74 -6
- package/templates/animation-studio/studio/src/App.tsx +146 -78
- package/templates/animation-studio/studio/src/components/Console.tsx +8 -2
- package/templates/animation-studio/studio/src/components/Inspector.tsx +57 -1
- package/templates/animation-studio/studio/src/components/Stage.tsx +10 -5
- package/templates/animation-studio/studio/src/components/Timeline.tsx +49 -2
- package/templates/animation-studio/studio/src/state/mapDocument.ts +13 -2
- package/templates/animation-studio/studio/src/state/sceneTool.ts +20 -9
- package/templates/animation-studio/studio/src/state/types.ts +8 -0
- package/templates/animation-studio/tests/route-health.spec.ts +33 -0
- package/templates/animation-studio/tests/screenshot.spec.ts +30 -0
- package/templates/character-controller/package.json +1 -1
- package/templates/character-controller/src/main.ts +18 -1
- package/templates/cinematic-scene/package.json +1 -1
- package/templates/cinematic-scene/tests/screenshot.spec.ts +3 -3
- package/templates/episode-builder/package.json +1 -1
- package/templates/episode-builder/tests/screenshot.spec.ts +15 -0
- package/templates/falling-blocks-starter/README.md +18 -0
- package/templates/falling-blocks-starter/index.html +23 -0
- package/templates/falling-blocks-starter/package.json +21 -0
- package/templates/falling-blocks-starter/playwright.config.ts +12 -0
- package/templates/falling-blocks-starter/public/aura-assets/showcaseBlockfallCabinet.679d52fe.glb +0 -0
- package/templates/falling-blocks-starter/public/aura-assets/showcaseBlockfallCabinet.thumb.svg +1 -0
- package/templates/falling-blocks-starter/src/aura-assets.ts +20 -0
- package/templates/falling-blocks-starter/src/main.ts +358 -0
- package/templates/falling-blocks-starter/tests/playable.spec.ts +85 -0
- package/templates/falling-blocks-starter/tests/route-health.spec.ts +34 -0
- package/templates/falling-blocks-starter/tsconfig.json +13 -0
- package/templates/fighting-game/package.json +1 -1
- package/templates/fighting-game/tests/screenshot.spec.ts +15 -0
- package/templates/mini-game/README.md +13 -0
- package/templates/mini-game/index.html +1 -1
- package/templates/mini-game/package.json +2 -2
- package/templates/mini-game/src/main.ts +251 -21
- package/templates/mini-game/tests/playable.spec.ts +49 -0
- package/templates/mini-game/tests/screenshot.spec.ts +37 -32
- package/templates/product-viewer/package.json +1 -1
- package/templates/product-viewer/tests/screenshot.spec.ts +4 -4
- package/templates/prompt-animation-channel/package.json +1 -1
- package/templates/prompt-animation-channel/tests/screenshot.spec.ts +15 -0
- package/templates/racing-starter/README.md +27 -0
- package/templates/racing-starter/index.html +23 -0
- package/templates/racing-starter/package.json +21 -0
- package/templates/racing-starter/playwright.config.ts +12 -0
- package/templates/racing-starter/public/aura-assets/showcaseCleanSportsCar.1c69283f.glb +0 -0
- package/templates/racing-starter/public/aura-assets/showcaseCleanSportsCar.thumb.svg +1 -0
- package/templates/racing-starter/public/aura-assets/showcaseReadableKartCircuit.5cbb912e.glb +0 -0
- package/templates/racing-starter/public/aura-assets/showcaseReadableKartCircuit.thumb.svg +1 -0
- package/templates/racing-starter/src/aura-assets.ts +36 -0
- package/templates/racing-starter/src/main.ts +280 -0
- package/templates/racing-starter/tests/playable.spec.ts +93 -0
- package/templates/racing-starter/tests/route-health.spec.ts +40 -0
- package/templates/racing-starter/tsconfig.json +13 -0
- package/templates/three-compat-architecture-interior/index.html +16 -0
- package/templates/three-compat-architecture-interior/package.json +21 -0
- package/templates/three-compat-architecture-interior/playwright.config.ts +14 -0
- package/templates/three-compat-architecture-interior/src/main.ts +27 -0
- package/templates/three-compat-architecture-interior/tests/route-health.spec.ts +16 -0
- package/templates/three-compat-architecture-interior/tests/screenshot.spec.ts +15 -0
- package/templates/three-compat-architecture-interior/tsconfig.json +19 -0
- package/templates/three-compat-asset-inspector/index.html +16 -0
- package/templates/three-compat-asset-inspector/package.json +21 -0
- package/templates/three-compat-asset-inspector/playwright.config.ts +14 -0
- package/templates/three-compat-asset-inspector/src/main.ts +17 -0
- package/templates/three-compat-asset-inspector/tests/route-health.spec.ts +16 -0
- package/templates/three-compat-asset-inspector/tests/screenshot.spec.ts +15 -0
- package/templates/three-compat-asset-inspector/tsconfig.json +19 -0
- package/templates/three-compat-character-viewer/index.html +16 -0
- package/templates/three-compat-character-viewer/package.json +21 -0
- package/templates/three-compat-character-viewer/playwright.config.ts +14 -0
- package/templates/three-compat-character-viewer/src/main.ts +17 -0
- package/templates/three-compat-character-viewer/tests/route-health.spec.ts +16 -0
- package/templates/three-compat-character-viewer/tests/screenshot.spec.ts +15 -0
- package/templates/three-compat-character-viewer/tsconfig.json +19 -0
- package/templates/three-compat-custom-threejs-migration/index.html +16 -0
- package/templates/three-compat-custom-threejs-migration/package.json +21 -0
- package/templates/three-compat-custom-threejs-migration/playwright.config.ts +14 -0
- package/templates/three-compat-custom-threejs-migration/src/main.ts +16 -0
- package/templates/three-compat-custom-threejs-migration/tests/route-health.spec.ts +16 -0
- package/templates/three-compat-custom-threejs-migration/tests/screenshot.spec.ts +15 -0
- package/templates/three-compat-custom-threejs-migration/tsconfig.json +19 -0
- package/templates/three-compat-large-scene/index.html +16 -0
- package/templates/three-compat-large-scene/package.json +21 -0
- package/templates/three-compat-large-scene/playwright.config.ts +14 -0
- package/templates/three-compat-large-scene/src/main.ts +31 -0
- package/templates/three-compat-large-scene/tests/route-health.spec.ts +16 -0
- package/templates/three-compat-large-scene/tests/screenshot.spec.ts +15 -0
- package/templates/three-compat-large-scene/tsconfig.json +19 -0
- package/templates/three-compat-material-authoring/index.html +16 -0
- package/templates/three-compat-material-authoring/package.json +21 -0
- package/templates/three-compat-material-authoring/playwright.config.ts +14 -0
- package/templates/three-compat-material-authoring/src/main.ts +33 -0
- package/templates/three-compat-material-authoring/tests/route-health.spec.ts +16 -0
- package/templates/three-compat-material-authoring/tests/screenshot.spec.ts +15 -0
- package/templates/three-compat-material-authoring/tsconfig.json +19 -0
- package/templates/three-compat-postprocess-scene/index.html +16 -0
- package/templates/three-compat-postprocess-scene/package.json +21 -0
- package/templates/three-compat-postprocess-scene/playwright.config.ts +14 -0
- package/templates/three-compat-postprocess-scene/src/main.ts +17 -0
- package/templates/three-compat-postprocess-scene/tests/route-health.spec.ts +16 -0
- package/templates/three-compat-postprocess-scene/tests/screenshot.spec.ts +15 -0
- package/templates/three-compat-postprocess-scene/tsconfig.json +19 -0
- package/templates/three-compat-premium-product-viewer/index.html +16 -0
- package/templates/three-compat-premium-product-viewer/package.json +21 -0
- package/templates/three-compat-premium-product-viewer/playwright.config.ts +14 -0
- package/templates/three-compat-premium-product-viewer/src/main.ts +18 -0
- package/templates/three-compat-premium-product-viewer/tests/route-health.spec.ts +16 -0
- package/templates/three-compat-premium-product-viewer/tests/screenshot.spec.ts +15 -0
- package/templates/three-compat-premium-product-viewer/tsconfig.json +19 -0
- package/templates/animation-channel/public/aura-assets/moon-garden-feature-frame.png +0 -0
- package/templates/animation-channel/tests/reports/prompt-animation/cartoon-sample-episode.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/episode-3d.webm +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/action.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/dialogue.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/final.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/first.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/mouth-closed.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/mouth-open.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/render-live-summary.json +0 -5616
- package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/broken.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/chefs.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/customer.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/worker-1.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/worker-2.png +0 -0
- package/templates/animation-studio/dist/generated/second-scene.document.json +0 -1210
- package/templates/animation-studio/dist/generated/studio-edited.document.json +0 -1196
- package/templates/animation-studio/dist/scene/inshader-accept.document.json +0 -1
- package/templates/animation-studio/dist/scene/inshader-test.document.json +0 -1
- package/templates/animation-studio/dist/scene/integ.document.json +0 -1
- package/templates/animation-studio/dist/scene/working.document.json +0 -594
- package/templates/animation-studio/dist/scene/working.history.json +0 -1
- package/templates/animation-studio/studio/dist/assets/index-i8URxOOt.css +0 -1
- package/templates/animation-studio/studio/dist/assets/index-pC9hdZ-B.js +0 -11
- package/templates/animation-studio/studio/dist/index.html +0 -19
- package/templates/animation-studio/tests/reports/animation-studio/hifi-cast-validation.json +0 -938
|
@@ -61,6 +61,12 @@ export interface RuntimeCharacter {
|
|
|
61
61
|
rigGrade?: "A" | "B" | "C" | "D";
|
|
62
62
|
/** M7 — dominant motion source the render played (mocap/extracted/procedural…), when recorded. */
|
|
63
63
|
motionSource?: string;
|
|
64
|
+
/** Default performance clip id. */
|
|
65
|
+
defaultClip?: string;
|
|
66
|
+
/** Mouth morph target index for lip-sync. */
|
|
67
|
+
mouthMorphIndex?: number;
|
|
68
|
+
/** Foot IK configuration (truthy when enabled). */
|
|
69
|
+
footIk?: unknown;
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
export interface RuntimeShotBlocking {
|
|
@@ -254,6 +260,8 @@ export function mapDocument(doc: RuntimeDocument): EpisodeDocument {
|
|
|
254
260
|
|
|
255
261
|
const cast: CastMember[] = rChars.map((c) => {
|
|
256
262
|
const { source, sourceLabel } = castProvenance(c);
|
|
263
|
+
const fidelity =
|
|
264
|
+
fidelityById.get(c.id) ?? { id: c.id, grade: "C", previz: true, reason: "previz: ungraded" };
|
|
257
265
|
return {
|
|
258
266
|
id: c.id,
|
|
259
267
|
name: cap(c.id),
|
|
@@ -263,8 +271,11 @@ export function mapDocument(doc: RuntimeDocument): EpisodeDocument {
|
|
|
263
271
|
lines: linesPerSpeaker(c.id),
|
|
264
272
|
source,
|
|
265
273
|
sourceLabel,
|
|
266
|
-
fidelity
|
|
267
|
-
|
|
274
|
+
fidelity,
|
|
275
|
+
defaultClip: c.defaultClip,
|
|
276
|
+
mouthMorphIndex: c.mouthMorphIndex,
|
|
277
|
+
footIk: !!c.footIk,
|
|
278
|
+
gradeAwareIntent: `${fidelity.grade}-grade`
|
|
268
279
|
};
|
|
269
280
|
});
|
|
270
281
|
|
|
@@ -16,16 +16,27 @@ export interface VerbSpec {
|
|
|
16
16
|
desc: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
// The REAL CLI grammar (animation-scene.ts) — every entry here, inserted verbatim with its
|
|
20
|
+
// placeholders filled, is accepted by the CLI's switch/flag parser. These strings are also
|
|
21
|
+
// surfaced verbatim to LLMs, so they must never advertise a syntax the validator rejects.
|
|
19
22
|
export const VERBS: VerbSpec[] = [
|
|
20
|
-
{ verb: "
|
|
21
|
-
{ verb: "
|
|
22
|
-
{ verb: "cast
|
|
23
|
-
{ verb: "
|
|
23
|
+
{ verb: "new", tail: '--prompt "<scene>" [--full]', desc: "Start a new working scene from a prompt" },
|
|
24
|
+
{ verb: "set", tail: '<studio|garage|office|kitchen|moon-garden|space-station|meadow> | --query "<setting>"', desc: "Choose the active set template" },
|
|
25
|
+
{ verb: "cast add", tail: '--id <id> --query "<look>" [--scale <s>]', desc: "Cast a character (catalog resolve)" },
|
|
26
|
+
{ verb: "prop add", tail: '--id <id> --query "<look>"', desc: "Register a prop from the catalog" },
|
|
27
|
+
{ verb: "shot add", tail: "--id <id> --preset <preset> --duration <s>", desc: "Block a new shot" },
|
|
28
|
+
{ verb: "shot remove", tail: "--id <id>", desc: "Remove a shot" },
|
|
24
29
|
{ verb: "shot retime", tail: "--id <id> --duration <s>", desc: "Change a shot's duration" },
|
|
25
|
-
{ verb: "
|
|
26
|
-
{ verb: "
|
|
27
|
-
{ verb: "
|
|
28
|
-
{ verb: "
|
|
30
|
+
{ verb: "camera", tail: "--shot <id> --preset <establishing|medium|two-shot|close-up>", desc: "Set a shot's camera" },
|
|
31
|
+
{ verb: "dialogue", tail: '--line <id> --speaker <id> --text "<line>" --start <s>', desc: "Write a dialogue line" },
|
|
32
|
+
{ verb: "block", tail: "--character <id> --shot <id> --to <x,z> [--clip <clip>]", desc: "Move a character in a shot" },
|
|
33
|
+
{ verb: "gesture", tail: "--character <id> --shot <id> --clip <clip>", desc: "Queue a gesture clip for a character" },
|
|
34
|
+
{ verb: "dress", tail: "--prop <id> --at <x,z> [--scale <s>]", desc: "Place a registered prop on the set" },
|
|
35
|
+
{ verb: "scale", tail: "--character <id> --to <s>", desc: "Rescale a character" },
|
|
36
|
+
{ verb: "show", tail: "", desc: "Print the scene summary" },
|
|
37
|
+
{ verb: "validate", tail: "", desc: "Check scene coherence" },
|
|
38
|
+
{ verb: "undo", tail: "", desc: "Undo the last committed edit" },
|
|
39
|
+
{ verb: "render", tail: "[--shot <id>]", desc: "Render a low-fi preview (shot or full sequence)" }
|
|
29
40
|
];
|
|
30
41
|
|
|
31
42
|
export interface ParsedCommand {
|
|
@@ -47,7 +58,7 @@ export function parse(raw: string): ParsedCommand {
|
|
|
47
58
|
const toks = head.split(/\s+/).filter(Boolean);
|
|
48
59
|
let verb = toks[0] || "";
|
|
49
60
|
let rest = toks.slice(1);
|
|
50
|
-
if (["cast", "shot", "
|
|
61
|
+
if (["cast", "shot", "prop"].includes(verb) && rest[0]) {
|
|
51
62
|
verb += " " + rest[0];
|
|
52
63
|
rest = rest.slice(1);
|
|
53
64
|
}
|
|
@@ -39,6 +39,14 @@ export interface CastMember {
|
|
|
39
39
|
sourceLabel: string;
|
|
40
40
|
/** M7 — honest fidelity tier (A/B/C). C is "previz" — never presented as finished. */
|
|
41
41
|
fidelity: CharacterFidelity;
|
|
42
|
+
/** Default performance clip id (e.g. "idle"). */
|
|
43
|
+
defaultClip?: string;
|
|
44
|
+
/** Mouth morph target index for lip-sync; -1 when absent. */
|
|
45
|
+
mouthMorphIndex?: number;
|
|
46
|
+
/** Whether foot IK is enabled for this cast member. */
|
|
47
|
+
footIk?: boolean;
|
|
48
|
+
/** Read-only grade-aware performance intent label. */
|
|
49
|
+
gradeAwareIntent?: string;
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
export interface SetEntity {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { expect, test } from "@playwright/test";
|
|
4
|
+
|
|
5
|
+
test.setTimeout(60_000);
|
|
6
|
+
|
|
7
|
+
// The animation-studio route is the generic scene player (render-live-route.ts ->
|
|
8
|
+
// scene-player.ts). Its readiness contract is window.__AURA_LIVE_ROUTE_READY__ /
|
|
9
|
+
// __AURA_LIVE_ROUTE_ERROR__, not the createAuraApp data-aura3d-ready attribute.
|
|
10
|
+
test("Aura3D animation studio live route reaches ready state", async ({ page }) => {
|
|
11
|
+
await page.goto("/");
|
|
12
|
+
await expect
|
|
13
|
+
.poll(
|
|
14
|
+
() =>
|
|
15
|
+
page.evaluate(() => {
|
|
16
|
+
const w = window as unknown as {
|
|
17
|
+
__AURA_LIVE_ROUTE_READY__?: { ready?: boolean; backend?: string };
|
|
18
|
+
__AURA_LIVE_ROUTE_ERROR__?: string;
|
|
19
|
+
};
|
|
20
|
+
if (w.__AURA_LIVE_ROUTE_ERROR__) return `error: ${w.__AURA_LIVE_ROUTE_ERROR__}`;
|
|
21
|
+
return w.__AURA_LIVE_ROUTE_READY__?.ready === true ? "ready" : "pending";
|
|
22
|
+
}),
|
|
23
|
+
{ timeout: 45_000 }
|
|
24
|
+
)
|
|
25
|
+
.toBe("ready");
|
|
26
|
+
const proof = await page.evaluate(
|
|
27
|
+
() => (window as unknown as { __AURA_LIVE_ROUTE_READY__?: { ready?: boolean; backend?: string } }).__AURA_LIVE_ROUTE_READY__
|
|
28
|
+
);
|
|
29
|
+
expect(proof?.ready).toBe(true);
|
|
30
|
+
expect(typeof proof?.backend).toBe("string");
|
|
31
|
+
mkdirSync(resolve("tests/reports"), { recursive: true });
|
|
32
|
+
writeFileSync(resolve("tests/reports/route-health.json"), `${JSON.stringify({ ready: true, backend: proof?.backend }, null, 2)}\n`);
|
|
33
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { expect, test } from "@playwright/test";
|
|
4
|
+
|
|
5
|
+
test.setTimeout(60_000);
|
|
6
|
+
|
|
7
|
+
// Waits on the scene player's real readiness contract (__AURA_LIVE_ROUTE_READY__),
|
|
8
|
+
// then captures the rendered route as visual evidence.
|
|
9
|
+
test("Aura3D animation studio screenshot shows content", async ({ page }) => {
|
|
10
|
+
await page.goto("/");
|
|
11
|
+
await expect
|
|
12
|
+
.poll(
|
|
13
|
+
() =>
|
|
14
|
+
page.evaluate(() => {
|
|
15
|
+
const w = window as unknown as {
|
|
16
|
+
__AURA_LIVE_ROUTE_READY__?: { ready?: boolean };
|
|
17
|
+
__AURA_LIVE_ROUTE_ERROR__?: string;
|
|
18
|
+
};
|
|
19
|
+
if (w.__AURA_LIVE_ROUTE_ERROR__) return `error: ${w.__AURA_LIVE_ROUTE_ERROR__}`;
|
|
20
|
+
return w.__AURA_LIVE_ROUTE_READY__?.ready === true ? "ready" : "pending";
|
|
21
|
+
}),
|
|
22
|
+
{ timeout: 45_000 }
|
|
23
|
+
)
|
|
24
|
+
.toBe("ready");
|
|
25
|
+
const screenshot = await page.screenshot({ fullPage: false });
|
|
26
|
+
mkdirSync(resolve("tests/reports"), { recursive: true });
|
|
27
|
+
writeFileSync(resolve("tests/reports/screenshot.png"), screenshot);
|
|
28
|
+
writeFileSync(resolve("tests/reports/screenshot.json"), `${JSON.stringify({ bytes: screenshot.byteLength }, null, 2)}\n`);
|
|
29
|
+
expect(screenshot.byteLength).toBeGreaterThan(1000);
|
|
30
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Character controller preview: keyboard input -> kinematic speed -> @aura3d/animation locomotion
|
|
2
2
|
// kit (idle/walk/run blended by speed) -> live proof object. Hold a direction key (W/A/S/D or
|
|
3
|
-
// arrows) to walk; hold Shift to run.
|
|
3
|
+
// arrows) to walk; hold Shift to run. A minimal Aura3D stage renders beneath the HUD.
|
|
4
|
+
import { camera, createAuraApp, lights, material, primitives, scene } from "@aura3d/engine";
|
|
4
5
|
import { createLocomotionKit } from "@aura3d/animation";
|
|
5
6
|
import { defaultCharacterControllerTuning, stepCharacterSpeed, type CharacterControllerState } from "./controller.js";
|
|
6
7
|
|
|
@@ -32,6 +33,22 @@ hud.id = "character-controller-hud";
|
|
|
32
33
|
hud.style.cssText = "font:14px monospace;padding:16px;color:#6cf;background:#0c0f16;min-height:140px";
|
|
33
34
|
root.appendChild(hud);
|
|
34
35
|
|
|
36
|
+
// Minimal visual stage: a capsule stand-in on a floor so the route renders a real
|
|
37
|
+
// Aura3D scene alongside the locomotion HUD proof.
|
|
38
|
+
const stage = document.createElement("div");
|
|
39
|
+
stage.id = "character-controller-stage";
|
|
40
|
+
stage.style.cssText = "height:320px";
|
|
41
|
+
root.appendChild(stage);
|
|
42
|
+
createAuraApp(stage, {
|
|
43
|
+
scene: scene()
|
|
44
|
+
.background("#0c0f16")
|
|
45
|
+
.camera(camera.orbit({ target: [0, 1, 0], distance: 5 }))
|
|
46
|
+
.add(primitives.box({ name: "floor", size: [6, 0.1, 6], position: [0, -0.05, 0], material: material.pbr({ color: "#151b27", roughness: 0.9 }), receiveShadow: true }))
|
|
47
|
+
.add(primitives.capsule({ name: "character stand-in", size: [0.7, 1.7, 0.7], position: [0, 1.2, 0], material: material.pbr({ color: "#6cb1f0", roughness: 0.5 }), castShadow: true }))
|
|
48
|
+
.add(lights.ambient({ intensity: 0.35 }))
|
|
49
|
+
.add(lights.directional({ name: "key", position: [3, 5, 2], intensity: 1.4 }))
|
|
50
|
+
});
|
|
51
|
+
|
|
35
52
|
let state: CharacterControllerState = { speed: 0 };
|
|
36
53
|
let last = 0;
|
|
37
54
|
|
|
@@ -31,8 +31,8 @@ test("Aura3D cinematic scene screenshot shows the rainy neon hero prompt", async
|
|
|
31
31
|
const luminance = r * 0.2126 + g * 0.7152 + b * 0.0722;
|
|
32
32
|
if (luminance > 30) buckets.add(`${r >> 5}-${g >> 5}-${b >> 5}`);
|
|
33
33
|
if (b > 110 && g > 90 && b > r * 1.22) cyanPixels += 1;
|
|
34
|
-
if (r >
|
|
35
|
-
if (r >
|
|
34
|
+
if (r > 145 && g > 105 && b < 180 && r >= g * 0.95 && g >= b * 0.65) amberPixels += 1;
|
|
35
|
+
if (r > 130 && g > 140 && b > 145 && Math.max(r, g, b) - Math.min(r, g, b) < 75) rainPixels += 1;
|
|
36
36
|
if (y < target.height * 0.36 && ((b > 95 && g > 65 && b > r * 1.12) || (r > 105 && g > 62 && b < 95))) wetReflectionPixels += 1;
|
|
37
37
|
if (x > target.width * 0.32 && x < target.width * 0.68 && y > target.height * 0.26 && y < target.height * 0.78 && luminance > 75) centerHeroPixels += 1;
|
|
38
38
|
if (luminance > 8 && luminance < 36 && b >= r && x > target.width * 0.08 && x < target.width * 0.92) darkAlleyPixels += 1;
|
|
@@ -50,7 +50,7 @@ test("Aura3D cinematic scene screenshot shows the rainy neon hero prompt", async
|
|
|
50
50
|
expect(profile.rainPixels).toBeGreaterThan(90);
|
|
51
51
|
expect(profile.wetReflectionPixels).toBeGreaterThan(60);
|
|
52
52
|
expect(profile.centerHeroPixels).toBeGreaterThan(600);
|
|
53
|
-
expect(profile.darkAlleyPixels).toBeGreaterThan(
|
|
53
|
+
expect(profile.darkAlleyPixels).toBeGreaterThan(150);
|
|
54
54
|
expect(profile.uniqueBuckets).toBeGreaterThan(22);
|
|
55
55
|
expect(screenshot.byteLength).toBeGreaterThan(1000);
|
|
56
56
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { expect, test } from "@playwright/test";
|
|
4
|
+
|
|
5
|
+
test.setTimeout(60_000);
|
|
6
|
+
|
|
7
|
+
test("Aura3D episode builder screenshot shows content", async ({ page }) => {
|
|
8
|
+
await page.goto("/");
|
|
9
|
+
await expect.poll(() => page.locator("body").getAttribute("data-aura3d-ready"), { timeout: 45_000 }).toBe("true");
|
|
10
|
+
const screenshot = await page.screenshot({ fullPage: false });
|
|
11
|
+
mkdirSync(resolve("tests/reports"), { recursive: true });
|
|
12
|
+
writeFileSync(resolve("tests/reports/screenshot.png"), screenshot);
|
|
13
|
+
writeFileSync(resolve("tests/reports/screenshot.json"), `${JSON.stringify({ bytes: screenshot.byteLength }, null, 2)}\n`);
|
|
14
|
+
expect(screenshot.byteLength).toBeGreaterThan(1000);
|
|
15
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Aura3D Falling Blocks Starter
|
|
2
|
+
|
|
3
|
+
Keyboard-playable falling-block starter using only the public
|
|
4
|
+
`@aura3d/engine` API.
|
|
5
|
+
|
|
6
|
+
- The arcade cabinet is a typed GLB asset in `src/aura-assets.ts`.
|
|
7
|
+
- `game.fallingBlocks(...)` owns board state, movement, rotation, hold,
|
|
8
|
+
gravity, hard drop, line clear, score, replay, and checksum behavior.
|
|
9
|
+
- `tests/playable.spec.ts` drives keyboard input and verifies move, rotate,
|
|
10
|
+
hold, reset, and line clear behavior.
|
|
11
|
+
|
|
12
|
+
Run:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install
|
|
16
|
+
npm run dev
|
|
17
|
+
npm test
|
|
18
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Aura3D Falling Blocks Starter</title>
|
|
7
|
+
<style>
|
|
8
|
+
html,
|
|
9
|
+
body,
|
|
10
|
+
#app {
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 100%;
|
|
13
|
+
margin: 0;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
background: #05070a;
|
|
16
|
+
}
|
|
17
|
+
</style>
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
<div id="app"></div>
|
|
21
|
+
<script type="module" src="./src/main.ts"></script>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aura3d-falling-blocks-starter",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite --host 127.0.0.1",
|
|
8
|
+
"typecheck": "tsc --noEmit",
|
|
9
|
+
"build": "npm run typecheck && vite build",
|
|
10
|
+
"preview": "vite preview --host 127.0.0.1",
|
|
11
|
+
"test": "playwright test tests/playable.spec.ts --workers=1"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@aura3d/engine": "1.0.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@playwright/test": "^1.52.0",
|
|
18
|
+
"typescript": "^5.8.3",
|
|
19
|
+
"vite": "^7.3.2"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineConfig } from "@playwright/test";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
webServer: {
|
|
5
|
+
command: "npm run dev -- --port 5179",
|
|
6
|
+
url: "http://127.0.0.1:5179",
|
|
7
|
+
reuseExistingServer: !process.env.CI
|
|
8
|
+
},
|
|
9
|
+
use: {
|
|
10
|
+
baseURL: "http://127.0.0.1:5179"
|
|
11
|
+
}
|
|
12
|
+
});
|
package/templates/falling-blocks-starter/public/aura-assets/showcaseBlockfallCabinet.679d52fe.glb
ADDED
|
Binary file
|
package/templates/falling-blocks-starter/public/aura-assets/showcaseBlockfallCabinet.thumb.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180"><rect width="320" height="180" fill="#101720"/><path d="M80 126 160 46l80 80-80 28z" fill="#77a7ff"/><text x="160" y="160" text-anchor="middle" font-family="Arial" font-size="18" fill="#f4f7fb">showcaseBlockfallCabinet 2x2x3.27</text></svg>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineAuraAssets } from "@aura3d/engine";
|
|
2
|
+
|
|
3
|
+
export const assets = defineAuraAssets({
|
|
4
|
+
cabinetModel: {
|
|
5
|
+
type: "model",
|
|
6
|
+
format: "glb",
|
|
7
|
+
url: "/aura-assets/showcaseBlockfallCabinet.679d52fe.glb",
|
|
8
|
+
bounds: [2, 2, 3.27],
|
|
9
|
+
hash: "sha256-679d52fe0c7bf99373fc873f3c3892548f6c5758ae9c81be91f09acae6a35a36",
|
|
10
|
+
metadata: {
|
|
11
|
+
materials: ["arcade_machine"],
|
|
12
|
+
animations: [],
|
|
13
|
+
textures: ["image-0", "image-1", "image-2", "image-3"],
|
|
14
|
+
license: "CC-BY-4.0",
|
|
15
|
+
author: "Dmitry Blagodaryov",
|
|
16
|
+
sourcePage: "https://huggingface.co/datasets/allenai/objaverse/blob/main/glbs/000-012/f73986356b6e4d72b7a889279837aec2.glb",
|
|
17
|
+
thumbnailUrl: "/aura-assets/showcaseBlockfallCabinet.thumb.svg"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
} as const);
|