00001 #include "PerspectiveCamera.h"
00002 #include <cmath>
00003
00004 namespace rcrt
00005 {
00006
00007 PerspectiveCamera::PerspectiveCamera():init(false)
00008 {
00009 }
00010
00011 PerspectiveCamera::PerspectiveCamera(float angle, const Point3D& p, const Vec3D& d,
00012 const Vec3D& u, const int& resX, const int& resY)
00013 : vangle(angle * (float)M_PI / 180.f), pos(p), dir(d), up(u), init(true)
00014 {
00015 setResolution(resX, resY);
00016 dir.normalize();
00017 up.normalize();
00018 zAxis = dir;
00019 xAxis = dir.crossP(up);
00020 yAxis = xAxis.crossP(zAxis);
00021 xAxis.normalize();
00022 yAxis.normalize();
00023 }
00024
00025 PerspectiveCamera::~PerspectiveCamera()
00026 {
00027 }
00028
00029 void PerspectiveCamera::initialise(float angle, const Point3D& p, const Vec3D& d,
00030 const Vec3D& u, const int& resX, const int& resY)
00031 {
00032 vangle = angle * M_PI/180.f;
00033 pos = p;
00034 dir = d;
00035 up = u;
00036 setResolution(resX, resY);
00037 dir.normalize();
00038 up.normalize();
00039 zAxis = dir;
00040 xAxis = dir.crossP(up);
00041 yAxis = xAxis.crossP(zAxis);
00042 xAxis.normalize();
00043 yAxis.normalize();
00044 init = true;
00045 }
00046
00047 void PerspectiveCamera::update(const Point3D& p, const Vec3D& d,
00048 const Vec3D& u)
00049 {
00050 pos = p;
00051 dir = d;
00052 up = u;
00053 setResolution(resolutionX, resolutionY);
00054 dir.normalize();
00055 up.normalize();
00056 zAxis = dir;
00057 xAxis = dir.crossP(up);
00058 yAxis = xAxis.crossP(zAxis);
00059 xAxis.normalize();
00060 yAxis.normalize();
00061 init = true;
00062 }
00063
00064 Ray PerspectiveCamera::getRay(const Point2D& px) const
00065 {
00066 if(!init)
00067 throw std::runtime_error("[PerspectiveCamera] not initialised");
00068 Vec3D rDir = ( 2.0 * ((px.x()/resolutionX - 0.5f)*aspect) * xAxis)
00069 + ( 2.0f * (px.y()/resolutionY - 0.5f) * yAxis)
00070 + (focus * zAxis);
00071 rDir.normalize();
00072 return Ray(pos, rDir);
00073 }
00074
00075 void PerspectiveCamera::setResolution(const int& resX, const int& resY)
00076 {
00077 resolutionX = resX;
00078 resolutionY = resY;
00079 aspect = float(resolutionX)/float(resolutionY);
00080 focus = 1.f/(tan(vangle/2));
00081
00082 }
00083
00084 void PerspectiveCamera::setAngle(const float& angle)
00085 {
00086 initialise(angle, pos, dir, up, resolutionX, resolutionY);
00087 }
00088
00089 const Vec3D& PerspectiveCamera::getDirection()
00090 {
00091 return dir;
00092 }
00093
00094 const Vec3D& PerspectiveCamera::getXAxis()
00095 {
00096 return xAxis;
00097 }
00098
00099 const Vec3D& PerspectiveCamera::getUp()
00100 {
00101 return up;
00102 }
00103
00104 const Point3D& PerspectiveCamera::getPosition()
00105 {
00106 return pos;
00107 }
00108
00109 const float PerspectiveCamera::getAngle()
00110 {
00111 return vangle / ((float)M_PI / 180.f);
00112 }
00113
00114 const float& PerspectiveCamera::getFocus()
00115 {
00116 return focus;
00117 }
00118
00119 }