Heavily restructured. To be completed only rotation works...
This commit is contained in:
parent
68a6f52588
commit
782b814293
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.7 2004/05/14 03:15:09 ponchio
|
||||
Redesigned partial version.
|
||||
|
||||
Revision 1.6 2004/05/12 20:55:18 ponchio
|
||||
*** empty log message ***
|
||||
|
||||
|
@ -41,7 +44,7 @@ Adding copyright.
|
|||
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include<gl/glew.h>
|
||||
#include "trackball.h"
|
||||
|
||||
#include <wrap/gl/math.h>
|
||||
|
@ -111,7 +114,15 @@ void Trackball::GetView() {
|
|||
}
|
||||
|
||||
void Trackball::Apply() {
|
||||
glTranslate(center);
|
||||
glMultMatrix(track.Matrix());
|
||||
glTranslate(-center);
|
||||
}
|
||||
|
||||
void Trackball::ApplyInverse() {
|
||||
glTranslate(center);
|
||||
glMultMatrix(track.InverseMatrix());
|
||||
glTranslate(-center);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
@ -163,6 +174,15 @@ void Trackball::DrawPlaneHandle() {
|
|||
}
|
||||
|
||||
void Trackball::Draw() {
|
||||
|
||||
glPushMatrix();
|
||||
ApplyInverse();
|
||||
glBegin(GL_POINTS);
|
||||
for(int i=0;i<Hits.size();++i)
|
||||
glVertex(Hits[i]);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glTranslate(center);
|
||||
|
@ -183,17 +203,15 @@ void Trackball::Draw() {
|
|||
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,amb);
|
||||
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,col);
|
||||
glPushMatrix();
|
||||
DrawCircle();
|
||||
glPushMatrix();
|
||||
|
||||
DrawCircle();
|
||||
glPushMatrix();
|
||||
|
||||
glRotatef(90,1,0,0);
|
||||
DrawCircle();
|
||||
glRotatef(90,0,1,0);
|
||||
DrawCircle();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glRotatef(90,1,0,0);
|
||||
DrawCircle();
|
||||
glRotatef(90,0,1,0);
|
||||
DrawCircle();
|
||||
|
||||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
|
||||
glColor4f(1.0,.8f,.8f,1.0f);
|
||||
|
@ -249,10 +267,11 @@ void Trackball::Reset() {
|
|||
}
|
||||
|
||||
//interface
|
||||
void Trackball::MouseDown(int x, int y, Trackball::Button button) {
|
||||
void Trackball::MouseDown(int x, int y, int button) {
|
||||
current_button |= button;
|
||||
SetCurrentAction();
|
||||
last_point = Point3f((float)x, (float)y, 0);
|
||||
Hits.clear();
|
||||
}
|
||||
|
||||
void Trackball::MouseMove(int x, int y) {
|
||||
|
@ -264,7 +283,7 @@ void Trackball::MouseMove(int x, int y) {
|
|||
current_mode->Apply(this, Point3f(float(x), float(y), 0));
|
||||
}
|
||||
|
||||
void Trackball::MouseUp(int /* x */, int /* y */, Trackball::Button button) {
|
||||
void Trackball::MouseUp(int /* x */, int /* y */, int button) {
|
||||
current_button &= (~button);
|
||||
SetCurrentAction();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.6 2004/05/14 03:15:09 ponchio
|
||||
Redesigned partial version.
|
||||
|
||||
Revision 1.5 2004/05/12 20:55:18 ponchio
|
||||
*** empty log message ***
|
||||
|
||||
|
@ -47,17 +50,13 @@ Adding copyright.
|
|||
#include <wrap/gui/view.h>
|
||||
#include <wrap/gui/trackmode.h>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#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.
|
||||
|
||||
/* A trackball stores a transformation called 'track' that effectively rotate the object.
|
||||
the rotation center, and size are kept in center and radius.
|
||||
|
||||
*/
|
||||
|
||||
class Transform {
|
||||
|
@ -97,6 +96,7 @@ namespace vcg {
|
|||
//operating
|
||||
void GetView();
|
||||
void Apply();
|
||||
void ApplyInverse();
|
||||
void Draw();
|
||||
void ApplynDraw() { Apply(); Draw(); }
|
||||
void Reset();
|
||||
|
@ -107,9 +107,9 @@ namespace vcg {
|
|||
static void DrawPlaneHandle();
|
||||
|
||||
//interface
|
||||
void MouseDown(int x, int y, Button button);
|
||||
void MouseDown(int x, int y, /*Button*/ int button);
|
||||
void MouseMove(int x, int y);
|
||||
void MouseUp(int x, int y, Button button);
|
||||
void MouseUp(int x, int y, /*Button */ int button);
|
||||
void MouseWheel(Button notch);
|
||||
void ButtonUp(Button button);
|
||||
void ButtonDown(Button button);
|
||||
|
@ -147,15 +147,9 @@ namespace vcg {
|
|||
};
|
||||
|
||||
|
||||
///Find the current action ussing the current button
|
||||
|
||||
|
||||
//protected:
|
||||
View<float> camera;
|
||||
|
||||
/* float ScreenRadius;
|
||||
Point3f ScreenCenter;*/
|
||||
|
||||
void SetCurrentAction();
|
||||
|
||||
int current_button;
|
||||
|
@ -166,6 +160,7 @@ namespace vcg {
|
|||
Similarityf last_track;
|
||||
Similarityf last_view;
|
||||
Point3f last_point;
|
||||
std::vector<Point3f> Hits;
|
||||
bool dragging;
|
||||
int button_mask;
|
||||
|
||||
|
@ -176,14 +171,6 @@ namespace vcg {
|
|||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.5 2004/05/14 03:15:09 ponchio
|
||||
Redesigned partial version.
|
||||
|
||||
Revision 1.4 2004/05/07 12:46:08 cignoni
|
||||
Restructured and adapted in a better way to opengl
|
||||
|
||||
|
@ -45,15 +48,20 @@ Adding copyright.
|
|||
using namespace std;
|
||||
|
||||
using namespace vcg;
|
||||
|
||||
Plane3f TrackMode::GetViewPlane(const View<float> &camera, Point3f center) {
|
||||
/// Compute the plane plane perpedicular to view dir and passing through manip center
|
||||
Plane3f TrackMode::GetViewPlane(const View<float> &camera, const Point3f ¢er) {
|
||||
Point3f vp = camera.ViewPoint();
|
||||
|
||||
Plane3f pl; //plane perpedicular to view dir and passing through manip center
|
||||
pl.Set(vp - center, (vp - center)*center);
|
||||
Plane3f pl;
|
||||
Point3f plnorm= vp - center;
|
||||
plnorm.Normalize();
|
||||
pl.Set(plnorm, plnorm*center);
|
||||
return pl;
|
||||
}
|
||||
|
||||
/// Given a point p in window coordinate it compute the point where the lie p
|
||||
/// over the plane paralell the viewplane and passing through the center of the trackball
|
||||
|
||||
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);
|
||||
|
@ -65,14 +73,23 @@ Point3f TrackMode::HitViewPlane(Trackball *tb, const Point3f &p) {
|
|||
return PonVP;
|
||||
}
|
||||
|
||||
|
||||
// the most important function; given a new point in window coord, it update the transformation computed by the trackball.
|
||||
// General scheme : the transformation is a function of just the begin and current mouse positions, with greater precision is function of just two 3d points over the manipulator.
|
||||
void SphereMode::Apply(Trackball *tb, Point3f new_point) {
|
||||
Point3f hitOld=Hit(tb, tb->last_point);
|
||||
Point3f hitNew=Hit(tb, new_point);
|
||||
tb->Hits.push_back(hitNew);
|
||||
|
||||
Point3f axis = (hitNew- tb->center)^(hitOld- tb->center);
|
||||
|
||||
// Figure out how much to rotate around that axis.
|
||||
//float phi=Angle((hitNew- tb->center),(hitOld- tb->center));
|
||||
float phi = Distance(hitNew,hitOld) / tb->radius;
|
||||
|
||||
tb->track.rot = tb->last_track.rot * Quaternionf(phi,axis);
|
||||
/* Codice Originale Ponchio
|
||||
|
||||
Point3f ref = (tb->camera.ViewPoint() - tb->center).Normalize();
|
||||
|
||||
|
||||
Point3f axis = hitNew^ref;
|
||||
axis.Normalize();
|
||||
float dist = (hitNew - ref).Norm()/2;
|
||||
|
@ -88,9 +105,65 @@ void SphereMode::Apply(Trackball *tb, Point3f new_point) {
|
|||
Quaternionf diff = r * Quaternionf(phi, axis) *
|
||||
Quaternionf(-ophi, oaxis) * Inverse(r);
|
||||
|
||||
tb->track = Similarityf().SetRotate(diff) * tb->last_track;
|
||||
tb->track = Similarityf().SetRotate(diff) * tb->last_track;*/
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
dato un punto in coordinate di schermo e.g. in pixel stile opengl
|
||||
calcola il punto di intersezione tra la viewline che passa per viewpoint e per hitplane e l'iperboloide.
|
||||
l'iperboloide si assume essere quello di rotazione attorno alla retta viewpoint-center e di raggio rad
|
||||
si assume come sistema di riferimento quello con l'origine su center ecome x la retta center-viewpoint
|
||||
|
||||
eq linea
|
||||
hitplane.y
|
||||
y = - ----------- * x + hitplane.y
|
||||
viewpoint.x
|
||||
|
||||
eq hiperboloide di raggio r (e.g. che passa per (r/sqrt2,r/sqrt2)
|
||||
|
||||
1
|
||||
y = --- * (r^2 /2.0)
|
||||
x
|
||||
|
||||
hitplane.y
|
||||
----------- * x^2 - hitplane.y *x + (r^2/2.0) == 0
|
||||
viewpoint.x
|
||||
|
||||
*/
|
||||
bool SphereMode::HitHyper(Point3f center, float radius, Point3f viewpoint, Plane3f vp, Point3f hitplane, Point3f &hit)
|
||||
{
|
||||
float hitplaney = Distance(center,hitplane);
|
||||
float viewpointx= Distance(center,viewpoint);
|
||||
|
||||
float a = hitplaney/viewpointx;
|
||||
float b = -hitplaney;
|
||||
float c = radius*radius/2.0f;
|
||||
float delta = b*b - 4*a*c;
|
||||
float x1,x2,xval,yval;
|
||||
if(delta>0)
|
||||
{
|
||||
x1= (- b - sqrt(delta))/(2.0*a);
|
||||
x2= (- b + sqrt(delta))/(2.0*a);
|
||||
|
||||
xval=x1; // always take the minimum value solution
|
||||
yval=c/xval; // alternatively it also oould be the other part of the equation yval=-(hitplaney/viewpointx)*xval+hitplaney;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Computing the result in 3d space;
|
||||
Point3f dirRadial=hitplane-center;
|
||||
dirRadial.Normalize();
|
||||
Point3f dirView=vp.Direction();
|
||||
dirView.Normalize();
|
||||
hit= center +dirRadial*yval+dirView*xval;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* dato un punto in coordinate di schermo e.g. in pixel stile opengl
|
||||
restituisce un punto in coordinate di mondo sulla superficie
|
||||
della trackball.
|
||||
|
@ -101,45 +174,76 @@ void SphereMode::Apply(Trackball *tb, Point3f new_point) {
|
|||
|
||||
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 iperboloide : y=1/2*x; inf sqrt(1/2) 1/2
|
||||
eq cono y=x+sqrt(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(tb->camera, tb->center);
|
||||
vp.SetOffset(vp.Offset() + Thr);
|
||||
Point3f hit,hitPlane,hitSphere,hitSphere1,hitSphere2,hitHyper;
|
||||
Intersection<float>(vp, ln, hitPlane);
|
||||
Sphere3f sphere(tb->center,tb->radius);
|
||||
bool resSp = Intersection<float>(sphere, ln, hitSphere1, hitSphere2);
|
||||
if(Distance(viewpoint,hitSphere1)<Distance(viewpoint,hitSphere2))
|
||||
hitSphere=hitSphere1;
|
||||
else hitSphere=hitSphere2;
|
||||
|
||||
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);
|
||||
float dl=Distance(ln,tb->center);
|
||||
bool resHp = HitHyper(tb->center, tb->radius, viewpoint, vp, hitPlane, hitHyper) ;
|
||||
|
||||
//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);
|
||||
// four cases
|
||||
|
||||
// 1) Degenerate line tangent to both sphere and hyperboloid!
|
||||
if((!resSp && !resHp) )
|
||||
{
|
||||
hit=ClosestPoint(ln,tb->center);
|
||||
//printf("closest point to line %f\n",Distance(hit,tb->center));
|
||||
return hit;
|
||||
}
|
||||
hit.Normalize();
|
||||
return hit;
|
||||
if((resSp && !resHp) ) return hitSphere; // 2) line cross only the sphere
|
||||
if((!resSp && resHp) ) return hitHyper; // 3) line cross only the hyperboloid
|
||||
|
||||
// 4) line cross both sphere and hyperboloid: choose according angle.
|
||||
float angleDeg=math::ToDeg(Angle((viewpoint-tb->center),(hitSphere-tb->center)));
|
||||
//printf("Angle %f (%5.2f %5.2f %5.2f) (%5.2f %5.2f %5.2f)\n",angleDeg,hitSphere[0],hitSphere[1],hitSphere[2],hitHyper[0],hitHyper[1],hitHyper[2]);
|
||||
if(angleDeg<45) return hitSphere;
|
||||
else return hitHyper;
|
||||
|
||||
//
|
||||
// Codice ORIGINALE PONCHIO
|
||||
//vp.SetOffset(vp.Offset() + Thr);
|
||||
|
||||
//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);
|
||||
//}
|
||||
// hit.Normalize();
|
||||
// return hit;
|
||||
}
|
||||
|
||||
void PlaneMode::Apply(Trackball *tb, Point3f new_point) {
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.5 2004/05/14 03:15:09 ponchio
|
||||
Redesigned partial version.
|
||||
|
||||
Revision 1.4 2004/05/07 12:46:08 cignoni
|
||||
Restructured and adapted in a better way to opengl
|
||||
|
||||
|
@ -52,12 +55,8 @@ public:
|
|||
virtual ~TrackMode() {}
|
||||
virtual void Apply(Trackball *trackball, Point3f new_point) = 0;
|
||||
virtual void Draw() {}
|
||||
//virtual void Draw() {}
|
||||
// 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);
|
||||
Plane3f GetViewPlane(const View<float> &view, const Point3f ¢er);
|
||||
Point3f HitViewPlane(Trackball *trackball, const Point3f &p);
|
||||
};
|
||||
|
||||
|
@ -68,12 +67,14 @@ class SphereMode: public TrackMode {
|
|||
void Apply(Trackball *trackball, Point3f new_point);
|
||||
protected:
|
||||
Point3f Hit(Trackball *trackball, const Point3f &p);
|
||||
bool HitHyper(Point3f center, float radius, Point3f viewpoint, Plane3f vp, Point3f hitplane, Point3f &hit) ;
|
||||
|
||||
};
|
||||
|
||||
class CylinderMode: public TrackMode {
|
||||
public:
|
||||
CylinderMode(const Line3f &line, float radius = 1) {}
|
||||
void Apply(Trackball *trackball, Point3f new_point) {}
|
||||
CylinderMode(const Line3f &/*line*/, float /*radius = 1*/) {}
|
||||
void Apply(Trackball * /*trackball*/, Point3f /*new_point*/) {}
|
||||
protected:
|
||||
Line3f line;
|
||||
float radius;
|
||||
|
@ -89,15 +90,15 @@ protected:
|
|||
|
||||
class LineMode: public TrackMode {
|
||||
public:
|
||||
LineMode(const Line3f &line) {}
|
||||
void Apply(Trackball *trackball, Point3f new_point) {}
|
||||
LineMode(const Line3f &/*line*/) {}
|
||||
void Apply(Trackball * /*trackball*/, Point3f /*new_point*/) {}
|
||||
protected:
|
||||
Line3f line;
|
||||
};
|
||||
|
||||
class ScaleMode: public TrackMode {
|
||||
public:
|
||||
void Apply(Trackball *trackball, Point3f new_point) {}
|
||||
void Apply(Trackball * /*trackball*/, Point3f /*new_point*/) {}
|
||||
};
|
||||
|
||||
}//namespace
|
||||
|
|
Loading…
Reference in New Issue