Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/freestyle/intern/app_blender/AppGLWidget_frame.h')
-rw-r--r--source/blender/freestyle/intern/app_blender/AppGLWidget_frame.h408
1 files changed, 408 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_frame.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_frame.h
new file mode 100644
index 00000000000..30297499285
--- /dev/null
+++ b/source/blender/freestyle/intern/app_blender/AppGLWidget_frame.h
@@ -0,0 +1,408 @@
+/****************************************************************************
+
+ Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr)
+
+ This file is part of the QGLViewer library.
+ Version 2.2.6-3, released on August 28, 2007.
+
+ http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer
+
+ libQGLViewer 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.
+
+ libQGLViewer 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 libQGLViewer; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
+
+#ifndef QGLVIEWER_FRAME_H
+#define QGLVIEWER_FRAME_H
+
+#include "AppGLWidget_constraint.h"
+// #include "GL/gl.h" is now included in config.h for ease of configuration
+
+//namespace qglviewer {
+ /*! \brief The Frame class represents a coordinate system, defined by a position and an
+ orientation. \class Frame frame.h QGLViewer/frame.h
+
+ A Frame is a 3D coordinate system, represented by a position() and an orientation(). The order of
+ these transformations is important: the Frame is first translated \e and \e then rotated around
+ the new translated origin.
+
+ A Frame is useful to define the position and orientation of a 3D rigid object, using its matrix()
+ method, as shown below:
+ \code
+ // Builds a Frame at position (0.5,0,0) and oriented such that its Y axis is along the (1,1,1)
+ // direction. One could also have used setPosition() and setOrientation().
+ Frame fr(Vec(0.5,0,0), Quaternion(Vec(0,1,0), Vec(1,1,1)));
+ glPushMatrix();
+ glMultMatrixd(fr.matrix());
+ // Draw your object here, in the local fr coordinate system.
+ glPopMatrix();
+ \endcode
+
+ Many functions are provided to transform a 3D point from one coordinate system (Frame) to an
+ other: see coordinatesOf(), inverseCoordinatesOf(), coordinatesOfIn(), coordinatesOfFrom()...
+
+ You may also want to transform a 3D vector (such as a normal), which corresponds to applying only
+ the rotational part of the frame transformation: see transformOf() and inverseTransformOf(). See
+ the <a href="../examples/frameTransform.html">frameTransform example</a> for an illustration.
+
+ The translation() and the rotation() that are encapsulated in a Frame can also be used to
+ represent a \e rigid \e transformation of space. Such a transformation can also be interpreted as
+ a change of coordinate system, and the coordinate system conversion functions actually allow you
+ to use a Frame as a rigid transformation. Use inverseCoordinatesOf() (resp. coordinatesOf()) to
+ apply the transformation (resp. its inverse). Note the inversion.
+
+ <h3>Hierarchy of Frames</h3>
+
+ The position and the orientation of a Frame are actually defined with respect to a
+ referenceFrame(). The default referenceFrame() is the world coordinate system (represented by a \c
+ NULL referenceFrame()). If you setReferenceFrame() to a different Frame, you must then
+ differentiate:
+
+ \arg the \e local translation() and rotation(), defined with respect to the referenceFrame(),
+
+ \arg the \e global position() and orientation(), always defined with respect to the world
+ coordinate system.
+
+ A Frame is actually defined by its translation() with respect to its referenceFrame(), and then by
+ a rotation() of the coordinate system around the new translated origin.
+
+ This terminology for \e local (translation() and rotation()) and \e global (position() and
+ orientation()) definitions is used in all the methods' names and should be sufficient to prevent
+ ambiguities. These notions are obviously identical when the referenceFrame() is \c NULL, i.e. when
+ the Frame is defined in the world coordinate system (the one you are in at the beginning of the
+ QGLViewer::draw() method, see the <a href="../introduction.html">introduction page</a>).
+
+ Frames can hence easily be organized in a tree hierarchy, which root is the world coordinate
+ system. A loop in the hierarchy would result in an inconsistent (multiple) Frame definition.
+ settingAsReferenceFrameWillCreateALoop() checks this and prevents setReferenceFrame() from
+ creating such a loop.
+
+ This frame hierarchy is used in methods like coordinatesOfIn(), coordinatesOfFrom()... which allow
+ coordinates (or vector) conversions from a Frame to any other one (including the world coordinate
+ system).
+
+ However, one must note that this hierarchical representation is internal to the Frame classes.
+ When the Frames represent OpenGL coordinates system, one should map this hierarchical
+ representation to the OpenGL GL_MODELVIEW matrix stack. See the matrix() documentation for
+ details.
+
+ <h3>Constraints</h3>
+
+ An interesting feature of Frames is that their displacements can be constrained. When a Constraint
+ is attached to a Frame, it filters the input of translate() and rotate(), and only the resulting
+ filtered motion is applied to the Frame. The default constraint() is \c NULL resulting in no
+ filtering. Use setConstraint() to attach a Constraint to a frame.
+
+ Constraints are especially usefull for the ManipulatedFrame instances, in order to forbid some
+ mouse motions. See the <a href="../examples/constrainedFrame.html">constrainedFrame</a>, <a
+ href="../examples/constrainedCamera.html">constrainedCamera</a> and <a
+ href="../examples/luxo.html">luxo</a> examples for an illustration.
+
+ Classical constraints are provided for convenience (see LocalConstraint, WorldConstraint and
+ CameraConstraint) and new constraints can very easily be implemented.
+
+ <h3>Derived classes</h3>
+
+ The ManipulatedFrame class inherits Frame and implements a mouse motion convertion, so that a
+ Frame (and hence an object) can be manipulated in the scene with the mouse.
+
+ \nosubgrouping */
+ class Frame
+ {
+
+ public:
+ Frame();
+
+ /*! Virtual destructor. Empty. */
+ virtual ~Frame() {};
+
+ Frame(const Frame& frame);
+ Frame& operator=(const Frame& frame);
+
+ /*! This signal is emitted whenever the position() or the orientation() of the Frame is modified.
+
+ Connect this signal to any object that must be notified:
+ \code
+ QObject::connect(myFrame, SIGNAL(modified()), myObject, SLOT(update()));
+ \endcode
+ Use the QGLViewer::QGLViewerPool() to connect the signal to all the viewers.
+
+ \note If your Frame is part of a Frame hierarchy (see referenceFrame()), a modification of one
+ of the parents of this Frame will \e not emit this signal. Use code like this to change this
+ behavior (you can do this recursively for all the referenceFrame() until the \c NULL world root
+ frame is encountered):
+ \code
+ // Emits the Frame modified() signal when its referenceFrame() is modified().
+ connect(myFrame->referenceFrame(), SIGNAL(modified()), myFrame, SIGNAL(modified()));
+ \endcode
+
+ \attention Connecting this signal to a QGLWidget::updateGL() slot (or a method that calls it)
+ will prevent you from modifying the Frame \e inside your QGLViewer::draw() method as it would
+ result in an infinite loop. However, QGLViewer::draw() should not modify the scene.
+
+ \note For efficiency reasons, this signal is emitted even if the Frame is not actually modified, for
+ instance with translate(Vec(0,0,0)) or setPosition(position()). */
+ void modified();
+
+ /*! This signal is emitted when the Frame is interpolated by a KeyFrameInterpolator.
+
+ See the KeyFrameInterpolator documentation for details.
+
+ If a KeyFrameInterpolator is used to successively interpolate several Frames in your scene,
+ connect the KeyFrameInterpolator::interpolated() signal instead (identical, but independent of
+ the interpolated Frame). */
+ void interpolated();
+
+ public:
+ /*! @name World coordinates position and orientation */
+ //@{
+ Frame(const Vec& position, const Quaternion& orientation);
+
+ void setPosition(const Vec& position);
+ void setPosition(float x, float y, float z);
+ void setPositionWithConstraint(Vec& position);
+
+ void setOrientation(const Quaternion& orientation);
+ void setOrientation(double q0, double q1, double q2, double q3);
+ void setOrientationWithConstraint(Quaternion& orientation);
+
+ void setPositionAndOrientation(const Vec& position, const Quaternion& orientation);
+ void setPositionAndOrientationWithConstraint(Vec& position, Quaternion& orientation);
+
+ /*! Returns the position of the Frame, defined in the world coordinate system. See also
+ orientation(), setPosition() and translation(). */
+ Vec position() const { return inverseCoordinatesOf(Vec(0.0,0.0,0.0)); };
+ Quaternion orientation() const;
+
+ void getPosition(float& x, float& y, float& z) const;
+ void getOrientation(double& q0, double& q1, double& q2, double& q3) const;
+ //@}
+
+
+ public:
+ /*! @name Local translation and rotation w/r reference Frame */
+ //@{
+ /*! Sets the translation() of the frame, locally defined with respect to the referenceFrame().
+ Emits the modified() signal.
+
+ Use setPosition() to define the world coordinates position(). Use
+ setTranslationWithConstraint() to take into account the potential constraint() of the Frame. */
+ void setTranslation(const Vec& translation) { t_ = translation; };
+ void setTranslation(float x, float y, float z);
+ void setTranslationWithConstraint(Vec& translation);
+
+ /*! Set the current rotation Quaternion. See rotation() and the different Quaternion
+ constructors. Emits the modified() signal. See also setTranslation() and
+ setRotationWithConstraint(). */
+
+ /*! Sets the rotation() of the Frame, locally defined with respect to the referenceFrame().
+ Emits the modified() signal.
+
+ Use setOrientation() to define the world coordinates orientation(). The potential
+ constraint() of the Frame is not taken into account, use setRotationWithConstraint()
+ instead. */
+ void setRotation(const Quaternion& rotation) { q_ = rotation; };
+ void setRotation(double q0, double q1, double q2, double q3);
+ void setRotationWithConstraint(Quaternion& rotation);
+
+ void setTranslationAndRotation(const Vec& translation, const Quaternion& rotation);
+ void setTranslationAndRotationWithConstraint(Vec& translation, Quaternion& rotation);
+
+ /*! Returns the Frame translation, defined with respect to the referenceFrame().
+
+ Use position() to get the result in the world coordinates. These two values are identical
+ when the referenceFrame() is \c NULL (default).
+
+ See also setTranslation() and setTranslationWithConstraint(). */
+ Vec translation() const { return t_; };
+ /*! Returns the Frame rotation, defined with respect to the referenceFrame().
+
+ Use orientation() to get the result in the world coordinates. These two values are identical
+ when the referenceFrame() is \c NULL (default).
+
+ See also setRotation() and setRotationWithConstraint(). */
+
+ /*! Returns the current Quaternion orientation. See setRotation(). */
+ Quaternion rotation() const { return q_; };
+
+ void getTranslation(float& x, float& y, float& z) const;
+ void getRotation(double& q0, double& q1, double& q2, double& q3) const;
+ //@}
+
+ public:
+ /*! @name Frame hierarchy */
+ //@{
+ /*! Returns the reference Frame, in which coordinates system the Frame is defined.
+
+ The translation() and rotation() of the Frame are defined with respect to the referenceFrame()
+ coordinate system. A \c NULL referenceFrame() (default value) means that the Frame is defined in
+ the world coordinate system.
+
+ Use position() and orientation() to recursively convert values along the referenceFrame() chain
+ and to get values expressed in the world coordinate system. The values match when the
+ referenceFrame() is \c NULL.
+
+ Use setReferenceFrame() to set this value and create a Frame hierarchy. Convenient functions
+ allow you to convert 3D coordinates from one Frame to an other: see coordinatesOf(),
+ localCoordinatesOf(), coordinatesOfIn() and their inverse functions.
+
+ Vectors can also be converted using transformOf(), transformOfIn, localTransformOf() and their
+ inverse functions. */
+ const Frame* referenceFrame() const { return referenceFrame_; };
+ void setReferenceFrame(const Frame* const refFrame);
+ bool settingAsReferenceFrameWillCreateALoop(const Frame* const frame);
+ //@}
+
+
+ /*! @name Frame modification */
+ //@{
+ void translate(Vec& t);
+ void translate(const Vec& t);
+ // Some compilers complain about "overloading cannot distinguish from previous declaration"
+ // Simply comment out the following method and its associated implementation
+ void translate(float x, float y, float z);
+ void translate(float& x, float& y, float& z);
+
+ void rotate(Quaternion& q);
+ void rotate(const Quaternion& q);
+ // Some compilers complain about "overloading cannot distinguish from previous declaration"
+ // Simply comment out the following method and its associated implementation
+ void rotate(double q0, double q1, double q2, double q3);
+ void rotate(double& q0, double& q1, double& q2, double& q3);
+
+ void rotateAroundPoint(Quaternion& rotation, const Vec& point);
+ void rotateAroundPoint(const Quaternion& rotation, const Vec& point);
+
+ void alignWithFrame(const Frame* const frame, bool move=false, float threshold=0.85f);
+ void projectOnLine(const Vec& origin, const Vec& direction);
+ //@}
+
+
+ /*! @name Coordinate system transformation of 3D coordinates */
+ //@{
+ Vec coordinatesOf(const Vec& src) const;
+ Vec inverseCoordinatesOf(const Vec& src) const;
+ Vec localCoordinatesOf(const Vec& src) const;
+ Vec localInverseCoordinatesOf(const Vec& src) const;
+ Vec coordinatesOfIn(const Vec& src, const Frame* const in) const;
+ Vec coordinatesOfFrom(const Vec& src, const Frame* const from) const;
+
+ void getCoordinatesOf(const float src[3], float res[3]) const;
+ void getInverseCoordinatesOf(const float src[3], float res[3]) const;
+ void getLocalCoordinatesOf(const float src[3], float res[3]) const;
+ void getLocalInverseCoordinatesOf(const float src[3], float res[3]) const;
+ void getCoordinatesOfIn(const float src[3], float res[3], const Frame* const in) const;
+ void getCoordinatesOfFrom(const float src[3], float res[3], const Frame* const from) const;
+ //@}
+
+ /*! @name Coordinate system transformation of vectors */
+ // A frame is as a new coordinate system, defined with respect to a reference frame (the world
+ // coordinate system by default, see the "Composition of frame" section).
+
+ // The transformOf() (resp. inverseTransformOf()) functions transform a 3D vector from (resp.
+ // to) the world coordinates system. This section defines the 3D vector transformation
+ // functions. See the Coordinate system transformation of 3D points above for the transformation
+ // of 3D points. The difference between the two sets of functions is simple: for vectors, only
+ // the rotational part of the transformations is taken into account, while translation is also
+ // considered for 3D points.
+
+ // The length of the resulting transformed vector is identical to the one of the source vector
+ // for all the described functions.
+
+ // When local is prepended to the names of the functions, the functions simply transform from
+ // (and to) the reference frame.
+
+ // When In (resp. From) is appended to the names, the functions transform from (resp. To) the
+ // frame that is given as an argument. The frame does not need to be in the same branch or the
+ // hierarchical tree, and can be \c NULL (the world coordinates system).
+
+ // Combining any of these functions with its inverse (in any order) leads to the identity.
+ //@{
+ Vec transformOf(const Vec& src) const;
+ Vec inverseTransformOf(const Vec& src) const;
+ Vec localTransformOf(const Vec& src) const;
+ Vec localInverseTransformOf(const Vec& src) const;
+ Vec transformOfIn(const Vec& src, const Frame* const in) const;
+ Vec transformOfFrom(const Vec& src, const Frame* const from) const;
+
+ void getTransformOf(const float src[3], float res[3]) const;
+ void getInverseTransformOf(const float src[3], float res[3]) const;
+ void getLocalTransformOf(const float src[3], float res[3]) const;
+ void getLocalInverseTransformOf(const float src[3], float res[3]) const;
+ void getTransformOfIn(const float src[3], float res[3], const Frame* const in) const;
+ void getTransformOfFrom(const float src[3], float res[3], const Frame* const from) const;
+ //@}
+
+
+ /*! @name Constraint on the displacement */
+ //@{
+ /*! Returns the current constraint applied to the Frame.
+
+ A \c NULL value (default) means that no Constraint is used to filter Frame translation and
+ rotation. See the Constraint class documentation for details.
+
+ You may have to use a \c dynamic_cast to convert the result to a Constraint derived class. */
+ Constraint* constraint() const { return constraint_; }
+ /*! Sets the constraint() attached to the Frame.
+
+ A \c NULL value means no constraint. The previous constraint() should be deleted by the calling
+ method if needed. */
+ void setConstraint(Constraint* const constraint) { constraint_ = constraint; }
+ //@}
+
+ /*! @name Associated matrices */
+ //@{
+ public:
+ const GLdouble* matrix() const;
+ void getMatrix(GLdouble m[4][4]) const;
+ void getMatrix(GLdouble m[16]) const;
+
+ const GLdouble* worldMatrix() const;
+ void getWorldMatrix(GLdouble m[4][4]) const;
+ void getWorldMatrix(GLdouble m[16]) const;
+
+ void setFromMatrix(const GLdouble m[4][4]);
+ void setFromMatrix(const GLdouble m[16]);
+ //@}
+
+ /*! @name Inversion of the transformation */
+ //@{
+ Frame inverse() const;
+ /*! Returns the inverse() of the Frame world transformation.
+
+ The orientation() of the new Frame is the Quaternion::inverse() of the original orientation.
+ Its position() is the negated and inverse rotated image of the original position.
+
+ The result Frame has a \c NULL referenceFrame() and a \c NULL constraint().
+
+ Use inverse() for a local (i.e. with respect to referenceFrame()) transformation inverse. */
+ Frame worldInverse() const { return Frame(-(orientation().inverseRotate(position())), orientation().inverse()); }
+ //@}
+
+
+ private:
+ // P o s i t i o n a n d o r i e n t a t i o n
+ Vec t_;
+ Quaternion q_;
+
+ // C o n s t r a i n t s
+ Constraint* constraint_;
+
+ // F r a m e c o m p o s i t i o n
+ const Frame* referenceFrame_;
+ };
+
+//} // namespace qglviewer
+
+#endif // QGLVIEWER_FRAME_H