Advertisement
rsreusser

OpenGL camera followup

Mar 13th, 2011
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.26 KB | None | 0 0
  1. /* [1] YOU HAVE THE FOLLOWING LINE ON YOUR AXISROTATION FUNCTION:
  2.    
  3.    axis = NormalizeVector( &axis );
  4.  
  5.    AND YOUR COMMENT ABOUT MAKING SURE NOT TO CHANGE THE ORIGINAL CONFUSED ME A
  6.    LITTLE BIT. MY NORMALIZE VECTOR FUNCTION ACCEPTS A VECTOR BY VALUE AND IT
  7.    CREATES AND RETURNS A NEW ONE (SEE BELOW). WHICH MEANS I HAD TO CHANGE THE
  8.    ABOVE LINE TO THIS:
  9.  
  10.    axis = NormalizeVector(axis);
  11.  
  12.    NOW, YOU SAID TO MAKE SURE I WASN'T CHANGING THE ORIGINAL (WHICH IS RIGHTVECTOR
  13.    OR SKYVECTOR, DEPENDING ON THE FUNCTION THAT CALLED AXISROTATION). THE ORIGINAL
  14.    WILL BE PASSED BY VALUE TO AXISROTATION, THAN IT WILL BE PASSED AGAIN BY VALUE
  15.    TO NORMALIZEVECTOR. I ASSUME I'M NOT DOING ANYTHING WRONG TO MESS UP THE
  16.    ROTATIONS? */
  17.  
  18. /*I just mentioned that in passing since I wasn't sure what your convention was for passing by value/by pointer/by c++-style reference.  I usually pass vectors by value since there's not much overhead in duplicating three floats.  No problem here, just my limited knowledge of your code.*/
  19.  
  20. Vector3D NormalizeVector(Vector3D v) {
  21.     GLfloat length = (GLfloat)sqrt((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
  22.  
  23.     if(length == 0.0f) return NULLVECTOR;
  24.  
  25.     Vector3D result;
  26.  
  27.     result.x = v.x / length;
  28.     result.y = v.y / length;
  29.     result.z = v.z / length;
  30.  
  31.     return result;
  32. }
  33.  
  34. /* [2] YOUR CODE INTRODUCED A LITTLE SIDE EFFECT. WHEN I CALL PITCH/YAW USING
  35.   THE KEYBOARD, I CAN ROTATE ONE THOSE AXIS FREELY (COMPLETING 360º). WHEN
  36.   USING THE MOUSE, I CAN ROTATE FREELY WITH YAW BUT NOT WITH PITCHING, IT
  37.   SEEMS LIMITED AT [-90º, 90º]. I DON'T UNDERSTAND HOW IS THE MOUSE CAUSING
  38.   THIS, THE FUNCTION CALLS ARE THE SAME
  39.  
  40.   EDIT: ACTUALLY THE ABOVE IS NOT 100% TRUE, IT SEEMS THERE IS SOME WEIRD
  41.         BEHAVIOR WHEN THE ANGLE GOES ABOVE BELOW/ABOVE -90º/90º AND THEN I
  42.         YAW LEFT OR RIGHT. IT'S LIKE, IF I GO BELOW -90º AND THEN YAW, IT
  43.         SEEMS THE ORIENTATION CHANGES, IS THIS WHAT YOU MEAN BY THE FOLLOWING?
  44.  
  45.         "When you look straight up, you can still yaw gracefully, but the
  46.          horizon won't stay level. It's one or the other."
  47.  
  48.          I WOULD ASSUME THE ONLY WAY TO PREVENT THIS STRANGE BEHAVIOR (THE
  49.          MOUSE IS JUMPY WHEN IT REACHES SUCH HIGH ANGLES) IS TO LIMIT THE
  50.          ANGLE TO BE CONFINED BETWEEN [-90º, 90º] AND DON'T LET IT ROTATE
  51.          BELOW/ABOVE THOSE LIMITS?*/
  52.  
  53. /* Yes.  The real problem is that you need to consider what you're trying to do.  When I implemented this, I just used spherical coordinates to store an azimuth and an elevation.  Only thing is, looking straight up results in a singularity.  i.e. UpVector will be in the horizontal plane, but which direction will it point?  The only advice I can give is to consider carefully which behavior you want for your application, work out the vectors with arms, fingers, and the right hand rule, and implement it.  I limited mine to [-90+epsilonº, 90-epsilonº].*/
  54.  
  55. void Camera::Yaw(GLfloat angleX) {
  56.     Reference = AxisRotation(Reference, SkyVector, angleX );
  57.     RightVector = NormalizeVector(CrossProduct(Reference, SkyVector));
  58.     UpVector = NormalizeVector(CrossProduct(RightVector, Reference));
  59. }
  60.  
  61. void Camera::Pitch(GLfloat angleY) {
  62.     Reference = AxisRotation(Reference, RightVector, angleY);
  63.     UpVector = NormalizeVector(CrossProduct(RightVector, Reference));
  64. }
  65.  
  66. /* [3] I TRIED TO ADAPT YOUR AXISROTATION FUNCTION FOR THE ROLL(), JUST SO I
  67.    COULD KEEP THE CODE IMPLEMETANTIONS CONSISTENT, BUT I CAN'T MAKE IT WORK.
  68.  
  69.    LOOKING AT MY CURRENT ROLL FUNCTION, THIS WAS MY ATTEMPT WHICH DOESN'T
  70.    SEEM TO WORK, WHATEVER I'M LOOKING AT JUST GOES OFF VIEW
  71.    
  72.    WHAT AM I MISSING? */
  73.  
  74. /* The problem is that 'Yaw' is not a true yaw.  It looks like roll rotates the camera so the horizon is not level, then yaw restores it to level.  Strictly speaking, if you pitch up by 45 degrees, then yaw right by 90 degrees, the horizion will show up on camera at a 45 degree angle.  Try it.  If you want the horizion to stay level, then you can just rotate everything around the vertical axis like I suggested.  To be precise though, it's not really a yaw then.  It's more of a 'swivel.' */
  75.  
  76. void Camera::Roll(GLfloat angle) {
  77.     RightVector = AxisRotation(Reference, RightVector, angle);
  78.     UpVector = NormalizeVector(CrossProduct(RightVector, Reference));
  79. }
  80.  
  81. /* [4] YOU CAN SEE ABOVE THAT CROSSPRODUCT NO LONGER TAKES ADDRESSES TO THE
  82.    VECTORS. THIS WAS THE ONLY VECTOR FUNCTION I HAD WHICH ACCEPTED VECTORS
  83.    BY REFERENCE AND I CHANGED IT FOR CONSISTENCY. BELOW YOU CAN SEE HOW I
  84.    HAD THE ORIGINAL (TOP) AGAINST THE NEW ONE (BOTTOM). ALL MY VECTOR FUNCTIONS
  85.    ACCEPT VECTORS BY VALUE AND NOT BY REFERENCE, DO YOU THINK THERE'S ANYTHING
  86.    WRONG DOING IT LIKE THIS, OR IT'S GOOD ENOUGH? */
  87.  
  88. Again, I always pass vectors by value.  There's not usually a good reason to modify the operands in a mathematical expression and this ensures that you can't.
  89.  
  90. Vector3D CrossProduct(Vector3D *v, Vector3D *u) {
  91.     Vector3D result;
  92.  
  93.     result.x = v->y * u->z - v->z * u->y;
  94.     result.y = v->z * u->x - v->x * u->z;
  95.     result.z = v->x * u->y - v->y * u->x;
  96.  
  97.     return result;
  98. }
  99.  
  100. Vector3D CrossProduct(Vector3D v, Vector3D u) {
  101.     Vector3D result;
  102.  
  103.     result.x = v.y * u.z - v.z * u.y;
  104.     result.y = v.z * u.x - v.x * u.z;
  105.     result.z = v.x * u.y - v.y * u.x;
  106.  
  107.     return result;
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement