1
0
forked from 0ad/0ad
0ad/source/graphics/Camera.cpp

147 lines
4.6 KiB
C++
Raw Normal View History

//***********************************************************
//
// Name: Camera.Cpp
// Last Update: 24/2/02
// Author: Poya Manouchehri
//
// Description: CCamera holds a view and a projection matrix.
// It also has a frustum which can be used to
// cull objects for rendering.
//
//***********************************************************
#include "Camera.h"
CCamera::CCamera ()
{
// set viewport to something anything should handle, but should be initialised
// to window size before use
m_ViewPort.m_X = 0;
m_ViewPort.m_Y = 0;
m_ViewPort.m_Width = 800;
m_ViewPort.m_Height = 600;
}
CCamera::~CCamera ()
{
}
void CCamera::SetProjection (float nearp, float farp, float fov)
{
float h, w, Q;
m_NearPlane = nearp;
m_FarPlane = farp;
m_FOV = fov;
float Aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height;
w = 1/tanf (fov*0.5f*Aspect);
h = 1/tanf (fov*0.5f);
Q = m_FarPlane / (m_FarPlane - m_NearPlane);
m_ProjMat.SetZero ();
m_ProjMat._11 = w;
m_ProjMat._22 = h;
m_ProjMat._33 = (m_FarPlane+m_NearPlane)/(m_FarPlane-m_NearPlane);;
m_ProjMat._34 = -2*m_FarPlane*m_NearPlane/(m_FarPlane-m_NearPlane);
m_ProjMat._43 = 1.0f;
}
//Updates the frustum planes. Should be called
//everytime the view or projection matrices are
//altered.
void CCamera::UpdateFrustum ()
{
CMatrix3D MatFinal;
CMatrix3D MatView;
m_Orientation.GetInverse(MatView);
MatFinal = m_ProjMat * MatView;
//get the RIGHT plane
m_ViewFrustum.SetNumPlanes (6);
m_ViewFrustum.m_aPlanes[0].m_Norm.X = MatFinal._41-MatFinal._11;
m_ViewFrustum.m_aPlanes[0].m_Norm.Y = MatFinal._42-MatFinal._12;
m_ViewFrustum.m_aPlanes[0].m_Norm.Z = MatFinal._43-MatFinal._13;
m_ViewFrustum.m_aPlanes[0].m_Dist = MatFinal._44-MatFinal._14;
//get the LEFT plane
m_ViewFrustum.m_aPlanes[1].m_Norm.X = MatFinal._41+MatFinal._11;
m_ViewFrustum.m_aPlanes[1].m_Norm.Y = MatFinal._42+MatFinal._12;
m_ViewFrustum.m_aPlanes[1].m_Norm.Z = MatFinal._43+MatFinal._13;
m_ViewFrustum.m_aPlanes[1].m_Dist = MatFinal._44+MatFinal._14;
//get the BOTTOM plane
m_ViewFrustum.m_aPlanes[2].m_Norm.X = MatFinal._41+MatFinal._21;
m_ViewFrustum.m_aPlanes[2].m_Norm.Y = MatFinal._42+MatFinal._22;
m_ViewFrustum.m_aPlanes[2].m_Norm.Z = MatFinal._43+MatFinal._23;
m_ViewFrustum.m_aPlanes[2].m_Dist = MatFinal._44+MatFinal._24;
//get the TOP plane
m_ViewFrustum.m_aPlanes[3].m_Norm.X = MatFinal._41-MatFinal._21;
m_ViewFrustum.m_aPlanes[3].m_Norm.Y = MatFinal._42-MatFinal._22;
m_ViewFrustum.m_aPlanes[3].m_Norm.Z = MatFinal._43-MatFinal._23;
m_ViewFrustum.m_aPlanes[3].m_Dist = MatFinal._44-MatFinal._24;
//get the FAR plane
m_ViewFrustum.m_aPlanes[4].m_Norm.X = MatFinal._41-MatFinal._31;
m_ViewFrustum.m_aPlanes[4].m_Norm.Y = MatFinal._42-MatFinal._32;
m_ViewFrustum.m_aPlanes[4].m_Norm.Z = MatFinal._43-MatFinal._33;
m_ViewFrustum.m_aPlanes[4].m_Dist = MatFinal._44-MatFinal._34;
//get the NEAR plane
m_ViewFrustum.m_aPlanes[5].m_Norm.X = MatFinal._41+MatFinal._31;
m_ViewFrustum.m_aPlanes[5].m_Norm.Y = MatFinal._42+MatFinal._32;
m_ViewFrustum.m_aPlanes[5].m_Norm.Z = MatFinal._43+MatFinal._33;
m_ViewFrustum.m_aPlanes[5].m_Dist = MatFinal._44+MatFinal._34;
}
void CCamera::SetViewPort (SViewPort *viewport)
{
m_ViewPort.m_X = viewport->m_X;
m_ViewPort.m_Y = viewport->m_Y;
m_ViewPort.m_Width = viewport->m_Width;
m_ViewPort.m_Height = viewport->m_Height;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GetCameraPlanePoints: return four points in camera space at given distance from camera
void CCamera::GetCameraPlanePoints(float dist,CVector3D pts[4]) const
{
float aspect=float(m_ViewPort.m_Width)/float(m_ViewPort.m_Height);
float x=dist*float(tan(GetFOV()*aspect*0.5));
float y=dist*float(tan(GetFOV()*0.5));
pts[0].X=-x;
pts[0].Y=-y;
pts[0].Z=dist;
pts[1].X=x;
pts[1].Y=-y;
pts[1].Z=dist;
pts[2].X=x;
pts[2].Y=y;
pts[2].Z=dist;
pts[3].X=-x;
pts[3].Y=y;
pts[3].Z=dist;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GetFrustumPoints: calculate and return the position of the 8 points of the frustum in world space
void CCamera::GetFrustumPoints(CVector3D pts[8]) const
{
// get camera space points for near and far planes
CVector3D cpts[8];
GetCameraPlanePoints(m_NearPlane,pts);
GetCameraPlanePoints(m_FarPlane,pts+4);
// transform to world space
for (int i=0;i<8;i++) {
m_Orientation.Transform(cpts[i],pts[i]);
}
}