Dance library: bundled clips bind to any rigged model + repertoire + manual BPM
- models/dance_library.glb: skeleton-only GLB with the 13 Mixamo dances, loaded at startup and bound BY BONE NAME to whatever rigged GLB the user loads — new models dance immediately, no baking needed. - Repertoire UI (Media tab): checkbox chips of the available clips, the director only picks the ticked ones (none = all); persisted. - 'Aggiungi animazioni': extra .glb clips load directly; .fbx are converted on the fly by Blender via a new anim:convert IPC and the bundled scripts/fbx2animglb.py (asarUnpacked for packaged builds). - Manual BPM with TAP tempo: 0 = follow the detected beat, otherwise a pure metronome drives the dance clock. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
83fc655219
commit
97376b22c9
10 files changed
+340
-20
No files matched your search
@@ -321,6 +321,18 @@ djv.onControl(async (m) => {
|
||||
break;
|
||||
case 'svg': loadCustomTexture(m.dataUrl); break;
|
||||
case 'modelBg': viz.modelBg = m.mode || 'gradient'; break;
|
||||
case 'glbAnims': viz.setClipFilter(m.names || []); break;
|
||||
case 'modelBpm': viz.setManualBpm(m.bpm || 0); break;
|
||||
case 'animAdd':
|
||||
// extra animation GLB for the dance library
|
||||
try {
|
||||
const b = await djv.readFile(m.path);
|
||||
if (!b) throw new Error('file non leggibile');
|
||||
const names = viz.addAnimLibrary(b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength));
|
||||
reportClips();
|
||||
if (names.length) djv.report({ type: 'animAdded', names });
|
||||
} catch (e) { djv.report({ type: 'error', message: 'Animazione: ' + e.message }); }
|
||||
break;
|
||||
case 'glb':
|
||||
try {
|
||||
const bytes = await djv.readFile(m.path);
|
||||
@@ -329,6 +341,7 @@ djv.onControl(async (m) => {
|
||||
const ok = viz.setModelData(buf);
|
||||
if (ok === false) throw new Error((viz.model3d && viz.model3d.loadError) || 'GLB non valido');
|
||||
djv.report({ type: 'glbLoaded', name: m.path.split('/').pop() });
|
||||
reportClips();
|
||||
hideHint();
|
||||
} catch (e) { djv.report({ type: 'error', message: 'GLB: ' + e.message }); }
|
||||
break;
|
||||
@@ -615,5 +628,18 @@ function frame() {
|
||||
}
|
||||
requestAnimationFrame(frame);
|
||||
|
||||
// Tell the panel which dance clips the current model can play.
|
||||
function reportClips() {
|
||||
const names = viz.model3d && viz.model3d.anims ? viz.model3d.anims.map(a => a.name) : [];
|
||||
djv.report({ type: 'glbClips', names });
|
||||
}
|
||||
|
||||
// Bundled dance library (skeleton-only GLB with the Mixamo clips): binds to
|
||||
// any rigged model the user loads.
|
||||
fetch('djvres://models/dance_library.glb')
|
||||
.then(r => r.arrayBuffer())
|
||||
.then(b => { viz.setAnimLibrary(b); reportClips(); })
|
||||
.catch(() => { /* library optional: models with own clips still dance */ });
|
||||
|
||||
// Populate the device list once at startup so the control dropdown fills in.
|
||||
reportDevices();
|
||||
Reference in new issue
Block a user