jerome Posted February 7, 2017 Share Posted February 7, 2017 Hi people, I'm about to implement a new useful feature to the core. For now, it's called addRotation(). What is it for ? Well, usually the BJS users aren't big fans of quaternions to manage their mesh rotations, although the quaternions are the best tools to achieve it. Quaternion aren't intuitive, so people prefer the Euler angles, right ? Moreover BJS imposes the rotation order, what is, if I'm not wrong, YXZ. This means that, when you set a mesh rotation (x, y, z), it is rotated first around Y, then around X and finally around Z in its local space. This is important because the rotation is not commutative : if you rotate a mesh for, say, 30° around Y and then for 20° around X, you won't get the same final orientation than if you rotate it first for 20° around X and then only for 30° around Y. In brief, the rotation order really matters ! So, you want to use only the Euler angles and you are constrained by the engine rotation order : no surprise you can hardly achieve the rotation you really want. Here's comes addRotation(x, y, z) to the rescue ! addRotation() will do 3 things for you : - to let you use only Euler angles, whatever the internal mesh rotation is Euler or quaternion based (note : under the hood, addRotation() works with quaternions, but it's hidden for your convenience) - to allow you to decompose your rotation by steps in your custom order to achieve your final orientation : you can rotate a mesh first around X, then around Y, then around X again, then around Z, etc. - to update the initial mesh rotation values for you : if the rotation is Euler based, it's updated as Euler angles (mesh.rotation), if it's a quaternionRotation (mesh.rotationQuaternion), the quaternion is updated. How does it work ? Just give the mesh an initial rotation, or none, (this rotation can be Euler angles or a quaternion, as you want), then add your rotation steps to achieve the wanted final orientation : mesh.rotation.x = Math.PI / 4.0; // initial rotation around x mesh.addRotation(0, Math.PI / 3.0, 0); // the mesh is fisrt rotated around X, then only around Y for PI/3 // you can even link all the rotation steps // here X first, then Z, finally Y mesh.addRotation(x1, 0, 0).addRotation(0, 0, z2).addRotation(0, y3, 0); // the mesh rotation property is computed for you console.log(mesh.rotation); First demo :http://www.babylonjs-playground.com/#1PON40 The left box is the model box. The central box is rotated as usual for PI/3 around X and PI/2 around Y. The BJS rotation order makes it rotate first around Y, then around X. The right box is given an initial rotation for PI/3 around X, then a rotation step is added for PI/2 around Y. You can see that the final orientation differs. If you have a look at the console where the box2 rotation is displayed : http://www.babylonjs-playground.com/#1PON40#1 you will notice that the Euler angles needed to achieve this final orientation have a z value, although you didn't specify anything about Z. Simply because this is the Euler rotation to be done in the required BJS rotation order to achieve this final orientation. Something you wouldn't probably have found by yourself just playing with Euler angles ... Let's go further with the torus wheel challenge. Remember the number of times that, in this forum, people tried out to use the BJS provided shape called torus and to use it as a car wheel. It's damned complex because the torus is designed horizontally in its local space and we need to make rotate either around its central axis (rolling), either around a vertical axis (wheel direction). So some head hache with quaternions or mesh.rotate() once in the local space, once in the world space. Let's try an easier way. Here's the just born torus : http://www.babylonjs-playground.com/#1PON40#2 Let's set it vertical as an initial rotation around Z : http://www.babylonjs-playground.com/#1PON40#3 Too bad the method debugLayer.shouldDisplayAxis() doesn't currently display anything, just keep in mind the torus local axis at this step : Y is the torus central axis (so now horizontal after this first rotation around Z) X is, now the torus is vertical, the vertical axis, Z keeps unchanged along the world Z axis. So in order to make the wheel roll, we will give each frame, from this initial rotation, an extra rotation around X first (wheel direction) and then a rotation around the torus central axis Y http://www.babylonjs-playground.com/#1PON40#4 As you can see, the code is quite short and intuitive : I don't know the BJS required rotation, but I know how to set my torus orientation step by step using only Euler angles. No need for quaternion or space switching here. I just "build" each frame the way to achieve the final rotation with my own rotation steps and my own order. Then it's quite easy to animate car wheels : http://www.babylonjs-playground.com/#1PON40#5 Have fun Sebavan, Dad72, ian and 5 others 8 Quote Link to comment Share on other sites More sharing options...
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.