The simple creature in Fig 1 is our pilot (a mesh) through the world of positions, rotations, translations and spaces in Babylon.js.
Fig 1
NOTE - When a mesh is created its position and rotation are both set to (0, 0, 0).
In all figures X axis is red, Y axis is Green and Z axis is blue.
The easiest way of placing the pilot within the world is pilot.position = new BABYLON.Vector3(x, y, z);
and this is equivalent to
pilot.position.x = x;
pilot.position.y = y;
pilot.position.z = z;
Demo 1 -
In this case a mathematician and game designer will agree
pilot.position = new BABYLON.Vector3(3, 3, 3);
pilot.position = new BABYLON.Vector3(2, 4, 1);
moves the pilot to position vector (2, 4, 1) as in Fig 2, since this is the last position vector set by the code.
Fig 2
The easiest way of rotating the pilot within the world is pilot.rotation = new BABYLON.Vector3(alpha, beta, gamma)
and this is equivalent to
pilot.rotation.x = alpha;
pilot.rotation.y = beta;
pilot.rotation.z = gamma;
where alpha, beta and gama are angles in radians that give the rotations anti-clockwise about the x, y and z axes respectively when viewed in the positive direction along the axes.
Now a mathematician begins to get a little worried. Rotations are not commutative so the order they are carried out is important yet this method does not specify the order the rotations are applied. More of this later, for the moment consider the results of using pilot.rotation.
A rotation of PI/2 about the y (vertical axis) is achieved by
pilot.rotation = new BABYLON.Vector3(0, Math.PI/2, 0);
Demo 2 -
Fig 3
The first thing to note is that the rotation takes place about axes local to the pilot. From the point of view of a simulation of the real world this makes sense, since when we observe things rotating generally we see them turning about their own local axes. For example watching a big (ferris) wheel or straightening a picture.
What happens when the following is applied?
pilot.rotation = new BABYLON.Vector3(0, Math.PI/2, 0);
pilot.rotation = new BABYLON.Vector3(Math.PI/2, 0, 0);
You get the same result as just doing
pilot.rotation = new BABYLON.Vector3( Math.PI/2, 0, 0);
This can be seen in Demo 3 -
Just as pilot.position sets a position vector based from the world origin (0, 0, 0) so pilot.rotation sets, say, an 'orientation vector' starting from a local orientation matching the world orientation of (0, 0, 0). It is the last set rotation that is achieved.
The following three sets of code are all equivalent for a given alpha, beta and gamma.
pilot.rotation = new BABYLON.Vector3(alpha, beta, gamma);
pilot.rotation.x = alpha;
pilot.rotation.y = beta;
pilot.rotation.z = gamma;
pilot.rotation.x = beta;
pilot.rotation.z = gamma;
pilot.rotation.y = alpha;
since the rendering is done after the angles are set. In other words the order of setting rotations for x, y and z is not important.
Demo 4 -
Fig 4
Commenting out different groups of lines in Demo 4 -
To see that the rotations are around the local axes use Demo 4 -
Step 1 comment out all rotation Step 2 comment out all rotations except
pilot.rotation.y = Math.PI/2;
Step 3 comment out all rotations except
pilot.rotation.y = Math.PI/2;
pilot.rotation.x = Math.PI/2;
Step 4 Comment out all rotations except
pilot.rotation.y = Math.PI/2;
pilot.rotation.x = Math.PI/2;
pilot.rotation.z = Math.PI/2;
Results for 1, 2, 3 and 4 are in Figs 5a, b, c, d.
Fig 5a Fig5b Fig 5c Fig 5d
Starting at
Fig 5a apply a rotation around local (= world) y axis (green) to obtain
Fig 5b apply a rotation around local x axis (red) to obtain
Fig 5c apply a rotation around local z axis (blue) to obtain
Fig 5d
Translate and Rotate change the position and orientation of a mesh along a given vector or axis using either the world or the mesh's local axes.
you can use pilot.translate(vector, distance, space) to move the pilot the given distance in the direction of the vector based on either the world or local space.
The world space is set using BABYLON.Space.WORLD
Demo 5 -
Experimenting with the distance shows that the pilot moves distance * vector length.
It is often useful if the given vector is a unit vector so the distance moved is precisely the distance given.
For a given V = new BABYLON.Vector3(x, y, z) a unit vector in this direction is given by V.normalize(). Also V.length() will give the length of the vector.
For convenience unit vectors in the positive directions of the x, y and z axes are pre-defined as the constants BABYLON.Axis.X, BABYLON.Axis.Y and BABYLON.Axis.Z respectively.
The local space is set using BABYLON.Space.LOCAL.
In the local space translate behaves as would a mathematical translate. That is, a sequence of translations is an accumulation of direction vectors as opposed to the setting of a position vector.
Demo 6 -
NOTE
local-axes means axes local to the pilot that maintain their original orientation to the pilot, ie as the pilot turns the local axes turn with it.
world-local-axes means axes local to the pilot that stay in the direction of the world axes whatever the orientation of the pilot.
Rotations take place around the world-local-axes and are accumulative. This can be seen in Demo 7 -
Commenting the correct lines in Demo 7 -
Fig 6a Fig6b Fig 6c Fig 6d
Starting from
Fig 6a rotate about the world-local-axis y to obtain
Fig 6b rotate about world-local-axis y to obtain
Fig 6c rotate about world local axis x to obtain
Fig 6d
Demo 8 -
Fig 7a Fig7b Fig 7c Fig 7d Fig 7e
Starting from
Fig 7a rotate about local-axis y to obtain
Fig 7b rotate about local-axis y to obtain
Fig 7c rotate about local-axis x to obtain
Fig 7d rotate about local-axis z to obtain
Fig 7e
Whether the pilot is rotated in the world or the local space applying pilot.translate in the world space is essentially equivalent to applying pilot.position.
So what happens when pilot.translate is applied in the local space after rotations.
Firstly when rotating in the world space the word-local-axes are used for rotation and these are then also used for pilot.translate(vector, distance, BABYLON.Space.LOCAL). See Figs 8a, b
Demo 9 -
Fig 8a Fig8b
Starting from
Fig 8a translate LOCAL applies a translation of -2 along z world-local-axes to obtain
Fig 8b
Secondly when rotating in the local space the local axes are used for rotation and the world-local-axes are still used for pilot.translate(vector, distance, BABYLON.Space.LOCAL).
Fig 9 shows that the translation of (0, 0, -2) is still along the world-local-axis for z as it was in Fig 8b.
Demo 10 -
You use pilot.locallyTranslate(vector), where vector is a BABYLON.Vector3 giving the required translation.
Demo 11 -
Figs 10 a, b, c and d show the pilot rotations around the world-local-axes.
Fig 11 shows the final result as in Fig 10d but with the local-axes shown.
Fig 12 shows the result of applying the following two translations, the first of distance 3 along the local z axis and the second of distance 3 along the local y axis.
Fig 10a Fig10b Fig 10c Fig 10d
Starting from
Fig 10a rotate around world-local-axis y to obtain
Fig 10b rotate around world-local-axis y to obtain
Fig 10c rotate around world-local-axis x to obtain
Fig 10d
Fig 11
Fig 12
Demo 12 -
Figs 13 a, b, c and d show the pilot rotations around the local-axes.
Fig 14 shows the final result as in Fig 13d but with the local-axes shown.
Fig 15 shows the result of applying the following two translations, the first of distance 3 along the local z axis and the second of distance 3 along the local y axis.
Fig 13a Fig13b Fig 13c Fig 13d
Starting from
Fig 13a rotate around local-axis y to obtain
Fig 13b rotate around local-axis y to obtain
Fig 13c rotate around local-axis x to obtain
Fig 13d
Fig 14
Fig 15
Using Pivots
Rotate About a Pivot Other than the Local Origin
Translate and Rotate in Detail