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.
Files changed (226) hide show
  1. package/dist/cli.js +10 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +11 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/showcase-spec-artifacts.d.ts +104 -0
  8. package/dist/showcase-spec-artifacts.d.ts.map +1 -0
  9. package/dist/showcase-spec-artifacts.js +142 -0
  10. package/dist/showcase-spec-artifacts.js.map +1 -0
  11. package/dist/showcase-spec-category-plan.d.ts +15 -0
  12. package/dist/showcase-spec-category-plan.d.ts.map +1 -0
  13. package/dist/showcase-spec-category-plan.js +45 -0
  14. package/dist/showcase-spec-category-plan.js.map +1 -0
  15. package/dist/showcase-spec-compiler.d.ts +5 -0
  16. package/dist/showcase-spec-compiler.d.ts.map +1 -0
  17. package/dist/showcase-spec-compiler.js +240 -0
  18. package/dist/showcase-spec-compiler.js.map +1 -0
  19. package/dist/showcase-spec-evidence.d.ts +7 -0
  20. package/dist/showcase-spec-evidence.d.ts.map +1 -0
  21. package/dist/showcase-spec-evidence.js +815 -0
  22. package/dist/showcase-spec-evidence.js.map +1 -0
  23. package/dist/showcase-spec-game-geometry-extractor.d.ts +21 -0
  24. package/dist/showcase-spec-game-geometry-extractor.d.ts.map +1 -0
  25. package/dist/showcase-spec-game-geometry-extractor.js +725 -0
  26. package/dist/showcase-spec-game-geometry-extractor.js.map +1 -0
  27. package/dist/showcase-spec-game-replacement-evidence.d.ts +14 -0
  28. package/dist/showcase-spec-game-replacement-evidence.d.ts.map +1 -0
  29. package/dist/showcase-spec-game-replacement-evidence.js +219 -0
  30. package/dist/showcase-spec-game-replacement-evidence.js.map +1 -0
  31. package/dist/showcase-spec-game-template-evidence.d.ts +72 -0
  32. package/dist/showcase-spec-game-template-evidence.d.ts.map +1 -0
  33. package/dist/showcase-spec-game-template-evidence.js +435 -0
  34. package/dist/showcase-spec-game-template-evidence.js.map +1 -0
  35. package/dist/showcase-spec-gameplay-evidence.d.ts +3 -0
  36. package/dist/showcase-spec-gameplay-evidence.d.ts.map +1 -0
  37. package/dist/showcase-spec-gameplay-evidence.js +108 -0
  38. package/dist/showcase-spec-gameplay-evidence.js.map +1 -0
  39. package/dist/showcase-spec-parser.d.ts +3 -0
  40. package/dist/showcase-spec-parser.d.ts.map +1 -0
  41. package/dist/showcase-spec-parser.js +662 -0
  42. package/dist/showcase-spec-parser.js.map +1 -0
  43. package/dist/showcase-spec-platformer-artifacts.d.ts +3 -0
  44. package/dist/showcase-spec-platformer-artifacts.d.ts.map +1 -0
  45. package/dist/showcase-spec-platformer-artifacts.js +276 -0
  46. package/dist/showcase-spec-platformer-artifacts.js.map +1 -0
  47. package/dist/showcase-spec-racing-artifacts.d.ts +3 -0
  48. package/dist/showcase-spec-racing-artifacts.d.ts.map +1 -0
  49. package/dist/showcase-spec-racing-artifacts.js +273 -0
  50. package/dist/showcase-spec-racing-artifacts.js.map +1 -0
  51. package/dist/showcase-spec-replacement-apply.d.ts +10 -0
  52. package/dist/showcase-spec-replacement-apply.d.ts.map +1 -0
  53. package/dist/showcase-spec-replacement-apply.js +166 -0
  54. package/dist/showcase-spec-replacement-apply.js.map +1 -0
  55. package/dist/showcase-spec-replacement-candidates.d.ts +16 -0
  56. package/dist/showcase-spec-replacement-candidates.d.ts.map +1 -0
  57. package/dist/showcase-spec-replacement-candidates.js +244 -0
  58. package/dist/showcase-spec-replacement-candidates.js.map +1 -0
  59. package/dist/showcase-spec-replacement-game-geometry.d.ts +4 -0
  60. package/dist/showcase-spec-replacement-game-geometry.d.ts.map +1 -0
  61. package/dist/showcase-spec-replacement-game-geometry.js +175 -0
  62. package/dist/showcase-spec-replacement-game-geometry.js.map +1 -0
  63. package/dist/showcase-spec-replacement-manifest.d.ts +41 -0
  64. package/dist/showcase-spec-replacement-manifest.d.ts.map +1 -0
  65. package/dist/showcase-spec-replacement-manifest.js +62 -0
  66. package/dist/showcase-spec-replacement-manifest.js.map +1 -0
  67. package/dist/showcase-spec-replacement-values.d.ts +9 -0
  68. package/dist/showcase-spec-replacement-values.d.ts.map +1 -0
  69. package/dist/showcase-spec-replacement-values.js +41 -0
  70. package/dist/showcase-spec-replacement-values.js.map +1 -0
  71. package/dist/showcase-spec-replacement.d.ts +13 -0
  72. package/dist/showcase-spec-replacement.d.ts.map +1 -0
  73. package/dist/showcase-spec-replacement.js +144 -0
  74. package/dist/showcase-spec-replacement.js.map +1 -0
  75. package/dist/showcase-spec-types.d.ts +304 -0
  76. package/dist/showcase-spec-types.d.ts.map +1 -0
  77. package/dist/showcase-spec-types.js +2 -0
  78. package/dist/showcase-spec-types.js.map +1 -0
  79. package/package.json +21 -2
  80. package/templates/animation-channel/package.json +1 -1
  81. package/templates/animation-channel/tests/screenshot.spec.ts +16 -0
  82. package/templates/animation-studio/index.html +12 -0
  83. package/templates/animation-studio/node_modules.publish-aside/.vite/deps/_metadata.json +8 -0
  84. package/templates/animation-studio/node_modules.publish-aside/.vite/deps/package.json +3 -0
  85. package/templates/animation-studio/package.json +1 -1
  86. package/templates/animation-studio/scripts/animation-scene.ts +1 -1
  87. package/templates/animation-studio/scripts/asset-motion-probe.ts +7 -1
  88. package/templates/animation-studio/scripts/author-office-scene.ts +1 -1
  89. package/templates/animation-studio/scripts/build-characters.ts +1 -1
  90. package/templates/animation-studio/scripts/render-live.ts +24 -0
  91. package/templates/animation-studio/src/director/director-heuristics.ts +2 -2
  92. package/templates/animation-studio/src/director/{prompt-to-scene.ts → prompt-scene.ts} +74 -6
  93. package/templates/animation-studio/studio/src/App.tsx +146 -78
  94. package/templates/animation-studio/studio/src/components/Console.tsx +8 -2
  95. package/templates/animation-studio/studio/src/components/Inspector.tsx +57 -1
  96. package/templates/animation-studio/studio/src/components/Stage.tsx +10 -5
  97. package/templates/animation-studio/studio/src/components/Timeline.tsx +49 -2
  98. package/templates/animation-studio/studio/src/state/mapDocument.ts +13 -2
  99. package/templates/animation-studio/studio/src/state/sceneTool.ts +20 -9
  100. package/templates/animation-studio/studio/src/state/types.ts +8 -0
  101. package/templates/animation-studio/tests/route-health.spec.ts +33 -0
  102. package/templates/animation-studio/tests/screenshot.spec.ts +30 -0
  103. package/templates/character-controller/package.json +1 -1
  104. package/templates/character-controller/src/main.ts +18 -1
  105. package/templates/cinematic-scene/package.json +1 -1
  106. package/templates/cinematic-scene/tests/screenshot.spec.ts +3 -3
  107. package/templates/episode-builder/package.json +1 -1
  108. package/templates/episode-builder/tests/screenshot.spec.ts +15 -0
  109. package/templates/falling-blocks-starter/README.md +18 -0
  110. package/templates/falling-blocks-starter/index.html +23 -0
  111. package/templates/falling-blocks-starter/package.json +21 -0
  112. package/templates/falling-blocks-starter/playwright.config.ts +12 -0
  113. package/templates/falling-blocks-starter/public/aura-assets/showcaseBlockfallCabinet.679d52fe.glb +0 -0
  114. package/templates/falling-blocks-starter/public/aura-assets/showcaseBlockfallCabinet.thumb.svg +1 -0
  115. package/templates/falling-blocks-starter/src/aura-assets.ts +20 -0
  116. package/templates/falling-blocks-starter/src/main.ts +358 -0
  117. package/templates/falling-blocks-starter/tests/playable.spec.ts +85 -0
  118. package/templates/falling-blocks-starter/tests/route-health.spec.ts +34 -0
  119. package/templates/falling-blocks-starter/tsconfig.json +13 -0
  120. package/templates/fighting-game/package.json +1 -1
  121. package/templates/fighting-game/tests/screenshot.spec.ts +15 -0
  122. package/templates/mini-game/README.md +13 -0
  123. package/templates/mini-game/index.html +1 -1
  124. package/templates/mini-game/package.json +2 -2
  125. package/templates/mini-game/src/main.ts +251 -21
  126. package/templates/mini-game/tests/playable.spec.ts +49 -0
  127. package/templates/mini-game/tests/screenshot.spec.ts +37 -32
  128. package/templates/product-viewer/package.json +1 -1
  129. package/templates/product-viewer/tests/screenshot.spec.ts +4 -4
  130. package/templates/prompt-animation-channel/package.json +1 -1
  131. package/templates/prompt-animation-channel/tests/screenshot.spec.ts +15 -0
  132. package/templates/racing-starter/README.md +27 -0
  133. package/templates/racing-starter/index.html +23 -0
  134. package/templates/racing-starter/package.json +21 -0
  135. package/templates/racing-starter/playwright.config.ts +12 -0
  136. package/templates/racing-starter/public/aura-assets/showcaseCleanSportsCar.1c69283f.glb +0 -0
  137. package/templates/racing-starter/public/aura-assets/showcaseCleanSportsCar.thumb.svg +1 -0
  138. package/templates/racing-starter/public/aura-assets/showcaseReadableKartCircuit.5cbb912e.glb +0 -0
  139. package/templates/racing-starter/public/aura-assets/showcaseReadableKartCircuit.thumb.svg +1 -0
  140. package/templates/racing-starter/src/aura-assets.ts +36 -0
  141. package/templates/racing-starter/src/main.ts +280 -0
  142. package/templates/racing-starter/tests/playable.spec.ts +93 -0
  143. package/templates/racing-starter/tests/route-health.spec.ts +40 -0
  144. package/templates/racing-starter/tsconfig.json +13 -0
  145. package/templates/three-compat-architecture-interior/index.html +16 -0
  146. package/templates/three-compat-architecture-interior/package.json +21 -0
  147. package/templates/three-compat-architecture-interior/playwright.config.ts +14 -0
  148. package/templates/three-compat-architecture-interior/src/main.ts +27 -0
  149. package/templates/three-compat-architecture-interior/tests/route-health.spec.ts +16 -0
  150. package/templates/three-compat-architecture-interior/tests/screenshot.spec.ts +15 -0
  151. package/templates/three-compat-architecture-interior/tsconfig.json +19 -0
  152. package/templates/three-compat-asset-inspector/index.html +16 -0
  153. package/templates/three-compat-asset-inspector/package.json +21 -0
  154. package/templates/three-compat-asset-inspector/playwright.config.ts +14 -0
  155. package/templates/three-compat-asset-inspector/src/main.ts +17 -0
  156. package/templates/three-compat-asset-inspector/tests/route-health.spec.ts +16 -0
  157. package/templates/three-compat-asset-inspector/tests/screenshot.spec.ts +15 -0
  158. package/templates/three-compat-asset-inspector/tsconfig.json +19 -0
  159. package/templates/three-compat-character-viewer/index.html +16 -0
  160. package/templates/three-compat-character-viewer/package.json +21 -0
  161. package/templates/three-compat-character-viewer/playwright.config.ts +14 -0
  162. package/templates/three-compat-character-viewer/src/main.ts +17 -0
  163. package/templates/three-compat-character-viewer/tests/route-health.spec.ts +16 -0
  164. package/templates/three-compat-character-viewer/tests/screenshot.spec.ts +15 -0
  165. package/templates/three-compat-character-viewer/tsconfig.json +19 -0
  166. package/templates/three-compat-custom-threejs-migration/index.html +16 -0
  167. package/templates/three-compat-custom-threejs-migration/package.json +21 -0
  168. package/templates/three-compat-custom-threejs-migration/playwright.config.ts +14 -0
  169. package/templates/three-compat-custom-threejs-migration/src/main.ts +16 -0
  170. package/templates/three-compat-custom-threejs-migration/tests/route-health.spec.ts +16 -0
  171. package/templates/three-compat-custom-threejs-migration/tests/screenshot.spec.ts +15 -0
  172. package/templates/three-compat-custom-threejs-migration/tsconfig.json +19 -0
  173. package/templates/three-compat-large-scene/index.html +16 -0
  174. package/templates/three-compat-large-scene/package.json +21 -0
  175. package/templates/three-compat-large-scene/playwright.config.ts +14 -0
  176. package/templates/three-compat-large-scene/src/main.ts +31 -0
  177. package/templates/three-compat-large-scene/tests/route-health.spec.ts +16 -0
  178. package/templates/three-compat-large-scene/tests/screenshot.spec.ts +15 -0
  179. package/templates/three-compat-large-scene/tsconfig.json +19 -0
  180. package/templates/three-compat-material-authoring/index.html +16 -0
  181. package/templates/three-compat-material-authoring/package.json +21 -0
  182. package/templates/three-compat-material-authoring/playwright.config.ts +14 -0
  183. package/templates/three-compat-material-authoring/src/main.ts +33 -0
  184. package/templates/three-compat-material-authoring/tests/route-health.spec.ts +16 -0
  185. package/templates/three-compat-material-authoring/tests/screenshot.spec.ts +15 -0
  186. package/templates/three-compat-material-authoring/tsconfig.json +19 -0
  187. package/templates/three-compat-postprocess-scene/index.html +16 -0
  188. package/templates/three-compat-postprocess-scene/package.json +21 -0
  189. package/templates/three-compat-postprocess-scene/playwright.config.ts +14 -0
  190. package/templates/three-compat-postprocess-scene/src/main.ts +17 -0
  191. package/templates/three-compat-postprocess-scene/tests/route-health.spec.ts +16 -0
  192. package/templates/three-compat-postprocess-scene/tests/screenshot.spec.ts +15 -0
  193. package/templates/three-compat-postprocess-scene/tsconfig.json +19 -0
  194. package/templates/three-compat-premium-product-viewer/index.html +16 -0
  195. package/templates/three-compat-premium-product-viewer/package.json +21 -0
  196. package/templates/three-compat-premium-product-viewer/playwright.config.ts +14 -0
  197. package/templates/three-compat-premium-product-viewer/src/main.ts +18 -0
  198. package/templates/three-compat-premium-product-viewer/tests/route-health.spec.ts +16 -0
  199. package/templates/three-compat-premium-product-viewer/tests/screenshot.spec.ts +15 -0
  200. package/templates/three-compat-premium-product-viewer/tsconfig.json +19 -0
  201. package/templates/animation-channel/public/aura-assets/moon-garden-feature-frame.png +0 -0
  202. package/templates/animation-channel/tests/reports/prompt-animation/cartoon-sample-episode.png +0 -0
  203. package/templates/animation-studio/dist/episodes/scene/episode-3d.webm +0 -0
  204. package/templates/animation-studio/dist/episodes/scene/frames/action.png +0 -0
  205. package/templates/animation-studio/dist/episodes/scene/frames/dialogue.png +0 -0
  206. package/templates/animation-studio/dist/episodes/scene/frames/final.png +0 -0
  207. package/templates/animation-studio/dist/episodes/scene/frames/first.png +0 -0
  208. package/templates/animation-studio/dist/episodes/scene/frames/mouth-closed.png +0 -0
  209. package/templates/animation-studio/dist/episodes/scene/frames/mouth-open.png +0 -0
  210. package/templates/animation-studio/dist/episodes/scene/render-live-summary.json +0 -5616
  211. package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/broken.png +0 -0
  212. package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/chefs.png +0 -0
  213. package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/customer.png +0 -0
  214. package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/worker-1.png +0 -0
  215. package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/worker-2.png +0 -0
  216. package/templates/animation-studio/dist/generated/second-scene.document.json +0 -1210
  217. package/templates/animation-studio/dist/generated/studio-edited.document.json +0 -1196
  218. package/templates/animation-studio/dist/scene/inshader-accept.document.json +0 -1
  219. package/templates/animation-studio/dist/scene/inshader-test.document.json +0 -1
  220. package/templates/animation-studio/dist/scene/integ.document.json +0 -1
  221. package/templates/animation-studio/dist/scene/working.document.json +0 -594
  222. package/templates/animation-studio/dist/scene/working.history.json +0 -1
  223. package/templates/animation-studio/studio/dist/assets/index-i8URxOOt.css +0 -1
  224. package/templates/animation-studio/studio/dist/assets/index-pC9hdZ-B.js +0 -11
  225. package/templates/animation-studio/studio/dist/index.html +0 -19
  226. package/templates/animation-studio/tests/reports/animation-studio/hifi-cast-validation.json +0 -938
@@ -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 three-compat template 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,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "allowJs": false,
8
+ "skipLibCheck": true,
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "strict": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "moduleResolution": "Bundler",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true
17
+ },
18
+ "include": ["src", "tests"]
19
+ }
@@ -0,0 +1,16 @@
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 Three-Compat Character Viewer</title>
7
+ <style>
8
+ html, body, #app { margin: 0; width: 100%; height: 100%; background: #080d15; }
9
+ body { font-family: Inter, ui-sans-serif, system-ui, sans-serif; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="app"></div>
14
+ <script type="module" src="/src/main.ts"></script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "aura3d-three-compat-character-viewer",
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/route-health.spec.ts tests/screenshot.spec.ts --workers=1"
12
+ },
13
+ "dependencies": {
14
+ "@aura3d/engine": "1.3.3"
15
+ },
16
+ "devDependencies": {
17
+ "@playwright/test": "^1.52.0",
18
+ "typescript": "^5.8.3",
19
+ "vite": "^7.3.2"
20
+ }
21
+ }
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from "@playwright/test";
2
+
3
+ export default defineConfig({
4
+ testDir: "./tests",
5
+ use: {
6
+ baseURL: "http://127.0.0.1:4193"
7
+ },
8
+ webServer: {
9
+ command: "npm exec vite -- --host 127.0.0.1 --port 4193 --strictPort",
10
+ url: "http://127.0.0.1:4193",
11
+ reuseExistingServer: !process.env.CI,
12
+ timeout: 120_000
13
+ }
14
+ });
@@ -0,0 +1,17 @@
1
+ // Three-compat character viewer: a capsule stand-in character on a pedestal,
2
+ // authored through the public @aura3d/engine API. Replace the capsule with
3
+ // `model(assets.character)` once you add a typed character asset.
4
+ import { camera, createAuraApp, lights, material, primitives, scene } from "@aura3d/engine";
5
+
6
+ createAuraApp("#app", {
7
+ scene: scene()
8
+ .background("#0d1119")
9
+ .camera(camera.orbit({ target: [0, 1.2, 0], distance: 4.6 }))
10
+ .add(primitives.box({ name: "viewer floor", size: [5, 0.1, 5], position: [0, -0.05, 0], material: material.pbr({ color: "#161d2a", roughness: 0.92 }), receiveShadow: true }))
11
+ .add(primitives.cylinder({ name: "character pedestal", size: [1.4, 0.3, 1.4], position: [0, 0.15, 0], material: material.pbr({ color: "#2b3548", roughness: 0.55, metalness: 0.2 }), receiveShadow: true, castShadow: true }))
12
+ .add(primitives.capsule({ name: "stand-in character", size: [0.7, 1.7, 0.7], position: [0, 1.25, 0], material: material.pbr({ color: "#7fa6d9", roughness: 0.45 }), castShadow: true }))
13
+ .add(primitives.sphere({ name: "stand-in head marker", size: 0.3, position: [0, 2.25, 0], material: material.pbr({ color: "#d9c79f", roughness: 0.5 }), castShadow: true }))
14
+ .add(lights.ambient({ intensity: 0.32 }))
15
+ .add(lights.directional({ name: "key light", position: [3, 4.5, 3], intensity: 1.5 }))
16
+ .add(lights.point({ name: "rim light", position: [-2.4, 2.6, -2.2], intensity: 1.5, color: "#8fb8ff" }))
17
+ });
@@ -0,0 +1,16 @@
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 three-compat template reaches ready state", async ({ page }) => {
8
+ await page.goto("/");
9
+ await expect.poll(() => page.locator("body").getAttribute("data-aura3d-ready"), { timeout: 45_000 }).toBe("true");
10
+ const drawCalls = Number(await page.locator("body").getAttribute("data-aura3d-draw-calls"));
11
+ const diagnostics = await page.evaluate(() => (window as unknown as { __AURA3D_ROUTE_READY__?: { diagnostics?: { backend?: string } } }).__AURA3D_ROUTE_READY__?.diagnostics);
12
+ expect(diagnostics?.backend).toBe("webgl2");
13
+ expect(drawCalls).toBeGreaterThan(0);
14
+ mkdirSync(resolve("tests/reports"), { recursive: true });
15
+ writeFileSync(resolve("tests/reports/route-health.json"), `${JSON.stringify({ ready: true, backend: diagnostics?.backend, drawCalls }, null, 2)}\n`);
16
+ });
@@ -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 three-compat template 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,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "allowJs": false,
8
+ "skipLibCheck": true,
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "strict": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "moduleResolution": "Bundler",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true
17
+ },
18
+ "include": ["src", "tests"]
19
+ }
@@ -0,0 +1,16 @@
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 Three-Compat Custom Three.js Migration</title>
7
+ <style>
8
+ html, body, #app { margin: 0; width: 100%; height: 100%; background: #080d15; }
9
+ body { font-family: Inter, ui-sans-serif, system-ui, sans-serif; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="app"></div>
14
+ <script type="module" src="/src/main.ts"></script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "aura3d-three-compat-custom-threejs-migration",
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/route-health.spec.ts tests/screenshot.spec.ts --workers=1"
12
+ },
13
+ "dependencies": {
14
+ "@aura3d/engine": "1.3.3"
15
+ },
16
+ "devDependencies": {
17
+ "@playwright/test": "^1.52.0",
18
+ "typescript": "^5.8.3",
19
+ "vite": "^7.3.2"
20
+ }
21
+ }
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from "@playwright/test";
2
+
3
+ export default defineConfig({
4
+ testDir: "./tests",
5
+ use: {
6
+ baseURL: "http://127.0.0.1:4194"
7
+ },
8
+ webServer: {
9
+ command: "npm exec vite -- --host 127.0.0.1 --port 4194 --strictPort",
10
+ url: "http://127.0.0.1:4194",
11
+ reuseExistingServer: !process.env.CI,
12
+ timeout: 120_000
13
+ }
14
+ });
@@ -0,0 +1,16 @@
1
+ // Three-compat migration example: the classic hand-rolled three.js starter
2
+ // (ground plane + a few lit primitives) rebuilt with the public
3
+ // @aura3d/engine API — no manual renderer, scene graph, or render loop.
4
+ import { camera, createAuraApp, lights, material, primitives, scene } from "@aura3d/engine";
5
+
6
+ createAuraApp("#app", {
7
+ scene: scene()
8
+ .background("#101521")
9
+ .camera(camera.orbit({ target: [0, 0.7, 0], distance: 6 }))
10
+ .add(primitives.plane({ name: "ground", size: [10, 1, 10], material: material.pbr({ color: "#1b2334", roughness: 0.9 }), receiveShadow: true }))
11
+ .add(primitives.box({ name: "migrated box mesh", size: 1, position: [-1.6, 0.5, 0], rotation: [0, 0.6, 0], material: material.pbr({ color: "#e2674a", roughness: 0.5 }), castShadow: true }))
12
+ .add(primitives.sphere({ name: "migrated sphere mesh", size: 1.1, position: [0.2, 0.55, -0.4], material: material.metal({ color: "#bcd0e6", roughness: 0.18 }), castShadow: true }))
13
+ .add(primitives.torus({ name: "migrated torus mesh", size: 0.9, position: [1.9, 0.75, 0.6], rotation: [0.9, 0, 0.4], material: material.pbr({ color: "#5dbb8d", roughness: 0.4 }), castShadow: true }))
14
+ .add(lights.ambient({ intensity: 0.3 }))
15
+ .add(lights.directional({ name: "sun", position: [4, 6, 3], intensity: 1.5 }))
16
+ });
@@ -0,0 +1,16 @@
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 three-compat template reaches ready state", async ({ page }) => {
8
+ await page.goto("/");
9
+ await expect.poll(() => page.locator("body").getAttribute("data-aura3d-ready"), { timeout: 45_000 }).toBe("true");
10
+ const drawCalls = Number(await page.locator("body").getAttribute("data-aura3d-draw-calls"));
11
+ const diagnostics = await page.evaluate(() => (window as unknown as { __AURA3D_ROUTE_READY__?: { diagnostics?: { backend?: string } } }).__AURA3D_ROUTE_READY__?.diagnostics);
12
+ expect(diagnostics?.backend).toBe("webgl2");
13
+ expect(drawCalls).toBeGreaterThan(0);
14
+ mkdirSync(resolve("tests/reports"), { recursive: true });
15
+ writeFileSync(resolve("tests/reports/route-health.json"), `${JSON.stringify({ ready: true, backend: diagnostics?.backend, drawCalls }, null, 2)}\n`);
16
+ });
@@ -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 three-compat template 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,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "allowJs": false,
8
+ "skipLibCheck": true,
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "strict": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "moduleResolution": "Bundler",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true
17
+ },
18
+ "include": ["src", "tests"]
19
+ }
@@ -0,0 +1,16 @@
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 Three-Compat Large Scene</title>
7
+ <style>
8
+ html, body, #app { margin: 0; width: 100%; height: 100%; background: #080d15; }
9
+ body { font-family: Inter, ui-sans-serif, system-ui, sans-serif; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="app"></div>
14
+ <script type="module" src="/src/main.ts"></script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "aura3d-three-compat-large-scene",
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/route-health.spec.ts tests/screenshot.spec.ts --workers=1"
12
+ },
13
+ "dependencies": {
14
+ "@aura3d/engine": "1.3.3"
15
+ },
16
+ "devDependencies": {
17
+ "@playwright/test": "^1.52.0",
18
+ "typescript": "^5.8.3",
19
+ "vite": "^7.3.2"
20
+ }
21
+ }
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from "@playwright/test";
2
+
3
+ export default defineConfig({
4
+ testDir: "./tests",
5
+ use: {
6
+ baseURL: "http://127.0.0.1:4195"
7
+ },
8
+ webServer: {
9
+ command: "npm exec vite -- --host 127.0.0.1 --port 4195 --strictPort",
10
+ url: "http://127.0.0.1:4195",
11
+ reuseExistingServer: !process.env.CI,
12
+ timeout: 120_000
13
+ }
14
+ });
@@ -0,0 +1,31 @@
1
+ // Three-compat large scene: a deterministic grid of many boxes (a city-block
2
+ // style stress layout) authored through the public @aura3d/engine API.
3
+ import { camera, createAuraApp, lights, material, primitives, scene } from "@aura3d/engine";
4
+
5
+ const palette = ["#39465e", "#46587a", "#54688f", "#62799f", "#4d5a74"] as const;
6
+ const grid = scene()
7
+ .background("#0a0e15")
8
+ .camera(camera.orbit({ target: [0, 1, 0], distance: 16 }))
9
+ .add(primitives.box({ name: "large scene ground", size: [22, 0.1, 22], position: [0, -0.05, 0], material: material.pbr({ color: "#141b28", roughness: 0.95 }), receiveShadow: true }));
10
+
11
+ const span = 9; // 9 x 9 = 81 boxes
12
+ for (let row = 0; row < span; row += 1) {
13
+ for (let col = 0; col < span; col += 1) {
14
+ const index = row * span + col;
15
+ const height = 0.5 + ((index * 37) % 23) / 23 * 2.6;
16
+ grid.add(primitives.box({
17
+ name: `block r${row} c${col}`,
18
+ size: [1.1, height, 1.1],
19
+ position: [(col - (span - 1) / 2) * 2.2, height / 2, (row - (span - 1) / 2) * 2.2],
20
+ material: material.pbr({ color: palette[index % palette.length], roughness: 0.62 }),
21
+ castShadow: true,
22
+ receiveShadow: true
23
+ }));
24
+ }
25
+ }
26
+
27
+ grid
28
+ .add(lights.ambient({ intensity: 0.3 }))
29
+ .add(lights.directional({ name: "low sun", position: [8, 10, 6], intensity: 1.4, color: "#ffe7c8" }));
30
+
31
+ createAuraApp("#app", { scene: grid });
@@ -0,0 +1,16 @@
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 three-compat template reaches ready state", async ({ page }) => {
8
+ await page.goto("/");
9
+ await expect.poll(() => page.locator("body").getAttribute("data-aura3d-ready"), { timeout: 45_000 }).toBe("true");
10
+ const drawCalls = Number(await page.locator("body").getAttribute("data-aura3d-draw-calls"));
11
+ const diagnostics = await page.evaluate(() => (window as unknown as { __AURA3D_ROUTE_READY__?: { diagnostics?: { backend?: string } } }).__AURA3D_ROUTE_READY__?.diagnostics);
12
+ expect(diagnostics?.backend).toBe("webgl2");
13
+ expect(drawCalls).toBeGreaterThan(0);
14
+ mkdirSync(resolve("tests/reports"), { recursive: true });
15
+ writeFileSync(resolve("tests/reports/route-health.json"), `${JSON.stringify({ ready: true, backend: diagnostics?.backend, drawCalls }, null, 2)}\n`);
16
+ });
@@ -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 three-compat template 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,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "allowJs": false,
8
+ "skipLibCheck": true,
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "strict": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "moduleResolution": "Bundler",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true
17
+ },
18
+ "include": ["src", "tests"]
19
+ }
@@ -0,0 +1,16 @@
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 Three-Compat Material Authoring</title>
7
+ <style>
8
+ html, body, #app { margin: 0; width: 100%; height: 100%; background: #080d15; }
9
+ body { font-family: Inter, ui-sans-serif, system-ui, sans-serif; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="app"></div>
14
+ <script type="module" src="/src/main.ts"></script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "aura3d-three-compat-material-authoring",
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/route-health.spec.ts tests/screenshot.spec.ts --workers=1"
12
+ },
13
+ "dependencies": {
14
+ "@aura3d/engine": "1.3.3"
15
+ },
16
+ "devDependencies": {
17
+ "@playwright/test": "^1.52.0",
18
+ "typescript": "^5.8.3",
19
+ "vite": "^7.3.2"
20
+ }
21
+ }
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from "@playwright/test";
2
+
3
+ export default defineConfig({
4
+ testDir: "./tests",
5
+ use: {
6
+ baseURL: "http://127.0.0.1:4196"
7
+ },
8
+ webServer: {
9
+ command: "npm exec vite -- --host 127.0.0.1 --port 4196 --strictPort",
10
+ url: "http://127.0.0.1:4196",
11
+ reuseExistingServer: !process.env.CI,
12
+ timeout: 120_000
13
+ }
14
+ });
@@ -0,0 +1,33 @@
1
+ // Three-compat material authoring: a row of spheres showcasing the public
2
+ // @aura3d/engine material presets (pbr, metal, rubber, glass, emissive).
3
+ import { camera, createAuraApp, lights, material, primitives, scene } from "@aura3d/engine";
4
+
5
+ const swatches = [
6
+ { name: "pbr swatch", material: material.pbr({ color: "#c66f53", roughness: 0.55 }) },
7
+ { name: "metal swatch", material: material.metal({ color: "#d7e1ec", roughness: 0.12 }) },
8
+ { name: "rubber swatch", material: material.rubber({ color: "#22262e" }) },
9
+ { name: "glass swatch", material: material.glass({ color: "#bfe6ff" }) },
10
+ { name: "emissive swatch", material: material.emissive({ color: "#13202c", emissive: "#38d6ff", emissiveIntensity: 1.2 }) }
11
+ ] as const;
12
+
13
+ const lab = scene()
14
+ .background("#0c1018")
15
+ .camera(camera.orbit({ target: [0, 0.7, 0], distance: 6.4 }))
16
+ .add(primitives.box({ name: "swatch bench", size: [7, 0.12, 2.4], position: [0, -0.06, 0], material: material.pbr({ color: "#1c2433", roughness: 0.88 }), receiveShadow: true }));
17
+
18
+ swatches.forEach((swatch, index) => {
19
+ lab.add(primitives.sphere({
20
+ name: swatch.name,
21
+ size: 0.9,
22
+ position: [(index - (swatches.length - 1) / 2) * 1.35, 0.65, 0],
23
+ material: swatch.material,
24
+ castShadow: true
25
+ }));
26
+ });
27
+
28
+ lab
29
+ .add(lights.ambient({ intensity: 0.3 }))
30
+ .add(lights.directional({ name: "key", position: [3, 4.5, 3.5], intensity: 1.5 }))
31
+ .add(lights.point({ name: "cool rim", position: [-3, 2.4, -2.4], intensity: 1.3, color: "#9fc4ff" }));
32
+
33
+ createAuraApp("#app", { scene: lab });
@@ -0,0 +1,16 @@
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 three-compat template reaches ready state", async ({ page }) => {
8
+ await page.goto("/");
9
+ await expect.poll(() => page.locator("body").getAttribute("data-aura3d-ready"), { timeout: 45_000 }).toBe("true");
10
+ const drawCalls = Number(await page.locator("body").getAttribute("data-aura3d-draw-calls"));
11
+ const diagnostics = await page.evaluate(() => (window as unknown as { __AURA3D_ROUTE_READY__?: { diagnostics?: { backend?: string } } }).__AURA3D_ROUTE_READY__?.diagnostics);
12
+ expect(diagnostics?.backend).toBe("webgl2");
13
+ expect(drawCalls).toBeGreaterThan(0);
14
+ mkdirSync(resolve("tests/reports"), { recursive: true });
15
+ writeFileSync(resolve("tests/reports/route-health.json"), `${JSON.stringify({ ready: true, backend: diagnostics?.backend, drawCalls }, null, 2)}\n`);
16
+ });
@@ -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 three-compat template 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,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "allowJs": false,
8
+ "skipLibCheck": true,
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "strict": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "moduleResolution": "Bundler",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true
17
+ },
18
+ "include": ["src", "tests"]
19
+ }
@@ -0,0 +1,16 @@
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 Three-Compat Postprocess Scene</title>
7
+ <style>
8
+ html, body, #app { margin: 0; width: 100%; height: 100%; background: #080d15; }
9
+ body { font-family: Inter, ui-sans-serif, system-ui, sans-serif; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="app"></div>
14
+ <script type="module" src="/src/main.ts"></script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "aura3d-three-compat-postprocess-scene",
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/route-health.spec.ts tests/screenshot.spec.ts --workers=1"
12
+ },
13
+ "dependencies": {
14
+ "@aura3d/engine": "1.3.3"
15
+ },
16
+ "devDependencies": {
17
+ "@playwright/test": "^1.52.0",
18
+ "typescript": "^5.8.3",
19
+ "vite": "^7.3.2"
20
+ }
21
+ }
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from "@playwright/test";
2
+
3
+ export default defineConfig({
4
+ testDir: "./tests",
5
+ use: {
6
+ baseURL: "http://127.0.0.1:4197"
7
+ },
8
+ webServer: {
9
+ command: "npm exec vite -- --host 127.0.0.1 --port 4197 --strictPort",
10
+ url: "http://127.0.0.1:4197",
11
+ reuseExistingServer: !process.env.CI,
12
+ timeout: 120_000
13
+ }
14
+ });