mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.81k stars 35.38k forks source link

FBXLoader does not pay attention to TimeMode #12332

Closed ignazioa closed 5 years ago

ignazioa commented 7 years ago
(fixed) framerate is hardcoded to 30

Both TimeMode and TimeProtocol (FBXTree.GlobalSettings) are parsed correctly but fps are hardcoded to 30 in several places in the code. As a result animations with different (fixed) frame-rates do not play correctly (nor they have the correct number of frames).

Three.js version
Browser
OS
Hardware Requirements (graphics card, VR Device, ...)
looeee commented 7 years ago

Yeah, I've been working on this but haven't finished it yet. It's on the to do list though!

If you have any example files at nonstandard framerates I can use for testing that would be great.

ignazioa commented 7 years ago

Great to hear you are working on this 👍 I'll keep my workaround in for now Here you go a test file which only contain an animation at 60 fps test_60fps.zip I'll search for a better example with a mesh.

looeee commented 7 years ago

Thanks! What's your workaround btw?

ignazioa commented 7 years ago

Just a quick hack that serve my puropuse, see below:

//inside parseAnimations()
var TimeModeEnum = [30, 120, 100, 60, 50, 48, 30 ];         
if ( 'GlobalSettings' in FBXTree && 'TimeMode' in FBXTree.GlobalSettings.properties ) 
        fps = TimeModeEnum[FBXTree.GlobalSettings.properties.TimeMode.value];

var returnObject = {
        curves: new Map(),
        layers: {},
        stacks: {},
        length: 0,
        fps: fps,
        frames: 0
};
//and then reference animations.fps instead of hardcoding 30fps
looeee commented 7 years ago

Looks good - I've been doing something similar, but I haven't tested it enough to see if there are problems.

The other issue is that there are a few more enums to support. The full list of is here.

I really don't understand why they can't just use a float for framerate and support all of them at once 😆

But anyway... the ones I'm having difficulty with are

Then there is

And a couple of others like this, which I guess explain the use of enums... but I think we can ignore these and just set this equal to eNTSC (29.97fps)

ignazioa commented 7 years ago

My comments here below:

eFrames1000: same understanding you have, should be 1fps. eCustom: this could be interesting, probably would require support for FrameRate property. eNTSCDropFrame: given my understanding, this would probably require a more complex implementation on how frame time is reconstructed. I agree that having it equal to eNTSC could be a best effort implementation as today (probably good for all practical threejs cases :D )

ignazioa commented 7 years ago

@looeee Just realized that TimeMode = eDEFAULT_MODE = 0 may hide fps different than 30. In my understanding in such cases a fixed frame rate can be derived as max_frame_number/timestamp_interval

looeee commented 7 years ago

@ignazioa good to know. Do you have any models that use this method for determining frame rate so I can test? If not I'll try and create some myself.

liubgithub commented 7 years ago

good idea,I have solved may problem!

ignazioa commented 7 years ago

@looeee Here you are! Hope it helps :) test_defaulttimemode.zip

looeee commented 7 years ago

@ignazioa I don't see any model when I load that file ( with any loader ) - it looks like there should be a character called RokokoGuy?

ignazioa commented 7 years ago

@looeee I am afraid that's correct, the file only contains animation. (sorry, was the only example I found lying around). However, animation time should be ~37 seconds (and fps ~ 99).

looeee commented 5 years ago

Closing this for now. It's hard to tell for sure without a visible model, but far as I can see the animation is now parsed correctly.