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
|
@@ -1,27 +1,257 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
camera,
|
|
3
|
+
createAuraApp,
|
|
4
|
+
game,
|
|
5
|
+
lights,
|
|
6
|
+
material,
|
|
7
|
+
model,
|
|
8
|
+
primitives,
|
|
9
|
+
scene,
|
|
10
|
+
type AuraNodeInput
|
|
11
|
+
} from "@aura3d/engine";
|
|
2
12
|
import { assets } from "./aura-assets";
|
|
3
13
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
declare global {
|
|
15
|
+
interface Window {
|
|
16
|
+
__AURA3D_MINI_GAME__?: MiniGameEvidence;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface MiniGameEvidence {
|
|
21
|
+
readonly status: string;
|
|
22
|
+
readonly frame: number;
|
|
23
|
+
readonly score: number;
|
|
24
|
+
readonly deaths: number;
|
|
25
|
+
readonly checkpointId: string;
|
|
26
|
+
readonly collected: readonly string[];
|
|
27
|
+
readonly player: {
|
|
28
|
+
readonly x: number;
|
|
29
|
+
readonly y: number;
|
|
30
|
+
readonly grounded: boolean;
|
|
31
|
+
};
|
|
32
|
+
readonly events: readonly string[];
|
|
33
|
+
readonly evidence: unknown;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const level = {
|
|
37
|
+
start: { x: 0, y: 0.35 },
|
|
38
|
+
finish: { x: 12.4, y: 0.35 },
|
|
39
|
+
platforms: [
|
|
40
|
+
{ id: "launch", x: -0.6, y: 0, width: 4.2, height: 0.35 },
|
|
41
|
+
{ id: "middle", x: 3.8, y: 0.62, width: 3.2, height: 0.3 },
|
|
42
|
+
{ id: "finish", x: 8.2, y: 0.18, width: 4.8, height: 0.35 }
|
|
43
|
+
],
|
|
44
|
+
movingPlatforms: [
|
|
45
|
+
{ id: "lift", x: 6.9, y: 1.05, width: 1.35, height: 0.22, axis: "y" as const, amplitude: 0.42, period: 2.4 }
|
|
46
|
+
],
|
|
47
|
+
collectibles: [
|
|
48
|
+
{ id: "coin-01", x: 1.4, y: 1.15, value: 50, radius: 0.55 },
|
|
49
|
+
{ id: "coin-02", x: 4.8, y: 1.45, value: 75, radius: 0.55 },
|
|
50
|
+
{ id: "coin-03", x: 9.8, y: 1.05, value: 100, radius: 0.55 }
|
|
51
|
+
],
|
|
52
|
+
hazards: [
|
|
53
|
+
{ id: "spikes", x: 7.7, y: 0.42, width: 0.85, height: 0.24 }
|
|
54
|
+
],
|
|
55
|
+
checkpoints: [
|
|
56
|
+
{ id: "mid", x: 5.2, y: 0.92, radius: 0.8 }
|
|
17
57
|
],
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
58
|
+
lowerBound: -2.4,
|
|
59
|
+
moveSpeed: 5.2,
|
|
60
|
+
jumpVelocity: 8,
|
|
61
|
+
dashSpeed: 9.5
|
|
62
|
+
};
|
|
23
63
|
|
|
24
|
-
|
|
64
|
+
const input = game.input({
|
|
65
|
+
actions: {
|
|
66
|
+
left: ["KeyA", "ArrowLeft"],
|
|
67
|
+
right: ["KeyD", "ArrowRight"],
|
|
68
|
+
jump: ["Space", "KeyW", "ArrowUp"],
|
|
69
|
+
dash: ["ShiftLeft", "ShiftRight"],
|
|
70
|
+
down: ["KeyS", "ArrowDown"],
|
|
71
|
+
reset: ["KeyR"]
|
|
72
|
+
},
|
|
73
|
+
axes: {
|
|
74
|
+
moveX: { negative: "left", positive: "right" }
|
|
75
|
+
},
|
|
76
|
+
bufferMs: 140
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const platformer = game.platformer(level);
|
|
80
|
+
const routeEvents = game.eventLog({ label: "mini game route events", maxEvents: 16 });
|
|
81
|
+
const hud = game.hud.bindings([
|
|
82
|
+
game.hud.score({ valuePath: "appState.score" }),
|
|
83
|
+
game.hud.lives({ valuePath: "appState.lives" }),
|
|
84
|
+
game.hud.objective({ valuePath: "appState.objective" }),
|
|
85
|
+
game.hud.checkpoint({ valuePath: "appState.checkpoint" }),
|
|
86
|
+
game.hud.eventLog({ valuePath: "appState.events" })
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
const app = createAuraApp("#app", {
|
|
25
90
|
diagnostics: { overlay: true, performancePanel: true },
|
|
26
|
-
scene:
|
|
91
|
+
scene: buildScene()
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const player = app.nodes.require("mini-player");
|
|
95
|
+
const lift = app.nodes.require("platform-lift");
|
|
96
|
+
const coins = level.collectibles.map((coin) => [coin.id, app.nodes.require(`coin-${coin.id}`)] as const);
|
|
97
|
+
const checkpoint = app.nodes.require("checkpoint-mid");
|
|
98
|
+
const goal = app.nodes.require("goal");
|
|
99
|
+
const hudRoot = createHud();
|
|
100
|
+
|
|
101
|
+
let objective = "Collect coins, avoid spikes, reach the goal";
|
|
102
|
+
|
|
103
|
+
app.onFrame(({ dt }: { readonly dt: number }) => {
|
|
104
|
+
input.update(dt);
|
|
105
|
+
if (input.pressed("reset")) {
|
|
106
|
+
platformer.reset();
|
|
107
|
+
routeEvents.push({ type: "reset", label: "Route reset" });
|
|
108
|
+
objective = "Collect coins, avoid spikes, reach the goal";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const state = platformer.step(dt, {
|
|
112
|
+
moveX: input.axis("moveX"),
|
|
113
|
+
jumpPressed: input.buffered("jump"),
|
|
114
|
+
jumpHeld: input.held("jump"),
|
|
115
|
+
dashPressed: input.pressed("dash"),
|
|
116
|
+
fastFall: input.held("down")
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
for (const event of state.events) {
|
|
120
|
+
routeEvents.push({
|
|
121
|
+
type: event.type,
|
|
122
|
+
label: event.id ? `${event.type}:${event.id}` : event.type,
|
|
123
|
+
targetId: event.id,
|
|
124
|
+
severity: event.type === "complete" || event.type === "collect" ? "success" : event.type === "hazard" || event.type === "fall" ? "warning" : "info",
|
|
125
|
+
frame: event.frame,
|
|
126
|
+
time: event.time
|
|
127
|
+
});
|
|
128
|
+
if (event.type === "checkpoint") objective = "Checkpoint reached. Finish the route.";
|
|
129
|
+
if (event.type === "complete") objective = "Finished. Press R to replay.";
|
|
130
|
+
if (event.type === "respawn") objective = "Respawned. Take the safer route.";
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
player.setPosition(state.player.x, state.player.y + 0.54, 0);
|
|
134
|
+
lift.setPosition(level.movingPlatforms[0].x + level.movingPlatforms[0].width / 2, movingLiftY(state.time), 0);
|
|
135
|
+
for (const [id, node] of coins) node.setVisible(!state.collected.includes(id));
|
|
136
|
+
checkpoint.setVisible(!state.activatedCheckpoints.includes("mid"));
|
|
137
|
+
goal.setScale(state.status === "completed" ? [0.28, 1.08, 0.18] : [0.22, 0.92, 0.16]);
|
|
138
|
+
|
|
139
|
+
renderHud(state);
|
|
140
|
+
publishEvidence(state);
|
|
27
141
|
});
|
|
142
|
+
|
|
143
|
+
publishEvidence(platformer.snapshot());
|
|
144
|
+
renderHud(platformer.snapshot());
|
|
145
|
+
|
|
146
|
+
function buildScene() {
|
|
147
|
+
const nodes: AuraNodeInput[] = [
|
|
148
|
+
model(assets.playerModel, { name: "typed mini-game player", castShadow: true })
|
|
149
|
+
.position(level.start.x, level.start.y + 0.54, 0)
|
|
150
|
+
.scale(0.42)
|
|
151
|
+
.runtime(game.runtimeNode("mini-player", { tags: ["player", "typed-asset", "runtime"] })),
|
|
152
|
+
...level.platforms.map((platform) =>
|
|
153
|
+
primitives.box({ name: `${platform.id} platform`, material: material.neon({ color: "#62d8ef", emissive: "#62d8ef", emissiveIntensity: 0.18 }) })
|
|
154
|
+
.position(platform.x + platform.width / 2, platform.y + platform.height / 2, -0.05)
|
|
155
|
+
.scale([platform.width, platform.height, 0.22])
|
|
156
|
+
),
|
|
157
|
+
primitives.box({ name: "moving lift platform", material: material.neon({ color: "#b5f77d", emissive: "#b5f77d", emissiveIntensity: 0.35 }) })
|
|
158
|
+
.position(level.movingPlatforms[0].x + level.movingPlatforms[0].width / 2, movingLiftY(0), 0)
|
|
159
|
+
.scale([level.movingPlatforms[0].width, level.movingPlatforms[0].height, 0.22])
|
|
160
|
+
.runtime(game.runtimeNode("platform-lift", { tags: ["moving-platform", "runtime"] })),
|
|
161
|
+
...level.collectibles.map((coin) =>
|
|
162
|
+
primitives.sphere({ name: `${coin.id} collectible`, material: material.neon({ color: "#f7d76b", emissive: "#f7d76b", emissiveIntensity: 0.7 }) })
|
|
163
|
+
.position(coin.x, coin.y, 0.02)
|
|
164
|
+
.scale(0.18)
|
|
165
|
+
.runtime(game.runtimeNode(`coin-${coin.id}`, { tags: ["coin", "runtime"] }))
|
|
166
|
+
),
|
|
167
|
+
primitives.box({ name: "hazard spikes", material: material.neon({ color: "#f06b7a", emissive: "#f06b7a", emissiveIntensity: 0.7 }) })
|
|
168
|
+
.position(level.hazards[0].x + level.hazards[0].width / 2, level.hazards[0].y + level.hazards[0].height / 2, 0.05)
|
|
169
|
+
.scale([level.hazards[0].width, level.hazards[0].height, 0.2]),
|
|
170
|
+
primitives.box({ name: "checkpoint marker", material: material.neon({ color: "#9df59e", emissive: "#9df59e", emissiveIntensity: 0.65 }) })
|
|
171
|
+
.position(level.checkpoints[0].x, level.checkpoints[0].y + 0.42, 0.08)
|
|
172
|
+
.scale([0.14, 0.85, 0.14])
|
|
173
|
+
.runtime(game.runtimeNode("checkpoint-mid", { tags: ["checkpoint", "runtime"] })),
|
|
174
|
+
primitives.box({ name: "finish portal", material: material.neon({ color: "#ffad57", emissive: "#ffad57", emissiveIntensity: 0.82 }) })
|
|
175
|
+
.position(level.finish.x, level.finish.y + 0.7, 0.08)
|
|
176
|
+
.scale([0.22, 0.92, 0.16])
|
|
177
|
+
.runtime(game.runtimeNode("goal", { tags: ["finish", "runtime"] }))
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
return scene()
|
|
181
|
+
.background("#071015")
|
|
182
|
+
.addMany(nodes)
|
|
183
|
+
.add(lights.ambient({ name: "game ambient", intensity: 0.38, color: "#d9f8ff" }))
|
|
184
|
+
.add(lights.directional({ name: "game key", position: [4, 6, 5], intensity: 1.2, color: "#ffffff" }))
|
|
185
|
+
.camera(camera.perspective({ position: [5.8, 4.3, 8.5], target: [5.8, 0.9, 0], fov: 44 }));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function movingLiftY(time: number): number {
|
|
189
|
+
const platform = level.movingPlatforms[0];
|
|
190
|
+
return platform.y + platform.height / 2 + Math.sin((time / platform.period) * Math.PI * 2) * platform.amplitude;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function createHud(): HTMLElement {
|
|
194
|
+
const root = document.createElement("aside");
|
|
195
|
+
root.id = "mini-game-hud";
|
|
196
|
+
root.style.cssText = [
|
|
197
|
+
"position:absolute",
|
|
198
|
+
"left:16px",
|
|
199
|
+
"top:16px",
|
|
200
|
+
"z-index:5",
|
|
201
|
+
"min-width:260px",
|
|
202
|
+
"font:600 13px/1.35 Inter, system-ui, sans-serif",
|
|
203
|
+
"color:#f5fbff",
|
|
204
|
+
"background:rgba(3,9,14,0.78)",
|
|
205
|
+
"border:1px solid rgba(125,220,235,0.34)",
|
|
206
|
+
"border-radius:8px",
|
|
207
|
+
"padding:12px",
|
|
208
|
+
"pointer-events:none"
|
|
209
|
+
].join(";");
|
|
210
|
+
document.body.append(root);
|
|
211
|
+
return root;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function renderHud(state: ReturnType<typeof platformer.snapshot>): void {
|
|
215
|
+
hudRoot.innerHTML = [
|
|
216
|
+
`<strong>Aura3D Mini Game</strong>`,
|
|
217
|
+
`<div>Score ${state.score} | Lives ${state.lives} | Deaths ${state.deaths}</div>`,
|
|
218
|
+
`<div>Checkpoint ${state.checkpointId}</div>`,
|
|
219
|
+
`<div>${objective}</div>`,
|
|
220
|
+
`<div>Move A/D or arrows. Jump Space. Dash Shift. Reset R.</div>`
|
|
221
|
+
].join("");
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function publishEvidence(state: ReturnType<typeof platformer.snapshot>): void {
|
|
225
|
+
const evidence = app.evidence({
|
|
226
|
+
input,
|
|
227
|
+
events: routeEvents,
|
|
228
|
+
hud,
|
|
229
|
+
appState: {
|
|
230
|
+
score: state.score,
|
|
231
|
+
lives: state.lives,
|
|
232
|
+
objective,
|
|
233
|
+
checkpoint: state.checkpointId,
|
|
234
|
+
events: routeEvents.events().map((event: { readonly label: string }) => event.label)
|
|
235
|
+
},
|
|
236
|
+
assets: {
|
|
237
|
+
typedAssets: Object.keys(assets).length,
|
|
238
|
+
missingAssets: []
|
|
239
|
+
},
|
|
240
|
+
source: { expectsGame: true }
|
|
241
|
+
});
|
|
242
|
+
window.__AURA3D_MINI_GAME__ = {
|
|
243
|
+
status: state.status,
|
|
244
|
+
frame: state.frame,
|
|
245
|
+
score: state.score,
|
|
246
|
+
deaths: state.deaths,
|
|
247
|
+
checkpointId: state.checkpointId,
|
|
248
|
+
collected: state.collected,
|
|
249
|
+
player: {
|
|
250
|
+
x: state.player.x,
|
|
251
|
+
y: state.player.y,
|
|
252
|
+
grounded: state.player.grounded
|
|
253
|
+
},
|
|
254
|
+
events: routeEvents.events().map((event: { readonly label: string }) => event.label),
|
|
255
|
+
evidence
|
|
256
|
+
};
|
|
257
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { expect, test } from "@playwright/test";
|
|
2
|
+
|
|
3
|
+
test.setTimeout(60_000);
|
|
4
|
+
|
|
5
|
+
type MiniGameState = {
|
|
6
|
+
readonly score: number;
|
|
7
|
+
readonly events: readonly string[];
|
|
8
|
+
readonly player: {
|
|
9
|
+
readonly x: number;
|
|
10
|
+
readonly y: number;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
function readMiniGameState(): MiniGameState | undefined {
|
|
15
|
+
return (window as unknown as { readonly __AURA3D_MINI_GAME__?: MiniGameState }).__AURA3D_MINI_GAME__;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
test("Aura3D mini game responds to keyboard input, scoring, and reset", async ({ page }) => {
|
|
19
|
+
await page.goto("/");
|
|
20
|
+
await expect.poll(() => page.locator("body").getAttribute("data-aura3d-ready"), { timeout: 45_000 }).toBe("true");
|
|
21
|
+
|
|
22
|
+
const initial = await page.evaluate(readMiniGameState);
|
|
23
|
+
expect(initial?.player.x).toBeLessThan(0.2);
|
|
24
|
+
|
|
25
|
+
await page.keyboard.down("ArrowRight");
|
|
26
|
+
await page.waitForTimeout(650);
|
|
27
|
+
await page.keyboard.up("ArrowRight");
|
|
28
|
+
|
|
29
|
+
const moved = await page.evaluate(readMiniGameState);
|
|
30
|
+
expect(moved?.player.x ?? 0).toBeGreaterThan((initial?.player.x ?? 0) + 1.2);
|
|
31
|
+
|
|
32
|
+
await page.keyboard.press("Space");
|
|
33
|
+
await page.waitForTimeout(180);
|
|
34
|
+
const jumped = await page.evaluate(readMiniGameState);
|
|
35
|
+
expect(jumped?.player.y ?? 0).toBeGreaterThan(moved?.player.y ?? 0);
|
|
36
|
+
|
|
37
|
+
await page.keyboard.down("ArrowRight");
|
|
38
|
+
await page.waitForTimeout(1600);
|
|
39
|
+
await page.keyboard.up("ArrowRight");
|
|
40
|
+
const progressed = await page.evaluate(readMiniGameState);
|
|
41
|
+
expect(progressed?.score ?? 0).toBeGreaterThanOrEqual(50);
|
|
42
|
+
expect(progressed?.events.length ?? 0).toBeGreaterThan(0);
|
|
43
|
+
|
|
44
|
+
await page.keyboard.press("KeyR");
|
|
45
|
+
await page.waitForTimeout(120);
|
|
46
|
+
const reset = await page.evaluate(readMiniGameState);
|
|
47
|
+
expect(reset?.player.x ?? 99).toBeLessThan(0.3);
|
|
48
|
+
expect(reset?.events.some((event) => event.includes("reset"))).toBe(true);
|
|
49
|
+
});
|
|
@@ -4,60 +4,65 @@ import { expect, test } from "@playwright/test";
|
|
|
4
4
|
|
|
5
5
|
test.setTimeout(60_000);
|
|
6
6
|
|
|
7
|
-
test("Aura3D mini game screenshot shows a playable
|
|
7
|
+
test("Aura3D mini game screenshot shows a readable playable scene", async ({ page }) => {
|
|
8
8
|
await page.goto("/");
|
|
9
9
|
await expect.poll(() => page.locator("body").getAttribute("data-aura3d-ready"), { timeout: 45_000 }).toBe("true");
|
|
10
|
+
|
|
11
|
+
await page.keyboard.down("ArrowRight");
|
|
12
|
+
await page.waitForTimeout(550);
|
|
13
|
+
await page.keyboard.up("ArrowRight");
|
|
14
|
+
|
|
15
|
+
const state = await page.evaluate(() =>
|
|
16
|
+
(window as unknown as {
|
|
17
|
+
readonly __AURA3D_MINI_GAME__?: {
|
|
18
|
+
readonly score: number;
|
|
19
|
+
readonly player: { readonly x: number };
|
|
20
|
+
};
|
|
21
|
+
}).__AURA3D_MINI_GAME__
|
|
22
|
+
);
|
|
23
|
+
expect(state?.player.x ?? 0).toBeGreaterThan(0.8);
|
|
24
|
+
|
|
10
25
|
const canvas = page.locator("canvas");
|
|
11
26
|
const profile = await canvas.evaluate((element) => {
|
|
12
27
|
const target = element as HTMLCanvasElement;
|
|
13
28
|
const gl = target.getContext("webgl2", { preserveDrawingBuffer: true });
|
|
14
|
-
if (!gl) return { error: "missing-webgl2",
|
|
29
|
+
if (!gl) return { error: "missing-webgl2", brightPixels: 0, warmPixels: 0, cyanPixels: 0, redPixels: 0, uniqueBuckets: 0 };
|
|
15
30
|
const pixels = new Uint8Array(target.width * target.height * 4);
|
|
16
31
|
gl.readPixels(0, 0, target.width, target.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
|
|
17
32
|
const buckets = new Set<string>();
|
|
18
|
-
let
|
|
19
|
-
let
|
|
20
|
-
let
|
|
21
|
-
let
|
|
22
|
-
let hazardPixels = 0;
|
|
23
|
-
let portalPixels = 0;
|
|
24
|
-
let cyanTrailPixels = 0;
|
|
25
|
-
let arenaPixels = 0;
|
|
33
|
+
let brightPixels = 0;
|
|
34
|
+
let warmPixels = 0;
|
|
35
|
+
let cyanPixels = 0;
|
|
36
|
+
let redPixels = 0;
|
|
26
37
|
for (let y = 0; y < target.height; y += 4) {
|
|
27
38
|
for (let x = 0; x < target.width; x += 4) {
|
|
28
|
-
if (x > target.width * 0.76 && y > target.height * 0.74) continue;
|
|
29
39
|
const offset = (y * target.width + x) * 4;
|
|
30
40
|
const r = pixels[offset] ?? 0;
|
|
31
41
|
const g = pixels[offset + 1] ?? 0;
|
|
32
42
|
const b = pixels[offset + 2] ?? 0;
|
|
33
43
|
const luminance = r * 0.2126 + g * 0.7152 + b * 0.0722;
|
|
34
|
-
if (luminance >
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (
|
|
39
|
-
if (
|
|
40
|
-
if (r >
|
|
41
|
-
if (r > 165 && g > 95 && b < 125) portalPixels += 1;
|
|
42
|
-
if (g > 140 && b > 150 && r < 150) cyanTrailPixels += 1;
|
|
43
|
-
if (g > 42 && b > 50 && b > r * 1.08 && luminance > 24 && luminance < 100) arenaPixels += 1;
|
|
44
|
+
if (luminance > 30) {
|
|
45
|
+
brightPixels += 1;
|
|
46
|
+
buckets.add(`${r >> 5}-${g >> 5}-${b >> 5}`);
|
|
47
|
+
}
|
|
48
|
+
if (r > 130 && g > 105 && b < 155 && r >= g * 0.9) warmPixels += 1;
|
|
49
|
+
if (g > 115 && b > 105 && r < 190 && b >= r * 0.78) cyanPixels += 1;
|
|
50
|
+
if (r > 120 && g < 150 && b < 180 && r > g * 1.03) redPixels += 1;
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
|
-
return {
|
|
53
|
+
return { brightPixels, warmPixels, cyanPixels, redPixels, uniqueBuckets: buckets.size };
|
|
47
54
|
});
|
|
55
|
+
|
|
48
56
|
const screenshot = await page.screenshot({ fullPage: false });
|
|
49
57
|
mkdirSync(resolve("tests/reports"), { recursive: true });
|
|
50
58
|
writeFileSync(resolve("tests/reports/screenshot.png"), screenshot);
|
|
51
|
-
writeFileSync(resolve("tests/reports/screenshot.json"), `${JSON.stringify({ bytes: screenshot.byteLength, profile }, null, 2)}\n`);
|
|
59
|
+
writeFileSync(resolve("tests/reports/screenshot.json"), `${JSON.stringify({ bytes: screenshot.byteLength, profile, state }, null, 2)}\n`);
|
|
60
|
+
|
|
52
61
|
expect(profile.error).toBeUndefined();
|
|
53
|
-
expect(profile.
|
|
54
|
-
expect(profile.
|
|
55
|
-
expect(profile.
|
|
56
|
-
expect(profile.
|
|
57
|
-
expect(profile.
|
|
58
|
-
expect(profile.portalPixels).toBeGreaterThan(45);
|
|
59
|
-
expect(profile.cyanTrailPixels).toBeGreaterThan(90);
|
|
60
|
-
expect(profile.arenaPixels).toBeGreaterThan(600);
|
|
61
|
-
expect(profile.uniqueBuckets).toBeGreaterThan(22);
|
|
62
|
+
expect(profile.brightPixels).toBeGreaterThan(900);
|
|
63
|
+
expect(profile.cyanPixels).toBeGreaterThan(20);
|
|
64
|
+
expect(profile.warmPixels).toBeGreaterThan(10);
|
|
65
|
+
expect(profile.redPixels).toBeGreaterThan(5);
|
|
66
|
+
expect(profile.uniqueBuckets).toBeGreaterThan(10);
|
|
62
67
|
expect(screenshot.byteLength).toBeGreaterThan(1000);
|
|
63
68
|
});
|
|
@@ -31,8 +31,8 @@ test("Aura3D product viewer screenshot shows a prompt-aligned studio product", a
|
|
|
31
31
|
if (luminance > 32) buckets.add(`${r >> 5}-${g >> 5}-${b >> 5}`);
|
|
32
32
|
const inProductWindow = x > target.width * 0.34 && x < target.width * 0.68 && y > target.height * 0.24 && y < target.height * 0.78;
|
|
33
33
|
if (inProductWindow && r > 145 && g > 145 && b > 138 && Math.abs(r - g) < 32 && Math.abs(g - b) < 40) metalPixels += 1;
|
|
34
|
-
if (r >
|
|
35
|
-
if (Math.max(r, g, b) - Math.min(r, g, b) >
|
|
34
|
+
if (r > 70 && g > 45 && b < 120 && r >= g && g >= b * 0.75) warmAccentPixels += 1;
|
|
35
|
+
if (Math.max(r, g, b) - Math.min(r, g, b) > 32 && luminance > 38) saturatedStudioPixels += 1;
|
|
36
36
|
if (inProductWindow && luminance > 32) centerObjectPixels += 1;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -44,9 +44,9 @@ test("Aura3D product viewer screenshot shows a prompt-aligned studio product", a
|
|
|
44
44
|
writeFileSync(resolve("tests/reports/screenshot.json"), `${JSON.stringify({ bytes: screenshot.byteLength, profile }, null, 2)}\n`);
|
|
45
45
|
expect(profile.error).toBeUndefined();
|
|
46
46
|
expect(profile.metalPixels).toBeGreaterThan(5);
|
|
47
|
-
expect(profile.warmAccentPixels).toBeGreaterThan(
|
|
47
|
+
expect(profile.warmAccentPixels).toBeGreaterThan(8);
|
|
48
48
|
expect(profile.centerObjectPixels).toBeGreaterThan(650);
|
|
49
|
-
expect(profile.saturatedStudioPixels).toBeGreaterThan(
|
|
49
|
+
expect(profile.saturatedStudioPixels).toBeGreaterThan(800);
|
|
50
50
|
expect(profile.uniqueBuckets).toBeGreaterThan(18);
|
|
51
51
|
expect(screenshot.byteLength).toBeGreaterThan(1000);
|
|
52
52
|
});
|
|
@@ -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 prompt animation channel 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,27 @@
|
|
|
1
|
+
# Aura3D Racing Starter
|
|
2
|
+
|
|
3
|
+
Keyboard-playable racing starter using only the public `@aura3d/engine` API.
|
|
4
|
+
|
|
5
|
+
Status: source-level prototype starter, not a public-quality racing game claim.
|
|
6
|
+
It proves input, route progress, checkpoints, lap/reset state, and deployable
|
|
7
|
+
source structure. It does not prove that an arbitrary track GLB has certified
|
|
8
|
+
road topology, car-to-road binding, camera-safe race composition, or public
|
|
9
|
+
visual quality.
|
|
10
|
+
|
|
11
|
+
- Typed vehicle and track assets are defined in `src/aura-assets.ts`.
|
|
12
|
+
- `game.racing(...)` owns route progress, throttle, steering, drift, checkpoint,
|
|
13
|
+
lap, reset, and camera proof state.
|
|
14
|
+
- `tests/playable.spec.ts` drives keyboard input and verifies checkpoint/lap
|
|
15
|
+
progression.
|
|
16
|
+
|
|
17
|
+
Run:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install
|
|
21
|
+
npm run dev
|
|
22
|
+
npm test
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Before presenting a generated racing route as a public example, add retained
|
|
26
|
+
racing topology evidence, prove the car is visibly bound to the road surface,
|
|
27
|
+
capture a readable public screenshot, and pass visual review.
|
|
@@ -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 Racing Starter</title>
|
|
7
|
+
<style>
|
|
8
|
+
html,
|
|
9
|
+
body,
|
|
10
|
+
#app {
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 100%;
|
|
13
|
+
margin: 0;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
background: #05090c;
|
|
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-racing-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 5178",
|
|
6
|
+
url: "http://127.0.0.1:5178",
|
|
7
|
+
reuseExistingServer: !process.env.CI
|
|
8
|
+
},
|
|
9
|
+
use: {
|
|
10
|
+
baseURL: "http://127.0.0.1:5178"
|
|
11
|
+
}
|
|
12
|
+
});
|
|
Binary file
|
|
@@ -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">showcaseCleanSportsCar 3.455x3.428x2.206</text></svg>
|
|
Binary file
|
|
@@ -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">showcaseReadableKartCircuit 24.651x24.647x2.073</text></svg>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { defineAuraAssets } from "@aura3d/engine";
|
|
2
|
+
|
|
3
|
+
export const assets = defineAuraAssets({
|
|
4
|
+
carModel: {
|
|
5
|
+
type: "model",
|
|
6
|
+
format: "glb",
|
|
7
|
+
url: "/aura-assets/showcaseCleanSportsCar.1c69283f.glb",
|
|
8
|
+
bounds: [3.455, 3.428, 2.206],
|
|
9
|
+
hash: "sha256-1c69283fa2b3fb96b3dc3418f2d0dede842e6984f1776a8ca00b099836fc9c14",
|
|
10
|
+
metadata: {
|
|
11
|
+
materials: ["Material.001", "Material.002", "Material.003", "Material.004"],
|
|
12
|
+
animations: [],
|
|
13
|
+
textures: [],
|
|
14
|
+
license: "CC-BY-4.0",
|
|
15
|
+
author: "JUFF",
|
|
16
|
+
sourcePage: "https://huggingface.co/datasets/allenai/objaverse/blob/main/glbs/000-008/23dfdeb55dc24970b36065afaab7a8a5.glb",
|
|
17
|
+
thumbnailUrl: "/aura-assets/showcaseCleanSportsCar.thumb.svg"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
trackModel: {
|
|
21
|
+
type: "model",
|
|
22
|
+
format: "glb",
|
|
23
|
+
url: "/aura-assets/showcaseReadableKartCircuit.5cbb912e.glb",
|
|
24
|
+
bounds: [24.651, 24.647, 2.073],
|
|
25
|
+
hash: "sha256-5cbb912e511e5e82363c347210096d59dd3007db12c363fd0c9f07919f5ebbd0",
|
|
26
|
+
metadata: {
|
|
27
|
+
materials: ["LINEAS", "gris", "verde", "rojo", "azul", "amarillo"],
|
|
28
|
+
animations: [],
|
|
29
|
+
textures: [],
|
|
30
|
+
license: "CC-BY-4.0",
|
|
31
|
+
author: "Puendiz",
|
|
32
|
+
sourcePage: "https://huggingface.co/datasets/allenai/objaverse/blob/main/glbs/000-034/2fc89fcd8c034bc9ba05eac24c9bf537.glb",
|
|
33
|
+
thumbnailUrl: "/aura-assets/showcaseReadableKartCircuit.thumb.svg"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
} as const);
|