Shot2Trackball trasformation with gluLookAt compensation.

Fixed bug in getShotFromTrack2 (negative sign)
This commit is contained in:
Michele Sottile sottile 2010-05-05 15:27:08 +00:00
parent 0459c7a59d
commit 5d9977c1d4
7 changed files with 284 additions and 7 deletions

View File

@ -258,18 +258,18 @@ void GLArea::paintGL()
setView(); // Set Modelview and Projection matrix
drawGradient(); // draws the background
drawLight();
drawLight();
glPushMatrix();
// Finally apply the Trackball for the model
trackball.GetView();
trackball.Apply(false);
trackball.Apply(false);
glPushMatrix();
//glScale(d);
// glTranslate(-FullBBox.Center());
setLightModel();
//glTranslate(-FullBBox.Center());
setLightModel();
// Set proper colorMode
if(rm.colorMode != GLW::CMNone)
@ -680,6 +680,16 @@ void GLArea::mouseReleaseEvent(QMouseEvent*e)
update();
if(isCurrent())
mvc->updateReleaseViewers(e);
//TestShot
Shot shot1; initializeShot(shot1);
Shot shot2; initializeShot(shot2);
shot1.Extrinsics.SetTra(Point3<double>(0,0,10));
shot2.Extrinsics.SetTra(Point3<double>(0,0,10));
shot1 = getShotFromTrack(shot1,&trackball);
shot2 = getShotFromTrack2(shot2, &trackball);
}
//Processing of tablet events, interesting only for painting plugins
@ -1022,3 +1032,108 @@ void GLArea::initGlobalParameterSet( RichParameterSet * defaultGlobalParamSet)
GLAreaSetting::initGlobalParameterSet(defaultGlobalParamSet);
}
void GLArea::initializeShot(Shot &shot)
{
//Da vedere
shot.Intrinsics.PixelSizeMm[0]=0.036916077;
shot.Intrinsics.PixelSizeMm[1]=0.036916077;
shot.Intrinsics.FocalMm= 27.846098; //per avere circa 60 gradi
shot.Intrinsics.DistorCenterPx[0]=width()/2;
shot.Intrinsics.DistorCenterPx[1]=height()/2;
shot.Intrinsics.CenterPx[0]=width()/2;
shot.Intrinsics.CenterPx[1]=height()/2;
shot.Intrinsics.ViewportPx[0]=width();
shot.Intrinsics.ViewportPx[1]=height();
shot.Extrinsics.SetIdentity();
//Shot newshot;
//vcg::Box3<double> box;
//box.Import(meshDoc->bbox());
//newshot.Extrinsics.SetIdentity();
//vcg::Point3d c = box.Center();
//vcg::Point3d v = c - vcg::Point3d(0, 0, 3*box.Diag());
//newshot.SetViewPoint(v);
//newshot.LookAt(c, vcg::Point3d(0, 1, 0));
//vcg::Camera<double> &cam = shot.Intrinsics;
//double dx = cam.ViewportPx[0]*cam.PixelSizeMm[0];
////if we have the focal we compute the angle (and viceversa)
//cout << "Focal: " << cam.FocalMm << endl;
//cout << "dx: " << dx << endl;
//double angle = 60.0;
//if(dx != 0 && cam.FocalMm != 0) { //we have the focal
// angle = atan(dx/cam.FocalMm)*180.0f/M_PI;
//} else if(dx != 0) {
// cam.FocalMm = dx/tan(angle*M_PI/180.0f);
//} else {
// cam.FocalMm = 60;
//}
//cout << "Angle: " << angle << endl;
//cout << "Focal: " << cam.FocalMm << endl;
//cout << endl;
//newshot.Intrinsics.SetPerspective(angle/2, width()/(double)height(), cam.FocalMm, vcg::Point2<int>(width(), height()));
//vcg::Camera<double> &cam1 = newshot.Intrinsics;
//double dx1 = cam.ViewportPx[0]*cam1.PixelSizeMm[0];
//cout << "Dx now: " << dx1 << " fcal: " << newshot.Intrinsics.FocalMm << endl;
//return newshot;
}
void GLArea::loadShot(){
//Shot test
Shot shot;
initializeShot(shot);
//oppure lo leggi da file
double viewportYMm=shot.Intrinsics.PixelSizeMm[1]*shot.Intrinsics.ViewportPx[1];
fov = 2*(vcg::math::ToDeg(atanf(viewportYMm/(2*shot.Intrinsics.FocalMm))));
/*fov=60;
float focal = viewportYMm/(2*tanf(vcg::math::ToRad(fov/2)));*/
// This parameter is the one that controls:
// HOW LARGE IS THE TRACKBALL ICON ON THE SCREEN.
float viewRatio = 1.75f;
float cameraDist = viewRatio / tanf(vcg::math::ToRad(fov*.5f));
//Esempi di shot di ingresso
//shot.Extrinsics.SetTra(Point3d(0, 0, cameraDist));
vcg::Matrix44d rot;
rot.Identity();
rot.SetRotateDeg(90,Point3<double>(0,1,0));
shot.Extrinsics.SetRot(rot);
shot.Extrinsics.SetTra(Inverse(rot)*Point3d(0, 0, cameraDist));
//correct the traslation introduced by gluLookAt() (0,0,cameraDist)---------------------------------------
//T(gl) S R T(t) => S R T(S^(-1) R^(-1)(gl) + t)
//Shot doesn't introduce scaling
//To compensate S^(-1) R^(-1)(gl)we add to t S^(-1) R^(-1)(-gl)
shot.Extrinsics.SetTra(shot.Extrinsics.Tra() + (Inverse(shot.Extrinsics.Rot())*Point3d(0, 0, -cameraDist)));
//reset trackball. The point of view must be set only by the shot
trackball.Reset();
float newScale= 3.0f/meshDoc->bbox().Diag();
trackball.track.sca = newScale;
trackball.track.tra = -meshDoc->bbox().Center();
Shot2Track(shot, cameraDist,trackball);
//Test on trackball
/*Matrix44f s_inv = Matrix44f().SetScale(1/trackball.track.sca, 1/trackball.track.sca, 1/trackball.track.sca);
vcg::Matrix44f rot_inv;
Inverse(trackball.track.rot).ToMatrix(rot_inv);
Shot2Track(shot, cameraDist,trackball);
trackball.track.tra += s_inv*rot_inv*Point3f(0, 0, cameraDist);*/
//Shot2Track(shot, cameraDist,trackball);
updateGL();
}

View File

@ -34,6 +34,8 @@
#include <wrap/gl/math.h>
#include <wrap/gl/trimesh.h>
#include <wrap/gui/trackball.h>
#include <vcg/math/shot.h>
#include <wrap/gl/shot.h>
#include "../common/interfaces.h"
#include "../common/filterscript.h"
@ -42,6 +44,9 @@
#include "viewer.h"
#include "multiViewer_Container.h"
//mathematics
#include <vcg/math/quaternion.h>
#define SSHOT_BYTES_PER_PIXEL 4
enum LightingModel{LDOUBLE,LFANCY};
@ -69,6 +74,8 @@ class GLArea : public QGLWidget, public Viewer
{
Q_OBJECT
typedef vcg::Shot<double> Shot;
public:
GLArea(QWidget *parent, MultiViewer_Container *mvcont, RichParameterSet *current, int id, MeshDocument *meshDoc);
~GLArea();
@ -127,6 +134,7 @@ public:
void setLightModel();
void setView();
void resetTrackBall();
void loadShot();
std::list<QAction *> iDecoratorsList;
void setRenderer(MeshRenderInterface *rend, QAction *shader){ iRenderer = rend; currentShader = shader;}
@ -309,7 +317,144 @@ private:
int tileCol, tileRow, totalCols, totalRows;
void setCursorTrack(vcg::TrackMode *tm);
void initializeShot(Shot &shot);
/*
Given a shot "refCamera" and a trackball "track", computes a new shot which is equivalent
to apply "refCamera" o "track".
*/
template <class T>
vcg::Shot<T> getShotFromTrack(vcg::Shot<T> &refCamera, vcg::Trackball *track){
vcg::Shot<T> view;
double _near, _far;
_near = 0.1;
_far = 100;
//get OpenGL modelview matrix after applying the trackball
GlShot<vcg::Shot<T> >::SetView(refCamera, _near, _far);
glPushMatrix();
track->GetView();
track->Apply();
vcg::Matrix44d model;
glGetv(GL_MODELVIEW_MATRIX, model);
glPopMatrix();
GlShot<vcg::Shot<T> >::UnsetView();
//get translation out of modelview
vcg::Point3d tra;
tra[0] = model[0][3]; tra[1] = model[1][3]; tra[2] = model[2][3];
model[0][3] = model[1][3] = model[2][3] = 0;
//get pure rotation out of modelview
double det = model.Determinant();
double idet = 1/pow(det, 1/3.0); //inverse of the determinant
model *= idet;
model[3][3] = 1;
view.Extrinsics.SetRot(model);
//get pure translation out of modelview
vcg::Matrix44d imodel = model;
vcg::Transpose(imodel);
tra = -(imodel*tra);
tra *= idet;
view.Extrinsics.SetTra(vcg::Point3<T>::Construct(tra));
//use same current intrinsics
view.Intrinsics = refCamera.Intrinsics;
return view;
}
/*
Given a shot "refCamera" and a trackball "track", computes a new shot which is equivalent
to apply "refCamera" o "track".
*/
template <class T>
vcg::Shot<T> getShotFromTrack2(vcg::Shot<T> &refCamera, vcg::Trackball *track){
vcg::Shot<T> view;
double _near, _far;
_near = 0.1;
_far = 100;
//---------------------- ALTERED--------------------
// //get OpenGL modelview matrix after applying the trackball
// GlShot<vcg::Shot<T> >::SetView(refCamera, _near, _far);
// glPushMatrix();
// track->GetView();
// track->Apply();
// vcg::Matrix44d model;
// glGetv(GL_MODELVIEW_MATRIX, model);
// glPopMatrix();
// GlShot<vcg::Shot<T> >::UnsetView();
//GlShot<vcg::Shot<T> >::SetView(refCamera, _near, _far); //mi serve per la proj di refcamera... altrimenti come la ottengo?
vcg::Matrix44f shotExtr;
refCamera.GetWorldToExtrinsicsMatrix().ToMatrix(shotExtr);
////legge la matrice di proj settata prima
//vcg::Matrix44f proj;
//glGetv(GL_PROJECTION_MATRIX,proj);
//GlShot<vcg::Shot<T> >::UnsetView();
////aggiorna la matrice di rototraslazione di track
//int viewport[] = {0,0,width(),height()};
//track->camera.SetView(proj.V(),shotExtr.V(), viewport);
vcg::Matrix44f model2;
model2 = (shotExtr)* track->Matrix();
vcg::Matrix44d model;
model2.ToMatrix(model);
//---------------------- ORIGINAL--------------------
//get translation out of modelview
vcg::Point3d tra;
tra[0] = model[0][3]; tra[1] = model[1][3]; tra[2] = model[2][3];
model[0][3] = model[1][3] = model[2][3] = 0;
//get pure rotation out of modelview
double det = model.Determinant();
double idet = 1/pow(det, 1/3.0); //inverse of the determinant
model *= idet;
model[3][3] = 1;
view.Extrinsics.SetRot(model);
//get pure translation out of modelview
vcg::Matrix44d imodel = model;
vcg::Transpose(imodel);
tra = -(imodel*tra);
tra *= idet;
view.Extrinsics.SetTra(vcg::Point3<T>::Construct(tra));
//use same current intrinsics
view.Intrinsics = refCamera.Intrinsics;
return view;
}
/*
Given a Shot "from", and a trackball "tb" replaces "tb" with a trackball "tb'" such that:
"from" o "tb" = "tb'"
*/
template <class T>
void Shot2Track(const vcg::Shot<T> &from, const float cameraDist, vcg::Trackball &tb){
Shot id;
vcg::Quaterniond qto; qto.FromMatrix(id.Extrinsics.Rot());
vcg::Quaterniond qfrom; qfrom.FromMatrix(from.Extrinsics.Rot());
/*float sca=tb.track.sca;
tb.track.sca=1;*/
tb.track.tra += ( tb.track.rot.Inverse().Rotate( vcg::Point3f::Construct(-from.Extrinsics.Tra()) + tb.center ) ) / tb.track.sca;
tb.track.rot = vcg::Quaternionf::Construct(qto.Inverse() * qfrom) * tb.track.rot;
tb.track.tra -= ( tb.track.rot.Inverse().Rotate( vcg::Point3f::Construct(- id.Extrinsics.Tra()) + tb.center ) ) / tb.track.sca;
//aggiustare sca e tra per mettere il centro della trackbal al punto giusto
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -110,6 +110,7 @@ private slots:
void toggleBackFaceCulling();
void toggleSelectFaceRendering();
void toggleSelectVertRendering();
void loadShot();
//void applyDecorateMode();
///////////Slot Menu View ////////////////////////
void fullScreen();
@ -296,6 +297,8 @@ private:
QAction *colorModePerMeshAct;
QAction *colorModePerVertexAct;
QAction *colorModePerFaceAct;
QAction *loadShotAct;
///////////Actions Menu View ////////////////////////
QAction *fullScreenAct;
QAction *showToolbarStandardAct;

View File

@ -205,6 +205,12 @@ void MainWindow::createActions()
setSelectVertRenderingAct->setShortcutContext(Qt::ApplicationShortcut);
connect(setSelectVertRenderingAct, SIGNAL(triggered()), this, SLOT(toggleSelectVertRendering()));
loadShotAct = new QAction(QIcon(":/images/camera.png"),tr("Load Shot"),this);
loadShotAct->setCheckable(false);
loadShotAct->setShortcutContext(Qt::ApplicationShortcut);
loadShotAct->setShortcut(Qt::CTRL+Qt::Key_W);
connect(loadShotAct, SIGNAL(triggered()), this, SLOT(loadShot()));
//////////////Action Menu View ////////////////////////////////////////////////////////////////////////////
fullScreenAct = new QAction (tr("&FullScreen"), this);
fullScreenAct->setCheckable(true);
@ -324,8 +330,10 @@ void MainWindow::createToolBars()
renderToolBar->addActions(renderModeGroupAct->actions());
renderToolBar->addAction(renderModeTextureAct);
renderToolBar->addAction(setLightAct);
renderToolBar->addAction(setSelectFaceRenderingAct);
renderToolBar->addAction(setSelectVertRenderingAct);
renderToolBar->addAction(setSelectFaceRenderingAct);
renderToolBar->addAction(setSelectVertRenderingAct);
renderToolBar->addAction(loadShotAct);
/*editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(suspendEditModeAct);
@ -439,6 +447,9 @@ void MainWindow::createMenus()
renderMenu->addSeparator();
//Shot SUBmenu
renderMenu ->addAction(loadShotAct);
//////////////////// Menu View ////////////////////////////////////////////////////////////////////////////
viewMenu = menuBar()->addMenu(tr("&View"));
viewMenu->addAction(fullScreenAct);

View File

@ -1172,6 +1172,8 @@ void MainWindow::setUnsplit()
updateMenus();
}
void MainWindow::loadShot() { GLA()->loadShot(); }
void MainWindow::renderBbox() { GLA()->setDrawMode(GLW::DMBox ); }
void MainWindow::renderPoint() { GLA()->setDrawMode(GLW::DMPoints ); }
void MainWindow::renderWire() { GLA()->setDrawMode(GLW::DMWire ); }

View File

@ -2,6 +2,7 @@
<qresource prefix="/">
<file>images/backlines.png</file>
<file>images/bbox.png</file>
<file>images/camera.png</file>
<file>images/cursors/plain.png</file>
<file>images/cursors/plain_pan.png</file>
<file>images/cursors/plain_trackball.png</file>