Moving Camera Along It's Local Axis - Printable Version +- iDevGames Forums (http://www.idevgames.com/forums) +-- Forum: Development Zone (/forum-3.html) +--- Forum: Graphics & Audio Programming (/forum-9.html) +--- Thread: Moving Camera Along It's Local Axis (/thread-2283.html) Moving Camera Along It's Local Axis - Oddity007 - Oct 15, 2008 03:39 PM For a little background: I am trying to make a simple opengl renderer. However, I can't get the camera to move along its local axis. For a simple concept like this you would think I would have no problem in searching for a solution. Yet, all of the solutions are so cryptic-ly math-ish or C++ class laden. I need pure C and nothing translates well to my program. Here is my drawing function(other functions exist but not shown) Code: ```static inline void oeRender(void){          glPushMatrix();                  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT);                  oePoint3d_t *n=oeCamGetVectors(&oe.cam);//camera normal                 //I had used this for multiplying the camera pos by the vector but recieved strange results                  //camera transforms                  glRotatef(oe.cam.rot.x,    1,0,0);         glRotatef(oe.cam.rot.y,    0,1,0);         glRotatef(oe.cam.rot.z,    0,0,1);         glTranslatef(oe.cam.x,oe.cam.y,oe.cam.z);//temporary         //object drawing start         for (int i = 0; i < oe.count.obj; i++) {             glPushMatrix();                                  glTranslatef(oe.obj[i]->x ,    oe.obj[i]->y ,    oe.obj[i]->z );                 glRotatef(oe.obj[i]->rot.x,    1,0,0);                 glRotatef(oe.obj[i]->rot.y,    0,1,0);                 glRotatef(oe.obj[i]->rot.z,    0,0,1);                                  if(oeObjectOnScreen(oe.obj[i])) oeObjectDraw(oe.obj[i]);                              glPopMatrix();         }         //object drawing end              glPopMatrix();     glFlush();     glfwSwapBuffers();          return; }``` Here is my simple main function: Code: ```void perFrame(void); oeObject_t cube; #include "oengine.h" #define CamTurnSpeed 0.1 #define CamSpeed 0.2 void perFrame(void){     if(oeKey(GLFW_KEY_ESC)) exit(0);         if(oeKey('W')) oe.cam.z-=CamSpeed;     if(oeKey('S')) oe.cam.z+= CamSpeed;     if(oeKey('A')) oe.cam.x+= CamSpeed;     if(oeKey('D')) oe.cam.x-= CamSpeed;          if(oeKey(GLFW_KEY_UP)) oe.cam.rot.x-=CamTurnSpeed;     if(oeKey(GLFW_KEY_DOWN)) oe.cam.rot.x+=CamTurnSpeed;         if(oeKey(GLFW_KEY_RIGHT)) oe.cam.rot.y-=CamTurnSpeed;     if(oeKey(GLFW_KEY_LEFT)) oe.cam.rot.y+=CamTurnSpeed; } int main(void){     oeInit("OE test",640,480);     oeRegisterObj(&cube);          glClearColor(1,1,1,1);          oeStart(&perFrame);          return 1; }``` I can get it to turn correct, but it moves it on the global axis. Moving Camera Along It's Local Axis - reubert - Oct 15, 2008 04:44 PM There are many ways of doing this, but the simplest thing in your case would probably be to: a) in perFrame function (if w s a or d), use the direction the camera is facing and translate camera position based on that normal and it's right vector b) in your drawRect, translate then rotate. Watch out because your camera 'direction' is not a normal vector, it is just 3 rotations. You will need to calculate the direction based on those angles. To do this you probably want to construct a rotation matrix and multiply your default camera direction and right vector by this matrix. Alternatively you could investigate using quaternions to do the same thing. Or... the quickest easiest dirtiest (least accurate, most artifact prone) way is to use trig with the angles on each axis in turn. Might be OK if you have 360Â° freedom of rotation around y, but less than 180Â° freedom around x, and no z rotation. Moving Camera Along It's Local Axis - reubert - Oct 15, 2008 04:52 PM btw I don't understand quaternions (I tried once I think but then I realised I didn't care!). Just find some code that does axis/angle rotation if you don't want to know the math behind it. This might help, though it's a snippet of C++ code I am not standing by this code saying this is the fastest best or error free, but it seems to work for me! Code: ```Vector multiplyQuaternions(Vector quaternion1, Vector quaternion2) {     Vector result;     result[0] = quaternion1[3]*quaternion2[0] + quaternion1[0]*quaternion2[3] + quaternion1[1]*quaternion2[2] - quaternion1[2]*quaternion2[1];     result[1] = quaternion1[3]*quaternion2[1] - quaternion1[0]*quaternion2[2] + quaternion1[1]*quaternion2[3] + quaternion1[2]*quaternion2[0];     result[2] = quaternion1[3]*quaternion2[2] + quaternion1[0]*quaternion2[1] - quaternion1[1]*quaternion2[0] + quaternion1[2]*quaternion2[3];     result[3] = quaternion1[3]*quaternion2[3] - quaternion1[0]*quaternion2[0] - quaternion1[1]*quaternion2[1] - quaternion1[2]*quaternion2[2];        return result; } Vector quaternionConjugate(Vector quat) {     Vector result = quat;     result[0] = -quat[0];     result[1] = -quat[1];     result[2] = -quat[2];     return result; } Vector rotate(float angle, Vector axis_) {     float *vector = _vector;     float *axis = axis_._vector;     Vector quat_vector, quat_axis, result;          float halfAngle = angle * 0.5f;     float sinHalfAngle = sin(halfAngle);     quat_axis[0] = axis[0] * sinHalfAngle;     quat_axis[1] = axis[1] * sinHalfAngle;     quat_axis[2] = axis[2] * sinHalfAngle;     quat_axis[3] = cos(halfAngle);     quat_vector[0] = vector[0];     quat_vector[1] = vector[1];     quat_vector[2] = vector[2];     quat_vector[3] = 0;     result = multiplyQuaternions(multiplyQuaternions(quat_axis, quat_vector), quaternionConjugate(quat_axis));     return Vector(result[0], result[1], result[2]); }``` Moving Camera Along It's Local Axis - Oddity007 - Oct 15, 2008 04:54 PM I was thinking of option (a) along time ago, but I would want to put that in to my oeRender function. ps. drawRect? WTF? Moving Camera Along It's Local Axis - reubert - Oct 15, 2008 04:56 PM They weren't options, you need to do both. And sorry, by drawRect I meant oeRender. Moving Camera Along It's Local Axis - Oddity007 - Oct 18, 2008 11:04 AM I ended up doing this: Code: ```void oeCamMove(oePoint3d_t p){     oeRotate(&p,&oe.cam.rot);     oe.cam.x+=p.x;     oe.cam.y+=p.y;     oe.cam.z+=p.z;          }``` Code: ```void perFrame(void); oeObject_t cube; #include "oengine.h" #define CamTurnSpeed 0.1 #define CamSpeed 0.1 void perFrame(void){     if(oeKey(GLFW_KEY_ESC)) exit(0);         if(oeKey('W')) oeCamMove(0,0,CamSpeed);     if(oeKey('S')) oeCamMove(0,0,-CamSpeed);     if(oeKey('A')) oeCamMove(CamSpeed,0,0);     if(oeKey('D')) oeCamMove(-CamSpeed,0,0);          if(oeKey(GLFW_KEY_UP)) oe.cam.rot.x-=CamTurnSpeed;     if(oeKey(GLFW_KEY_DOWN)) oe.cam.rot.x+=CamTurnSpeed;         if(oeKey(GLFW_KEY_RIGHT)) oe.cam.rot.y-=CamTurnSpeed;     if(oeKey(GLFW_KEY_LEFT)) oe.cam.rot.y+=CamTurnSpeed; } int main(void){     oeInit("OE test",640,480);     oeRegisterObj(&cube);          glClearColor(1,1,1,1);          oeStart(&perFrame);          return 1; }``` Works perfect! Thank you father! LOL!!