Jump to content
  • Advertisement
Sign in to follow this  
3Dgonewild

[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.

If you intended to correct an error in the post then please contact us.

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()
{
      	 heading += 1.0f;	
				
          yrot = heading;
}
 void CAMERA::CamRight()
{
      	 heading -= 1.0f;	
				
          yrot = heading;
}
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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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
#endif

class 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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by 3Dgonewild
Thanks 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 this post


Link to post
Share on other sites
Quote:
Original post by Dim_Yimma_H
Quote:
Original post by 3Dgonewild
Thanks 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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Dim_Yimma_H
I 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 this post


Link to post
Share on other sites
Quote:
Original post by 3Dgonewild
1)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 3Dgonewild
2) 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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!