Commit c9445446 authored by Kenneth Vanhoey's avatar Kenneth Vanhoey

Merge cgogn:~cgogn/CGoGN

parents f4446e0d 39c7eaff
......@@ -196,7 +196,7 @@ void MyQT::cb_initGL()
// timer example for animation
m_timer = new QTimer( m_glWidget );
m_timer = new QTimer( this );
connect( m_timer, SIGNAL(timeout()), SLOT(animate()) );
}
......
......@@ -91,8 +91,17 @@ protected:
int m_state_modifier;
/**
* met a jour la matrice modelview
*/
void recalcModelView();
/**
* recalcul le quaternion ainsi que le deplacement courant
* pour un nouveau centre de rotation
*/
void changeCenterOfRotation(const glm::vec3& newCenter);
public:
void setParamObject(float width, float* pos);
......@@ -109,6 +118,8 @@ public:
void mouseClickEvent(QMouseEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void keyPressEvent(QKeyEvent* event);
......
......@@ -64,8 +64,7 @@ namespace Utils
* The resulting rotation is returned as a quaternion rotation in the
* first paramater.
*/
void
trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
void trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
/*
* Given two quaternions, add them together to get a third quaternion.
......@@ -75,26 +74,25 @@ trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
* rotation, the second and third the total rotation (which will be
* over-written with the resulting new total rotation).
*/
void
add_quats(float *q1, float *q2, float *dest);
void add_quats(float *q1, float *q2, float *dest);
/*
* A useful function, builds a rotation matrix in Matrix based on
* given quaternion.
*/
void
build_rotmatrix(float m[4][4], float q[4]);
void build_rotmatrix(float m[4][4], float q[4]);
void build_rotmatrixgl3(glm::mat4& m, float q[4]);
void matrix_to_quat( float* q, const glm::mat4& m);
/*
* This function computes a quaternion based on an axis (defined by
* the given vector) and an angle about which to rotate. The angle is
* expressed in radians. The result is put into the third argument.
*/
void
axis_to_quat(float a[3], float phi, float q[4]);
void axis_to_quat(float a[3], float phi, float q[4]);
} //namespace Utils
......
......@@ -28,6 +28,7 @@
#include "Utils/trackball.h"
#include "Utils/qtSimple.h"
#include "glm/gtc/type_precision.hpp"
namespace CGoGN
{
......@@ -96,33 +97,73 @@ QSize GLWidget::sizeHint() const
void GLWidget::recalcModelView()
{
m_cbs->modelViewMatrix()= glm::mat4(1.0f);
// positionne l'objet / mvt souris
oglTranslate(m_cbs->trans_x(), m_cbs->trans_y(), m_cbs->trans_z());
// tourne l'objet / mvt souris
glm::mat4 m;
build_rotmatrixgl3(m, m_cbs->curquat());
// update matrice
m_cbs->modelViewMatrix() *= m;
// ajout transformation in screen
m_cbs->modelViewMatrix()*= m_cbs->transfoMatrix();
// transfo pour que l'objet soit centre et a la bonne taille
oglScale(m_obj_sc, m_obj_sc, m_obj_sc);
oglTranslate(m_obj_pos[0], m_obj_pos[1], m_obj_pos[2]);
newModel = 0;
if (m_cbs)
m_cbs->cb_updateMatrix();
}
void GLWidget::changeCenterOfRotation(const glm::vec3& newCenter)
{
oglPushModelViewMatrix();
m_cbs->modelViewMatrix()= glm::mat4(1.0f);
// positionne l'objet / mvt souris
oglTranslate(m_cbs->trans_x(), m_cbs->trans_y(), m_cbs->trans_z());
// tourne l'objet / mvt souris
glm::mat4 m;
build_rotmatrixgl3(m, m_cbs->curquat());
// update matrice
m_cbs->modelViewMatrix() *= m;
// ajout transformation in screen
m_cbs->modelViewMatrix()*= m_cbs->transfoMatrix();
// transfo pour que l'objet soit centre et a la bonne taille
oglScale(m_obj_sc, m_obj_sc, m_obj_sc);
oglTranslate(m_obj_pos[0], m_obj_pos[1], m_obj_pos[2]);
// ajout transformation in screen
m_cbs->modelViewMatrix()*= m_cbs->transfoMatrix();
newModel = 0;
oglTranslate(newCenter[0], newCenter[1], newCenter[2]);
oglScale(1.0f/m_obj_sc, 1.0f/m_obj_sc, 1.0f/m_obj_sc);
if (m_cbs)
m_cbs->cb_updateMatrix();
m = glm::inverse(m_cbs->transfoMatrix());
m_cbs->modelViewMatrix()*= m;
matrix_to_quat( m_cbs->curquat(), m_cbs->modelViewMatrix());
m_cbs->trans_x() = m_cbs->modelViewMatrix()[3][0];
m_cbs->trans_y() = m_cbs->modelViewMatrix()[3][1];
m_cbs->trans_z() = m_cbs->modelViewMatrix()[3][2];
oglPopModelViewMatrix();
m_obj_pos = glm::vec3(-newCenter[0],-newCenter[1],-newCenter[2]);
}
void GLWidget::initializeGL()
{
glEnable(GL_DEPTH_TEST);
......@@ -175,10 +216,31 @@ void GLWidget::mouseReleaseEvent(QMouseEvent* event)
void GLWidget::mouseClickEvent(QMouseEvent* event)
{
if (m_cbs)
m_cbs->cb_mouseClick(event->button(), event->x(), getHeight() - event->y());
}
void GLWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
if (event->button()==1)
{
GLint x = event->x();
GLint y = getHeight() - event->y();
GLfloat depth;
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
if (depth < 1.0f)
{
glm::i32vec4 viewport;
glGetIntegerv(GL_VIEWPORT, &(viewport[0]));
glm::vec3 win(x, y, depth);
glm::vec3 P = glm::unProject(win, m_cbs->modelViewMatrix(), m_cbs->projectionMatrix(), viewport);
changeCenterOfRotation(P);
}
}
}
void GLWidget::mouseMoveEvent(QMouseEvent* event)
{
// move object only if no special keys pressed
......@@ -268,8 +330,34 @@ void GLWidget::keyReleaseEvent(QKeyEvent *event)
QWidget::keyReleaseEvent(event);
m_state_modifier = event->modifiers();
int k = event->key();
// align on axis
if ((k=='Z') && (event->modifiers() & Qt::ShiftModifier))
{
float Z[3]={0.0f,0.0f,1.0f};
axis_to_quat(Z,0.0f,m_cbs->curquat());
newModel=1;
updateGL();
}
if ((k=='Y') && (event->modifiers() & Qt::ShiftModifier))
{
float X[3]={1.0f,0.0f,0.0f};
axis_to_quat(X,M_PI/2.0f,m_cbs->curquat());
newModel=1;
updateGL();
}
if ((k=='X') && (event->modifiers() & Qt::ShiftModifier))
{
float Y[3]={0.0f,1.0f,0.0f};
axis_to_quat(Y,-M_PI/2.0f,m_cbs->curquat());
newModel=1;
updateGL();
}
if ( (k >= 65) && (k <= 91) && (event->modifiers() != Qt::ShiftModifier) )
k += 32;
......
......@@ -389,6 +389,45 @@ void build_rotmatrixgl3(glm::mat4& m, float q[4])
m[3][3] = 1.0;
}
void matrix_to_quat( float* q, const glm::mat4& m)
{
double tr = m[0][0] + m[1][1] + m[2][2];
if (tr > 0.0)
{
double S = sqrt(tr+1.0) * 2.0; // S=4*q[3]
q[3] = 0.25 * S;
q[0] = (m[2][1] - m[1][2]) / S;
q[1] = (m[0][2] - m[2][0]) / S;
q[2] = (m[1][0] - m[0][1]) / S;
}
else if ((m[0][0] > m[1][1])&(m[0][0] > m[2][2]))
{
double S = sqrt(1.0f + m[0][0] - m[1][1] - m[2][2]) * 2.0; // S=4*q[0]
q[3] = (m[2][1] - m[1][2]) / S;
q[0] = 0.25 * S;
q[1] = (m[0][1] + m[1][0]) / S;
q[2] = (m[0][2] + m[2][0]) / S;
}
else if (m[1][1] > m[2][2])
{
double S = sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]) * 2.0; // S=4*q[1]
q[3] = (m[0][2] - m[2][0]) / S;
q[0] = (m[0][1] + m[1][0]) / S;
q[1] = 0.25 * S;
q[2] = (m[1][2] + m[2][1]) / S;
}
else
{
double S = sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]) * 2.0; // S=4*q[2]
q[3] = (m[1][0] - m[0][1]) / S;
q[0] = (m[0][2] + m[2][0]) / S;
q[1] = (m[1][2] + m[2][1]) / S;
q[2] = 0.25 * S;
}
}
} //namespace Utils
} //namespace CGoGN
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment