yorke Posted March 28, 2017 Share Posted March 28, 2017 Hi all, I lurked some topics related to bones and their rotation but didn't find a clear solution to my problem, so I try to expose it. I'm trying to find the best way to compose rotation of bone on all 3 local axes. In my simulation, i rotate manually the bones of a human rigged model to match desired poses. Everything works fine when a bone rotates only around one local axis (x, y or z), but if I have to compose rotations and rotate, by example, a bone 90° around original x axis and 90° around original z axis, the results are not the ones I expected. E.g: bone.rotate(BABYLON.Axis.X,Math.PI/2, BABYLON.Space.LOCAL); bone.rotate(BABYLON.Axis.Z,Math.PI/2, BABYLON.Space.LOCAL); gives different results than bone.rotate(BABYLON.Axis.Z,Math.PI/2, BABYLON.Space.LOCAL); bone.rotate(BABYLON.Axis.X,Math.PI/2, BABYLON.Space.LOCAL); So what's the best way to compose rotations on 3 bone axes? Using quaternions and multiplying 3 rotation matrixes with the initial quaternion? Thus I'd like to write a sort of function rotateBone(bone, x, y, z) that rotates a bone of x degrees around its original X axis, y axis and z axis, where x, y, and z are expressed in radians [0 - 6.28] (or degrees [0 - 360]) Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted March 28, 2017 Share Posted March 28, 2017 Hello This is expected Rotations are relative and not associative. This means that rotations are done based on current state. I think you can find this interesting: http://doc.babylonjs.com/overviews/how_rotations_and_translations_work Quote Link to comment Share on other sites More sharing options...
adam Posted March 28, 2017 Share Posted March 28, 2017 This might be helpful: http://www.babylonjs-playground.com/#E49AL#1 edit: If you are rotating in the order Y, X, Z just use setYawPitchRoll. Another PG that could be helpful: http://www.babylonjs-playground.com/#E49AL#4 Quote Link to comment Share on other sites More sharing options...
yorke Posted March 29, 2017 Author Share Posted March 29, 2017 Many thanks to both of you for your good hints. I'm taking a look at the second PG posted by adam. After some tests on that PG, it seems to me that calling three times bone.rotate() on local axes and ZXY order is equivalent to setYawPitchRoll(Y,X,Z), which is also equivalent to multiplying quaternions (no order needed in this case). Am i wrong? Maybe the problems I noticed could be caused by the fact that I was calling bone.rotate() in YXZ order, I'm just verifying Quote Link to comment Share on other sites More sharing options...
adam Posted March 29, 2017 Share Posted March 29, 2017 23 minutes ago, yorke said: which is also equivalent to multiplying quaternions (no order needed in this case). Changing the order of quaternion multiplication changes the rotation order. Note that bone.rotate() accumulates rotation. It will act differently than the other rotation functions if you are calling it on each frame without resetting the rotation at the beginning of each frame. http://www.babylonjs-playground.com/#E49AL#5 resetting rotation before using rotate: http://www.babylonjs-playground.com/#E49AL#6 yorke 1 Quote Link to comment Share on other sites More sharing options...
yorke Posted March 29, 2017 Author Share Posted March 29, 2017 Woah just what I needed Awesome adam, the latter PG made things very more clear to me with your explanation about resetting bone and re-applying rotations vs rotating by deltas on previous frame. Also I was totally missing rotations' order. Putting it at work: still many thanks, you saved me a huge waste of time! adam 1 Quote Link to comment Share on other sites More sharing options...
yorke Posted April 27, 2017 Author Share Posted April 27, 2017 Up. I'm achieving nice results using bone quaternions, but now i've the problem to let bone rotation not be affected by mesh rotation (or translation) Thus I can successfully work on bone rotations retrieving bone quaternion, interpolating it with the quaternion of the final pose and reapplying il to the bone: var quat = mesh.skeleton.bones[i].getRotationQuaternion(BABYLON.Space.WORLD, mesh); [...] modify quaternion mesh.skeleton.bones[i].setRotationQuaternion(quat,BABYLON.Space.WORLD,mesh); but if I rotate the mesh, the poses become wrong because I use world coordinates (e.g. mesh rotates but bone stays in the same place and does not rotate with the mesh). I tried to substitute Space.WORLD with Space.LOCAL but it gives odd results, e.g if I simply get the bone quaternion in local space and reapply it to the bone without changing it: var quat = mesh.skeleton.bones[i].getRotationQuaternion(BABYLON.Space.LOCAL, mesh); mesh.skeleton.bones[i].setRotationQuaternion(quat, BABYLON.Space.LOCAL,mesh); bone rotation changes, while I'd expect it to stay the same not having changed its local quaternion... How to let bone quaternion independent from mesh position/rotation? Quote Link to comment Share on other sites More sharing options...
Raggar Posted April 27, 2017 Share Posted April 27, 2017 It does seem to work as expected here: http://www.babylonjs-playground.com/#1EVNNB#90 Quote Link to comment Share on other sites More sharing options...
adam Posted April 27, 2017 Share Posted April 27, 2017 49 minutes ago, yorke said: How to let bone quaternion independent from mesh position/rotation? Don't pass the mesh to the rotation function. yorke 1 Quote Link to comment Share on other sites More sharing options...
adam Posted April 27, 2017 Share Posted April 27, 2017 1 hour ago, yorke said: bone rotation changes, while I'd expect it to stay the same not having changed its local quaternion... What version of BJS are you using? I fixed an issue with rotation a couple weeks. Quote Link to comment Share on other sites More sharing options...
yorke Posted April 27, 2017 Author Share Posted April 27, 2017 Thanks raggar and adam for your kind replys 40 minutes ago, adam said: Don't pass the mesh to the rotation function. That seems to have done the trick, awesome as usual adam! Passed Space.WORLD with no mesh and everything seems working fine now, doing more tests however. On the opposite Space.LOCAL continues to give me strange results also with no mesh passed, althought if I saw it's working fine in the PG posted by raggar... But I'm working on models created and imported from blender, don't know if the problem can depend on that. I'm still on v2.5: I'm planning to move to BJS3 but i'm afraid with compatibility issues - and long, long debug sessions -, I had bad experiences with three.js (although that's a great framework, don't misunderstand me... maybe only a little bit "dynamic") Quote Link to comment Share on other sites More sharing options...
yorke Posted April 28, 2017 Author Share Posted April 28, 2017 Sorry I've still another question on this topic, I couldn't find an answer to this on the forum and official docs on rotations didn't help me. The question is: is there a way to get yaw, roll and pitch of a bone? Let me explain: I can rotate a bone using eulers: mesh.skeleton.bone.setYawPitchRoll(y,x,z) But how do I read those Eulers from the bone? if I try to read them using mesh.skeleton.bones.getRotation() I would have expected to obtain exactly x,y and z passed to setYawPitchRoll() function, but results are quite different. Lurking BJ'S code, I saw that getRotation() gets bone's RotQuaternion and calculates toEulers() on it, so I can't understand why results are different. By example: getRotation() output (x,y,z) coincide with values passed to setYawPitchRoll(y,x,z) only if x=z=0 and y in [0 , 3.14]. I tried both in local and world spaces but with no result, also tryed with quaternions but didn't arrive to anything... Am I missing something or babylon uses different euler conventions in those two functions? Quote Link to comment Share on other sites More sharing options...
Raggar Posted April 28, 2017 Share Posted April 28, 2017 23 hours ago, yorke said: I'm still on v2.5: I'm planning to move to BJS3 but i'm afraid with compatibility issues - and long, long debug sessions -, I had bad experiences with three.js (although that's a great framework, don't misunderstand me... maybe only a little bit "dynamic") It will only get worse the longer you wait. I don't believe you'll face any major issues. Why not give the newest release or preview version a test run, just to see whether or not you've been affected by breaking changes? Quote Link to comment Share on other sites More sharing options...
Raggar Posted April 28, 2017 Share Posted April 28, 2017 38 minutes ago, yorke said: Sorry I've still another question on this topic, I couldn't find an answer to this on the forum and official docs on rotations didn't help me. The question is: is there a way to get yaw, roll and pitch of a bone? Let me explain: I can rotate a bone using eulers: mesh.skeleton.bone.setYawPitchRoll(y,x,z) But how do I read those Eulers from the bone? if I try to read them using mesh.skeleton.bones.getRotation() I would have expected to obtain exactly x,y and z passed to setYawPitchRoll() function, but results are quite different. Lurking BJ'S code, I saw that getRotation() gets bone's RotQuaternion and calculates toEulers() on it, so I can't understand why results are different. By example: getRotation() output (x,y,z) coincide with values passed to setYawPitchRoll(y,x,z) only if x=z=0 and y in [0 , 3.14]. I tried both in local and world spaces but with no result, also tryed with quaternions but didn't arrive to anything... Am I missing something or babylon uses different euler conventions in those two functions? http://www.babylonjs-playground.com/#1EVNNB#91 Try updating to the latest Babylon.js version. Quote Link to comment Share on other sites More sharing options...
yorke Posted April 29, 2017 Author Share Posted April 29, 2017 Thanks raggar, I saw your PG and I'm investigating what's wrong in my scene or models, that's really strange. At least you confirmed me that both functions use the same conventions for eulers, that's a good starting point. In previous PGs there was the option to run the PG on an older version of BJS, was this feature removed on PGs from BJS3? I can't see that option. For what concerns upgrading to v3, you're right but I saw that v3 is not marked as stable yet. I'm surely planning to upgrade and wasting some time to let my code compatible with it, but I'll first wait for the stable version Quote Link to comment Share on other sites More sharing options...
Raggar Posted April 29, 2017 Share Posted April 29, 2017 That feature is still present in the top right corner. Changing from "latest" to "2.5" doesn't seem to affect it, so the issue must be somewhere in your code I think. Quote Link to comment Share on other sites More sharing options...
yorke Posted April 29, 2017 Author Share Posted April 29, 2017 Really strange, I can't see the old dropdown to select BJS version nor in firefox 48 nor in chrome 56 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted April 30, 2017 Share Posted April 30, 2017 We have a pretty aggressive media query here this could be because of the resolution yorke 1 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted April 30, 2017 Share Posted April 30, 2017 I've just created this issue for it: https://github.com/BabylonJS/Babylon.js/issues/2077 yorke 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.