Public Group

# [OPENGL]Whats wrong with my camera class?

This topic is 4178 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi again! You guessed right , i need your help again! Im trying to create a FPS CAMERA CLASS ***WITHOUT USING COMPLEX MATH*** , and so far i only got the camera to turn AROUND a 3d object. Thats not what i want! , i want to rotate the camera like for example in quake 3 (!!!!) !!. Can someone tell me what do i have to edit? Here's the source: update (cAMERA CLASS):
void CAMERA::CAM_DO_UPDATE()
{
//thanks to nexe xD
GLfloat xtrans = -xpos;
GLfloat ztrans = -zpos;
GLfloat ytrans = -walkbias-0.25f;
GLfloat sceneroty = 360.0f - yrot;
glRotatef(lookupdown,1.0f,0,0);
glRotatef(sceneroty,0,1.0f,0);
glTranslatef(xtrans, ytrans, ztrans);
}


turn left/right(cAMERA CLASS):
 void CAMERA::CamLeft()
{

}
void CAMERA::CamRight()
{

}

Mouse control:
if( EVENT.type == SDL_MOUSEMOTION )
{

if (EVENT.button.x < Screen_WIDTH/2)
{
THE_CAMERA.CamLeft();
}
if (EVENT.button.x > Screen_WIDTH/2)
{
THE_CAMERA.CamRight();
}
}


##### Share on other sites
Think of it like this, when you haven't specified any transformations to the 3D world, the camera is in the origin looking along the negative z-axis. If you want to move the camera to the position (10, 0, 0) you translate the world with (-10, 0, 0). Edit: for a world transformed in steps, the vertices in the world are first translated, then rotated (about the camera position). In OpenGL though, translation and rotation are instead combined into a single transformation (4x4 matrix) by calling the gl functions, and the order of combinations aren't the same as the order you would do the transformations if they are separated. Calling glRotate will combine the rotation with the current transformation (the matrix), and the last call, will appear to be applied first to the vertices.

And you're calling the rotation function first, so that should be doing the right thing with the order of the transformations.

[Edited by - Dim_Yimma_H on June 11, 2007 9:21:26 AM]

##### Share on other sites
Thanks for the reply , its a little better now , but still im having problems :/!

Here's a test compiled executable:
http://www.gigasize.com/get.php/-1100140700/testME.zip.zip
Controls:
Up & down : move forward / backward
move mouse left/right : rotate(..) the camera left/right.

And the source (camera class):

CCAMERA.CPP
//SOME CODE IS TAKEN FROM NEXE'S TUTORIALS!!#include "cCAMERA.h"#include <math.h>CAMERA::CAMERA(){     walkbias = 0;    walkbiasangle = 0;    lookupdown = 0.0f; 	z=0.0f;	     xpos=0.0f;    zpos=0.0f;}void CAMERA::CAM_DO_UPDATE(){	GLfloat xtrans = -xpos;	GLfloat ztrans = -zpos;	GLfloat ytrans = -walkbias-0.25f;	GLfloat sceneroty = 360.0f - yrot;		glTranslatef(xtrans, ytrans, ztrans);    glRotatef(lookupdown,1.0f,0,0); 	glRotatef(sceneroty,0,1.0f,0);}void CAMERA::CamBW(){	    xpos += ( float )sin( yrot * PI180 ) * 0.05f;	    zpos += ( float )cos( yrot * PI180 ) * 0.05f;	    if ( walkbiasangle <= 1.0f )                walkbiasangle = 359.0f;	    else                walkbiasangle -= 10;	    walkbias = ( float )sin( walkbiasangle * PI180 ) / 20.0f;	    CAM_DO_UPDATE();}void CAMERA::CamFW(){        xpos -= ( float )sin( yrot * PI180 ) * 0.05f;	    zpos -= ( float )cos( yrot * PI180 ) * 0.05f;	    if ( walkbiasangle >= 359.0f )		walkbiasangle = 0.0f;	    else		walkbiasangle+= 10;	    walkbias = ( float )sin( walkbiasangle * PI180 ) / 20.0f;	     CAM_DO_UPDATE();  } void CAMERA::CamLeft(){      yrot+=0.5f;      //	 heading += 1.0f;			//		yrot = heading;		 CAM_DO_UPDATE();} void CAMERA::CamRight(){      yrot-=0.5f;      //	 heading -= 1.0f;				//	yrot = heading;			 CAM_DO_UPDATE();}

and the CCAMERA.H sourcE:
#ifndef cCAMERA__H#define cCAMERA__H#include "SDL/SDL.h"#include "SDL/SDL_opengl.h"#ifndef PI180#define PI180 0.0174532925f#endifclass CAMERA{private:        float heading;float xpos;float zpos;GLfloat	yrot;				GLfloat walkbias  ;GLfloat walkbiasangle  ;GLfloat lookupdown  ;GLfloat	z;	            public:          void CAM_DO_UPDATE();          CAMERA();          void CamLeft();          void CamRight();          void CamFW();          void CamBW();          void CamLookUP();          void CamLookDN();          };#endif

##### Share on other sites
If you want it to be simple, forget about all those transformation orders and just use gluLookAt once each frame.

http://msdn2.microsoft.com/en-us/library/ms537475.aspx

##### Share on other sites
Thats even harder to code .....and im not pro ! :/!!!!!

##### Share on other sites
Quote:
 Original post by 3DgonewildThanks for the reply , its a little better now , but still im having problems :/!

What kind of problems are you still having? I don't have SDL installed and can't test the binary. If it's about the rotation plane, does the problematic behavior disappear if you call horizontal rotation first? Like the following.

void CAMERA::CAM_DO_UPDATE(){	GLfloat xtrans = -xpos;	GLfloat ztrans = -zpos;	GLfloat ytrans = -walkbias-0.25f;	GLfloat sceneroty = 360.0f - yrot;	glRotatef(sceneroty,0,1.0f,0);	glRotatef(lookupdown,1.0f,0,0);	glTranslatef(xtrans, ytrans, ztrans);}

##### Share on other sites
Quote:
Original post by Dim_Yimma_H
Quote:
 Original post by 3DgonewildThanks for the reply , its a little better now , but still im having problems :/!

What kind of problems are you still having? I don't have SDL installed and can't test the binary. If it's about the rotation plane, does the problematic behavior disappear if you rotate horizontally first? Like the following.

*** Source Snippet Removed ***

Well here is the binary :
http://www.gigasize.com/get.php/-1100140561/sdlBIN.zip.zip
When you get some time take a look :) !

Actually , the problem is that i cant move in the "world" , plus the controls are crapy :/...you have to see it running .........

##### Share on other sites
I realized that my first explanation wasn't good, I apologize.

I took a look at the executable, and it seems like it's possible to move the camera in the world actually. But the order of rotation and movement seems reversed. It was only possible to move by repeatedly tapping the forward- and backward arrow keys, though, I guess you're aware of that already [smile]

##### Share on other sites
Quote:
 Original post by Dim_Yimma_HI realized that my first explanation wasn't good, I apologize.

Apologize for what?
For trying to help a nooblet ? :) !!lol!!

Anyway , after hours of work , THE ROTATION WORKS NOW!!!!!!!!!!!!!!!!!!!!!!!!.
Here's the new update function:

void CAMERA::CAM_DO_UPDATE(){    GLfloat xtrans = -xpos;    GLfloat ztrans = -zpos;    GLfloat ytrans = -walkbias - 0.25f;    GLfloat sceneroty = 360.0f - yrot;    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );    glLoadIdentity( );    glRotatef( lookupdown, 1.0f, 0.0f , 0.0f );    glRotatef( sceneroty, 0.0f, 1.0f , 0.0f );    glTranslatef( xtrans, ytrans, ztrans );}

But i have few questions:

1)PI180(#define PI180 0.0174532925f) , returns this number:
stdout.txt:
printf("%f \n",PI180);result:0.017453

....why?

2) How can i improve the mouse movement?
Here's the function:
if( EVENT.type == SDL_MOUSEMOTION ){  if (EVENT.button.x < Screen_WIDTH/2) {        THE_CAMERA.CamLeft();            }  if (EVENT.button.x > Screen_WIDTH/2) {        THE_CAMERA.CamRight();              }}

##### Share on other sites
Quote:
 Original post by 3Dgonewild1)PI180(#define PI180 0.0174532925f) , returns this number:stdout.txt:*** Source Snippet Removed ***....why?

The f on the end of the number declares it of the type float, and the standard that the C/C++ language follows defines that float only has 6 significant decimals. Because of that, printf also normally outputs float-types with 6 decimals. Luckily, printf takes precision flags that can be used to force the amount of decimals, you write it in the format string, before the f-specifier, like this:

printf("%.3f \n",PI180);

The above results in 3 decimals being output. It's possible to output more than 6 decimals, but they might not be accurate. You can read more about printf flags on printf at www.cplusplus.com.

I'm still trying to understand the mysterious relation between PI and 0.0174532925 [smile]

Quote:
 Original post by 3Dgonewild2) How can i improve the mouse movement?Here's the function:*** Source Snippet Removed ***

Improving the mouse movement is a bit of a design issue (there are different more or less intuitive ways of controlling what you see), but in Quake it's basically like this:

If the horizontal mouse coordinate decreases, the camera turns left.
If the horizontal mouse coordinate increases, the camera turns right.
The same goes for the vertical movement, but limit it at +-90 degrees.

To find out how much the mouse coordinates have changed between two updates, you either can:
A. Store coordinate from each update, and subtract it from the coordinate next update.
B. Get the relative mouse movement (relative to the last update, it's actually the same value as in A).

Since you're using SDL, I think option B is easier because I've seen in the SDL documentation that the mouse event struct has relative motion data, named xrel and yrel. Take a look on the following page in the documentation:
SDL_MouseMotionEvent.
Notice that the xrel and yrel members aren't in the button struct, but in the motion struct.

Here follows an example, remember that I don't use SDL though so the code isn't tested, but it should give you the idea of how to do it.

if( EVENT.type == SDL_MOUSEMOTION ){	if (EVENT.motion.xrel < 0)	{		THE_CAMERA.CamLeft();           	}	else if (EVENT.motion.xrel > 0)	{		THE_CAMERA.CamRight();             	}}

If you want a smoother rotation, you should also check the magnitude of xrel and compute a velocity based on it. The rotation velocity is then used to rotate/turn the camera, so you would need a velocity parameter in CamLeft/CamRight.

1. 1
Rutin
40
2. 2
3. 3
4. 4
5. 5

• 18
• 20
• 12
• 14
• 9
• ### Forum Statistics

• Total Topics
633363
• Total Posts
3011514
• ### Who's Online (See full list)

There are no registered users currently online

×