diff --git a/demos/opengl/CMakeLists.txt b/demos/opengl/CMakeLists.txt
new file mode 100644
index 0000000..299aa44
--- /dev/null
+++ b/demos/opengl/CMakeLists.txt
@@ -0,0 +1,28 @@
+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/demos/opengl/README b/demos/opengl/README
new file mode 100644
index 0000000..8fb1649
--- /dev/null
+++ b/demos/opengl/README
@@ -0,0 +1,13 @@
+
+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/demos/opengl/camera.cpp b/demos/opengl/camera.cpp
new file mode 100644
index 0000000..8a2344c
--- /dev/null
+++ b/demos/opengl/camera.cpp
@@ -0,0 +1,264 @@
+// 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/demos/opengl/camera.h b/demos/opengl/camera.h
new file mode 100644
index 0000000..15714d2
--- /dev/null
+++ b/demos/opengl/camera.h
@@ -0,0 +1,118 @@
+// 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/demos/opengl/gpuhelper.cpp b/demos/opengl/gpuhelper.cpp
new file mode 100644
index 0000000..fd236b1
--- /dev/null
+++ b/demos/opengl/gpuhelper.cpp
@@ -0,0 +1,126 @@
+// 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/demos/opengl/gpuhelper.h b/demos/opengl/gpuhelper.h
new file mode 100644
index 0000000..9ff98e9
--- /dev/null
+++ b/demos/opengl/gpuhelper.h
@@ -0,0 +1,207 @@
+// 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/demos/opengl/icosphere.cpp b/demos/opengl/icosphere.cpp
new file mode 100644
index 0000000..39444cb
--- /dev/null
+++ b/demos/opengl/icosphere.cpp
@@ -0,0 +1,120 @@
+// 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/demos/opengl/icosphere.h b/demos/opengl/icosphere.h
new file mode 100644
index 0000000..b0210ed
--- /dev/null
+++ b/demos/opengl/icosphere.h
@@ -0,0 +1,30 @@
+// 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/demos/opengl/quaternion_demo.cpp b/demos/opengl/quaternion_demo.cpp
new file mode 100644
index 0000000..0416561
--- /dev/null
+++ b/demos/opengl/quaternion_demo.cpp
@@ -0,0 +1,656 @@
+// 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 = internal::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/demos/opengl/quaternion_demo.h b/demos/opengl/quaternion_demo.h
new file mode 100644
index 0000000..dbff46c
--- /dev/null
+++ b/demos/opengl/quaternion_demo.h
@@ -0,0 +1,114 @@
+// 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/demos/opengl/trackball.cpp b/demos/opengl/trackball.cpp
new file mode 100644
index 0000000..77ac790
--- /dev/null
+++ b/demos/opengl/trackball.cpp
@@ -0,0 +1,59 @@
+// 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 ( internal::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/demos/opengl/trackball.h b/demos/opengl/trackball.h
new file mode 100644
index 0000000..1ea842f
--- /dev/null
+++ b/demos/opengl/trackball.h
@@ -0,0 +1,42 @@
+// 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
