src/DepthOfFieldCamera.h

Go to the documentation of this file.
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),  //some good values i tested
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         //u = 0;
00109         //       v = 0;
00110 
00111         Vec3f pos = mPos + u*mXAxis + v*mYAxis;
00112 
00113         const Vec3f dir = P - pos;
00114         //const Vec3f dir = rdir;
00115         Ray ray;
00116         ray.init(pos, dir);
00117         //mRay.init(mPos,rdir);
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

Generated on Fri Feb 1 00:01:42 2008 for Grayfall by  doxygen 1.5.1