00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #pragma once
00024
00025 #include "cinder/Vector.h"
00026 #include "cinder/Matrix.h"
00027 #include "cinder/Quaternion.h"
00028 #include "cinder/Ray.h"
00029
00030 namespace cinder {
00031
00032
00033 class Camera
00034 {
00035 public:
00036 Camera() : mInverseModelViewCached( false ), mWorldUp( Vec3f::yAxis() ) {}
00037 virtual ~Camera() {}
00038
00039 Vec3f getEyePoint() const { return mEyePoint; }
00040 void setEyePoint( const Vec3f &aEyePoint );
00041
00042 float getCenterOfInterest() const { return mCenterOfInterest; }
00043 void setCenterOfInterest( float aCenterOfInterest ) { mCenterOfInterest = aCenterOfInterest; }
00044
00045 Vec3f getCenterOfInterestPoint() const { return mEyePoint + mViewDirection * mCenterOfInterest; }
00046 void setCenterOfInterestPoint( const Vec3f ¢erOfInterestPoint );
00047
00048 Vec3f getWorldUp() const { return mWorldUp; }
00049 void setWorldUp( const Vec3f &aWorldUp );
00050
00051 void lookAt( const Vec3f &target );
00052 void lookAt( const Vec3f &aEyePoint, const Vec3f &target );
00053 void lookAt( const Vec3f &aEyePoint, const Vec3f &target, const Vec3f &aUp );
00054 Vec3f getViewDirection() const { return mViewDirection; }
00055 void setViewDirection( const Vec3f &aViewDirection );
00056
00057 Quatf getOrientation() const { return mOrientation; }
00058 void setOrientation( const Quatf &aOrientation );
00059
00060 float getFov() const { return mFov; }
00061 void setFov( float aFov ) { mFov = aFov; calcProjection(); }
00062 float getAspectRatio() const { return mAspectRatio; }
00063 void setAspectRatio( float aAspectRatio ) { mAspectRatio = aAspectRatio; calcProjection(); }
00064 float getNearClip() const { return mNearClip; }
00065 void setNearClip( float aNearClip ) { mNearClip = aNearClip; calcProjection(); }
00066 float getFarClip() const { return mFarClip; }
00067 void setFarClip( float aFarClip ) { mFarClip = aFarClip; calcProjection(); }
00068 void getNearClipCoordinates( Vec3f *topLeft, Vec3f *topRight, Vec3f *bottomLeft, Vec3f *bottomRight ) const;
00069 void getFarClipCoordinates( Vec3f *topLeft, Vec3f *topRight, Vec3f *bottomLeft, Vec3f *bottomRight ) const;
00070
00072 void getFrustum( float *left, float *top, float *right, float *bottom, float *near, float *far ) const;
00074 virtual bool isPersp() const = 0;
00075
00076 const Matrix44f& getProjectionMatrix() const { return mProjectionMatrix; }
00077 const Matrix44f& getModelViewMatrix() const { return mModelViewMatrix; }
00078 const Matrix44f& getInverseModelViewMatrix() const { if( ! mInverseModelViewCached ) calcInverseModelView(); return mInverseModelViewMatrix; }
00079
00080 Ray generateRay( float u, float v, float imagePlaneAspectRatio ) const;
00081 void getBillboardVectors( Vec3f *right, Vec3f *up ) const;
00082
00084 Vec2f worldToScreen( const Vec3f &worldCoord, float screenWidth, float screenHeight ) const;
00086 Vec3f worldToEye( const Vec3f &worldCoord ) { return getModelViewMatrix().transformPointAffine( worldCoord ); }
00088 float worldToEyeDepth( const Vec3f &worldCoord ) const { return mModelViewMatrix.m[2] * worldCoord.x + mModelViewMatrix.m[6] * worldCoord.y + mModelViewMatrix.m[10] * worldCoord.z + mModelViewMatrix.m[14]; }
00090 Vec3f worldToNdc( const Vec3f &worldCoord ) { Vec3f eye = getModelViewMatrix().transformPointAffine( worldCoord ); return mProjectionMatrix.transformPoint( eye ); }
00091
00092
00093 float getScreenRadius( const class Sphere &sphere, float screenWidth, float screenHeight ) const;
00094
00095 protected:
00096 Vec3f mEyePoint;
00097 Vec3f mViewDirection;
00098 Quatf mOrientation;
00099 float mCenterOfInterest;
00100 Vec3f mWorldUp;
00101 Vec3f mU;
00102 Vec3f mV;
00103 Vec3f mW;
00104
00105 float mFov;
00106 float mAspectRatio;
00107 float mNearClip;
00108 float mFarClip;
00109
00110 Matrix44f mProjectionMatrix, mInverseProjectionMatrix;
00111 Matrix44f mModelViewMatrix;
00112 mutable Matrix44f mInverseModelViewMatrix;
00113 mutable bool mInverseModelViewCached;
00114
00115 float mFrustumLeft, mFrustumRight, mFrustumTop, mFrustumBottom;
00116
00117 void calcModelView();
00118 void calcInverseModelView() const;
00119 virtual void calcProjection() = 0;
00120 };
00121
00122 class CameraPersp : public Camera {
00123 public:
00124 CameraPersp();
00125 CameraPersp( int pixelWidth, int pixelHeight, float fov );
00126 CameraPersp( int pixelWidth, int pixelHeight, float fov, float nearPlane, float farPlane );
00127
00128 void setPerspective( float horizFovDegrees, float aspectRatio, float nearPlane, float farPlane );
00129
00130 virtual bool isPersp() const { return true; }
00131
00132 CameraPersp getFrameSphere( const class Sphere &worldSpaceSphere, int maxIterations = 20 ) const;
00133
00134 protected:
00135 virtual void calcProjection();
00136 };
00137
00138 class CameraOrtho : public Camera {
00139 public:
00140 CameraOrtho();
00141 CameraOrtho( float left, float right, float bottom, float top, float nearPlane, float farPlane );
00142
00143 void setOrtho( float left, float right, float bottom, float top, float nearPlane, float farPlane );
00144
00145 virtual bool isPersp() const { return false; }
00146
00147 protected:
00148 virtual void calcProjection();
00149 };
00150
00151 }