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;
}
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:
with the backhand animation, there is a global translate that moves all the child objects along the y axis.
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
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
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
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?
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