Restructured and adapted in a better way to opengl
This commit is contained in:
parent
ab4f6f00ef
commit
6df79edd1f
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.4 2004/04/07 10:54:10 cignoni
|
||||
Commented out unused parameter names and other minor warning related issues
|
||||
|
||||
Revision 1.3 2004/03/31 15:08:03 ponchio
|
||||
Fixed current_action initialization.
|
||||
|
||||
|
@ -33,16 +36,21 @@ Adding copyright.
|
|||
|
||||
****************************************************************************/
|
||||
|
||||
#include <gl/glew.h>
|
||||
|
||||
#include "trackball.h"
|
||||
|
||||
#include <wrap/gl/math.h>
|
||||
#include <wrap/gl/space.h>
|
||||
using namespace vcg;
|
||||
|
||||
#include <iostream> //debug!
|
||||
using namespace std;
|
||||
|
||||
Transform::Transform() {
|
||||
local.SetIdentity();
|
||||
track.SetIdentity();
|
||||
radius=1.0f;
|
||||
center=Point3f(0,0,0);
|
||||
}
|
||||
|
||||
Trackball::Trackball(): current_button(0), last_x(-1), last_y(-1), dragging(false),
|
||||
|
@ -57,12 +65,11 @@ Trackball::Trackball(): current_button(0), last_x(-1), last_y(-1), dragging(fals
|
|||
}
|
||||
|
||||
void Trackball::SetIdentity() {
|
||||
local.SetIdentity();
|
||||
track.SetIdentity();
|
||||
Reset();
|
||||
}
|
||||
void Trackball::SetPosition(const Similarityf &m, int /* millisec */) {
|
||||
local = m;
|
||||
//millisec ignored at the moment.
|
||||
void Trackball::SetPosition(const Point3f &c, int /* millisec */) {
|
||||
center = c;
|
||||
}
|
||||
|
||||
//operating
|
||||
|
@ -70,13 +77,15 @@ void Trackball::GetView() {
|
|||
camera.GetView();
|
||||
|
||||
//lets get view matrix
|
||||
Similarityf m = local * last_track;
|
||||
Point3f c_obj = Point3f(0, 0, 0) * m; //coordinate of the center of the trackball in obj coords
|
||||
Point3f c_view = camera.Project(c_obj); //center of the trackball in screen coords.
|
||||
Similarityf m = last_track;
|
||||
Point3f c_obj = m*center; //coordinate of the center of the trackball in obj coords
|
||||
ScreenCenter = camera.Project(c_obj); //center of the trackball in screen coords.
|
||||
ScreenRadius = 10.0f/Distance(center, camera.UnProject(Point3f(ScreenCenter[0] + 10, ScreenCenter[1], ScreenCenter[2])));
|
||||
|
||||
Point3f X, Y, Z, C;
|
||||
X = camera.UnProject(Point3f(c_view[0] + 100, c_view[1], c_view[2]));
|
||||
Y = camera.UnProject(Point3f(c_view[0], c_view[1] - 100, c_view[2]));
|
||||
Z = camera.UnProject(Point3f(c_view[0], c_view[1], c_view[2] + 0.1f));
|
||||
X = camera.UnProject(Point3f(ScreenCenter[0] + 100, ScreenCenter[1], ScreenCenter[2]));
|
||||
Y = camera.UnProject(Point3f(ScreenCenter[0], ScreenCenter[1] - 100, ScreenCenter[2]));
|
||||
Z = camera.UnProject(Point3f(ScreenCenter[0], ScreenCenter[1], ScreenCenter[2] + 0.1f));
|
||||
C = c_obj;
|
||||
X = X - C; X.Normalize();
|
||||
Y = Y - C; Y.Normalize();
|
||||
|
@ -93,30 +102,124 @@ void Trackball::GetView() {
|
|||
//spinning ignored
|
||||
}
|
||||
void Trackball::Apply() {
|
||||
Matrix44f a = track.Matrix();
|
||||
//Transpose(a);
|
||||
glMultMatrix(a);
|
||||
//glMultMatrix(track.Matrix());
|
||||
//glMultMatrix(track);
|
||||
glMultMatrix(track.Matrix());
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
void Trackball::DrawCircle()
|
||||
{
|
||||
const int nside=18;
|
||||
const double pi2=3.14159265*2.0;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for(double i=0;i<=nside;i++){
|
||||
glNormal3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0);
|
||||
glVertex3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0);
|
||||
}
|
||||
glEnd();
|
||||
DrawPlaneHandle();
|
||||
}
|
||||
|
||||
void Trackball::DrawPlane()
|
||||
{
|
||||
const int nl=10;
|
||||
float w=5.0f/3.0f;
|
||||
float u;
|
||||
glBegin(GL_LINES);
|
||||
glNormal3f(0.0,0.0,1.0);
|
||||
for( u=-w; u<=w+0.01f; u+=2*w/nl){
|
||||
glVertex3f(-w, +u, 0);
|
||||
glVertex3f(+w, +u, 0);
|
||||
glVertex3f(+u, -w, 0);
|
||||
glVertex3f(+u, +w, 0);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void Trackball::DrawPlaneHandle()
|
||||
{
|
||||
float r=1.0;
|
||||
float dr=r/10.0f;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(+r+dr, +r, 0.0);
|
||||
glVertex3f(+r , +r+dr,0.0);
|
||||
glVertex3f(+r-dr, +r, 0.0);
|
||||
glVertex3f(+r , +r-dr,0.0);
|
||||
glVertex3f(+r+dr, +r, 0.0);
|
||||
glEnd();
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(-r+dr, -r, 0.0);
|
||||
glVertex3f(-r , -r+dr,0.0);
|
||||
glVertex3f(-r-dr, -r, 0.0);
|
||||
glVertex3f(-r , -r-dr,0.0);
|
||||
glVertex3f(-r+dr, -r, 0.0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void Trackball::Draw() {
|
||||
glPushMatrix();
|
||||
glMultMatrix(local.Matrix());
|
||||
//Disegnamo un cubo:
|
||||
glColor3f(1, 0, 0);
|
||||
glScalef(0.5, 0.5, 0.5);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(-1, -1, -1);
|
||||
glVertex3f( 1, -1, -1);
|
||||
glVertex3f( 1, 1, -1);
|
||||
glVertex3f(-1, 1, -1);
|
||||
glVertex3f(-1, 1, 1);
|
||||
glVertex3f( 1, 1, 1);
|
||||
glVertex3f( 1, -1, 1);
|
||||
glVertex3f(-1, -1, 1);
|
||||
glVertex3f(-1, -1, 1);
|
||||
glEnd();
|
||||
glTranslate(center);
|
||||
glScalef(radius,radius,radius);
|
||||
|
||||
/// Here start the real drawing stuff
|
||||
|
||||
float amb[4] ={.3f,.3f,.3f,1.0f};
|
||||
float col[4] ={.5f,.5f,.8f,1.0f};
|
||||
float col2[4]={.9f,.9f,1.0f,1.0f};
|
||||
glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT);
|
||||
glLineWidth(2.0);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,amb);
|
||||
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,col);
|
||||
glPushMatrix();
|
||||
DrawCircle();
|
||||
glPushMatrix();
|
||||
glRotatef(90,1,0,0);
|
||||
DrawCircle();
|
||||
glRotatef(90,0,1,0);
|
||||
DrawCircle();
|
||||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
glColor4f(1.0,.8f,.8f,1.0f);
|
||||
if(current_action.motion==ROTATE_X || current_action.motion==ROTATE_Y || current_action.motion==ROTATE_Z ){
|
||||
//Point3d raxt(0,0,0),rax;// compute the rotation axis
|
||||
//raxt[current_action.motion-ROTATE_X]=1;
|
||||
//RotM.Apply(rax,raxt);
|
||||
//
|
||||
//glDisable(GL_LIGHTING);
|
||||
//glBegin(GL_LINE_STRIP);
|
||||
// glVertex(Manip.c-raxt*TrackballRadius*1.3);
|
||||
// glVertex(Manip.c+raxt*TrackballRadius*1.3);
|
||||
//glEnd();
|
||||
}
|
||||
glPopAttrib();
|
||||
|
||||
if(current_action.motion==DRAG_XY) {
|
||||
glPushMatrix();
|
||||
//glTranslate(Manip.c);
|
||||
DrawPlane();
|
||||
glPopMatrix();
|
||||
}
|
||||
if(current_action.motion==DRAG_XZ) {
|
||||
glPushMatrix();
|
||||
//glTranslate(Manip.c);
|
||||
glRotatef(90,1,0,0);
|
||||
DrawPlane();
|
||||
glPopMatrix();
|
||||
}
|
||||
if(current_action.motion==DRAG_YZ) {
|
||||
glPushMatrix();
|
||||
//glTranslate(Manip.c);
|
||||
glRotatef(90,0,1,0);
|
||||
DrawPlane();
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
@ -140,32 +243,14 @@ void Trackball::MouseMove(int x, int y) {
|
|||
return;
|
||||
}
|
||||
|
||||
Point3f origin = camera.ViewportToScreen(ScreenOrigin());
|
||||
Point3f new_point = camera.ViewportToScreen(Point3f(float(x), float(y), 0)) - origin;
|
||||
Point3f old_point = camera.ViewportToScreen(Point3f(float(last_x), float(last_y), 0)) - origin;
|
||||
new_point *= 2;
|
||||
old_point *= 2;
|
||||
|
||||
Similarityf u;
|
||||
TrackMode *mode = CurrentMode();
|
||||
Similarityf new_track = mode->Apply(new_point, u);
|
||||
Similarityf old_track = mode->Apply(old_point, u);
|
||||
delete mode;
|
||||
mode->tb=this;
|
||||
|
||||
Invert(old_track);
|
||||
new_track = old_track * new_track;
|
||||
|
||||
Similarityf diff;
|
||||
switch(current_action.system) {
|
||||
case VIEW:
|
||||
u = last_view * Similarityf((-local.tra) * Similarityf(last_track.rot)) * Similarityf(-last_track.tra);
|
||||
diff = Inverse(u) * new_track * u;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
track = diff * last_track;
|
||||
Point3f new_point = Point3f(float(x), float(y), 0);
|
||||
Point3f old_point = Point3f(float(last_x), float(last_y), 0);
|
||||
Similarityf diff=mode->ComputeFromWindow(old_point,new_point);
|
||||
|
||||
track = last_track*diff;
|
||||
}
|
||||
|
||||
void Trackball::MouseUp(int /* x */, int /* y */, Trackball::Button button) {
|
||||
|
@ -240,24 +325,24 @@ TrackMode *Trackball::CurrentMode() {
|
|||
}
|
||||
return mode;
|
||||
}
|
||||
//return center of trackball in Screen coordinates.
|
||||
Point3f Trackball::ScreenOrigin() {
|
||||
return camera.Project(ModelOrigin());
|
||||
}
|
||||
////return center of trackball in Window coordinates.
|
||||
//Point3f Trackball::ScreenOrigin() {
|
||||
// return camera.Project(ModelOrigin());
|
||||
//}
|
||||
|
||||
|
||||
//return center of trackball in Model coordinates
|
||||
Point3f Trackball::ModelOrigin() {
|
||||
Similarityf m = local * last_track;
|
||||
return Point3f(0, 0, 0) * m;
|
||||
return center;
|
||||
}
|
||||
|
||||
Matrix44f Trackball::ScreenToModel() {
|
||||
return camera.inverse;
|
||||
}
|
||||
|
||||
Similarityf Trackball::ModelToLocal() {
|
||||
Similarityf m = local * last_track;
|
||||
return m;
|
||||
}
|
||||
//Matrix44f Trackball::ScreenToModel() {
|
||||
// return camera.inverse;
|
||||
//}
|
||||
//
|
||||
//Similarityf Trackball::ModelToLocal() {
|
||||
// Similarityf m = local * last_track;
|
||||
// return m;
|
||||
//}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* VCGLib o o *
|
||||
* Visual and Computer Graphics Library o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2004 \/)\/ *
|
||||
* Copyright(C) 2004
|
||||
\/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
|
@ -24,6 +25,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.3 2004/04/07 10:54:10 cignoni
|
||||
Commented out unused parameter names and other minor warning related issues
|
||||
|
||||
Revision 1.2 2004/03/25 14:55:25 ponchio
|
||||
Adding copyright.
|
||||
|
||||
|
@ -40,16 +44,27 @@ Adding copyright.
|
|||
#include <map>
|
||||
|
||||
namespace vcg {
|
||||
/* A trackball stores two transformations
|
||||
the first one, local, is the one 'placing' the trackball somewhere,
|
||||
the second one, track, is the one that effectively rotate the object.
|
||||
|
||||
The 'local' transformation is the one that contains information about
|
||||
the rotation center, the size and the orientation of the trackball.
|
||||
the 'track' is the one implementing the effective transformation.
|
||||
|
||||
*/
|
||||
class Transform {
|
||||
public:
|
||||
Transform();
|
||||
Similarityf track;
|
||||
Similarityf local;
|
||||
|
||||
Point3f center; // la posizione della trackball nello spazio di modello. il defgault e' 000
|
||||
float radius; /// size of the widget in spazio di modello.
|
||||
//Quaternion orientation;
|
||||
};
|
||||
|
||||
Transform interpolate(const Transform &a, const Transform &b, float t);
|
||||
|
||||
class TrackMode;
|
||||
class Trackball: public Transform {
|
||||
public:
|
||||
enum Button { BUTTON_NONE = 0x0000,
|
||||
|
@ -64,8 +79,10 @@ public:
|
|||
|
||||
Trackball();
|
||||
void SetIdentity();
|
||||
void SetPosition(const Similarityf &local, int millisec = 0);
|
||||
void SetPosition(const Point3f &c, int millisec = 0);
|
||||
void SetScale(const float s) {radius=s;};
|
||||
void SetTransform(const Transform &transform, int miilisec = 0);
|
||||
// float ScreenScale();
|
||||
|
||||
//operating
|
||||
void GetView();
|
||||
|
@ -73,6 +90,12 @@ public:
|
|||
void Draw();
|
||||
void Reset();
|
||||
|
||||
// Internal Drawing stuff
|
||||
void DrawCircle ();
|
||||
void DrawPlane();
|
||||
void DrawPlaneHandle();
|
||||
|
||||
|
||||
//interface
|
||||
void MouseDown(int x, int y, Button button);
|
||||
void MouseMove(int x, int y);
|
||||
|
@ -120,10 +143,13 @@ public:
|
|||
///Find the current action ussing the current button
|
||||
void SetCurrentAction();
|
||||
|
||||
protected:
|
||||
//protected:
|
||||
View<float> camera;
|
||||
Similarityf view; //Rotate LOCAL coordinate into VIEW coordinates
|
||||
|
||||
float ScreenRadius;
|
||||
Point3f ScreenCenter;
|
||||
|
||||
int current_button;
|
||||
Action current_action;
|
||||
|
||||
|
@ -144,7 +170,7 @@ protected:
|
|||
int history_size;
|
||||
|
||||
|
||||
Point3f ScreenOrigin(); //center of trackball in Screen coord
|
||||
//Point3f ScreenOrigin(); //center of trackball in Screen coord
|
||||
Point3f ModelOrigin(); //center of trackball in Model coord
|
||||
|
||||
Matrix44f ScreenToModel(); //forse non serve.....
|
||||
|
|
|
@ -24,81 +24,116 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.3 2004/04/07 10:54:11 cignoni
|
||||
Commented out unused parameter names and other minor warning related issues
|
||||
|
||||
Revision 1.2 2004/03/25 14:55:25 ponchio
|
||||
Adding copyright.
|
||||
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "trackmode.h"
|
||||
#include <vcg/space/point2.h>
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/space/plane3.h>
|
||||
#include <vcg/space/intersection3.h>
|
||||
#include "trackmode.h"
|
||||
#include <vcg/math/similarity.h>
|
||||
|
||||
using namespace vcg;
|
||||
|
||||
Similarityf SphereMode::Apply(const Point3f &p, const Similarityf & /* m */) {
|
||||
float u = p[0];
|
||||
float w = p[1];
|
||||
float thr = 1/math::Sqrt(2.0f); //in the plane x-y distance from origin, above this use hyperboloid
|
||||
|
||||
float dist = math::Sqrt(u * u + w * w);
|
||||
Point3f result;
|
||||
if(dist < thr) { // First case: The ray is nearer to the sphere than r/sqrt(2)
|
||||
float z = math::Sqrt(1 - u * u - w* w);
|
||||
result = Point3f(u, w, z);
|
||||
} else { // Second case: The ray should hit the 1/d hyperboloid
|
||||
float a = thr;
|
||||
result = Point3f(u, w, -a*(u*u + w * w) + 3*a/2);
|
||||
result.Normalize();
|
||||
|
||||
|
||||
/*
|
||||
Le varie Apply prendono una coppia di punti in screen space e restituiscono una trasformazione
|
||||
*/
|
||||
|
||||
Plane3f SphereMode::GetViewPlane()
|
||||
{
|
||||
Point3f mo=tb->ModelOrigin();
|
||||
Point3f vp; vp.Import(tb->camera.ViewPoint());
|
||||
Plane3f pl; // plane perpedicular to view direction and passing through manip center
|
||||
pl.Set(vp-tb->center, (vp-tb->center)*tb->center);
|
||||
return pl;
|
||||
}
|
||||
if(result == Point3f(0, 0, 1))
|
||||
|
||||
|
||||
|
||||
/* dato un punto in coordinate di schermo e.g. in pixel stile opengl
|
||||
restituisce un punto in coordinate di mondo sulla superficie della trackball
|
||||
La superficie della trackball e' data da una sfera + una porzione di iperboloide di rotazione
|
||||
assumiamo la sfera di raggio unitario e centrata sull'origine e di guardare lungo la y negativa.
|
||||
X 0 sqrt(1/2) 1
|
||||
eq sfera: y=sqrt(1-x*x); 1 sqrt(1/2) 0
|
||||
eq iperboloide : y=1/2x; inf sqrt(1/2) 1/2
|
||||
|
||||
*/
|
||||
|
||||
Point3f SphereMode::Hit(const Point3f &p)
|
||||
{
|
||||
printf("Hit in screen space at %5.3f %5.3f %5.3f\n",p[0],p[1],p[2]);
|
||||
|
||||
Plane3f vp=GetViewPlane(); // plane perpedicular to view direction and passing through manip center
|
||||
Line3fN ln= tb->camera.ViewLineFromWindow(Point3f(p[0],p[1],0));
|
||||
//Point3f P0,P1;
|
||||
Point3f PonVP;
|
||||
bool res=Intersection<float>(vp,ln,PonVP);
|
||||
const float Thr=tb->radius/math::Sqrt(2.0f);
|
||||
|
||||
Point3f HitPoint;
|
||||
float dd=Distance(tb->center,PonVP);
|
||||
if(dd<Thr)
|
||||
{ // First case: We hit the sphere so, we must set the z accordingly
|
||||
float hh=math::Sqrt(tb->radius*tb->radius - dd*dd);
|
||||
HitPoint=PonVP+ln.Direction()*hh;
|
||||
printf("Hit the sphere point on plane is %5.3f %5.3f %5.3f\n",PonVP[0],PonVP[1],PonVP[2]);
|
||||
printf(" Distance from center is %5.3f \n",dd);
|
||||
printf(" Heigth for view plane should be %5.3f \n",hh );
|
||||
}
|
||||
else
|
||||
{ // Second Case we hit the hyperboloid
|
||||
float hh=tb->radius/(2.0f*(dd/tb->radius));
|
||||
HitPoint=PonVP+ln.Direction()*hh;
|
||||
|
||||
printf("Hit the hiperboloid at %5.3f %5.3f %5.3f\n",PonVP[0],PonVP[1],PonVP[2]);
|
||||
printf(" Distance from center is %5.3f \n",dd);
|
||||
printf(" Heigth for view plane should be %5.3f \n",hh );
|
||||
|
||||
}
|
||||
return HitPoint;
|
||||
}
|
||||
|
||||
/*
|
||||
Nella trackball classica si considera
|
||||
|
||||
*/
|
||||
Similarityf PlaneMode::ComputeFromWindow(const Point3f &oldP, const Point3f &newP)
|
||||
{
|
||||
return Similarityf().SetIdentity();
|
||||
}
|
||||
/*
|
||||
Restituisce la trasformazione originata dal drag in window coord da oldp a newp.
|
||||
*/
|
||||
Similarityf SphereMode::ComputeFromWindow(const Point3f &oldP, const Point3f &newP)
|
||||
{
|
||||
Point3f hitOld=Hit(oldP);
|
||||
Point3f hitNew=Hit(newP);
|
||||
// Now compute the rotation defined on the sphere...
|
||||
|
||||
Point3f norm;
|
||||
|
||||
return Similarityf().SetIdentity();
|
||||
|
||||
Point3f axis = Point3f(0, 0, 1)^result; /* Axis of rotation */
|
||||
axis.Normalize();
|
||||
Point3f d = result - Point3f(0, 0, 1);
|
||||
float t = d.Norm() / 2.0f;
|
||||
if(t > thr)
|
||||
t += (t - thr) * 0.7f;
|
||||
if (t > 1.0f) t = 1.0f;
|
||||
if (t < -1.0f) t = -1.0f;
|
||||
float phi = 2 * math::Asin(t);
|
||||
//return Similarityf().SetRotate(phi * 180/(float)M_PI, axis);
|
||||
return Similarityf().SetRotate(phi, axis);
|
||||
}
|
||||
|
||||
Similarityf PlaneMode::Apply(const Point3f &p, const Similarityf &a) {
|
||||
return Similarityf(Point3f(p[0], p[1], 0));
|
||||
Point3f r = x * a;
|
||||
Point3f u = y * a;
|
||||
int leading = 0; //leadiing x.
|
||||
if(fabs(u[2]) < fabs(r[2])) //sceglie l'asse principale: quello che piu' e' parallelo al piano di vista.
|
||||
leading = 1;
|
||||
r[2] = 0;
|
||||
u[2] = 0;
|
||||
if(r == Point3f(0,0,0)) //casi degeneri: un asse e' perpendicolare al piano di vista.
|
||||
r = Point3f(0, 1, 0);
|
||||
if(u == Point3f(0,0,0))
|
||||
u = Point3f(0, 1, 0);
|
||||
r.Normalize();
|
||||
u.Normalize();
|
||||
float cu, cr;
|
||||
if(leading == 0) { //leading x
|
||||
if(u == r || u == -r) { //caso degenere: i due assi si proiettano sullo stesso
|
||||
u[0] = -r[1];
|
||||
u[1] = r[0];
|
||||
}
|
||||
u = u - r * (r * u);
|
||||
u.Normalize();
|
||||
} else {
|
||||
if(r == u || r == -u) { //caso degenere: i due assi si proiettano sullo stesso
|
||||
r[0] = -u[1];
|
||||
r[1] = u[0];
|
||||
}
|
||||
r = r - u * (u * r);
|
||||
r.Normalize();
|
||||
}
|
||||
cr = r * p;
|
||||
cu = u * p;
|
||||
return Similarityf(x * cr + y * cu);
|
||||
//Point3f axis = Point3f(0, 0, 1)^result; /* Axis of rotation */
|
||||
//axis.Normalize();
|
||||
//Point3f d = result - Point3f(0, 0, 1);
|
||||
//float t = d.Norm() / 2.0f;
|
||||
//if(t > thr)
|
||||
// t += (t - thr) * 0.7f;
|
||||
//if (t > 1.0f) t = 1.0f;
|
||||
//if (t < -1.0f) t = -1.0f;
|
||||
// float phi = 2 * math::Asin(t);
|
||||
////return Similarityf().SetRotate(phi * 180/(float)M_PI, axis);
|
||||
// return Similarityf().SetRotate(phi, axis);
|
||||
}
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.3 2004/04/07 10:54:11 cignoni
|
||||
Commented out unused parameter names and other minor warning related issues
|
||||
|
||||
Revision 1.2 2004/03/25 14:55:25 ponchio
|
||||
Adding copyright.
|
||||
|
||||
|
@ -35,19 +38,28 @@ Adding copyright.
|
|||
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/math/similarity.h>
|
||||
#include <wrap/gui/trackball.h>
|
||||
|
||||
namespace vcg {
|
||||
|
||||
class Trackball;
|
||||
class TrackMode {
|
||||
public:
|
||||
virtual ~TrackMode() {}
|
||||
virtual void Draw() {}
|
||||
virtual Similarityf Apply(const Point3f &/* p */, const Similarityf &/*a*/) { return Similarityf().SetIdentity(); }
|
||||
//virtual void Draw() {}
|
||||
virtual Similarityf ComputeFromWindow(const Point3f &/* oldp */, const Point3f &/* newp */) { return Similarityf().SetIdentity(); }
|
||||
Point3f Hit(const Point3f &p);
|
||||
Trackball *tb;
|
||||
|
||||
};
|
||||
|
||||
class SphereMode: public TrackMode {
|
||||
public:
|
||||
Similarityf Apply(const Point3f &p, const Similarityf &/*a*/);
|
||||
Similarityf ComputeFromWindow(const Point3f &oldP, const Point3f &newP);
|
||||
//Plane3f SetViewPlane();
|
||||
Point3f Hit(const Point3f &p);
|
||||
Plane3f GetViewPlane();
|
||||
// Line3f GetViewLine(const Point3f &p);
|
||||
|
||||
};
|
||||
|
||||
class GravityMode: public TrackMode {
|
||||
|
@ -64,7 +76,7 @@ protected:
|
|||
class PlaneMode: public TrackMode {
|
||||
public:
|
||||
PlaneMode(const Point3f _x, const Point3f _y): x(_x), y(_y) { x.Normalize(); y.Normalize(); }
|
||||
Similarityf Apply(const Point3f &p, const Similarityf &a);
|
||||
Similarityf ComputeFromWindow(const Point3f &oldP, const Point3f &newP);
|
||||
protected:
|
||||
Point3f x;
|
||||
Point3f y;
|
||||
|
|
113
wrap/gui/view.h
113
wrap/gui/view.h
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.4 2004/04/07 10:54:11 cignoni
|
||||
Commented out unused parameter names and other minor warning related issues
|
||||
|
||||
Revision 1.3 2004/03/31 15:07:37 ponchio
|
||||
CAMERA_H -> VCG_CAMERA_H
|
||||
|
||||
|
@ -36,13 +39,24 @@ Adding copyright.
|
|||
#ifndef VCG_CAMERA_H
|
||||
#define VCG_CAMERA_H
|
||||
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/math/Matrix44.h>
|
||||
/**********************
|
||||
WARNING
|
||||
Everything here assumes the opengl window coord system.
|
||||
the 0,0 is bottom left
|
||||
y is upward!
|
||||
**********************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <GL/GL.h>
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/space/plane3.h>
|
||||
#include <vcg/space/line3.h>
|
||||
#include <vcg/math/matrix44.h>
|
||||
|
||||
namespace vcg {
|
||||
/**
|
||||
This class represent the viewing parameters under opengl.
|
||||
Mainly it stores the projection and modelview matrix and the viewport
|
||||
and it is used to simply project back and forth points, computing line of sight, planes etc.
|
||||
*/
|
||||
|
||||
template <class T> class View {
|
||||
public:
|
||||
|
@ -51,10 +65,18 @@ public:
|
|||
Point3<T> Project(const Point3<T> &p) const;
|
||||
Point3<T> UnProject(const Point3<T> &p) const;
|
||||
Point3<T> ViewPoint();
|
||||
//convert coordinates range 0-1 to range 0 viewport[2]
|
||||
Point3<T> ScreenToViewport(const Point3<T> &p) const;
|
||||
//viceversa
|
||||
Point3<T> ViewportToScreen(const Point3<T> &p) const;
|
||||
|
||||
/// Return the plane perpendicular to the view axis and passing through point P.
|
||||
Plane3<T> ViewPlaneFromModel(const Point3<T> &p);
|
||||
|
||||
/// Return the line passing through the point p and the observer.
|
||||
Line3<T> ViewLineFromWindow(const Point3<T> &p);
|
||||
|
||||
/// Convert coordinates from the range -1..1 of Normalized Device Coords to range 0 viewport[2]
|
||||
Point3<T> NormDevCoordToWindowCoord(const Point3<T> &p) const;
|
||||
|
||||
/// Convert coordinates from 0--viewport[2] to the range -1..1 of Normalized Device Coords to
|
||||
Point3<T> WindowCoordToNormDevCoord(const Point3<T> &p) const;
|
||||
|
||||
Matrix44<T> proj;
|
||||
Matrix44<T> model;
|
||||
|
@ -65,14 +87,14 @@ public:
|
|||
|
||||
template <class T> void View<T>::GetView() {
|
||||
double m[16];
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, m);
|
||||
glGetDoublev(GL_TRANSPOSE_PROJECTION_MATRIX_ARB, m);
|
||||
proj.Import(Matrix44d(m));
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, m);
|
||||
glGetDoublev(GL_TRANSPOSE_MODELVIEW_MATRIX_ARB, m);
|
||||
model.Import(Matrix44d(m));
|
||||
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
||||
matrix = model * proj;
|
||||
matrix = proj*model;
|
||||
inverse = matrix;
|
||||
Invert(inverse);
|
||||
}
|
||||
|
@ -82,56 +104,65 @@ template <class T> void View<T>::SetView() {
|
|||
}
|
||||
|
||||
template <class T> Point3<T> View<T>::ViewPoint() {
|
||||
return inverse * Point3<T>(0, 0, 0);
|
||||
/*Matrix44d model(model_matrix);
|
||||
model.Invert();
|
||||
Point3d view = model * Point3d(0, 0, 0);
|
||||
return Point3<T>(view[0], view[1], view[2]); */
|
||||
Matrix44<T> mi=model;
|
||||
Invert(mi);
|
||||
return mi* Point3<T>(0, 0, 0);
|
||||
}
|
||||
// Note that p it is assumed to be in model coordinate.
|
||||
template <class T> Plane3<T> View<T>::ViewPlaneFromModel(const Point3<T> &p)
|
||||
{
|
||||
Point3<T> vp=ViewPoint();
|
||||
Plane3<T> pl; // plane perpedicular to view direction and passing through manip center
|
||||
pl.n=(vp-p);
|
||||
pl.d=pl.n*p;
|
||||
return pl;
|
||||
}
|
||||
// Note that p it is assumed to be in window coordinate.
|
||||
template <class T> Line3<T> View<T>::ViewLineFromWindow(const Point3<T> &p)
|
||||
{
|
||||
Point3<T> vp=ViewPoint();
|
||||
Line3<T> ln; // plane perpedicular to view direction and passing through manip center
|
||||
/*Matrix44<T> mi=model;
|
||||
Invert(mi);
|
||||
*/Point3f pp=UnProject(p);
|
||||
ln.SetOrigin(vp);
|
||||
ln.SetDirection(pp-vp);
|
||||
return ln;
|
||||
}
|
||||
|
||||
template <class T> Point3<T> View<T>::Project(const Point3<T> &p) const {
|
||||
Point3<T> r;
|
||||
r = p * matrix;
|
||||
r[0] = (r[0]+1)*(viewport[2]/(T)2.0)+viewport[0];
|
||||
r[1] =(r[1]+1)*(viewport[3]/(T)2.0)+viewport[1];
|
||||
r[1] = viewport[3]-r[1];
|
||||
return r;
|
||||
/*double r[3];
|
||||
gluProject(p[0], p[1], p[2], model_matrix, proj_matrix, viewport, &r[0], &r[1], &r[2]);
|
||||
return Point3<T>((T)r[0], (T)r[1], (T)r[2]);*/
|
||||
r = matrix * p;
|
||||
return NormDevCoordToWindowCoord(r);
|
||||
}
|
||||
|
||||
template <class T> Point3<T> View<T>::UnProject(const Point3<T> &p) const {
|
||||
Point3<T> s = p;
|
||||
s[0] = (p[0]- viewport[0])/ (viewport[2]/(T)2.0) - 1;
|
||||
s[1] = (p[1]- viewport[1])/ (viewport[3]/(T)2.0) - 1;
|
||||
s[1] = -s[1];
|
||||
s[2] = p[2];
|
||||
//s[1] = -s[1]; // pezza aggiunta per il tan2.... ?????????????
|
||||
|
||||
s = s * inverse;
|
||||
Point3<T> s = WindowCoordToNormDevCoord(p);
|
||||
s = inverse * s ;
|
||||
return s;
|
||||
/*double r[3];
|
||||
gluUnProject(p[0], p[1], p[2], model_matrix, proj_matrix, viewport, &r[0], &r[1], &r[2]);
|
||||
return Point3<T>((T)r[0], (T)r[1], (T)r[2]);*/
|
||||
}
|
||||
|
||||
template <class T> Point3<T> View<T>::ScreenToViewport(const Point3<T> &p) const {
|
||||
// Come spiegato nelle glspec
|
||||
// dopo la perspective division le coordinate sono dette normalized device coords ( NDC ).
|
||||
// Per passare alle window coords si deve fare la viewport transformation.
|
||||
// Le coordinate di viewport stanno tra -1 e 1
|
||||
|
||||
template <class T> Point3<T> View<T>::NormDevCoordToWindowCoord(const Point3<T> &p) const {
|
||||
Point3<T> a;
|
||||
a[0] = (p[0]+1)*(viewport[2]/(T)2.0)+viewport[0];
|
||||
a[1] = (p[1]+1)*(viewport[3]/(T)2.0)+viewport[1];
|
||||
a[1] = viewport[3] - a[1];
|
||||
//a[1] = viewport[3] - a[1];
|
||||
a[2] = p[2];
|
||||
return a;
|
||||
}
|
||||
//viceversa
|
||||
template <class T> Point3<T> View<T>::ViewportToScreen(const Point3<T> &p) const {
|
||||
|
||||
|
||||
template <class T> Point3<T> View<T>::WindowCoordToNormDevCoord(const Point3<T> &p) const {
|
||||
Point3<T> a;
|
||||
a[0] = (p[0]- viewport[0])/ (viewport[2]/(T)2.0) - 1;
|
||||
a[1] = (p[1]- viewport[1])/ (viewport[3]/(T)2.0) - 1;
|
||||
a[1] = -a[1];
|
||||
//a[1] = -a[1];
|
||||
a[2] = p[2];
|
||||
//a[1] = -a[1]; // pezza aggiunta per il tan2.... ?????????????
|
||||
return a;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue