Redesigned partial version.
This commit is contained in:
parent
99b51766f6
commit
8381f2f5a0
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$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
|
||||
Restructured and adapted in a better way to opengl
|
||||
|
||||
|
@ -54,17 +57,24 @@ Transform::Transform() {
|
|||
center=Point3f(0,0,0);
|
||||
}
|
||||
|
||||
Trackball::Trackball(): current_button(0), last_x(-1), last_y(-1), dragging(false),
|
||||
spinnable(true), spinning(false), history_size(10) {
|
||||
//qui si aggiungono tutte le actions
|
||||
actions[0] = Action(LOCAL, NONE);
|
||||
actions[BUTTON_LEFT] = Action(VIEW, ROTATE);
|
||||
actions[BUTTON_LEFT | KEY_CTRL] = Action(VIEW, DRAG_XY);
|
||||
actions[BUTTON_LEFT | KEY_SHIFT] = Action(VIEW, SCALE);
|
||||
actions[WHEEL] = Action(SCREEN, SCALE);
|
||||
Trackball::Trackball(): current_button(0), current_mode(NULL),
|
||||
dragging(false), spinnable(true), spinning(false),
|
||||
history_size(10) {
|
||||
//here we add mode
|
||||
modes[0] = NULL;
|
||||
modes[BUTTON_LEFT] = new SphereMode();
|
||||
modes[BUTTON_LEFT | KEY_CTRL] = new PlaneMode(Plane3f(0, Point3f(1, 0, 0)));
|
||||
modes[BUTTON_LEFT | KEY_SHIFT] = new ScaleMode();
|
||||
modes[WHEEL] = new ScaleMode();
|
||||
SetCurrentAction();
|
||||
}
|
||||
|
||||
Trackball::~Trackball() {
|
||||
map<int, TrackMode *>::iterator i;
|
||||
for(i = modes.begin(); i != modes.end(); i++)
|
||||
delete (*i).second;
|
||||
}
|
||||
|
||||
void Trackball::SetIdentity() {
|
||||
track.SetIdentity();
|
||||
Reset();
|
||||
|
@ -73,153 +83,163 @@ void Trackball::SetPosition(const Point3f &c, int /* millisec */) {
|
|||
center = c;
|
||||
}
|
||||
|
||||
//operating
|
||||
void Trackball::GetView() {
|
||||
camera.GetView();
|
||||
|
||||
//lets get view matrix
|
||||
/* //lets get view matrix
|
||||
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 c_obj = m*center; //coordinate of the center of the trackball in obj coords
|
||||
Point3f ScreenCenter = camera.Project(c_obj); //center of the trackball in screen coords.
|
||||
Point3f ScreenRadius = 10.0f/Distance(center, camera.UnProject(Point3f(ScreenCenter[0] + 10, ScreenCenter[1], ScreenCenter[2])));
|
||||
|
||||
Point3f X, Y, Z, C;
|
||||
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));
|
||||
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();
|
||||
Z = X ^ Y;
|
||||
X = X - C; X.Normalize();
|
||||
Y = Y - C; Y.Normalize();
|
||||
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.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(2, 0) = Z[0]; view_axis.element(2, 1) = Z[1]; view_axis.element(2, 2) = Z[2];
|
||||
view.SetIdentity();
|
||||
view.FromMatrix(view_axis);
|
||||
//view = view * Inverse(Similarityf(track.rot));
|
||||
//spinning ignored
|
||||
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(2, 0) = Z[0]; view_axis.element(2, 1) = Z[1]; view_axis.element(2, 2) = Z[2];
|
||||
view.SetIdentity();
|
||||
view.FromMatrix(view_axis); */
|
||||
}
|
||||
|
||||
void Trackball::Apply() {
|
||||
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::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::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::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();
|
||||
|
||||
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);
|
||||
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_LIGHT0);
|
||||
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();
|
||||
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,amb);
|
||||
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,col);
|
||||
glPushMatrix();
|
||||
|
||||
DrawCircle();
|
||||
glPushMatrix();
|
||||
|
||||
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();
|
||||
glRotatef(90,1,0,0);
|
||||
DrawCircle();
|
||||
glRotatef(90,0,1,0);
|
||||
DrawCircle();
|
||||
|
||||
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();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glColor4f(1.0,.8f,.8f,1.0f);
|
||||
|
||||
/* switch(current_action) {
|
||||
case TRACK_ROTATE_X:
|
||||
case TRACK_ROTATE_Y:
|
||||
case TRACK_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();
|
||||
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();
|
||||
}
|
||||
|
@ -232,26 +252,16 @@ void Trackball::Reset() {
|
|||
void Trackball::MouseDown(int x, int y, Trackball::Button button) {
|
||||
current_button |= button;
|
||||
SetCurrentAction();
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
last_point = Point3f((float)x, (float)y, 0);
|
||||
}
|
||||
|
||||
void Trackball::MouseMove(int x, int y) {
|
||||
if(current_action.motion == NONE) return;
|
||||
if(last_x == -1 && last_y == -1) { //changed mode in the middle of moving
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
if(current_mode == NULL) return;
|
||||
if(last_point[2] == -1) { //changed mode in the middle of moving
|
||||
last_point = Point3f((float)x, (float)y, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
current_mode->Apply(this, Point3f(float(x), float(y), 0));
|
||||
}
|
||||
|
||||
void Trackball::MouseUp(int /* x */, int /* y */, Trackball::Button button) {
|
||||
|
@ -293,39 +303,17 @@ void Trackball::HistorySize(int /* lenght */){}
|
|||
|
||||
void Trackball::SetCurrentAction() {
|
||||
//I use strict matching.
|
||||
assert(actions.count(0));
|
||||
if(!actions.count(current_button))
|
||||
current_action = actions[0];
|
||||
assert(modes.count(0));
|
||||
if(!modes.count(current_button))
|
||||
current_mode = NULL;
|
||||
else
|
||||
current_action = actions[current_button];
|
||||
current_mode = modes[current_button];
|
||||
|
||||
last_x = -1;
|
||||
last_y = -1;
|
||||
last_point = Point3f(0, 0, -1);
|
||||
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.
|
||||
//Point3f Trackball::ScreenOrigin() {
|
||||
// return camera.Project(ModelOrigin());
|
||||
|
@ -333,9 +321,9 @@ TrackMode *Trackball::CurrentMode() {
|
|||
|
||||
|
||||
//return center of trackball in Model coordinates
|
||||
Point3f Trackball::ModelOrigin() {
|
||||
return center;
|
||||
}
|
||||
//Point3f Trackball::ModelOrigin() {
|
||||
// return center;
|
||||
//}
|
||||
|
||||
//Matrix44f Trackball::ScreenToModel() {
|
||||
// return camera.inverse;
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
History
|
||||
|
||||
$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
|
||||
Restructured and adapted in a better way to opengl
|
||||
|
||||
|
@ -47,142 +50,142 @@ 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.
|
||||
/* 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.
|
||||
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;
|
||||
*/
|
||||
|
||||
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;
|
||||
};
|
||||
class Transform {
|
||||
public:
|
||||
Transform();
|
||||
Similarityf track;
|
||||
|
||||
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();
|
||||
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
|
||||
/// la posizione della track nello spazio di modello. il defgault e' 000
|
||||
Point3f center;
|
||||
/// size of the widget in spazio di modello.
|
||||
float radius;
|
||||
};
|
||||
|
||||
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 {
|
||||
System system;
|
||||
Motion motion;
|
||||
Action() {}
|
||||
Action(System s, Motion m): system(s), motion(m) {}
|
||||
///Find the current action ussing the current button
|
||||
|
||||
|
||||
//protected:
|
||||
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
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$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
|
||||
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 <vcg/space/plane3.h>
|
||||
|
||||
#include <wrap/gui/trackmode.h>
|
||||
#include <wrap/gui/trackball.h>
|
||||
#include <vcg/space/intersection3.h>
|
||||
#include "trackmode.h"
|
||||
#include <vcg/math/similarity.h>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
using namespace vcg;
|
||||
|
||||
Plane3f TrackMode::GetViewPlane(const View<float> &camera, Point3f center) {
|
||||
Point3f vp = camera.ViewPoint();
|
||||
|
||||
|
||||
|
||||
/*
|
||||
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);
|
||||
Plane3f pl; //plane perpedicular to view dir and passing through manip center
|
||||
pl.Set(vp - center, (vp - center)*center);
|
||||
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
|
||||
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.
|
||||
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
|
||||
eq cono y=x+sqrt(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]);
|
||||
Point3f SphereMode::Hit(Trackball *tb, const Point3f &p) {
|
||||
const float Thr = tb->radius/math::Sqrt(2.0f);
|
||||
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
|
||||
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);
|
||||
Plane3f vp = GetViewPlane(tb->camera, tb->center);
|
||||
vp.SetOffset(vp.Offset() + Thr);
|
||||
|
||||
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 );
|
||||
Point3f hit;
|
||||
bool res = Intersection<float>(vp, ln, hit);
|
||||
float d = Distance(tb->center - vn.Direction()*Thr, hit);
|
||||
if(d < Thr) {
|
||||
Point3f hit2;
|
||||
Sphere3f sphere(tb->center, tb->radius);
|
||||
bool res = Intersection<float>(sphere, ln, hit, hit2);
|
||||
|
||||
//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
|
||||
{ // 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;
|
||||
hit.Normalize();
|
||||
return hit;
|
||||
}
|
||||
|
||||
/*
|
||||
Nella trackball classica si considera
|
||||
void PlaneMode::Apply(Trackball *tb, Point3f new_point) {
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$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
|
||||
Commented out unused parameter names and other minor warning related issues
|
||||
|
||||
|
@ -36,61 +39,65 @@ Adding copyright.
|
|||
#ifndef TRACKMODE_H
|
||||
#define TRACKMODE_H
|
||||
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/math/similarity.h>
|
||||
#include <wrap/gui/trackball.h>
|
||||
#include <vcg/space/line3.h>
|
||||
#include <vcg/space/plane3.h>
|
||||
#include <wrap/gui/view.h>
|
||||
|
||||
namespace vcg {
|
||||
|
||||
class Trackball;
|
||||
|
||||
class TrackMode {
|
||||
public:
|
||||
virtual ~TrackMode() {}
|
||||
virtual void Apply(Trackball *trackball, Point3f new_point) = 0;
|
||||
virtual void Draw() {}
|
||||
//virtual void Draw() {}
|
||||
virtual Similarityf ComputeFromWindow(const Point3f &/* oldp */, const Point3f &/* newp */) { return Similarityf().SetIdentity(); }
|
||||
Point3f Hit(const Point3f &p);
|
||||
Trackball *tb;
|
||||
|
||||
// virtual Similarityf ComputeFromWindow(const Point3f &old_point,
|
||||
//const Point3f &new_point) = 0;
|
||||
// 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 {
|
||||
public:
|
||||
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 {
|
||||
public:
|
||||
public:
|
||||
void Apply(Trackball *trackball, Point3f new_point);
|
||||
protected:
|
||||
Point3f Hit(Trackball *trackball, const Point3f &p);
|
||||
};
|
||||
|
||||
class CylinderMode: public TrackMode {
|
||||
public:
|
||||
CylinderMode(const Point3f _axis): axis(_axis) { axis.Normalize(); }
|
||||
CylinderMode(const Line3f &line, float radius = 1) {}
|
||||
void Apply(Trackball *trackball, Point3f new_point) {}
|
||||
protected:
|
||||
Point3f axis;
|
||||
Line3f line;
|
||||
float radius;
|
||||
};
|
||||
|
||||
class PlaneMode: public TrackMode {
|
||||
public:
|
||||
PlaneMode(const Point3f _x, const Point3f _y): x(_x), y(_y) { x.Normalize(); y.Normalize(); }
|
||||
Similarityf ComputeFromWindow(const Point3f &oldP, const Point3f &newP);
|
||||
PlaneMode(const Plane3f &pl): plane(pl) {}
|
||||
void Apply(Trackball *trackball, Point3f new_point);
|
||||
protected:
|
||||
Point3f x;
|
||||
Point3f y;
|
||||
Plane3f plane;
|
||||
};
|
||||
|
||||
class LineMode: public TrackMode {
|
||||
public:
|
||||
LineMode(const Point3f _axis): axis(_axis) { axis.Normalize();}
|
||||
LineMode(const Line3f &line) {}
|
||||
void Apply(Trackball *trackball, Point3f new_point) {}
|
||||
protected:
|
||||
Point3f axis;
|
||||
Line3f line;
|
||||
};
|
||||
|
||||
class ScaleMode: public TrackMode {
|
||||
public:
|
||||
void Apply(Trackball *trackball, Point3f new_point) {}
|
||||
};
|
||||
|
||||
}//namespace
|
||||
|
|
Loading…
Reference in New Issue