How to convert UniversalCamera rotation to ArcRotateCamera rotation

I am trying to create an office scene in which I have an office with editable rooms to showcase. I have many edit options per room, and a floorplan view that shows everything from a top-down view. When I am in the office space, I use a UniversalCamera. When I am in the floorplan-view mode, I use an ArcRotateCamera. In order to showcase the spaces in a focused manner, I created empty transform nodes in Blender that act as camera anchors that focus on the room being edited in the camera’s FOV. I have a camera anchor for the floorplan view as well. This is where the issue comes in.

When the floorplan mode is clicked, I would like to smoothly animate the Universal Camera to the floorplan camera anchor transform node, and then switch to the arc rotate camera in the same position and rotation as the universal camera, so that I can then rotate around the model as a whole. However, when I move the universal camera to the floorplan camera anchor transform node’s position and rotation, it shows up with the correct rotation, but I cannot get the arc rotate camera to do the same. This causes a very noticeable SNAP in rotation when changing the active camera from the universal camera to the arc rotate camera, which creates a UX issue. I have thought about fading to black and then switching, but I would still like the arc rotate camera to share the same rotation as the camera anchor that I placed in Blender, which it seems to never be able to do so.

Right now, I am using this setup:

var newCameraPosition = new Vector3(0, 0, 0);
configAreaCameraAnchor.computeWorldMatrix(true);
newCameraPosition.copyFrom(configAreaCameraAnchor.absolutePosition);
var dir = configAreaCameraAnchor.getDirection(new Vector3(0, -1, 0));
var newCameraTarget = (newCameraPosition.add(dir)).add(new Vector3(0, (-1) * newCameraPosition.y, 0))

var positionKeys = [
{
frame: 0,
value: this._camera.position.clone(), //pos
},
{
frame: 100,
value: newCameraPosition, //move
},
];
this.animCameraPosition.setKeys(positionKeys);

var targetKeys = [
{
frame: 0,
value: this._camera.getTarget(),
},
{
frame: 100,
value: newCameraTarget,
},
];
this.animCameraTarget.setKeys(targetKeys);
this._camera.animations = ;
this._camera.animations.push(this.animCameraPosition);
this._camera.animations.push(this.animCameraTarget);
this._camera.detachControl(this._canvas);
this._scene.beginDirectAnimation(
this._camera,
this._camera.animations,
0,
100,
false,
2,
() => {

this._arcCamera = new ArcRotateCamera(
“arcCamera”,
(-1) * this._camera.rotation.x,
this._camera.rotation.y,
newCameraPosition.y,
newCameraTarget,
this._scene
);

this._arcCamera.position.copyFrom(this._camera.position);
this._arcCamera.lowerRadiusLimit = newCameraPosition.y * 0.25;
this._arcCamera.upperRadiusLimit = newCameraPosition.y * 1.1;
this._arcCamera.attachControl(true);
this.animationFinished = true;
}
);

The issue of the arc rotate camera always being skewed off of the correct rotation that the floorplan camera anchor has seems to be with the alpha and beta rotation values of the arc rotate camera. However, I have tried MANY different combinations of x and y and z rotation values and have not been able to replicate the universal camera rotation for the arc rotate camera across multiple models. (It might work for one, but not all of them).

It also doesn’t help that the camera anchor transform node’s rotation values are either all 0 or skewed due to the transform node being a descendant of many other empty nodes in my scene graph hierarchy. When I setTarget for the universal camera in the manner displayed above, it changes the rotation of the universal camera, which I try to grab for the arc rotate camera’s alpha and beta values, but doing so often alters the universal camera’s rotation value around the x axis 90 degrees, for whatever reason, even though the camera still looks at the target.

Any help with these rotation conversions would be most appreciated. I have read the rotation conventions doc and the Universal and ArcRotate cameras docs extensively, but to no avail. I also looked at other ArcRotate <-> Universal camera questions on forums as well, but none quite talk about this problem specifically.

Thanks in advance!

I believe the complexity here is first to understand what the arc rotate camera should target. Take this example - Babylon.js Playground

Press “s” to switch to the arc rotate camera and “a” back to the universal camera. you will notice that when switching to the arc rotate the direction is now correct, since I am targeting the forward ray of the free camera, but at a specific distance from the camera. I don’t really know if the user was looking at an object 5 units away or 2 units away, and that would make a huge difference. ArcRotate focuses on a point in space, and this is why position and target are much more important than rotation

2 Likes

Thank you for your answer Raanan. I understand the difference between the arc rotate camera and the universal camera, that is not the issue. The issue is that when I animate the universal camera’s position and orientation so that it is positioned and oriented in the same way that the floorplan camera anchor node is positioned and oriented (so that I can look directly down at the office space model), I cannot get the arc rotate camera to be oriented in the same specific way as the universal camera. setTarget gets the cameras to look at something, yes. But I want both cameras to be looking at the thing in the same orientation, so that when I switch the activeCamera from the universalCamera to the arcRotateCamera, the user cannot tell that a camera change was made because they are both oriented in the same way. This issue deals with the alpha and beta values of the arc rotate camera being different than the rotation values of the universal camera. Thanks

Have you tried the example i provided? It does exactly that.

And I still stand behind everything i said :slight_smile:
An arc rotate camera get its orientation based on its position and target. not rotation like the universal camera. it is true that you can set alpha and beta, but these are not tools to set rotation but a viewing point around a specific target.

When you say this:

I say - yeah, but what is the thing they are looking at exactly? Can you tell, always, what a universal camera is currently looking at? if you do (which is possible, since you know the scene the best), all you need to do is set the target and position accordingly and you wouldn’t even notice the camera has switched. I solved it by saying “the dev is looking at an object 5 units away from them”. Not a perfect solution, but it does work.

Thank you again for your response. So I agree with what you said in that setting the position and target the same makes the orientations the same, if that is all that is being set and all that is desired. But, you can notice in my provided code that the UniversalCamera gets its target set in the direction that the floorplan camera anchor faces. I NEED both the Universal Camera and the arc rotate camera to be not just oriented the same way, but oriented the same way as the floorplan camera anchor is oriented, specifically around the y axis, so that the model fits in the fov correctly. I cannot just the universal camera rotation to the same as the floorplan anchor rotation because the latter is read in as 0,0,0 because it is nested in other empties. even the absolute rotation and quaternion is 0,0,0. Not sure if that is a blender → babylon or gltf error or what, but that is an issue. So, to get the unviersal camera rotation the same as the anchor, I set its target in the direction the anchor is facing. For whatever reason, I cannot do the same with the arc rotate camera to get it oriented in the same way. I can get it facing the same way, but not rotated in the same way. As an illustration of this problem, the code produces this result:

Universal Camera:

ArcRotateCamera:

The orientation of the floorplan camera anchor in the Blender model, for reference (has a different fov, but the orientation is the same as the universal camera):

So I think I understand what you are saying, but just setting the positions and targets the same does not work for what I’m trying to achieve. You’re example seemed to be predicated on the alpha and beta of the arc rotate camera always being zero, and the target and rotation of the universal camera being 0,0,0 as well. Believe me, I’ve tried many ways with setting everything to zero, etc., and that works for what you said, but that is not the only thing that is desired, because I need to match the orientations with the reference anchor that is read from the model. So I can get both cameras looking at the same place from the same position, but that last mile of rotation around the y axis is missing without the alpha and beta parameters being set properly. Setting them at 0 and 0 is no good. It changes the orientation. I’m trying to set them to the x and y values of the universal camera rotation (really, I’ve tried every permutation, including z and negative values to flip them), to no avail. Hope this helps clear things up. Thanks!

Hi @RaananW, don’t mean to bother you, but do you have any thoughts based on my update? I tried what you recommended and it didn’t work. Thanks!

This is exactly what my example doesn’t show. The only thing fixed in my example is the radius from the object, which is set at 5 (as i mentioned before). The alpha and beta are being calculated when you press “s” and are then applied to the camera (using the setTarget function). The values in the constructor are only there to have something. you can write 300 and Math.PI, it wouldn’t make a difference. If you want to show me an example where the camera changes orientation incorrectly (this is what i understand from your images), I will be more than happy to look into it.

There might be edge cases where the arc-rotate camera “flips”, especially when beta === 0, as it only has an up vector (y), but not orientation towards what’s “forward”. This is also solvable, but it’s an edge case.

Gooootcha. This is making more sense, thanks.

So that ^ seems to be my issue. I have the camera looking straight down, and because of that. its rotation around the y axis is not as desired. I can get the universal camera and arc rotate camera looking the same way, but not in the exact manner (rotation around the y axis) that I have the predefined camera anchor transform node set in.

I tried setting the predefined camera anchor to have the x axis rotation be slightly skewed (like 1 or 0.1 radians) so that the forward direction had both the x and y axes rotations non-zero, and that seemed to be an effective minor adjustment (temporary fix) for one model, but the solution did not persist across models.

You mentioned this is solvable, do you have a reference that you can provide me/point me to? Thanks so much for your patience.

Edit: This might be a good illustration of a common occurrence of this problem. The immediate rotation snap is due to (I think) the switch between the universal camera and the arc rotate camera. both use the same position and target.

Even so, both are still wrong because the correct orientation (based on the camera anchor) is flipped to how the camera is at the end in the video above.

Would you be able to share a playground that simulates this behavior?
It will be much simpler to help you this way :slight_smile: