create-aura3d 1.1.1 → 1.3.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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/package.json +11 -9
- package/templates/{cartoon-channel → animation-channel}/README.md +20 -10
- package/templates/{cartoon-studio → animation-channel}/index.html +1 -1
- package/templates/{cartoon-channel → animation-channel}/package.json +2 -2
- package/templates/{cartoon-channel → animation-channel}/src/episode.ts +22 -22
- package/templates/animation-channel/src/experimental/README.md +24 -0
- package/templates/{cartoon-channel/src → animation-channel/src/experimental}/concept-episode-2-5d.css +3 -3
- package/templates/{cartoon-channel/src → animation-channel/src/experimental}/concept-episode-2-5d.ts +8 -8
- package/templates/{cartoon-channel/src → animation-channel/src/experimental}/image-puppet-episode.css +4 -4
- package/templates/{cartoon-channel/src → animation-channel/src/experimental}/image-puppet-episode.ts +7 -7
- package/templates/{cartoon-channel/src → animation-channel/src/experimental}/puppet-episode-2d.css +3 -3
- package/templates/{cartoon-channel/src → animation-channel/src/experimental}/puppet-episode-2d.ts +8 -8
- package/templates/{cartoon-channel → animation-channel}/src/main.ts +32 -32
- package/templates/{cartoon-channel → animation-channel}/src/render-plan.ts +13 -13
- package/templates/{cartoon-channel → animation-channel}/src/sample-episode-visual.css +34 -34
- package/templates/{cartoon-channel → animation-channel}/src/sample-episode-visual.ts +20 -20
- package/templates/{cartoon-channel → animation-channel}/tests/concept-2-5d-animation.spec.ts +3 -3
- package/templates/{cartoon-channel → animation-channel}/tests/concept-2-5d.spec.ts +6 -6
- package/templates/{cartoon-channel → animation-channel}/tests/image-puppet-animation.spec.ts +3 -3
- package/templates/{cartoon-channel → animation-channel}/tests/image-puppet.spec.ts +5 -5
- package/templates/{cartoon-channel → animation-channel}/tests/puppet-2d-animation.spec.ts +3 -3
- package/templates/{cartoon-channel → animation-channel}/tests/puppet-2d.spec.ts +4 -4
- package/templates/{prompt-cartoon-channel → animation-channel}/tests/route-health.spec.ts +1 -1
- package/templates/{cartoon-channel → animation-channel}/tests/sample-episode-visual.spec.ts +5 -5
- package/templates/{cartoon-channel → animation-channel}/tests/storyboard-playback.spec.ts +7 -7
- package/templates/animation-studio/AGENTS.md +71 -0
- package/templates/animation-studio/ASSET-LICENSES.md +41 -0
- package/templates/{cartoon-studio → animation-studio}/README.md +6 -6
- package/templates/animation-studio/aura.assets.json +669 -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 +10284 -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 +1210 -0
- package/templates/animation-studio/dist/generated/studio-edited.document.json +1196 -0
- package/templates/animation-studio/dist/scene/inshader-accept.document.json +1 -0
- package/templates/animation-studio/dist/scene/inshader-test.document.json +1 -0
- package/templates/animation-studio/dist/scene/integ.document.json +1 -0
- package/templates/animation-studio/dist/scene/working.document.json +723 -0
- package/templates/animation-studio/dist/scene/working.history.json +1 -0
- package/templates/{cartoon-channel/index.html → animation-studio/live-route.html} +3 -4
- package/templates/{cartoon-studio → animation-studio}/package-lock.json +2 -2
- package/templates/animation-studio/package.json +32 -0
- package/templates/animation-studio/public/aura-assets/cast-a.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/cast-b.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/luma.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/luma2.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/miko.catalog.glb +0 -0
- package/templates/{cartoon-studio → animation-studio}/public/aura-assets/moonGarden.gltf +1 -1
- package/templates/animation-studio/public/aura-assets/mushroom.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/rusty.catalog.glb +0 -0
- package/templates/animation-studio/public/cast-library/cast-library.json +71 -0
- package/templates/animation-studio/public/clip-library/gesture.json +173903 -0
- package/templates/animation-studio/public/clip-library/idle.json +23035 -0
- package/templates/animation-studio/public/clip-library/manifest.json +154 -0
- package/templates/animation-studio/public/clip-library/nod.json +173903 -0
- package/templates/animation-studio/public/clip-library/point.json +69879 -0
- package/templates/animation-studio/public/clip-library/react.json +66084 -0
- package/templates/animation-studio/public/clip-library/run.json +9648 -0
- package/templates/animation-studio/public/clip-library/talk.json +69879 -0
- package/templates/animation-studio/public/clip-library/walk.json +8283 -0
- package/templates/animation-studio/public/hifi-cast/BrainStem.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/CesiumMan.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/RiggedFigure.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Barbarian.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Knight.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Mage.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Rogue.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Rogue_Hooded.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/khronos-report.json +295 -0
- package/templates/animation-studio/public/hifi-cast/quaternius-report.json +449 -0
- package/templates/animation-studio/public/hifi-cast/rpm/cesiumman.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/rpm/fox.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/rpm/riggedfigure.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/rpm-report.json +301 -0
- package/templates/animation-studio/scripts/anim.ts +103 -0
- package/templates/animation-studio/scripts/animation-scene.ts +457 -0
- package/templates/animation-studio/scripts/asset-motion-probe.ts +450 -0
- package/templates/animation-studio/scripts/asset-render-probe.ts +152 -0
- package/templates/animation-studio/scripts/author-office-scene.ts +65 -0
- package/templates/animation-studio/scripts/build-cast-library.ts +97 -0
- package/templates/animation-studio/scripts/build-characters.ts +1543 -0
- package/templates/animation-studio/scripts/build-clip-library.ts +972 -0
- package/templates/animation-studio/scripts/clip-decision-cli.ts +51 -0
- package/templates/animation-studio/scripts/determinism-check.ts +48 -0
- package/templates/animation-studio/scripts/generate-scene.ts +95 -0
- package/templates/animation-studio/scripts/hifi-cast-validate.ts +572 -0
- package/templates/animation-studio/scripts/motion-evidence-cli.ts +150 -0
- package/templates/animation-studio/scripts/motion-evidence.ts +362 -0
- package/templates/animation-studio/scripts/preview-server.ts +52 -0
- package/templates/animation-studio/scripts/regen-manifest.ts +156 -0
- package/templates/animation-studio/scripts/render-core.ts +360 -0
- package/templates/animation-studio/scripts/render-live.ts +813 -0
- package/templates/animation-studio/scripts/render-parallel.ts +70 -0
- package/templates/animation-studio/scripts/render-server.ts +119 -0
- package/templates/animation-studio/scripts/resolve-asset.ts +669 -0
- package/templates/animation-studio/scripts/skeleton-overlay-cli.ts +82 -0
- package/templates/animation-studio/scripts/skeleton-overlay.ts +293 -0
- package/templates/animation-studio/scripts/studio-tools-demo.ts +45 -0
- package/templates/animation-studio/scripts/texture-bake.ts +297 -0
- package/templates/animation-studio/scripts/validate-characters.ts +0 -0
- package/templates/animation-studio/scripts/verify-extracted-overlay-cli.ts +264 -0
- package/templates/animation-studio/src/animation-episode-validator.ts +97 -0
- package/templates/animation-studio/src/animation-performance.ts +556 -0
- package/templates/animation-studio/src/aura-assets.ts +71 -0
- package/templates/animation-studio/src/character.ts +40 -0
- package/templates/animation-studio/src/director/compile-episode-document.ts +45 -0
- package/templates/animation-studio/src/director/director-heuristics.ts +697 -0
- package/templates/animation-studio/src/director/prompt-to-scene.ts +369 -0
- package/templates/animation-studio/src/empty-document.ts +77 -0
- package/templates/animation-studio/src/episode-document.ts +442 -0
- package/templates/animation-studio/src/examples/moon-garden.example.ts +183 -0
- package/templates/animation-studio/src/fidelity.ts +129 -0
- package/templates/animation-studio/src/graph.ts +14 -0
- package/templates/animation-studio/src/procedural-hdri.ts +243 -0
- package/templates/animation-studio/src/profile.ts +97 -0
- package/templates/animation-studio/src/render-live-route.ts +42 -0
- package/templates/animation-studio/src/render-modes.ts +137 -0
- package/templates/animation-studio/src/scene-player.ts +867 -0
- package/templates/animation-studio/src/set-templates.ts +361 -0
- package/templates/animation-studio/src/studio/episode-document-store.ts +72 -0
- package/templates/animation-studio/src/studio/scene-tool-registry.ts +86 -0
- package/templates/animation-studio/src/studio/scene-tools.ts +169 -0
- package/templates/animation-studio/tests/reports/animation-studio/hifi-cast-validation.json +938 -0
- package/templates/animation-studio/tsconfig.json +26 -0
- package/templates/animation-studio/vite.config.ts +18 -0
- package/templates/character-controller/README.md +33 -0
- package/templates/character-controller/index.html +19 -0
- package/templates/character-controller/package.json +23 -0
- package/templates/character-controller/playwright.config.ts +14 -0
- package/templates/character-controller/src/controller.ts +44 -0
- package/templates/character-controller/src/main.ts +62 -0
- package/templates/character-controller/tests/route-health.spec.ts +26 -0
- package/templates/character-controller/tests/screenshot.spec.ts +9 -0
- package/templates/character-controller/tsconfig.json +15 -0
- package/templates/cinematic-scene/package.json +1 -1
- package/templates/episode-builder/README.md +6 -2
- package/templates/episode-builder/package.json +1 -1
- package/templates/episode-builder/src/aura-assets.ts +1 -1
- package/templates/episode-builder/src/builder.ts +4 -4
- package/templates/episode-builder/src/episode.ts +21 -21
- package/templates/episode-builder/src/main.ts +20 -20
- package/templates/episode-builder/src/render-plan.ts +13 -13
- package/templates/episode-builder/tests/storyboard-playback.spec.ts +7 -7
- package/templates/fighting-game/README.md +16 -0
- package/templates/fighting-game/package.json +1 -1
- package/templates/mini-game/package.json +1 -1
- package/templates/product-viewer/package.json +1 -1
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/README.md +7 -3
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/index.html +1 -1
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/package.json +2 -2
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/aura-assets.ts +1 -1
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/episode.ts +22 -22
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/main.ts +28 -28
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/render-plan.ts +13 -13
- package/templates/{cartoon-channel → prompt-animation-channel}/tests/route-health.spec.ts +1 -1
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/tests/storyboard-playback.spec.ts +8 -8
- package/templates/cartoon-studio/aura.assets.json +0 -157
- package/templates/cartoon-studio/package.json +0 -32
- package/templates/cartoon-studio/public/aura-assets/luma.047f5e5f.glb +0 -0
- package/templates/cartoon-studio/public/aura-assets/luma.humanoid-fixture.glb +0 -0
- package/templates/cartoon-studio/public/aura-assets/miko.047f5e5f.glb +0 -0
- package/templates/cartoon-studio/scripts/episode.ts +0 -276
- package/templates/cartoon-studio/src/aura-assets.ts +0 -61
- package/templates/cartoon-studio/src/characters.ts +0 -65
- package/templates/cartoon-studio/src/episode-renderer.ts +0 -605
- package/templates/cartoon-studio/src/episode.ts +0 -306
- package/templates/cartoon-studio/src/main.ts +0 -333
- package/templates/cartoon-studio/src/render-plan.ts +0 -567
- package/templates/cartoon-studio/src/review.ts +0 -99
- package/templates/cartoon-studio/src/studio.ts +0 -101
- package/templates/cartoon-studio/test-results/.last-run.json +0 -4
- package/templates/cartoon-studio/tests/episode-render.spec.ts +0 -44
- package/templates/cartoon-studio/tests/motion-quality.spec.ts +0 -45
- package/templates/cartoon-studio/tests/route-health.spec.ts +0 -7
- package/templates/cartoon-studio/tests/storyboard-playback.spec.ts +0 -99
- package/templates/cartoon-studio/tests/visual-review.spec.ts +0 -21
- package/templates/prompt-cartoon-channel/src/sets.ts +0 -14
- package/templates/prompt-cartoon-channel/tsconfig.json +0 -12
- /package/templates/{cartoon-channel → animation-channel}/aura.assets.json +0 -0
- /package/templates/{cartoon-channel → animation-channel}/playwright.config.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/luma.047f5e5f.glb +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/luma.thumb.svg +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/miko.047f5e5f.glb +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/miko.thumb.svg +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/moon-garden-feature-frame.png +0 -0
- /package/templates/{cartoon-channel → animation-channel}/src/aura-assets.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/src/characters.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/src/contract.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/src/sets.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/test-results/.last-run.json +0 -0
- /package/templates/{cartoon-channel → animation-channel}/tests/reports/prompt-animation/cartoon-sample-episode.png +0 -0
- /package/templates/{cartoon-channel → animation-channel}/tsconfig.json +0 -0
- /package/templates/{cartoon-studio → animation-studio}/playwright.config.ts +0 -0
- /package/templates/{cartoon-studio → animation-studio}/public/aura-assets/luma.thumb.svg +0 -0
- /package/templates/{cartoon-studio → animation-studio}/public/aura-assets/miko.thumb.svg +0 -0
- /package/templates/{cartoon-studio → animation-studio}/src/contract.ts +0 -0
- /package/templates/{prompt-cartoon-channel → prompt-animation-channel}/playwright.config.ts +0 -0
- /package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/characters.ts +0 -0
- /package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/contract.ts +0 -0
- /package/templates/{cartoon-studio → prompt-animation-channel}/src/sets.ts +0 -0
- /package/templates/{cartoon-studio → prompt-animation-channel}/tsconfig.json +0 -0
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schema": "aura3d.assets/1.0",
|
|
3
|
-
"assetBasePath": "/aura-assets/",
|
|
4
|
-
"outputDir": "public/aura-assets",
|
|
5
|
-
"typegen": "src/aura-assets.ts",
|
|
6
|
-
"assets": [
|
|
7
|
-
{
|
|
8
|
-
"id": "luma",
|
|
9
|
-
"type": "model",
|
|
10
|
-
"format": "glb",
|
|
11
|
-
"source": "public/aura-assets/luma.humanoid-fixture.glb",
|
|
12
|
-
"outputPath": "public/aura-assets/luma.humanoid-fixture.glb",
|
|
13
|
-
"url": "/aura-assets/luma.humanoid-fixture.glb",
|
|
14
|
-
"hash": "sha256-dfb230fc1f942f259dd00281a1186953ad602fc5d69067ce63e24b2aa439736b",
|
|
15
|
-
"sizeBytes": 2160468,
|
|
16
|
-
"bounds": [1.1, 1.8, 0.8],
|
|
17
|
-
"boundsMetadata": {
|
|
18
|
-
"min": [-0.55, 0, -0.4],
|
|
19
|
-
"max": [0.55, 1.8, 0.4],
|
|
20
|
-
"size": [1.1, 1.8, 0.8],
|
|
21
|
-
"center": [0, 0.9, 0],
|
|
22
|
-
"maxDimension": 1.8,
|
|
23
|
-
"grounded": true
|
|
24
|
-
},
|
|
25
|
-
"materials": ["luma-body", "luma-face", "luma-accent"],
|
|
26
|
-
"materialMetadata": [
|
|
27
|
-
{ "name": "luma-body", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
|
|
28
|
-
{ "name": "luma-face", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
|
|
29
|
-
{ "name": "luma-accent", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] }
|
|
30
|
-
],
|
|
31
|
-
"animations": ["Idle", "Walking", "Wave", "Punch", "Jump"],
|
|
32
|
-
"animationMetadata": {
|
|
33
|
-
"clipCount": 5,
|
|
34
|
-
"clips": [
|
|
35
|
-
{ "index": 0, "name": "Idle", "channelCount": 6, "samplerCount": 6, "targetPaths": ["rotation"], "targetNodes": ["Body", "Head", "UpperArm.L", "UpperArm.R"] },
|
|
36
|
-
{ "index": 1, "name": "Walking", "channelCount": 8, "samplerCount": 8, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] },
|
|
37
|
-
{ "index": 2, "name": "Wave", "channelCount": 5, "samplerCount": 5, "targetPaths": ["rotation"], "targetNodes": ["Head", "UpperArm.R", "LowerArm.R"] },
|
|
38
|
-
{ "index": 3, "name": "Punch", "channelCount": 5, "samplerCount": 5, "targetPaths": ["rotation"], "targetNodes": ["Body", "UpperArm.L", "LowerArm.L"] },
|
|
39
|
-
{ "index": 4, "name": "Jump", "channelCount": 7, "samplerCount": 7, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] }
|
|
40
|
-
]
|
|
41
|
-
},
|
|
42
|
-
"humanoid": { "status": "candidate", "humanoid": true, "boneCount": 10 },
|
|
43
|
-
"skeleton": { "jointCount": 10, "skinnedMeshCount": 1 },
|
|
44
|
-
"morphTargets": { "targetCount": 0, "targetNames": [] },
|
|
45
|
-
"textures": [],
|
|
46
|
-
"dependencies": [],
|
|
47
|
-
"nodeNames": ["Luma", "Body", "Head", "mouth card", "UpperArm.L", "UpperArm.R", "UpperLeg.L", "UpperLeg.R"],
|
|
48
|
-
"provenance": {
|
|
49
|
-
"license": "CC0-1.0",
|
|
50
|
-
"author": "Aura3D",
|
|
51
|
-
"sourceFamily": "Aura3D curated starter pack",
|
|
52
|
-
"sourcePath": "public/aura-assets/luma.humanoid-fixture.glb",
|
|
53
|
-
"sourceUrl": "https://aura3d.auraone.ai/aura-assets/luma.humanoid-fixture.glb",
|
|
54
|
-
"attribution": "Bundled Aura3D starter rig for local cartoon-studio validation.",
|
|
55
|
-
"evidence": ["cartoon-character", "primitive mouth card", "rigged humanoid robot"]
|
|
56
|
-
},
|
|
57
|
-
"thumbnailUrl": "/aura-assets/luma.thumb.svg",
|
|
58
|
-
"warnings": []
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"id": "miko",
|
|
62
|
-
"type": "model",
|
|
63
|
-
"format": "glb",
|
|
64
|
-
"source": "public/aura-assets/miko.047f5e5f.glb",
|
|
65
|
-
"outputPath": "public/aura-assets/miko.047f5e5f.glb",
|
|
66
|
-
"url": "/aura-assets/miko.047f5e5f.glb",
|
|
67
|
-
"hash": "sha256-047f5e5fb3bb6d378bd1df16ca6137f2a596c99b3a1b5690b4020c05aaf6f319",
|
|
68
|
-
"sizeBytes": 463988,
|
|
69
|
-
"bounds": [0.066, 0.026, 0.017],
|
|
70
|
-
"boundsMetadata": {
|
|
71
|
-
"min": [-0.033, -0.013, -0.009],
|
|
72
|
-
"max": [0.033, 0.013, 0.008],
|
|
73
|
-
"size": [0.066, 0.026, 0.017],
|
|
74
|
-
"center": [0, 0, 0],
|
|
75
|
-
"maxDimension": 0.066,
|
|
76
|
-
"grounded": true
|
|
77
|
-
},
|
|
78
|
-
"materials": ["Grey", "Main", "Black"],
|
|
79
|
-
"materialMetadata": [
|
|
80
|
-
{ "name": "Grey", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
|
|
81
|
-
{ "name": "Main", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
|
|
82
|
-
{ "name": "Black", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] }
|
|
83
|
-
],
|
|
84
|
-
"animations": ["Dance", "Death", "Idle", "Jump", "Punch", "Running", "Walking", "Wave"],
|
|
85
|
-
"animationMetadata": {
|
|
86
|
-
"clipCount": 8,
|
|
87
|
-
"clips": [
|
|
88
|
-
{ "index": 0, "name": "Dance", "channelCount": 12, "samplerCount": 12, "targetPaths": ["weights", "translation", "rotation"], "targetNodes": ["Head", "Body", "UpperArm.L", "UpperArm.R"] },
|
|
89
|
-
{ "index": 1, "name": "Death", "channelCount": 18, "samplerCount": 18, "targetPaths": ["weights", "translation", "rotation"], "targetNodes": ["Head", "Body", "UpperArm.L", "UpperArm.R"] },
|
|
90
|
-
{ "index": 2, "name": "Idle", "channelCount": 7, "samplerCount": 7, "targetPaths": ["weights", "translation", "rotation"], "targetNodes": ["Head", "Body"] },
|
|
91
|
-
{ "index": 3, "name": "Jump", "channelCount": 10, "samplerCount": 10, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] },
|
|
92
|
-
{ "index": 4, "name": "Punch", "channelCount": 8, "samplerCount": 8, "targetPaths": ["rotation"], "targetNodes": ["Body", "UpperArm.L", "LowerArm.L"] },
|
|
93
|
-
{ "index": 5, "name": "Running", "channelCount": 10, "samplerCount": 10, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] },
|
|
94
|
-
{ "index": 6, "name": "Walking", "channelCount": 10, "samplerCount": 10, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] },
|
|
95
|
-
{ "index": 7, "name": "Wave", "channelCount": 8, "samplerCount": 8, "targetPaths": ["rotation"], "targetNodes": ["Head", "UpperArm.R", "LowerArm.R"] }
|
|
96
|
-
]
|
|
97
|
-
},
|
|
98
|
-
"humanoid": { "status": "candidate", "humanoid": true, "boneCount": 10 },
|
|
99
|
-
"skeleton": { "jointCount": 10, "skinnedMeshCount": 1 },
|
|
100
|
-
"morphTargets": { "targetCount": 1, "targetNames": ["mouthSmile"] },
|
|
101
|
-
"textures": [],
|
|
102
|
-
"dependencies": [],
|
|
103
|
-
"nodeNames": ["Miko", "Head", "Body", "mouth card", "UpperArm.L", "UpperArm.R", "UpperLeg.L", "UpperLeg.R"],
|
|
104
|
-
"provenance": {
|
|
105
|
-
"license": "CC0-1.0",
|
|
106
|
-
"author": "Aura3D",
|
|
107
|
-
"sourceFamily": "Aura3D curated starter pack",
|
|
108
|
-
"sourcePath": "public/aura-assets/miko.047f5e5f.glb",
|
|
109
|
-
"sourceUrl": "https://aura3d.auraone.ai/aura-assets/miko.047f5e5f.glb",
|
|
110
|
-
"attribution": "Bundled Aura3D starter rig for local cartoon-studio validation.",
|
|
111
|
-
"evidence": ["cartoon-character", "blendshape mouth", "rigged humanoid robot"]
|
|
112
|
-
},
|
|
113
|
-
"thumbnailUrl": "/aura-assets/miko.thumb.svg",
|
|
114
|
-
"warnings": []
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
"id": "moonGarden",
|
|
118
|
-
"type": "model",
|
|
119
|
-
"format": "gltf",
|
|
120
|
-
"source": "public/aura-assets/moonGarden.gltf",
|
|
121
|
-
"outputPath": "public/aura-assets/moonGarden.gltf",
|
|
122
|
-
"url": "/aura-assets/moonGarden.gltf",
|
|
123
|
-
"hash": "sha256-85a288d6d434cc5c56ac154c3e996c2ad7612791622fc20a339fb647a6d426bd",
|
|
124
|
-
"sizeBytes": 3744,
|
|
125
|
-
"bounds": [3.2, 0.6, 1.2],
|
|
126
|
-
"boundsMetadata": {
|
|
127
|
-
"min": [-1.6, 0, -0.6],
|
|
128
|
-
"max": [1.6, 0.6, 0.6],
|
|
129
|
-
"size": [3.2, 0.6, 1.2],
|
|
130
|
-
"center": [0, 0.3, 0],
|
|
131
|
-
"maxDimension": 3.2,
|
|
132
|
-
"grounded": true
|
|
133
|
-
},
|
|
134
|
-
"materials": ["soft blue moon path", "warm glow stone", "distant teal skyline"],
|
|
135
|
-
"materialMetadata": [
|
|
136
|
-
{ "name": "soft blue moon path", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
|
|
137
|
-
{ "name": "warm glow stone", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
|
|
138
|
-
{ "name": "distant teal skyline", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] }
|
|
139
|
-
],
|
|
140
|
-
"animations": [],
|
|
141
|
-
"textures": [],
|
|
142
|
-
"dependencies": [],
|
|
143
|
-
"nodeNames": ["Moon Garden starter set anchor", "moon garden floor anchor", "moon garden glow stone anchor", "moon garden skyline anchor", "walkable garden set"],
|
|
144
|
-
"provenance": {
|
|
145
|
-
"license": "MIT",
|
|
146
|
-
"author": "Aura3D",
|
|
147
|
-
"sourceFamily": "Aura3D curated starter pack",
|
|
148
|
-
"sourcePath": "public/aura-assets/moonGarden.gltf",
|
|
149
|
-
"sourceUrl": "https://aura3d.auraone.ai/aura-assets/moonGarden.gltf",
|
|
150
|
-
"attribution": "Bundled Aura3D Moon Garden starter set for local cartoon-studio validation.",
|
|
151
|
-
"evidence": ["cartoon-set", "moon garden", "walkable set", "framing ready"]
|
|
152
|
-
},
|
|
153
|
-
"thumbnailUrl": "/aura-assets/moonGarden.thumb.svg",
|
|
154
|
-
"warnings": []
|
|
155
|
-
}
|
|
156
|
-
]
|
|
157
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "aura3d-cartoon-studio",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"private": true,
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite --host 0.0.0.0",
|
|
8
|
-
"episode:plan": "tsx scripts/episode.ts plan",
|
|
9
|
-
"episode:preview": "tsx scripts/episode.ts preview",
|
|
10
|
-
"episode:render": "tsx scripts/episode.ts render",
|
|
11
|
-
"episode:package": "tsx scripts/episode.ts package",
|
|
12
|
-
"episode:review": "tsx scripts/episode.ts review",
|
|
13
|
-
"episode:verify": "npm run episode:render && npm run episode:package && npm run episode:review && tsx scripts/episode.ts verify",
|
|
14
|
-
"typecheck": "tsc --noEmit",
|
|
15
|
-
"build": "npm run typecheck && vite build",
|
|
16
|
-
"preview": "vite preview --host 0.0.0.0",
|
|
17
|
-
"test": "playwright test tests/route-health.spec.ts tests/storyboard-playback.spec.ts tests/episode-render.spec.ts tests/motion-quality.spec.ts tests/visual-review.spec.ts --workers=1"
|
|
18
|
-
},
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"@aura3d/animation": "1.1.0",
|
|
21
|
-
"@aura3d/assets": "1.1.0",
|
|
22
|
-
"@aura3d/core": "1.1.0",
|
|
23
|
-
"@aura3d/physics": "1.1.0",
|
|
24
|
-
"@aura3d/engine": "1.1.0"
|
|
25
|
-
},
|
|
26
|
-
"devDependencies": {
|
|
27
|
-
"@playwright/test": "^1.52.0",
|
|
28
|
-
"tsx": "^4.20.6",
|
|
29
|
-
"typescript": "^5.9.3",
|
|
30
|
-
"vite": "^7.2.4"
|
|
31
|
-
}
|
|
32
|
-
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { execFileSync, spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
|
|
3
|
-
import { existsSync } from "node:fs";
|
|
4
|
-
import { copyFile, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
5
|
-
import path from "node:path";
|
|
6
|
-
import {
|
|
7
|
-
createCartoonEpisodePackage,
|
|
8
|
-
type CartoonEpisodePackageBuild,
|
|
9
|
-
type CartoonEpisodePackageMode
|
|
10
|
-
} from "../src/episode-renderer";
|
|
11
|
-
|
|
12
|
-
const command = process.argv[2] ?? "package";
|
|
13
|
-
|
|
14
|
-
async function main() {
|
|
15
|
-
if (command === "plan") {
|
|
16
|
-
await writePackage("plan", { only: new Set(["episode-plan.json", "metadata.json"]) });
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
if (command === "preview") {
|
|
20
|
-
await writePackage("preview", { only: new Set(["route-proof.json", "metadata.json"]) });
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
if (command === "render") {
|
|
24
|
-
await writePackage("render");
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if (command === "package") {
|
|
28
|
-
await writePackage("package");
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (command === "review") {
|
|
32
|
-
await writePackage("review", { only: new Set(["review-package.md", "visual-acceptance.json", "render-manifest.json"]) });
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
if (command === "verify") {
|
|
36
|
-
await verifyPackage(createCartoonEpisodePackage("package"));
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
throw new Error(`Unknown episode command "${command}". Use plan, preview, render, package, review, or verify.`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async function writePackage(mode: CartoonEpisodePackageMode, options: { only?: ReadonlySet<string> } = {}) {
|
|
43
|
-
const pkg = createCartoonEpisodePackage(mode);
|
|
44
|
-
await mkdir(pkg.packageDirectory, { recursive: true });
|
|
45
|
-
if (mode === "render" || mode === "package") {
|
|
46
|
-
await rm(path.join(pkg.packageDirectory, "frames"), { recursive: true, force: true });
|
|
47
|
-
await rm(path.join(pkg.packageDirectory, "episode.png-sequence-fallback.json"), { force: true });
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
for (const file of pkg.files) {
|
|
51
|
-
if (options.only && !options.only.has(file.path)) continue;
|
|
52
|
-
const target = path.join(pkg.packageDirectory, file.path);
|
|
53
|
-
await mkdir(path.dirname(target), { recursive: true });
|
|
54
|
-
if (file.kind === "png-base64") {
|
|
55
|
-
await writeFile(target, Buffer.from(file.contents, "base64"));
|
|
56
|
-
} else {
|
|
57
|
-
await writeFile(target, file.contents, "utf8");
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!options.only && (mode === "render" || mode === "package")) await renderEpisodeMedia(pkg);
|
|
62
|
-
if (!options.only && mode === "package") await captureRouteThumbnail(pkg);
|
|
63
|
-
if (!options.only) await writeChecksumManifest(pkg);
|
|
64
|
-
console.log(JSON.stringify({
|
|
65
|
-
ok: true,
|
|
66
|
-
command: mode,
|
|
67
|
-
packageDirectory: pkg.packageDirectory,
|
|
68
|
-
hasWebm: pkg.hasWebm,
|
|
69
|
-
hasPngSequenceFallback: pkg.hasPngSequenceFallback,
|
|
70
|
-
publishReady: pkg.publishReady,
|
|
71
|
-
fileCount: options.only ? options.only.size : pkg.files.length
|
|
72
|
-
}, null, 2));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function writeChecksumManifest(pkg: CartoonEpisodePackageBuild) {
|
|
76
|
-
const artifactEntries = [];
|
|
77
|
-
const packageArtifacts = [
|
|
78
|
-
...pkg.files.map((file) => ({ path: file.path, kind: file.kind })),
|
|
79
|
-
{ path: "episode.webm", kind: "video/webm" },
|
|
80
|
-
{ path: "thumbnail.png", kind: "png" },
|
|
81
|
-
{ path: "frames/first.png", kind: "png" },
|
|
82
|
-
{ path: "frames/dialogue.png", kind: "png" },
|
|
83
|
-
{ path: "frames/action.png", kind: "png" },
|
|
84
|
-
{ path: "frames/final.png", kind: "png" }
|
|
85
|
-
];
|
|
86
|
-
for (const file of packageArtifacts) {
|
|
87
|
-
const target = path.join(pkg.packageDirectory, file.path);
|
|
88
|
-
if (!existsSync(target)) continue;
|
|
89
|
-
const bytes = await readFile(target);
|
|
90
|
-
artifactEntries.push({
|
|
91
|
-
path: file.path,
|
|
92
|
-
kind: file.kind,
|
|
93
|
-
byteSize: bytes.length,
|
|
94
|
-
sha256: createHash("sha256").update(bytes).digest("hex")
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
const manifestPath = path.join(pkg.packageDirectory, "render-manifest.json");
|
|
98
|
-
const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
99
|
-
manifest.artifacts = artifactEntries;
|
|
100
|
-
manifest.requiredFiles = pkg.requiredFiles;
|
|
101
|
-
await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async function renderEpisodeMedia(pkg: CartoonEpisodePackageBuild) {
|
|
105
|
-
const frameDirectory = path.join(pkg.packageDirectory, "frames");
|
|
106
|
-
const imageTool = executable("sips") ?? executable("magick") ?? executable("convert");
|
|
107
|
-
const ffmpeg = executable("ffmpeg");
|
|
108
|
-
if (!imageTool) throw new Error("Cannot render cartoon episode frames: ImageMagick `magick` or `convert` is required.");
|
|
109
|
-
if (!ffmpeg) throw new Error("Cannot encode cartoon episode: `ffmpeg` is required.");
|
|
110
|
-
|
|
111
|
-
const sequenceSvgFiles = pkg.files
|
|
112
|
-
.filter((file) => file.kind === "svg" && /^frames\/frame-\d+\.svg$/.test(file.path))
|
|
113
|
-
.map((file) => file.path)
|
|
114
|
-
.sort();
|
|
115
|
-
|
|
116
|
-
for (const svgPath of sequenceSvgFiles) {
|
|
117
|
-
const input = path.join(pkg.packageDirectory, svgPath);
|
|
118
|
-
const output = input.replace(/\.svg$/, ".png");
|
|
119
|
-
renderSvgToPng(imageTool, input, output);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const representativePairs = [
|
|
123
|
-
["frames/first.svg", "frames/first.png"],
|
|
124
|
-
["frames/dialogue.svg", "frames/dialogue.png"],
|
|
125
|
-
["frames/action.svg", "frames/action.png"],
|
|
126
|
-
["frames/final.svg", "frames/final.png"]
|
|
127
|
-
] as const;
|
|
128
|
-
for (const [svgPath, pngPath] of representativePairs) {
|
|
129
|
-
renderSvgToPng(imageTool, path.join(pkg.packageDirectory, svgPath), path.join(pkg.packageDirectory, pngPath));
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
await copyFile(path.join(pkg.packageDirectory, "frames", "action.png"), path.join(pkg.packageDirectory, "thumbnail.png"));
|
|
133
|
-
encodeWebm(ffmpeg, frameDirectory, path.join(pkg.packageDirectory, "episode.webm"));
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async function captureRouteThumbnail(pkg: CartoonEpisodePackageBuild) {
|
|
137
|
-
const vite = viteExecutable();
|
|
138
|
-
if (!vite) throw new Error("Cannot capture route thumbnail: Vite executable was not found.");
|
|
139
|
-
const port = 4387;
|
|
140
|
-
const origin = `http://127.0.0.1:${port}`;
|
|
141
|
-
const server = spawn(vite, ["--host", "127.0.0.1", "--port", String(port)], {
|
|
142
|
-
cwd: process.cwd(),
|
|
143
|
-
env: { ...process.env, BROWSER: "none" },
|
|
144
|
-
stdio: "pipe"
|
|
145
|
-
});
|
|
146
|
-
let startupLog = "";
|
|
147
|
-
server.stdout.on("data", (chunk) => {
|
|
148
|
-
startupLog += String(chunk);
|
|
149
|
-
});
|
|
150
|
-
server.stderr.on("data", (chunk) => {
|
|
151
|
-
startupLog += String(chunk);
|
|
152
|
-
});
|
|
153
|
-
try {
|
|
154
|
-
await waitForServer(origin, server, () => startupLog);
|
|
155
|
-
const { chromium } = await import("playwright");
|
|
156
|
-
const browser = await chromium.launch();
|
|
157
|
-
try {
|
|
158
|
-
const page = await browser.newPage({ viewport: { width: 1280, height: 720 }, deviceScaleFactor: 1 });
|
|
159
|
-
await page.goto(`${origin}/?capture=thumbnail`, { waitUntil: "networkidle" });
|
|
160
|
-
await page.waitForSelector("canvas", { timeout: 10_000 });
|
|
161
|
-
await page.waitForTimeout(500);
|
|
162
|
-
await page.locator("canvas").first().screenshot({
|
|
163
|
-
path: path.join(pkg.packageDirectory, "thumbnail.png")
|
|
164
|
-
});
|
|
165
|
-
} finally {
|
|
166
|
-
await browser.close();
|
|
167
|
-
}
|
|
168
|
-
} finally {
|
|
169
|
-
stopServer(server);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function renderSvgToPng(command: string, input: string, output: string) {
|
|
174
|
-
if (path.basename(command) === "sips") {
|
|
175
|
-
execFileSync(command, ["-s", "format", "png", input, "--out", output], { stdio: "pipe" });
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
const args = path.basename(command) === "magick"
|
|
179
|
-
? [input, "-background", "none", "-alpha", "remove", "-alpha", "off", output]
|
|
180
|
-
: [input, "-background", "none", "-alpha", "remove", "-alpha", "off", output];
|
|
181
|
-
execFileSync(command, args, { stdio: "pipe" });
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function encodeWebm(ffmpeg: string, frameDirectory: string, output: string) {
|
|
185
|
-
execFileSync(ffmpeg, [
|
|
186
|
-
"-y",
|
|
187
|
-
"-framerate",
|
|
188
|
-
"30",
|
|
189
|
-
"-stream_loop",
|
|
190
|
-
"59",
|
|
191
|
-
"-i",
|
|
192
|
-
path.join(frameDirectory, "frame-%04d.png"),
|
|
193
|
-
"-t",
|
|
194
|
-
"60",
|
|
195
|
-
"-c:v",
|
|
196
|
-
"libvpx-vp9",
|
|
197
|
-
"-pix_fmt",
|
|
198
|
-
"yuv420p",
|
|
199
|
-
"-b:v",
|
|
200
|
-
"0",
|
|
201
|
-
"-crf",
|
|
202
|
-
"34",
|
|
203
|
-
output
|
|
204
|
-
], { stdio: "pipe" });
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function executable(command: string): string | undefined {
|
|
208
|
-
try {
|
|
209
|
-
return execFileSync("which", [command], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim() || undefined;
|
|
210
|
-
} catch {
|
|
211
|
-
return undefined;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function viteExecutable(): string | undefined {
|
|
216
|
-
const local = path.join(process.cwd(), "node_modules", ".bin", process.platform === "win32" ? "vite.cmd" : "vite");
|
|
217
|
-
return existsSync(local) ? local : executable("vite");
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
async function waitForServer(origin: string, server: ChildProcessWithoutNullStreams, log: () => string) {
|
|
221
|
-
const startedAt = Date.now();
|
|
222
|
-
while (Date.now() - startedAt < 30_000) {
|
|
223
|
-
if (server.exitCode !== null) {
|
|
224
|
-
throw new Error(`Vite exited before route thumbnail capture. Log:\n${log()}`);
|
|
225
|
-
}
|
|
226
|
-
try {
|
|
227
|
-
const response = await fetch(origin);
|
|
228
|
-
if (response.ok) return;
|
|
229
|
-
} catch {
|
|
230
|
-
// Keep polling until Vite is ready.
|
|
231
|
-
}
|
|
232
|
-
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
233
|
-
}
|
|
234
|
-
throw new Error(`Timed out waiting for Vite route thumbnail capture. Log:\n${log()}`);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function stopServer(server: ChildProcessWithoutNullStreams) {
|
|
238
|
-
if (server.exitCode === null) server.kill("SIGTERM");
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async function verifyPackage(pkg: CartoonEpisodePackageBuild) {
|
|
242
|
-
const missing = [];
|
|
243
|
-
for (const requiredFile of pkg.requiredFiles) {
|
|
244
|
-
const target = path.join(pkg.packageDirectory, requiredFile);
|
|
245
|
-
if (!existsSync(target)) missing.push(requiredFile);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const hasWebm = existsSync(path.join(pkg.packageDirectory, "episode.webm"));
|
|
249
|
-
const hasFallback = existsSync(path.join(pkg.packageDirectory, "episode.png-sequence-fallback.json"));
|
|
250
|
-
if (!hasWebm && !hasFallback) missing.push("episode.webm or episode.png-sequence-fallback.json");
|
|
251
|
-
|
|
252
|
-
const byteSizes = [];
|
|
253
|
-
for (const requiredFile of pkg.requiredFiles) {
|
|
254
|
-
const target = path.join(pkg.packageDirectory, requiredFile);
|
|
255
|
-
if (!existsSync(target)) continue;
|
|
256
|
-
const info = await stat(target);
|
|
257
|
-
byteSizes.push({ path: requiredFile, byteSize: info.size });
|
|
258
|
-
if (info.size <= 0) missing.push(`${requiredFile} is empty`);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const ok = missing.length === 0;
|
|
262
|
-
console.log(JSON.stringify({
|
|
263
|
-
ok,
|
|
264
|
-
packageDirectory: pkg.packageDirectory,
|
|
265
|
-
hasWebm,
|
|
266
|
-
hasPngSequenceFallback: hasFallback,
|
|
267
|
-
checkedFiles: byteSizes,
|
|
268
|
-
missing
|
|
269
|
-
}, null, 2));
|
|
270
|
-
if (!ok) process.exitCode = 1;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
main().catch((error) => {
|
|
274
|
-
console.error(error instanceof Error ? error.message : error);
|
|
275
|
-
process.exitCode = 1;
|
|
276
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { defineAuraAssets } from "@aura3d/engine";
|
|
2
|
-
import { AURAVOICE_AURA3D_PROMPT_ANIMATION_CONTRACT_ID } from "./contract";
|
|
3
|
-
|
|
4
|
-
export const assetContractId = AURAVOICE_AURA3D_PROMPT_ANIMATION_CONTRACT_ID;
|
|
5
|
-
|
|
6
|
-
export const cartoonStudioRequiredAssetKeys = ["miko", "luma", "moonGarden"] as const;
|
|
7
|
-
|
|
8
|
-
export const cartoonStudioOptionalAudioAssetKeys = [
|
|
9
|
-
"mikoDialogueStem",
|
|
10
|
-
"lumaDialogueStem",
|
|
11
|
-
"moonGardenMusic",
|
|
12
|
-
"moonGardenChimeSfx"
|
|
13
|
-
] as const;
|
|
14
|
-
|
|
15
|
-
export const assets = defineAuraAssets({
|
|
16
|
-
miko: {
|
|
17
|
-
type: "model",
|
|
18
|
-
format: "glb",
|
|
19
|
-
url: "/aura-assets/miko.047f5e5f.glb",
|
|
20
|
-
bounds: [0.066, 0.026, 0.017],
|
|
21
|
-
hash: "sha256-047f5e5fb3bb6d378bd1df16ca6137f2a596c99b3a1b5690b4020c05aaf6f319",
|
|
22
|
-
metadata: {
|
|
23
|
-
contractId: assetContractId,
|
|
24
|
-
role: "cartoon-character",
|
|
25
|
-
license: "CC0",
|
|
26
|
-
source: "Aura3D bundled humanoid starter fixture",
|
|
27
|
-
animationClips: ["Idle", "Walking", "Wave", "Punch", "Jump"],
|
|
28
|
-
mouthReadiness: "primitive-mouth-card"
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
luma: {
|
|
32
|
-
type: "model",
|
|
33
|
-
format: "glb",
|
|
34
|
-
url: "/aura-assets/luma.humanoid-fixture.glb",
|
|
35
|
-
bounds: [1.1, 1.8, 0.8],
|
|
36
|
-
hash: "sha256-dfb230fc1f942f259dd00281a1186953ad602fc5d69067ce63e24b2aa439736b",
|
|
37
|
-
metadata: {
|
|
38
|
-
contractId: assetContractId,
|
|
39
|
-
role: "cartoon-character",
|
|
40
|
-
license: "CC0",
|
|
41
|
-
source: "Aura3D bundled humanoid starter fixture",
|
|
42
|
-
animationClips: ["Idle", "Walking", "Wave", "Punch", "Jump"],
|
|
43
|
-
mouthReadiness: "primitive-mouth-card"
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
moonGarden: {
|
|
47
|
-
type: "model",
|
|
48
|
-
format: "gltf",
|
|
49
|
-
url: "/aura-assets/moonGarden.gltf",
|
|
50
|
-
bounds: [3.2, 0.6, 1.2],
|
|
51
|
-
hash: "sha256-85a288d6d434cc5c56ac154c3e996c2ad7612791622fc20a339fb647a6d426bd",
|
|
52
|
-
metadata: {
|
|
53
|
-
contractId: assetContractId,
|
|
54
|
-
role: "cartoon-set",
|
|
55
|
-
license: "MIT",
|
|
56
|
-
source: "Aura3D cartoon-studio local generated starter set anchor",
|
|
57
|
-
walkable: true,
|
|
58
|
-
framingReady: true
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
} as const);
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { AURAVOICE_AURA3D_PROMPT_ANIMATION_CONTRACT_ID } from "./contract";
|
|
2
|
-
|
|
3
|
-
export const characterContractId = AURAVOICE_AURA3D_PROMPT_ANIMATION_CONTRACT_ID;
|
|
4
|
-
|
|
5
|
-
export const characters = [
|
|
6
|
-
{
|
|
7
|
-
id: "miko",
|
|
8
|
-
name: "Miko",
|
|
9
|
-
palette: ["#7de2ff", "#f7ffe8"],
|
|
10
|
-
primitiveFallback: "round robot with antenna",
|
|
11
|
-
typedAssetKey: "miko",
|
|
12
|
-
runtimeNodeId: "miko",
|
|
13
|
-
primitiveMouthNodeId: "miko:mouth",
|
|
14
|
-
clipRequirements: ["Idle", "Walking", "Wave", "Talk"],
|
|
15
|
-
performanceChannels: ["body", "facial", "gesture", "blocking", "gaze"],
|
|
16
|
-
glbUpgrade: "After assets add, use model(assets.miko) and keep viseme blendshape metadata."
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
id: "luma",
|
|
20
|
-
name: "Luma",
|
|
21
|
-
palette: ["#ffe18e", "#40ffbf"],
|
|
22
|
-
primitiveFallback: "small moon-garden helper",
|
|
23
|
-
typedAssetKey: "luma",
|
|
24
|
-
runtimeNodeId: "luma",
|
|
25
|
-
primitiveMouthNodeId: "luma:mouth",
|
|
26
|
-
clipRequirements: ["Idle", "Walking", "Wave", "Talk"],
|
|
27
|
-
performanceChannels: ["body", "facial", "gesture", "blocking", "gaze"],
|
|
28
|
-
glbUpgrade: "After assets add, use model(assets.luma) and keep viseme blendshape metadata."
|
|
29
|
-
}
|
|
30
|
-
] as const;
|
|
31
|
-
|
|
32
|
-
export interface CartoonStudioCharacterReadiness {
|
|
33
|
-
readonly id: string;
|
|
34
|
-
readonly ok: boolean;
|
|
35
|
-
readonly missingClips: readonly string[];
|
|
36
|
-
readonly mouthReady: boolean;
|
|
37
|
-
readonly gestureReady: boolean;
|
|
38
|
-
readonly diagnostics: readonly string[];
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function validateCartoonStudioCharacters(
|
|
42
|
-
entries: readonly typeof characters[number][] = characters,
|
|
43
|
-
options: { readonly requiredClips?: readonly string[] } = {}
|
|
44
|
-
): readonly CartoonStudioCharacterReadiness[] {
|
|
45
|
-
const requiredClips = options.requiredClips ?? ["Idle", "Walking", "Wave"];
|
|
46
|
-
return entries.map((character) => {
|
|
47
|
-
const declaredClips = new Set(character.clipRequirements.map((clip) => clip.toLowerCase()));
|
|
48
|
-
const missingClips = requiredClips.filter((clip) => !declaredClips.has(clip.toLowerCase()));
|
|
49
|
-
const mouthReady = Boolean(character.primitiveMouthNodeId);
|
|
50
|
-
const gestureReady = character.performanceChannels.includes("gesture");
|
|
51
|
-
const diagnostics = [
|
|
52
|
-
...missingClips.map((clip) => `${character.id} missing required clip metadata: ${clip}`),
|
|
53
|
-
...(mouthReady ? [] : [`${character.id} missing primitive mouth or blendshape metadata`]),
|
|
54
|
-
...(gestureReady ? [] : [`${character.id} missing gesture performance channel`])
|
|
55
|
-
];
|
|
56
|
-
return {
|
|
57
|
-
id: character.id,
|
|
58
|
-
ok: diagnostics.length === 0,
|
|
59
|
-
missingClips,
|
|
60
|
-
mouthReady,
|
|
61
|
-
gestureReady,
|
|
62
|
-
diagnostics
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
}
|