Closed Dino4674 closed 12 years ago
I found this library http://www.c3dl.org/index.php/tutorials/tutorial-9-camera-basics/ and I see that it can set camera's roll, pitch and yaw values.
How to do this with Three.js?
Camera always look at 0,0,0? You must have a camera.lookAt()
overriding your rotation somewhere in your code.
Indeed I had, in my render function I left camera.lookAt(camera.target). I fotgot that the rotation is what I must change in my function not camera.target.
Can you answer my other question then. What would be the best way to set those rotation values?
Currently I have fixed mesh at 0,0,0 and it is a cube 200,200,200. Camera is fixed at 0,0,1500.
Now I would like to set camera's rotation based on roll, pitch and yaw I get from my mobile device. Currently I am doing this and there is some movement:
camera.rotation.x = roll / Math.PI
camera.rotation.y = yaw / Math.PI
camera.rotation.z = pitch / Math.PI
So the question is. Is this the right math I am doing here and does it matter which axis rotation goes first? Those roll, yaw and pitch I get from my device are values from -PI to +PI
That should work I think. By default rotation order is xyz
.
Ok, I'll play with it now. Just wanted to know if I was using these values correctly and in which order should I rotate camera. Thank you.
@mrdoob I remember I red somewhere on this issues list about camera which can have roll, pitch and yaw values to be set. I am struggling now with that thing. I have roll, pitch and yaw values and now I see that those values are relative to the camera's axis with some refference point.
So lets say that I init camera and it's rotation is (0,0,0) and roll, pitch and yaw are (0, 0, 0)
What I would like to do is set camera's rotation (x, y, z) based on those roll, pitch and yaw values.
Can you give me some tips about it?
What do you have so far?
Well I've been doing some research about rotations and realized that roll, pitch and yaw are not so good for transformations in 3D graphics and that quaternions or matrices are better solution. I see that Object3D can also use quaternions so this is good.
I'm most familiar with roll, pitch and yaw because they are more natural and right now I am reading an article about matrices and quaternions so I can understand them better.
I can easily acces my mobile device's orientation and I can read them as (roll, pitch, yaw) or I can read quaternions (X, Y, Z, W) or I can read rotation matrix.
I guess then I should go with quaternions here and do something like this:
//at init
camera.useQuaternions = true;
//refreshing the camera orientation latter in code
camera.quaternion.x = deviceQuaternion.x;
camera.quaternion.y = deviceQuaternion.y;
camera.quaternion.z = deviceQuaternion.z;
camera.quaternion.w = deviceQuaternion.w;
I tried this directly but it is not behaving as expected, I guess I am not using properly those values. Do I have to do some math also before?
Maybe the coordinate system from the device is different from the one we use? We use right handed:
iOS devices also use right handed system:
So when I say that I can read device's orientation, It is done from some reference point which I can choose (trueNorth, magneticNorth). And then rotation 0,0,0 is when the device is in this position:
Lets say that device is laying on a flat table and its right side is pointing north. That is (0, 0, 0) orientation.
I know that ThreeJS has reference point when camera is standing straight and looks down the Z-axis in it's own coordinate system.
What I would like to do is "remap" somehow that values from phone so that it gives me (0,0,0) when device is standing straight and looking at the north (it's back size is pointed north) just like ThreeJS camera is looking down the Z-axis when it's rotation is (0, 0, 0)
That is (0, 0, 0) orientation.
I think that's incorrect. Orientation needs to be either (1,0,0), (0,1,0), (0,0,1), (-1,0,0), (0,-1,0), ...
What I would like to do is "remap" somehow that values from phone so that it gives me (0,0,0) when device is standing straight and looking at the north (it's back size is pointed north) just like ThreeJS camera is looking down the Z-axis when it's rotation is (0, 0, 0)
Oh wait. So you're saying that the rotation is working fine but that your model needs to be rotated so it's standing up instead?
Sorry, I am talking about roll, pitch and yaw values here. They are (0,0,0) when device is in described postion.
Actually I am saying both. I need to rotate the model so it stands up and that should be (0,0,0) just like in ThreeJS. And I need to set correct values to ThreeJS's camera and for that I think quaternions are better then roll, pitch and yaw.
I monitored the values of x,y,z and w on a device.
w is always 0.
x,y,z are (0, 0, 0) when device is flat on table and X+ axis is pointing north (X+ of device).
Values goes from 0 to 0.99999 and sometimes -0.03 or something like this. So the question is, can I directly put those values in Object3D's (Camera's) quaternion variable or do I have to do some math in between because if I put them directly I don't get expected behavior.
@Dino4674 Do you understand what your mobile device output represents?
Will you answer the questions I asked you in this related thread? https://github.com/mrdoob/three.js/issues/1439#issuecomment-4312559
I'm sorry, but without additional information, it is very hard to help you.
@WestLangley I understand that output and values (roll, pitch, yaw). They are behaving exactly as they should. Today I started learning about quaternions so I don't understand those (x,y,z,w) values but I guess they are correct since (roll, pitch, yaw) are OK.
Sorry for not answering there, I thought I could solve this with Euler angles but then I learned some things about them and realized that they are not so cool.
Not sure if I understood from wikipedia but I guess this will answer. Example scenario:
Then I again tilt device by 90 deg to the right (screen is now looking south) (roll, pitch, yaw) = (1.57, 0, 3.14) (x, y, z, w) = (- 0.7, 0 , 0.7, 0)
You see in this last rolling, I rolled device by 90deg and it is showing me roll 1.57 just like the first time. But that rotation was over Y axis counterclockwise this time since I first rotated device by Z-axis (yawed) first.
If I need to tell you some more info, please let me know, thank you.
This is hard to do long-distance, I hope someone else who has an iPhone will chime in. (I don't have one.)
It looks to me, and I am making an educated guess, that the triple is ( roll, pitch, yaw ).
I am guessing that the Euler order is ZXY; that is, yaw-pitch-roll.
That means that given a desired reading of ( roll, pitch, yaw ), to orient the device so it gives that reading you:
Test out the theory for a lot of triples -- including rotation like (PI/4, PI/2, -Pi/4), to see if the theory is correct.
If my guess is wrong, I think I'll have to ask you to get someone else to give it a shot, as this is a bit difficult long-distance.
The goal is to understand what the readings mean, and what order they are intended to be applied to achieve the specified orientation.
I understand it's hard to do long-distance so let me try to explain with screen shoots.
I've put camera at (0,0,0) and plane mesh at (0,0,-1500). Mesh size is (200, 200). By default, camera is looking down the Z-axis in ThreeJS.
This are mobile's coordinates:
And when mobile is in this postion, (Roll, Pitch, Yaw) are (0,0,0) and now ThreeJS's X,Y,Z are at the same position as iPhone's X,Y,Z. And device's rotation "matches" ThreeJS's camera rotation. (0,0,0)
Now below are some of the examples of rotating the device: (when I say (0,0,0) I'll be referencing Roll, Pitch, Yaw values)
I rotate ThreeJS's camera like this in code:
camera.rotation.x = deviceRotation.pitch;
camera.rotation.y = deviceRotation.roll;
camera.rotation.z = deviceRotation.yaw;
Values in red label are values from mobile device rotation. And imagine that you are holding a device in your hand while it is looking at the ground and north is at yours right side.
Init position:
(0,0,0) and ThreeJS camera rotation is (0,0,0)
I roll device to the right now and set the camera's rotation and it is behaving as expected:
Now I roll it left and it is behaving as expected:
Now I pitch device down:
Pitch up:
Back in init (0,0,0) and yaw for 180 deg and it is as expected:
But here comes the problems.. if I now roll device to the right I don't get expected values, because roll is still positive and I acctuly did negative rotation over y axis adn that image should be on screen's right side:
Roll left:
Pitch down, image shoud go up, not down:
Pitch up, image should go down:
Back in init (0,0,0):
Yaw 90deg OK:
Pitch up. Image goes left when it should go down:
Pitch down. Image goes right when it should go up:
Roll right:
Roll left:
I hope this explains situation better to you.
I guess that I need some way of rotating the camera over it's own axis not the scene's or something like that.
EDIT: I watched values more carefully and I realized that those values on phone are relative to the gravity. So that means that Roll represents an angle between iPhone's X-axis and surface (gravity is vertical to surface). Pitch represents an angle between iPhone's Y-axis and surface. And Yaw represents rotation over gravity vector.
@WestLangley Just to let you know that I found a solution. It helped a lot that you noticed that iPhones Euler's order is ZXY.
All I had to do was:
camera.eulerOrder = 'ZXY';
.. and later in refreshing method:
camera.rotation.x = deviceRotation.pitch;
camera.rotation.y = deviceRotation.roll;
camera.rotation.z = deviceRotation.yaw;
Yay! Success! :D
When I init my ThreeJS base application I must specify camera target:
I also have one mesh which I have put on 0,0,0 coordinates.
Now I need to set camera's rotation based on roll, pitch and yaw values that I receive from my mobile phone and these values are from -PI to +PI.
I tried something like this
but camera would always look at 0,0,0 and I need it to look at place based on roll, pitch and yaw. How can I accomplish this?