diff options
Diffstat (limited to 'eigen/demos/opengl')
-rw-r--r-- | eigen/demos/opengl/CMakeLists.txt | 28 | ||||
-rw-r--r-- | eigen/demos/opengl/README | 13 | ||||
-rw-r--r-- | eigen/demos/opengl/camera.cpp | 264 | ||||
-rw-r--r-- | eigen/demos/opengl/camera.h | 118 | ||||
-rw-r--r-- | eigen/demos/opengl/gpuhelper.cpp | 126 | ||||
-rw-r--r-- | eigen/demos/opengl/gpuhelper.h | 207 | ||||
-rw-r--r-- | eigen/demos/opengl/icosphere.cpp | 120 | ||||
-rw-r--r-- | eigen/demos/opengl/icosphere.h | 30 | ||||
-rw-r--r-- | eigen/demos/opengl/quaternion_demo.cpp | 656 | ||||
-rw-r--r-- | eigen/demos/opengl/quaternion_demo.h | 114 | ||||
-rw-r--r-- | eigen/demos/opengl/trackball.cpp | 59 | ||||
-rw-r--r-- | eigen/demos/opengl/trackball.h | 42 |
12 files changed, 0 insertions, 1777 deletions
diff --git a/eigen/demos/opengl/CMakeLists.txt b/eigen/demos/opengl/CMakeLists.txt deleted file mode 100644 index 299aa44..0000000 --- a/eigen/demos/opengl/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -find_package(Qt4) -find_package(OpenGL) - -if(QT4_FOUND AND OPENGL_FOUND) - - set(QT_USE_QTOPENGL TRUE) - include(${QT_USE_FILE}) - - set(CMAKE_INCLUDE_CURRENT_DIR ON) - - include_directories( ${QT_INCLUDE_DIR} ) - - set(quaternion_demo_SRCS gpuhelper.cpp icosphere.cpp camera.cpp trackball.cpp quaternion_demo.cpp) - - qt4_automoc(${quaternion_demo_SRCS}) - - add_executable(quaternion_demo ${quaternion_demo_SRCS}) - add_dependencies(demos quaternion_demo) - - target_link_libraries(quaternion_demo - ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} - ${QT_QTOPENGL_LIBRARY} ${OPENGL_LIBRARIES} ) - -else() - - message(STATUS "OpenGL demo disabled because Qt4 and/or OpenGL have not been found.") - -endif()
\ No newline at end of file diff --git a/eigen/demos/opengl/README b/eigen/demos/opengl/README deleted file mode 100644 index 8fb1649..0000000 --- a/eigen/demos/opengl/README +++ /dev/null @@ -1,13 +0,0 @@ - -Navigation: - left button: rotate around the target - middle button: zoom - left button + ctrl quake rotate (rotate around camera position) - middle button + ctrl walk (progress along camera's z direction) - left button: pan (translate in the XY camera's plane) - -R : move the camera to initial position -A : start/stop animation -C : clear the animation -G : add a key frame - diff --git a/eigen/demos/opengl/camera.cpp b/eigen/demos/opengl/camera.cpp deleted file mode 100644 index 8a2344c..0000000 --- a/eigen/demos/opengl/camera.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "camera.h" - -#include "gpuhelper.h" -#include <GL/glu.h> - -#include "Eigen/LU" -using namespace Eigen; - -Camera::Camera() - : mViewIsUptodate(false), mProjIsUptodate(false) -{ - mViewMatrix.setIdentity(); - - mFovY = M_PI/3.; - mNearDist = 1.; - mFarDist = 50000.; - - mVpX = 0; - mVpY = 0; - - setPosition(Vector3f::Constant(100.)); - setTarget(Vector3f::Zero()); -} - -Camera& Camera::operator=(const Camera& other) -{ - mViewIsUptodate = false; - mProjIsUptodate = false; - - mVpX = other.mVpX; - mVpY = other.mVpY; - mVpWidth = other.mVpWidth; - mVpHeight = other.mVpHeight; - - mTarget = other.mTarget; - mFovY = other.mFovY; - mNearDist = other.mNearDist; - mFarDist = other.mFarDist; - - mViewMatrix = other.mViewMatrix; - mProjectionMatrix = other.mProjectionMatrix; - - return *this; -} - -Camera::Camera(const Camera& other) -{ - *this = other; -} - -Camera::~Camera() -{ -} - - -void Camera::setViewport(uint offsetx, uint offsety, uint width, uint height) -{ - mVpX = offsetx; - mVpY = offsety; - mVpWidth = width; - mVpHeight = height; - - mProjIsUptodate = false; -} - -void Camera::setViewport(uint width, uint height) -{ - mVpWidth = width; - mVpHeight = height; - - mProjIsUptodate = false; -} - -void Camera::setFovY(float value) -{ - mFovY = value; - mProjIsUptodate = false; -} - -Vector3f Camera::direction(void) const -{ - return - (orientation() * Vector3f::UnitZ()); -} -Vector3f Camera::up(void) const -{ - return orientation() * Vector3f::UnitY(); -} -Vector3f Camera::right(void) const -{ - return orientation() * Vector3f::UnitX(); -} - -void Camera::setDirection(const Vector3f& newDirection) -{ - // TODO implement it computing the rotation between newDirection and current dir ? - Vector3f up = this->up(); - - Matrix3f camAxes; - - camAxes.col(2) = (-newDirection).normalized(); - camAxes.col(0) = up.cross( camAxes.col(2) ).normalized(); - camAxes.col(1) = camAxes.col(2).cross( camAxes.col(0) ).normalized(); - setOrientation(Quaternionf(camAxes)); - - mViewIsUptodate = false; -} - -void Camera::setTarget(const Vector3f& target) -{ - mTarget = target; - if (!mTarget.isApprox(position())) - { - Vector3f newDirection = mTarget - position(); - setDirection(newDirection.normalized()); - } -} - -void Camera::setPosition(const Vector3f& p) -{ - mFrame.position = p; - mViewIsUptodate = false; -} - -void Camera::setOrientation(const Quaternionf& q) -{ - mFrame.orientation = q; - mViewIsUptodate = false; -} - -void Camera::setFrame(const Frame& f) -{ - mFrame = f; - mViewIsUptodate = false; -} - -void Camera::rotateAroundTarget(const Quaternionf& q) -{ - Matrix4f mrot, mt, mtm; - - // update the transform matrix - updateViewMatrix(); - Vector3f t = mViewMatrix * mTarget; - - mViewMatrix = Translation3f(t) - * q - * Translation3f(-t) - * mViewMatrix; - - Quaternionf qa(mViewMatrix.linear()); - qa = qa.conjugate(); - setOrientation(qa); - setPosition(- (qa * mViewMatrix.translation()) ); - - mViewIsUptodate = true; -} - -void Camera::localRotate(const Quaternionf& q) -{ - float dist = (position() - mTarget).norm(); - setOrientation(orientation() * q); - mTarget = position() + dist * direction(); - mViewIsUptodate = false; -} - -void Camera::zoom(float d) -{ - float dist = (position() - mTarget).norm(); - if(dist > d) - { - setPosition(position() + direction() * d); - mViewIsUptodate = false; - } -} - -void Camera::localTranslate(const Vector3f& t) -{ - Vector3f trans = orientation() * t; - setPosition( position() + trans ); - setTarget( mTarget + trans ); - - mViewIsUptodate = false; -} - -void Camera::updateViewMatrix(void) const -{ - if(!mViewIsUptodate) - { - Quaternionf q = orientation().conjugate(); - mViewMatrix.linear() = q.toRotationMatrix(); - mViewMatrix.translation() = - (mViewMatrix.linear() * position()); - - mViewIsUptodate = true; - } -} - -const Affine3f& Camera::viewMatrix(void) const -{ - updateViewMatrix(); - return mViewMatrix; -} - -void Camera::updateProjectionMatrix(void) const -{ - if(!mProjIsUptodate) - { - mProjectionMatrix.setIdentity(); - float aspect = float(mVpWidth)/float(mVpHeight); - float theta = mFovY*0.5; - float range = mFarDist - mNearDist; - float invtan = 1./tan(theta); - - mProjectionMatrix(0,0) = invtan / aspect; - mProjectionMatrix(1,1) = invtan; - mProjectionMatrix(2,2) = -(mNearDist + mFarDist) / range; - mProjectionMatrix(3,2) = -1; - mProjectionMatrix(2,3) = -2 * mNearDist * mFarDist / range; - mProjectionMatrix(3,3) = 0; - - mProjIsUptodate = true; - } -} - -const Matrix4f& Camera::projectionMatrix(void) const -{ - updateProjectionMatrix(); - return mProjectionMatrix; -} - -void Camera::activateGL(void) -{ - glViewport(vpX(), vpY(), vpWidth(), vpHeight()); - gpu.loadMatrix(projectionMatrix(),GL_PROJECTION); - gpu.loadMatrix(viewMatrix().matrix(),GL_MODELVIEW); -} - - -Vector3f Camera::unProject(const Vector2f& uv, float depth) const -{ - Matrix4f inv = mViewMatrix.inverse().matrix(); - return unProject(uv, depth, inv); -} - -Vector3f Camera::unProject(const Vector2f& uv, float depth, const Matrix4f& invModelview) const -{ - updateViewMatrix(); - updateProjectionMatrix(); - - Vector3f a(2.*uv.x()/float(mVpWidth)-1., 2.*uv.y()/float(mVpHeight)-1., 1.); - a.x() *= depth/mProjectionMatrix(0,0); - a.y() *= depth/mProjectionMatrix(1,1); - a.z() = -depth; - // FIXME /\/| - Vector4f b = invModelview * Vector4f(a.x(), a.y(), a.z(), 1.); - return Vector3f(b.x(), b.y(), b.z()); -} diff --git a/eigen/demos/opengl/camera.h b/eigen/demos/opengl/camera.h deleted file mode 100644 index 15714d2..0000000 --- a/eigen/demos/opengl/camera.h +++ /dev/null @@ -1,118 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_CAMERA_H -#define EIGEN_CAMERA_H - -#include <Eigen/Geometry> -#include <QObject> -// #include <frame.h> - -class Frame -{ - public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - - inline Frame(const Eigen::Vector3f& pos = Eigen::Vector3f::Zero(), - const Eigen::Quaternionf& o = Eigen::Quaternionf()) - : orientation(o), position(pos) - {} - Frame lerp(float alpha, const Frame& other) const - { - return Frame((1.f-alpha)*position + alpha * other.position, - orientation.slerp(alpha,other.orientation)); - } - - Eigen::Quaternionf orientation; - Eigen::Vector3f position; -}; - -class Camera -{ - public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - - Camera(void); - - Camera(const Camera& other); - - virtual ~Camera(); - - Camera& operator=(const Camera& other); - - void setViewport(uint offsetx, uint offsety, uint width, uint height); - void setViewport(uint width, uint height); - - inline uint vpX(void) const { return mVpX; } - inline uint vpY(void) const { return mVpY; } - inline uint vpWidth(void) const { return mVpWidth; } - inline uint vpHeight(void) const { return mVpHeight; } - - inline float fovY(void) const { return mFovY; } - void setFovY(float value); - - void setPosition(const Eigen::Vector3f& pos); - inline const Eigen::Vector3f& position(void) const { return mFrame.position; } - - void setOrientation(const Eigen::Quaternionf& q); - inline const Eigen::Quaternionf& orientation(void) const { return mFrame.orientation; } - - void setFrame(const Frame& f); - const Frame& frame(void) const { return mFrame; } - - void setDirection(const Eigen::Vector3f& newDirection); - Eigen::Vector3f direction(void) const; - void setUp(const Eigen::Vector3f& vectorUp); - Eigen::Vector3f up(void) const; - Eigen::Vector3f right(void) const; - - void setTarget(const Eigen::Vector3f& target); - inline const Eigen::Vector3f& target(void) { return mTarget; } - - const Eigen::Affine3f& viewMatrix(void) const; - const Eigen::Matrix4f& projectionMatrix(void) const; - - void rotateAroundTarget(const Eigen::Quaternionf& q); - void localRotate(const Eigen::Quaternionf& q); - void zoom(float d); - - void localTranslate(const Eigen::Vector3f& t); - - /** Setup OpenGL matrices and viewport */ - void activateGL(void); - - Eigen::Vector3f unProject(const Eigen::Vector2f& uv, float depth, const Eigen::Matrix4f& invModelview) const; - Eigen::Vector3f unProject(const Eigen::Vector2f& uv, float depth) const; - - protected: - void updateViewMatrix(void) const; - void updateProjectionMatrix(void) const; - - protected: - - uint mVpX, mVpY; - uint mVpWidth, mVpHeight; - - Frame mFrame; - - mutable Eigen::Affine3f mViewMatrix; - mutable Eigen::Matrix4f mProjectionMatrix; - - mutable bool mViewIsUptodate; - mutable bool mProjIsUptodate; - - // used by rotateAroundTarget - Eigen::Vector3f mTarget; - - float mFovY; - float mNearDist; - float mFarDist; -}; - -#endif // EIGEN_CAMERA_H diff --git a/eigen/demos/opengl/gpuhelper.cpp b/eigen/demos/opengl/gpuhelper.cpp deleted file mode 100644 index fd236b1..0000000 --- a/eigen/demos/opengl/gpuhelper.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "gpuhelper.h" -#include "icosphere.h" -#include <GL/glu.h> -// PLEASE don't look at this old code... ;) - -#include <fstream> -#include <algorithm> - -GpuHelper gpu; - -GpuHelper::GpuHelper() -{ - mVpWidth = mVpHeight = 0; - mCurrentMatrixTarget = 0; - mInitialized = false; -} - -GpuHelper::~GpuHelper() -{ -} - -void GpuHelper::pushProjectionMode2D(ProjectionMode2D pm) -{ - // switch to 2D projection - pushMatrix(Matrix4f::Identity(),GL_PROJECTION); - - if(pm==PM_Normalized) - { - //glOrtho(-1., 1., -1., 1., 0., 1.); - } - else if(pm==PM_Viewport) - { - GLint vp[4]; - glGetIntegerv(GL_VIEWPORT, vp); - glOrtho(0., vp[2], 0., vp[3], -1., 1.); - } - - pushMatrix(Matrix4f::Identity(),GL_MODELVIEW); -} - -void GpuHelper::popProjectionMode2D(void) -{ - popMatrix(GL_PROJECTION); - popMatrix(GL_MODELVIEW); -} - -void GpuHelper::drawVector(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect /* = 50.*/) -{ - static GLUquadricObj *cylindre = gluNewQuadric(); - glColor4fv(color.data()); - float length = vec.norm(); - pushMatrix(GL_MODELVIEW); - glTranslatef(position.x(), position.y(), position.z()); - Vector3f ax = Matrix3f::Identity().col(2).cross(vec); - ax.normalize(); - Vector3f tmp = vec; - tmp.normalize(); - float angle = 180.f/M_PI * acos(tmp.z()); - if (angle>1e-3) - glRotatef(angle, ax.x(), ax.y(), ax.z()); - gluCylinder(cylindre, length/aspect, length/aspect, 0.8*length, 10, 10); - glTranslatef(0.0,0.0,0.8*length); - gluCylinder(cylindre, 2.0*length/aspect, 0.0, 0.2*length, 10, 10); - - popMatrix(GL_MODELVIEW); -} - -void GpuHelper::drawVectorBox(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect) -{ - static GLUquadricObj *cylindre = gluNewQuadric(); - glColor4fv(color.data()); - float length = vec.norm(); - pushMatrix(GL_MODELVIEW); - glTranslatef(position.x(), position.y(), position.z()); - Vector3f ax = Matrix3f::Identity().col(2).cross(vec); - ax.normalize(); - Vector3f tmp = vec; - tmp.normalize(); - float angle = 180.f/M_PI * acos(tmp.z()); - if (angle>1e-3) - glRotatef(angle, ax.x(), ax.y(), ax.z()); - gluCylinder(cylindre, length/aspect, length/aspect, 0.8*length, 10, 10); - glTranslatef(0.0,0.0,0.8*length); - glScalef(4.0*length/aspect,4.0*length/aspect,4.0*length/aspect); - drawUnitCube(); - popMatrix(GL_MODELVIEW); -} - -void GpuHelper::drawUnitCube(void) -{ - static float vertices[][3] = { - {-0.5,-0.5,-0.5}, - { 0.5,-0.5,-0.5}, - {-0.5, 0.5,-0.5}, - { 0.5, 0.5,-0.5}, - {-0.5,-0.5, 0.5}, - { 0.5,-0.5, 0.5}, - {-0.5, 0.5, 0.5}, - { 0.5, 0.5, 0.5}}; - - glBegin(GL_QUADS); - glNormal3f(0,0,-1); glVertex3fv(vertices[0]); glVertex3fv(vertices[2]); glVertex3fv(vertices[3]); glVertex3fv(vertices[1]); - glNormal3f(0,0, 1); glVertex3fv(vertices[4]); glVertex3fv(vertices[5]); glVertex3fv(vertices[7]); glVertex3fv(vertices[6]); - glNormal3f(0,-1,0); glVertex3fv(vertices[0]); glVertex3fv(vertices[1]); glVertex3fv(vertices[5]); glVertex3fv(vertices[4]); - glNormal3f(0, 1,0); glVertex3fv(vertices[2]); glVertex3fv(vertices[6]); glVertex3fv(vertices[7]); glVertex3fv(vertices[3]); - glNormal3f(-1,0,0); glVertex3fv(vertices[0]); glVertex3fv(vertices[4]); glVertex3fv(vertices[6]); glVertex3fv(vertices[2]); - glNormal3f( 1,0,0); glVertex3fv(vertices[1]); glVertex3fv(vertices[3]); glVertex3fv(vertices[7]); glVertex3fv(vertices[5]); - glEnd(); -} - -void GpuHelper::drawUnitSphere(int level) -{ - static IcoSphere sphere; - sphere.draw(level); -} - - diff --git a/eigen/demos/opengl/gpuhelper.h b/eigen/demos/opengl/gpuhelper.h deleted file mode 100644 index 9ff98e9..0000000 --- a/eigen/demos/opengl/gpuhelper.h +++ /dev/null @@ -1,207 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_GPUHELPER_H -#define EIGEN_GPUHELPER_H - -#include <Eigen/Geometry> -#include <GL/gl.h> -#include <vector> - -using namespace Eigen; - -typedef Vector4f Color; - -class GpuHelper -{ - public: - - GpuHelper(); - - ~GpuHelper(); - - enum ProjectionMode2D { PM_Normalized = 1, PM_Viewport = 2 }; - void pushProjectionMode2D(ProjectionMode2D pm); - void popProjectionMode2D(); - - /** Multiply the OpenGL matrix \a matrixTarget by the matrix \a mat. - Essentially, this helper function automatically calls glMatrixMode(matrixTarget) if required - and does a proper call to the right glMultMatrix*() function according to the scalar type - and storage order. - \warning glMatrixMode() must never be called directly. If your're unsure, use forceMatrixMode(). - \sa Matrix, loadMatrix(), forceMatrixMode() - */ - template<typename Scalar, int _Flags> - void multMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget); - - /** Load the matrix \a mat to the OpenGL matrix \a matrixTarget. - Essentially, this helper function automatically calls glMatrixMode(matrixTarget) if required - and does a proper call to the right glLoadMatrix*() or glLoadIdentity() function according to the scalar type - and storage order. - \warning glMatrixMode() must never be called directly. If your're unsure, use forceMatrixMode(). - \sa Matrix, multMatrix(), forceMatrixMode() - */ - template<typename Scalar, int _Flags> - void loadMatrix(const Eigen::Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget); - - template<typename Scalar, typename Derived> - void loadMatrix( - const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&, - GLenum matrixTarget); - - /** Make the matrix \a matrixTarget the current OpenGL matrix target. - Call this function before loadMatrix() or multMatrix() if you cannot guarantee that glMatrixMode() - has never been called after the last loadMatrix() or multMatrix() calls. - \todo provides a debug mode checking the sanity of the cached matrix mode. - */ - inline void forceMatrixTarget(GLenum matrixTarget) {glMatrixMode(mCurrentMatrixTarget=matrixTarget);} - - inline void setMatrixTarget(GLenum matrixTarget); - - /** Push the OpenGL matrix \a matrixTarget and load \a mat. - */ - template<typename Scalar, int _Flags> - inline void pushMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget); - - template<typename Scalar, typename Derived> - void pushMatrix( - const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&, - GLenum matrixTarget); - - /** Push and clone the OpenGL matrix \a matrixTarget - */ - inline void pushMatrix(GLenum matrixTarget); - - /** Pop the OpenGL matrix \a matrixTarget - */ - inline void popMatrix(GLenum matrixTarget); - - void drawVector(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect = 50.); - void drawVectorBox(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect = 50.); - void drawUnitCube(void); - void drawUnitSphere(int level=0); - - /// draw the \a nofElement first elements - inline void draw(GLenum mode, uint nofElement); - - /// draw a range of elements - inline void draw(GLenum mode, uint start, uint end); - - /// draw an indexed subset - inline void draw(GLenum mode, const std::vector<uint>* pIndexes); - -protected: - - void update(void); - - GLuint mColorBufferId; - int mVpWidth, mVpHeight; - GLenum mCurrentMatrixTarget; - bool mInitialized; -}; - -/** Singleton shortcut -*/ -extern GpuHelper gpu; - - -/** \internal -*/ -template<bool RowMajor, int _Flags> struct GlMatrixHelper; - -template<int _Flags> struct GlMatrixHelper<false,_Flags> -{ - static void loadMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glLoadMatrixf(mat.data()); } - static void loadMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glLoadMatrixd(mat.data()); } - static void multMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glMultMatrixf(mat.data()); } - static void multMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glMultMatrixd(mat.data()); } -}; - -template<int _Flags> struct GlMatrixHelper<true,_Flags> -{ - static void loadMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glLoadMatrixf(mat.transpose().eval().data()); } - static void loadMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glLoadMatrixd(mat.transpose().eval().data()); } - static void multMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glMultMatrixf(mat.transpose().eval().data()); } - static void multMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glMultMatrixd(mat.transpose().eval().data()); } -}; - -inline void GpuHelper::setMatrixTarget(GLenum matrixTarget) -{ - if (matrixTarget != mCurrentMatrixTarget) - glMatrixMode(mCurrentMatrixTarget=matrixTarget); -} - -template<typename Scalar, int _Flags> -void GpuHelper::multMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget) -{ - setMatrixTarget(matrixTarget); - GlMatrixHelper<_Flags&Eigen::RowMajorBit, _Flags>::multMatrix(mat); -} - -template<typename Scalar, typename Derived> -void GpuHelper::loadMatrix( - const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&, - GLenum matrixTarget) -{ - setMatrixTarget(matrixTarget); - glLoadIdentity(); -} - -template<typename Scalar, int _Flags> -void GpuHelper::loadMatrix(const Eigen::Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget) -{ - setMatrixTarget(matrixTarget); - GlMatrixHelper<(_Flags&Eigen::RowMajorBit)!=0, _Flags>::loadMatrix(mat); -} - -inline void GpuHelper::pushMatrix(GLenum matrixTarget) -{ - setMatrixTarget(matrixTarget); - glPushMatrix(); -} - -template<typename Scalar, int _Flags> -inline void GpuHelper::pushMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget) -{ - pushMatrix(matrixTarget); - GlMatrixHelper<_Flags&Eigen::RowMajorBit,_Flags>::loadMatrix(mat); -} - -template<typename Scalar, typename Derived> -void GpuHelper::pushMatrix( - const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&, - GLenum matrixTarget) -{ - pushMatrix(matrixTarget); - glLoadIdentity(); -} - -inline void GpuHelper::popMatrix(GLenum matrixTarget) -{ - setMatrixTarget(matrixTarget); - glPopMatrix(); -} - -inline void GpuHelper::draw(GLenum mode, uint nofElement) -{ - glDrawArrays(mode, 0, nofElement); -} - - -inline void GpuHelper::draw(GLenum mode, const std::vector<uint>* pIndexes) -{ - glDrawElements(mode, pIndexes->size(), GL_UNSIGNED_INT, &(pIndexes->front())); -} - -inline void GpuHelper::draw(GLenum mode, uint start, uint end) -{ - glDrawArrays(mode, start, end-start); -} - -#endif // EIGEN_GPUHELPER_H diff --git a/eigen/demos/opengl/icosphere.cpp b/eigen/demos/opengl/icosphere.cpp deleted file mode 100644 index 39444cb..0000000 --- a/eigen/demos/opengl/icosphere.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "icosphere.h" - -#include <GL/gl.h> -#include <map> - -using namespace Eigen; - -//-------------------------------------------------------------------------------- -// icosahedron data -//-------------------------------------------------------------------------------- -#define X .525731112119133606 -#define Z .850650808352039932 - -static GLfloat vdata[12][3] = { - {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z}, - {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X}, - {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0} -}; - -static GLint tindices[20][3] = { - {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1}, - {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3}, - {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, - {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} }; -//-------------------------------------------------------------------------------- - -IcoSphere::IcoSphere(unsigned int levels) -{ - // init with an icosahedron - for (int i = 0; i < 12; i++) - mVertices.push_back(Map<Vector3f>(vdata[i])); - mIndices.push_back(new std::vector<int>); - std::vector<int>& indices = *mIndices.back(); - for (int i = 0; i < 20; i++) - { - for (int k = 0; k < 3; k++) - indices.push_back(tindices[i][k]); - } - mListIds.push_back(0); - - while(mIndices.size()<levels) - _subdivide(); -} - -const std::vector<int>& IcoSphere::indices(int level) const -{ - while (level>=int(mIndices.size())) - const_cast<IcoSphere*>(this)->_subdivide(); - return *mIndices[level]; -} - -void IcoSphere::_subdivide(void) -{ - typedef unsigned long long Key; - std::map<Key,int> edgeMap; - const std::vector<int>& indices = *mIndices.back(); - mIndices.push_back(new std::vector<int>); - std::vector<int>& refinedIndices = *mIndices.back(); - int end = indices.size(); - for (int i=0; i<end; i+=3) - { - int ids0[3], // indices of outer vertices - ids1[3]; // indices of edge vertices - for (int k=0; k<3; ++k) - { - int k1 = (k+1)%3; - int e0 = indices[i+k]; - int e1 = indices[i+k1]; - ids0[k] = e0; - if (e1>e0) - std::swap(e0,e1); - Key edgeKey = Key(e0) | (Key(e1)<<32); - std::map<Key,int>::iterator it = edgeMap.find(edgeKey); - if (it==edgeMap.end()) - { - ids1[k] = mVertices.size(); - edgeMap[edgeKey] = ids1[k]; - mVertices.push_back( (mVertices[e0]+mVertices[e1]).normalized() ); - } - else - ids1[k] = it->second; - } - refinedIndices.push_back(ids0[0]); refinedIndices.push_back(ids1[0]); refinedIndices.push_back(ids1[2]); - refinedIndices.push_back(ids0[1]); refinedIndices.push_back(ids1[1]); refinedIndices.push_back(ids1[0]); - refinedIndices.push_back(ids0[2]); refinedIndices.push_back(ids1[2]); refinedIndices.push_back(ids1[1]); - refinedIndices.push_back(ids1[0]); refinedIndices.push_back(ids1[1]); refinedIndices.push_back(ids1[2]); - } - mListIds.push_back(0); -} - -void IcoSphere::draw(int level) -{ - while (level>=int(mIndices.size())) - const_cast<IcoSphere*>(this)->_subdivide(); - if (mListIds[level]==0) - { - mListIds[level] = glGenLists(1); - glNewList(mListIds[level], GL_COMPILE); - glVertexPointer(3, GL_FLOAT, 0, mVertices[0].data()); - glNormalPointer(GL_FLOAT, 0, mVertices[0].data()); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glDrawElements(GL_TRIANGLES, mIndices[level]->size(), GL_UNSIGNED_INT, &(mIndices[level]->at(0))); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glEndList(); - } - glCallList(mListIds[level]); -} - - diff --git a/eigen/demos/opengl/icosphere.h b/eigen/demos/opengl/icosphere.h deleted file mode 100644 index b0210ed..0000000 --- a/eigen/demos/opengl/icosphere.h +++ /dev/null @@ -1,30 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_ICOSPHERE_H -#define EIGEN_ICOSPHERE_H - -#include <Eigen/Core> -#include <vector> - -class IcoSphere -{ - public: - IcoSphere(unsigned int levels=1); - const std::vector<Eigen::Vector3f>& vertices() const { return mVertices; } - const std::vector<int>& indices(int level) const; - void draw(int level); - protected: - void _subdivide(); - std::vector<Eigen::Vector3f> mVertices; - std::vector<std::vector<int>*> mIndices; - std::vector<int> mListIds; -}; - -#endif // EIGEN_ICOSPHERE_H diff --git a/eigen/demos/opengl/quaternion_demo.cpp b/eigen/demos/opengl/quaternion_demo.cpp deleted file mode 100644 index dd323a4..0000000 --- a/eigen/demos/opengl/quaternion_demo.cpp +++ /dev/null @@ -1,656 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "quaternion_demo.h" -#include "icosphere.h" - -#include <Eigen/Geometry> -#include <Eigen/QR> -#include <Eigen/LU> - -#include <iostream> -#include <QEvent> -#include <QMouseEvent> -#include <QInputDialog> -#include <QGridLayout> -#include <QButtonGroup> -#include <QRadioButton> -#include <QDockWidget> -#include <QPushButton> -#include <QGroupBox> - -using namespace Eigen; - -class FancySpheres -{ - public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - - FancySpheres() - { - const int levels = 4; - const float scale = 0.33; - float radius = 100; - std::vector<int> parents; - - // leval 0 - mCenters.push_back(Vector3f::Zero()); - parents.push_back(-1); - mRadii.push_back(radius); - - // generate level 1 using icosphere vertices - radius *= 0.45; - { - float dist = mRadii[0]*0.9; - for (int i=0; i<12; ++i) - { - mCenters.push_back(mIcoSphere.vertices()[i] * dist); - mRadii.push_back(radius); - parents.push_back(0); - } - } - - static const float angles [10] = { - 0, 0, - M_PI, 0.*M_PI, - M_PI, 0.5*M_PI, - M_PI, 1.*M_PI, - M_PI, 1.5*M_PI - }; - - // generate other levels - int start = 1; - for (int l=1; l<levels; l++) - { - radius *= scale; - int end = mCenters.size(); - for (int i=start; i<end; ++i) - { - Vector3f c = mCenters[i]; - Vector3f ax0 = (c - mCenters[parents[i]]).normalized(); - Vector3f ax1 = ax0.unitOrthogonal(); - Quaternionf q; - q.setFromTwoVectors(Vector3f::UnitZ(), ax0); - Affine3f t = Translation3f(c) * q * Scaling(mRadii[i]+radius); - for (int j=0; j<5; ++j) - { - Vector3f newC = c + ( (AngleAxisf(angles[j*2+1], ax0) - * AngleAxisf(angles[j*2+0] * (l==1 ? 0.35 : 0.5), ax1)) * ax0) - * (mRadii[i] + radius*0.8); - mCenters.push_back(newC); - mRadii.push_back(radius); - parents.push_back(i); - } - } - start = end; - } - } - - void draw() - { - int end = mCenters.size(); - glEnable(GL_NORMALIZE); - for (int i=0; i<end; ++i) - { - Affine3f t = Translation3f(mCenters[i]) * Scaling(mRadii[i]); - gpu.pushMatrix(GL_MODELVIEW); - gpu.multMatrix(t.matrix(),GL_MODELVIEW); - mIcoSphere.draw(2); - gpu.popMatrix(GL_MODELVIEW); - } - glDisable(GL_NORMALIZE); - } - protected: - std::vector<Vector3f> mCenters; - std::vector<float> mRadii; - IcoSphere mIcoSphere; -}; - - -// generic linear interpolation method -template<typename T> T lerp(float t, const T& a, const T& b) -{ - return a*(1-t) + b*t; -} - -// quaternion slerp -template<> Quaternionf lerp(float t, const Quaternionf& a, const Quaternionf& b) -{ return a.slerp(t,b); } - -// linear interpolation of a frame using the type OrientationType -// to perform the interpolation of the orientations -template<typename OrientationType> -inline static Frame lerpFrame(float alpha, const Frame& a, const Frame& b) -{ - return Frame(lerp(alpha,a.position,b.position), - Quaternionf(lerp(alpha,OrientationType(a.orientation),OrientationType(b.orientation)))); -} - -template<typename _Scalar> class EulerAngles -{ -public: - enum { Dim = 3 }; - typedef _Scalar Scalar; - typedef Matrix<Scalar,3,3> Matrix3; - typedef Matrix<Scalar,3,1> Vector3; - typedef Quaternion<Scalar> QuaternionType; - -protected: - - Vector3 m_angles; - -public: - - EulerAngles() {} - inline EulerAngles(Scalar a0, Scalar a1, Scalar a2) : m_angles(a0, a1, a2) {} - inline EulerAngles(const QuaternionType& q) { *this = q; } - - const Vector3& coeffs() const { return m_angles; } - Vector3& coeffs() { return m_angles; } - - EulerAngles& operator=(const QuaternionType& q) - { - Matrix3 m = q.toRotationMatrix(); - return *this = m; - } - - EulerAngles& operator=(const Matrix3& m) - { - // mat = cy*cz -cy*sz sy - // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx - // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy - m_angles.coeffRef(1) = std::asin(m.coeff(0,2)); - m_angles.coeffRef(0) = std::atan2(-m.coeff(1,2),m.coeff(2,2)); - m_angles.coeffRef(2) = std::atan2(-m.coeff(0,1),m.coeff(0,0)); - return *this; - } - - Matrix3 toRotationMatrix(void) const - { - Vector3 c = m_angles.array().cos(); - Vector3 s = m_angles.array().sin(); - Matrix3 res; - res << c.y()*c.z(), -c.y()*s.z(), s.y(), - c.z()*s.x()*s.y()+c.x()*s.z(), c.x()*c.z()-s.x()*s.y()*s.z(), -c.y()*s.x(), - -c.x()*c.z()*s.y()+s.x()*s.z(), c.z()*s.x()+c.x()*s.y()*s.z(), c.x()*c.y(); - return res; - } - - operator QuaternionType() { return QuaternionType(toRotationMatrix()); } -}; - -// Euler angles slerp -template<> EulerAngles<float> lerp(float t, const EulerAngles<float>& a, const EulerAngles<float>& b) -{ - EulerAngles<float> res; - res.coeffs() = lerp(t, a.coeffs(), b.coeffs()); - return res; -} - - -RenderingWidget::RenderingWidget() -{ - mAnimate = false; - mCurrentTrackingMode = TM_NO_TRACK; - mNavMode = NavTurnAround; - mLerpMode = LerpQuaternion; - mRotationMode = RotationStable; - mTrackball.setCamera(&mCamera); - - // required to capture key press events - setFocusPolicy(Qt::ClickFocus); -} - -void RenderingWidget::grabFrame(void) -{ - // ask user for a time - bool ok = false; - double t = 0; - if (!m_timeline.empty()) - t = (--m_timeline.end())->first + 1.; - t = QInputDialog::getDouble(this, "Eigen's RenderingWidget", "time value: ", - t, 0, 1e3, 1, &ok); - if (ok) - { - Frame aux; - aux.orientation = mCamera.viewMatrix().linear(); - aux.position = mCamera.viewMatrix().translation(); - m_timeline[t] = aux; - } -} - -void RenderingWidget::drawScene() -{ - static FancySpheres sFancySpheres; - float length = 50; - gpu.drawVector(Vector3f::Zero(), length*Vector3f::UnitX(), Color(1,0,0,1)); - gpu.drawVector(Vector3f::Zero(), length*Vector3f::UnitY(), Color(0,1,0,1)); - gpu.drawVector(Vector3f::Zero(), length*Vector3f::UnitZ(), Color(0,0,1,1)); - - // draw the fractal object - float sqrt3 = std::sqrt(3.); - glLightfv(GL_LIGHT0, GL_AMBIENT, Vector4f(0.5,0.5,0.5,1).data()); - glLightfv(GL_LIGHT0, GL_DIFFUSE, Vector4f(0.5,1,0.5,1).data()); - glLightfv(GL_LIGHT0, GL_SPECULAR, Vector4f(1,1,1,1).data()); - glLightfv(GL_LIGHT0, GL_POSITION, Vector4f(-sqrt3,-sqrt3,sqrt3,0).data()); - - glLightfv(GL_LIGHT1, GL_AMBIENT, Vector4f(0,0,0,1).data()); - glLightfv(GL_LIGHT1, GL_DIFFUSE, Vector4f(1,0.5,0.5,1).data()); - glLightfv(GL_LIGHT1, GL_SPECULAR, Vector4f(1,1,1,1).data()); - glLightfv(GL_LIGHT1, GL_POSITION, Vector4f(-sqrt3,sqrt3,-sqrt3,0).data()); - - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Vector4f(0.7, 0.7, 0.7, 1).data()); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Vector4f(0.8, 0.75, 0.6, 1).data()); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Vector4f(1, 1, 1, 1).data()); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64); - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - - sFancySpheres.draw(); - glVertexPointer(3, GL_FLOAT, 0, mVertices[0].data()); - glNormalPointer(GL_FLOAT, 0, mNormals[0].data()); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glDrawArrays(GL_TRIANGLES, 0, mVertices.size()); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - glDisable(GL_LIGHTING); -} - -void RenderingWidget::animate() -{ - m_alpha += double(m_timer.interval()) * 1e-3; - - TimeLine::const_iterator hi = m_timeline.upper_bound(m_alpha); - TimeLine::const_iterator lo = hi; - --lo; - - Frame currentFrame; - - if(hi==m_timeline.end()) - { - // end - currentFrame = lo->second; - stopAnimation(); - } - else if(hi==m_timeline.begin()) - { - // start - currentFrame = hi->second; - } - else - { - float s = (m_alpha - lo->first)/(hi->first - lo->first); - if (mLerpMode==LerpEulerAngles) - currentFrame = ::lerpFrame<EulerAngles<float> >(s, lo->second, hi->second); - else if (mLerpMode==LerpQuaternion) - currentFrame = ::lerpFrame<Eigen::Quaternionf>(s, lo->second, hi->second); - else - { - std::cerr << "Invalid rotation interpolation mode (abort)\n"; - exit(2); - } - currentFrame.orientation.coeffs().normalize(); - } - - currentFrame.orientation = currentFrame.orientation.inverse(); - currentFrame.position = - (currentFrame.orientation * currentFrame.position); - mCamera.setFrame(currentFrame); - - updateGL(); -} - -void RenderingWidget::keyPressEvent(QKeyEvent * e) -{ - switch(e->key()) - { - case Qt::Key_Up: - mCamera.zoom(2); - break; - case Qt::Key_Down: - mCamera.zoom(-2); - break; - // add a frame - case Qt::Key_G: - grabFrame(); - break; - // clear the time line - case Qt::Key_C: - m_timeline.clear(); - break; - // move the camera to initial pos - case Qt::Key_R: - resetCamera(); - break; - // start/stop the animation - case Qt::Key_A: - if (mAnimate) - { - stopAnimation(); - } - else - { - m_alpha = 0; - connect(&m_timer, SIGNAL(timeout()), this, SLOT(animate())); - m_timer.start(1000/30); - mAnimate = true; - } - break; - default: - break; - } - - updateGL(); -} - -void RenderingWidget::stopAnimation() -{ - disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(animate())); - m_timer.stop(); - mAnimate = false; - m_alpha = 0; -} - -void RenderingWidget::mousePressEvent(QMouseEvent* e) -{ - mMouseCoords = Vector2i(e->pos().x(), e->pos().y()); - bool fly = (mNavMode==NavFly) || (e->modifiers()&Qt::ControlModifier); - switch(e->button()) - { - case Qt::LeftButton: - if(fly) - { - mCurrentTrackingMode = TM_LOCAL_ROTATE; - mTrackball.start(Trackball::Local); - } - else - { - mCurrentTrackingMode = TM_ROTATE_AROUND; - mTrackball.start(Trackball::Around); - } - mTrackball.track(mMouseCoords); - break; - case Qt::MidButton: - if(fly) - mCurrentTrackingMode = TM_FLY_Z; - else - mCurrentTrackingMode = TM_ZOOM; - break; - case Qt::RightButton: - mCurrentTrackingMode = TM_FLY_PAN; - break; - default: - break; - } -} -void RenderingWidget::mouseReleaseEvent(QMouseEvent*) -{ - mCurrentTrackingMode = TM_NO_TRACK; - updateGL(); -} - -void RenderingWidget::mouseMoveEvent(QMouseEvent* e) -{ - // tracking - if(mCurrentTrackingMode != TM_NO_TRACK) - { - float dx = float(e->x() - mMouseCoords.x()) / float(mCamera.vpWidth()); - float dy = - float(e->y() - mMouseCoords.y()) / float(mCamera.vpHeight()); - - // speedup the transformations - if(e->modifiers() & Qt::ShiftModifier) - { - dx *= 10.; - dy *= 10.; - } - - switch(mCurrentTrackingMode) - { - case TM_ROTATE_AROUND: - case TM_LOCAL_ROTATE: - if (mRotationMode==RotationStable) - { - // use the stable trackball implementation mapping - // the 2D coordinates to 3D points on a sphere. - mTrackball.track(Vector2i(e->pos().x(), e->pos().y())); - } - else - { - // standard approach mapping the x and y displacements as rotations - // around the camera's X and Y axes. - Quaternionf q = AngleAxisf( dx*M_PI, Vector3f::UnitY()) - * AngleAxisf(-dy*M_PI, Vector3f::UnitX()); - if (mCurrentTrackingMode==TM_LOCAL_ROTATE) - mCamera.localRotate(q); - else - mCamera.rotateAroundTarget(q); - } - break; - case TM_ZOOM : - mCamera.zoom(dy*100); - break; - case TM_FLY_Z : - mCamera.localTranslate(Vector3f(0, 0, -dy*200)); - break; - case TM_FLY_PAN : - mCamera.localTranslate(Vector3f(dx*200, dy*200, 0)); - break; - default: - break; - } - - updateGL(); - } - - mMouseCoords = Vector2i(e->pos().x(), e->pos().y()); -} - -void RenderingWidget::paintGL() -{ - glEnable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - glDisable(GL_TEXTURE_1D); - glDisable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_3D); - - // Clear buffers - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - mCamera.activateGL(); - - drawScene(); -} - -void RenderingWidget::initializeGL() -{ - glClearColor(1., 1., 1., 0.); - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); - glDepthMask(GL_TRUE); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - mCamera.setPosition(Vector3f(-200, -200, -200)); - mCamera.setTarget(Vector3f(0, 0, 0)); - mInitFrame.orientation = mCamera.orientation().inverse(); - mInitFrame.position = mCamera.viewMatrix().translation(); -} - -void RenderingWidget::resizeGL(int width, int height) -{ - mCamera.setViewport(width,height); -} - -void RenderingWidget::setNavMode(int m) -{ - mNavMode = NavMode(m); -} - -void RenderingWidget::setLerpMode(int m) -{ - mLerpMode = LerpMode(m); -} - -void RenderingWidget::setRotationMode(int m) -{ - mRotationMode = RotationMode(m); -} - -void RenderingWidget::resetCamera() -{ - if (mAnimate) - stopAnimation(); - m_timeline.clear(); - Frame aux0 = mCamera.frame(); - aux0.orientation = aux0.orientation.inverse(); - aux0.position = mCamera.viewMatrix().translation(); - m_timeline[0] = aux0; - - Vector3f currentTarget = mCamera.target(); - mCamera.setTarget(Vector3f::Zero()); - - // compute the rotation duration to move the camera to the target - Frame aux1 = mCamera.frame(); - aux1.orientation = aux1.orientation.inverse(); - aux1.position = mCamera.viewMatrix().translation(); - float duration = aux0.orientation.angularDistance(aux1.orientation) * 0.9; - if (duration<0.1) duration = 0.1; - - // put the camera at that time step: - aux1 = aux0.lerp(duration/2,mInitFrame); - // and make it look at the target again - aux1.orientation = aux1.orientation.inverse(); - aux1.position = - (aux1.orientation * aux1.position); - mCamera.setFrame(aux1); - mCamera.setTarget(Vector3f::Zero()); - - // add this camera keyframe - aux1.orientation = aux1.orientation.inverse(); - aux1.position = mCamera.viewMatrix().translation(); - m_timeline[duration] = aux1; - - m_timeline[2] = mInitFrame; - m_alpha = 0; - animate(); - connect(&m_timer, SIGNAL(timeout()), this, SLOT(animate())); - m_timer.start(1000/30); - mAnimate = true; -} - -QWidget* RenderingWidget::createNavigationControlWidget() -{ - QWidget* panel = new QWidget(); - QVBoxLayout* layout = new QVBoxLayout(); - - { - QPushButton* but = new QPushButton("reset"); - but->setToolTip("move the camera to initial position (with animation)"); - layout->addWidget(but); - connect(but, SIGNAL(clicked()), this, SLOT(resetCamera())); - } - { - // navigation mode - QGroupBox* box = new QGroupBox("navigation mode"); - QVBoxLayout* boxLayout = new QVBoxLayout; - QButtonGroup* group = new QButtonGroup(panel); - QRadioButton* but; - but = new QRadioButton("turn around"); - but->setToolTip("look around an object"); - group->addButton(but, NavTurnAround); - boxLayout->addWidget(but); - but = new QRadioButton("fly"); - but->setToolTip("free navigation like a spaceship\n(this mode can also be enabled pressing the \"shift\" key)"); - group->addButton(but, NavFly); - boxLayout->addWidget(but); - group->button(mNavMode)->setChecked(true); - connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setNavMode(int))); - box->setLayout(boxLayout); - layout->addWidget(box); - } - { - // track ball, rotation mode - QGroupBox* box = new QGroupBox("rotation mode"); - QVBoxLayout* boxLayout = new QVBoxLayout; - QButtonGroup* group = new QButtonGroup(panel); - QRadioButton* but; - but = new QRadioButton("stable trackball"); - group->addButton(but, RotationStable); - boxLayout->addWidget(but); - but->setToolTip("use the stable trackball implementation mapping\nthe 2D coordinates to 3D points on a sphere"); - but = new QRadioButton("standard rotation"); - group->addButton(but, RotationStandard); - boxLayout->addWidget(but); - but->setToolTip("standard approach mapping the x and y displacements\nas rotations around the camera's X and Y axes"); - group->button(mRotationMode)->setChecked(true); - connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setRotationMode(int))); - box->setLayout(boxLayout); - layout->addWidget(box); - } - { - // interpolation mode - QGroupBox* box = new QGroupBox("spherical interpolation"); - QVBoxLayout* boxLayout = new QVBoxLayout; - QButtonGroup* group = new QButtonGroup(panel); - QRadioButton* but; - but = new QRadioButton("quaternion slerp"); - group->addButton(but, LerpQuaternion); - boxLayout->addWidget(but); - but->setToolTip("use quaternion spherical interpolation\nto interpolate orientations"); - but = new QRadioButton("euler angles"); - group->addButton(but, LerpEulerAngles); - boxLayout->addWidget(but); - but->setToolTip("use Euler angles to interpolate orientations"); - group->button(mNavMode)->setChecked(true); - connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setLerpMode(int))); - box->setLayout(boxLayout); - layout->addWidget(box); - } - layout->addItem(new QSpacerItem(0,0,QSizePolicy::Minimum,QSizePolicy::Expanding)); - panel->setLayout(layout); - return panel; -} - -QuaternionDemo::QuaternionDemo() -{ - mRenderingWidget = new RenderingWidget(); - setCentralWidget(mRenderingWidget); - - QDockWidget* panel = new QDockWidget("navigation", this); - panel->setAllowedAreas((QFlags<Qt::DockWidgetArea>)(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea)); - addDockWidget(Qt::RightDockWidgetArea, panel); - panel->setWidget(mRenderingWidget->createNavigationControlWidget()); -} - -int main(int argc, char *argv[]) -{ - std::cout << "Navigation:\n"; - std::cout << " left button: rotate around the target\n"; - std::cout << " middle button: zoom\n"; - std::cout << " left button + ctrl quake rotate (rotate around camera position)\n"; - std::cout << " middle button + ctrl walk (progress along camera's z direction)\n"; - std::cout << " left button: pan (translate in the XY camera's plane)\n\n"; - std::cout << "R : move the camera to initial position\n"; - std::cout << "A : start/stop animation\n"; - std::cout << "C : clear the animation\n"; - std::cout << "G : add a key frame\n"; - - QApplication app(argc, argv); - QuaternionDemo demo; - demo.resize(600,500); - demo.show(); - return app.exec(); -} - -#include "quaternion_demo.moc" - diff --git a/eigen/demos/opengl/quaternion_demo.h b/eigen/demos/opengl/quaternion_demo.h deleted file mode 100644 index dbff46c..0000000 --- a/eigen/demos/opengl/quaternion_demo.h +++ /dev/null @@ -1,114 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_QUATERNION_DEMO_H -#define EIGEN_QUATERNION_DEMO_H - -#include "gpuhelper.h" -#include "camera.h" -#include "trackball.h" -#include <map> -#include <QTimer> -#include <QtGui/QApplication> -#include <QtOpenGL/QGLWidget> -#include <QtGui/QMainWindow> - -class RenderingWidget : public QGLWidget -{ - Q_OBJECT - - typedef std::map<float,Frame> TimeLine; - TimeLine m_timeline; - Frame lerpFrame(float t); - - Frame mInitFrame; - bool mAnimate; - float m_alpha; - - enum TrackMode { - TM_NO_TRACK=0, TM_ROTATE_AROUND, TM_ZOOM, - TM_LOCAL_ROTATE, TM_FLY_Z, TM_FLY_PAN - }; - - enum NavMode { - NavTurnAround, - NavFly - }; - - enum LerpMode { - LerpQuaternion, - LerpEulerAngles - }; - - enum RotationMode { - RotationStable, - RotationStandard - }; - - Camera mCamera; - TrackMode mCurrentTrackingMode; - NavMode mNavMode; - LerpMode mLerpMode; - RotationMode mRotationMode; - Vector2i mMouseCoords; - Trackball mTrackball; - - QTimer m_timer; - - void setupCamera(); - - std::vector<Vector3f> mVertices; - std::vector<Vector3f> mNormals; - std::vector<int> mIndices; - - protected slots: - - virtual void animate(void); - virtual void drawScene(void); - - virtual void grabFrame(void); - virtual void stopAnimation(); - - virtual void setNavMode(int); - virtual void setLerpMode(int); - virtual void setRotationMode(int); - virtual void resetCamera(); - - protected: - - virtual void initializeGL(); - virtual void resizeGL(int width, int height); - virtual void paintGL(); - - //-------------------------------------------------------------------------------- - virtual void mousePressEvent(QMouseEvent * e); - virtual void mouseReleaseEvent(QMouseEvent * e); - virtual void mouseMoveEvent(QMouseEvent * e); - virtual void keyPressEvent(QKeyEvent * e); - //-------------------------------------------------------------------------------- - - public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - - RenderingWidget(); - ~RenderingWidget() { } - - QWidget* createNavigationControlWidget(); -}; - -class QuaternionDemo : public QMainWindow -{ - Q_OBJECT - public: - QuaternionDemo(); - protected: - RenderingWidget* mRenderingWidget; -}; - -#endif // EIGEN_QUATERNION_DEMO_H diff --git a/eigen/demos/opengl/trackball.cpp b/eigen/demos/opengl/trackball.cpp deleted file mode 100644 index 7c2da8e..0000000 --- a/eigen/demos/opengl/trackball.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "trackball.h" -#include "camera.h" - -using namespace Eigen; - -void Trackball::track(const Vector2i& point2D) -{ - if (mpCamera==0) - return; - Vector3f newPoint3D; - bool newPointOk = mapToSphere(point2D, newPoint3D); - - if (mLastPointOk && newPointOk) - { - Vector3f axis = mLastPoint3D.cross(newPoint3D).normalized(); - float cos_angle = mLastPoint3D.dot(newPoint3D); - if ( std::abs(cos_angle) < 1.0 ) - { - float angle = 2. * acos(cos_angle); - if (mMode==Around) - mpCamera->rotateAroundTarget(Quaternionf(AngleAxisf(angle, axis))); - else - mpCamera->localRotate(Quaternionf(AngleAxisf(-angle, axis))); - } - } - - mLastPoint3D = newPoint3D; - mLastPointOk = newPointOk; -} - -bool Trackball::mapToSphere(const Vector2i& p2, Vector3f& v3) -{ - if ((p2.x() >= 0) && (p2.x() <= int(mpCamera->vpWidth())) && - (p2.y() >= 0) && (p2.y() <= int(mpCamera->vpHeight())) ) - { - double x = (double)(p2.x() - 0.5*mpCamera->vpWidth()) / (double)mpCamera->vpWidth(); - double y = (double)(0.5*mpCamera->vpHeight() - p2.y()) / (double)mpCamera->vpHeight(); - double sinx = sin(M_PI * x * 0.5); - double siny = sin(M_PI * y * 0.5); - double sinx2siny2 = sinx * sinx + siny * siny; - - v3.x() = sinx; - v3.y() = siny; - v3.z() = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0; - - return true; - } - else - return false; -} diff --git a/eigen/demos/opengl/trackball.h b/eigen/demos/opengl/trackball.h deleted file mode 100644 index 1ea842f..0000000 --- a/eigen/demos/opengl/trackball.h +++ /dev/null @@ -1,42 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_TRACKBALL_H -#define EIGEN_TRACKBALL_H - -#include <Eigen/Geometry> - -class Camera; - -class Trackball -{ - public: - - enum Mode {Around, Local}; - - Trackball() : mpCamera(0) {} - - void start(Mode m = Around) { mMode = m; mLastPointOk = false; } - - void setCamera(Camera* pCam) { mpCamera = pCam; } - - void track(const Eigen::Vector2i& newPoint2D); - - protected: - - bool mapToSphere( const Eigen::Vector2i& p2, Eigen::Vector3f& v3); - - Camera* mpCamera; - Eigen::Vector3f mLastPoint3D; - Mode mMode; - bool mLastPointOk; - -}; - -#endif // EIGEN_TRACKBALL_H |