Mugen87 / three-m2loader

three.js loader for importing M2 assets from World of Warcraft.
MIT License
25 stars 8 forks source link

Texture-animation applied to too many parts #9

Closed Mat2095 closed 9 months ago

Mat2095 commented 9 months ago

https://github.com/Mugen87/three-m2loader/assets/11258252/263c8def-79c2-4953-ab8b-80dec9deeca8

The model in the middle is done with the three-m2loader. The one on the left is done with x3dom (up until 2014 https://wowmodelviewer.net/ had a x3d export), which supports skeletal-animations but no texture-animations. The one on the right is done with https://github.com/Deamon87/WebWowViewerCpp which supports both.

M2Loader applies texture-animations to parts of the model that souldn't have texture-animation. In this case, it can be seen on the hands/bracelets of the elemental. They should be static, but M2Loader still "scrolls them around".

Mugen87 commented 9 months ago

Can you share the M2 asset in this thread? Or maybe you can just share the file ID so I can download the asset from https://wow.tools/.

Mugen87 commented 9 months ago

I've published a new release with a fix that should resolve the animation targeting issue (see d278d862b929061fb04c2e9d369e64c319526f50).

Note this is a breaking change since you have to playback animations on app level in a different way than before.

Mat2095 commented 9 months ago

The file-IDs are: 122877 (airelemental.m2) for the model itself, 122878 as the "main texture" (that M2-Loader expects as 0.blp) and in addition files 189281.blp, 243229.blp, 472554.skin.

I've tried using the new version (including the adjustments to test/index.html). It seems like the animation is still applied to the incorrect parts, but now the animation "jumps back" at seemingly random times.

https://github.com/Mugen87/three-m2loader/assets/11258252/cbcce32b-ef61-40e2-81dd-ea82dda2c6ca

Also I just realised, while the x3d version has some skeletal-animations, they are incomplete. The actual model (and the one from WebWowViewer) does rotate the "shells". Previously I thought the rotation-effect was a texture-animation only, and the skeletal-animation would just "wobble" a bit like the x3d-model. But I guess the rotation-effect is done with a combination of texture-animation and skeletal-animation. That makes it difficult to know how the texture-animation should look like alone (without skeletal-animaitons).

Mugen87 commented 9 months ago

Ah, the flickering happens because the example now plays all available animations. Try it with

for ( const entry of animationMap ) {

    const [ object, animations ] = entry;

    const mixer = new THREE.AnimationMixer( object );
    mixers.push( mixer );

    if ( animations.size > 0 ) {

        const clip = animations.values().next().value; // select first clip
        const action = mixer.clipAction( clip );
        action.play();

    }

}

But yeah, the textures are animated on the entire mesh.

Mat2095 commented 9 months ago

I can confirm, this fixes the flickering.

Mugen87 commented 9 months ago

I think 06146534b311f9ab9c95cfa676b3d941ba233ae1 should fix the issue.

Now I wonder why the bracelets are duplicated 🤔 .

Mat2095 commented 9 months ago

Yes, the texture animation is now applied correctly. Thanks for the quick fix!

https://github.com/Mugen87/three-m2loader/assets/11258252/c77d54c1-1d98-46bc-9da9-59fa14e12a43

I have a theory about the bracelets: for the death-animation the elemental raises its arms, disappears and the bracelets fall to the ground. At the moment the elemental disappears, his arms are in the position of the duplicate bracelets. I assume the model has two parts. One is elemental plus bracelets and two is just the bracelets. And during the death-animation they get swapped. I don't know why the part that should be hidden is shown, maybe that has to do with M2Loader not supporting skeletal-animations. so #2 .

Mugen87 commented 9 months ago

I have implemented basic support for skeletal animation but the bracelets are still visible above the air elemental. There must be some other sort of flag or setting that controls the visibility.

https://github.com/Mugen87/three-m2loader/assets/12612165/04f34b05-714a-4202-aff4-a730f290ec2c

Mat2095 commented 9 months ago

Hm, interesting. Did you notice, the left bracelet (from the elementals perspective) is rotating very slightly? ^^ I took a quick glance at https://wowdev.wiki/M2 and was quite overwhelmed, M2 seems more complex than I thought.

Mugen87 commented 9 months ago

I think the missing data are located in the color and transparency section which is not yet applied to the assets. When debugging you can see that the elemental defines alpha data which have to be honored during the animation somehow.

Did you notice, the left bracelet (from the elementals perspective) is rotating very slightly? ^^

Yep, but I think that is the expected transformation according to the animated data. When the alpha data would be correctly honored, you wouldn't see these bracelets anyway.

Mugen87 commented 9 months ago

I have released a new version 2.2.0 that supports animated colors and alpha which displays the elemental correctly now.

https://github.com/Mugen87/three-m2loader/assets/12612165/f429a7f7-c05c-40b7-aed3-ff8cfc6e8fb6

However, the animation and timeline system of M2 is a tricky to implement with three.js. Whenever you playback a character animation, you have to play the corresponding ColorAndAlpha_ material clip as well (meaning the clip with the same index). Right now, the keyframe tracks for animating bones and materials can't be in one clip which is why you have to manage both separately on app level.

Mat2095 commented 9 months ago

Wow, nice work! The elemental has come a long way ^^ Well, I'd still say getting three.js and M2Loader to run was easier for me than X3D and WebWowViewerCpp ^^

Mugen87 commented 9 months ago

However, the animation and timeline system of M2 is a tricky to implement with three.js. Whenever you playback a character animation, you have to play the corresponding ColorAndAlpha_ material clip as well (meaning the clip with the same index). Right now, the keyframe tracks for animating bones and materials can't be in one clip which is why you have to manage both separately on app level.

FYI: There is a new version 3.0.0 out that redesigns the animation playback. There is now a SequenceManager that simplifies the playback of animations. It makes sure all clips that belong to the same sequence (which is more or less an animation in terms of Wow) are not played automatically together. The example also lists now all available animations in the GUI similar to other viewers.

Mat2095 commented 9 months ago

Oh, that's convenient. And I see the elemental now plays the global skeletal-animation, which it didn't before. I guess by now my choice for which viewer (x3d, m2loader or WebWowViewerCpp) I will use for a project has become simple ^^