Changed: Updated OPENARENA_VERSION to CVS this should be set to a number for release builds. ~g2k
233 lines
6.4 KiB
C++
233 lines
6.4 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Module: camera.cpp
|
|
// Author: Tom Hicks
|
|
// Creation: 09-01-2003
|
|
// LastEdit: 10-09-2003
|
|
// Editors: Tom Hicks
|
|
//
|
|
// Purpose:
|
|
// To implement an OpenGL Camera
|
|
//
|
|
// Summary of Methods:
|
|
// Camera
|
|
// -Camera();
|
|
// Initalize PDM's. Sets position to 0,0,0 up to 0,1,0 and view to 0,0,-1
|
|
// -Vec3f Position();
|
|
// Returns a copy of the position vector.
|
|
// -Vec3f View();
|
|
// Returns a copy of the view vector.
|
|
// -Vec3f UpVector();
|
|
// Returns a copy of the up vector.
|
|
// -Vec3f Strafe();
|
|
// Returns a copy of the strafe vector.
|
|
// -void PositionCamera(double xpos, double ypos, double zpos,
|
|
// double xview, double yview, double zview,
|
|
// double xup, double yup, double zup);
|
|
// Sets the position, up, and view vectors to those created from the respective input values.
|
|
// -void PositionCamera(Vec3f pos, Vec3f view, Vec3f up);
|
|
// Sets the position, up, and view vectors to those passed in.
|
|
// -void RotateView(double angle, double X, double Y, double Z);
|
|
// Rotates the view angle degrees on the axis specified by X, Y, and Z.
|
|
// -void SetViewByMouse(Screen g_Screen);
|
|
// Rotates the pitch and yaw of the view based on the mouse.
|
|
// -void RotateAroundPoint(double angle, double X, double Y, double Z, Vec3f vCenter);
|
|
// Rotates the view angle degrees around a point vCenter on the axis specified by X, Y, Z.
|
|
// -void StrafeCamera(double speed);
|
|
// Moves the camera along an axis perpendicular to the plane specified by the up and view vectors a distance specified by speed.
|
|
// -void MoveCamera(double speed);
|
|
// Moves the camera along the axis specified by it's view vector a distance equal to speed.
|
|
// -void Update();
|
|
// Update the internal strafe vector.
|
|
// -void Look();
|
|
// Positions the current viewport at point of the camera and facing the same direction.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "../include/camera.h"
|
|
|
|
namespace OpenArena
|
|
{
|
|
Camera::Camera()
|
|
{
|
|
m_vPosition = Vec3f(0,0,0);
|
|
m_vView = Vec3f(0,0,-1);
|
|
m_vUpVector = Vec3f(0,1,0);
|
|
}
|
|
|
|
void Camera::PositionCamera(double xpos, double ypos, double zpos,
|
|
double xview, double yview, double zview,
|
|
double xup, double yup, double zup)
|
|
{
|
|
m_vPosition = Vec3f(xpos, ypos, zpos);
|
|
m_vView = Vec3f(xview, yview, zview);
|
|
m_vUpVector = Vec3f(xup, yup, zup);
|
|
}
|
|
|
|
void Camera::PositionCamera(Vec3f pos, Vec3f view, Vec3f up)
|
|
{
|
|
m_vPosition = pos;
|
|
m_vView = view;
|
|
m_vUpVector = up;
|
|
}
|
|
|
|
void Camera::SetViewByMouse(Window window)
|
|
{
|
|
//Remove the ifdef and use the linux section for both linux and windows
|
|
#ifdef __linux
|
|
static double currentRotX = 0.0f;
|
|
Vec2i pos;
|
|
Vec2i middle;
|
|
double angleZ;
|
|
|
|
middle.x = window.width/2;
|
|
middle.y = window.height/2;
|
|
pos = window.GetMousePosition();
|
|
if(pos != middle)
|
|
{
|
|
window.SetMousePosition(middle);
|
|
angleZ = (middle.y - pos.y)/1000.0;
|
|
currentRotX-=angleZ;
|
|
if(currentRotX >1.0)
|
|
{
|
|
currentRotX = 1.0;
|
|
}
|
|
else if(currentRotX < -1.0)
|
|
{
|
|
currentRotX = -1.0;
|
|
}
|
|
else
|
|
{
|
|
Vec3d axis = (m_vView - m_vPosition).cross(m_vUpVector);
|
|
axis.normalize();
|
|
RotateView(angleZ, axis.x, axis.y, axis.z);
|
|
RotateView((middle.x-pos.x)/1000.0, 0, 1, 0);
|
|
//RotateView((middle.x-pos.x)/1000.0, m_vUpVector.x, m_vUpVector.y, m_vUpVector.z);
|
|
}
|
|
}
|
|
#endif
|
|
//Most of this is sorta right for linux I think but since I don't know how yet it's currently windows only
|
|
#ifdef WIN32
|
|
static double currentRotX = 0.0f;
|
|
POINT mpos;
|
|
POINT middle;
|
|
double angleZ;
|
|
middle.x = window.GetWidth() / 2;
|
|
middle.y = window.GetHeight() / 2;
|
|
GetCursorPos(&mpos);
|
|
SetCursorPos(middle.x, middle.y);
|
|
if(mpos.x != middle.x || mpos.y != middle.y)
|
|
{
|
|
angleZ = double(middle.y - mpos.y) / 1000.0f;
|
|
currentRotX -= angleZ;
|
|
|
|
if(currentRotX > 1.0f)
|
|
currentRotX = 1.0f;
|
|
else if(currentRotX < -1.0f)
|
|
currentRotX = -1.0f;
|
|
else
|
|
{
|
|
Vec3f axis = (m_vView - m_vPosition).cross(m_vUpVector);
|
|
axis.normalize();
|
|
|
|
RotateView(angleZ, axis.x, axis.y, axis.z);
|
|
|
|
//need to switch these two when I figure out stuff for flight
|
|
//till then I think the first is faster
|
|
|
|
RotateView(double(middle.x - mpos.x) / 1000.0f, 0, 1, 0);
|
|
//RotateView(double(middle.x - mpos.x) / 1000.0f, m_vUpVector.x, m_vUpVector.y, m_vUpVector.z);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void Camera::MoveCamera(double speed)
|
|
{
|
|
Vec3f heading = (m_vView - m_vPosition).normalized();
|
|
|
|
m_vPosition.x += heading.x * speed;
|
|
m_vPosition.z += heading.z * speed;
|
|
m_vView.x += heading.x * speed;
|
|
m_vView.z += heading.z * speed;
|
|
}
|
|
|
|
void Camera::RotateView(double angle, Vec3d axis)
|
|
{
|
|
//Maybe make this not call the other RotateView later
|
|
axis.normalize();
|
|
RotateView(angle, axis.x, axis.y, axis.z);
|
|
}
|
|
|
|
void Camera::RotateView(double angle, double x, double y, double z)
|
|
{
|
|
Vec3f nView;
|
|
Vec3f cView;
|
|
|
|
cView = m_vView - m_vPosition;
|
|
|
|
double cosTheta = cos(angle);
|
|
double sinTheta = sin(angle);
|
|
|
|
nView.x = (cosTheta + (1 - cosTheta) * x * x) * cView.x +
|
|
((1 - cosTheta) * x * y - z * sinTheta) * cView.y +
|
|
((1 - cosTheta) * x * z + y * sinTheta) * cView.z;
|
|
|
|
nView.y = (cosTheta + (1 - cosTheta) * y * y) * cView.y +
|
|
((1- cosTheta) * x * y + z * sinTheta) * cView.x +
|
|
((1 - cosTheta) * y * z - x * sinTheta) * cView.z;
|
|
|
|
nView.z = (cosTheta + (1 - cosTheta) * z * z) * cView.z+
|
|
((1 - cosTheta) * x * z - y * sinTheta) * cView.x +
|
|
((1 - cosTheta) * y * z + x * sinTheta) * cView.y;
|
|
|
|
m_vView.x = m_vPosition.x + nView.x;
|
|
m_vView.y = m_vPosition.y + nView.y;
|
|
m_vView.z = m_vPosition.z + nView.z;
|
|
}
|
|
|
|
void Camera::StrafeCamera(double speed)
|
|
{
|
|
m_vPosition.x += m_vStrafe.x * speed;
|
|
m_vPosition.z += m_vStrafe.z * speed;
|
|
m_vView.x += m_vStrafe.x * speed;
|
|
m_vView.z += m_vStrafe.z * speed;
|
|
}
|
|
|
|
|
|
|
|
void Camera::Update()
|
|
{
|
|
m_vStrafe =((m_vView - m_vPosition).cross(m_vUpVector)).normalized();
|
|
//SetViewByMouse(); //TODO take this whole function out asap
|
|
|
|
}
|
|
|
|
void Camera::Look()
|
|
{
|
|
gluLookAt(m_vPosition.x, m_vPosition.y, m_vPosition.z,
|
|
m_vView.x, m_vView.y, m_vView.z,
|
|
m_vUpVector.x, m_vUpVector.y, m_vUpVector.z);
|
|
}
|
|
|
|
Vec3f Camera::Position()
|
|
{
|
|
return m_vPosition;
|
|
}
|
|
|
|
Vec3f Camera::Strafe()
|
|
{
|
|
return m_vStrafe;
|
|
}
|
|
|
|
Vec3f Camera::UpVector()
|
|
{
|
|
return m_vUpVector;
|
|
}
|
|
|
|
Vec3f Camera::View()
|
|
{
|
|
return m_vView;
|
|
}
|
|
};
|