2001-10-04 23:12:57 +08:00
|
|
|
//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
|
|
|
|
|
2002-04-13 18:18:58 +08:00
|
|
|
#include <osg/Export>
|
2001-09-20 05:08:56 +08:00
|
|
|
#include <osg/ref_ptr>
|
|
|
|
#include <osg/Referenced>
|
|
|
|
#include <osg/Matrix>
|
|
|
|
#include <osg/Quat>
|
2001-09-22 10:42:08 +08:00
|
|
|
#include <osg/Viewport>
|
2001-12-22 06:48:19 +08:00
|
|
|
#include <osg/DisplaySettings>
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
namespace osg {
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** 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
|
2001-09-29 04:10:41 +08:00
|
|
|
* respectively.
|
2001-09-20 05:08:56 +08:00
|
|
|
*/
|
2001-01-11 00:32:10 +08:00
|
|
|
class SG_EXPORT Camera: public osg::Referenced
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2001-12-22 06:48:19 +08:00
|
|
|
Camera(DisplaySettings* ds=NULL);
|
|
|
|
|
2001-12-03 06:20:46 +08:00
|
|
|
Camera(const Camera&);
|
|
|
|
Camera& operator=(const Camera&);
|
2001-01-11 00:32:10 +08:00
|
|
|
virtual ~Camera();
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Range of projection types.
|
2001-09-29 04:10:41 +08:00
|
|
|
* ORTHO2D is a special case of ORTHO where the near and far planes
|
2001-09-20 05:08:56 +08:00
|
|
|
* are equal to -1 and 1 respectively.
|
2001-09-29 04:10:41 +08:00
|
|
|
* PERSPECTIVE is a special case of FRUSTUM where the left & right
|
|
|
|
* and bottom and top and symmetrical.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
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; }
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** Set a orthographic projection. See glOrtho for further details.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
void setOrtho(const double left, const double right,
|
|
|
|
const double bottom, const double top,
|
|
|
|
const double zNear, const double zFar);
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** Set a 2D orthographic projection. See gluOrtho2D for further details.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
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);
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** Set a symmetrical perspective projection, See gluPerspective for further details.
|
2001-09-20 05:08:56 +08:00
|
|
|
* 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
|
|
|
|
2001-09-29 04:10:41 +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
|
|
|
|
2001-09-20 05:08:56 +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
|
|
|
|
2001-09-20 05:08:56 +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
|
2001-09-20 05:08:56 +08:00
|
|
|
{
|
|
|
|
ADJUST_VERTICAL,
|
2002-01-15 19:05:00 +08:00
|
|
|
ADJUST_HORIZONTAL,
|
|
|
|
ADJUST_NONE
|
2001-09-20 05:08:56 +08:00
|
|
|
};
|
|
|
|
|
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; }
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** Adjust the clipping planes to account for a new window aspect ratio.
|
|
|
|
* Typically used after resizing a window. Aspect ratio is defined as
|
2001-09-20 05:08:56 +08:00
|
|
|
* width/height.*/
|
2001-09-22 10:42:08 +08:00
|
|
|
void adjustAspectRatio(const double newAspectRatio)
|
|
|
|
{
|
|
|
|
adjustAspectRatio(newAspectRatio,_adjustAspectRatioMode);
|
|
|
|
}
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** 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);
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2002-04-16 19:41:32 +08:00
|
|
|
const double left() const { return _left; }
|
|
|
|
const double right() const { return _right; }
|
|
|
|
const double bottom() const { return _bottom; }
|
|
|
|
const double top() const { return _top; }
|
|
|
|
const double zNear() const { return _zNear; }
|
|
|
|
const double zFar() const { return _zFar; }
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** Calculate and return the equivalent fovx for the current project setting.
|
|
|
|
* This value is only valid for when a symmetric perspective projection exists.
|
2001-09-20 05:08:56 +08:00
|
|
|
* i.e. getProjectionType()==PERSPECTIVE.*/
|
|
|
|
const double calc_fovy() const;
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** Calculate and return the equivalent fovy for the current project setting.
|
|
|
|
* This value is only valid for when a symmetric perspective projection exists.
|
2001-09-20 05:08:56 +08:00
|
|
|
* 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;
|
2001-12-21 00:35:38 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2001-12-21 21:07:35 +08:00
|
|
|
|
2001-12-21 00:35:38 +08:00
|
|
|
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
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();
|
|
|
|
|
|
|
|
/**
|
2001-09-20 05:08:56 +08:00
|
|
|
* 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);
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** set the position and orientation of the camera, using the same convention as
|
2001-09-20 05:08:56 +08:00
|
|
|
* gluLookAt.
|
|
|
|
*/
|
|
|
|
void setLookAt(const Vec3& eye,
|
|
|
|
const Vec3& center,
|
|
|
|
const Vec3& up);
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** set the position and orientation of the camera, using the same convention as
|
2001-09-20 05:08:56 +08:00
|
|
|
* 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
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** get the eye point. */
|
|
|
|
inline const Vec3& getEyePoint() const { return _eye; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** get the center point. */
|
|
|
|
inline const Vec3& getCenterPoint() const { return _center; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** get the up vector */
|
|
|
|
inline const Vec3& getUpVector() const { return _up; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
/** calculate look vector.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
const Vec3 getLookVector() const;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** calculate side vector.*/
|
|
|
|
const Vec3 getSideVector() const;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-12-21 21:07:35 +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
|
|
|
|
2001-09-20 05:08:56 +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
|
2001-09-29 04:10:41 +08:00
|
|
|
* 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
|
2001-09-20 05:08:56 +08:00
|
|
|
* 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.
|
2001-09-29 04:10:41 +08:00
|
|
|
* If the same behavior as IRIS Performer's setViewMat is desired
|
2001-09-20 05:08:56 +08:00
|
|
|
* 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
|
2002-06-06 00:11:57 +08:00
|
|
|
* internally and ensures that they are the inverse of one another.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
void attachTransform(const TransformMode mode, Matrix* modelTransform=0);
|
|
|
|
|
|
|
|
Matrix* getTransform(const TransformMode mode);
|
|
|
|
|
|
|
|
const Matrix* getTransform(const TransformMode mode) const;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-12-21 21:07:35 +08:00
|
|
|
enum FusionDistanceMode
|
|
|
|
{
|
|
|
|
PROPORTIONAL_TO_LOOK_DISTANCE,
|
|
|
|
PROPORTIONAL_TO_SCREEN_DISTANCE
|
|
|
|
};
|
|
|
|
|
2001-12-22 06:48:19 +08:00
|
|
|
/** Set the mode of the fusion distance function which in use to calculate the
|
2001-12-21 21:07:35 +08:00
|
|
|
* fusion distance used in stereo rendering. Default value is
|
2001-12-22 06:48:19 +08:00
|
|
|
* PROPORTIONAL_TO_LOOK_DISTANCE. Use in conjunction with setFusionDistanceRatio(float).*/
|
2002-04-16 19:41:32 +08:00
|
|
|
void setFusionDistanceMode(FusionDistanceMode mode) { _fusionDistanceMode = mode; }
|
2001-12-21 21:07:35 +08:00
|
|
|
|
2001-12-22 06:48:19 +08:00
|
|
|
/** 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(..).*/
|
2002-04-16 19:41:32 +08:00
|
|
|
void setFusionDistanceRatio(float ratio) { _fusionDistanceRatio = ratio; }
|
2001-12-22 06:48:19 +08:00
|
|
|
|
|
|
|
/** Get the ratio of the fusion distance function.*/
|
|
|
|
float getFusionDistanceRatio() const { return _fusionDistanceRatio; }
|
2001-12-21 21:07:35 +08:00
|
|
|
|
|
|
|
/** Calculate and return the fusion distance, using the FusionDistanceFunction.*/
|
|
|
|
const float getFusionDistance() const;
|
|
|
|
|
2001-12-22 06:48:19 +08:00
|
|
|
|
2001-12-21 21:07:35 +08:00
|
|
|
/** Set the physical distance between the viewers eyes and the display system.
|
|
|
|
* Note, only used when rendering in stereo.*/
|
2002-04-16 19:41:32 +08:00
|
|
|
void setScreenDistance(float screenDistance) { _screenDistance = screenDistance; }
|
2001-12-21 21:07:35 +08:00
|
|
|
|
|
|
|
/** Get the physical distance between the viewers eyes and the display system.*/
|
|
|
|
const float getScreenDistance() const { return _screenDistance; }
|
|
|
|
|
2001-12-21 00:35:38 +08:00
|
|
|
|
2002-04-16 19:41:32 +08:00
|
|
|
|
|
|
|
/** Get the Projection Matrix.*/
|
|
|
|
const Matrix getProjectionMatrix() 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;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
protected:
|
2001-12-03 06:20:46 +08:00
|
|
|
|
|
|
|
void copy(const Camera&);
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +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;
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
// 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
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
double _zNear;
|
|
|
|
double _zFar;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
|
|
|
|
// look at details.
|
|
|
|
LookAtType _lookAtType;
|
|
|
|
|
|
|
|
Vec3 _eye;
|
|
|
|
Vec3 _center;
|
|
|
|
Vec3 _up;
|
|
|
|
|
|
|
|
TransformMode _attachedTransformMode;
|
|
|
|
ref_ptr<Matrix> _eyeToModelTransform;
|
|
|
|
ref_ptr<Matrix> _modelToEyeTransform;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-12-21 21:07:35 +08:00
|
|
|
float _screenDistance;
|
|
|
|
|
|
|
|
FusionDistanceMode _fusionDistanceMode;
|
|
|
|
float _fusionDistanceRatio;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
# endif
|