/* * CCamera.h * $Id: CCamera.h,v 1.4 2002/11/13 14:09:28 gwetekam Exp $ * * Copyright (C) 1999, 2000 Markus Janich * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * As a special exception to the GPL, the QGLViewer authors (Markus * Janich, Michael Meissner, Richard Guenther, Alexander Buck and Thomas * Woerner) give permission to link this program with Qt (non-)commercial * edition, and distribute the resulting executable, without including * the source code for the Qt (non-)commercial edition in the source * distribution. * */ // Description : Class CCamera // Purpose : Provides funcionality (rotate, move, etc.) #ifndef __CCAMERA_H_ #define __CCAMERA_H_ // Qt /////// // System /////////// #include #include // Own /////////// #include "GeoGeneric.h" #include "CP4D.h" #include "CV4D.h" #include "CP3D.h" #include "CV3D.h" #include "CMat4D.h" #include "CBoundingBox3D.h" /// Camera class /** * This class implements a camera including functionality to * modify the camera (rotate, move, etc.). * * @author Markus Janich */ class CCamera { public: /** An enum type for the different types of projection. */ enum CameraType { orthographic, /**< stands for a camera for parallel projection. */ perspective /**< stands for a camera for perspective projection. */ }; /** Default Constructor * Eye is at (0,0,-1), center is at (0,0,0), and up is (0,1,0) * and it has a boundingbox with the edge (-1,-1,-1) and (1,1,1). */ CCamera() : m_CameraType( perspective ), m_cBBox(CBoundingBox3D(-1, -1, -1, 1, 1, 1)), m_rdVerAngle(30.0), m_rdRatio(4.0/3.0), m_rdNearPlane(0.0001), m_rdFarPlane(10000.0), m_nVPHeight(480), m_fValidViewDir(false), m_fValidViewRight(false), m_cEyePos(CP3D(0,0,-1)), m_cRefPoint(CP3D(0,0,0)), m_cViewUp(CV3D(0,1,0)), m_nTimeStep(0) { setEyePos(m_cEyePos); // updates near/far plane }; /** Constructor defining the view parameters. * @param cEyePos defines the eye position * @param cRefPoint defines the reference point (focuspoint) * @param cViewUp defines the view up vector * @param rdNearPlane distance between the eyepoint and the near clipping plane * @param cBBox the boundingbox of the whole scene * @param rdFarPlane distance between the eyepoint and the far clipping plane * @param rdVerAngle vertical open angle of the field of view * @param nVPHeight resolution (in pixels) of the viewplane in y-direction * @param rdRatio ratio between height and width, or hor. and vert. angle */ CCamera( double rdEyePosX, double rdEyePosY, double rdEyePosZ, double rdRefPointX, double rdRefPointY, double rdRefPointZ, double rdViewUpX, double rdViewUpY, double rdViewUpZ, const CBoundingBox3D &cBBox=CBoundingBox3D(-1, -1, -1, 1, 1, 1), double rdVerAngle=30.0, int nVPHeight=480, double rdRatio=4.0/3.0, double rdNearPlane=0.0001, double rdFarPlane=10000.0, int nTimeStep = 0) : m_CameraType( perspective ), m_cBBox(cBBox), m_rdVerAngle(rdVerAngle), m_rdRatio(rdRatio), m_rdNearPlane(rdNearPlane), m_rdFarPlane(rdFarPlane), m_nVPHeight(nVPHeight), m_fValidViewDir(false), m_fValidViewRight(false), m_cEyePos(CP3D(rdEyePosX, rdEyePosY, rdEyePosZ)), m_cRefPoint(CP3D(rdRefPointX, rdRefPointY, rdRefPointZ)), m_cViewUp(CV3D(rdViewUpX, rdViewUpY, rdViewUpZ)), m_nTimeStep(nTimeStep) { setEyePos(m_cEyePos); // updates near/far plane }; /** The same as above but different types of parameters. */ CCamera( CP3D cEyePos, CP3D cRefPoint, CV3D cViewUp, const CBoundingBox3D &cBBox=CBoundingBox3D(-1, -1, -1, 1, 1, 1), double rdVerAngle=30.0, int nVPHeight=480, double rdRatio=4.0/3.0, double rdNearPlane=0.0001, double rdFarPlane=10000.0, CameraType ctype=perspective, int nTimeStep = 0) : m_CameraType( ctype ), m_cBBox(cBBox), m_rdVerAngle(rdVerAngle), m_rdRatio(rdRatio), m_rdNearPlane(rdNearPlane), m_rdFarPlane(rdFarPlane), m_nVPHeight(nVPHeight), m_fValidViewDir(false), m_fValidViewRight(false), m_cEyePos(cEyePos), m_cRefPoint(cRefPoint), m_cViewUp(cViewUp), m_nTimeStep(nTimeStep) { setEyePos(cEyePos); // updates near/far plane }; // Use default copy constructor /////////////////////////////// /** Default Destructor. */ virtual ~CCamera() {}; /** Rotates the camera by an angle of 'rdAngle' degrees around * an axis which goes through the reference point if 'global' is set to 'true'. * If 'global' is 'false' the axis goes through the point of the eye position * (for pitch, roll and yaw the camera). * The direction of the axis is specified with 'cAxis'. * This method changes the position of the camera if 'global' is 'true'. */ void rotate(double rdAngle, CV3D cAxis, bool global=true); /** Move the camera relative to the current position by any distance * in a 3-dimensional direction given by 'vDiff'. * \par NOTE: The view direction doesn't change! */ void translate(CV3D vDiff); /** Sets a new reference-point. */ void setRefPoint(const CP3D &cRefPoint) { m_fValidViewRight = m_fValidViewDir = false; m_cRefPoint = cRefPoint; }; /** Get the current reference-point. */ const CP3D& getRefPoint() const { return m_cRefPoint; }; /** Set a new eye-point. */ void setEyePos(const CP3D &cEyePos); /** Get the current eye-point. */ const CP3D& getEyePos() const { return m_cEyePos; }; /** Set a new viewup-vector. */ void setViewUp(const CV3D &cViewUp) { m_cViewUp = cViewUp; }; /** Get the current viewup-vector. */ const CV3D& getViewUp() const { return m_cViewUp; }; /** Get the current normalized viewdirection-vector. */ // Same problem as before. const CV3D& getViewDir() const; /** Get the current normalized viewright-vector. */ // Same problem as before. const CV3D& getViewRight() const; /** \deprecated This method is is just for downwards compatibility. * \deprecated Don't use this method in new programs use 'setFovy()' * and 'setRatio()' instead. * * Set horizontal and vertical angle of view of the camera. * The range for the angles goes from 0 to 180 degrees. * Remember to adjust the resolution of the viewplane of the * camera to the right ratio. If you don't do that you will * get a distorted view volume by calling 'getVVolume()'. * * \par NOTE: * What this function real does is setting the vertical * opening angle and the ratio which it calculates * out of the given angles. */ void setHVAngle(double rdHorAngle, double rdVerAngle) { m_rdVerAngle = rdVerAngle>180.0 ? 180.0 : rdVerAngle; rdHorAngle = rdHorAngle/180.0*M_PI; rdVerAngle = rdVerAngle/180.0*M_PI; //m_rdRatio = rdHorAngle/rdVerAngle; m_rdRatio = tan(rdHorAngle)/tan(rdVerAngle); } /** Get horizontal and vertical angle of view of the camera. * \par NOTE: * This is a similar workaround in reversed direction as used in * in the method 'setHVAngle()'. */ void getHVAngle(double &rdHorAngle, double &rdVerAngle) const { rdVerAngle = m_rdVerAngle; //rdHorAngle = m_rdVerAngle * m_rdRatio; rdHorAngle = atan(tan(m_rdVerAngle) * m_rdRatio); //cout << rdHorAngle << "," << rdVerAngle << endl; } /** Set distance between eye point and near/far clipplane. */ void setClipPlanes(double rdNearPlane, double rdFarPlane) { m_rdNearPlane = rdNearPlane; m_rdFarPlane = rdFarPlane; } /** Returns the distance between eye point and near/far clipplane. */ void getClipPlanes(double &rdNearPlane, double &rdFarPlane) const { rdNearPlane = m_rdNearPlane; rdFarPlane = m_rdFarPlane; } /** Sets the dimension of the scene as a boundingbox * in world coordinates. */ void setBoundingBox(const CBoundingBox3D &cBBox, bool fViewAll=true) { m_cBBox = cBBox; if (fViewAll) viewAll(); } /** Returns the boundingbox. */ const CBoundingBox3D &getBoundingBox() const { return m_cBBox; } /** Sets the type of the camera (perspective or orthographic). */ void setCameraType( CameraType type ) { m_CameraType = type; }; /** Returns the type of the camera (perspective or orthographic). */ CameraType getCameraType() const { return m_CameraType; }; /** Returns the viewing volume. The values are in right order:
* x-coordinate of the upper left corner,
* x-coordinate of the lower right corner,
* y-coordinate of the upper left corner,
* y-coordinate of the lower right corner, and
* the distance between eye point and near/far clipplane.
* Hey, what a surprise! These are the values especially needed * for the OpenGL functions 'glFrustum' or 'glOrtho' to set * the projection matrix. */ void getVVolume( double array[6] ) const; /** \deprecated This method is is just for downwards compatibility. * \deprecated Don't use this method in new programs use 'setVPHeight()' * and 'setRatio()' instead. * * Set resolution of the viewplane in x- and y-direction. * Remember to adjust the opening angles of the camera * to the right ratio if don't want to get distorted * view volume by calling 'getVVolume()'. * * \par NOTE: * What this function real does is setting the vertical * resolution of the viewplane and the ratio which it * calculates out of the given x,y-resolution. */ void setVPRes( int nVPWidth, int nVPHeight) { m_nVPHeight = nVPHeight; m_rdRatio = double(nVPWidth)/nVPHeight; } /** Returns the resolution of the viewplane in x- and y-direction. */ void getVPRes( int &nVPWidth, int &nVPHeight) const { nVPHeight = m_nVPHeight; nVPWidth = int(m_nVPHeight * m_rdRatio); } /** Returns all parameters of a viewplane which is orthogonal to the viewdirection * and with a dimension of nXSize x nYSize. * @param origin returns the upper left point. * @param xStep returns the vector in x-direction from one pixel to another. * @param yStep returns the vector in y-direction from one pixel to another. * @param rdXSize the resolution of the viewplane in x-direction. * @param rdYSize the resolution of the viewplane in y-direction. */ void getVPParams( CP3D &origin, CV3D &xStep, CV3D &yStep, int nXSize, int nYSize) const; /** This method gets you the modelview matrix of the current * setup just like gluLookAt(). */ CMat4D getModelview() const; /** This method returns the glOrtho() like matrix. */ CMat4D getOrtho() const; /** This method returns the glFrustrum() like matrix. */ CMat4D getFrustrum() const; /** This method gets you the projection matrix of the current * setup just like glFrustrum()/glOrtho(). */ CMat4D getProjection() const; /** This method gets you the viewport transformation matrix of * the current setup just like glViewport(). */ CMat4D getVPTrans(int nXSize, int nYSize) const; /** This method sets the ratio between width and height (horizontal and * vertical opening angle). */ void setRatio(double rdRatio) { m_rdRatio = rdRatio; } /** This method returns the ratio. */ double getRatio() const { return m_rdRatio; } /** This method sets the fovy (i.e. vertical opening) angle of the camera. */ void setFovy(double rdFovy) { m_rdVerAngle = rdFovy; } /** This method returns the fovy angle. */ double getFovy() const { return m_rdVerAngle; } /** This method sets the vertical resolution of the viewplane. */ void setVPHeight(int nVPHeight) { m_nVPHeight = nVPHeight; } /** This method returns the vertical resolution of the viewplane. */ int getVPHeight() const { return m_nVPHeight; } /** Set the TimeStep in a 4DVolume */ void setTimeStep(int nTimeStep) { m_nTimeStep = nTimeStep; } /** Get the TimeStep of the Camera for a 4DVolume */ int getTimeStep() const { return m_nTimeStep; } /** Modifies the camera that the bounding box fits * within the currently defined view frustum. */ void viewAll(); /** Prints the camera parameter to standard output. */ void print(); /** Same as above. But more useful for streams. */ //friend ostream& operator<<(ostream&, const CCamera&); /** Reads a vector from the given stream. */ //friend istream& operator>>(istream&, CCamera&); private: ///////////////////// // PRIVATE METHODS // ///////////////////// ///////////////////// // PRIVATE MEMBERS // ///////////////////// CameraType m_CameraType; // holds the current type of the camera CBoundingBox3D m_cBBox; // boundingbox of the scene is needed // to switch bwtween perspective and orthographic double m_rdVerAngle; // vertical focus angle in degrees double m_rdRatio; // ratio between height and width, or hor. and vert. angle double m_rdNearPlane; // distance between eyepoint and near clipplane double m_rdFarPlane; // distance between eyepoint and far clipplane int m_nVPHeight; // size of viewplane in y-direction mutable bool m_fValidViewDir; // is true if the m_cViewDir has a valid value mutable bool m_fValidViewRight; // is true if the m_cViewRight has a valid value CP3D m_cEyePos; CP3D m_cRefPoint; CV3D m_cViewUp; mutable CV3D m_cViewDir; // NOTE: Don't use this direct. Use 'getViewDir()' instead. mutable CV3D m_cViewRight; // NOTE: Don't use this direct. Use 'getViewRight()' instead. int m_nTimeStep; }; #endif // __CCAMERA_H_