vcglib/wrap/gl/shot.h

240 lines
7.6 KiB
C++

/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.12 2006/12/18 16:02:57 matteodelle
minor eroor correction on variable names
Revision 1.11 2006/12/18 15:26:24 callieri
added a function to approximate a far plane value given a shot and the mesh bbox
Revision 1.10 2006/12/18 14:28:07 matteodelle
*** empty log message ***
Revision 1.9 2006/12/18 09:46:39 callieri
camera+shot revamp: changed field names to something with more sense, cleaning of various functions, correction of minor bugs/incongruences, removal of the infamous reference in shot.
Revision 1.8 2006/01/11 16:06:25 matteodelle
*** empty log message ***
Revision 1.8 2005/01/11 17:06:30 dellepiane
FromTrackball() coorected (similarity->Extrinsics
Revision 1.7 2005/11/25 10:33:33 spinelli
shot.camera -> shot.Intrinsics
shot.similarity.Matrix() -> shot.Extrinsics.Matrix()
Revision 1.6 2005/02/22 11:15:01 ganovelli
added vcg namespace
Revision 1.5 2005/02/11 11:43:09 tommyfranken
FromTrackball() corrected
Revision 1.4 2004/12/15 18:45:06 tommyfranken
*** empty log message ***
Revision 1.3 2004/11/03 09:41:57 ganovelli
added FromTrackball and fixed include names (Poiint to point)
Revision 1.2 2004/10/05 19:04:45 ganovelli
changed from classes to functions
Revision 1.1 2004/09/15 22:59:13 ganovelli
creation
Revision 1.2 2004/09/06 21:41:30 ganovelli
*** empty log message ***
Revision 1.1 2004/09/03 13:01:51 ganovelli
creation
****************************************************************************/
#ifndef __VCGLIB_GLSHOT
#define __VCGLIB_GLSHOT
// include vcg stuff
#include <vcg/space/point2.h>
#include <vcg/space/point3.h>
#include <vcg/math/similarity.h>
#include <vcg/math/shot.h>
// include wrap stuff
#include <wrap/gui/trackball.h>
#include <wrap/gl/math.h>
#include <wrap/gl/camera.h>
template <class ShotType>
struct GlShot {
typedef typename ShotType::ScalarType ScalarType;
typedef GlCamera<typename ShotType::CameraType> GlCameraType;
/// returns the OpenGL 4x4 MODELVIEW matrix that describes the shot position and orientation (extrinsics)
static void MatrixGL(ShotType & shot,vcg::Matrix44<ScalarType> & m)
{
m = shot.GetWorldToExtrinsicsMatrix();
}
/// set the OpenGL MODELVIEW matrix to match the shot (extrinsics)
static void TransformGL(vcg::Shot<ScalarType> & shot)
{
vcg::Matrix44<ScalarType> m;
MatrixGL(shot,m);
glMultMatrix(m);
}
/// set the OpenGL PROJECTION and MODELVIEW matrix to match camera+shot. requires near and far plane
static void SetView(vcg::Shot<ScalarType> & shot, ScalarType nearDist, ScalarType farDist)
{
assert(glGetError() == 0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
assert(glGetError() == 0);
GlCameraType::TransformGL(shot.Intrinsics, nearDist, farDist); // apply camera/projection transformation
assert(glGetError() == 0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
GlShot<ShotType>::TransformGL(shot); // apply similarity/modelview transformation
assert(glGetError() == 0);
}
/// restore the previous OpenGL modelview and projection state. to be called AFTER a SetView
static void UnsetView()
{
glPushAttrib(GL_TRANSFORM_BIT);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
}
/// given a shot and the mesh bounding box, returns an approximate far plane distance
/// distance is always approximated by excess
static ScalarType GetFarPlane(vcg::Shot<ScalarType> & shot, vcg::Box3<ScalarType> bbox)
{
ScalarType farDist;
vcg::Point3<ScalarType> farcorner;
vcg::Point3<ScalarType> campos = shot.Extrinsics.Tra();
if (abs(campos.X() - bbox.max.X()) > abs(campos.X() - bbox.min.X()))
farcorner.X() = bbox.max.X();
else
farcorner.X() = bbox.min.X();
if (abs(campos.Y() - bbox.max.Y()) > abs(campos.Y() - bbox.min.Y()))
farcorner.Y() = bbox.max.Y();
else
farcorner.Y() = bbox.min.Y();
if (abs(campos.Z() - bbox.max.Z()) > abs(campos.Z() - bbox.min.Z()))
farcorner.Z() = bbox.max.Z();
else
farcorner.Z() = bbox.min.Z();
farDist = (campos - farcorner).Norm();
return farDist;
}
/// given a shot and the mesh bounding box, return near and far plane (exact)
static void GetNearFarPlanes(vcg::Shot<ScalarType> & shot, vcg::Box3<ScalarType> bbox, ScalarType &nr, ScalarType &fr)
{
vcg::Point3<ScalarType> zaxis = shot.Axis(2);
ScalarType offset = zaxis * shot.GetViewPoint();
bool first = true;
for(int i = 0; i < 8; i++) {
vcg::Point3<ScalarType> c = bbox.P(i);
ScalarType d = -(zaxis * c - offset);
if(first || d < nr) {
nr = d;
first = false;
}
if(first || d > fr) {
fr = d;
first = false;
}
}
}
static void SetSubView(vcg::Shot<ScalarType> & shot,
vcg::Point2<ScalarType> p1,
vcg::Point2<ScalarType> p2)
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
assert(glGetError() == 0);
GlCameraType::SetSubView(shot.Intrinsics,p1,0,1000,p2);
assert(glGetError() == 0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
GlShot<ShotType>::TransformGL(shot); // apply similarity/modelview transformation
assert(glGetError() == 0);
}
/**********************************
DEFINE SHOT FROM TRACKBALL
Adds to a given shot the trackball transformations.
After this operation the trackball should be resetted, to avoid
multiple apply of the same transformation.
***********************************/
static void FromTrackball(const vcg::Trackball & tr,
vcg::Shot<ScalarType> & sShot,
vcg::Shot<ScalarType> & shot )
{
vcg::Point3<ScalarType> cen; cen.Import(tr.center);
vcg::Point3<ScalarType> tra; tra.Import(tr.track.tra);
vcg::Matrix44<ScalarType> trM; trM.FromMatrix(tr.track.Matrix());
vcg::Point3<ScalarType> vp = Inverse(trM)*(sShot.GetViewPoint()-cen) +cen +tra;
shot.SetViewPoint(vp);
shot.Extrinsics.SetRot(sShot.Extrinsics.Rot()*trM);
// shot.Extrinsics.sca = sShot.Extrinsics.sca*(ScalarType)tr.track.sca;
}
};
#endif