Switching between FreeCamera and DeviceOrientationCamera

I am trying to switch between a FreeCamera and a DeviceOrientationCamera, but I am getting some “offset” issues when switching between the two where is seems to “slide” according to the last rotation made by the camera I am switching from. A simple verson of what I am trying to do can be seen in this PG. I am assuming the rotation values here are the wrong value to copy across, or am I missing something else in regards of how the orientation camera is supposed to handle rotations ? change camera with C key.

https://playground.babylonjs.com/#D3HXVZ

So what I want is to have the cameras have the same point of view when switching back an forth, so no visual change until the user rotates or interacts again after switching.

Any help is greatly apriciated.

1 Like

hey!

you need to cancel the current rotation (accumulated by the inertia):
https://playground.babylonjs.com/#D3HXVZ#1

Ok. So the .rotation does not do the same for meshes and cameras, but that clears a bit of my confusion regarding the use of .cameraRotation. The playground was a bit hackish, gut I should ba able to make this work in my actual project, so I will mark this as solution for now. Thanks Deltakosh :+1:

1 Like

So i tested a bit more, and everything seems fine on desktop, but I am having some problems when I run it on a phone;

https://playground.babylonjs.com/#D3HXVZ#6

This is my updated attempt(with some unnecessary calls). I tried with .resetCurrentRotation and getViewMatrix(true) but no improvement, but i might be using them wrong. It looks to me like the orientation is based on the actual orientation of the device and not like a delta value of the changes in the gyro or whatever, so i guess I need to calculate the differance to “ofsett” it back to the correct rotation. switching from device orientation back to free camera seems to work correctly.

Sry for probably basic stuff here, but I hope someone can help me figure this out. :woozy_face:

Hey

the function to call should be something like camera.resetToCurrentRotation(). In this case the camera will get back to camera._quaternionCache.

I belive I already tried that, but I will give it another go and see if I can make it work, thanks for pointing in the right direction :slight_smile:

1 Like

I am still not getting the results I want, and I feel like I have tried everything.

Escentialy I want to have the deviceOrientationCamera rotated to be in line with the freeCamera when switching, so I took a look at the .enableHorizontalDragging() that seems to do most of what I want and it works fine on desktop and on mobile, but I cant figure out how to snap the camera in code when switching. The problem seems to be only when i get sensor inputs, so I am testing wtih the orientation sensor in chrome.

I guess I need to do something similar to the .enableHorizontalDragging() method, but I do’t quite get these two lines;

Quaternion.FromEulerAnglesToRef(0, e.offsetX * this._dragFactor, 0, this._tmpDragQuaternion);
this._initialQuaternion.multiplyToRef(this._tmpDragQuaternion, this._initialQuaternion);

In perticular the first line there. If anyone got a working solution to this feel free to post as I feel like I am just digging myself into a bigger hole with my own solution at this point … :S

Also is rotation and quaternionRotation “mutualy exclusive”, meining if I set one the other will be “nulled” and no convertion is done between them ? I was sort of assuming that rotations would be done with quaternions internaly, but I guess this might be an optimization issue … ?

Quaternion will have precedence. If you set a value to Rotation while Quaternion is set, it will be added to it. But I highly recommend to only use one of them and set the other to null

The main issue here is that the deviceOrientationCamera needs to keep track of the initial rotation (the one in place when the system received the first device orientation event). Maybe you could try to dispose the camera and recreate a fresh new one?

Thanks Deltakosh, I will try disposing and creating a new one. I was also thinking that I could set the _initialQuaternion, but I guess that will not work when I eventualy switch to TS as it is a private/protected property… or is there some other way to access it ?

Anyway, thanks for the help again, much apreciated :slight_smile:

I can still expose the property for you if you think it could help :slight_smile:

I have been getting some wierd results with fast spinning camera when I testing to sett it “manualy” but if I get some decent results I might just ask you to do it then. Will report back once i get to test some more.

1 Like

Getting a bit closer to a solution (I hope :S) but i still got some issues;

https://playground.babylonjs.com/#D3HXVZ#16

I tried to adopt the functionality from horizontal drag (implemented by @trevordev I belive). Taking the liberty to ping him, If he got some insights, hope that is ok…

Anyway, this code seems to work mostly on my iPad, so when i go from freeCamera to the deviceOrientationCamera it rotates the horizon to where it was for the freeCamera, but it looks like it renders like a frame or so before it pops to the correct rotation and that seems a bit odd to me, also on desktop it now just spins when I switch into the deviceOrientationCamera before I rotate the sensor in chrome developer tools. Is there something other than .cameraRotation.x .y and .z i need to “reset” to make it stop spinning maybe?

If it wasn’t for the first frame that “glitches” when i enter on iPad I could use this and just disable the option on desktop.

btw. is there anything built into babylon for device detection stuff for this kind of use, like phone vs. desktop, what browser is used and so on, or is this something people build themselves or use other libraries for?

EDIT: and in line 43 now i add a rotation to align it on my iPad. So I guess this might be different depending on device, so just save a new playground for testing if this is wrong for your device. I will figure out a more generic calculation later.

I do not have a device to test right now unfortunately

No worries Deltakosh, I think I am closing in on a solution, just need to figure out some rotation calculations I think, but it seems I am going to need the initalQuaternion to make it work it the way I am trying now, so if it is not a big deal, I would appreciate it being public for when I eventually port to TS.

https://playground.babylonjs.com/#D3HXVZ#18

This is how it is right now, so I just need to calculate the rotation in relation to the initial rotation i guess.

btw, is there a way to pull a sensor data, like the device orientation, or force an initial value. It seems it does not get set until i actualy rotate the device, so it might not be an issue other than with the sensor “debugging” in the chrome developer tools. If you rotate the camera slightly in this PG before switching it will start spinning unless the orientation sensor (like in chrome devTools) have been interacted with, so this should only happen on desktop i guess.

We have no public API to set an initial value unfortunately :frowning:

Ok. I have an ide for a workaround then, thanks again for the help :+1:

1 Like

Finally found the/a solution for this;

https://playground.babylonjs.com/#WL637P#4

Leaving a link here if anyone else needs the same/similar solution. You just need to give it some sensor info before you do the first switch , so I will enable the button in my own projects wen it first gets sensor input, but seems to work on both desktop and iPad tested so far.

But for my solution to work I set the internal value _initialQuaternion on the deviceOrientationCamera, so if this could be exposed as you mantioned erlier @Deltakosh, it would be real nice. Thanks.

1 Like