# Set Pivot on rotated/scaled mesh

## Recommended Posts

Hi there,

I'm trying to rotate a mesh around a specific point. I use the setPivotMatrix + translate back and it works great, as long as the mesh isn't already scaled or rotated. If it is, the mesh jumps to a wrong position before it starts rotating.

I took care of the scale but can't figure out how to handle the rotation. Here's what I have:

``````
var position = new BABYLON.Vector3(10, 10, 10);

// Mesh position relative to pivot point
var relativePosition = mesh.position.subtract(position);

// Set pivot matrix
mesh.setPivotMatrix(BABYLON.Matrix.Translation(relativePosition.x * (1 / mesh.scaling.x),
relativePosition.y * (1 / mesh.scaling.y),
relativePosition.z * (1 / mesh.scaling.z)));

// Translate back
-relativePosition.y,
-relativePosition.z));``````

Thanks guys

##### Share on other sites

Am working on the same problem (well the rotation one) as is @DigiHz Data

have an idea why and where it goes wrong but will take a few days to confirm (or not) that I can produce a solution.  If I get rotation solved, scaling will probably follow.

##### Share on other sites

Look at my updated PG about a possible solution.

##### Share on other sites

Looking good!

Why do we need pick a specific axis? let's say I want my pivot to be (3, 4, 5) instead of 0, 0, 0, could I just pass the (0, 0, 0).subtract(3, 4, 5) vector instead? Would that work?

##### Share on other sites

I can not tell you about that, sorry,

you can figure it out from the code in the PG i think.

##### Share on other sites

@Numa and @DigiHz Data after days playing around with setPivotMatrix I suddenly felt very foolish as I realised the approach was wrong and I had in fact produced the basis of a solution back in May 2015 in the post below (back in the days when I was new to BJS and was misinterpreting many things and was working on an un-necessary solution to something dealt with much easier - so nothing changes does it)

However as wrong headed as that solution was it was the solution to the pivot problem.

Here are two methods one for rotating around a pivot and one for scaling from a pivot both of which allow you to move the pivot and the mesh using just .position. If you would both like to test them out and see if they fail anywhere this would be very useful. (After all I though I had found a solution previously and it failed).

Of course anyone else is welcome to test them out as well.

The Rotation Method

rotateAroundPivot takes three parameters - the position of the pivot (Vector3), an axis (Vector3)  to rotate around and the angle (number as radians) to rotate. Rotations are accumulative.

``````BABYLON.Mesh.prototype.rotateAroundPivot = function(pivotPoint, axis, angle) {
if(!this._rq) {
this._rq = BABYLON.Quaternion.Identity();
}
var _p = new BABYLON.Quaternion(this.position.x - pivotPoint.x, this.position.y - pivotPoint.y, this.position.z - pivotPoint.z, 0);
axis.normalize();
var _q = BABYLON.Quaternion.RotationAxis(axis,angle);  //form quaternion rotation
var _qinv = BABYLON.Quaternion.Inverse(_q);
var _pdash = _q.multiply(_p).multiply(_qinv);
this.position = new BABYLON.Vector3(pivotPoint.x + _pdash.x, pivotPoint.y + _pdash.y, pivotPoint.z + _pdash.z);
this.rotationQuaternion = this._rq.multiply(_q);
this._rq = this.rotationQuaternion;
}``````

Scaling Method

scaleFromPivot takes four parameters the position of the pivot (Vector3) and the scale for x, y, z axes as numbers. The numbers used set the current scale of the mesh based on its original size with the pivot as centre of enlargement.

``````BABYLON.Mesh.prototype.scaleFromPivot = function(pivotPoint, sx, sy, sz) {
var _sx = sx / this.scaling.x;
var _sy = sy / this.scaling.y;
var _sz = sz / this.scaling.z;
this.scaling = new BABYLON.Vector3(sx, sy, sz);
this.position = new BABYLON.Vector3(pivotPoint.x + _sx * (this.position.x - pivotPoint.x), pivotPoint.y + _sy * (this.position.y - pivotPoint.y), pivotPoint.z + _sz * (this.position.z - pivotPoint.z));
}``````

Here is a playground to try it out

##### Share on other sites

Thanks @JohnK !! That worked for me. I had to change that first line though:

this._rq = BABYLON.Quaternion.Identity();

with

this._rq = this.rotationQuaternion;

otherwise if the object was already rotated it would mess things up.

Thank you so much!

##### Share on other sites

@Numa thank you for pointing this out. I had assumed that my methods would be applied from the start and all rotations would take place using them. In practice your correction would only work if previous rotations had been done using mesh.rotate. If a rotation was set just using mesh.rotation then this.rotationQuaternion would be undefined.

Hopefully between us we now have it working correctly in all cases using the modified code below.

``````BABYLON.Mesh.prototype.rotateAroundPivot = function(pivotPoint, axis, angle) {
if(!this._rotationQuaternion) {
this._rq = BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
}
var _p = new BABYLON.Quaternion(this.position.x - pivotPoint.x, this.position.y - pivotPoint.y, this.position.z - pivotPoint.z, 0);
axis.normalize();
var _q = BABYLON.Quaternion.RotationAxis(axis,angle);  //form quaternion rotation
var _qinv = BABYLON.Quaternion.Inverse(_q);
var _pdash = _q.multiply(_p).multiply(_qinv);
this.position = new BABYLON.Vector3(pivotPoint.x + _pdash.x, pivotPoint.y + _pdash.y, pivotPoint.z + _pdash.z);
this.rotationQuaternion = this._rq.multiply(_q);
this._rq = this.rotationQuaternion;
}``````

Please feel free to test again and once more thank you for the feedback.

##### Share on other sites

• 1 year later...

Hi here,

I'm planning to make a rubik's cube with babylon. I'm new to babylon and javascript.

I'm using your function to rotate the face around the cube axis.

Here is my playground : http://www.babylonjs-playground.com/#1MKHR9#62

The "u" key rotate the upper face.

The "r" key rotate the right face.

As long as I rotate only the upper face or only the right face, everything is ok.

But, if you press "u" once, then "r" once, some pieces rotate both around the world axis (as i wish) AND around the piece axis.

I really don't understand why because I only use your function RotateAroundPivot once .

Do someone have an idea why ?

Thanks.

JMB

## 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.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×