features

Positioning, Rotating, Scaling


Positioning, Rotating and Scaling

There are a variety of ways within Babylon.js to position, rotate and scale a mesh, from simple methods to the use of matrices. All of which depend on you knowing which frame of reference, either the world axes or the local axes, is being used.

Prior to the MeshBuilder method of creating a mesh the only way to produce a cuboid or ellipsoid, for example, was to create a cube and sphere and scale them in one dimension or another. This could produce difficulties with subsequent manipulations of a mesh. Since using MeshBuilder allows you to set different sizes for meshes in the x, y and z directions these difficuties with scaling no longer arise.

There are two types of tactic to position and rotate a mesh; one type is the set-at tactic and the other is move-by. Position and rotation are both of the set at type, the values being given set the actual position and rotation of the mesh. On the other hand addRotation is a move-by type since it adds the given rotation around one axis to the current rotation of the mesh. You can read about more set-at and move-by types below.

Set-At Methods

In addition to position, which places a mesh according to the world axes, and rotation which sets the orientation with Euler angles, the following are available to set a mesh's position and rotation.

Position using Local Axes

This setPositionWithLocalVector method sets the position with reference to local space which is a frame of reference that uses the origin of the world axes and axes parallel to those of the mesh's local axes.

mesh.setPositionWithLocalVector(new BABYLON.Vector3(x, y, z));

Playground Example setPositionWithLocalVector -


In order to obtain the current position of the object in local space use

var localPosition = mesh.getPositionExpressedInLocalSpace();

RotationQuaternion

All angles are in radians

A rotationQuaternion sets the orientation of a mesh by a rotation around a given axis. It is a four dimensional vector of the form (x, y, z, w). The most straight forward way to use a rotationQuaternion is as follows

var axis = new BABYLON.Vector3(1, 1, 1);
var angle = Math.PI / 8;
var quaternion = new BABYLON.Quaternion.RotationAxis(axis, angle);
mesh.rotationQuaternion = quaternion;

The default for rotationQuaternion is undefined . When a rotationQuaternion is set the value of rotation is set to (0, 0, 0).

Playground Example rotationQuaternion -


Note : You MUST set and use rotationQuaternion when creating physics objects because physics engines rely only on them.

Align Axes

When you want to rotate a camera or mesh so that it lines up with a set of given axes you can use the RotationFromAxis method to find the needed Euler angles to use with rotation as follows

var orientation = BABYLON.Vector3.RotationFromAxis(axis1, axis2, axis3);
mesh.rotation = orientation;

where axis1, axis2 and axis3 are three left-handed orthogonal vectors and the mesh will be aligned with

  • axis1 as the x axis in its local system
  • axis2 as the y axis in its local system
  • axis3 as the z axis in its local system

Using this a plane can be made to follow a curve so it lies parallel or perpendicular to the curve as it does so. In the following example a set of points is used to generate and draw a curve and a 3D path is created. Babylon.js provides the way to obtain the normal, tangent and binormal from the Path3D object at each of the points used to generate it. These form a set of orthangonal vectors, and depending on the order they are used, a plane can be made to follow and track the shape of the curve. All six orders are used in the example, the top one [0] has the plane tangental to the curve and the fourth one down [3] is perpendicular to the curve. Others can twist the plane at certain points.

Playground Animation - RotationFromAxis -


Move-By Methods

These methods add the given value (positive or negative) to the current position or orientation of the mesh. In the case of position and rotation and rotationQuaternion. This can be done by actually adding values using '+=' or `-=" to individual components or using vector addition. The following animated playgrounds show examples.

Playground Animation - Position -


Playground Animation - Rotation -

Playground Animation - Rotation Along Straight Horizontal Path -

Playground Animation - rotationQuaternion -

For rotating the most straight forward move-by method is addRotation which increments the orientation of a mesh about one of the local axes.

Playground Animation - addRotation -


The following playground shows you how to use addRotation to construct wheels.

Playground Example - Wheels -


Author Jerome Bousquie

The other ways below move by the values given in the parameters.

Locally Translate

This method moves, or more strictly translates, a mesh using the local axes

mesh.locallyTranslate(new BABYLON.Vector3(x, y, z));

Playground Example locallyTranslate -


Playground Animation locallyTranslate -

Translate

Mathematically a translation is a single vector which gives the direction and distance that an object moves by. The translate method in BABYLON.js requires three parameters direction, distance and space.

The space parameter allows you to state whether translate uses the world axes or the local axes and takes the values BABYLON.Space.WORLD and BABYLON.Space.LOCAL respectively.

By allowing direction and distance to be given Babylon.js gives you the opportunity to easily move a mesh along one the the axes x, y, or z. This is because Babylon.js supplies three constant unit vectors along each axis; these are BABYLON.Axis.X, BABYLON.Axis.Y and BABYLON.Axis.Z. So moving a distance 2 along the y axis becomes

mesh.translate(BABYLON.Axis.Y, 2, BABYLON.Space.WORLD);

for the world axes and

mesh.translate(BABYLON.Axis.Y, 2, BABYLON.Space.LOCAL);

for the local axes.

It is also possible to supply other unit vectors and a distance.

mesh.translate(new BABYLON.Vector3(-1, 3, -2).normalize(), 10, BABYLON.Space.LOCAL);

Alternatively, if you wish just to supply a vector giving the whole of the translation use a unit distance

mesh.translate(new BABYLON.Vector3(-1, 3, -2), 1, BABYLON.Space.WORLD);

Generally the total distance moved given vector v and distance d as parameters will be |v|d, so using

mesh.translate(new BABYLON.Vector3(-6, 3, -2), 5, BABYLON.Space.WORLD);

will move the mesh a distance of 35 units in the direction (-6, 3, -2) since |(-6, 3, -2)| = √49 = 7 and 7 * 5 = 35

Rotate

To rotate a mesh an axis, angle and the space are needed. The center of rotation is the origin of the local axes and the axis is given as any vector(x, y, z) and passes through the center of rotation. In other words the mesh spins at its current position. Changing the position of the center of rotation can be done by using a parent or a pivot.

The axes BABYLON.Axis.X, BABYLON.Axis.Y and BABYLON.Axis.Z may be used. The frame of reference for the axis can be the world axes or the local axes.

pilot.rotate(BABYLON.Axis.Y, Math.PI / 2, BABYLON.Space.WORLD);

pilot.rotate(new BABYLON.Vector3(-1, 3, -10), 7 * Math.PI / 12, BABYLON.Space.LOCAL);

Note: mesh.rotate() generates a new quaternion and then uses mesh.rotationQuaternion while mesh.rotation is set to (0, 0, 0).

Playground Animation - Rotate -


Change of Origin

Should you wish to position, rotate or scale a mesh about a point other than its own local origin then this can be done either using a parent or a pivot or by coordinate transformation.

Parent

Assigning a mesh a parent changes the world space for its children. Any change in position, orientation or scale of the parent will be applied to its children. Setting the position, rotation or scaling of a child will be done using the local space of the parent as the child's world space.

childMesh.parent = parentMesh;

Note : Parent-child hierarchies are evaluated on every frame. So any position, rotation and scaling transformations made to the parent prior to assigning it to children will also be applied to the children when the parent is assigned. It usually makes sense not to rotate or move a child until after you've assigned it to the parent.

Pivot

Setting a pivot point changes the local origin of a mesh and positioning, rotation and scaling transformations are based on the pivot.

mesh.setPivotPoint(Vector3);

Transform Coordinates

This method allows you to transform coordinates without assigning a parent or a pivot, though it is often more straight forward to do so.

The change from a local position to a global position is achieved using

mesh.computeWorldMatrix();
var matrix = mesh.getWorldMatrix();
var global_position = BABYLON.Vector3.TransformCoordinates(local_position, matrix);

Further Reading

Basic - L1

Positions, rotations, scaling 101

More Advanced - L3

How To Use Translations and Rotations
How To Set and Use a Pivot
How To Rotate Around an Axis About a Point
How To Use Path3D
How To Use a Parent
How To Transform Coordinates
Euler Angles and Quaternions
Aligning Rotation to Target
Frame of Reference
Baking Transformations
In-Browser Mesh Simplification (Auto-LOD)

Gamelet

A Simple Car Following a Path