I've been trying to come up with a decent camera class for myself (I know there's a new article up on this, but I'm trying to make sure I really understand what's going on). This is what I have so far:
Camera.h
/*
====================
File: Camer.h
Author: Shane Lillie
Description: Camera module header.
====================
*/
#if !defined __CAMERA_H__
#define __CAMERA_H__
#if _MSC_VER >= 1000
#pragma once
#endif
#include "EnVector.h"
/*
class Camera
*/
class Camera
{
public:
Camera();
~Camera();
public:
// calls gluLookAt()
// does contraints on the camera
void look();
// moves the camera
// in the looking direction
void move(const EnVector3<GLdouble>& vector);
// rotates the camera
// (these are angles in degrees)
void rotate(GLfloat yaw, GLfloat pitch);
private:
EnVector3<GLdouble> m_position;
EnVector3<GLdouble> m_lookat;
EnVector3<GLdouble> m_up;
GLfloat m_yaw, m_pitch;
private:
Camera(const Camera& camera);
Camera& operator=(const Camera& rhs);
};
#endif
Camera.cpp
/*
====================
File: Camer.cc
Author: Shane Lillie
Description: Camera module source.
====================
*/
#include <cassert>
#include <cmath>
#include <iostream>
#include <GL/glut.h>
#include "Camera.h"
#define DEG_RAD(d) ((d) * 0.0174532925) // M_PI / 180.0 is about 0.0174532925
/*
* Camera methods
*
*/
Camera::Camera()
: m_position(0.0, 0.0, 10.0),
m_lookat(0.0, 0.0, -90.0),
m_up(0.0, 1.0, 0.0),
m_yaw(90.0), m_pitch(0.0f)
{
}
Camera::~Camera()
{
}
void Camera::look()
{
gluLookAt(m_position.x(), m_position.y(), m_position.z(),
m_position.x() + m_lookat.x(), m_position.y() + m_lookat.y(), m_position.z() + m_lookat.z(),
m_up.x(), m_up.y(), m_up.z());
#if 1
glBegin(GL_LINES);
glVertex3f(m_position.x(), m_position.y(), m_position.z());
glVertex3f(m_position.x() + m_lookat.x(), m_position.y() + m_lookat.y(), m_position.z() + m_lookat.z());
glEnd();
#endif
}
void Camera::move(const EnVector3<GLdouble>& vector)
{
// rotate the vector into
// the direction we're looking
// only on the xz-plane
EnVector3<GLdouble> nv(vector);
nv[0] += std::cos(DEG_RAD(m_yaw));
// move the camera in the
// direction we're looking
m_position += nv;
}
void Camera::rotate(GLfloat yaw, GLfloat pitch)
{
m_yaw += yaw;
m_pitch -= pitch;
// constrain the yaw
if(m_yaw <= -360.0 || m_yaw >= 360.0)
m_yaw = 0.0;
// constrain the pitch
if(m_pitch > 60.0)
m_pitch = 60.0;
else if(m_pitch < -60.0)
m_pitch = -60.0;
std::cout << "yaw: " << m_yaw << ", pitch: " << m_pitch << std::endl;
// set the new lookat vector
// radius = 100
m_lookat = EnVector3<GLdouble>(std::cos(DEG_RAD(m_yaw)),
std::sin(DEG_RAD(m_pitch)),
-std::sin(DEG_RAD(m_yaw)));
std::cout << m_lookat.to_string() << std::endl;
/* // set the new up vector
// (position - lookat) x vector
EnVector3<GLdouble> vector = m_position - m_lookat;
if(!m_yaw) m_up = vector.cross(EnVector3<GLdouble>(-1.0, 0.0, 0.0)); // looking down the z-axis
else if(m_yaw > 0.0f) m_up = vector.cross(EnVector3<GLdouble>(0.0, 0.0, -1.0)); // positive rotation
else m_up = vector.cross(EnVector3<GLdouble>(0.0, 0.0, 1.0)); // negative rotation
std::cout << m_up.to_string() << std::endl;*/
}
Assuming all of my vector operations are done correctly, I'm wondering why my rotations don't work quite right. For example, if I rotate towads the +x-axis and then move down the rotated z-axis, then back on the z-axis, then forward and so on, it moves me down the x-axis. I'm sure it's something being inconsistant between my rotation and movement calculations, it's just not clear to me what it is.
I appreciate any advice or suggestions. I'm not so good with the math here so it's been a very slow process getting what I have. I feel close to the correct solution, it's just enough out of my reach that I don't see what I'm doing wrong.
EDIT - Also, the line I'm trying to draw from my position to where I'm looking (so I can see where I'm looking) doesn't show up at all. I have a polygon I'm rendering in front of me that I'm using a reference, but I'd really like to see that line if I can get it.
[Edited by - Chozo on October 18, 2004 4:58:13 PM]