00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #pragma once
00027
00028 #include "cinder/Vector.h"
00029 #include "cinder/Matrix.h"
00030 #include "cinder/Quaternion.h"
00031 #include "cinder/Ray.h"
00032
00033 namespace cinder {
00034
00035
00036 class Camera {
00037 public:
00038 Camera() : mModelViewCached(false), mProjectionCached(false), mInverseModelViewCached( false ), mWorldUp( Vec3f::yAxis() ) {}
00039 virtual ~Camera() {}
00040
00041 Vec3f getEyePoint() const { return mEyePoint; }
00042 void setEyePoint( const Vec3f &aEyePoint );
00043
00044 float getCenterOfInterest() const { return mCenterOfInterest; }
00045 void setCenterOfInterest( float aCenterOfInterest ) { mCenterOfInterest = aCenterOfInterest; }
00046
00047 Vec3f getCenterOfInterestPoint() const { return mEyePoint + mViewDirection * mCenterOfInterest; }
00048 void setCenterOfInterestPoint( const Vec3f ¢erOfInterestPoint );
00049
00050 Vec3f getWorldUp() const { return mWorldUp; }
00051 void setWorldUp( const Vec3f &aWorldUp );
00052
00053 void lookAt( const Vec3f &target );
00054 void lookAt( const Vec3f &aEyePoint, const Vec3f &target );
00055 void lookAt( const Vec3f &aEyePoint, const Vec3f &target, const Vec3f &aUp );
00056 Vec3f getViewDirection() const { return mViewDirection; }
00057 void setViewDirection( const Vec3f &aViewDirection );
00058
00059 Quatf getOrientation() const { return mOrientation; }
00060 void setOrientation( const Quatf &aOrientation );
00061
00062 float getFov() const { return mFov; }
00063 void setFov( float aFov ) { mFov = aFov; mProjectionCached = false; }
00064 float getAspectRatio() const { return mAspectRatio; }
00065 void setAspectRatio( float aAspectRatio ) { mAspectRatio = aAspectRatio; mProjectionCached = false; }
00066 float getNearClip() const { return mNearClip; }
00067 void setNearClip( float aNearClip ) { mNearClip = aNearClip; mProjectionCached = false; }
00068 float getFarClip() const { return mFarClip; }
00069 void setFarClip( float aFarClip ) { mFarClip = aFarClip; mProjectionCached = false; }
00070
00071 virtual void getNearClipCoordinates( Vec3f *topLeft, Vec3f *topRight, Vec3f *bottomLeft, Vec3f *bottomRight ) const;
00072 virtual void getFarClipCoordinates( Vec3f *topLeft, Vec3f *topRight, Vec3f *bottomLeft, Vec3f *bottomRight ) const;
00073
00075 void getFrustum( float *left, float *top, float *right, float *bottom, float *near, float *far ) const;
00077 virtual bool isPersp() const = 0;
00078
00079 virtual const Matrix44f& getProjectionMatrix() const { if( ! mProjectionCached ) calcProjection(); return mProjectionMatrix; }
00080 virtual const Matrix44f& getModelViewMatrix() const { if( ! mModelViewCached ) calcModelView(); return mModelViewMatrix; }
00081 virtual const Matrix44f& getInverseModelViewMatrix() const { if( ! mInverseModelViewCached ) calcInverseModelView(); return mInverseModelViewMatrix; }
00082
00083 Ray generateRay( float u, float v, float imagePlaneAspectRatio ) const;
00084 void getBillboardVectors( Vec3f *right, Vec3f *up ) const;
00085
00087 Vec2f worldToScreen( const Vec3f &worldCoord, float screenWidth, float screenHeight ) const;
00089 Vec3f worldToEye( const Vec3f &worldCoord ) { return getModelViewMatrix().transformPointAffine( worldCoord ); }
00091 float worldToEyeDepth( const Vec3f &worldCoord ) const { return getModelViewMatrix().m[2] * worldCoord.x + getModelViewMatrix().m[6] * worldCoord.y + getModelViewMatrix().m[10] * worldCoord.z + getModelViewMatrix().m[14]; }
00093 Vec3f worldToNdc( const Vec3f &worldCoord ) { Vec3f eye = getModelViewMatrix().transformPointAffine( worldCoord ); return getProjectionMatrix().transformPoint( eye ); }
00094
00095
00096 float getScreenRadius( const class Sphere &sphere, float screenWidth, float screenHeight ) const;
00097
00098 protected:
00099 Vec3f mEyePoint;
00100 Vec3f mViewDirection;
00101 Quatf mOrientation;
00102 float mCenterOfInterest;
00103 Vec3f mWorldUp;
00104
00105 float mFov;
00106 float mAspectRatio;
00107 float mNearClip;
00108 float mFarClip;
00109
00110 mutable Vec3f mU;
00111 mutable Vec3f mV;
00112 mutable Vec3f mW;
00113
00114 mutable Matrix44f mProjectionMatrix, mInverseProjectionMatrix;
00115 mutable bool mProjectionCached;
00116 mutable Matrix44f mModelViewMatrix;
00117 mutable bool mModelViewCached;
00118 mutable Matrix44f mInverseModelViewMatrix;
00119 mutable bool mInverseModelViewCached;
00120
00121 mutable float mFrustumLeft, mFrustumRight, mFrustumTop, mFrustumBottom;
00122
00123 inline void calcMatrices() const;
00124
00125 virtual void calcModelView() const;
00126 virtual void calcInverseModelView() const;
00127 virtual void calcProjection() const = 0;
00128 };
00129
00130 class CameraPersp : public Camera {
00131 public:
00132 CameraPersp();
00133 CameraPersp( int pixelWidth, int pixelHeight, float fov );
00134 CameraPersp( int pixelWidth, int pixelHeight, float fov, float nearPlane, float farPlane );
00135
00136 void setPerspective( float horizFovDegrees, float aspectRatio, float nearPlane, float farPlane );
00137
00141 void getLensShift( float *horizontal, float *vertical ) const { *horizontal = mLensShift.x; *vertical = mLensShift.y; }
00145 Vec2f getLensShift() const { return Vec2f( mLensShift.x, mLensShift.y ); }
00149 void setLensShift( float horizontal, float vertical );
00153 void setLensShift( const Vec2f &shift ) { setLensShift( shift.x, shift.y ); }
00155 float getLensShiftHorizontal() const { return mLensShift.x; }
00158 void setLensShiftHorizontal( float horizontal ) { setLensShift( horizontal, mLensShift.y ); }
00160 float getLensShiftVertical() const { return mLensShift.y; }
00163 void setLensShiftVertical( float vertical ) { setLensShift( mLensShift.x, vertical ); }
00164
00165 virtual bool isPersp() const { return true; }
00166
00167 CameraPersp getFrameSphere( const class Sphere &worldSpaceSphere, int maxIterations = 20 ) const;
00168
00169 protected:
00170 Vec2f mLensShift;
00171
00172 virtual void calcProjection() const;
00173 };
00174
00175 class CameraOrtho : public Camera {
00176 public:
00177 CameraOrtho();
00178 CameraOrtho( float left, float right, float bottom, float top, float nearPlane, float farPlane );
00179
00180 void setOrtho( float left, float right, float bottom, float top, float nearPlane, float farPlane );
00181
00182 virtual bool isPersp() const { return false; }
00183
00184 protected:
00185 virtual void calcProjection() const;
00186 };
00187
00188 class CameraStereo : public CameraPersp {
00189 public:
00190 CameraStereo()
00191 : mConvergence(1.0f), mEyeSeparation(0.05f), mIsStereo(false), mIsLeft(true) {}
00192 CameraStereo( int pixelWidth, int pixelHeight, float fov )
00193 : CameraPersp( pixelWidth, pixelHeight, fov ),
00194 mConvergence(1.0f), mEyeSeparation(0.05f), mIsStereo(false), mIsLeft(true) {}
00195 CameraStereo( int pixelWidth, int pixelHeight, float fov, float nearPlane, float farPlane )
00196 : CameraPersp( pixelWidth, pixelHeight, fov, nearPlane, farPlane ),
00197 mConvergence(1.0f), mEyeSeparation(0.05f), mIsStereo(false), mIsLeft(true) {}
00198
00200 float getConvergence() const { return mConvergence; }
00202 void setConvergence( float distance, bool adjustEyeSeparation=false ) {
00203 mConvergence = distance; mProjectionCached = false;
00204
00205 if(adjustEyeSeparation)
00206 mEyeSeparation = mConvergence / 30.0f;
00207 }
00209 float getEyeSeparation() const { return mEyeSeparation; }
00211 void setEyeSeparation( float distance ) { mEyeSeparation = distance; mModelViewCached = false; mProjectionCached = false; }
00213 Vec3f getEyePointShifted() const;
00214
00216 void enableStereoLeft() { mIsStereo = true; mIsLeft = true; }
00217 bool isStereoLeftEnabled() const { return mIsStereo && mIsLeft; }
00219 void enableStereoRight() { mIsStereo = true; mIsLeft = false; }
00220 bool isStereoRightEnabled() const { return mIsStereo && !mIsLeft; }
00222 void disableStereo() { mIsStereo = false; }
00223 bool isStereoEnabled() const { return mIsStereo; }
00224
00225 virtual void getNearClipCoordinates( Vec3f *topLeft, Vec3f *topRight, Vec3f *bottomLeft, Vec3f *bottomRight ) const;
00226 virtual void getFarClipCoordinates( Vec3f *topLeft, Vec3f *topRight, Vec3f *bottomLeft, Vec3f *bottomRight ) const;
00227
00228 virtual const Matrix44f& getProjectionMatrix() const;
00229 virtual const Matrix44f& getModelViewMatrix() const;
00230 virtual const Matrix44f& getInverseModelViewMatrix() const;
00231
00232 protected:
00233 mutable Matrix44f mProjectionMatrixLeft, mInverseProjectionMatrixLeft;
00234 mutable Matrix44f mProjectionMatrixRight, mInverseProjectionMatrixRight;
00235 mutable Matrix44f mModelViewMatrixLeft, mInverseModelViewMatrixLeft;
00236 mutable Matrix44f mModelViewMatrixRight, mInverseModelViewMatrixRight;
00237
00238 virtual void calcModelView() const;
00239 virtual void calcInverseModelView() const;
00240 virtual void calcProjection() const;
00241 private:
00242 bool mIsStereo;
00243 bool mIsLeft;
00244
00245 float mConvergence;
00246 float mEyeSeparation;
00247 };
00248
00249 }