Table of contents

The latest pivot in Babylon (v3.2+) is a pre-transformation pivot and behaves differently than in tools like 3DS Max and Maya as the object's position will move if scale is applied prior to setting the pivot. To get pivot behavior that matches these tools it is recommended to set the object as a child of another transform node that will act as the pivot see: https://www.babylonjs-playground.com/#GH4N1R#1 -

A pivot an be set with a translation matrix or directly with the *setPivotPoint* method.

A pivot in Babylon.js is the center of transformation for a mesh, that is the point used as the center of rotation or the center of enlargement. When a mesh is created the pivot (red sphere) is always at the local origin (yellow sphere) and the local origin always at the world origin, as in Fig 1. When the pivot and local origin are coincident they are shown as a red and yellow striped sphere.

Fig 1

When positioning a mesh it is the local origin that is placed at the given position, for example

```
box.position.x = 2;
```

moves the box as in Fig 2

Fig 2.

Now, mathematically, it is always more straight forward to rotate or enlarge about the local origin and any code to that does rotation and enlargement uses that principle.

When you want the pivot to be at a corner as in Fig 3 the way this is done is to translate the box corner to the local origin resulting as in Fig 4.

Fig 3. Fig 4.

Since it is the box that is translated the values used in the translation will be negative with regard to position. For example given a cube with sides of length 2 to set the pivot at position (-1, -1, -1) requires a translation of (1, 1, 1).

Prior to Babylon.js v3.2 setting a pivot meant that the mesh was translated as in Fig 4 and the local origin of the mesh was reset to the pivot point. This meant that after setting a pivot when you reset the the position of the mesh it was the pivot that was placed at this position. Compare Fig 2 with Fig 5 which shows the result of setting a pivot with the move mesh method followed by

```
box.position.x = 2;
```

Fig 5.

From Babylon.js v3.2 there is a breaking change and setting the pivot no longer produces a change in position of the mesh unless the mesh has been scaled.

Fig 6.

Fig 6 shows result of using setting a pivot with this method followed by

```
box.position.x = 2;
```

Compare this with Fig 5.

So there are two ways of setting a pivot, one that does not alter the position of the mesh (*set pivot only*) and one that does alter the mesh position (*set pivot with move*). The *set pivot only* method is much more straightforward and all playground examples on this page use this method. The *setPivotPoint* function, describe later, uses *set pivot only*.

In fact unless you have an older project coded for versions before 3.2 do not use the *set pivot with move* method. It is much better to *set pivot only* and then move the mesh as normal with *mesh.position* or *mesh.translate* When you do have an older project there is a simple way to update your project code to work with version 3.2 or later as described in the `Breaking Change`

section below.

You set a pivot at the point (x, y, z) with a translation matrix that using

```
mesh.setPivotMatrix(BABYLON.Matrix.Translation(-x, -y, -z));
```

Before v3.2 this would result in the mesh being moved and the local origin of the mesh being reset to the pivot point.

From v3.2 this results in the pivot point being set without the mesh being moved and the current local origin of the mesh is kept. To maintain the older behaviour of moving the mesh a second parameter, `false`

is needed

```
mesh.setPivotMatrix(BABYLON.Matrix.Translation(-x, -y, -z), false);
```

**STRESSED NOTE** For those of you who wrote code using a pivot for versions of Babylon.js before v3.2 and who want to update the version of Babylon.js to a currrent one should change each occurance, in their project code, of

```
mesh.setPivotMatrix(BABYLON.Matrix.Translation(-x, -y, -z));
```

to

```
mesh.setPivotMatrix(BABYLON.Matrix.Translation(-x, -y, -z), false);
```

To set a pivot at (x, y, z) relative to the local origin of a mesh requires the applied translation to be (-x, -y, -z).

```
mesh.setPivotMatrix(BABYLON.Matrix.Translation(-x, -y, -z));
```

When there is a mesh at position (xc, yc, zc) you want to set a pivot at (xp, yp, zp) then you need to use (xc - xp, yc - yp, zc - zp) as the translation.

```
mesh.setPivotMatrix(BABYLON.Matrix.Translation(xc - xp, yc - yp, zc - zp));
```

Simply recalculate the translation of the pivot to the local origin of the mesh as above.

The following sequence of playgrounds goes from setting the first pivot position to scaling about the second pivot position

- Playground Example - Set First Pivot -
- Playground Example - Set Second Pivot -
- Playground Example - Scaling from Second Pivot -

**NOTE:** When a mesh has been rotated before resetting the pivot on resetting the pivot the mesh will move since the current rotation will be applied to the new pivot point.

The following sequence of playgrounds shows setting the first pivot, rotating around the pivot then resetting the pivot.

- Playground Example - Set First Pivot -
- Playground Example - Rotate About First Pivot -
- Playground Example - Set Second Pivot -

There are three useful functions to aid setting and getting a pivot point. These are

```
mesh.setPivotPoint(Vector3);
mesh.getPivotPoint(); // returns Vector3
mesh.getAbsolutePivotPoint(); // returns Vector3
```

Using *setPivotPoint* you simply pass a Vector3 object that is the relative position of the pivot to the local origin of the mesh. To set a pivot at (x, y, z) relative to the local origin of a mesh requires

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

When there is a mesh at position (xc, yc, zc) you want to set a pivot at (xp, yp, zp) then the relative position is (xp - xc, yp - yc, zp - z) and use

```
mesh.setPivotPoint(BABYLON.Vector3(xp - xc, yp - yc, zp - z));
```

The following sequence of playgrounds goes from setting the first pivot point to scaling about the second pivot point

- Playground Example - Set First Pivot Point -

- Playground Example - Set Second Pivot Point -

- Playground Example - Scaling from Second Pivot Point -

It is possible to reset the pivot point and maintain the position and rotation of the mesh.

To do this the current rotation of the mesh has to be stored and then the mesh's rotation set to (0, 0, 0) before the pivot point is reset. The current rotation is then re-applied to the mesh.

The following sequence of playgrounds shows setting the first pivot point, rotating the pivot then resetting the pivot point and re-applying the rotation.

- Playground Example - Set First Pivot Point -

- Playground Example - Rotate About First Pivot Point -

- Playground Example - Set Second Pivot Point and Rotate -

When using `getPivotPoint`

or `getAbsolutePivotPoint`

the results obtained depend on whether you are using a *set pivot only* method, that is `setPivotMatrix(translation)`

or `setPivotPoint`

or the *set pivot with move* method, that is `setPivotMatrix(translation)`

.

In both of the following cases the box has then been rotated through 90 degrees, positioned at (6, 1, 2) and the pivot has been set to world position (5, 0, 1) which is (-1, -1, -1) relative to the current position of the local origin of the box.

**Set Pivot Only Method**

Getter | Results | Explanation |
---|---|---|

box.position | (6, 1, 2) | Position as set |

box.getAbsolutePosition() | (6, 1, 0) | Position of box (yellow sphere) as seen, in world coordinates |

box.getPivotPoint() | (-1, -1, -1) | Position of pivot (red sphere) relative to local origin of box, as set |

box.getAbsolutePivotPoint() | (5, 0, 1) | Position of pivot as seen, in world coordinates |

**Set Pivot Only Method**

Getter | Results | Explanation |
---|---|---|

box.position | (6, 1, 2) | Position as set |

box.getAbsolutePosition() | (7, 2, 1) | World coordinate position of the created origin of box (green sphere) |

box.getPivotPoint() | (-1, -1, -1) | Position of pivot (red/yellow sphere) relative to the created origin of box |

box.getAbsolutePivotPoint() | (6, 1, 2) | Position of pivot which is the same as the position of the box due to the change in the box's local origin |

This table alone shows one good reason not to use the *set pivot with move* method unless for amending old projects.