OpenSceneGraph/include/osg/Camera

378 lines
15 KiB
Plaintext
Raw Normal View History

//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
2001-01-11 00:32:10 +08:00
#ifndef OSG_CAMERA
#define OSG_CAMERA 1
#include <osg/ref_ptr>
#include <osg/Referenced>
#include <osg/Matrix>
#include <osg/Quat>
#include <osg/ClippingVolume>
2001-09-22 10:42:08 +08:00
#include <osg/Viewport>
#include <osg/DisplaySettings>
2001-01-11 00:32:10 +08:00
namespace osg {
/** Camera class for encapsulating the view position and orientation and
* projection (lens) used. Creates a projection and modelview matrices
* which can be used to set OpenGL's PROJECTION and MODELVIEW matrices
* respectively.
*/
2001-01-11 00:32:10 +08:00
class SG_EXPORT Camera: public osg::Referenced
{
public:
Camera(DisplaySettings* ds=NULL);
Camera(const Camera&);
Camera& operator=(const Camera&);
2001-01-11 00:32:10 +08:00
virtual ~Camera();
/** Range of projection types.
* ORTHO2D is a special case of ORTHO where the near and far planes
* are equal to -1 and 1 respectively.
* PERSPECTIVE is a special case of FRUSTUM where the left & right
* and bottom and top and symmetrical.*/
enum ProjectionType
{
ORTHO,
ORTHO2D,
FRUSTUM,
PERSPECTIVE
};
/** Get the projection type set by setOtho,setOtho2D,setFrustum,
* and set perspective methods.*/
const ProjectionType getProjectionType() const { return _projectionType; }
/** Set a orthographic projection. See glOrtho for further details.*/
void setOrtho(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar);
/** Set a 2D orthographic projection. See gluOrtho2D for further details.*/
void setOrtho2D(const double left, const double right,
const double bottom, const double top);
/** Set a perspective projection. See glFrustum for further details.*/
void setFrustum(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar);
/** Set a symmetrical perspective projection, See gluPerspective for further details.
* Aspect ratio is defined as width/height.*/
void setPerspective(const double fovy,const double aspectRatio,
const double zNear, const double zFar);
2001-01-11 00:32:10 +08:00
/** Set a sysmmetical perspective projection using field of view.*/
2001-09-22 10:42:08 +08:00
void setFOV(const double fovx,const double fovy,
const double zNear, const double zFar);
2001-01-11 00:32:10 +08:00
/** Set the near and far clipping planes.*/
void setNearFar(const double zNear, const double zFar);
2001-01-11 00:32:10 +08:00
/** Use in combination with adjustAspectRatio, to control
* the change in frustum clipping planes to account for
* changes in windows aspect ratio,*/
2001-09-22 10:42:08 +08:00
enum AdjustAspectRatioMode
{
ADJUST_VERTICAL,
ADJUST_HORIZONTAL
};
2001-09-22 10:42:08 +08:00
/** Set the way that the vertical or horizontal dimensions of the window
* are adjusted on a resize. */
void setAdjustAspectRatioMode(const AdjustAspectRatioMode aam) { _adjustAspectRatioMode = aam; }
/** Get the way that the vertical or horizontal dimensions of the window
* are adjusted on a resize. */
const AdjustAspectRatioMode getAdjustAspectRatioMode() const { return _adjustAspectRatioMode; }
/** Adjust the clipping planes to account for a new window aspect ratio.
* Typically used after resizing a window. Aspect ratio is defined as
* width/height.*/
2001-09-22 10:42:08 +08:00
void adjustAspectRatio(const double newAspectRatio)
{
adjustAspectRatio(newAspectRatio,_adjustAspectRatioMode);
}
/** Adjust the clipping planes to account for a new window aspect ratio.
2001-09-22 10:42:08 +08:00
* Typicall used after resizeing a window. Aspect ratio is defined as
* width/height.*/
void adjustAspectRatio(const double newAspectRatio, const AdjustAspectRatioMode aa);
const double left() const;
const double right() const;
const double top() const;
const double bottom() const;
const double zNear() const;
const double zFar() const;
/** Calculate and return the equivalent fovx for the current project setting.
* This value is only valid for when a symmetric perspective projection exists.
* i.e. getProjectionType()==PERSPECTIVE.*/
const double calc_fovy() const;
/** Calculate and return the equivalent fovy for the current project setting.
* This value is only valid for when a symmetric perspective projection exists.
* i.e. getProjectionType()==PERSPECTIVE.*/
const double calc_fovx() const;
/** Calculate and return the projection aspect ratio.
* Aspect ratio is defined as width/height.*/
const double calc_aspectRatio() const;
const Matrix& getProjectionMatrix() const;
enum LookAtType
{
USE_HOME_POSITON,
USE_EYE_AND_QUATERNION,
USE_EYE_CENTER_AND_UP
};
const LookAtType getLookAtType() const { return _lookAtType; }
2001-01-11 00:32:10 +08:00
/**
* hardwired home view for now, looking straight down the
* Z axis at the origin, with 'up' being the y axis.
*/
void home();
/**
* Set the View, the up vector should be orthogonal to the look vector.
* setView is now mapped to setLookAt(eye,center,up), and is only
* kept for backwards compatibility.
*/
void setView(const Vec3& eyePoint,
const Vec3& lookPoint,
const Vec3& upVector);
/** set the position and orientation of the camera, using the same convention as
* gluLookAt.
*/
void setLookAt(const Vec3& eye,
const Vec3& center,
const Vec3& up);
/** set the position and orientation of the camera, using the same convention as
* gluLookAt.
*/
void setLookAt(const double eyeX, const double eyeY, const double eyeZ,
const double centerX, const double centerY, const double centerZ,
const double upX, const double upY, const double upZ);
/** post multiple the existing eye point and orientation by matrix.
* note, does not affect any ModelTransforms that are applied.*/
void transformLookAt(const Matrix& matrix);
void ensureOrthogonalUpVector();
2001-01-11 00:32:10 +08:00
/** get the eye point. */
inline const Vec3& getEyePoint() const { return _eye; }
2001-01-11 00:32:10 +08:00
/** get the center point. */
inline const Vec3& getCenterPoint() const { return _center; }
2001-01-11 00:32:10 +08:00
/** get the up vector */
inline const Vec3& getUpVector() const { return _up; }
2001-01-11 00:32:10 +08:00
/** calculate look vector.*/
const Vec3 getLookVector() const;
2001-01-11 00:32:10 +08:00
/** calculate side vector.*/
const Vec3 getSideVector() const;
2001-01-11 00:32:10 +08:00
/** calculate the look distance which is the distance between the eye and the center.*/
inline float getLookDistance() const { return (_center-_eye).length(); }
2001-01-11 00:32:10 +08:00
enum TransformMode
{
EYE_TO_MODEL,
MODEL_TO_EYE,
NO_ATTACHED_TRANSFORM
};
/** Attach a transform matrix which is applied after the camera look at.
* The attached matrix can work in two ways, either as transform of the eye
* into the model coordinates - EYE_TO_MODEL, or as a transform of the
* model to the eye - MODEL_TO_EYE. The former is equivalent to attaching
* a camera internal to the scene graph. The later is equivalent to adding
* a osg::Transform at root of the scene to move the scene to the eye point.
* Typical used in conjunction with the LookAt position set to home,
* in which case it is simply treated as a model view matrix.
* If the same behavior as IRIS Performer's setViewMat is desired
* then set the LookAt to be (0,0,0),(0,1,0),(0,0,1) since Performer's
* default direction is along the y axis, unlike OpenGL and the default OSG.
* If modelTransfor is NULL then do not use any model transform - just use the
* basic LookAt values.
* note: Camera internals maintains the both EYE_TO_MODEL and MODEL_TO_EYE
* internally and ensures that they are the inverse of one another. However,
* if you modify the attached transform then you must call dirtyTransform, to
* allow the OSG to update matrices accordingly.*/
void attachTransform(const TransformMode mode, Matrix* modelTransform=0);
/** must be called after you modify an attachedTransform. */
void dirtyTransform();
Matrix* getTransform(const TransformMode mode);
const Matrix* getTransform(const TransformMode mode) const;
2001-01-11 00:32:10 +08:00
const Vec3 getEyePoint_Model() const;
const Vec3 getCenterPoint_Model() const;
const Vec3 getLookVector_Model() const;
const Vec3 getUpVector_Model() const;
const Vec3 getSideVector_Model() const;
/** Get the ModelView matrix.
* If a ModelTransform is supplied then the ModelView matrix is
* created by multiplying the current LookAt by ModelTransform.
* Otherwise it is simply created by using the current LookAt,
* equivalent to using gluLookAt.*/
const Matrix& getModelViewMatrix() const;
/** Switch on/off the use of the near clipping plane which creating the
* getClippingVolume(), uses the camera _znear value for the position of the
* near clipping plane. By default this value is off.*/
void setUseNearClippingPlane(const bool use);
/** get whether the ClippingVolume uses a near clipping plane.*/
const bool getUseNearClippingPlane() const { return _useNearClippingPlane; }
/** Switch on/off the use of the far clipping plane which creating the
* getClippingVolume(), uses the camera _zfar value for the position
* of the far clipping plane. By default this value is off.*/
void setUseFarClippingPlane(const bool use);
/** Get whether the ClippingVolume uses a far clipping plane.*/
const bool getUseFarClippingPlane() const { return _useFarClippingPlane; }
/** get the view frustum clipping in model coordinates */
const ClippingVolume& getClippingVolume() const;
2001-01-11 00:32:10 +08:00
/** Map object coordinates into windows coordinates.
* Equivalent to gluProject(...). */
2001-09-22 10:42:08 +08:00
const bool project(const Vec3& obj,const Viewport& viewport,Vec3& win) const;
/** Map window coordinates into object coordinates.
* Equivalent to gluUnProject(...). */
2001-09-22 10:42:08 +08:00
const bool unproject(const Vec3& win,const Viewport& viewport,Vec3& obj) const;
2001-01-11 00:32:10 +08:00
enum FusionDistanceMode
{
PROPORTIONAL_TO_LOOK_DISTANCE,
PROPORTIONAL_TO_SCREEN_DISTANCE
};
/** Set the mode of the fusion distance function which in use to calculate the
* fusion distance used in stereo rendering. Default value is
* PROPORTIONAL_TO_LOOK_DISTANCE. Use in conjunction with setFusionDistanceRatio(float).*/
void setFusionDistanceMode(FusionDistanceMode mode) { _fusionDistanceMode = mode; _dirty = true; }
/** Get the mode of the fusion distance function.*/
FusionDistanceMode getFusionDistanceMode() const { return _fusionDistanceMode; }
/** Set the ratio of the fusion distance function which in use to calculate the
* fusion distance used in stereo rendering. Default value is 1.0f
* Use in conjunction with setFusionDistanceMode(..).*/
void setFusionDistanceRatio(float ratio) { _fusionDistanceRatio = ratio; _dirty = true; }
/** Get the ratio of the fusion distance function.*/
float getFusionDistanceRatio() const { return _fusionDistanceRatio; }
/** Calculate and return the fusion distance, using the FusionDistanceFunction.*/
const float getFusionDistance() const;
/** Set the physical distance between the viewers eyes and the display system.
* Note, only used when rendering in stereo.*/
void setScreenDistance(float screenDistance) { _screenDistance = screenDistance; _dirty = true; }
/** Get the physical distance between the viewers eyes and the display system.*/
const float getScreenDistance() const { return _screenDistance; }
/** Convinience method for adjusting the project and model view to account for
* and eye offset, as used in stereo work, assumes that the users will use
* a seperate camera for each eye, adjustEyePointForStereo(..) being used to
* specialize the camera for each eye view.*/
void adjustEyeOffsetForStereo(const osg::Vec3& offset);
/** Set up the OpenGL projection and model view matrices.*/
virtual void apply(State& state);
protected:
void copy(const Camera&);
2001-01-11 00:32:10 +08:00
// projection details.
ProjectionType _projectionType;
2001-01-11 00:32:10 +08:00
2001-09-22 10:42:08 +08:00
// how the window dimensions should be altered during a window resize.
AdjustAspectRatioMode _adjustAspectRatioMode;
// note, in Frustum/Perspective mode these values are scaled
// by the zNear from when they were initialised to ensure that
// subsequent changes in zNear do not affect them.
double _left;
double _right;
double _bottom;
double _top;
2001-01-11 00:32:10 +08:00
double _zNear;
double _zFar;
2001-01-11 00:32:10 +08:00
// look at details.
LookAtType _lookAtType;
Vec3 _eye;
Vec3 _center;
Vec3 _up;
TransformMode _attachedTransformMode;
ref_ptr<Matrix> _eyeToModelTransform;
ref_ptr<Matrix> _modelToEyeTransform;
// flags to determine if near and far clipping planes are required.
bool _useNearClippingPlane;
bool _useFarClippingPlane;
2001-01-11 00:32:10 +08:00
// cached matrix and clipping volume derived from above settings.
mutable bool _dirty;
mutable ref_ptr<Matrix> _projectionMatrix;
mutable ref_ptr<Matrix> _modelViewMatrix;
mutable ClippingVolume _clippingVolume;
2001-01-11 00:32:10 +08:00
mutable ref_ptr<Matrix> _mp;
mutable ref_ptr<Matrix> _inversemp;
2001-01-11 00:32:10 +08:00
void calculateMatricesAndClippingVolume() const;
2001-01-11 00:32:10 +08:00
// used for offsetting camera to ajust for left and right stereo views.
bool _useEyeOffset;
osg::Vec3 _eyeOffset;
float _screenDistance;
FusionDistanceMode _fusionDistanceMode;
float _fusionDistanceRatio;
2001-01-11 00:32:10 +08:00
};
}
# endif