00001 #ifndef DEPTHOFFIELDCAMERA_H
00002 #define DEPTHOFFIELDCAMERA_H
00003
00004
00005 #include <cmath>
00006
00007 #include "Camera.h"
00008
00009 #include "InfinitePlane.h"
00010
00024 class DepthOfFieldCamera : public Camera
00025 {
00026 public:
00036 DepthOfFieldCamera( Vec3f pos,
00037 Vec3f dir,
00038 Vec3f up,
00039 float angle,
00040 int resX,
00041 int resY )
00042 : Camera(pos, resX, resY),
00043 mDir(dir),
00044 mUp(up),
00045 mAngle(angle * M_PI / 180.0f),
00046 mFocus(0.0f),
00047 mAspect(),
00048 mXAxis(),
00049 mYAxis(),
00050 mFocusDistance(0.3f),
00051 mAperture(0.0030f),
00052 mSlowCorrect(true),
00053 mActSample(0)
00054 {
00055 mDir.normalize();
00056 mUp.normalize();
00057
00058 mXAxis = mDir.cross(mUp).normal();
00059 mYAxis = mXAxis.cross(mDir).normal();
00060
00061 mAspect = static_cast<float>(resX) / resY;
00062 mFocus = 1.f / tanf(mAngle / 2.0f);
00063 }
00064
00067 virtual ~DepthOfFieldCamera()
00068 {}
00069
00075 virtual Ray initRay(float x, float y)
00076 {
00077 Vec3f rdir = (2.0f * ((x / mResX - .5f) * mAspect) * mXAxis)
00078 + (2.0f * (y / mResY - .5f) * mYAxis)
00079 + (mFocus * mDir);
00080
00081 rdir.normalize();
00082
00083 Vec3f P;
00084 if(! mSlowCorrect)
00085 {
00086 P = mPos + rdir * mFocusDistance;
00087 }
00088 else
00089 {
00090 InfinitePlane plane(mPos+mFocusDistance*mDir, -mDir);
00091 Ray ray;
00092 ray.init(mPos, rdir);
00093 if(plane.intersect(ray))
00094 {
00095 P = ray.hitPoint(0);
00096 }
00097 else
00098 assert(false);
00099 }
00100
00101
00102 const float radius = mAperture * frand();
00103 const float alpha = 2*M_PI*(frand() + mActSample )/ mDepthSamples;
00104 float u = radius * cosf( alpha );
00105 float v = radius * sinf( alpha );
00106
00107 mActSample = (mActSample +1) % mDepthSamples;
00108
00109
00110
00111 Vec3f pos = mPos + u*mXAxis + v*mYAxis;
00112
00113 const Vec3f dir = P - pos;
00114
00115 Ray ray;
00116 ray.init(pos, dir);
00117
00118 return ray;
00119 }
00120
00123 void setPos(Vec3f pos)
00124 {
00125 mPos = pos;
00126 }
00127
00130 void setDir(Vec3f dir)
00131 {
00132 mDir = dir;
00133
00134 mDir.normalize();
00135 mUp.normalize();
00136
00137 mXAxis = mDir.cross(mUp).normal();
00138 mYAxis = mXAxis.cross(mDir).normal();
00139
00140 mAspect = static_cast<float>(mResX) / mResY;
00141 mFocus = 1.f / tanf(mAngle / 2.0f);
00142 }
00143
00146 void setUp(Vec3f up)
00147 {
00148 mUp = up;
00149
00150 mDir.normalize();
00151 mUp.normalize();
00152
00153 mXAxis = mDir.cross(mUp).normal();
00154 mYAxis = mXAxis.cross(mDir).normal();
00155
00156 mAspect = static_cast<float>(mResX) / mResY;
00157 mFocus = 1.f / tanf(mAngle / 2.0f);
00158 }
00159
00162 virtual const Vec3f & dir() const
00163 {
00164 return mDir;
00165 }
00166
00169 const Vec3f & up() const
00170 {
00171 return mUp;
00172 }
00173
00176 float angle() const
00177 {
00178 return mAngle / M_PI * 180.0f;
00179 }
00180
00183 float aspect() const
00184 {
00185 return mAspect;
00186 }
00187
00190 virtual const float focusDistance() const
00191 {
00192 return mFocusDistance;
00193 }
00194
00197 virtual const float aperture() const
00198 {
00199 return mAperture;
00200 }
00203 int depthSamples() const
00204 {
00205 return mDepthSamples;
00206 }
00207
00210 void setDepthSamples(unsigned int i)
00211 {
00212 LOG("samples set to: " << i);
00213 mDepthSamples = i;
00214 }
00215
00218 void setFocusDistance(float f)
00219 {
00220 LOG("distance set to: " << f);
00221 assert(f>0);
00222 mFocusDistance = f;
00223 }
00224
00227 void setAperture(float a)
00228 {
00229 LOG("aperture set to: " << a);
00230 assert(a>0);
00231 mAperture = a;
00232 }
00233
00236 void setSlowCorrect()
00237 {
00238 mSlowCorrect = true;
00239 }
00240
00243 void setFastIncorrect()
00244 {
00245 mSlowCorrect = false;
00246 }
00247
00248 private:
00250 Vec3f mDir;
00251
00253 Vec3f mUp;
00254
00256 float mAngle;
00257
00259 float mFocus;
00260
00262 float mAspect;
00263
00265 Vec3f mXAxis;
00266
00268 Vec3f mYAxis;
00269
00271 float mFocusDistance;
00272
00274 float mAperture;
00275
00277 unsigned int mDepthSamples;
00278
00280 bool mSlowCorrect;
00281
00283 int mActSample;
00284 };
00285
00286 #endif