00001 #include <stdlib.h>
00002 #include <GL/glut.h>
00003 #include "camera.h"
00004 #include "scenemanager.h"
00005
00006 using namespace VRUT;
00007
00008 Camera::Camera(const wxString & _uid, const wxString & _name)
00009 : SceneNode(_uid, _name, SceneNode::CAMERA)
00010 {
00011 nearPlane = 1.0f;
00012 farPlane = 10000.0f;
00013 fov = 45.0f;
00014 lastWidth = 640;
00015 lastHeight = 480;
00016 }
00017
00018
00019 Camera::~Camera()
00020 {
00021 }
00022
00023
00024 void Camera::extractFrustum()
00025 {
00026 MATRIX mat = projMat.Transpose() * GetWorldTransMatrix()->Inverse().Transpose();
00027
00028 frustumPlanes[FRUSTUM_NEAR] = PLANE(mat._m41 + mat._m31, mat._m42 + mat._m32, mat._m43 + mat._m33, mat._m44 + mat._m34).Normalize();
00029 frustumPlanes[FRUSTUM_FAR] = PLANE(mat._m41 - mat._m31, mat._m42 - mat._m32, mat._m43 - mat._m33, mat._m44 - mat._m34).Normalize();
00030 frustumPlanes[FRUSTUM_LEFT] = PLANE(mat._m41 + mat._m11, mat._m42 + mat._m12, mat._m43 + mat._m13, mat._m44 + mat._m14).Normalize();
00031 frustumPlanes[FRUSTUM_RIGHT] = PLANE(mat._m41 - mat._m11, mat._m42 - mat._m12, mat._m43 - mat._m13, mat._m44 - mat._m14).Normalize();
00032 frustumPlanes[FRUSTUM_TOP] = PLANE(mat._m41 - mat._m21, mat._m42 - mat._m22, mat._m43 - mat._m23, mat._m44 - mat._m24).Normalize();
00033 frustumPlanes[FRUSTUM_BOTTOM] = PLANE(mat._m41 + mat._m21, mat._m42 + mat._m22, mat._m43 + mat._m23, mat._m44 + mat._m24).Normalize();
00034
00035 float tanHFov = tanf( fov * 0.5f * DEG2RAD );
00036 float aspect = float(lastWidth) / float(lastHeight);
00037 float hFarWidth = tanHFov * farPlane * aspect;
00038 float hFarHeight = tanHFov * farPlane;
00039
00041 VECTOR3 lowCorner( -hFarWidth, -hFarHeight, -farPlane );
00042 VECTOR3 highCorner( hFarWidth, hFarHeight, -farPlane );
00043 lowCorner = GetWorldTransMatrix()->TransformCoord(lowCorner);
00044 highCorner = GetWorldTransMatrix()->TransformCoord(highCorner);
00045 bSphere.Center = (((lowCorner + highCorner) * 0.5f) + GetWorldTransMatrix()->ExtractTranslation()) * 0.5f;
00046 bSphere.Radius = (highCorner - bSphere.Center).Length();
00047 }
00048
00049
00050 void Camera::updateProjection()
00051 {
00052 float top = nearPlane * tan(fov * M_PI / 360.0);
00053 float bottom = -top;
00054 float aspect = float(lastWidth)/float(lastHeight);
00055 float left = bottom * aspect;
00056 float right = top * aspect;
00057
00058 projMat = MATRIX();
00059 projMat._m11 = (2 * nearPlane) / (right - left);
00060 projMat._m31 = (right + left) / (right - left);
00061 projMat._m22 = (2 * nearPlane) / (top - bottom);
00062 projMat._m32 = (top + bottom) / (top - bottom);
00063 projMat._m33 = -(farPlane + nearPlane) / (farPlane - nearPlane);
00064 projMat._m43 = -(2 * farPlane * nearPlane) / (farPlane - nearPlane);
00065 projMat._m34 = -1;
00066 projMat._m44 = 0;
00067 }
00068
00069
00071 Camera::VFC_RESULT Camera::InFrustum(const AABB & aabb, int * lastOut, unsigned * planeMask) const
00072 {
00073 VFC_RESULT ret = INSIDE;
00074 int plane = *lastOut % 6;
00075 for (int cnt = 0; cnt < 6; plane = (plane + 1) % 6, cnt++)
00076 {
00078 if (*planeMask & (1 << plane))
00079 continue;
00080
00081 VECTOR3 nv, pv;
00082 aabb.ComputeNPvertices(&frustumPlanes[plane], &nv, &pv);
00083
00084 if (frustumPlanes[plane].DotCoord(pv) < 0.0f)
00085 {
00086 *lastOut = plane;
00087 return OUTSIDE;
00088 }
00089 if (frustumPlanes[plane].DotCoord(nv) < 0.0f)
00090 ret = INTERSECT;
00091 else
00092 *planeMask |= (1 << plane);
00093 }
00094
00095 return ret;
00096 }