OppaAI commited on
Commit
f41d624
·
1 Parent(s): 9cc47a5

refactor: adjust mouth clamping, jaw rotation, and viseme mappings while removing redundant mesh double-sided rendering logic

Browse files
Files changed (1) hide show
  1. ui/vrm.py +12 -19
ui/vrm.py CHANGED
@@ -252,11 +252,9 @@ def avatar_html(vrm_urls: str | list[str]) -> str:
252
  if (persistent) persistentEmotion = name;
253
  }}
254
 
255
- const MAX_MOUTH_WEIGHT = 0.7; // Cap mouth open to prevent chin mesh stretching artifacts
256
-
257
  function setMouth(weight, viseme = 'ih') {{
258
  if (!vrm) return;
259
- const clamped = Math.max(0, Math.min(MAX_MOUTH_WEIGHT, Number(weight) || 0));
260
  let preset = VISEME_MAP[viseme] ?? viseme ?? 'ih';
261
  if (preset === 'aa') preset = 'ih'; // Disable 'aa' completely due to chin artifact
262
  let usedExpression = false;
@@ -267,10 +265,16 @@ def avatar_html(vrm_urls: str | list[str]) -> str:
267
  usedExpression = true;
268
  }}
269
  }}
 
 
 
 
 
 
270
  }}
271
  if (!usedExpression) {{
272
  const jaw = vrm.humanoid?.getNormalizedBoneNode?.('jaw') || vrm.humanoid?.getRawBoneNode?.('jaw');
273
- if (jaw) jaw.rotation.x = clamped * 0.35;
274
  }}
275
  }}
276
 
@@ -716,18 +720,7 @@ def avatar_html(vrm_urls: str | list[str]) -> str:
716
  vrm = gltf.userData.vrm;
717
  window._aikoVrm = vrm;
718
  VRMUtils.removeUnnecessaryVertices(vrm.scene);
719
- vrm.scene.traverse(o => {{
720
- if (o.frustumCulled) o.frustumCulled = false;
721
- // Fix white chin artifacts: force double-sided rendering so
722
- // back-faces of stretched mouth/chin geometry render correctly
723
- // instead of showing as bright white patches.
724
- if (o.isMesh && o.material) {{
725
- const mats = Array.isArray(o.material) ? o.material : [o.material];
726
- for (const mat of mats) {{
727
- mat.side = THREE.DoubleSide;
728
- }}
729
- }}
730
- }});
731
  vrm.scene.rotation.y = 0;
732
  scene.add(vrm.scene);
733
 
@@ -765,12 +758,12 @@ def avatar_html(vrm_urls: str | list[str]) -> str:
765
  const audioMouth = speaking ? getAudioMouth() : null;
766
 
767
  if (audioMouth !== null) {{
768
- setMouth(audioMouth, textMouth?.viseme ?? 'ih');
769
  }} else if (textMouth) {{
770
  setMouth(textMouth.weight, textMouth.viseme);
771
  }} else if (speaking) {{
772
- mouth = 0.10 + Math.abs(Math.sin(now / 110)) * 0.50;
773
- setMouth(mouth, 'ih');
774
  }} else {{
775
  smoothedAudioMouth = 0;
776
  clearMouth();
 
252
  if (persistent) persistentEmotion = name;
253
  }}
254
 
 
 
255
  function setMouth(weight, viseme = 'ih') {{
256
  if (!vrm) return;
257
+ const clamped = Math.max(0, Math.min(1, Number(weight) || 0));
258
  let preset = VISEME_MAP[viseme] ?? viseme ?? 'ih';
259
  if (preset === 'aa') preset = 'ih'; // Disable 'aa' completely due to chin artifact
260
  let usedExpression = false;
 
265
  usedExpression = true;
266
  }}
267
  }}
268
+ try {{
269
+ const em = vrm.expressionManager;
270
+ if (em._expressions) {{
271
+ em._expressions.forEach(expr => expr.applyWeight({{ multiplier: 1 }}));
272
+ }}
273
+ }} catch (_) {{}}
274
  }}
275
  if (!usedExpression) {{
276
  const jaw = vrm.humanoid?.getNormalizedBoneNode?.('jaw') || vrm.humanoid?.getRawBoneNode?.('jaw');
277
+ if (jaw) jaw.rotation.x = clamped * 0.5;
278
  }}
279
  }}
280
 
 
720
  vrm = gltf.userData.vrm;
721
  window._aikoVrm = vrm;
722
  VRMUtils.removeUnnecessaryVertices(vrm.scene);
723
+ vrm.scene.traverse(o => {{ if (o.frustumCulled) o.frustumCulled = false; }});
 
 
 
 
 
 
 
 
 
 
 
724
  vrm.scene.rotation.y = 0;
725
  scene.add(vrm.scene);
726
 
 
758
  const audioMouth = speaking ? getAudioMouth() : null;
759
 
760
  if (audioMouth !== null) {{
761
+ setMouth(audioMouth, textMouth?.viseme ?? 'aa');
762
  }} else if (textMouth) {{
763
  setMouth(textMouth.weight, textMouth.viseme);
764
  }} else if (speaking) {{
765
+ mouth = 0.12 + Math.abs(Math.sin(now / 110)) * 0.65;
766
+ setMouth(mouth, 'aa');
767
  }} else {{
768
  smoothedAudioMouth = 0;
769
  clearMouth();