Modello 3D family: audio-reactive GLB model renderer

New model3d.js: minimal GLB loader (JSON+BIN chunks, accessors with
byteStride, node hierarchy baked into vertices, embedded PNG/JPEG base
colour textures) and a WebGL2 renderer on the shared canvas — palette
fill light, beat-pulsing fresnel rim, treble speculars, bass breathing
via normal displacement, orbiting camera auto-fitted to the bounding
box, gradient backdrop with a bass glow. A generated torus knot shows
before any GLB is loaded. 'Carica un modello .glb' button in the SVG
section; the path persists and is re-sent when the output restarts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
lucianoandClaude Fable 5 committed 2026-07-30 18:12:28 +02:00
1 parent b90066de6a
commit 65fb6ae895
7 files changed
+498 -2

No files matched your search

+25
View File
@@ -143,6 +143,30 @@ $('#svg-input').addEventListener('change', (e) => {
e.target.value = '';
});
// --- 3D model (GLB) for the 'Modello 3D' family -----------------------------
// The path persists and is re-sent when the output window (re)starts.
let glbPath = localStorage.getItem('glb3d') || '';
function glbSend() { if (glbPath) send({ type: 'glb', path: glbPath }); }
function glbLabel(name) {
$('#glb-name').textContent = name
? '🧊 ' + name + ' — attiva la famiglia “Modello 3D” per vederlo.'
: 'Il modello ruota a tempo di musica nella famiglia “Modello 3D”.';
}
if (glbPath) glbLabel(glbPath.split('/').pop());
$('#btn-glb-load').addEventListener('click', () => $('#glb-input').click());
$('#glb-input').addEventListener('change', (e) => {
const f = e.target.files[0];
if (!f) return;
const p = djv.pathForFile(f);
if (p) {
glbPath = p;
localStorage.setItem('glb3d', p);
glbSend();
glbLabel(f.name);
}
e.target.value = '';
});
// --- Effect sequence (playlist of effects with auto-cycle) ---
let sequence = []; // { effect, key }
let seqIndex = -1;
@@ -1495,6 +1519,7 @@ djv.onReport((m) => {
// The output reports its devices once at startup: good moment to push
// config the (possibly recreated) output window doesn't have yet.
if (ledCfg.on) ledSend();
glbSend();
const sel = $('#device-select');
const cur = sel.value;
sel.innerHTML = '<option value="">— Input live (mic/line/BlackHole) —</option>';