Redesigned partial version.

This commit is contained in:
Federico Ponchio 2004-05-14 03:15:09 +00:00
parent 99b51766f6
commit 8381f2f5a0
4 changed files with 408 additions and 400 deletions

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.6 2004/05/12 20:55:18 ponchio
*** empty log message ***
Revision 1.5 2004/05/07 12:46:08 cignoni Revision 1.5 2004/05/07 12:46:08 cignoni
Restructured and adapted in a better way to opengl Restructured and adapted in a better way to opengl
@ -54,17 +57,24 @@ Transform::Transform() {
center=Point3f(0,0,0); center=Point3f(0,0,0);
} }
Trackball::Trackball(): current_button(0), last_x(-1), last_y(-1), dragging(false), Trackball::Trackball(): current_button(0), current_mode(NULL),
spinnable(true), spinning(false), history_size(10) { dragging(false), spinnable(true), spinning(false),
//qui si aggiungono tutte le actions history_size(10) {
actions[0] = Action(LOCAL, NONE); //here we add mode
actions[BUTTON_LEFT] = Action(VIEW, ROTATE); modes[0] = NULL;
actions[BUTTON_LEFT | KEY_CTRL] = Action(VIEW, DRAG_XY); modes[BUTTON_LEFT] = new SphereMode();
actions[BUTTON_LEFT | KEY_SHIFT] = Action(VIEW, SCALE); modes[BUTTON_LEFT | KEY_CTRL] = new PlaneMode(Plane3f(0, Point3f(1, 0, 0)));
actions[WHEEL] = Action(SCREEN, SCALE); modes[BUTTON_LEFT | KEY_SHIFT] = new ScaleMode();
modes[WHEEL] = new ScaleMode();
SetCurrentAction(); SetCurrentAction();
} }
Trackball::~Trackball() {
map<int, TrackMode *>::iterator i;
for(i = modes.begin(); i != modes.end(); i++)
delete (*i).second;
}
void Trackball::SetIdentity() { void Trackball::SetIdentity() {
track.SetIdentity(); track.SetIdentity();
Reset(); Reset();
@ -73,153 +83,163 @@ void Trackball::SetPosition(const Point3f &c, int /* millisec */) {
center = c; center = c;
} }
//operating
void Trackball::GetView() { void Trackball::GetView() {
camera.GetView(); camera.GetView();
//lets get view matrix /* //lets get view matrix
Similarityf m = last_track; Similarityf m = last_track;
Point3f c_obj = m*center; //coordinate of the center of the trackball in obj coords 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. Point3f 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 ScreenRadius = 10.0f/Distance(center, camera.UnProject(Point3f(ScreenCenter[0] + 10, ScreenCenter[1], ScreenCenter[2])));
Point3f X, Y, Z, C; Point3f X, Y, Z, C;
X = camera.UnProject(Point3f(ScreenCenter[0] + 100, ScreenCenter[1], ScreenCenter[2])); X = camera.UnProject(Point3f(ScreenCenter[0] + 100, ScreenCenter[1], ScreenCenter[2]));
Y = camera.UnProject(Point3f(ScreenCenter[0], ScreenCenter[1] - 100, 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)); Z = camera.UnProject(Point3f(ScreenCenter[0], ScreenCenter[1], ScreenCenter[2] + 0.1f));
C = c_obj; C = c_obj;
X = X - C; X.Normalize(); X = X - C; X.Normalize();
Y = Y - C; Y.Normalize(); Y = Y - C; Y.Normalize();
Z = X ^ Y; Z = X ^ Y;
Matrix44f view_axis; //this is before applying last (or track...) Matrix44f view_axis; //this is before applying last (or track...)
view_axis.SetIdentity(); view_axis.SetIdentity();
view_axis.element(0, 0) = X[0]; view_axis.element(0, 1) = X[1]; view_axis.element(0, 2) = X[2]; view_axis.element(0, 0) = X[0]; view_axis.element(0, 1) = X[1]; view_axis.element(0, 2) = X[2];
view_axis.element(1, 0) = Y[0]; view_axis.element(1, 1) = Y[1]; view_axis.element(1, 2) = Y[2]; view_axis.element(1, 0) = Y[0]; view_axis.element(1, 1) = Y[1]; view_axis.element(1, 2) = Y[2];
view_axis.element(2, 0) = Z[0]; view_axis.element(2, 1) = Z[1]; view_axis.element(2, 2) = Z[2]; view_axis.element(2, 0) = Z[0]; view_axis.element(2, 1) = Z[1]; view_axis.element(2, 2) = Z[2];
view.SetIdentity(); view.SetIdentity();
view.FromMatrix(view_axis); view.FromMatrix(view_axis); */
//view = view * Inverse(Similarityf(track.rot));
//spinning ignored
} }
void Trackball::Apply() { void Trackball::Apply() {
glMultMatrix(track.Matrix()); glMultMatrix(track.Matrix());
} }
/***************************************************************/ /***************************************************************/
void Trackball::DrawCircle() void Trackball::DrawCircle() {
{ const int nside=18;
const int nside=18; const double pi2=3.14159265*2.0;
const double pi2=3.14159265*2.0; glBegin(GL_LINE_STRIP);
glBegin(GL_LINE_STRIP); for(double i=0;i<=nside;i++){
for(double i=0;i<=nside;i++){ glNormal3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0);
glNormal3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0); glVertex3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0);
glVertex3d(cos(i*pi2/nside), sin(i*pi2/nside), 0.0); }
} glEnd();
glEnd(); DrawPlaneHandle();
DrawPlaneHandle();
} }
void Trackball::DrawPlane() void Trackball::DrawPlane() {
{ const int nl=10;
const int nl=10; float w=5.0f/3.0f;
float w=5.0f/3.0f; float u;
float u; glBegin(GL_LINES);
glBegin(GL_LINES); glNormal3f(0.0,0.0,1.0);
glNormal3f(0.0,0.0,1.0); for( u=-w; u<=w+0.01f; u+=2*w/nl){
for( u=-w; u<=w+0.01f; u+=2*w/nl){ glVertex3f(-w, +u, 0);
glVertex3f(-w, +u, 0); glVertex3f(+w, +u, 0);
glVertex3f(+w, +u, 0); glVertex3f(+u, -w, 0);
glVertex3f(+u, -w, 0); glVertex3f(+u, +w, 0);
glVertex3f(+u, +w, 0); }
} glEnd();
glEnd(); }
}
void Trackball::DrawPlaneHandle() void Trackball::DrawPlaneHandle() {
{ float r=1.0;
float r=1.0; float dr=r/10.0f;
float dr=r/10.0f; glBegin(GL_LINE_STRIP);
glBegin(GL_LINE_STRIP); glVertex3f(+r+dr, +r, 0.0);
glVertex3f(+r+dr, +r, 0.0); glVertex3f(+r , +r+dr,0.0);
glVertex3f(+r , +r+dr,0.0); glVertex3f(+r-dr, +r, 0.0);
glVertex3f(+r-dr, +r, 0.0); glVertex3f(+r , +r-dr,0.0);
glVertex3f(+r , +r-dr,0.0); glVertex3f(+r+dr, +r, 0.0);
glVertex3f(+r+dr, +r, 0.0); glEnd();
glEnd(); glBegin(GL_LINE_STRIP);
glBegin(GL_LINE_STRIP); glVertex3f(-r+dr, -r, 0.0);
glVertex3f(-r+dr, -r, 0.0); glVertex3f(-r , -r+dr,0.0);
glVertex3f(-r , -r+dr,0.0); glVertex3f(-r-dr, -r, 0.0);
glVertex3f(-r-dr, -r, 0.0); glVertex3f(-r , -r-dr,0.0);
glVertex3f(-r , -r-dr,0.0); glVertex3f(-r+dr, -r, 0.0);
glVertex3f(-r+dr, -r, 0.0); glEnd();
glEnd();
} }
void Trackball::Draw() { void Trackball::Draw() {
glPushMatrix(); glPushMatrix();
glTranslate(center); glTranslate(center);
glScalef(radius,radius,radius); glScalef(radius,radius,radius);
/// Here start the real drawing stuff /// Here start the real drawing stuff
float amb[4] ={.3f,.3f,.3f,1.0f}; float amb[4] ={.3f,.3f,.3f,1.0f};
float col[4] ={.5f,.5f,.8f,1.0f}; float col[4] ={.5f,.5f,.8f,1.0f};
float col2[4]={.9f,.9f,1.0f,1.0f}; float col2[4]={.9f,.9f,1.0f,1.0f};
glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT); glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT);
glLineWidth(2.0); glLineWidth(2.0);
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
glEnable(GL_LINE_SMOOTH); glEnable(GL_LIGHT0);
glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,amb); glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,amb);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,col); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,col);
glPushMatrix(); glPushMatrix();
DrawCircle();
glPushMatrix();
glRotatef(90,1,0,0);
DrawCircle();
glRotatef(90,0,1,0);
DrawCircle();
glPopMatrix();
glPopMatrix();
DrawCircle();
glPushMatrix();
glColor4f(1.0,.8f,.8f,1.0f); glRotatef(90,1,0,0);
if(current_action.motion==ROTATE_X || current_action.motion==ROTATE_Y || current_action.motion==ROTATE_Z ){ DrawCircle();
//Point3d raxt(0,0,0),rax;// compute the rotation axis glRotatef(90,0,1,0);
//raxt[current_action.motion-ROTATE_X]=1; DrawCircle();
//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) { glPopMatrix();
glPushMatrix();
//glTranslate(Manip.c); glPopMatrix();
DrawPlane();
glPopMatrix(); glColor4f(1.0,.8f,.8f,1.0f);
}
if(current_action.motion==DRAG_XZ) { /* switch(current_action) {
glPushMatrix(); case TRACK_ROTATE_X:
//glTranslate(Manip.c); case TRACK_ROTATE_Y:
glRotatef(90,1,0,0); case TRACK_ROTATE_Z:
DrawPlane(); //Point3d raxt(0,0,0),rax;// compute the rotation axis
glPopMatrix(); //raxt[current_action.motion-ROTATE_X]=1;
} //RotM.Apply(rax,raxt);
if(current_action.motion==DRAG_YZ) { //
glPushMatrix(); //glDisable(GL_LIGHTING);
//glTranslate(Manip.c); //glBegin(GL_LINE_STRIP);
glRotatef(90,0,1,0); // glVertex(Manip.c-raxt*TrackballRadius*1.3);
DrawPlane(); // glVertex(Manip.c+raxt*TrackballRadius*1.3);
glPopMatrix(); //glEnd();
} break;
case DRAG_XY:
glPushMatrix();
//glTranslate(Manip.c);
DrawPlane();
glPopMatrix();
break;
case DRAG_XY:
glPushMatrix();
//glTranslate(Manip.c);
glRotatef(90,1,0,0);
DrawPlane();
glPopMatrix();
break;
case DRAG_XY:
glPushMatrix();
//glTranslate(Manip.c);
glRotatef(90,0,1,0);
DrawPlane();
glPopMatrix();
break;
default:
break;
}*/
glPopAttrib();
glPopMatrix(); glPopMatrix();
} }
@ -232,26 +252,16 @@ void Trackball::Reset() {
void Trackball::MouseDown(int x, int y, Trackball::Button button) { void Trackball::MouseDown(int x, int y, Trackball::Button button) {
current_button |= button; current_button |= button;
SetCurrentAction(); SetCurrentAction();
last_x = x; last_point = Point3f((float)x, (float)y, 0);
last_y = y;
} }
void Trackball::MouseMove(int x, int y) { void Trackball::MouseMove(int x, int y) {
if(current_action.motion == NONE) return; if(current_mode == NULL) return;
if(last_x == -1 && last_y == -1) { //changed mode in the middle of moving if(last_point[2] == -1) { //changed mode in the middle of moving
last_x = x; last_point = Point3f((float)x, (float)y, 0);
last_y = y;
return; return;
} }
current_mode->Apply(this, Point3f(float(x), float(y), 0));
TrackMode *mode = CurrentMode();
mode->tb=this;
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) { void Trackball::MouseUp(int /* x */, int /* y */, Trackball::Button button) {
@ -293,39 +303,17 @@ void Trackball::HistorySize(int /* lenght */){}
void Trackball::SetCurrentAction() { void Trackball::SetCurrentAction() {
//I use strict matching. //I use strict matching.
assert(actions.count(0)); assert(modes.count(0));
if(!actions.count(current_button)) if(!modes.count(current_button))
current_action = actions[0]; current_mode = NULL;
else else
current_action = actions[current_button]; current_mode = modes[current_button];
last_x = -1; last_point = Point3f(0, 0, -1);
last_y = -1;
last_track = track; last_track = track;
last_view = view; // last_view = view;
} }
TrackMode *Trackball::CurrentMode() {
Point3f x(1, 0, 0), y(0, 1, 0), z(0, 0, 1);
TrackMode *mode = NULL;
switch(current_action.motion) {
case NONE: mode = new TrackMode(); break;
case ROTATE: mode = new SphereMode(); break;
case ROTATE_DUMMY: mode = new GravityMode(); break;
case ROTATE_X: mode = new CylinderMode(x); break;
case ROTATE_Y: mode = new CylinderMode(y); break;
case ROTATE_Z: mode = new CylinderMode(z); break;
case DRAG_X: mode = new LineMode(x); break;
case DRAG_Y: mode = new LineMode(y); break;
case DRAG_Z: mode = new LineMode(z); break;
case DRAG_XY: mode = new PlaneMode(x, y); break;
case DRAG_YZ: mode = new PlaneMode(y, z); break;
case DRAG_XZ: mode = new PlaneMode(z, x); break;
case SCALE: mode = new ScaleMode(); break;
default: break;
}
return mode;
}
////return center of trackball in Window coordinates. ////return center of trackball in Window coordinates.
//Point3f Trackball::ScreenOrigin() { //Point3f Trackball::ScreenOrigin() {
// return camera.Project(ModelOrigin()); // return camera.Project(ModelOrigin());
@ -333,9 +321,9 @@ TrackMode *Trackball::CurrentMode() {
//return center of trackball in Model coordinates //return center of trackball in Model coordinates
Point3f Trackball::ModelOrigin() { //Point3f Trackball::ModelOrigin() {
return center; // return center;
} //}
//Matrix44f Trackball::ScreenToModel() { //Matrix44f Trackball::ScreenToModel() {
// return camera.inverse; // return camera.inverse;

View File

@ -25,6 +25,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.5 2004/05/12 20:55:18 ponchio
*** empty log message ***
Revision 1.4 2004/05/07 12:46:08 cignoni Revision 1.4 2004/05/07 12:46:08 cignoni
Restructured and adapted in a better way to opengl Restructured and adapted in a better way to opengl
@ -47,142 +50,142 @@ Adding copyright.
#include <map> #include <map>
namespace vcg { namespace vcg {
/* A trackball stores two transformations /* A trackball stores two transformations
the first one, local, is the one 'placing' the trackball somewhere, the first one, local, is the one 'placing' the trackball somewhere,
the second one, track, is the one that effectively rotate the object. the second one, track, is the one that effectively rotate the object.
The 'local' transformation is the one that contains information about The 'local' transformation is the one that contains information about
the rotation center, the size and the orientation of the trackball. the rotation center, the size and the orientation of the trackball.
the 'track' is the one implementing the effective transformation. the 'track' is the one implementing the effective transformation.
*/ */
class Transform {
public:
Transform();
Similarityf track;
Point3f center; // la posizione della trackball nello spazio di modello. il defgault e' 000 class Transform {
float radius; /// size of the widget in spazio di modello. public:
//Quaternion orientation; Transform();
}; Similarityf track;
Transform interpolate(const Transform &a, const Transform &b, float t); /// la posizione della track nello spazio di modello. il defgault e' 000
class TrackMode; Point3f center;
class Trackball: public Transform { /// size of the widget in spazio di modello.
public: float radius;
enum Button { BUTTON_NONE = 0x0000,
BUTTON_LEFT = 0x0001,
BUTTON_MIDDLE = 0x0002,
BUTTON_RIGHT = 0x0004,
WHEEL = 0x0008,
KEY_SHIFT = 0x0010,
KEY_CTRL = 0x0020,
KEY_ALT = 0x0040,
HANDLE = 0x0080 };
Trackball();
void SetIdentity();
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();
void Apply();
void Draw();
void ApplynDraw() { Apply(); 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);
void MouseUp(int x, int y, Button button);
void MouseWheel(Button notch);
void ButtonUp(Button button);
void ButtonDown(Button button);
//default sensitivity 1
void SetSensitivity(float s);
//spinning interface
void SetSpinnable(bool on);
bool IsSpinnable();
void SetSpinning(Quaternionf &spin);
void StopSpinning();
bool IsSpinning();
//interfaccia navigation:
void Back();
void Forward();
void Home();
void Store();
void HistorySize(int lenght);
//internals
enum System { LOCAL, VIEW, SCREEN };
enum Motion { NONE = 0, ROTATE = 1, ROTATE_DUMMY = 2, //really makes sense only in VIEW system
ROTATE_X = 3, ROTATE_Y = 4, ROTATE_Z = 5, // Axis Constrained Rotation
DRAG_X = 6, DRAG_Y = 7, DRAG_Z = 8, // Drag constrained to an axis (trackball axis)
DRAG_XY = 9, DRAG_YZ = 10, DRAG_XZ = 11, // Drag constrained to a plane
SCALE = 12 //scale respect to center of trackball
}; };
Transform interpolate(const Transform &a, const Transform &b, float t);
class TrackMode;
class Trackball: public Transform {
public:
enum Button { BUTTON_NONE = 0x0000,
BUTTON_LEFT = 0x0001,
BUTTON_MIDDLE = 0x0002,
BUTTON_RIGHT = 0x0004,
WHEEL = 0x0008,
KEY_SHIFT = 0x0010,
KEY_CTRL = 0x0020,
KEY_ALT = 0x0040,
HANDLE = 0x0080 };
Trackball();
~Trackball();
void SetIdentity();
void SetPosition(const Point3f &c, int millisec = 0);
void SetScale(const float s) {radius=s;};
void SetTransform(const Transform &transform, int miilisec = 0);
//operating
void GetView();
void Apply();
void Draw();
void ApplynDraw() { Apply(); Draw(); }
void Reset();
// Internal Drawing stuff
static void DrawCircle ();
static void DrawPlane();
static void DrawPlaneHandle();
//interface
void MouseDown(int x, int y, Button button);
void MouseMove(int x, int y);
void MouseUp(int x, int y, Button button);
void MouseWheel(Button notch);
void ButtonUp(Button button);
void ButtonDown(Button button);
//default sensitivity 1
void SetSensitivity(float s);
//spinning interface
void SetSpinnable(bool on);
bool IsSpinnable();
void SetSpinning(Quaternionf &spin);
void StopSpinning();
bool IsSpinning();
//interfaccia navigation:
void Back();
void Forward();
void Home();
void Store();
void HistorySize(int lenght);
//internals
enum Action { NONE = 0,
VIEW_ROTATE = 1,
// Axis Constrained Rotation
TRACK_ROTATE_X = 3, TRACK_ROTATE_Y = 4, TRACK_ROTATE_Z = 5,
// Drag constrained to an axis (trackball axis)
DRAG_X = 6, DRAG_Y = 7, DRAG_Z = 8,
// Drag constrained to a plane
DRAG_XY = 9, DRAG_YZ = 10, DRAG_XZ = 11,
//scale model respect to center of trackball
VIEW_SCALE = 12,
//scale trackball and model
TRACK_SCALE = 13
};
struct Action { ///Find the current action ussing the current button
System system;
Motion motion;
Action() {} //protected:
Action(System s, Motion m): system(s), motion(m) {} View<float> camera;
/* float ScreenRadius;
Point3f ScreenCenter;*/
void SetCurrentAction();
int current_button;
TrackMode *current_mode;
std::map<int, TrackMode *> modes;
Similarityf last_track;
Similarityf last_view;
Point3f last_point;
bool dragging;
int button_mask;
Quaternionf spin;
bool spinnable;
bool spinning;
std::list<Transform> history;
int history_size;
//Point3f ScreenOrigin(); //center of trackball in Screen coord
//Point3f ModelOrigin(); //center of trackball in Model coord
// Matrix44f ScreenToModel(); //forse non serve.....
// Similarityf ModelToLocal();
//Point3f ScreenToLocal(const Point3f &p);
//Point3f LocalToScreen(const Point3f &p);
friend class TrackMode;
}; };
///Find the current action ussing the current button
void SetCurrentAction();
//protected:
View<float> camera;
Similarityf view; //Rotate LOCAL coordinate into VIEW coordinates
float ScreenRadius;
Point3f ScreenCenter;
int current_button;
Action current_action;
TrackMode *CurrentMode();
std::map<int, Action> actions;
Similarityf last_track;
Similarityf last_view;
int last_x, last_y;
bool dragging;
int button_mask;
Quaternionf spin;
bool spinnable;
bool spinning;
std::list<Transform> history;
int history_size;
//Point3f ScreenOrigin(); //center of trackball in Screen coord
Point3f ModelOrigin(); //center of trackball in Model coord
Matrix44f ScreenToModel(); //forse non serve.....
Similarityf ModelToLocal();
//Point3f ScreenToLocal(const Point3f &p);
//Point3f LocalToScreen(const Point3f &p);
};
}//namespace }//namespace

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.4 2004/05/07 12:46:08 cignoni
Restructured and adapted in a better way to opengl
Revision 1.3 2004/04/07 10:54:11 cignoni Revision 1.3 2004/04/07 10:54:11 cignoni
Commented out unused parameter names and other minor warning related issues Commented out unused parameter names and other minor warning related issues
@ -33,107 +36,114 @@ Adding copyright.
****************************************************************************/ ****************************************************************************/
#include <vcg/space/point2.h>
#include <vcg/space/point3.h> #include <wrap/gui/trackmode.h>
#include <vcg/space/plane3.h> #include <wrap/gui/trackball.h>
#include <vcg/space/intersection3.h> #include <vcg/space/intersection3.h>
#include "trackmode.h"
#include <vcg/math/similarity.h> #include <vcg/math/similarity.h>
#include <iostream>
using namespace std;
using namespace vcg; using namespace vcg;
Plane3f TrackMode::GetViewPlane(const View<float> &camera, Point3f center) {
Point3f vp = camera.ViewPoint();
Plane3f pl; //plane perpedicular to view dir and passing through manip center
pl.Set(vp - center, (vp - center)*center);
/*
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; return pl;
} }
Point3f TrackMode::HitViewPlane(Trackball *tb, const Point3f &p) {
// plane perpedicular to view direction and passing through manip center
Plane3f vp = GetViewPlane(tb->camera, tb->center);
Line3fN ln= tb->camera.ViewLineFromWindow(Point3f(p[0],p[1],0));
Point3f PonVP;
bool res = Intersection<float>(vp,ln,PonVP);
return PonVP;
}
void SphereMode::Apply(Trackball *tb, Point3f new_point) {
Point3f hitOld=Hit(tb, tb->last_point);
Point3f hitNew=Hit(tb, new_point);
Point3f ref = (tb->camera.ViewPoint() - tb->center).Normalize();
Point3f axis = hitNew^ref;
axis.Normalize();
float dist = (hitNew - ref).Norm()/2;
float phi = 2 * math::Asin(dist);
Point3f oaxis = hitOld^ref;
oaxis.Normalize();
float odist = (hitOld - ref).Norm()/2;
float ophi = 2 * math::Asin(odist);
Quaternionf r = tb->last_track.rot;
Quaternionf diff = r * Quaternionf(phi, axis) *
Quaternionf(-ophi, oaxis) * Inverse(r);
tb->track = Similarityf().SetRotate(diff) * tb->last_track;
}
/* dato un punto in coordinate di schermo e.g. in pixel stile opengl /* dato un punto in coordinate di schermo e.g. in pixel stile opengl
restituisce un punto in coordinate di mondo sulla superficie della trackball restituisce un punto in coordinate di mondo sulla superficie
La superficie della trackball e' data da una sfera + una porzione di iperboloide di rotazione della trackball.
assumiamo la sfera di raggio unitario e centrata sull'origine e di guardare lungo la y negativa. 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 X 0 sqrt(1/2) 1
eq sfera: y=sqrt(1-x*x); 1 sqrt(1/2) 0 eq sfera: y=sqrt(1-x*x); 1 sqrt(1/2) 0
eq iperboloide : y=1/2x; inf sqrt(1/2) 1/2 eq iperboloide : y=1/2x; inf sqrt(1/2) 1/2
eq cono y=x+sqrt(2);
*/ */
Point3f SphereMode::Hit(const Point3f &p) Point3f SphereMode::Hit(Trackball *tb, const Point3f &p) {
{ const float Thr = tb->radius/math::Sqrt(2.0f);
printf("Hit in screen space at %5.3f %5.3f %5.3f\n",p[0],p[1],p[2]); Line3fN vn = tb->camera.ViewLineFromModel(tb->center);
Line3fN ln = tb->camera.ViewLineFromWindow(Point3f(p[0],p[1],0));
Point3f viewpoint = tb->camera.ViewPoint();
Plane3f vp=GetViewPlane(); // plane perpedicular to view direction and passing through manip center Plane3f vp = GetViewPlane(tb->camera, tb->center);
Line3fN ln= tb->camera.ViewLineFromWindow(Point3f(p[0],p[1],0)); vp.SetOffset(vp.Offset() + Thr);
//Point3f P0,P1;
Point3f PonVP;
bool res=Intersection<float>(vp,ln,PonVP);
const float Thr=tb->radius/math::Sqrt(2.0f);
Point3f HitPoint; Point3f hit;
float dd=Distance(tb->center,PonVP); bool res = Intersection<float>(vp, ln, hit);
if(dd<Thr) float d = Distance(tb->center - vn.Direction()*Thr, hit);
{ // First case: We hit the sphere so, we must set the z accordingly if(d < Thr) {
float hh=math::Sqrt(tb->radius*tb->radius - dd*dd); Point3f hit2;
HitPoint=PonVP+ln.Direction()*hh; Sphere3f sphere(tb->center, tb->radius);
printf("Hit the sphere point on plane is %5.3f %5.3f %5.3f\n",PonVP[0],PonVP[1],PonVP[2]); bool res = Intersection<float>(sphere, ln, hit, hit2);
printf(" Distance from center is %5.3f \n",dd);
printf(" Heigth for view plane should be %5.3f \n",hh ); //find closest intersection to sphere
float d = (hit - viewpoint).Norm();
float d2 = (hit2 - viewpoint).Norm();
if(d > d2) hit = hit2;
hit -= tb->center;
} else {
if(d > 2.99 * Thr)
d = 2.99 * Thr;
Point3f norm = (hit - tb->center)^(viewpoint - tb->center);
norm.Normalize();
float phi = -M_PI/4 - 3*M_PI/8 *(d - Thr)/Thr;
Quaternionf q(phi, norm);
hit = q.Rotate((viewpoint - tb->center).Normalize() * tb->radius);
} }
else hit.Normalize();
{ // Second Case we hit the hyperboloid return hit;
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;
} }
/* void PlaneMode::Apply(Trackball *tb, Point3f new_point) {
Nella trackball classica si considera Point3f hitOld=HitViewPlane(tb, tb->last_point);
Point3f hitNew=HitViewPlane(tb, new_point);
*/
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);
} }

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.4 2004/05/07 12:46:08 cignoni
Restructured and adapted in a better way to opengl
Revision 1.3 2004/04/07 10:54:11 cignoni Revision 1.3 2004/04/07 10:54:11 cignoni
Commented out unused parameter names and other minor warning related issues Commented out unused parameter names and other minor warning related issues
@ -36,61 +39,65 @@ Adding copyright.
#ifndef TRACKMODE_H #ifndef TRACKMODE_H
#define TRACKMODE_H #define TRACKMODE_H
#include <vcg/space/point3.h> #include <vcg/space/line3.h>
#include <vcg/math/similarity.h> #include <vcg/space/plane3.h>
#include <wrap/gui/trackball.h> #include <wrap/gui/view.h>
namespace vcg { namespace vcg {
class Trackball; class Trackball;
class TrackMode { class TrackMode {
public: public:
virtual ~TrackMode() {} virtual ~TrackMode() {}
virtual void Apply(Trackball *trackball, Point3f new_point) = 0;
virtual void Draw() {}
//virtual void Draw() {} //virtual void Draw() {}
virtual Similarityf ComputeFromWindow(const Point3f &/* oldp */, const Point3f &/* newp */) { return Similarityf().SetIdentity(); } // virtual Similarityf ComputeFromWindow(const Point3f &old_point,
Point3f Hit(const Point3f &p); //const Point3f &new_point) = 0;
Trackball *tb; // Point3f Hit(const Point3f &p);
protected:
Plane3f GetViewPlane(const View<float> &view, Point3f center);
Point3f HitViewPlane(Trackball *trackball, const Point3f &p);
}; };
/* View space modes */
class SphereMode: public TrackMode { class SphereMode: public TrackMode {
public: public:
Similarityf ComputeFromWindow(const Point3f &oldP, const Point3f &newP); void Apply(Trackball *trackball, Point3f new_point);
//Plane3f SetViewPlane(); protected:
Point3f Hit(const Point3f &p); Point3f Hit(Trackball *trackball, const Point3f &p);
Plane3f GetViewPlane();
// Line3f GetViewLine(const Point3f &p);
};
class GravityMode: public TrackMode {
public:
}; };
class CylinderMode: public TrackMode { class CylinderMode: public TrackMode {
public: public:
CylinderMode(const Point3f _axis): axis(_axis) { axis.Normalize(); } CylinderMode(const Line3f &line, float radius = 1) {}
void Apply(Trackball *trackball, Point3f new_point) {}
protected: protected:
Point3f axis; Line3f line;
float radius;
}; };
class PlaneMode: public TrackMode { class PlaneMode: public TrackMode {
public: public:
PlaneMode(const Point3f _x, const Point3f _y): x(_x), y(_y) { x.Normalize(); y.Normalize(); } PlaneMode(const Plane3f &pl): plane(pl) {}
Similarityf ComputeFromWindow(const Point3f &oldP, const Point3f &newP); void Apply(Trackball *trackball, Point3f new_point);
protected: protected:
Point3f x; Plane3f plane;
Point3f y;
}; };
class LineMode: public TrackMode { class LineMode: public TrackMode {
public: public:
LineMode(const Point3f _axis): axis(_axis) { axis.Normalize();} LineMode(const Line3f &line) {}
void Apply(Trackball *trackball, Point3f new_point) {}
protected: protected:
Point3f axis; Line3f line;
}; };
class ScaleMode: public TrackMode { class ScaleMode: public TrackMode {
public: public:
void Apply(Trackball *trackball, Point3f new_point) {}
}; };
}//namespace }//namespace