create-aura3d 1.0.10 → 1.1.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/package.json +1 -1
- package/templates/cartoon-channel/README.md +38 -0
- package/templates/cartoon-channel/aura.assets.json +1364 -0
- package/templates/cartoon-channel/package.json +2 -1
- package/templates/cartoon-channel/public/aura-assets/luma.047f5e5f.glb +0 -0
- package/templates/cartoon-channel/public/aura-assets/luma.thumb.svg +1 -0
- package/templates/cartoon-channel/public/aura-assets/miko.047f5e5f.glb +0 -0
- package/templates/cartoon-channel/public/aura-assets/miko.thumb.svg +1 -0
- package/templates/cartoon-channel/public/aura-assets/moon-garden-feature-frame.png +0 -0
- package/templates/cartoon-channel/src/aura-assets.ts +5 -11
- package/templates/cartoon-channel/src/concept-episode-2-5d.css +159 -0
- package/templates/cartoon-channel/src/concept-episode-2-5d.ts +155 -0
- package/templates/cartoon-channel/src/image-puppet-episode.css +290 -0
- package/templates/cartoon-channel/src/image-puppet-episode.ts +139 -0
- package/templates/cartoon-channel/src/main.ts +89 -71
- package/templates/cartoon-channel/src/puppet-episode-2d.css +526 -0
- package/templates/cartoon-channel/src/puppet-episode-2d.ts +189 -0
- package/templates/cartoon-channel/src/render-plan.ts +1 -1
- package/templates/cartoon-channel/src/sample-episode-visual.css +457 -0
- package/templates/cartoon-channel/src/sample-episode-visual.ts +185 -0
- package/templates/cartoon-channel/test-results/.last-run.json +4 -0
- package/templates/cartoon-channel/tests/concept-2-5d-animation.spec.ts +18 -0
- package/templates/cartoon-channel/tests/concept-2-5d.spec.ts +30 -0
- package/templates/cartoon-channel/tests/image-puppet-animation.spec.ts +18 -0
- package/templates/cartoon-channel/tests/image-puppet.spec.ts +29 -0
- package/templates/cartoon-channel/tests/puppet-2d-animation.spec.ts +18 -0
- package/templates/cartoon-channel/tests/puppet-2d.spec.ts +26 -0
- package/templates/cartoon-channel/tests/reports/prompt-animation/cartoon-sample-episode.png +0 -0
- package/templates/cartoon-channel/tests/sample-episode-visual.spec.ts +45 -0
- package/templates/cartoon-channel/tests/storyboard-playback.spec.ts +1 -1
- package/templates/cartoon-studio/README.md +36 -0
- package/templates/cartoon-studio/aura.assets.json +157 -0
- package/templates/cartoon-studio/package.json +12 -1
- 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/luma.thumb.svg +1 -0
- package/templates/cartoon-studio/public/aura-assets/miko.047f5e5f.glb +0 -0
- package/templates/cartoon-studio/public/aura-assets/miko.thumb.svg +1 -0
- package/templates/cartoon-studio/public/aura-assets/moonGarden.gltf +183 -0
- package/templates/cartoon-studio/scripts/episode.ts +276 -0
- package/templates/cartoon-studio/src/aura-assets.ts +55 -8
- package/templates/cartoon-studio/src/characters.ts +38 -1
- package/templates/cartoon-studio/src/episode-renderer.ts +605 -0
- package/templates/cartoon-studio/src/episode.ts +12 -6
- package/templates/cartoon-studio/src/main.ts +109 -41
- package/templates/cartoon-studio/src/render-plan.ts +162 -0
- package/templates/cartoon-studio/src/review.ts +99 -0
- package/templates/cartoon-studio/test-results/.last-run.json +4 -0
- package/templates/cartoon-studio/tests/episode-render.spec.ts +44 -0
- package/templates/cartoon-studio/tests/motion-quality.spec.ts +45 -0
- package/templates/cartoon-studio/tests/storyboard-playback.spec.ts +18 -10
- package/templates/cartoon-studio/tests/visual-review.spec.ts +21 -0
- package/templates/product-viewer/tests/screenshot.spec.ts +8 -16
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
body[data-cartoon-view="image-puppet"] {
|
|
2
|
+
background:
|
|
3
|
+
radial-gradient(circle at 50% 20%, rgba(115, 225, 255, 0.12), transparent 34%),
|
|
4
|
+
linear-gradient(180deg, #06101d 0%, #102820 58%, #07100f 100%);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body[data-cartoon-view="image-puppet"] #caption-overlay,
|
|
8
|
+
body[data-cartoon-view="image-puppet"] .aura-diagnostics-overlay {
|
|
9
|
+
display: none !important;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
body[data-cartoon-view="image-puppet"] #app {
|
|
13
|
+
opacity: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.image-puppet {
|
|
17
|
+
--source-frame: url("/aura-assets/moon-garden-feature-frame.png");
|
|
18
|
+
position: fixed;
|
|
19
|
+
inset: 0;
|
|
20
|
+
display: grid;
|
|
21
|
+
place-items: center;
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
padding: 28px;
|
|
24
|
+
background:
|
|
25
|
+
radial-gradient(circle at 50% 32%, rgba(255, 226, 150, 0.11), transparent 28%),
|
|
26
|
+
linear-gradient(180deg, rgba(7, 19, 28, 0.64), rgba(1, 8, 10, 0.9));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.image-puppet__frame {
|
|
30
|
+
position: relative;
|
|
31
|
+
width: min(1320px, calc(100vw - 56px));
|
|
32
|
+
aspect-ratio: 1672 / 941;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
border: 1px solid rgba(255, 232, 170, 0.28);
|
|
35
|
+
border-radius: 22px;
|
|
36
|
+
background: #06100f;
|
|
37
|
+
box-shadow:
|
|
38
|
+
0 36px 94px rgba(0, 0, 0, 0.58),
|
|
39
|
+
0 0 90px rgba(64, 255, 191, 0.12);
|
|
40
|
+
isolation: isolate;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.image-puppet__base,
|
|
44
|
+
.image-puppet__cutout {
|
|
45
|
+
position: absolute;
|
|
46
|
+
inset: 0;
|
|
47
|
+
background-image: var(--source-frame);
|
|
48
|
+
background-repeat: no-repeat;
|
|
49
|
+
background-position: 50% 50%;
|
|
50
|
+
background-size: 100% 100%;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.image-puppet__base {
|
|
54
|
+
z-index: 1;
|
|
55
|
+
filter: saturate(0.96) brightness(0.78);
|
|
56
|
+
transform: scale(1.01);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.image-puppet__matte {
|
|
60
|
+
position: absolute;
|
|
61
|
+
z-index: 2;
|
|
62
|
+
border-radius: 999px;
|
|
63
|
+
background:
|
|
64
|
+
radial-gradient(ellipse at 50% 50%, rgba(8, 30, 36, 0.78), rgba(8, 30, 36, 0.4) 52%, transparent 72%);
|
|
65
|
+
filter: blur(10px);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.image-puppet__matte--blue {
|
|
69
|
+
left: 28%;
|
|
70
|
+
top: 40%;
|
|
71
|
+
width: 22%;
|
|
72
|
+
height: 42%;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.image-puppet__matte--yellow {
|
|
76
|
+
left: 53%;
|
|
77
|
+
top: 33%;
|
|
78
|
+
width: 22%;
|
|
79
|
+
height: 47%;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.image-puppet__matte--cart {
|
|
83
|
+
left: 46%;
|
|
84
|
+
top: 62%;
|
|
85
|
+
width: 17%;
|
|
86
|
+
height: 18%;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.image-puppet__cutout {
|
|
90
|
+
z-index: 5;
|
|
91
|
+
will-change: transform;
|
|
92
|
+
filter:
|
|
93
|
+
saturate(1.2)
|
|
94
|
+
brightness(1.1)
|
|
95
|
+
drop-shadow(0 20px 22px rgba(0, 0, 0, 0.34));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.image-puppet__cutout--moon {
|
|
99
|
+
z-index: 3;
|
|
100
|
+
transform-origin: 58% 25%;
|
|
101
|
+
animation: sourceMoonPulse 2.4s ease-in-out infinite;
|
|
102
|
+
-webkit-mask-image: radial-gradient(ellipse 17% 20% at 58% 25%, black 0 58%, transparent 72%);
|
|
103
|
+
mask-image: radial-gradient(ellipse 17% 20% at 58% 25%, black 0 58%, transparent 72%);
|
|
104
|
+
filter: saturate(1.15) brightness(1.12) drop-shadow(0 0 30px rgba(115, 230, 255, 0.42));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.image-puppet__cutout--blue-body {
|
|
108
|
+
transform-origin: 35% 70%;
|
|
109
|
+
animation: sourceBlueBody 1.25s ease-in-out infinite;
|
|
110
|
+
-webkit-mask-image: radial-gradient(ellipse 9% 18% at 35% 67%, black 0 57%, transparent 72%);
|
|
111
|
+
mask-image: radial-gradient(ellipse 9% 18% at 35% 67%, black 0 57%, transparent 72%);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.image-puppet__cutout--blue-head {
|
|
115
|
+
z-index: 6;
|
|
116
|
+
transform-origin: 36.5% 54%;
|
|
117
|
+
animation: sourceBlueHead 1.25s ease-in-out infinite;
|
|
118
|
+
-webkit-mask-image: radial-gradient(ellipse 8% 10% at 36.5% 54%, black 0 56%, transparent 72%);
|
|
119
|
+
mask-image: radial-gradient(ellipse 8% 10% at 36.5% 54%, black 0 56%, transparent 72%);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.image-puppet__cutout--blue-broom {
|
|
123
|
+
z-index: 7;
|
|
124
|
+
transform-origin: 42% 70%;
|
|
125
|
+
animation: sourceBroomSweep 0.88s ease-in-out infinite;
|
|
126
|
+
-webkit-mask-image:
|
|
127
|
+
linear-gradient(118deg, transparent 0 39%, black 41% 45%, transparent 48% 100%),
|
|
128
|
+
radial-gradient(ellipse 5% 5% at 42% 83%, black 0 52%, transparent 70%);
|
|
129
|
+
mask-image:
|
|
130
|
+
linear-gradient(118deg, transparent 0 39%, black 41% 45%, transparent 48% 100%),
|
|
131
|
+
radial-gradient(ellipse 5% 5% at 42% 83%, black 0 52%, transparent 70%);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.image-puppet__cutout--cart {
|
|
135
|
+
z-index: 5;
|
|
136
|
+
transform-origin: 53% 72%;
|
|
137
|
+
animation: sourceCartRoll 1.15s ease-in-out infinite;
|
|
138
|
+
-webkit-mask-image: radial-gradient(ellipse 10% 8% at 52.5% 72%, black 0 60%, transparent 75%);
|
|
139
|
+
mask-image: radial-gradient(ellipse 10% 8% at 52.5% 72%, black 0 60%, transparent 75%);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.image-puppet__cutout--yellow-body {
|
|
143
|
+
transform-origin: 61% 67%;
|
|
144
|
+
animation: sourceYellowBody 1.6s ease-in-out infinite;
|
|
145
|
+
-webkit-mask-image: radial-gradient(ellipse 9% 20% at 61% 64%, black 0 60%, transparent 74%);
|
|
146
|
+
mask-image: radial-gradient(ellipse 9% 20% at 61% 64%, black 0 60%, transparent 74%);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.image-puppet__cutout--yellow-head {
|
|
150
|
+
z-index: 6;
|
|
151
|
+
transform-origin: 61% 45%;
|
|
152
|
+
animation: sourceYellowHead 1.6s ease-in-out infinite;
|
|
153
|
+
-webkit-mask-image: radial-gradient(ellipse 8% 10% at 61% 45%, black 0 57%, transparent 72%);
|
|
154
|
+
mask-image: radial-gradient(ellipse 8% 10% at 61% 45%, black 0 57%, transparent 72%);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.image-puppet__cutout--yellow-tool {
|
|
158
|
+
z-index: 7;
|
|
159
|
+
transform-origin: 57% 68%;
|
|
160
|
+
animation: sourceYellowTool 1.15s ease-in-out infinite;
|
|
161
|
+
-webkit-mask-image:
|
|
162
|
+
linear-gradient(73deg, transparent 0 43%, black 45% 48%, transparent 51% 100%),
|
|
163
|
+
radial-gradient(ellipse 8% 7% at 58% 67%, black 0 54%, transparent 72%);
|
|
164
|
+
mask-image:
|
|
165
|
+
linear-gradient(73deg, transparent 0 43%, black 45% 48%, transparent 51% 100%),
|
|
166
|
+
radial-gradient(ellipse 8% 7% at 58% 67%, black 0 54%, transparent 72%);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.image-puppet__cutout--foreground {
|
|
170
|
+
z-index: 9;
|
|
171
|
+
transform-origin: 50% 91%;
|
|
172
|
+
animation: sourceForegroundGlow 2s ease-in-out infinite alternate;
|
|
173
|
+
-webkit-mask-image: linear-gradient(180deg, transparent 0 70%, rgba(0, 0, 0, 0.42) 78%, black 100%);
|
|
174
|
+
mask-image: linear-gradient(180deg, transparent 0 70%, rgba(0, 0, 0, 0.42) 78%, black 100%);
|
|
175
|
+
filter: saturate(1.18) brightness(1.08) drop-shadow(0 -12px 24px rgba(115, 230, 255, 0.18));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.image-puppet__hud,
|
|
179
|
+
.image-puppet__caption {
|
|
180
|
+
position: absolute;
|
|
181
|
+
z-index: 12;
|
|
182
|
+
left: 28px;
|
|
183
|
+
right: 28px;
|
|
184
|
+
display: flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
gap: 14px;
|
|
187
|
+
color: #f8fff2;
|
|
188
|
+
text-shadow: 0 2px 14px rgba(0, 0, 0, 0.72);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.image-puppet__hud {
|
|
192
|
+
top: 24px;
|
|
193
|
+
justify-content: space-between;
|
|
194
|
+
font: 700 13px/1.2 ui-sans-serif, system-ui, sans-serif;
|
|
195
|
+
letter-spacing: 0.08em;
|
|
196
|
+
text-transform: uppercase;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.image-puppet__hud span,
|
|
200
|
+
.image-puppet__hud strong {
|
|
201
|
+
padding: 8px 12px;
|
|
202
|
+
border: 1px solid rgba(248, 255, 242, 0.18);
|
|
203
|
+
border-radius: 999px;
|
|
204
|
+
background: rgba(1, 10, 10, 0.58);
|
|
205
|
+
backdrop-filter: blur(8px);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.image-puppet__caption {
|
|
209
|
+
bottom: 42px;
|
|
210
|
+
justify-content: center;
|
|
211
|
+
text-align: center;
|
|
212
|
+
font: 800 clamp(18px, 2.2vw, 30px) / 1.24 ui-rounded, "Trebuchet MS", system-ui, sans-serif;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.image-puppet__caption::before {
|
|
216
|
+
content: "";
|
|
217
|
+
position: absolute;
|
|
218
|
+
inset: -14px auto auto 50%;
|
|
219
|
+
width: min(880px, calc(100vw - 120px));
|
|
220
|
+
height: calc(100% + 28px);
|
|
221
|
+
transform: translateX(-50%);
|
|
222
|
+
border-radius: 18px;
|
|
223
|
+
background: linear-gradient(180deg, rgba(1, 10, 10, 0.1), rgba(1, 10, 10, 0.68));
|
|
224
|
+
z-index: -1;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.image-puppet__timeline {
|
|
228
|
+
position: absolute;
|
|
229
|
+
z-index: 13;
|
|
230
|
+
left: 28px;
|
|
231
|
+
right: 28px;
|
|
232
|
+
bottom: 20px;
|
|
233
|
+
height: 4px;
|
|
234
|
+
overflow: hidden;
|
|
235
|
+
border-radius: 999px;
|
|
236
|
+
background: rgba(248, 255, 242, 0.16);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.image-puppet__timeline-fill {
|
|
240
|
+
display: block;
|
|
241
|
+
width: var(--progress, 0%);
|
|
242
|
+
height: 100%;
|
|
243
|
+
border-radius: inherit;
|
|
244
|
+
background: linear-gradient(90deg, #ffdd87, #65ffc6);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
@keyframes sourceMoonPulse {
|
|
248
|
+
0%, 100% { transform: scale(0.985); opacity: 0.52; }
|
|
249
|
+
50% { transform: scale(1.035); opacity: 0.88; }
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
@keyframes sourceBlueBody {
|
|
253
|
+
0%, 100% { transform: translate(-2px, 0) rotate(-1.2deg); }
|
|
254
|
+
50% { transform: translate(7px, 8px) rotate(2.6deg); }
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@keyframes sourceBlueHead {
|
|
258
|
+
0%, 100% { transform: translate(0, 0) rotate(-2deg); }
|
|
259
|
+
50% { transform: translate(5px, 8px) rotate(4deg); }
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
@keyframes sourceBroomSweep {
|
|
263
|
+
0%, 100% { transform: translate(-8px, 0) rotate(-5deg); }
|
|
264
|
+
50% { transform: translate(15px, 9px) rotate(8deg); }
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@keyframes sourceCartRoll {
|
|
268
|
+
0%, 100% { transform: translateX(0) rotate(0deg); }
|
|
269
|
+
50% { transform: translateX(-10px) rotate(-1.6deg); }
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
@keyframes sourceYellowBody {
|
|
273
|
+
0%, 100% { transform: translate(0, 0) rotate(1deg); }
|
|
274
|
+
50% { transform: translate(-9px, 3px) rotate(-1.8deg); }
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
@keyframes sourceYellowHead {
|
|
278
|
+
0%, 100% { transform: translate(0, 0) rotate(1.5deg); }
|
|
279
|
+
50% { transform: translate(-7px, 4px) rotate(-3deg); }
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
@keyframes sourceYellowTool {
|
|
283
|
+
0%, 100% { transform: translate(0, 0) rotate(0deg); }
|
|
284
|
+
50% { transform: translate(-13px, 9px) rotate(-5deg); }
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
@keyframes sourceForegroundGlow {
|
|
288
|
+
from { opacity: 0.62; transform: scale(1); }
|
|
289
|
+
to { opacity: 0.86; transform: scale(1.012); }
|
|
290
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { episode, episodeSampleDescription } from "./episode";
|
|
2
|
+
import type { CartoonRouteSampleForVisual } from "./sample-episode-visual";
|
|
3
|
+
import "./image-puppet-episode.css";
|
|
4
|
+
|
|
5
|
+
export interface ImagePuppetEpisodeOptions {
|
|
6
|
+
readonly sampleAt: (time: number) => CartoonRouteSampleForVisual;
|
|
7
|
+
readonly duration: number;
|
|
8
|
+
readonly fixedTime?: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ImagePuppetEpisodeProof {
|
|
12
|
+
readonly contractId: string;
|
|
13
|
+
readonly episodeId: string;
|
|
14
|
+
readonly title: string;
|
|
15
|
+
readonly route: string;
|
|
16
|
+
readonly mode: "image-derived-puppet-cutouts";
|
|
17
|
+
readonly sourceImage: string;
|
|
18
|
+
readonly sourcePixelsAnimated: true;
|
|
19
|
+
readonly notTrue3D: true;
|
|
20
|
+
readonly screenshotTarget: "#image-puppet-episode";
|
|
21
|
+
readonly sample: CartoonRouteSampleForVisual;
|
|
22
|
+
readonly movingCutouts: readonly string[];
|
|
23
|
+
readonly limitations: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const sourceImage = "/aura-assets/moon-garden-feature-frame.png";
|
|
27
|
+
const movingCutouts = [
|
|
28
|
+
"blue robot source-pixel head/body cutout",
|
|
29
|
+
"blue robot source-pixel broom area",
|
|
30
|
+
"yellow robot source-pixel head/body cutout",
|
|
31
|
+
"yellow robot source-pixel arm/tool area",
|
|
32
|
+
"wheelbarrow source-pixel cutout",
|
|
33
|
+
"foreground flower source-pixel layer",
|
|
34
|
+
"moon source-pixel pulse layer"
|
|
35
|
+
] as const;
|
|
36
|
+
|
|
37
|
+
export function installImagePuppetEpisode(options: ImagePuppetEpisodeOptions) {
|
|
38
|
+
document.body.dataset.cartoonView = "image-puppet";
|
|
39
|
+
const root = document.createElement("section");
|
|
40
|
+
root.id = "image-puppet-episode";
|
|
41
|
+
root.className = "image-puppet";
|
|
42
|
+
root.setAttribute("aria-label", "Image-derived puppet animation using cutouts from the moon garden source PNG");
|
|
43
|
+
root.innerHTML = `
|
|
44
|
+
<div class="image-puppet__frame">
|
|
45
|
+
<div class="image-puppet__base" aria-hidden="true"></div>
|
|
46
|
+
<div class="image-puppet__matte image-puppet__matte--blue" aria-hidden="true"></div>
|
|
47
|
+
<div class="image-puppet__matte image-puppet__matte--yellow" aria-hidden="true"></div>
|
|
48
|
+
<div class="image-puppet__matte image-puppet__matte--cart" aria-hidden="true"></div>
|
|
49
|
+
|
|
50
|
+
<div class="image-puppet__cutout image-puppet__cutout--moon" data-source-cutout="moon" aria-hidden="true"></div>
|
|
51
|
+
<div class="image-puppet__cutout image-puppet__cutout--blue-body" data-source-cutout="blue-body" aria-hidden="true"></div>
|
|
52
|
+
<div class="image-puppet__cutout image-puppet__cutout--blue-head" data-source-cutout="blue-head" aria-hidden="true"></div>
|
|
53
|
+
<div class="image-puppet__cutout image-puppet__cutout--blue-broom" data-source-cutout="blue-broom" aria-hidden="true"></div>
|
|
54
|
+
<div class="image-puppet__cutout image-puppet__cutout--cart" data-source-cutout="cart" aria-hidden="true"></div>
|
|
55
|
+
<div class="image-puppet__cutout image-puppet__cutout--yellow-body" data-source-cutout="yellow-body" aria-hidden="true"></div>
|
|
56
|
+
<div class="image-puppet__cutout image-puppet__cutout--yellow-head" data-source-cutout="yellow-head" aria-hidden="true"></div>
|
|
57
|
+
<div class="image-puppet__cutout image-puppet__cutout--yellow-tool" data-source-cutout="yellow-tool" aria-hidden="true"></div>
|
|
58
|
+
<div class="image-puppet__cutout image-puppet__cutout--foreground" data-source-cutout="foreground" aria-hidden="true"></div>
|
|
59
|
+
|
|
60
|
+
<div class="image-puppet__hud">
|
|
61
|
+
<span>Image-derived cutouts</span>
|
|
62
|
+
<strong data-image-puppet-shot-label>Shot 1 / 3</strong>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="image-puppet__caption" data-image-puppet-caption></div>
|
|
65
|
+
<div class="image-puppet__timeline" aria-hidden="true">
|
|
66
|
+
<span class="image-puppet__timeline-fill" data-image-puppet-progress></span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
`;
|
|
70
|
+
document.body.appendChild(root);
|
|
71
|
+
|
|
72
|
+
const caption = root.querySelector<HTMLElement>("[data-image-puppet-caption]");
|
|
73
|
+
const shotLabel = root.querySelector<HTMLElement>("[data-image-puppet-shot-label]");
|
|
74
|
+
const progress = root.querySelector<HTMLElement>("[data-image-puppet-progress]");
|
|
75
|
+
const query = new URLSearchParams(window.location.search);
|
|
76
|
+
const queryTime = query.get("sampleTime");
|
|
77
|
+
const fixedTime = options.fixedTime ?? (queryTime ? Number(queryTime) : undefined);
|
|
78
|
+
const start = performance.now();
|
|
79
|
+
|
|
80
|
+
function render(time: number) {
|
|
81
|
+
const sample = options.sampleAt(clampTime(time, options.duration));
|
|
82
|
+
const shotIndex = Math.max(0, episode.shotTimeline.shots.findIndex((shot) => shot.shotId === sample.shotId));
|
|
83
|
+
const progressPercent = Math.max(0, Math.min(100, (sample.time / options.duration) * 100));
|
|
84
|
+
|
|
85
|
+
root.dataset.shotId = sample.shotId ?? "";
|
|
86
|
+
root.dataset.captionId = sample.captionId ?? "";
|
|
87
|
+
root.dataset.sourceImage = sourceImage;
|
|
88
|
+
|
|
89
|
+
if (caption) {
|
|
90
|
+
caption.textContent = sample.captionText ?? "The source image is duplicated into moving cutout layers.";
|
|
91
|
+
}
|
|
92
|
+
if (shotLabel) {
|
|
93
|
+
shotLabel.textContent = `Shot ${shotIndex + 1} / ${episode.shotTimeline.shots.length}`;
|
|
94
|
+
}
|
|
95
|
+
if (progress) {
|
|
96
|
+
progress.style.setProperty("--progress", `${progressPercent}%`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
window.__AURA3D_CARTOON_IMAGE_PUPPET_PROOF__ = {
|
|
100
|
+
contractId: episodeSampleDescription.contractId,
|
|
101
|
+
episodeId: episode.episodePlan.episodeId,
|
|
102
|
+
title: episode.episodePlan.title,
|
|
103
|
+
route: "/?view=image-puppet",
|
|
104
|
+
mode: "image-derived-puppet-cutouts",
|
|
105
|
+
sourceImage,
|
|
106
|
+
sourcePixelsAnimated: true,
|
|
107
|
+
notTrue3D: true,
|
|
108
|
+
screenshotTarget: "#image-puppet-episode",
|
|
109
|
+
sample,
|
|
110
|
+
movingCutouts,
|
|
111
|
+
limitations: [
|
|
112
|
+
"The PNG is flattened, so these are approximate masked source-pixel cutouts, not clean production layers.",
|
|
113
|
+
"The original still remains visible under the moving cutouts unless a real background plate or inpainted clean plate exists.",
|
|
114
|
+
"This is image-derived 2D animation, not 3D reconstruction or rigged GLB character animation."
|
|
115
|
+
]
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
render(Number.isFinite(fixedTime) ? Number(fixedTime) : 0);
|
|
120
|
+
const tick = () => {
|
|
121
|
+
if (!Number.isFinite(fixedTime)) {
|
|
122
|
+
render(((performance.now() - start) / 1000) % options.duration);
|
|
123
|
+
}
|
|
124
|
+
requestAnimationFrame(tick);
|
|
125
|
+
};
|
|
126
|
+
tick();
|
|
127
|
+
return root;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
declare global {
|
|
131
|
+
interface Window {
|
|
132
|
+
__AURA3D_CARTOON_IMAGE_PUPPET_PROOF__?: ImagePuppetEpisodeProof;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function clampTime(time: number, duration: number) {
|
|
137
|
+
if (!Number.isFinite(time)) return 0;
|
|
138
|
+
return Math.max(0, Math.min(duration - 1 / 30, time));
|
|
139
|
+
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
scene,
|
|
17
17
|
type AuraAssetRef
|
|
18
18
|
} from "@aura3d/engine";
|
|
19
|
+
import "./sample-episode-visual.css";
|
|
19
20
|
import { assets } from "./aura-assets";
|
|
20
21
|
import {
|
|
21
22
|
episode,
|
|
@@ -45,6 +46,7 @@ import {
|
|
|
45
46
|
visemeFrameSyncSourceProof,
|
|
46
47
|
visemeTrack
|
|
47
48
|
} from "./render-plan";
|
|
49
|
+
import { installSampleEpisodeVisual } from "./sample-episode-visual";
|
|
48
50
|
|
|
49
51
|
declare global {
|
|
50
52
|
interface Window {
|
|
@@ -64,8 +66,12 @@ declare global {
|
|
|
64
66
|
readonly bridgeIssues: readonly unknown[];
|
|
65
67
|
readonly promptAnimationEvidence: unknown;
|
|
66
68
|
readonly publishReadiness: unknown;
|
|
69
|
+
readonly releaseFacingViews: readonly string[];
|
|
70
|
+
readonly rejectedViews: readonly string[];
|
|
71
|
+
readonly rejectedViewReason: string;
|
|
67
72
|
readonly sourceProofs: unknown;
|
|
68
73
|
readonly sampleRenderSourceWorkflow: unknown;
|
|
74
|
+
diagnostics(): unknown;
|
|
69
75
|
sampleAt(time: number): unknown;
|
|
70
76
|
};
|
|
71
77
|
}
|
|
@@ -118,14 +124,22 @@ captionOverlay.dataset.captionId = playbackProbeSamples[0]?.captionId ?? firstCa
|
|
|
118
124
|
document.body.dataset.cartoonShotCount = String(episode.shotTimeline.shots.length);
|
|
119
125
|
document.body.dataset.cartoonCaptionCount = String(episode.captionTrack.cues.length);
|
|
120
126
|
document.body.dataset.cartoonStoryBibleProps = String(storyBible.props.length);
|
|
127
|
+
document.body.dataset.cartoonReleaseFacingView = "sample-episode-visual";
|
|
128
|
+
document.body.dataset.cartoonRejectedViews = "concept-2-5d,puppet-2d,image-puppet";
|
|
129
|
+
installSampleEpisodeVisual({
|
|
130
|
+
sampleAt: sampleCartoonRouteAt,
|
|
131
|
+
duration: episode.episodePlan.runtime.duration,
|
|
132
|
+
usesTypedAssets: missingCartoonCharacterAssets.length === 0
|
|
133
|
+
});
|
|
121
134
|
|
|
122
135
|
const app = createAuraApp("#app", {
|
|
123
136
|
scene: scene()
|
|
124
137
|
.background("#081b2a")
|
|
125
|
-
.
|
|
126
|
-
.add(
|
|
127
|
-
.add(
|
|
128
|
-
.add(
|
|
138
|
+
.addMany(createAuraRenderedCartoonScene())
|
|
139
|
+
.add(createCharacterBody("miko", "Miko", "miko", [-0.72, 0.08, -0.34], [0.32, 0.42, 0.32], 0.9, "#7de2ff"))
|
|
140
|
+
.add(createMouthCard("miko:mouth", "Miko", [-3.2, -3.2, -3.2], "#f8fff2"))
|
|
141
|
+
.add(createCharacterBody("luma", "Luma", "luma", [0.72, 0.08, -0.34], [0.3, 0.38, 0.3], 0.9, "#ffe18e"))
|
|
142
|
+
.add(createMouthCard("luma:mouth", "Luma", [3.2, -3.2, -3.2], "#40ffbf"))
|
|
129
143
|
.add(
|
|
130
144
|
primitives
|
|
131
145
|
.box({ name: "moon garden path", material: material.pbr({ color: "#182d3f", roughness: 0.78 }) })
|
|
@@ -134,7 +148,7 @@ const app = createAuraApp("#app", {
|
|
|
134
148
|
)
|
|
135
149
|
.add(
|
|
136
150
|
primitives
|
|
137
|
-
.sphere({ name: "glow stones primitive fallback", material: material.emissive({ color: "#ffe18e"
|
|
151
|
+
.sphere({ name: "glow stones primitive fallback", material: material.emissive({ color: "#ffe18e" }) })
|
|
138
152
|
.position(0.18, 0.16, 0.28)
|
|
139
153
|
.scale([0.16, 0.08, 0.16])
|
|
140
154
|
)
|
|
@@ -144,73 +158,11 @@ const app = createAuraApp("#app", {
|
|
|
144
158
|
.position(-0.38, 0.2, 0.18)
|
|
145
159
|
.scale([0.12, 0.24, 0.04])
|
|
146
160
|
)
|
|
147
|
-
.add(labels.hud(
|
|
161
|
+
.add(labels.hud(firstCaption?.text ?? firstStoryboardShot?.storyBeat ?? "Aura3D cartoon channel"))
|
|
148
162
|
.add(lights.studio({ intensity: 1.2 }))
|
|
149
163
|
.add(effects.bloom({ intensity: 0.18, color: "#7de2ff" }))
|
|
150
|
-
.camera(camera.perspective({ position: [0, 1.
|
|
151
|
-
diagnostics: true
|
|
152
|
-
metadata: {
|
|
153
|
-
contractId: episodeContractId,
|
|
154
|
-
template: "cartoon-channel",
|
|
155
|
-
runtimePlayback: "app.onFrame updates runtime nodes; createAuraApp is called once",
|
|
156
|
-
renderQueueItems: renderPlan.items.length,
|
|
157
|
-
renderPackageId: renderOutputPackage.packageId,
|
|
158
|
-
storyBibleId: storyBible.episodeId,
|
|
159
|
-
storyBibleProps: storyBible.props.map((prop) => prop.id),
|
|
160
|
-
styleGuide: storyBible.styleGuide.visualStyle,
|
|
161
|
-
shotListCount: storyBible.shotList.length,
|
|
162
|
-
playbackProbeSamples: playbackProbeSamples.map((sample) => ({
|
|
163
|
-
time: sample.time,
|
|
164
|
-
frame: sample.frame,
|
|
165
|
-
shotId: sample.shotId,
|
|
166
|
-
captionId: sample.captionId,
|
|
167
|
-
nodeUpdateCount: sample.nodeUpdates.length
|
|
168
|
-
})),
|
|
169
|
-
thumbnailCaptureSceneStateId: thumbnailCapture.sourceSceneStateId,
|
|
170
|
-
thumbnailCaptureTime: thumbnailCapture.time,
|
|
171
|
-
thumbnailCaptionId: thumbnailCaption?.captionId,
|
|
172
|
-
deterministicCaptureItems: renderPlan.items.filter((item) => item.sourceSceneState).length,
|
|
173
|
-
deterministicScreenshotFixtures,
|
|
174
|
-
typedAssets: typedCartoonAssetSummary,
|
|
175
|
-
requiredTypedAssets: requiredCartoonCharacterAssets,
|
|
176
|
-
missingTypedAssets: missingCartoonCharacterAssets,
|
|
177
|
-
assetCommands: publicCartoonAssetInstructions,
|
|
178
|
-
bridgeIssueCount: bridgeIssues.length,
|
|
179
|
-
bridgeSampleAtThumbnail: {
|
|
180
|
-
time: bridgeSampleAtThumbnail.time,
|
|
181
|
-
frame: bridgeSampleAtThumbnail.frame,
|
|
182
|
-
shotId: bridgeSampleAtThumbnail.shot?.shotId,
|
|
183
|
-
dialogueLineId: bridgeSampleAtThumbnail.dialogue?.lineId
|
|
184
|
-
},
|
|
185
|
-
promptAnimationEvidence: {
|
|
186
|
-
publishReady: promptAnimationEvidence.publishReady,
|
|
187
|
-
assetStatus: promptAnimationEvidence.assetStatus,
|
|
188
|
-
captions: promptAnimationEvidence.captions,
|
|
189
|
-
visemes: promptAnimationEvidence.visemes,
|
|
190
|
-
audio: promptAnimationEvidence.audio,
|
|
191
|
-
deterministicCapture: promptAnimationEvidence.deterministicCapture,
|
|
192
|
-
routeHealth: promptAnimationEvidence.routeHealth
|
|
193
|
-
},
|
|
194
|
-
publishReadiness: {
|
|
195
|
-
ready: publishReadiness.ready,
|
|
196
|
-
issueCount: publishReadiness.issues.length
|
|
197
|
-
},
|
|
198
|
-
captionTimingProof: {
|
|
199
|
-
status: captionTimingProof.status,
|
|
200
|
-
maxDriftFrames: captionTimingProof.maxDriftFrames,
|
|
201
|
-
coveredLineIds: captionTimingProof.coveredLineIds
|
|
202
|
-
},
|
|
203
|
-
captionFrameSyncSourceProof,
|
|
204
|
-
visemeFrameSyncSourceProof,
|
|
205
|
-
sampleRenderSourceWorkflow,
|
|
206
|
-
accessibilityProof: {
|
|
207
|
-
captions: accessibilityProofMetadata?.captions.status,
|
|
208
|
-
reducedMotion: accessibilityProofMetadata?.reducedMotion.status,
|
|
209
|
-
highContrast: accessibilityProofMetadata?.highContrast.status
|
|
210
|
-
},
|
|
211
|
-
primitiveMouthRuntimeExample,
|
|
212
|
-
glbVisemeRuntimeExample
|
|
213
|
-
}
|
|
164
|
+
.camera(camera.perspective({ position: [0, 1.18, 4.4], target: [0, 0.82, -0.45], fov: 38 })),
|
|
165
|
+
diagnostics: true
|
|
214
166
|
});
|
|
215
167
|
|
|
216
168
|
window.__AURA3D_CARTOON_TEMPLATE__ = {
|
|
@@ -229,12 +181,19 @@ window.__AURA3D_CARTOON_TEMPLATE__ = {
|
|
|
229
181
|
bridgeIssues,
|
|
230
182
|
promptAnimationEvidence,
|
|
231
183
|
publishReadiness,
|
|
184
|
+
releaseFacingViews: ["sample-episode-visual"],
|
|
185
|
+
rejectedViews: ["concept-2-5d", "puppet-2d", "image-puppet"],
|
|
186
|
+
rejectedViewReason:
|
|
187
|
+
"Rejected 1.0.10 puppet/parallax experiments are quarantined from the release-facing cartoon-channel route because still-image parallax, flat cutout motion, and notTrue3D proof cannot satisfy Aura3D 1.1 cartoon animation readiness.",
|
|
232
188
|
sourceProofs: {
|
|
233
189
|
captionFrameSyncSourceProof,
|
|
234
190
|
visemeFrameSyncSourceProof,
|
|
235
191
|
phonemeVisemeDubSyncSourceProof
|
|
236
192
|
},
|
|
237
193
|
sampleRenderSourceWorkflow,
|
|
194
|
+
diagnostics() {
|
|
195
|
+
return app.diagnostics();
|
|
196
|
+
},
|
|
238
197
|
sampleAt(time: number) {
|
|
239
198
|
return sampleCartoonRouteAt(time);
|
|
240
199
|
}
|
|
@@ -267,6 +226,7 @@ function createCharacterBody(
|
|
|
267
226
|
return model(asset, { name: `${name} typed character asset` })
|
|
268
227
|
.position(position[0], position[1], position[2])
|
|
269
228
|
.scale(modelScale)
|
|
229
|
+
.material(material.pbr({ color, roughness: 0.38, metallic: 0.02 }))
|
|
270
230
|
.runtime(runtime);
|
|
271
231
|
}
|
|
272
232
|
return primitives
|
|
@@ -283,13 +243,71 @@ function createMouthCard(id: "miko:mouth" | "luma:mouth", name: string, position
|
|
|
283
243
|
return primitives
|
|
284
244
|
.box({
|
|
285
245
|
name: `${name} primitive mouth card`,
|
|
286
|
-
material: material.emissive({ color
|
|
246
|
+
material: material.emissive({ color })
|
|
287
247
|
})
|
|
288
248
|
.position(position[0], position[1], position[2])
|
|
289
249
|
.scale([0.22, 0.035, 0.025])
|
|
290
250
|
.runtime(game.runtimeNode(id, { tags: ["mouth", "primitive", name.toLowerCase()] }));
|
|
291
251
|
}
|
|
292
252
|
|
|
253
|
+
function createAuraRenderedCartoonScene() {
|
|
254
|
+
const skyMat = material.emissive({ color: "#0a2941", emissive: "#0f4765", emissiveIntensity: 0.18 });
|
|
255
|
+
const gardenMat = material.pbr({ color: "#17493e", roughness: 0.64, metallic: 0.02 });
|
|
256
|
+
const pathMat = material.clearcoat({ color: "#526b62", roughness: 0.2, clearcoat: 0.4 });
|
|
257
|
+
const shadowMat = material.pbr({ color: "#020813", roughness: 0.96, opacity: 0.44 });
|
|
258
|
+
const moonMat = material.emissive({ color: "#b7f4ff", emissive: "#7de2ff", emissiveIntensity: 0.82, opacity: 0.72 });
|
|
259
|
+
const bloomCyan = material.emissive({ color: "#7de2ff", emissive: "#7de2ff", emissiveIntensity: 1.45 });
|
|
260
|
+
const bloomGold = material.emissive({ color: "#ffe18e", emissive: "#ffe18e", emissiveIntensity: 1.35 });
|
|
261
|
+
return [
|
|
262
|
+
primitives.plane({ name: "Aura3D moon garden sky plate", material: skyMat }).position(0, 1.35, -2.15).rotate(-0.04, 0, 0).scale([5.8, 1, 2.5]),
|
|
263
|
+
primitives.sphere({ name: "Aura3D glowing moon portal core", material: moonMat }).position(0, 1.35, -1.95).scale([0.62, 0.62, 0.04]),
|
|
264
|
+
primitives.torus({ name: "Aura3D moon portal rim", material: bloomCyan }).position(0, 1.35, -1.94).scale([0.78, 0.78, 0.026]),
|
|
265
|
+
...createCartoonCitySilhouette(),
|
|
266
|
+
primitives.plane({ name: "Aura3D moon garden floor", material: gardenMat }).position(0, -0.02, -0.45).scale([4.8, 1, 2.6]),
|
|
267
|
+
primitives.cylinder({ name: "Aura3D curved garden mound", material: gardenMat }).position(0, 0.03, -0.64).scale([1.72, 0.08, 0.74]),
|
|
268
|
+
primitives.box({ name: "Aura3D warm stone path", material: pathMat }).position(0, 0.06, 0.1).scale([1.58, 0.04, 0.28]),
|
|
269
|
+
primitives.cylinder({ name: "Aura3D blue robot contact shadow", material: shadowMat }).position(-0.72, 0.055, -0.34).scale([0.44, 0.012, 0.28]),
|
|
270
|
+
primitives.cylinder({ name: "Aura3D gold robot contact shadow", material: shadowMat }).position(0.72, 0.055, -0.34).scale([0.44, 0.012, 0.28]),
|
|
271
|
+
primitives.box({ name: "Aura3D broom handle", material: bloomCyan }).position(-0.25, 0.28, -0.2).rotate(0, 0, -0.6).scale([0.58, 0.035, 0.035]),
|
|
272
|
+
primitives.box({ name: "Aura3D broom bristles", material: bloomGold }).position(-0.55, 0.14, -0.18).rotate(0, 0, -0.25).scale([0.18, 0.1, 0.04]),
|
|
273
|
+
...createGlowStones(),
|
|
274
|
+
...createMoonLilies(),
|
|
275
|
+
lights.ambient({ intensity: 0.2, color: "#b9f2ff" }),
|
|
276
|
+
lights.point({ name: "Aura3D moon garden cyan key", position: [-1.8, 2.4, 1.2], color: "#7de2ff", intensity: 2.8 }),
|
|
277
|
+
lights.point({ name: "Aura3D moon garden warm robot rim", position: [1.8, 1.7, 0.8], color: "#ffe18e", intensity: 2.0 })
|
|
278
|
+
];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function createCartoonCitySilhouette() {
|
|
282
|
+
const mat = material.pbr({ color: "#071825", roughness: 0.88, metallic: 0.04 });
|
|
283
|
+
return [-2.2, -1.45, -0.62, 0.38, 1.25, 2.04].map((x, index) =>
|
|
284
|
+
primitives.box({ name: `Aura3D rounded distant city tower ${index + 1}`, material: mat })
|
|
285
|
+
.position(x, 0.45 + (index % 3) * 0.08, -1.72)
|
|
286
|
+
.scale([0.22 + (index % 2) * 0.08, 0.82 + (index % 3) * 0.18, 0.08])
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function createGlowStones() {
|
|
291
|
+
const cyan = material.emissive({ color: "#7de2ff", emissive: "#7de2ff", emissiveIntensity: 1.2 });
|
|
292
|
+
const gold = material.emissive({ color: "#ffe18e", emissive: "#ffe18e", emissiveIntensity: 1.1 });
|
|
293
|
+
return [
|
|
294
|
+
primitives.sphere({ name: "Aura3D glow stone left foreground", material: gold }).position(-1.45, 0.1, 0.22).scale([0.1, 0.045, 0.08]),
|
|
295
|
+
primitives.sphere({ name: "Aura3D glow stone center", material: cyan }).position(-0.1, 0.1, 0.0).scale([0.08, 0.035, 0.06]),
|
|
296
|
+
primitives.sphere({ name: "Aura3D glow stone right foreground", material: gold }).position(1.48, 0.1, 0.18).scale([0.1, 0.045, 0.08])
|
|
297
|
+
];
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function createMoonLilies() {
|
|
301
|
+
const petal = material.emissive({ color: "#eafcff", emissive: "#d7fbff", emissiveIntensity: 0.48 });
|
|
302
|
+
const stem = material.emissive({ color: "#40ffbf", emissive: "#40ffbf", emissiveIntensity: 0.72 });
|
|
303
|
+
return [
|
|
304
|
+
primitives.cylinder({ name: "Aura3D moon lily stem left", material: stem }).position(-1.72, 0.22, -0.2).scale([0.018, 0.24, 0.018]),
|
|
305
|
+
primitives.sphere({ name: "Aura3D moon lily bloom left", material: petal }).position(-1.72, 0.42, -0.2).scale([0.16, 0.06, 0.12]),
|
|
306
|
+
primitives.cylinder({ name: "Aura3D moon lily stem right", material: stem }).position(1.76, 0.22, -0.26).scale([0.018, 0.24, 0.018]),
|
|
307
|
+
primitives.sphere({ name: "Aura3D moon lily bloom right", material: petal }).position(1.76, 0.42, -0.26).scale([0.16, 0.06, 0.12])
|
|
308
|
+
];
|
|
309
|
+
}
|
|
310
|
+
|
|
293
311
|
function sampleCartoonRouteAt(time: number) {
|
|
294
312
|
const bridgeSample = sampleAuraVoiceBridgeAtTime(auraVoicePackage, time);
|
|
295
313
|
const playbackSample = sampleShotPlaybackPlan(shotPlaybackPlan, time);
|