Gltf: Complex animation workflow?

I’m having a hard time figuring out how to implment complex animations with the current animation system. I’m not the most familiar with the system, so hopefully someone can shed some light on where I’m going wrong with my thought process or introduce me to the proper techniques/limits to the system.

My though process:

image

Say I have file containing 3 clips for a jump animation like in the image above. jumpstart frames 1-30, hangloop frames 31-60, and landing frames 61-90.

  • jumpstart > hangloop
    In order for hangloop to start at the correct frame I’ll have to start it at the same time as jumpstart in order to prevent the initial 30 frame delay of the clip.

  • hangloop loop
    If my character is launched in the air I can’t be sure how long they’ll up there, so I’d like to be able to loop this animation. I can’t loop this clip though because it has 30 frames of delay at the start of every loop. The start time needs to be shift to t=0, but I’m not sure if there’s any support for that in the current GLTFLoader.

  • hangloop > landing
    Again, in order to properly execute the landing I’d have to start it’s animation at least 60 frames in advance in order to get a proper timing for the crossfade.

@donmccurdy I was wondering if the GLTFLoader had a similar feature to what we discussed in this issue: https://github.com/mrdoob/three.js/issues/14894? I’d just like to set all clips to begin at t=0, and use event listeners to trigger transitions into the next clip like in the webgl_animation_skinning_blending example.

If this isn’t possible is there any documentation for how to use subclips discussed in this PR: https://github.com/mrdoob/three.js/pull/13430? Maybe this is the solution? I’m open for suggestions!

Thanks

glTF supports multiple animations in a single file, so ideally you’d export from the DCC tool with clips already separated (each starting at t=0), and get an array of AnimationClip objects back from GLTFLoader. I’m not sure how that workflow is best handled in Maya, but note that there are some Maya2glTF settings (-animationClipName, -animationClipStartTime, -animationClipEndTime) that you can use at least on the CLI to split animations. In Blender (which has a somewhat un-intuitive animation clip system itself…) I do this by “stashing” or making an NLA track for each Action to include as an animation.

If you find that you can’t split the animation and zero out clip start time at export, then yeah https://github.com/mrdoob/three.js/pull/13430 may be the solution and I can explain that further.

I’m thinking subclips will probably be the way to go. Is there any documentation for that PR yet?

glTF supports multiple animations in a single file, so ideally you’d export from the DCC tool with clips already separated (each starting at t=0)

I can’t do that from Maya with the current game exporter limitations. The exporter doesn’t solo the track so exported clips (like in the image below) results in 3 clips, but they all have the garbled animations because they just blend on top of each other during export:

In order to get the clips that I need I’d have to manually export each soloed track like so:

But that results in several output files and I need all the animations in a single file. So at the moment it seems that my only option is to export all animations on a single track and then set them to t=0 in the code.

note that there are some Maya2glTF settings ( -animationClipName , -animationClipStartTime , -animationClipEndTime ) that you can use at least on the CLI to split animations.

Are these flags to put in? Where can I get a list of the flags and what they do? I can’t find anything in the readme other than the mention of them. Also the features described in the readme (like choosing the source) don’t seem to match up with what I’m seeing in Maya:

I only have access to Maya LT, and can’t use plugins to test any of this, but I think the instructions here may be what you’re looking for: https://github.com/WonderMediaProductions/Maya2glTF/issues/16. Seems like you have to use the console in Maya to start the export.

If using AnimationUtils.subclip(), The basic usage of the PR’s code would be:

var jumpClip = AnimationUtils.subclip( sourceClip, 'jump', 1, 30, fps = 30 );
var hangClip = AnimationUtils.subclip( sourceClip, 'hang', 31, 60, fps = 30 );
var landClip = AnimationUtils.subclip( sourceClip, 'land', 61, 90, fps = 30 );

Each clip will be automatically shifted to begin at t=0. You’ll also need to be on at least three.js r95, because without #14385 this does not work. At this point the subclip PR is mainly blocked by the fact that I don’t have a good example model that actually benefits from it. I’m able to export multiple animations via glTF in Blender now (I couldn’t at the time). So for tools that can’t split animations, we need an example workflow (modeling tool -> exporter -> loading) that produces cleanly looping animation using that PR.

I checked out the workflow in the link. The exporter does what I need and sets all clips to t=0 with the caveat being you have to use the Trax Editor (which is losing support in favor of the new Time Editor). So I just transferred my Time Editor clips to the Trax Editor and it works! The only bug is that I have some animated scaling going on and it’s not exporting correctly.

So until that bug is fixed I’m going to have to go with subclips. So how do I go about utilizing just the AnimationUtils from that PR while staying in the latest release three.js? Should I clone another three.js repo and only import #13430’s AnimationUtils into my project?

EDIT
I went here and am copying and pasting each module’s code into a local file then doing something like this for my imports:

<script src="./js/src/animation/AnimationUtils.js"></script>
<script src="./js/src/animation/AnimationClip.js"></script>
<script src="./js/src/animation/KeyframeTrack.js"></script>

Is this ok?

Animating scale of bones, or just a normal node or mesh?

So how do I go about utilizing just the AnimationUtils from that PR while staying in the latest release three.js? Should I clone another three.js repo and only import #13430’s AnimationUtils into my project?

I would copy the three functions from my PR (clip.clone(), track.clone(), and AnimationUtils.subclip()) into a new file, and patch the two .clone() functions onto the prototype of the three.js classes:

THREE.AnimationClip.prototype.clone = function () { ... }
THREE.KeyframeTrack.prototype.clone = function () { ... }
THREE.AnimationUtils.subclip = function () { ... }

If you’ve got an example model that does (or should) animate properly with that done, I can probably rebase that PR and get it reviewed.

I’ll try this out this weekend.

I think you mentioned Houdini in another thread but I can’t find it, so posting here — Houdini 17 will add direct import/export of glTF: https://vimeo.com/291934239 (about 7:00)

4 Likes

That’s awesome!

1 Like

When I grow up I want to be big like that hahaha :drooling_face: