Implementing Arc Rotate Object like Arc Rotate camera

I want to rotate an object exactly like Arc rotate camera works. So instead of rotating the camera, the camera is fixed and the object rotates instead (using mouse inputs). What is the simplest way to do this?

A. Any pointers as to the approach for the rotation maths. Should I rotate the object along the camera(view) up and side vectors rather than the world axis? This topic has been asked several times but the solutions do not behave like the art rotate camera, mainly… that the rotations are not based on the cameras view vector. An example of this problem: https://www.babylonjs-playground.com/#CGXLT#5

B. Any way to just hijack the camera rotation behaviour from ArcRotateCamera and apply it to an object instead?

C. We can assume that the object I am trying to rotate has a pivot always at the origin.

D. Helpful code samples or psudocode are welcome

@PolygonalSun might be able to help with pointers for this.

1 Like

thanks @sebavan

I have donet something similar in unity where I have rotated the object based on the cameras up vector and side vector. I tried this in babylon but camera up in babylon is always 0,1,0 even after I set camera.updateUpVectorFromRotation = true; (I am using an arc rotate camera)

Hey there! Going to follow up on this to get the ball going a bit.
If we want to exactly mimic the behavior of the ArcRotateCamera we can take a look into the source code itself. Babylon.js/arcRotateCamera.ts at master · BabylonJS/Babylon.js · GitHub

However another solution we can do is just taking a look at the math of the demo you posted!
At first, I wasn’t sure what the initial problem was with this demo. This was until I started tilting in the up and down direction. Think we’re gonna need some math for this! Instead of just X rotation when we move up and down with the mouse, we want to rotation around BOTH X and Z based on the current rotation of Y.

Here is corrected demo: https://www.babylonjs-playground.com/#CGXLT#27

And to break it down further let’s look at the math changes:


   let dx = evt.clientX - currentPosition.x;
   let dy = evt.clientY - currentPosition.y;
   let f_r = new BABYLON.Quaternion.Identity();

   BABYLON.Quaternion.FromEulerAnglesToRef(-dy/300,-dx/300,-dy/300,f_r);
   f_r.multiplyToRef(meshmodel.rotationQuaternion,meshmodel.rotationQuaternion);

First we get the deltas of the X and Y of the mouse. Next we want to use quaternions to go from local space to world space. Notice how I use dy in both the X and Z spots because we want to account for both.

Shout out to @syntheticmagus who gave me some insight on the math :wink:

Let me know if you have any follow up questions. :slight_smile:

2 Likes

@msDestiny14 this is awesome, and makes sense. I ended up implementing a slightly similar solution (after a refresher on model view matrices) actually only I constrain the Y axis rotation so it doesn’t “tilt” the model undesirably if that makes sense. I’ll try to post a sample of that and see if anyone has a better way, thanks again. Wonderful community here.

1 Like

Hey @Anupam_Das did you find a way to turn of tilting by any chance?

Since the aim of this is to emulate the ArcRotateCamera, it seems like the only thing that’s missing is to rotate the mesh along the camera viewpoint’s z-axis (camera.getForwardToRef?). With all movements of the ArcRotateCamera, the viewpoint should always be upright (viewpoint’s up is always point up, even if at an angle). For the mesh’s rotation to look right, the mesh’s up and down need to point straight up and down, relative to the camera viewpoint’s x and y axes. TBH, I’m not sure what the math/code would look like, off the top of my head, but that’s the only thing missing from the solutions provided.

1 Like