pixiv / ChatVRM

MIT License
710 stars 200 forks source link

Glitch occurs when playing animation file downloaded from Mixamo #9

Closed trend-surf closed 4 months ago

trend-surf commented 1 year ago

Problem

A glitch occurs when playing an animation file downloaded from Mixamo.

Steps to reproduce

  1. Download an animation file (fbx) from Mixamo.
  2. Convert it to glb.
  3. Use VRMAnimation.ts to play it.

Expected result

The animation plays smoothly without any glitch.

Actual result

Glitches occur in some cases.

Possible solution

The glitch does not occur when I modify the code as follows (VRMAnimation.ts):

-       const track = new THREE.VectorKeyframeTrack(
-          `${nodeName}.quaternion`,
-          origTrack.times,
-          origTrack.values.map((v, i) =>
-            metaVersion === "0" && i % 2 === 0 ? -v : v
-          )
-       );
+      const newValues: number[] = [];
+      const metaVersionZero = metaVersion === "0";
+      let sign = metaVersionZero ? -1 : 1;
+      let opposite = metaVersionZero ? 1 : 1;
+      let prevQuaternion = new THREE.Quaternion();
+
+      if (origTrack.values.length % 4 !== 0) {
+        throw new Error("Invalid origTrack values length");
+      }
+        
+      for (let i = 0; i < origTrack.values.length; i += 4) {
+          const quaternion = new THREE.Quaternion(
+              origTrack.values[i],
+              origTrack.values[i + 1],
+              origTrack.values[i + 2],
+              origTrack.values[i + 3]
+          );
+          if (prevQuaternion.dot(quaternion) < 0 && metaVersionZero) {
+              sign *= -1;
+              opposite *= -1;
+          }
+          newValues.push(
+              sign * origTrack.values[i],
+              opposite * origTrack.values[i + 1],
+              sign * origTrack.values[i + 2],
+              opposite * origTrack.values[i + 3]
+          );
+          prevQuaternion = quaternion;
+      }
+      const track = origTrack.clone();
+      track.values = new Float32Array(newValues);
+      track.name = `${nodeName}.quaternion`;

Before:

https://github.com/pixiv/ChatVRM/assets/87652581/d6c1865f-23b1-442d-be40-4297c52fc804

After:

https://github.com/pixiv/ChatVRM/assets/87652581/215893ad-a6bc-40fa-8382-92d2712b086a


I'm not very familiar with 3D graphics, so I apologize if my corrections are not accurate. Please consider them as references only 😂

yakotoka commented 1 year ago

Do you have a gist of the file you used to play the glb? Did you simply update the VRMAnimation.ts file? It's very cool what you have!

trend-surf commented 1 year ago

Did you simply update the VRMAnimation.ts file?

Yes, that's all I've done!


FYI: I wrote a blog post about it, so it might be helpful for you. https://qiita.com/galpro/items/bdc2bdcbd6f4cf99e157

0b5vr commented 4 months ago

ChatVRM is intended to share technology and provide demonstrations, and this repository has not been actively operated. Considering our maintenance system, we will archive this repository with the current code. If you would like to change ChatVRM in the future, we would appreciate it if you fork it. We apologize for the late response to your kind contributions.