Avogadro
1.1.0
|
Representation of the camera looking at the molecule. More...
#include <avogadro/camera.h>
Public Member Functions | |
Camera (const GLWidget *parent=0, double angleOfViewY=40.0) | |
virtual | ~Camera () |
Camera (const Camera *camera) | |
const GLWidget * | parent () const |
void | setAngleOfViewY (double angleOfViewY) |
double | angleOfViewY () const |
void | setModelview (const Eigen::Transform3d &matrix) |
const Eigen::Transform3d & | modelview () const |
Eigen::Transform3d & | modelview () |
void | applyPerspective () const |
void | applyProjection () const |
void | applyModelview () const |
void | initializeViewPoint () |
double | distance (const Eigen::Vector3d &point) const |
void | translate (const Eigen::Vector3d &vector) |
void | pretranslate (const Eigen::Vector3d &vector) |
void | rotate (const double &angle, const Eigen::Vector3d &axis) |
void | prerotate (const double &angle, const Eigen::Vector3d &axis) |
void | scale (double coefficient) |
Eigen::Vector3d | unProject (const Eigen::Vector3d &v) const |
Eigen::Vector3d | unProject (const QPoint &p, const Eigen::Vector3d &ref) const |
Eigen::Vector3d | unProject (const QPoint &p) const |
Eigen::Vector3d | project (const Eigen::Vector3d &v) const |
Eigen::Vector3d | backTransformedXAxis () const |
Eigen::Vector3d | backTransformedYAxis () const |
Eigen::Vector3d | backTransformedZAxis () const |
Eigen::Vector3d | transformedXAxis () const |
Eigen::Vector3d | transformedYAxis () const |
Eigen::Vector3d | transformedZAxis () const |
bool | nearClippingPlane (Eigen::Vector3d *normal, Eigen::Vector3d *point) |
void | normalize () |
double | scalingCoefficient () |
Protected Member Functions | |
void | setParent (const GLWidget *glwidget) |
Representation of the camera looking at the molecule.
This class represents a camera looking at the molecule loaded in a GLWidget. It stores the parameters describing the camera and a pointer to the parent GLWidget. It uses this to retrieve information about the molecule being looked at, automatically setting up the OpenGL projection matrix to ensure that the molecule will not be clipped. It also provides a method to initialize a nice default viewpoint of the molecule. In order to setup the OpenGL matrices before rendering the molecule, do the following:
// setup the OpenGL projection matrix using the camera glMatrixMode(GL_PROJECTION); glLoadIdentity(); camera.applyPerspective(); // setup the OpenGL modelview matrix using the camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); camera.applyModelview();
The reason why Camera class does not provide a single method to do all of this is that in some cases you don't want to. For instance, when doing OpenGL selection, you want to call gluPickMatrix() right before Camera::applyPerspective().
Avogadro::Camera::Camera | ( | const GLWidget * | parent = 0 , |
double | angleOfViewY = 40.0 |
||
) | [explicit] |
The constructor.
parent | the GLWidget parent of this camera instance. |
angleOfViewY | the vertical viewing angle in degrees. |
References angleOfViewY(), and parent().
Avogadro::Camera::~Camera | ( | ) | [virtual] |
The destructor.
Avogadro::Camera::Camera | ( | const Camera * | camera | ) |
The copy constructor - it is useful to be able to copy the Camera.
double Avogadro::Camera::angleOfViewY | ( | ) | const |
Referenced by Camera(), and setAngleOfViewY().
void Avogadro::Camera::applyModelview | ( | ) | const |
Calls glMultMatrix() with the camera's "modelview" matrix. Should be called only in GL_MODELVIEW matrix mode. Example code is given in the class's comment.
void Avogadro::Camera::applyPerspective | ( | ) | const |
Calls gluPerspective() or glOrtho() with parameters automatically chosen for rendering the GLWidget's molecule with this camera. Should be called only in GL_PROJECTION matrix mode. Example code is given in the class's comment.
References applyProjection().
void Avogadro::Camera::applyProjection | ( | ) | const |
Calls gluPerspective() or glOrtho() with parameters automatically chosen for rendering the GLWidget's molecule with this camera. Should be called only in GL_PROJECTION matrix mode. Example code is given in the class's comment.
References distance().
Referenced by applyPerspective().
Eigen::Vector3d Avogadro::Camera::backTransformedXAxis | ( | ) | const |
Returns a unit vector pointing toward the right, expressed in the scene's coordinate system. This is simply the unit vector that is mapped to (1,0,0) by the camera rotation.
Referenced by Avogadro::Navigate::rotate().
Eigen::Vector3d Avogadro::Camera::backTransformedYAxis | ( | ) | const |
Returns a unit vector pointing upward, expressed in the scene's coordinate system. This is simply the unit vector that is mapped to (0,1,0) by the camera rotation.
Referenced by Avogadro::Navigate::rotate().
Eigen::Vector3d Avogadro::Camera::backTransformedZAxis | ( | ) | const |
Returns a unit vector pointing toward the camera, expressed in the scene's coordinate system. This is simply the unit vector that is mapped to (0,0,1) by the camera rotation.
Referenced by Avogadro::Navigate::rotate().
double Avogadro::Camera::distance | ( | const Eigen::Vector3d & | point | ) | const |
Returns the distance between point and the camera. For instance, to determine the distance between a molecule's center and the camera, do:
double d = camera.distance( molecule.center() );
Referenced by applyProjection().
Sets up the camera so that it gives a nice view of the molecule loaded in the parent GLWidget. Typically you would call this method right after loading a molecule.
References pretranslate(), and translate().
const Eigen::Transform3d & Avogadro::Camera::modelview | ( | ) | const |
Referenced by Avogadro::GLWidget::render(), and Avogadro::Navigate::zoom().
Eigen::Transform3d & Avogadro::Camera::modelview | ( | ) |
bool Avogadro::Camera::nearClippingPlane | ( | Eigen::Vector3d * | normal, |
Eigen::Vector3d * | point | ||
) |
Obtain a normal vector and point defining the plane of the clipping plane nearest the camera.
normal | Overwritten with a normalized vector orthogonal to the plane. All planes have two normal vectors -- this vector is the one pointing into the viewing volume. |
point | Overwritten with a point that lies within the plane. This is the point at (-1, -1, -1) in normalized device coordinates (i.e. the bottom left corner of the viewport). |
References cross().
void Avogadro::Camera::normalize | ( | ) |
The linear component (ie the 3x3 topleft block) of the camera matrix must always be a rotation. But after several hundreds of operations on it, it can drift farther and farther away from being a rotation. This method normalizes the camera matrix so that the linear component is guaranteed to be a rotation. Concretely, it performs a Gram-Schmidt orthonormalization to transform the linear component into a nearby rotation.
The bottom row must always have entries 0, 0, 0, 1. This function overwrites the bottom row with these values.
References scalingCoefficient().
Referenced by prerotate(), and rotate().
const GLWidget * Avogadro::Camera::parent | ( | ) | const |
Referenced by Camera(), project(), setParent(), and unProject().
void Avogadro::Camera::prerotate | ( | const double & | angle, |
const Eigen::Vector3d & | axis | ||
) |
Multiply the camera's "modelview" matrix on the left by the rotation of the given angle and axis. Because the rotation is applied on the left, the axis vector is understood in the the coordinate system obtained by applying the camera's matrix to the molecule's coordinate system. Use this method if you want to give the impression that the camera is rotating while the molecule remains fixed.
After the rotation is multiplied, a normalization is performed to ensure that the camera matrix remains sane.
angle | the rotation angle in radians |
axis | a unit vector around which to rotate. This MUST be a unit vector, i.e. axis.norm() must be close to 1. |
References normalize().
void Avogadro::Camera::pretranslate | ( | const Eigen::Vector3d & | vector | ) |
Multiply the camera's "modelview" matrix on the left by the translation of given vector. Because the translation is applied on the left, the vector is understood in the coordinate system obtained by applying the camera's matrix to the molecule's coordinate system. Use this method if you want to give the impression that the camera is moving while the molecule remains fixed.
vector | the translation vector |
Referenced by initializeViewPoint().
Eigen::Vector3d Avogadro::Camera::project | ( | const Eigen::Vector3d & | v | ) | const |
Performs a projection from space coordinates to window coordinates.
v | the vector to project, expressed in space coordinates. |
References QWidget::height, parent(), and QWidget::width.
Referenced by unProject().
void Avogadro::Camera::rotate | ( | const double & | angle, |
const Eigen::Vector3d & | axis | ||
) |
Multiply the camera's "modelview" matrix on the right by the rotation of the given angle and axis. As the rotation is applied on the right, the axis vector is understood in the molecule's coordinate system. Use this method if you want to give the impression that the molecule is rotating while the camera remains fixed. This is the equivalent of the OpenGL function glRotate(), except that here the angle is expressed in radians, not in degrees.
After the rotation is multiplied, a normalization is performed to ensure that the camera matrix remains sane.
angle | the rotation angle in radians |
axis | a unit vector around which to rotate. This MUST be a unit vector, i.e. axis.norm() must be close to 1. |
References normalize().
Referenced by Avogadro::Navigate::rotate().
void Avogadro::Camera::scale | ( | double | coefficient | ) |
For perspective projections, multiply the camera's "modelview" matrix by a scaling coefficient. It affects the linear part of the camera's "modelview" matrix only.
For orthographic projections, this affects the width and height of the projection, scaling the eye coordinates isotropically.
Use this method if you want to give the impression that the camera is zooming in or out.
coefficient | the scaling coefficient |
Referenced by Avogadro::Navigate::zoom().
double Avogadro::Camera::scalingCoefficient | ( | ) |
Calculate the isotropic scaling coefficient of the camera's "modelview" matrix. It assumes the intial volume of the camera's "modelview" space (determinant of the camera's "modelview" matrix linear component) is equal to unity.
Referenced by normalize().
void Avogadro::Camera::setAngleOfViewY | ( | double | angleOfViewY | ) |
Sets the vertical viewing angle.
angleOfViewY | the new vertical viewing angle in degrees. |
References angleOfViewY().
void Avogadro::Camera::setModelview | ( | const Eigen::Transform3d & | matrix | ) |
Sets 4x4 "modelview" matrix representing the camera orientation and position.
matrix | the matrix to copy from |
void Avogadro::Camera::setParent | ( | const GLWidget * | glwidget | ) | [protected] |
Eigen::Vector3d Avogadro::Camera::transformedXAxis | ( | ) | const |
Returns a unit vector pointing in the x direction, expressed in the space coordinate system.
Eigen::Vector3d Avogadro::Camera::transformedYAxis | ( | ) | const |
Returns a unit vector pointing in the y direction, expressed in the space coordinate system.
Eigen::Vector3d Avogadro::Camera::transformedZAxis | ( | ) | const |
Returns a unit vector pointing in the z direction, expressed in the space coordinate system.
void Avogadro::Camera::translate | ( | const Eigen::Vector3d & | vector | ) |
Multiply the camera's "modelview" matrix on the right by the translation of the given vector. As the translation is applied on the right, the vector is understood in the molecule's coordinate system. Use this method if you want to give the impression that the molecule is moving while the camera remains fixed. This is the equivalent of the OpenGL function glTranslate().
vector | the translation vector |
Referenced by initializeViewPoint(), Avogadro::Navigate::rotate(), and Avogadro::Navigate::translate().
Eigen::Vector3d Avogadro::Camera::unProject | ( | const Eigen::Vector3d & | v | ) | const |
Performs an unprojection from window coordinates to space coordinates.
v | The vector to unproject, expressed in window coordinates. Thus v.x() and v.y() are the x and y coords of the pixel to unproject. v.z() represents it's "z-distance". If you don't know what value to put in v.z(), see the other unProject(const QPoint&) method. |
References QWidget::height, parent(), and QWidget::width.
Referenced by Avogadro::Navigate::translate(), and unProject().
Eigen::Vector3d Avogadro::Camera::unProject | ( | const QPoint & | p, |
const Eigen::Vector3d & | ref | ||
) | const |
Performs an unprojection from window coordinates to space coordinates, into the plane passing through a given reference point and parallel to the screen. Thus the returned vector is a point of that plane. The rationale is that when unprojecting 2D window coords to 3D space coords, there are a priori infinitely many solutions, and one has to be choose. This is equivalent to choosing a plane parallel to the screen.
p | the point to unproject, expressed in window coordinates. |
ref | the reference point, determining the plane into which to unproject. If you don't know what to put here, see the other unProject(const QPoint&) method. |
References project(), unProject(), QPoint::x(), and QPoint::y().
Eigen::Vector3d Avogadro::Camera::unProject | ( | const QPoint & | p | ) | const |
Performs an unprojection from window coordinates to space coordinates, into the plane passing through the molecule's center and parallel to the screen. Thus the returned vector is a point belonging to that plane. This is equivalent to
unProject( p, center() );
p | the point to unproject, expressed in window coordinates. |
References parent(), and unProject().