Skip to content

Commit cc9e984

Browse files
jcgglclaude
andcommitted
fix: update source code viewer to reflect V1/V2 engine selector and emotion control
- Config: VERSION_V1/V2 + CDN_V1/V2 + selectedEngine - Init: dynamic engine loading with V1/V2 selection - Emotion control comments and queue flush pattern - Controls: engine select dropdown + generic "Initialize Engine" button Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 50ac28c commit cc9e984

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

examples/guide/index.html

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,7 +1623,11 @@ <h2 class="step-title">Add Real-time Microphone</h2>
16231623
'</div>',
16241624
'',
16251625
'<div class="controls">',
1626-
' <button class="btn btn-primary" id="btn-init">Initialize V1 Engine</button>',
1626+
' <select id="engine-select">',
1627+
' <option value="v1" selected>V1 — Phoneme (111-dim)</option>',
1628+
' <option value="v2">V2 — Emotion (52-dim)</option>',
1629+
' </select>',
1630+
' <button class="btn btn-primary" id="btn-init">Initialize Engine</button>',
16271631
' <button class="btn btn-secondary" id="btn-vrm">Upload VRM</button>',
16281632
' <input type="file" id="vrm-input" accept=".vrm" style="display:none">',
16291633
' <button class="btn btn-secondary" id="btn-audio" disabled>Upload Audio</button>',
@@ -1632,7 +1636,7 @@ <h2 class="step-title">Add Real-time Microphone</h2>
16321636
' <button class="btn btn-secondary" id="btn-mic" disabled>Start Mic</button>',
16331637
'</div>',
16341638
'',
1635-
'<div class="status-bar" id="status">Click "Initialize V1 Engine" to start.</div>',
1639+
'<div class="status-bar" id="status">Select engine and click "Initialize" to start.</div>',
16361640
'',
16371641
'<script type="module">',
16381642
'import * as THREE from ' + "'three'" + ';',
@@ -1642,8 +1646,11 @@ <h2 class="step-title">Add Real-time Microphone</h2>
16421646
'import { VRMAnimationLoaderPlugin, createVRMAnimationClip } from ' + "'@pixiv/three-vrm-animation'" + ';',
16431647
'',
16441648
'// \u2500\u2500 Config \u2500\u2500',
1645-
"const VERSION = '" + VERSION + "';",
1646-
'const CDN = ' + BT + 'https://cdn.jsdelivr.net/npm/@goodganglabs/lipsync-wasm-v1@' + DL + '{VERSION}' + BT + ';',
1649+
"const VERSION_V1 = '" + VERSION_V1 + "';",
1650+
"const VERSION_V2 = '" + VERSION_V2 + "';",
1651+
'const CDN_V1 = ' + BT + 'https://cdn.jsdelivr.net/npm/@goodganglabs/lipsync-wasm-v1@' + DL + '{VERSION_V1}' + BT + ';',
1652+
'const CDN_V2 = ' + BT + 'https://cdn.jsdelivr.net/npm/@goodganglabs/lipsync-wasm-v2@' + DL + '{VERSION_V2}' + BT + ';',
1653+
"let selectedEngine = 'v1';",
16471654
'',
16481655
'// ARKit 52-dim blendshape names',
16491656
"const ARKIT_52 = [",
@@ -1785,30 +1792,45 @@ <h2 class="step-title">Add Real-time Microphone</h2>
17851792
' updateControls();',
17861793
'}',
17871794
'',
1788-
'// \u2500\u2500 Initialize AnimaSync V1 \u2500\u2500',
1795+
'// \u2500\u2500 Initialize AnimaSync (V1 or V2) \u2500\u2500',
1796+
"const engineSelect = el('engine-select');",
17891797
"btnInit.addEventListener('click', async () => {",
1790-
' if (lipsync?.ready) return;',
1798+
' if (lipsync?.ready && engineSelect.value === selectedEngine) return;',
1799+
' selectedEngine = engineSelect.value;',
1800+
" const cdn = selectedEngine === 'v1' ? CDN_V1 : CDN_V2;",
1801+
" const wasmFile = selectedEngine === 'v1' ? 'lipsync_wasm_v1.js' : 'lipsync_wasm_v2.js';",
1802+
' const label = selectedEngine.toUpperCase();',
1803+
'',
1804+
' if (lipsync) { try { lipsync.reset?.(); } catch {} lipsync = null; }',
1805+
' idleGenerator = null; idleClock = 0;',
17911806
' btnInit.disabled = true;',
1792-
" btnInit.textContent = 'Initializing...';",
1793-
" setStatus('Loading WASM + ONNX model...');",
1807+
' setStatus(' + BT + 'Loading ' + DL + '{label} WASM + ONNX model...' + BT + ');',
17941808
'',
17951809
' try {',
1796-
' const { LipSyncWasmWrapper } = await import(' + BT + DL + '{CDN}/lipsync-wasm-wrapper.js' + BT + ');',
1797-
' lipsync = new LipSyncWasmWrapper({ wasmPath: ' + BT + DL + '{CDN}/lipsync_wasm_v1.js' + BT + ' });',
1810+
' const { LipSyncWasmWrapper } = await import(' + BT + DL + '{cdn}/lipsync-wasm-wrapper.js' + BT + ');',
1811+
' lipsync = new LipSyncWasmWrapper({ wasmPath: ' + BT + DL + '{cdn}/' + DL + '{wasmFile}' + BT + ' });',
17981812
' await lipsync.init({',
1799-
' onProgress: (stage, pct) => setStatus(' + BT + DL + '{stage} \\u2014 ' + DL + '{pct}%' + BT + '),',
1813+
' onProgress: (stage, pct) => setStatus(' + BT + DL + '{label} ' + DL + '{stage} \\u2014 ' + DL + '{pct}%' + BT + '),',
18001814
' });',
18011815
'',
1802-
' // Eye blink + micro expressions',
1816+
' // Eye blink + micro expressions (V1 only)',
18031817
' try {',
1804-
' idleGenerator = new lipsync.wasmModule.IdleExpressionGenerator();',
1805-
' idleClock = 0;',
1818+
' if (lipsync.wasmModule?.IdleExpressionGenerator) {',
1819+
' idleGenerator = new lipsync.wasmModule.IdleExpressionGenerator();',
1820+
' idleClock = 0;',
1821+
' }',
18061822
" } catch (e) { console.warn('Idle generator init failed:', e); }",
18071823
'',
1808-
" initBadge.textContent = 'V1 Ready';",
1824+
' initBadge.textContent = label + ' + "' Ready'" + ';',
18091825
" initBadge.className = 'status-badge badge-ready';",
1810-
" btnInit.textContent = 'Initialized';",
1811-
" setStatus('Engine ready. Upload a VRM to continue.');",
1826+
' btnInit.textContent = label + ' + "' Initialized'" + ';',
1827+
' btnInit.disabled = false;',
1828+
' setStatus(label + ' + "' engine ready. Upload a VRM to continue.'" + ');',
1829+
'',
1830+
" // Emotion control: setEmotion() available on V2",
1831+
" // Mic streaming: emotion applies per-chunk in real time",
1832+
" // File playback: emotion applies on next processFile()",
1833+
'',
18121834
' updateControls();',
18131835
' } catch (err) {',
18141836
' lipsync = null;',
@@ -1921,6 +1943,13 @@ <h2 class="step-title">Add Real-time Microphone</h2>
19211943
" setStatus('Microphone stopped.');",
19221944
'}',
19231945
'',
1946+
'// \u2500\u2500 Emotion Control (V2 only) \u2500\u2500',
1947+
'// Call lipsync.setEmotion([neutral, joy, anger, sadness, surprise]) with values 0-1.',
1948+
'// Mic streaming: emotion applies per-chunk in real time.',
1949+
'// File playback: set emotion before uploading audio.',
1950+
'// Flush queue on change so new emotion frames appear immediately:',
1951+
'// if (micActive) frameQueue.length = 0;',
1952+
'',
19241953
'// \u2500\u2500 Blendshape Helpers \u2500\u2500',
19251954
'function applyArkitBlendshapes(frame) {',
19261955
' if (!vrm?.expressionManager) return;',

0 commit comments

Comments
 (0)