How to properly rotate an AnimationClip?

I think it should be enough with rotating every quaternion of the main QuaternionKeyframeTrack, which is the index 1 in my animation

I’ve tried the following, but the rotation is not produced over the Y axis, no matter which axis I choose. What’s wrong with it?

let t = clips.serve.action0.getClip().tracks[1].values;
for (let i = 0; i < t.length; i += 4) {
	let q = new THREE.Quaternion();
	q.setFromAxisAngle(new THREE.Vector3(0,1,0), Math.PI / 4);
	t[i] = q.x;
	t[i+1] = q.y;
	t[i+2] = q.z;
	t[i+3] = q.w;
}

from your screen grab, it looks like you could solve your problem just by rotating the root of your model.

That has bad consequences. I need to play different animations smoothly. If I rotate the model, the result is not always the desired

I could also edit the animation in Blender and rotate it, but then I have another problem: the animation size is multiplied by 10:

Now you would say: you could scale it down by 10… but then everything messes up:

can you show some code showing how you load the model and all the things you do to it before you rotate it.

also check your models origin in blender.
Is it at the feet, the middle of its body, or somewhere far off into the horizon?

It’s in the origin:

The source can be found here:

http://formulamanager.com/tennis

Relevant parts…

The loader function:

	function LoadModel(modelo, callback) {
	    total_modelos++;

	    const loadingManager = new THREE.LoadingManager();
		const loader = new FBXLoader(loadingManager);
		loader.load(modelo, function ( object ) {

	        if (callback) {
			    callback(object);
	            modelo_cargado();
			}
		}, undefined, function ( e ) {
			console.error( e );
		} );
	}

The original “backhand” animation, which is odd one when modified with Blender:

http://formulamanager.com/tennis/modelos/John/J_Forced_Backhand.fbx

Let me know if you need any further explanation

with the backhand animation, there is a global translate that moves all the child objects along the y axis.
test

Either remove this in the original animation source,
or
you can find and remove the specific track using JavaScript after its loaded

I.e.,
after you load the J_Forced_Backhand.fbx animation,
try deleting the relevant QuaternionKeyframeTrack from the animations array.
It just so happens that it is the first QuaternionKeyframeTrack in the animation array, so you can just

object.animations[0].tracks.shift()

If you can edit the original animation files, then I think that is the best solution. Its these translations that are conflicting with what you want it to do after you’ve loaded it in threejs.
Otherwise you have to hack all your animations one by one after you’ve loaded them.
I also noticed that the J_Run_F.fbx also works better when you delete the first QuaternionKeyframeTrack

I know. I don’t remove the track it because there are animations, like the serve, that need to jump. What I do is to set X and Z to zero while keeping the Y. That works fine:

function clip_quieto(clip) {
        let t = clip.tracks[0];
        for (let i = 0; i < t.values.length / 3; i++) {
            t.values[i * 3] = 0;
            t.values[i * 3 + 2] = 0;
        }
}

My problem I think is with quaternions, which maybe I don’t understand well :stuck_out_tongue:

Deleting the roots translation from the animation array, is how how I solved the issue I was having with this demo. See line 166 in the example source code provided on page.
Kick Boxing - Three.js Tutorials (sbcode.net)

The Kachujin@walking.glb animation is very similar to your J_Forced_Backhand.fbx animation where it also moves the whole model along one of the axes.
I didn’t want that behaviour because it ruined the transition when the walk animation was looped.
So I deleted the specific track, and now control the position of my model using mouse double click and tweens.
This is exactly how I’d solve your problem.

Yeah, it seems the same idea. But that problem is already solved with the function I posted :stuck_out_tongue:

The problem I describe is that the animation is rotated 90 degrees and I cannot edit it in Blender or other editor I tried because, when I do it, it gets corrupted. I’m also trying to find a solution in that way, but I’d like to learn how to do it programatically too, since programming is the way I’m more comfortable with and it could help me understanding other problem I have, which is how to make an horizontal flip of an animation. That’s a harder one since, if I just scale the model, the bones are also flipped, which result in a bad transition from other animations (the raquet should remain in the right hand :P)

Anyways, I tried removing the quaternion track, and it helped me to understand something: that track is needed. Without it, the model seems to float. It stands it to the ground. So I think I need to “add” the needed degrees instead of “setting” them. I’m going to explore that way, thank you :slight_smile:

I am closer now :slight_smile:

I’ve learnt that, to add the effect of two quaternions, I need to multiply them:

	        let t = clips.serve.action0.getClip().tracks[1].values;
	        for (let i = 0; i < t.length; i += 4) {
    	        let q = new THREE.Quaternion(t[i], t[i+1], t[i+2], t[i+3]);
	            let w = new THREE.Quaternion();
    	        w.setFromAxisAngle(new THREE.Vector3(0,0,1), Math.PI / 2);
    	        q.multiply(w);
    	        t[i] = q.x;
                t[i+1] = q.y;
                t[i+2] = q.z;
                t[i+3] = q.w;
	        }

I don’t understand why I need the Z axis. That’s the depth. It should be Y axis the one to alter although it didn’t work

But, specially, there’s still that floating effect which I don’t understand where it comes from. Any ideas?

2 Likes

Finally, I think I did everything ok. I just tried this simple example and it worked as expected. I think the animation has some strange composition and that’s why it behaves strangely

1 Like