Coder Social home page Coder Social logo

three-m2loader's People

Contributors

mat2095 avatar mugen87 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

three-m2loader's Issues

Add Skeletal Animation.

M2Loader does not yet support skeletal animation which is however the most important animation technique for character models.

I've tried to implement the feature and tested it with druidcat2.m2 however the geometry gets distorted and not properly animated. Unfortunately, https://wowdev.wiki/ does not provide enough information about how the skeleton should be built and integrated in the scene graph.

Improve the parsing of chunked assets.

Starting with Legion, M2 assets might be chunked. M2Loader only support a small subset of chunks for far. To improve the compatibility with newer files, chunk parsing support has to be improved. Possible chunks are:

  • MD21
  • PFID
  • SFID
  • AFID
  • BFID
  • TXAC
  • EXPT
  • EXP2
  • PABC
  • PADC
  • PSBC
  • PEDC
  • SKID
  • TXID
  • LDV1
  • RPID
  • GPID
  • WFV1
  • WFV2
  • PGD1
  • WFV3
  • PFDC
  • EDGF
  • NERF

Checked entries are at least partially supported or not implemented for a specific reasons. The idea is to use the parsed chunk data as an alternative data source for building three.js entities.

Add support for loading `.anim` files.

Low priority sequences (like emotes) are not embedded in M2 files but located in separate files with .anim extensions. There is such a file for each low priority sequence and it can be identified via the sequence and subsequence id.

Each sequence that does not hold the 0x20 value in its flag is a called external sequence and must be processed in a separate code path.

I think it's best to introduce an option (loadExternalSequences) that can be passed to the load() method. It's default value would be false. When set to true, the loader automatically loads all external .anim files. Their content is stored as array buffers internally and used when parsing tracks.

How to reliably detect static/animated models?

It would be good to know if there is an intended way to detect whether an object is animated or not. Right now, M2Loader counts the number of bones although this approach is not robust.

three-m2loader/M2Loader.js

Lines 394 to 397 in e71c776

// TODO: Find out a better way for detecting static models
// Problem: Even static models have some bone definitions
if ( boneDefinitions.length < 8 ) return null;

Global Animation with different track-length

xAvsrWaplr.mp4

When testing the new version with the air-elemental, I noticed one problem: the "shells" pause after each rotation, while they should rotate continuously. The issue seems to be that the skeletal-animation has tracks of different duration and THREE.js sets the duration for the whole clip to the maximum of the tracks, so the shorter tracks have to wait for the longer ones to finish.

For this instance I could fix it by simply adding a separate clip for each track, like this:

three-m2loader/M2Loader.js

Lines 425 to 426 in 7fe01af

const clip = new AnimationClip( 'GlobalSkeletonAnimation_' + j, - 1, [ ... globalTracks[ j ] ] );
sequenceManager.addAnimationToGlobalSequence( clip, group, j );

replace with

        for ( let t = 0; t < globalTracks[ j ].length; t++) {
          const clip = new AnimationClip( 'GlobalSkeletonAnimation_' + j + '_' + t, - 1, [  globalTracks[ j ][ t ] ] );
          sequenceManager.addAnimationToGlobalSequence( clip, group, j );
        }

However I have no idea if that has implications. Probably that should be done for other global animations as well. The airelemental also uses multiple GlobalTextureTransform-Animations, but they all only have a single track, so no issue there. And for non-global animations, all tracks (excluding ones with length 0) have the same length for the airelemental, but I have no idea if that is always the case, and whether tracks should loop individually if tracks do have different lengths.

Better support for early game assets.

Hey I basically used the code in your ./test dir to test how it loads vanilla .m2 files.

I get this
RangeError: Offset is outside the bounds of the DataView at DataView.getUint32 (<anonymous>) at BinaryParser.readUInt32 (M2Loader.js:1875:25) at M2Loader._readTrack (M2Loader.js:1176:25) at M2Loader._readBoneDefinition (M2Loader.js:802:27) at M2Loader._readBoneDefinitions (M2Loader.js:828:22) at M2Loader.parse (M2Loader.js:150:32) at Object.onLoad (M2Loader.js:66:10) at three.module.js:39951:38

Any ideas?

Make sure legacy track data can be parsed.

M2 files lower than Wrath of the Lich King (264) use a legacy data structure for tracks. It would be good for compatibility to support this format if the required code paths for parsing and key frame creation are manageable.

Synchronize animations with different durations

I've noticed an issue with the WotLK-Version of the airelemental:

bSnxhbFc2T.mp4

When playing the death-sequence, the "main body" of the elemental should disappear, but that doesn't work. This is because the sequence consists of animations with different duration. Some are 3 seconds long, but some (those that fade out the body) are only ~0.9 seconds long. They set the opacity to 0 right at the end of those 0.9 seconds, but then the animation already loops and opacity is back at 1. Instead the animation should wait until all animations of that sequence are finished.
This is almost the opposite of #13.

I tried synchronizing the animations in this commit:
fcbeb7b
And it works for that case:

6CIAsmF1Z7.mp4

That looks like it does in game, except the hands and eyes should disappear as well, not sure what's the issue with that.

But I'm not too happy with the code as it really takes active control over the animation-orchestration. I'd rather let tree.js handle it, but I don't think that's possible, since the animations might have different root-objects and thus different mixers, which is why I couldn't get it done with https://threejs.org/docs/index.html#api/en/animation/AnimationAction.syncWith (according to ChatGPT, I have no idea if that's true).
Also I have no idea if doing it this way is always correct or if for some sequences this is wrong. Especially since the death-sequence doesn't really loop ingame anyway, so having the animations loop doesn't make sense. But for sequences like Stand/Walk/Run, maybe it is correct that animations loop individually instead of waiting.

Problem finding .blp and .skin

Hello, in your example in the test folder I saw that bearmount.m2 is used, I exported all the files with wow.export but threem2loader searches for textures and skins by fileDataID and not by file name. After I looked at bearmount.manifest.json and renamed all the .blp and .skin file names to {fileDataID}.blp everything worked. Is there any way to fix this?

Texture-animation applied to too many parts

Uk8WhawU3D.mp4

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".

Looking for M2 asset with embedded skin data.

Since Wrath of the Lich King, skin profiles are stored in separate .skin files. However, earlier M2 assets stored the data in the M2 itself. It would be good to know the filename of such an asset for testing (https://wow.tools/) so the below code path can be implemented and verified:

three-m2loader/M2Loader.js

Lines 160 to 164 in e71c776

if ( header.version <= M2_VERSION_THE_BURNING_CRUSADE ) {
// TODO: read embedded skin data
} else {

Looking for M2 asset with animated colors.

M2 allows to animate the color and transparency of vertices. The loader already parses M2Color but it does not yet map the data to three.js entities. AFAICS, M2Color.color would animate Material.color and M2Color.alpha would animate Material.opacity(next to texture weights).

It would be good to know the filename of such an asset for testing (https://wow.tools/) so _readColors() can verified and the animation implemented:

const colors = this._readColors( parser, header ); // eslint-disable-line no-unused-vars

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.