|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic Page: 1 2 »» |
Last Thread Next Thread ![]() |
| A Simple Quaternion-based Camera |
|
![]() s_cloudx Member since: 12/12/2001 From: Agoo, Philippines |
||||
|
|
||||
| Thanks for the Great Article! :-D I would love to see a third-person and a SLERP tutorial in the future. Keep up the good work. |
||||
|
||||
![]() DarranJones Member since: 9/16/2003 |
||||
|
|
||||
| Good article dude! Ive been looking for a good article on quaternion based cameras for ages but never been able to find one I can get to grips with. Also, a third person version would be groovy aswell =) Thanks again. Darran. |
||||
|
||||
![]() Ronin Magus Member since: 5/30/2002 From: Franklin, USA |
||||
|
|
||||
| Awesome article man. I'm just barely struggling through calculus 2, and the quaternion tutorials out there are mind-boggling.. but this one is great! Thanks very much. |
||||
|
||||
![]() swiftcoder Member since: 7/3/2003 From: Boston, MA, United States |
||||
|
|
||||
| Great article, I have a good understanding of quaternions, but this is the most concise article I have ever seen on the subject! ------------------------------------------- Here's to the crazy ones, the misfits, the rebels, the troublemakers, the round pegs in the square holes, the ones who see things differently. ------------------------------------------- |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| Nice and simple just like it should be. I hate seeing a bunch of technical bla bla's I like source examples even if it isn't a full or optimized implementation, snippets of data structures are much better.. kudos my boy, now show me how to slerp ! |
||||
|
||||
![]() max621 Member since: 2/9/2000 From: Riverside, USA |
||||
|
|
||||
| Examples + conciseness = awesome. Hope to see more articles from you |
||||
|
||||
![]() Xetrov Member since: 11/7/2000 From: Brisbane, Australia |
||||
|
|
||||
| Yep, good stuff! You have implemented a camera pretty much the way I wanted to, but mine just wouldn't work!!! Maybe trying out your tutorial will remove my problem! Thanks |
||||
|
||||
![]() Timkin Member since: 4/29/2001 From: Melbourne, Australia |
||||
|
|
||||
| Just one very small point... on the third page, the equation for W, which reads: W = R*V*P' should actually read W = R*V*R'. It's a good introductory article... please keep em coming! Timkin |
||||
|
||||
![]() Sander Moderator - Web Development Member since: 4/19/2002 From: Den Bosch, Netherlands |
||||
|
|
||||
| A very good article. I've been struggling with rotating vectors with quaternions a bit. I finally understands now. Thanks! Now for the nitty gritty: I found two code bugs in your article. It's the same bug twice and their in the first two sample codes (the conjungate and normalize functions) Both functions should be " void FunctionName" and not " quaternion FunctionName". Maybe it's just an error on the page and the "::" between them got eaten by IE, maybe not. Sorry if I sound picky. Oh, and please do that 3rd person camera :-) Sander Maréchal [Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail] |
||||
|
||||
![]() eratos Member since: 6/28/2002 From: United Kingdom |
||||
|
|
||||
quote: No, the last line of the function says "return quat;" so it's certainly not a void function! The fuction could have been written using references to modify the quaternion in place, but it's not. It's expected use would be: quaternion q; q.w = q.x = q.y = q.z = Somehting random q = normalize(q); The functions, as written, are perfect. |
||||
|
||||
![]() Sander Moderator - Web Development Member since: 4/19/2002 From: Den Bosch, Netherlands |
||||
|
|
||||
| A, I see now, it's not passing by reference. Excuse my ignorance :-) I'm used to passing by reference so much when dealing with math that I missed it. Sander Maréchal [Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail] |
||||
|
||||
![]() Seriema Member since: 6/15/2001 From: Stockholm, Sweden |
||||
|
|
||||
| WOW! thanx! that was a very short and great article! Just the way they should be Can I give you a tip? I'm always struggling with interfaces (classes), in this case your camera and quaternion class are perfectly clear how they should be (you gave great examples). But one thing I missed would be a simple index over the stuff you went through in "Quaternion operations", in your case they were only a few and easily readable. But when the number of stuff grows a simple index of operations really helps the reader in designing a class One thing that boogled me was the RotateCamera(). Isn't using quaternions like that like killing a mouse with a bazooka? I've heard about cameras using quaternions to store their data and quickly make rotations and such, I was curious about how that's really implemented. How would you go about rotating the view quaternion directly (without 3 temp quaternions)? Another question is the Camera::SetViewByMouse(), you have statics in there. If you would have 2 or more Camera objects, wouldn't they share statics and give really weird hard tracable bugs? Hope you write that second article soon, a 3rd person camera with SLERP interpolation would be sweet! And how one would go about having _several_ cameras out in the scene (think GTA3 Vice City), what you could do with them and what you should think about. Having cameras following objects is also fun. Both "following" like a stalker, and also "following" as a surveilance camera. How do one make a "stalker" camera avoid objects such as walls (don't go inside the wall) and bridges (go under/over it). Camera effects, like "shaking" and motion-blurr (but that might be closer to rendering techniques?) etc. Using the camera to billboard stuff is also a usual technique, both the "right" way (projecting on the inside of a ball) and the "fast" way (projecting on the "camera plane" of up and right vectors). Those are all stuff I'm interested in hearing about, there are a bunch more things a camera can/should do that I probably don't know about }-- Programmer/Gamer/Dreamer --{ |
||||
|
||||
![]() FlamePixel Member since: 7/16/2002 |
||||
|
|
||||
| Very Nice. I've been waiting for something like this. |
||||
|
||||
![]() izzo Member since: 10/15/2002 From: Melbourne, Australia |
||||
|
|
||||
| Shouldn't RotateCamera also rotate the Up vector? At the moment it only modifies the view vector.. sam |
||||
|
||||
![]() cycloid Member since: 1/13/2004 |
||||
|
|
||||
| i still dont understand all i want to do is rotate stuff in 3d but all the sites i find on google go on and on about the math when all i want is a function to slap (Vector,pitch,yaw,roll) in and get a new rotated Vector out! EDIT: got it working! here;s the working code g_v_cam_dir = my cameras position in space g_v_cam_dir = the direction it is facing g_v_cam_angles = where i keep my pitch,yaw,roll g_v_cam_angles_diff = where i store the incriments to rotate by void UpdateCamera( void ) { // get the axis to rotate around the x-axis. //this part will not work if the camera is looking //exactly straight up or straight down TVector Axis = VectorNormal(VectorCross(g_v_cam_dir, TVector(0,1,0) )); g_v_cam_angle.x += g_v_cam_angle_diff.x; g_v_cam_angle.y += g_v_cam_angle_diff.y; g_v_cam_angle.z += g_v_cam_angle_diff.z; //stop x and y getting too bug if( g_v_cam_angle.x < -0.9 ) { g_v_cam_angle_diff.x = 0.0; g_v_cam_angle.x = -0.9; } if( g_v_cam_angle.x > 0.9 ) { g_v_cam_angle_diff.x = 0.0; g_v_cam_angle.x = 0.9; } while( g_v_cam_angle.y < -M_PI ) g_v_cam_angle.y += M_PI; while( g_v_cam_angle.y > M_PI ) g_v_cam_angle.y -= M_PI; //pitch RotateCamera(g_v_cam_angle_diff.x, Axis.x, Axis.y, Axis.z); //yaw RotateCamera(g_v_cam_angle_diff.y, 0,1,0); //done with these, reset g_v_cam_angle_diff.x = g_v_cam_angle_diff.y = g_v_cam_angle_diff.z = 0; } void RotateCamera(double Angle, double x, double y, double z) { quaternion temp, quat_view, result; temp.x = x * sin(Angle/2); temp.y = y * sin(Angle/2); temp.z = z * sin(Angle/2); temp.w = cos(Angle/2); quat_view.x = g_v_cam_dir.x; quat_view.y = g_v_cam_dir.y; quat_view.z = g_v_cam_dir.z; quat_view.w = 0; result = mult(mult(temp, quat_view), conjugate(temp)); g_v_cam_dir.x = result.x; g_v_cam_dir.y = result.y; g_v_cam_dir.z = result.z; } and finally (elsewhere) gluLookAt(g_v_cam_pos.x,g_v_cam_pos.y,g_v_cam_pos.z, g_v_cam_pos.x+g_v_cam_dir.x,g_v_cam_pos.y+g_v_cam_dir.y,g_v_cam_pos.z+g_v_cam_dir.z, 0.0,1.0,0.0); [edited by - cycloid on January 13, 2004 6:48:06 AM] |
||||
|
||||
![]() rockmover12 Member since: 1/18/2005 |
||||
|
|
||||
| Can anyone post the full working code for this? I have been trying to get this to work in C#, without luck. One fundamental thing I dont understtand in this specific tutorial is the View Vector. A while back I used quaternions to rotate a camea (based on a different tutorial) but in that one the roation was done as a gloable roation of the model (ie glrotate(Angle, x,y,z)). In this case the "View" vector is a point, teh vector seems to be calcaulted by tkaeing the (View - Position) x Up. But then you only update the "View". A workign exampel would be great, whatever language it is in. |
||||
|
||||
![]() sparkx Member since: 9/4/2005 From: Novara, Italy |
||||
|
|
||||
| Maybe if you rename "View" to "Target" it's clearer. If you use 2 vectors to represent the position of the camera (in the tutorial: Position) and the position of the target the camera aims to (in this case named "view", but I prefer "target") the actual "View" direction, is the vector View_Direction = target - position (th one normal to the camera plane directed to the target). Updating only "view" in the tutorial means rotating the camera position while aiming at the same target. Hope This helps. I coded this Camera tutorial in c++, with a Vector and Quaternion class, if you want it, send me a pm. |
||||
|
||||
![]() Oxyacetylene Member since: 3/22/2002 From: Dundee, United Kingdom |
||||
|
|
||||
| I found this article to be very helpful. I ended up implementing my camera in a completely different way, rather than generating a look-at matrix from a rotated view vector, but this article gave me a very important push towards understanding quaternion cameras. Good work. |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| Hello. I've seen the article and it's good. About the 3rd person camera, have you made it? I'm really interested in knowing how game gurus do that kind of camera on Max Payne or Dead to Rights for example. I hope you could also include those concepts in your 3rd person camera tutorial if you start making it. |
||||
|
||||
![]() EricmBrown Member since: 9/8/2005 From: Arlington, TX, United States |
||||
|
|
||||
| The article is great but i have 2 questions. 1)At the end where you say: Vector Axis = CrossProduct( View - Position, Up). Can some1 show me the source for the CrossProduct function. 2) Earlier in the article you created a normalize function for quanternions, but at the end of the code you use a normalize for the Axis Vector. What is the source for normalizing a vector (i'm assuming its different than normalizing a quanternion). |
||||
|
||||
![]() CrashStar Member since: 9/13/2004 From: Croatia |
||||
|
|
||||
void camera::RotateCamera(double Angle, double x, double y, double z)
{
quaternion temp, quat_view, result;
temp.x = x * sin(Angle/2);
temp.y = y * sin(Angle/2);
temp.z = z * sin(Angle/2);
temp.w = cos(Angle/2);
quat_view.x = look.x;
quat_view.y = look.y;
quat_view.z = look.z;
quat_view.w = 0;
result = mult(mult(temp, quat_view), conjugate(temp));
look.x = result.x;
look.y = result.y;
look.z = result.z;
}
void camera::control()
{
vect MouseDirection;
//middle
int midx = screensize.x/2;
int midy = screensize.y/2;
static double xrot = 0.0;
double maxAngle = 1;
quaternion dlp;
dlp.x = look.x - pos.x;
dlp.y = look.y - pos.y;
dlp.z = look.z - pos.z;
if((pt.x == midx) && (pt.y == midy))
return;
MouseDirection.x = (midx - pt.x)/MouseSensitivity;
MouseDirection.y = (midy - pt.y)/MouseSensitivity;
SetCursorPos(midx, midy);
if(xrot > 1)
{
xrot = 1;
return;
}
if(xrot < -1)
{
xrot = -1;
return;
}
else
{
// get the axis to rotate around the x-axis.
quaternion Axis = CrossProduct(dlp, up);
// To be able to use the quaternion conjugate, the axis to
// rotate around must be normalized.
Axis = normalize(Axis);
// Rotate around the y axis
RotateCamera(MouseDirection.y, Axis.x, Axis.y, Axis.z);
// Rotate around the x axis
RotateCamera(MouseDirection.x, 0, 1, 0);
}
gluLookAt(pos.x, pos.y, pos.z, look.x, look.y, look.z, up.x, up.y, up.z);
}this is my code. screen reacts with some flickering only on the objects camera affects. can anyone tell me whats wrong? |
||||
|
||||
![]() sepul Member since: 7/20/2004 From: Tehran, Iran |
||||
|
|
||||
| thanks for the article, but I have a problem that is really buggin me in first person mode, when we rotate the camera in circular fashion (ex. pitch(+1), yaw(+1), pitch(-1), yaw(-1) ) , after each time we do this, the camera get's rotated around z-axis too, and it's really wierd. you can try with the included demo too. how can I solve this problem ? I tried to solve this by re-calculating the up/right vectors from "look" vector, but I got more problems like a wierd gimbal lock and other wierd stuff. |
||||
|
||||
![]() spiral_jetty Member since: 6/2/2006 From: Santa Barbara, CA, United States |
||||
|
|
||||
| I have the same problem as above. Why isn't there a tutorial that has actual working code available? Every single explanation I've seen is followed by dozens of comments where no one can actually implement the camera correctly. It's driving me nuts. Can someone please direct me to a working example of an opengl quartenion camera that correctly rotates *fully* in every direction? Thanks! |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| hey I just wanted to say... GREAT ARTICLE/TUTORIAL!!! :D :D :D Well I had my eye on this article/tutorial for a while, but never read through it. Anyhows, finally I did, and found it rocks!!!, everything made perfect sense. I was actually trying to track down your email just to thank you personally, hehe :). BTW, while quickly reading over this thread, I noticed some were asking how to rotate the up vector, or were having other problems. Now I think the only point that may be of confusion is at "To make a camera you typically use three vectors: Position, View, and Up". Now obviously I think "Position" is a POINT, not a VECTOR. IIRC, I see this quite alot, and I think people just call it a VECTOR as they use identical structures. Anyhows always remember, a VECTOR defines Direction and Length/Magnitude, and a POINT defines a Position. Well I think anyone learning of Quaternions should already know this, so this really shouldn't be an issue :P. Now here is how I think you can get the proper Up Vector. Firstly get a temporary Right VECTOR, by calculating the CrossProduct between the View VECTOR and Up VECTOR. You can then get the proper Up Vector by calculating the CrossProduct between the View Vector and Right Vector. I hope that made sense :). Finally, to anyone who doesn't properly understand VECTOR operations, such as the CrossProduct and the DotProduct, I recommend you spend some time looking into and understanding these. Some nice places of note for learning such things are http://www.jmckell.com/ and/or http://www.exsanity.freeola.com/vectors.html and/or http://www.geocities.com/pcgpe/graphics.html :). Anyhows I'm looking forward to a SLERP tutorial from ya, if one is in the makings? anyhows it's no problems if there isn't, as I am already so pleased about this tutorial :). cyas |
||||
|
||||
|
Page: 1 2 »» All times are ET (US) ![]() |
Last Thread Next Thread ![]() |
|