Using the camera rotation axis to rotate an object

I have a situation in AR where I have parented an object to a camera in order to manipulate the parented object. Right now when I rotate it, the object to rotate around its own local axis as that is “normal” behavior. But, as you can see in the video, this gets disorienting to figure out which axis control rotates which axis after the object’s rotation starts to change.

Instead, I want it to rotate around the camera’s alpha, beta, gamma, axis. So the rotation always changes consistently from the view of the user. This is much less disorienting as then swiping left or right would always rotate the object left and right regardless to its local orientation, swiping up and down would always rotate end over end regardless as to the object’s local orientation.

I don’t know why this one is giving me so much trouble today. Can someone walk me through the process of setting up that transformation? I am using Quaternions.

cc @RaananW @PolygonalSun

Can you provide a playground with what you currently have?

this feels to me a little similar to this thread which helped me out a lot doing similar stuff where we want to spin the object regardless of its local orientation. Implementing Arc Rotate Object like Arc Rotate camera - #3 by Anupam_Das

I was playing Zelda TOTK tonight and found a great example of what I am talking about.

Do you see how the object is basically parented to the camera when undergoing manipulation, but the rotation gizmo does not rotate along the manipulated objects local axis. The rotation gizmo instead stays aligned with the camera view and more importantly causes the object to rotates along the gizmo (and camera’s) alpha and beta axis. I want that.

That way swiping up or down always predictably rotates the object end over end and swiping left and right always rotates the object left and right.

The problem with my current setup is the manipulated object rotates along its local axis, so the user loses the frame of reference easy and it becomes a real pain to manipulate. I would guess the Zelda developers realized the same thing.

wouldn’t that be extremely confusing to the user? as this will mean that technically, the rotation axis will change after every rotation? (unless I misunderstand something, which is very much possible).

Instead, I think it would make sense to show guiding circles - similar to the way the gizmos work. Three colors, and three controls that correspond to these colors. So the user knows - if I use the red slider it will rotate around THIS axis. it doesn’t matter what THIS axis is, as long as visualy the user knows what they rotate.

I think you may be misunderstanding but easy to do as I am having trouble articulating this one… which consequently is why I am having trouble programming it :stuck_out_tongue:

On screen now you have three sliders that appear once you select an object to manipulate. Left slider is Rotate X, Center is Rotate Y, Right is Depth from the camera. Eventually these will be swapped out for swipe commands - Swipe Up/Down always rotate the object end over end, Swipe Left/Right always rotate the object left to right, Pinch changes distance. Since this is AR, moving the physical device (phone / tablet) around positions the objects in the world, this is done by parenting to the camera. The Distance and camera based positioning work fine. Its the how to keep a user from getting confused with the rotations, when the object is parented to the camera for manipulation, that is giving me trouble.

Since the AR camera is able to move around the environment, my current method of using the manipulated objects (MO), the cubes for now, local transform rotation gets really confusing quickly because your perspective to the MO’s local axis is always changing. Once you rotate the MO out of the Y=Up, X=LR, Z=Back its really hard to know how to manipulate the object to get it into an orientation you want.

Consistency in interaction seems like the key to solving this. The only real consistent frame of reference a user has is that of their own camera. The thought I had was that if we take the perspective of the screen, and regardless as to the MO’s current local axis rotations, if you swipe left or right, that would always rotate the object left / right (Alpha axis) from the camera’s point of view, and swiping up and down would always cause the MO to tumble end over end (beta axis) from the camera’s point of view. This works because while the object is being manipulated, its actually pinned to the camera through parenting. It looks like Zelda took a very similar approach with their object manipulation rotational controls. Though not perfect, it does get the job done.

But, setting up the axis transforms so that no matter if the MO is rightside up, or sideways, if I swipe up/down the MO locally rotates end over end along from the perspective of the camera’s ZY plane (beta axis), and swiping left / right always rotates the MO locally but along the camera’s XZ plane (alpha axis) is what I am having trouble setting up.

I am also happy to entertain other thoughts.

Note: eventually I would want to introduce the third rotation along the XY. You don’t need that if you have the other two rotations outlined above, you can get to any rotation using just those two rotation axis, but a custom two finger twisting gesture that sort of mimics turning a dial with your fingers in order to turn something upside down or rightside up would save a few movements

A few thoughts :slight_smile:

  1. This:

Is not entirely correct. It is actually much better to anchor an object in the real world and have it positioned there, as opposed to displaying it flying in the air in front of the camera. Of course, it depends on the use case, but why use AR if you don’t interact with the real world?

  1. Parenting an object to the camera also forces the camera’s rotation to be applied to it. You already found that out yourself, of course. But maybe, instead of parenting (if that’s the use case) you will only change the position? A very naive approach could be - update the object’s position on each frame instead of parenting. This way the rotation of the object is fully controlled by you

A very simple approach - get the normal you are trying to rotate around (in local space), transform it using the box’s world matrix, and apply it as rotation. This has an example of how the box will rotate around either the X axis or the Y axis, independent of the camera’s rotation, though the box is the camera’s child:

Babylon.js Playground (babylonjs.com)

1 Like

Yeah the use case on this one is a bit unique.

The attaching the component to the camera to translate evolved from some testing of options. It beat out other options I tried to allow you to pick up a component sitting one surface, like a table, move it across the room to say a bed where a larger object under construction like a robot is being assembled, rotate it around to correctly position it, and then attach it to the correct spot in a similar way to how you would pick up and move an object across the room IRL. Manipulating your device for translation is a much more precise and intuitive interaction than using some sort of on-screen control to manipulate world-coordinates as the device is “in-hand”. Sadly that does not carry to rotation as you can’t see the phone once rotated :person_shrugging: It has a few other major benefits too.

The playground shared may do the trick for rotation. I’ll throw it in tonight to test. Ridiculously simple as always with BJS :expressionless: Thank you.

1 Like

With one small change to the transformation matrix, it works perfectly. Thank you.

2 Likes