WebGL/OpenGL: Rotate camera according to device or

2019-07-21 11:03发布

I have a web application I am trying to show a plane of map image tiles in a 3D space.

I want the plane to be always horizontal however the device rotate, the final effect is similar to this marine compass demo.

I can now capture device orientation through the W3C device orientation API for mobile devices, and I successfully rendered the map image tiles.

My problem is me lacking of essential math knowledge of how to rotate the camera correctly according to the device orientation.

I am using the Three.js library. I tried to set rotation of the camera object directly by the alpha/beta/gamma (converted to radian). But it's not working since the camera seems to always rotate according to the world axis used by openGL/webGL not according to its local axis.

I came across the idea of rotate a point 100 unit in front the camera and rotate the point relatively to the camera position by angles supplied by the device orientation API. But I don't know how to implement this either.

Can anyone help me with what I want to achieve?

EDIT:

MISTAKE CORRECTION:

For anyone interested in implementing similar things, I found out that Three.js objects uses local space axis by default, not world space axis, I was wrong. Though the official document stated that by setting "object.matrixAutoUpdate = false" and then modify "object.matrixWorld" and call "object.updateWorldMatrix()" you can manually move/rotate/scale the object in world axis. However it does not work when the object has a parent, the local axis matrix will always be used when the object has a parent.

1条回答
我想做一个坏孩纸
2楼-- · 2019-07-21 11:50

According to the W3C Device Orientation Event Specification, the angles alphabeta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''.

The Three.js camera also rotates according to intrinsic angles. However the default order in which the rotations are applied is:

camera.rotation.order = 'XYZ'.

What you need to do, then, is to set:

camera.rotation.order = 'ZXY'; // or whatever order is appropriate for your device

You then set the camera rotation like so:

camera.rotation.x = beta * Math.PI / 180;
camera.rotation.y = gamma * Math.PI / 180;
camera.rotation.z = alpha * Math.PI / 180;

Disclaimer: I do not have your device type. This is an educated guess based on my knowledge of three.js.

EDIT: Updated for three.js r.65

查看更多
登录 后发表回答