@bitmagic/cli 0.1.65-dev.19 → 0.1.65-dev.20

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/README.md CHANGED
@@ -879,7 +879,16 @@ from; an image opens as the image; a sound gets a player; an animation plays on
879
879
  character — the same clip preview the Creator has — with play/pause and a speed slider. A clip
880
880
  generated from a recording also shows its source video, with the trim marked on it: the frame
881
881
  dims behind a `CUT 1.2s FROM THE START` badge whenever the playhead is inside a removed stretch,
882
- over a seek bar split into labelled `cut | kept | cut` segments. Beside it is everything the row has no
882
+ over a seek bar split into labelled `cut | kept | cut` segments.
883
+
884
+ **A character asset gets a row of built-in animations** — Idle, Walk, Run, Jump, Punch, Kick, Flip,
885
+ Dance — so you can see the body move rather than stand there. Each plays the engine's own clip on
886
+ your rigged character, with the same play/pause and speed slider; **Model** goes back to the still
887
+ mesh. The clips are looked up in your project's vendored engine, so they are the ones your game
888
+ actually plays. A very old engine has no `characterUrl` option and falls back to playing the clip
889
+ on the block character.
890
+
891
+ Beside the viewer is everything the row has no
883
892
  room for — extent in world units, voxel count, triangle count, and the asset id, with a button to
884
893
  copy it so you can paste it into a `bitmagic generate prop --asset …`. Escape closes it. The game
885
894
  pauses while it is open and resumes when you close it.
@@ -177,16 +177,58 @@ function tell(message) {
177
177
  try { window.parent.postMessage(message, window.location.origin); } catch (error) { /* detached */ }
178
178
  }
179
179
 
180
+ /**
181
+ * Turn a BUILT-IN clip name (Idle, Walk, SlowRun...) into a URL, through the project's own
182
+ * engine/AnimationAssets.js.
183
+ *
184
+ * The dev view sends a NAME rather than a URL on purpose: the animation library moves — its
185
+ * base URL is a datetime-stamped folder that changes on every publish, and which table is live
186
+ * is a per-engine decision (activeLibrary). A CLI that carried its own copy of either would go
187
+ * stale silently, showing a creator a clip their game does not use. Names are the stable part:
188
+ * they are the engine's own, and both tables use the same ones.
189
+ *
190
+ * Exact match first, then a prefix — so the name Dance finds the generated library's Dance and
191
+ * the CDN library's DanceUthana without the caller knowing which one is live.
192
+ */
193
+ async function builtinClipUrl(name) {
194
+ var assets = (await import('engine/AnimationAssets.js')).animationAssets;
195
+ var generated = assets.activeLibrary === 'generated';
196
+ var list = (generated ? assets.generatedAnimations : assets.coreAnimations) || [];
197
+ var base = generated ? assets.generatedAnimationBaseUrl : assets.animationBaseUrl;
198
+ var wanted = name.toLowerCase();
199
+ var exact = null;
200
+ var prefixed = null;
201
+ for (var i = 0; i < list.length; i++) {
202
+ var candidate = String(list[i].name || '').toLowerCase();
203
+ if (candidate === wanted) { exact = list[i]; break; }
204
+ if (prefixed === null && candidate.indexOf(wanted) === 0) prefixed = list[i];
205
+ }
206
+ var entry = exact || prefixed;
207
+ if (!entry) throw new Error('This engine has no built-in animation called ' + name + '.');
208
+ // An entry may pin its own absolute URL (the motion-captured locomotion does); the rest hang
209
+ // off the active library base.
210
+ return entry.url || (base + '/' + entry.file);
211
+ }
212
+
180
213
  try {
214
+ // A clip NAME resolves through the engine's table; an explicit url is an asset of the
215
+ // project's own and is used as it stands.
216
+ var animationUrl = params.get('url') || '';
217
+ var clip = params.get('clip') || '';
218
+ if (animationUrl === '' && clip !== '') animationUrl = await builtinClipUrl(clip);
181
219
  // Dynamic import so a project whose vendored engine predates the module reaches the catch
182
220
  // below with the browser's own "failed to fetch" instead of a blank page.
183
221
  var mod = await import('debug/AnimationPreview.js');
184
222
  var handle = await mod.startAnimationPreview({
185
- animationUrl: params.get('url') || '',
223
+ animationUrl: animationUrl,
186
224
  container: document.getElementById('stage'),
187
225
  characterHeight: mod.DEFAULT_ANIMATION_PREVIEW_OPTIONS.characterHeight,
188
226
  showGrid: true,
189
227
  paused: params.get('paused') === '1',
228
+ // The creator's own rigged character, when the dev view opened this from a character asset.
229
+ // An engine too old to know the option ignores it and plays the clip on the block mascot —
230
+ // the clip still reads, which is the better failure than refusing to show anything.
231
+ characterUrl: params.get('character') || undefined,
190
232
  });
191
233
  status.classList.add('hidden');
192
234
  controls.classList.remove('hidden');
@@ -1 +1 @@
1
- {"version":3,"file":"animation-preview-page.js","sourceRoot":"","sources":["../../src/editor/animation-preview-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAQtE,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,MAAM,GAAG,oBAAoB,QAAQ,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAC/B,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CACzF,CAAC;IACF,sFAAsF;IACtF,qFAAqF;IACrF,OAAO,EAAE,GAAG,WAAW,EAAE,GAAG,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,OAAoC;IAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACrF,OAAO;;;;;EAKP,kBAAkB;;EAElB,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2EnB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsGR,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"animation-preview-page.js","sourceRoot":"","sources":["../../src/editor/animation-preview-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAQtE,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,MAAM,GAAG,oBAAoB,QAAQ,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAC/B,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CACzF,CAAC;IACF,sFAAsF;IACtF,qFAAqF;IACrF,OAAO,EAAE,GAAG,WAAW,EAAE,GAAG,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,OAAoC;IAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACrF,OAAO;;;;;EAKP,kBAAkB;;EAElB,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2EnB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgJR,CAAC;AACF,CAAC"}
@@ -16,7 +16,7 @@
16
16
  * The surface, the pills and the modal backdrop come from `design.ts` (`.bm-overlay`,
17
17
  * `.bm-dialog`, `.bm-pill`); only what is specific to this dialog's layout lives here.
18
18
  */
19
- export declare const ASSET_DETAIL_CSS = "\n /* Above #hq-overlay, which sits at 10 \u2014 a preview opened from a row must cover it. */\n #asset-overlay { z-index: 11; }\n #asset-dialog { display: flex; width: min(1100px, 94vw); height: min(760px, 88vh);\n overflow: hidden; }\n /* The viewer takes the room. Everything else is a caption. The near-black ground is the\n brand's: a creation is the only thing on this surface that carries colour. */\n #asset-view { flex: 1; min-width: 0; position: relative; background: var(--bm-bg); }\n #asset-view iframe { display: block; width: 100%; height: 100%; border: 0; }\n #asset-view img { display: block; width: 100%; height: 100%; object-fit: contain;\n background: var(--bm-bg); }\n #asset-view audio { position: absolute; left: 50%; top: 50%; width: min(420px, 80%);\n transform: translate(-50%, -50%); }\n /* Fitted rather than filled, like the image rule above: a generated clip is 16:9 by default but\n follows its first frame when one was given, so the dialog cannot assume a shape. */\n #asset-view video { display: block; width: 100%; height: 100%; object-fit: contain;\n background: var(--bm-bg); }\n /* A note here is always a failure or a wait that has gone on too long \u2014 the negative accent. */\n #asset-note { position: absolute; inset: auto 0 0 0; padding: 10px 12px;\n background: var(--bm-scrim); color: var(--bm-pink-hover); font-size: 12px; }\n #asset-note.hidden, #asset-view > .hidden { display: none; }\n /* Wide enough for the action pills to sit on one row (wrapping to two once Edit voxels shows):\n uppercase tracked labels are wider than the sentence-case ones this panel used to have. */\n #asset-meta { width: 360px; flex: none; padding: 16px; overflow-y: auto;\n border-left: 1px solid var(--bm-border-muted); }\n #asset-meta h2 { margin: 0 0 4px; word-break: break-word; }\n #asset-meta .sub { color: var(--bm-text-dim); font-size: 12px; margin-bottom: 16px; }\n #asset-facts { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; font-size: 12px; }\n #asset-facts dt { color: var(--bm-text-dim); }\n #asset-facts dd { margin: 0; color: var(--bm-text); word-break: break-word; }\n #asset-facts dd.mono { font-family: var(--bm-font-mono); }\n #asset-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }\n /* The .hidden rules above are scoped to the viewer side; the actions row needs its own. */\n #asset-actions .hidden { display: none; }\n #asset-close { margin-left: auto; }\n";
19
+ export declare const ASSET_DETAIL_CSS = "\n /* Above #hq-overlay, which sits at 10 \u2014 a preview opened from a row must cover it. */\n #asset-overlay { z-index: 11; }\n #asset-dialog { display: flex; width: min(1100px, 94vw); height: min(760px, 88vh);\n overflow: hidden; }\n /* The viewer takes the room. Everything else is a caption. The near-black ground is the\n brand's: a creation is the only thing on this surface that carries colour. */\n #asset-view { flex: 1; min-width: 0; position: relative; background: var(--bm-bg); }\n #asset-view iframe { display: block; width: 100%; height: 100%; border: 0; }\n #asset-view img { display: block; width: 100%; height: 100%; object-fit: contain;\n background: var(--bm-bg); }\n #asset-view audio { position: absolute; left: 50%; top: 50%; width: min(420px, 80%);\n transform: translate(-50%, -50%); }\n /* Fitted rather than filled, like the image rule above: a generated clip is 16:9 by default but\n follows its first frame when one was given, so the dialog cannot assume a shape. */\n #asset-view video { display: block; width: 100%; height: 100%; object-fit: contain;\n background: var(--bm-bg); }\n /* A note here is always a failure or a wait that has gone on too long \u2014 the negative accent. */\n #asset-note { position: absolute; inset: auto 0 0 0; padding: 10px 12px;\n background: var(--bm-scrim); color: var(--bm-pink-hover); font-size: 12px; }\n #asset-note.hidden, #asset-view > .hidden { display: none; }\n /* Wide enough for the action pills to sit on one row (wrapping to two once Edit voxels shows):\n uppercase tracked labels are wider than the sentence-case ones this panel used to have. */\n #asset-meta { width: 360px; flex: none; padding: 16px; overflow-y: auto;\n border-left: 1px solid var(--bm-border-muted); }\n #asset-meta h2 { margin: 0 0 4px; word-break: break-word; }\n #asset-meta .sub { color: var(--bm-text-dim); font-size: 12px; margin-bottom: 16px; }\n #asset-facts { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; font-size: 12px; }\n #asset-facts dt { color: var(--bm-text-dim); }\n #asset-facts dd { margin: 0; color: var(--bm-text); word-break: break-word; }\n #asset-facts dd.mono { font-family: var(--bm-font-mono); }\n /* The built-in clip row, shown only for a character. Pills are the dialog's own, tightened:\n nine of them at the toolbar's tracking would run to four rows in a 360px column. */\n #asset-clips { margin-top: 16px; }\n #asset-clips.hidden { display: none; }\n #asset-clips-title { color: var(--bm-text-dim); font-size: 12px; margin-bottom: 8px; }\n #asset-clip-row { display: flex; flex-wrap: wrap; gap: 6px; }\n #asset-clip-row .bm-pill { padding: 5px 10px; letter-spacing: 1px; }\n #asset-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }\n /* The .hidden rules above are scoped to the viewer side; the actions row needs its own. */\n #asset-actions .hidden { display: none; }\n #asset-close { margin-left: auto; }\n";
20
20
  /**
21
21
  * The overlay itself.
22
22
  *
@@ -29,4 +29,4 @@ export declare const ASSET_DETAIL_CSS = "\n /* Above #hq-overlay, which sits at
29
29
  * the creator has already asked for it, and a poster frame beats a black rectangle. Muted is
30
30
  * deliberately absent — a generated clip may carry audio and this is where you would check.
31
31
  */
32
- export declare const ASSET_DETAIL_HTML = "\n <div id=\"asset-overlay\" class=\"bm-overlay\">\n <div id=\"asset-dialog\" class=\"bm-dialog\">\n <div id=\"asset-view\">\n <iframe id=\"asset-frame\" class=\"hidden\" title=\"Asset preview\"></iframe>\n <img id=\"asset-image\" class=\"hidden\" alt=\"\">\n <audio id=\"asset-audio\" class=\"hidden\" controls preload=\"none\"></audio>\n <video id=\"asset-video\" class=\"hidden\" controls playsinline preload=\"metadata\"></video>\n <div id=\"asset-note\" class=\"hidden\"></div>\n </div>\n <aside id=\"asset-meta\">\n <h2 id=\"asset-name\"></h2>\n <div class=\"sub\" id=\"asset-sub\"></div>\n <dl id=\"asset-facts\"></dl>\n <div id=\"asset-actions\">\n <button id=\"asset-edit-voxels\" class=\"bm-pill bm-pill--primary hidden\" type=\"button\" title=\"Open the 3D voxel editor: add, delete and recolor voxels, and set which ones glow\">Edit voxels</button>\n <button id=\"asset-reset\" class=\"bm-pill\" type=\"button\" title=\"Back to the angle the thumbnail uses\">Reset view</button>\n <button id=\"asset-copy\" class=\"bm-pill\" type=\"button\" title=\"Copy this asset's id\">Copy id</button>\n <button id=\"asset-close\" class=\"bm-pill bm-pill--ghost\" type=\"button\">Close</button>\n </div>\n </aside>\n </div>\n </div>\n";
32
+ export declare const ASSET_DETAIL_HTML = "\n <div id=\"asset-overlay\" class=\"bm-overlay\">\n <div id=\"asset-dialog\" class=\"bm-dialog\">\n <div id=\"asset-view\">\n <iframe id=\"asset-frame\" class=\"hidden\" title=\"Asset preview\"></iframe>\n <img id=\"asset-image\" class=\"hidden\" alt=\"\">\n <audio id=\"asset-audio\" class=\"hidden\" controls preload=\"none\"></audio>\n <video id=\"asset-video\" class=\"hidden\" controls playsinline preload=\"metadata\"></video>\n <div id=\"asset-note\" class=\"hidden\"></div>\n </div>\n <aside id=\"asset-meta\">\n <h2 id=\"asset-name\"></h2>\n <div class=\"sub\" id=\"asset-sub\"></div>\n <dl id=\"asset-facts\"></dl>\n <div id=\"asset-clips\" class=\"hidden\">\n <div id=\"asset-clips-title\">Built-in animations</div>\n <div id=\"asset-clip-row\">\n <button class=\"bm-pill\" type=\"button\" data-clip=\"\" title=\"Back to the still model\">Model</button>\n <button class=\"bm-pill\" type=\"button\" data-clip=\"Idle\">Idle</button>\n <button class=\"bm-pill\" type=\"button\" data-clip=\"Walk\">Walk</button>\n <button class=\"bm-pill\" type=\"button\" data-clip=\"SlowRun\">Run</button>\n <button class=\"bm-pill\" type=\"button\" data-clip=\"Jump\">Jump</button>\n <button class=\"bm-pill\" type=\"button\" data-clip=\"Punching\">Punch</button>\n <button class=\"bm-pill\" type=\"button\" data-clip=\"Kicking\">Kick</button>\n <button class=\"bm-pill\" type=\"button\" data-clip=\"ForwardFlip\">Flip</button>\n <button class=\"bm-pill\" type=\"button\" data-clip=\"Dance\">Dance</button>\n </div>\n </div>\n <div id=\"asset-actions\">\n <button id=\"asset-edit-voxels\" class=\"bm-pill bm-pill--primary hidden\" type=\"button\" title=\"Open the 3D voxel editor: add, delete and recolor voxels, and set which ones glow\">Edit voxels</button>\n <button id=\"asset-reset\" class=\"bm-pill\" type=\"button\" title=\"Back to the angle the thumbnail uses\">Reset view</button>\n <button id=\"asset-copy\" class=\"bm-pill\" type=\"button\" title=\"Copy this asset's id\">Copy id</button>\n <button id=\"asset-close\" class=\"bm-pill bm-pill--ghost\" type=\"button\">Close</button>\n </div>\n </aside>\n </div>\n </div>\n";
@@ -47,6 +47,13 @@ export const ASSET_DETAIL_CSS = `
47
47
  #asset-facts dt { color: var(--bm-text-dim); }
48
48
  #asset-facts dd { margin: 0; color: var(--bm-text); word-break: break-word; }
49
49
  #asset-facts dd.mono { font-family: var(--bm-font-mono); }
50
+ /* The built-in clip row, shown only for a character. Pills are the dialog's own, tightened:
51
+ nine of them at the toolbar's tracking would run to four rows in a 360px column. */
52
+ #asset-clips { margin-top: 16px; }
53
+ #asset-clips.hidden { display: none; }
54
+ #asset-clips-title { color: var(--bm-text-dim); font-size: 12px; margin-bottom: 8px; }
55
+ #asset-clip-row { display: flex; flex-wrap: wrap; gap: 6px; }
56
+ #asset-clip-row .bm-pill { padding: 5px 10px; letter-spacing: 1px; }
50
57
  #asset-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
51
58
  /* The .hidden rules above are scoped to the viewer side; the actions row needs its own. */
52
59
  #asset-actions .hidden { display: none; }
@@ -78,6 +85,20 @@ export const ASSET_DETAIL_HTML = `
78
85
  <h2 id="asset-name"></h2>
79
86
  <div class="sub" id="asset-sub"></div>
80
87
  <dl id="asset-facts"></dl>
88
+ <div id="asset-clips" class="hidden">
89
+ <div id="asset-clips-title">Built-in animations</div>
90
+ <div id="asset-clip-row">
91
+ <button class="bm-pill" type="button" data-clip="" title="Back to the still model">Model</button>
92
+ <button class="bm-pill" type="button" data-clip="Idle">Idle</button>
93
+ <button class="bm-pill" type="button" data-clip="Walk">Walk</button>
94
+ <button class="bm-pill" type="button" data-clip="SlowRun">Run</button>
95
+ <button class="bm-pill" type="button" data-clip="Jump">Jump</button>
96
+ <button class="bm-pill" type="button" data-clip="Punching">Punch</button>
97
+ <button class="bm-pill" type="button" data-clip="Kicking">Kick</button>
98
+ <button class="bm-pill" type="button" data-clip="ForwardFlip">Flip</button>
99
+ <button class="bm-pill" type="button" data-clip="Dance">Dance</button>
100
+ </div>
101
+ </div>
81
102
  <div id="asset-actions">
82
103
  <button id="asset-edit-voxels" class="bm-pill bm-pill--primary hidden" type="button" title="Open the 3D voxel editor: add, delete and recolor voxels, and set which ones glow">Edit voxels</button>
83
104
  <button id="asset-reset" class="bm-pill" type="button" title="Back to the angle the thumbnail uses">Reset view</button>
@@ -1 +1 @@
1
- {"version":3,"file":"asset-detail-panel.js","sourceRoot":"","sources":["../../src/editor/asset-detail-panel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmC/B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuBhC,CAAC"}
1
+ {"version":3,"file":"asset-detail-panel.js","sourceRoot":"","sources":["../../src/editor/asset-detail-panel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0C/B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqChC,CAAC"}
@@ -2166,6 +2166,11 @@ ${ASSET_DETAIL_HTML}
2166
2166
  var assetLoadTimer = null;
2167
2167
  // The asset the overlay is showing, for the Edit voxels action. Null whenever it is closed.
2168
2168
  var assetDetailAsset = null;
2169
+ // The rigged GLB the built-in clip pills play on — empty for everything that is not a character.
2170
+ var assetClipUrl = '';
2171
+ // Triangles arrive with the viewer's READY, and the clip pills reopen the viewer more than once
2172
+ // per dialog. Without this the fact list grows a duplicate row on every trip back to Model.
2173
+ var assetTriangleShown = false;
2169
2174
 
2170
2175
  var IMAGE_TYPES = { image: true, skybox: true };
2171
2176
  var AUDIO_TYPES = { audio: true, sound: true, 'sound-effect': true };
@@ -2216,6 +2221,7 @@ ${ASSET_DETAIL_HTML}
2216
2221
  + (asset.type || 'unknown');
2217
2222
 
2218
2223
  assetFacts.textContent = '';
2224
+ assetTriangleShown = false;
2219
2225
  fact('Size', formatSize(asset.size));
2220
2226
  fact('Length', typeof asset.durationSeconds === 'number' && asset.durationSeconds > 0
2221
2227
  ? asset.durationSeconds.toFixed(1) + 's' : '');
@@ -2235,6 +2241,14 @@ ${ASSET_DETAIL_HTML}
2235
2241
  // The asset's own file, for the types a browser can show without a renderer.
2236
2242
  var direct = typeof asset.url === 'string' ? asset.url : '';
2237
2243
 
2244
+ // A built-in clip needs a rigged body to play on, and a character asset is exactly that: a
2245
+ // GLB on the standard Mixamo skeleton. Every other type keeps the row out of sight rather
2246
+ // than disabled, for the reason Edit voxels does.
2247
+ var characterJob = type === 'character' ? glbJobFor(asset) : null;
2248
+ assetClipUrl = characterJob === null ? '' : characterJob.url;
2249
+ document.getElementById('asset-clips').classList.toggle('hidden', assetClipUrl === '');
2250
+ setActiveClip('');
2251
+
2238
2252
  // '=== true' rather than a truthy read: a type of 'constructor' would otherwise find
2239
2253
  // Object.prototype's own property and pass for an image.
2240
2254
  if (IMAGE_TYPES[type] === true && direct) {
@@ -2312,6 +2326,7 @@ ${ASSET_DETAIL_HTML}
2312
2326
  function closeAssetDetail() {
2313
2327
  if (!assetOverlay.classList.contains('show')) return false;
2314
2328
  assetDetailAsset = null;
2329
+ assetClipUrl = '';
2315
2330
  assetOverlay.classList.remove('show');
2316
2331
  if (assetLoadTimer) clearTimeout(assetLoadTimer);
2317
2332
  // about:blank rather than hiding it: an idle iframe would hold a WebGL context and a render
@@ -2346,7 +2361,8 @@ ${ASSET_DETAIL_HTML}
2346
2361
  if (message.type === 'ASSET_PREVIEW_READY') {
2347
2362
  if (assetLoadTimer) clearTimeout(assetLoadTimer);
2348
2363
  assetNote.classList.add('hidden');
2349
- if (typeof message.triangles === 'number' && message.triangles > 0) {
2364
+ if (typeof message.triangles === 'number' && message.triangles > 0 && !assetTriangleShown) {
2365
+ assetTriangleShown = true;
2350
2366
  fact('Triangles', message.triangles.toLocaleString());
2351
2367
  }
2352
2368
  } else if (message.type === 'ASSET_PREVIEW_FAILED') {
@@ -2394,6 +2410,52 @@ ${ASSET_DETAIL_HTML}
2394
2410
  post('EDIT_VOXEL_ASSET', { assetId: assetId });
2395
2411
  }
2396
2412
 
2413
+ /**
2414
+ * The built-in animation pills — the dev view's answer to "what does this character look like
2415
+ * moving?", which a still mesh cannot show.
2416
+ *
2417
+ * The pills carry NAMES, not URLs, and /animation-preview resolves them against the project's
2418
+ * own engine/AnimationAssets.js. That is deliberate: the animation library lives in a
2419
+ * datetime-stamped folder that changes on every publish, and which of the two tables is live is
2420
+ * the engine's decision. A copy of either here would go stale with nothing to catch it, and
2421
+ * would show a creator a clip their game does not actually play.
2422
+ *
2423
+ * The empty name is the Model pill: back to the still asset viewer, which is what the dialog
2424
+ * opens on. Reset view goes with it — it speaks to the orbit viewer only, and a dead button on
2425
+ * a playing clip is worse than no button.
2426
+ */
2427
+ function setActiveClip(name) {
2428
+ var pills = document.querySelectorAll('#asset-clip-row button');
2429
+ for (var i = 0; i < pills.length; i++) {
2430
+ // The accent, not --pressed: this is a tab-like selector, and DESIGN.md spends aquamarine on
2431
+ // the active tab. --pressed reads as the same dark pill as its neighbours at this size, which
2432
+ // left the creator with no way to tell which clip was playing. Edit voxels is hidden for a
2433
+ // character asset, so this is still the one primary on the surface.
2434
+ pills[i].classList.toggle('bm-pill--primary', pills[i].getAttribute('data-clip') === name);
2435
+ }
2436
+ }
2437
+
2438
+ function playAssetClip(name) {
2439
+ if (assetClipUrl === '') return;
2440
+ setActiveClip(name);
2441
+ assetNote.classList.add('hidden');
2442
+ if (assetLoadTimer) clearTimeout(assetLoadTimer);
2443
+ assetImage.classList.add('hidden');
2444
+ assetResetButton.classList.toggle('hidden', name !== '');
2445
+ assetFrame.classList.remove('hidden');
2446
+ assetFrame.src = name === ''
2447
+ ? '/asset-preview?kind=glb&url=' + encodeURIComponent(assetClipUrl)
2448
+ : '/animation-preview?character=' + encodeURIComponent(assetClipUrl)
2449
+ + '&clip=' + encodeURIComponent(name);
2450
+ assetLoadTimer = setTimeout(function () {
2451
+ showAssetNote('Still loading. If this does not clear, check the dev server output.');
2452
+ }, 12000);
2453
+ }
2454
+
2455
+ document.getElementById('asset-clip-row').addEventListener('click', function (event) {
2456
+ var button = event.target.closest('button[data-clip]');
2457
+ if (button) playAssetClip(button.getAttribute('data-clip'));
2458
+ });
2397
2459
  document.getElementById('asset-edit-voxels').addEventListener('click', function () {
2398
2460
  void startVoxelEditFromOverlay();
2399
2461
  });
@@ -1 +1 @@
1
- {"version":3,"file":"shell-page.js","sourceRoot":"","sources":["../../src/editor/shell-page.ts"],"names":[],"mappings":"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EAAE;;;;;;;;0BAQF,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA4hCvC,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA01C1C,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmChB,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"shell-page.js","sourceRoot":"","sources":["../../src/editor/shell-page.ts"],"names":[],"mappings":"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EAAE;;;;;;;;0BAQF,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA4hCvC,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAw5C1C,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmChB,CAAC;AACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitmagic/cli",
3
- "version": "0.1.65-dev.19",
3
+ "version": "0.1.65-dev.20",
4
4
  "description": "Build Bitmagic games from your own agent tool",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Bitmagic Oy",
@@ -25,9 +25,9 @@
25
25
  "playwright-core": "^1.59.1",
26
26
  "tar": "^7.4.3",
27
27
  "ws": "^8.21.3",
28
- "@bitmagic/asset-core": "0.2.20-dev.19",
29
- "@bitmagic/animation-forger": "0.1.20-dev.19",
30
- "@bitmagic/world-forger": "0.1.25-dev.19"
28
+ "@bitmagic/animation-forger": "0.1.20-dev.20",
29
+ "@bitmagic/asset-core": "0.2.20-dev.20",
30
+ "@bitmagic/world-forger": "0.1.25-dev.20"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@eslint/js": "^9.38.0",