Odd Camera Motion

Started by
8 comments, last by MindCode 21 years, 11 months ago
I''ve been doing a camera class to create motion for my characters through keyboard/mouse. It''s with OpenGL/Glut. I get a wierd but in which when I move down on axis, the camera moves back on the forward arrow, and forward on the back arrow. I tought I just had a sign mixed up in my trig math, but the wierdest part is that when you turn 180 degrees on this abberation, you would expect to get the same error mirrored, but you don''t. It works fine were it logically shouldn''t. Here''s the code.


#ifndef Camera_h
#define Camera_h

#include "Vector.cpp"


class CCamera {

	public:

		CVector m_fVelocity;
		CVector m_fPosition;
		CVector m_fRotation;
	public:

		void OrientGl();
		void Drift(float);
		void Strafe(float);

};


#endif // Camera_h //

 


#ifndef Camera_cpp
#define Camera_cpp

#include <gl/gl.h>
#include <gl/glu.h>

#include "Camera.h"
#include "Trig.h"



void CCamera::OrientGl() {

	glRotatef( -m_fRotation.x(), 1.0f, 0.0f, 0.0f );
	glRotatef( -m_fRotation.y(), 0.0f, 1.0f, 0.0f );
	glRotatef( -m_fRotation.z(), 0.0f, 0.0f, 1.0f );

	glTranslatef( -m_fPosition.x(),-m_fPosition.y(),-m_fPosition.z() );
}


void CCamera::Drift(float speed) {

	int deg = int(m_fRotation.y());

	if(deg<0) {
		deg = -deg;
	}
	deg %= 360;

	m_fPosition.x( m_fPosition.x() - (g_fvSin[deg] * speed) );
	m_fPosition.z( m_fPosition.z() - (g_fvCos[deg] * speed) );
}


void CCamera::Strafe(float speed) {

	int deg = int(m_fRotation.y() + 90.0f);

	if(deg<0) {
		deg = -deg;
	}
	deg %= 360;

	m_fPosition.x( m_fPosition.x() - (g_fvSin[deg] * speed) );
	m_fPosition.z( m_fPosition.z() - (g_fvCos[deg] * speed) );
}


#endif // Camera_cpp //

 


#ifndef Trig_h
#define Trig_h


float g_fvSin[360];
float g_fvCos[360];


void BuildTrigTables();


#endif // Trig_h //

 


#ifndef Trig_cpp
#define Trig_cpp


#include <math.h>

#include "Trig.h"


void BuildTrigTables() {

	for( int deg = 0; deg < 360; deg++ ) {

		float rad = deg * 3.1415 / 180;

		g_fvSin[deg] = float(sin(rad));
		g_fvCos[deg] = float(cos(rad));
	}
}



#endif // Trig_cpp //

 


#ifndef Main_h
#define Main_h

#include <stdlib.h>

#include "Trig.cpp"
#include "Camera.cpp"
#include "Bsp.cpp"


// Game defs //


const float g_cfWalkSpeed  =  0.3f;
const float g_cfRunSpeed   =  0.9f;
const float g_cfMousePitch =  0.06f;
const float g_cfMouseYaw   = -0.06f;


// Globals //


CCamera g_Camera;

float g_fWidth;
float g_fHeight;


// Glut callbacks //


GLvoid Display(GLvoid);
GLvoid Reshape(GLint,GLint);
GLvoid Keyboard(GLubyte,GLint,GLint);
GLvoid PassiveMotion(GLint,GLint);
GLvoid Special(GLint,GLint,GLint);
GLvoid Idle(GLvoid);


// Extra functions //


void ExitProc();


#endif // Main_h //

 


#include <windows.h>

// OpenGL headers //

#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>

// My headers //

#include "Main.h"


int main( int argc, char **argv ) {

	atexit(ExitProc);
	BuildTrigTables();

	g_Camera.m_fVelocity = CVector( 0.0f, 0.0f, 0.0f );
	g_Camera.m_fPosition = CVector( 0.0f, 1.5f, 0.0f );
	g_Camera.m_fRotation = CVector( 0.0f, 0.0f, 0.0f );

	glutInit(&argc,argv);
	glutInitWindowPosition(50,50);
	glutInitWindowSize(512,380);
	glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
	glutCreateWindow("Navigator");

	glutDisplayFunc(Display);
	glutReshapeFunc(Reshape);
	glutKeyboardFunc(Keyboard);
	glutPassiveMotionFunc(PassiveMotion);
   	glutIdleFunc(Idle);

	glutMainLoop();

	return 0;
}


// Glut callbacks //


GLvoid Display(GLvoid) {

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    g_Camera.OrientGl();

    glBegin(GL_LINES);
        for(float i=-9.0f; i<10.0f; i+=1.0f) {

            glVertex3f(i,0,-9.0f);
            glVertex3f(i,0,+9.0f);
            glVertex3f(-9.0f,0,i);
            glVertex3f(+9.0f,0,i);
        }
    glEnd();

    glutSwapBuffers();
}


GLvoid Reshape(GLint w,GLint h) {

	if(!h)h++;

	float ratio = 1.0f*w/h;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0,0,w,h);
	gluPerspective(45,ratio,1,1000);
	glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();
	g_Camera.OrientGl();

	g_fWidth  = glutGet(GLUT_WINDOW_WIDTH);
	g_fHeight = glutGet(GLUT_WINDOW_HEIGHT);
}


GLvoid Keyboard(GLubyte key,GLint x,GLint y) {

	switch(key) {

		case 27: // Esc key

            exit(0);

            break;
        case ''w'':

            g_Camera.Drift(+g_cfWalkSpeed);

            break;
        case ''W'':

            g_Camera.Drift(+g_cfRunSpeed);

            break;
        case ''s'':

            g_Camera.Drift(-g_cfWalkSpeed);

            break;
        case ''S'':

            g_Camera.Drift(-g_cfRunSpeed);

            break;
        case ''a'':

            g_Camera.Strafe(+g_cfWalkSpeed);

            break;
        case ''A'':

            g_Camera.Strafe(+g_cfRunSpeed);

            break;
        case ''d'':

            g_Camera.Strafe(-g_cfWalkSpeed);

            break;
        case ''D'':

            g_Camera.Strafe(-g_cfRunSpeed);

            break;
	};
}


GLvoid PassiveMotion(GLint x,GLint y) {

    bool  warp = false;
    int   cx   = int(g_fWidth/2);
    int   cy   = int(g_fHeight/2);
    float dx   = x - cx;
    float dy   = y - cy;

    if(x!=cx) {
        warp = true;
        g_Camera.m_fRotation.y( g_Camera.m_fRotation.y() - dx * g_cfMousePitch );
    }
    if(y!=cy) {
        warp = true;
        g_Camera.m_fRotation.x( g_Camera.m_fRotation.x() - dy * g_cfMouseYaw );
    }
    if(warp) {
        glutSetCursor(GLUT_CURSOR_NONE);
        glutWarpPointer(cx,cy);
    }
}


GLvoid Idle(GLvoid) {

    glutPostRedisplay();
}


// Extra functions //


void ExitProc() {

	// empty so far
}


 
Enough code I hope. Probably more than some want to read. Please don''t knock my use of .h/.cpp''s. I know it''s dumb to include .cpp files but It''s quicker to change stuff while I''m so early in the debug stage. Thank you in advance to anyone who responds.
That's just my understanding; I could be wrong.
Advertisement
Too much code to look at!

1. Just wanted to say that I find it alot easier to get the current camera matrix once per frame, just after positioning (right after the translate in OrientGl), and extract the forward and right inverse vectors. I use these to move and strafe, and for billboarding.

2. Why aren''t you using the arrows keys to do movement (using specialfunc)?

3. I include .cpp files too, files that include code that rarely change, and I don''t want to see it.

zin

zintel.com - 3d graphics & more or less
zintel.com - 3d graphics & more or less
Thanks for responding!

I already got the program to work properly. In the ''Drift'' and ''Strafe'' calculations I chaged the degree corrections to:

int deg = int(m_fRotation.y());

deg %= 360;

if(deg<0) deg += 360;

Works perfectly now.

Only thing is now I''m trying to figure out quaternion''s to do rotations. Know anything about those I could use?
That's just my understanding; I could be wrong.
Quats? I have the code but never used them. For some things they are indispensible, but for the way I like to navigate, I don''t like them, you can end up in a wierd orientation, which is ok if your in space I guess, but around terrain, you can get all disoriented.

Lots of tutorial out there on quats.

zin

zintel.com - 3d graphics & more or less
zintel.com - 3d graphics & more or less
Yea lots. None that I find particularly helpful. Actually how they work still eludes me even though I''ve gotten them to (kinda) work already. Just heard using them makes the rotations alot smoother, so I thought I''d try it out.

The only other thing I really want in my camera class right now it a way for camera to move up/down depending on it''s x orientation. I''ll fiddle with my old trig to figure it out.

Thanks for the help though.

p.s. I wasn''t using the arrow keys cuz I''m doing the cotrols in Half-Life style. I find it frusterating having both your hands huddled at one end of the desk (for mouse and arrow keys).
That's just my understanding; I could be wrong.
> Just heard using them makes the rotations alot smoother, so I thought I''d try it out.

I don''t know about smoother, it just prevents gimble lock (inability to rotate in a certain axis depending on prior axis rotations) The main thing is you can rotate freely about any axis while in any orientation. w/o it, rotations work like the Quake model. But as I said, you may not want quat type of rotation on a terrain, but in space w/o an "up" implied by some nearby planet, quats may feel better.



> The only other thing I really want in my camera class right now it a way for camera to move up/down depending on it''s x orientation. I''ll fiddle with my old trig to figure it out.

As I said, if you use the camera matrix vectors vs. your trig, all that stuff is trivial (though it can be done), I can move and strafe in any orientation, quats don''t help movement, just rotation.


> p.s. I wasn''t using the arrow keys cuz I''m doing the cotrols in Half-Life style.

I play Half-Life, and use the arrows to move/strafe.


> I find it frusterating having both your hands huddled at one end of the desk (for mouse and arrow keys).

Ah, a right-hander! I''m a lefty.

zin

zintel.com - 3d graphics & more or less
zintel.com - 3d graphics & more or less
I got the camera stuff working just as I like it now. Thanks again.

With Half-Life do you use a left-handed mouse?
That's just my understanding; I could be wrong.
> With Half-Life do you use a left-handed mouse?

Yes. And all hot keys are within 3" of the arrow keys for my right hand.


I play multiplayer as "a 49 & 3/4 yr old man" and my fav map is ChaoCity3.


zin

zintel.com - 3d graphics & more or less
zintel.com - 3d graphics & more or less
Never did mult-player half-life. Was obsessed with day of defeat for awhile though. I guess that's kinda half-life. Maybe I'll re-install it and get playin again.

Shoot! Now I gotta make keyboard support for 'lefties'.

[edited by - MindCode on May 9, 2002 8:21:11 PM]
That's just my understanding; I could be wrong.
All my code has a manual camera mode, rigged w/ mouse-look and arrow-move/strafe, no one''s complained.

But yes it is good to allow the user to select any key for any function, I did setup a key binder routine once but never developed it.

User-friendliness!

zin

zintel.com - 3d graphics & more or less
zintel.com - 3d graphics & more or less

This topic is closed to new replies.

Advertisement