Trackball Improvement. Now it works well also for ortho views
This commit is contained in:
parent
63046a8bab
commit
1ff3a301ec
|
@ -42,7 +42,7 @@ void TrackMode::SetAction (){}
|
||||||
void TrackMode::Reset (){}
|
void TrackMode::Reset (){}
|
||||||
|
|
||||||
bool TrackMode::IsAnimating(const Trackball *){
|
bool TrackMode::IsAnimating(const Trackball *){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackMode::Animate(unsigned int, Trackball *){
|
void TrackMode::Animate(unsigned int, Trackball *){
|
||||||
|
@ -72,9 +72,13 @@ void SphereMode::Apply (Trackball * tb, Point3f new_point)
|
||||||
tb->Hits.push_back (hitNew);
|
tb->Hits.push_back (hitNew);
|
||||||
Point3f center = tb->center;
|
Point3f center = tb->center;
|
||||||
Point3f axis = (hitNew - center) ^ (hitOld - center);
|
Point3f axis = (hitNew - center) ^ (hitOld - center);
|
||||||
|
vcg::Normalize(axis);
|
||||||
|
|
||||||
// Figure out how much to rotate around that axis.
|
// Figure out how much to rotate around that axis.
|
||||||
float phi = Distance (hitNew, hitOld) / tb->radius;
|
// float phi = Distance (hitNew, hitOld) / tb->radius;
|
||||||
// tb->track.rot = tb->last_track.rot * Quaternionf (-phi, axis);
|
// float phi = vcg::Angle(hitNew - center,hitOld - center)*(Distance(hitNew,center)/tb->radius);
|
||||||
|
float phi = max(vcg::Angle(hitNew - center,hitOld - center),(Distance(hitNew,hitOld)/tb->radius)) ;
|
||||||
|
|
||||||
tb->track.rot = Quaternionf (-phi, axis) * tb->last_track.rot;
|
tb->track.rot = Quaternionf (-phi, axis) * tb->last_track.rot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +161,7 @@ void PlaneMode::Apply (Trackball * tb, Point3f new_point)
|
||||||
std::pair< Point3f, bool > hitOld = HitPlane(tb,tb->last_point,plane);
|
std::pair< Point3f, bool > hitOld = HitPlane(tb,tb->last_point,plane);
|
||||||
std::pair< Point3f, bool > hitNew = HitPlane(tb,new_point,plane);
|
std::pair< Point3f, bool > hitNew = HitPlane(tb,new_point,plane);
|
||||||
if(hitOld.second && hitNew.second){
|
if(hitOld.second && hitNew.second){
|
||||||
tb->Translate (hitNew.first - hitOld.first);
|
tb->Translate (hitNew.first - hitOld.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,21 +246,21 @@ Point3f PathMode::SetStartNear(Point3f point)
|
||||||
float nearest_distance=Distance(nearest_point,point);
|
float nearest_distance=Distance(nearest_point,point);
|
||||||
unsigned int npts = int(points.size());
|
unsigned int npts = int(points.size());
|
||||||
for(unsigned int i = 1;i <= npts;i++){
|
for(unsigned int i = 1;i <= npts;i++){
|
||||||
if( i == npts){
|
if( i == npts){
|
||||||
if (wrap){
|
if (wrap){
|
||||||
p0=points[npts-1];
|
p0=points[npts-1];
|
||||||
p1=points[0];
|
p1=points[0];
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p0=points[i-1];
|
p0=points[i-1];
|
||||||
p1=points[i];
|
p1=points[i];
|
||||||
}
|
}
|
||||||
//Point3f segment_point=ClosestPoint(Segment3f(p0,p1),point);
|
//Point3f segment_point=ClosestPoint(Segment3f(p0,p1),point);
|
||||||
Point3f segment_point;
|
Point3f segment_point;
|
||||||
float distance;
|
float distance;
|
||||||
vcg::SegmentPointDistance<float>(Segment3f(p0,p1),point,segment_point,distance);
|
vcg::SegmentPointDistance<float>(Segment3f(p0,p1),point,segment_point,distance);
|
||||||
// float distance=Distance(segment_point,point);
|
// float distance=Distance(segment_point,point);
|
||||||
if(distance<nearest_distance){
|
if(distance<nearest_distance){
|
||||||
nearest_point=segment_point;
|
nearest_point=segment_point;
|
||||||
|
@ -283,17 +287,17 @@ void PathMode::GetPoints(float state, Point3f & point, Point3f & prev_point, Poi
|
||||||
Point3f p0(0,0,0),p1(0,0,0);
|
Point3f p0(0,0,0),p1(0,0,0);
|
||||||
unsigned int npts = int(points.size());
|
unsigned int npts = int(points.size());
|
||||||
for(unsigned int i = 1;i <= npts;i++){
|
for(unsigned int i = 1;i <= npts;i++){
|
||||||
if( i == npts){
|
if( i == npts){
|
||||||
if (wrap){
|
if (wrap){
|
||||||
p0=points[npts-1];
|
p0=points[npts-1];
|
||||||
p1=points[0];
|
p1=points[0];
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p0=points[i-1];
|
p0=points[i-1];
|
||||||
p1=points[i];
|
p1=points[i];
|
||||||
}
|
}
|
||||||
float segment_norm= Distance(p0,p1) / path_length;
|
float segment_norm= Distance(p0,p1) / path_length;
|
||||||
if (segment_norm < remaining_norm){
|
if (segment_norm < remaining_norm){
|
||||||
remaining_norm -= segment_norm;
|
remaining_norm -= segment_norm;
|
||||||
|
@ -303,24 +307,24 @@ void PathMode::GetPoints(float state, Point3f & point, Point3f & prev_point, Poi
|
||||||
next_point = p1;
|
next_point = p1;
|
||||||
float ratio= remaining_norm / segment_norm;
|
float ratio= remaining_norm / segment_norm;
|
||||||
point = prev_point + (( next_point - prev_point ) * ratio);
|
point = prev_point + (( next_point - prev_point ) * ratio);
|
||||||
const float EPSILON=min_seg_length * 0.01f;
|
const float EPSILON=min_seg_length * 0.01f;
|
||||||
if(Distance(point,prev_point) < EPSILON){
|
if(Distance(point,prev_point) < EPSILON){
|
||||||
point=prev_point;
|
point=prev_point;
|
||||||
if (i > 1){
|
if (i > 1){
|
||||||
prev_point=points[i-2];
|
prev_point=points[i-2];
|
||||||
} else if (wrap){
|
} else if (wrap){
|
||||||
prev_point=points[npts-1];
|
prev_point=points[npts-1];
|
||||||
}
|
}
|
||||||
} else if (Distance(point,next_point) < EPSILON){
|
} else if (Distance(point,next_point) < EPSILON){
|
||||||
point=next_point;
|
point=next_point;
|
||||||
if( i < (npts-1)){
|
if( i < (npts-1)){
|
||||||
next_point=points[i+1];
|
next_point=points[i+1];
|
||||||
} else {
|
} else {
|
||||||
if (wrap){
|
if (wrap){
|
||||||
next_point=points[1];
|
next_point=points[1];
|
||||||
} else {
|
} else {
|
||||||
next_point=points[npts-1];
|
next_point=points[npts-1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -412,14 +416,14 @@ float PathMode::HitPoint(float state, Ray3fN ray, Point3f &hit_point)
|
||||||
|
|
||||||
Segment3f active_segment;
|
Segment3f active_segment;
|
||||||
if (verse > 0){
|
if (verse > 0){
|
||||||
active_segment=Segment3f(current_point,next_point);
|
active_segment=Segment3f(current_point,next_point);
|
||||||
} else {
|
} else {
|
||||||
active_segment= Segment3f(current_point,prev_point);
|
active_segment= Segment3f(current_point,prev_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
//hit_point=ClosestPoint(active_segment,closest_point);
|
//hit_point=ClosestPoint(active_segment,closest_point);
|
||||||
float dist;
|
float dist;
|
||||||
vcg::SegmentPointDistance<float>(active_segment,closest_point,hit_point,dist);
|
vcg::SegmentPointDistance<float>(active_segment,closest_point,hit_point,dist);
|
||||||
|
|
||||||
return verse * ((hit_point-current_point).Norm() / path_length);
|
return verse * ((hit_point-current_point).Norm() / path_length);
|
||||||
}
|
}
|
||||||
|
@ -471,14 +475,14 @@ void AreaMode::Init(const std::vector < Point3f > &pts)
|
||||||
bool pts_not_in_line=false;
|
bool pts_not_in_line=false;
|
||||||
Point3f a,b;
|
Point3f a,b;
|
||||||
for(unsigned int i=0;i<onethird;i++){
|
for(unsigned int i=0;i<onethird;i++){
|
||||||
a=(pts[(i+ onethird )%npts] - pts[i%npts]).normalized();
|
a=(pts[(i+ onethird )%npts] - pts[i%npts]).normalized();
|
||||||
b=(pts[(i+(2*onethird))%npts] - pts[i%npts]).normalized();
|
b=(pts[(i+(2*onethird))%npts] - pts[i%npts]).normalized();
|
||||||
pts_not_in_line = (a ^ b).Norm() > EPSILON;
|
pts_not_in_line = (a ^ b).Norm() > EPSILON;
|
||||||
if(pts_not_in_line){
|
if(pts_not_in_line){
|
||||||
plane.Init( pts[i%npts],
|
plane.Init( pts[i%npts],
|
||||||
pts[(i+(onethird))%npts],
|
pts[(i+(onethird))%npts],
|
||||||
pts[(i+(2*onethird))%npts]);
|
pts[(i+(2*onethird))%npts]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(pts_not_in_line);
|
assert(pts_not_in_line);
|
||||||
|
@ -498,11 +502,11 @@ void AreaMode::Init(const std::vector < Point3f > &pts)
|
||||||
}
|
}
|
||||||
points.reserve(npts);
|
points.reserve(npts);
|
||||||
for(unsigned int i=0;i<npts;i++){
|
for(unsigned int i=0;i<npts;i++){
|
||||||
points.push_back(plane.Projection(pts[i]));
|
points.push_back(plane.Projection(pts[i]));
|
||||||
}
|
}
|
||||||
min_side_length=Distance(points[0],points[1]);
|
min_side_length=Distance(points[0],points[1]);
|
||||||
for(unsigned int i=1;i<npts;i++){
|
for(unsigned int i=1;i<npts;i++){
|
||||||
min_side_length=(std::min)(Distance(points[i-1],points[i]),min_side_length);
|
min_side_length=(std::min)(Distance(points[i-1],points[i]),min_side_length);
|
||||||
}
|
}
|
||||||
rubberband_handle=old_status=status=initial_status=p0;
|
rubberband_handle=old_status=status=initial_status=p0;
|
||||||
}
|
}
|
||||||
|
@ -528,7 +532,7 @@ void AreaMode::Apply (Trackball * tb, Point3f new_point)
|
||||||
}
|
}
|
||||||
std::pair< Point3f, bool > hitNew = HitPlane(tb,new_point+delta_mouse,plane);
|
std::pair< Point3f, bool > hitNew = HitPlane(tb,new_point+delta_mouse,plane);
|
||||||
if(! hitNew.second){
|
if(! hitNew.second){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Point3f hit_point=hitNew.first;
|
Point3f hit_point=hitNew.first;
|
||||||
Point3f delta_status=Move(status,hit_point);
|
Point3f delta_status=Move(status,hit_point);
|
||||||
|
@ -555,7 +559,7 @@ Point3f AreaMode::Move(Point3f start,Point3f end)
|
||||||
bool done=false;
|
bool done=false;
|
||||||
bool end_inside=Inside(end);
|
bool end_inside=Inside(end);
|
||||||
while(!done){
|
while(!done){
|
||||||
path.push_back(pt);
|
path.push_back(pt);
|
||||||
Segment3f segment(pt,end);
|
Segment3f segment(pt,end);
|
||||||
bool p_on_side = false;
|
bool p_on_side = false;
|
||||||
bool hit=false;
|
bool hit=false;
|
||||||
|
@ -568,25 +572,25 @@ Point3f AreaMode::Move(Point3f start,Point3f end)
|
||||||
Segment3f side(points[i],points[j]);
|
Segment3f side(points[i],points[j]);
|
||||||
Point3f pseg,psid;
|
Point3f pseg,psid;
|
||||||
//std::pair<float,bool> res=SegmentSegmentDistance(segment,side,pseg,psid);
|
//std::pair<float,bool> res=SegmentSegmentDistance(segment,side,pseg,psid);
|
||||||
std::pair<float,bool> res;
|
std::pair<float,bool> res;
|
||||||
vcg::SegmentSegmentDistance(segment,side,res.first,res.second,pseg,psid);
|
vcg::SegmentSegmentDistance(segment,side,res.first,res.second,pseg,psid);
|
||||||
if(res.first < EPSILON && ! res.second){
|
if(res.first < EPSILON && ! res.second){
|
||||||
float dist= Distance(pt,pseg);
|
float dist= Distance(pt,pseg);
|
||||||
if(dist < EPSILON){
|
if(dist < EPSILON){
|
||||||
//Point3f pn=ClosestPoint(side,end);
|
//Point3f pn=ClosestPoint(side,end);
|
||||||
Point3f pn;
|
Point3f pn;
|
||||||
float dist;
|
float dist;
|
||||||
vcg::SegmentPointDistance<float>(side,end,pn,dist);
|
vcg::SegmentPointDistance<float>(side,end,pn,dist);
|
||||||
if(!p_on_side || (Distance(pn,end)<Distance(end,pside))){
|
if(!p_on_side || (Distance(pn,end)<Distance(end,pside))){
|
||||||
pside=pn;
|
pside=pn;
|
||||||
p_on_side=true;
|
p_on_side=true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!hit || Distance(pt,pseg) < Distance(pt,phit)){
|
if (!hit || Distance(pt,pseg) < Distance(pt,phit)){
|
||||||
phit=pseg;
|
phit=pseg;
|
||||||
hit=true;
|
hit=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p_on_side)
|
if (p_on_side)
|
||||||
|
@ -620,15 +624,15 @@ bool AreaMode::Inside(Point3f point)
|
||||||
float yi, yj, xi, xj;
|
float yi, yj, xi, xj;
|
||||||
int i, j, np=int(points.size());
|
int i, j, np=int(points.size());
|
||||||
for (i = 0, j = np-1; i < np; j = i++) {
|
for (i = 0, j = np-1; i < np; j = i++) {
|
||||||
xi=points[i][first_coord_kept];
|
xi=points[i][first_coord_kept];
|
||||||
yi=points[i][second_coord_kept];
|
yi=points[i][second_coord_kept];
|
||||||
xj=points[j][first_coord_kept];
|
xj=points[j][first_coord_kept];
|
||||||
yj=points[j][second_coord_kept];
|
yj=points[j][second_coord_kept];
|
||||||
if ( ( ( (yi<=y) && (y<yj) ) || ( (yj<=y) && (y<yi) ) ) &&
|
if ( ( ( (yi<=y) && (y<yj) ) || ( (yj<=y) && (y<yi) ) ) &&
|
||||||
( x < ( xj - xi ) * ( y - yi ) / ( yj - yi ) + xi ) )
|
( x < ( xj - xi ) * ( y - yi ) / ( yj - yi ) + xi ) )
|
||||||
{
|
{
|
||||||
inside=!inside;
|
inside=!inside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
|
@ -647,9 +651,9 @@ Point3f AreaMode::SetStartNear(Point3f point)
|
||||||
Segment3f side(points[i],points[j]);
|
Segment3f side(points[i],points[j]);
|
||||||
//Point3f side_point=ClosestPoint(side,candidate);
|
//Point3f side_point=ClosestPoint(side,candidate);
|
||||||
//float distance=Distance(side_point,candidate);
|
//float distance=Distance(side_point,candidate);
|
||||||
Point3f side_point;
|
Point3f side_point;
|
||||||
float distance;
|
float distance;
|
||||||
vcg::SegmentPointDistance<float>(side,candidate,side_point,distance);
|
vcg::SegmentPointDistance<float>(side,candidate,side_point,distance);
|
||||||
if( distance < nearest_distance ){
|
if( distance < nearest_distance ){
|
||||||
nearest_point=side_point;
|
nearest_point=side_point;
|
||||||
nearest_distance=distance;
|
nearest_distance=distance;
|
||||||
|
@ -721,17 +725,17 @@ void PolarMode::Draw(Trackball * tb){
|
||||||
NavigatorWasdMode::NavigatorWasdMode() {
|
NavigatorWasdMode::NavigatorWasdMode() {
|
||||||
_flipH=1; _flipV=1;
|
_flipH=1; _flipV=1;
|
||||||
SetTopSpeedsAndAcc(1,1,4);
|
SetTopSpeedsAndAcc(1,1,4);
|
||||||
step_height = step_length = 0;
|
step_height = step_length = 0;
|
||||||
Reset();
|
Reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
void NavigatorWasdMode::Reset() {
|
void NavigatorWasdMode::Reset() {
|
||||||
alpha=0;
|
alpha=0;
|
||||||
beta=0;
|
beta=0;
|
||||||
current_speed.SetZero();
|
current_speed.SetZero();
|
||||||
step_x=0.0f;
|
step_x=0.0f;
|
||||||
|
|
||||||
step_current = step_last = 0.0;
|
step_current = step_last = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorWasdMode::FlipH(){
|
void NavigatorWasdMode::FlipH(){
|
||||||
|
@ -748,51 +752,51 @@ void NavigatorWasdMode::SetAction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NavigatorWasdMode::IsAnimating(const Trackball * tb){
|
bool NavigatorWasdMode::IsAnimating(const Trackball * tb){
|
||||||
const unsigned int MOVEMENT_KEY_MASK = (const unsigned int)(~Trackball::MODIFIER_MASK);
|
const unsigned int MOVEMENT_KEY_MASK = (const unsigned int)(~Trackball::MODIFIER_MASK);
|
||||||
if (tb->current_button & MOVEMENT_KEY_MASK) return true;
|
if (tb->current_button & MOVEMENT_KEY_MASK) return true;
|
||||||
if (current_speed!=Point3f(0,0,0)) return true;
|
if (current_speed!=Point3f(0,0,0)) return true;
|
||||||
if (step_current>0.0) return true;
|
if (step_current>0.0) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorWasdMode::Animate(unsigned int msec, Trackball * tb){
|
void NavigatorWasdMode::Animate(unsigned int msec, Trackball * tb){
|
||||||
vcg::Point3f acc(0,0,0);
|
vcg::Point3f acc(0,0,0);
|
||||||
|
|
||||||
float sa = sin(-alpha);
|
float sa = sin(-alpha);
|
||||||
float ca = cos(-alpha);
|
float ca = cos(-alpha);
|
||||||
if (tb->current_button & Trackball::KEY_UP ) acc += vcg::Point3f( sa,0,ca)*(accY*_flipH);
|
if (tb->current_button & Trackball::KEY_UP ) acc += vcg::Point3f( sa,0,ca)*(accY*_flipH);
|
||||||
if (tb->current_button & Trackball::KEY_DOWN ) acc -= vcg::Point3f( sa,0,ca)*(accY*_flipH);
|
if (tb->current_button & Trackball::KEY_DOWN ) acc -= vcg::Point3f( sa,0,ca)*(accY*_flipH);
|
||||||
if (tb->current_button & Trackball::KEY_LEFT ) acc -= vcg::Point3f(-ca,0,sa)*accX;
|
if (tb->current_button & Trackball::KEY_LEFT ) acc -= vcg::Point3f(-ca,0,sa)*accX;
|
||||||
if (tb->current_button & Trackball::KEY_RIGHT ) acc += vcg::Point3f(-ca,0,sa)*accX;
|
if (tb->current_button & Trackball::KEY_RIGHT ) acc += vcg::Point3f(-ca,0,sa)*accX;
|
||||||
if (tb->current_button & Trackball::KEY_PGUP ) acc -= vcg::Point3f( 0,1, 0)*accZ;
|
if (tb->current_button & Trackball::KEY_PGUP ) acc -= vcg::Point3f( 0,1, 0)*accZ;
|
||||||
if (tb->current_button & Trackball::KEY_PGDOWN) acc += vcg::Point3f( 0,1, 0)*accZ;
|
if (tb->current_button & Trackball::KEY_PGDOWN) acc += vcg::Point3f( 0,1, 0)*accZ;
|
||||||
|
|
||||||
float sec = msec/1.0f;
|
float sec = msec/1.0f;
|
||||||
current_speed += acc*sec;
|
current_speed += acc*sec;
|
||||||
tb->track.tra+=current_speed*sec;
|
tb->track.tra+=current_speed*sec;
|
||||||
|
|
||||||
// compute step height.
|
// compute step height.
|
||||||
Point3f current_speed_h = current_speed;
|
Point3f current_speed_h = current_speed;
|
||||||
current_speed_h[1]=0;
|
current_speed_h[1]=0;
|
||||||
float vel = current_speed_h.Norm();
|
float vel = current_speed_h.Norm();
|
||||||
if (vel<topSpeedH*0.05) {
|
if (vel<topSpeedH*0.05) {
|
||||||
// stopped: decrease step heigth to zero
|
// stopped: decrease step heigth to zero
|
||||||
step_current*=pow(dumping,sec);
|
step_current*=pow(dumping,sec);
|
||||||
if (step_current<step_height*0.06) { step_current=0; step_x=0.0f;}
|
if (step_current<step_height*0.06) { step_current=0; step_x=0.0f;}
|
||||||
} else {
|
} else {
|
||||||
// running: rise step heigth
|
// running: rise step heigth
|
||||||
vel = current_speed.Norm();
|
vel = current_speed.Norm();
|
||||||
step_x += vel*sec;
|
step_x += vel*sec;
|
||||||
float step_current_min = (float)fabs(sin( step_x*M_PI / step_length ))*step_height;
|
float step_current_min = (float)fabs(sin( step_x*M_PI / step_length ))*step_height;
|
||||||
if (step_current<step_current_min) step_current=step_current_min;
|
if (step_current<step_current_min) step_current=step_current_min;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_speed*=pow(dumping,sec);
|
current_speed*=pow(dumping,sec);
|
||||||
if (current_speed.Norm()<topSpeedH*0.005) current_speed.SetZero(); // full stop
|
if (current_speed.Norm()<topSpeedH*0.005) current_speed.SetZero(); // full stop
|
||||||
|
|
||||||
tb->track.tra[1]+=step_last;
|
tb->track.tra[1]+=step_last;
|
||||||
tb->track.tra[1]-=step_current;
|
tb->track.tra[1]-=step_current;
|
||||||
step_last=step_current;
|
step_last=step_current;
|
||||||
|
|
||||||
//tb->track.tra[1]+=0.01;
|
//tb->track.tra[1]+=0.01;
|
||||||
}
|
}
|
||||||
|
@ -801,7 +805,7 @@ void NavigatorWasdMode::Apply (Trackball * tb, Point3f new_point)
|
||||||
{
|
{
|
||||||
Point3f hitOld = tb->last_point;
|
Point3f hitOld = tb->last_point;
|
||||||
Point3f hitNew = new_point;
|
Point3f hitNew = new_point;
|
||||||
tb->last_point=new_point;
|
tb->last_point=new_point;
|
||||||
float dx = (hitNew.X() - hitOld.X());
|
float dx = (hitNew.X() - hitOld.X());
|
||||||
float dy = (hitNew.Y() - hitOld.Y());
|
float dy = (hitNew.Y() - hitOld.Y());
|
||||||
|
|
||||||
|
@ -816,15 +820,15 @@ void NavigatorWasdMode::Apply (Trackball * tb, Point3f new_point)
|
||||||
if(beta < -top) beta = -top;
|
if(beta < -top) beta = -top;
|
||||||
|
|
||||||
Point3f viewpoint = tb->track.InverseMatrix()*Point3f(0,0,0);
|
Point3f viewpoint = tb->track.InverseMatrix()*Point3f(0,0,0);
|
||||||
tb->track.tra = tb->track.rot.Inverse().Rotate(tb->track.tra + viewpoint ) ;
|
tb->track.tra = tb->track.rot.Inverse().Rotate(tb->track.tra + viewpoint ) ;
|
||||||
tb->track.rot = Quaternionf (beta , Point3f(1,0,0)) *
|
tb->track.rot = Quaternionf (beta , Point3f(1,0,0)) *
|
||||||
Quaternionf (alpha, Point3f(0,1,0)) ;
|
Quaternionf (alpha, Point3f(0,1,0)) ;
|
||||||
tb->track.tra = tb->track.rot.Rotate(tb->track.tra) - viewpoint ;
|
tb->track.tra = tb->track.rot.Rotate(tb->track.tra) - viewpoint ;
|
||||||
|
|
||||||
tb->track.tra[1]+=step_last;
|
tb->track.tra[1]+=step_last;
|
||||||
tb->track.tra[1]-=step_current;
|
tb->track.tra[1]-=step_current;
|
||||||
|
|
||||||
step_last=step_current;
|
step_last=step_current;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,5 +862,5 @@ void NavigatorWasdMode::Apply (Trackball * tb, float WheelNotch)
|
||||||
|
|
||||||
|
|
||||||
bool NavigatorWasdMode::isSticky(){
|
bool NavigatorWasdMode::isSticky(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,51 +20,7 @@
|
||||||
* for more details. *
|
* for more details. *
|
||||||
* *
|
* *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
/****************************************************************************
|
|
||||||
History
|
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
|
||||||
Revision 1.13 2008/02/26 18:46:55 ponchio
|
|
||||||
Fixed bug in drawing position of the trackball when changin center.
|
|
||||||
|
|
||||||
Revision 1.12 2008/02/24 18:10:54 ponchio
|
|
||||||
Fixed scale behaviour.
|
|
||||||
|
|
||||||
Revision 1.11 2008/02/24 18:05:08 ponchio
|
|
||||||
Should work as before. I didn't test cylinder and other exotic modes.
|
|
||||||
|
|
||||||
Revision 1.10 2008/02/24 14:37:00 ponchio
|
|
||||||
Restored trackball functionality. Not very much tested, and code will need some
|
|
||||||
cleanup.
|
|
||||||
|
|
||||||
Revision 1.9 2008/02/22 18:57:47 benedetti
|
|
||||||
first attempt to correct after quaternion ToMatrix() inversion (does not work yet)
|
|
||||||
|
|
||||||
Revision 1.8 2008/02/15 20:54:45 benedetti
|
|
||||||
removed some variable initialization related warning
|
|
||||||
|
|
||||||
Revision 1.7 2007/10/22 14:39:54 cignoni
|
|
||||||
corrected bug into the drawsphere (thanks to nico and guido!)
|
|
||||||
|
|
||||||
Revision 1.6 2007/08/17 09:19:40 cignoni
|
|
||||||
glEnable (GL_LINE_SMOOTH) should go before changing the linewidth.
|
|
||||||
|
|
||||||
Revision 1.5 2007/07/14 12:44:40 benedetti
|
|
||||||
Minor edits in Doxygen documentation.
|
|
||||||
|
|
||||||
Revision 1.4 2007/07/09 22:41:22 benedetti
|
|
||||||
Added Doxygen documentation, removed using namespace std, some other minor changes.
|
|
||||||
|
|
||||||
Revision 1.3 2007/06/12 08:58:08 benedetti
|
|
||||||
Minor fix in DrawUglyCylinderMode()
|
|
||||||
|
|
||||||
Revision 1.2 2007/05/28 08:10:47 fiorin
|
|
||||||
Removed type cast warnings
|
|
||||||
|
|
||||||
Revision 1.1 2007/05/15 14:57:34 benedetti
|
|
||||||
Utility functions for the trackmodes, first version
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef TRACKUTILS_H
|
#ifndef TRACKUTILS_H
|
||||||
#define TRACKUTILS_H
|
#define TRACKUTILS_H
|
||||||
|
@ -337,7 +293,7 @@ std::pair< float, bool > LineLineDistance(const Line3f & P,const Line3f & Q,Poin
|
||||||
const float det = ( VPVP * VQVQ ) - ( VPVQ * VPVQ );
|
const float det = ( VPVP * VQVQ ) - ( VPVQ * VPVQ );
|
||||||
const float EPSILON = 0.00001f;
|
const float EPSILON = 0.00001f;
|
||||||
if ( fabs(det) < EPSILON ) {
|
if ( fabs(det) < EPSILON ) {
|
||||||
return std::make_pair(Distance(P,q0), true);
|
return std::make_pair(Distance(P,q0), true);
|
||||||
}
|
}
|
||||||
float b1= (q0 - p0).dot(Vp);
|
float b1= (q0 - p0).dot(Vp);
|
||||||
float b2= (p0 - q0).dot(Vq);
|
float b2= (p0 - q0).dot(Vq);
|
||||||
|
@ -373,7 +329,7 @@ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3
|
||||||
const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ );
|
const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ );
|
||||||
const float EPSILON = 0.00001f;
|
const float EPSILON = 0.00001f;
|
||||||
if ( ( det >= 0.0f ? det : -det) < EPSILON ) {
|
if ( ( det >= 0.0f ? det : -det) < EPSILON ) {
|
||||||
return std::make_pair(Distance(Q,r0), true);
|
return std::make_pair(Distance(Q,r0), true);
|
||||||
}
|
}
|
||||||
float b1= (q0 - r0).dot(Vr);
|
float b1= (q0 - r0).dot(Vr);
|
||||||
float b2= (r0 - q0).dot(Vq);
|
float b2= (r0 - q0).dot(Vq);
|
||||||
|
@ -492,7 +448,7 @@ std::pair< Point3f,bool > HitNearestPointOnAxis (Trackball * tb,Line3f axis, Poi
|
||||||
Point3f axis_p(0,0,0), ray_p(0,0,0);
|
Point3f axis_p(0,0,0), ray_p(0,0,0);
|
||||||
std::pair< float, bool > resp=RayLineDistance(ray,axis,ray_p,axis_p);
|
std::pair< float, bool > resp=RayLineDistance(ray,axis,ray_p,axis_p);
|
||||||
if(resp.second || (ray_p == ray.Origin())){
|
if(resp.second || (ray_p == ray.Origin())){
|
||||||
return std::make_pair(Point3f(0,0,0),false);
|
return std::make_pair(Point3f(0,0,0),false);
|
||||||
}
|
}
|
||||||
return std::make_pair(axis_p,true);
|
return std::make_pair(axis_p,true);
|
||||||
}
|
}
|
||||||
|
@ -712,7 +668,7 @@ void DrawSphereIcon (Trackball * tb, bool active, bool planeshandle=false)
|
||||||
|
|
||||||
col[0] = .40f; col[1] = .40f; col[2] = .85f;
|
col[0] = .40f; col[1] = .40f; col[2] = .85f;
|
||||||
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
||||||
DrawCircle(planeshandle);
|
DrawCircle(planeshandle);
|
||||||
|
|
||||||
glRotatef (90, 1, 0, 0);
|
glRotatef (90, 1, 0, 0);
|
||||||
col[0] = .40f; col[1] = .85f; col[2] = .40f;
|
col[0] = .40f; col[1] = .85f; col[2] = .40f;
|
||||||
|
@ -722,10 +678,10 @@ void DrawSphereIcon (Trackball * tb, bool active, bool planeshandle=false)
|
||||||
glRotatef (90, 0, 1, 0);
|
glRotatef (90, 0, 1, 0);
|
||||||
col[0] = .85f; col[1] = .40f; col[2] = .40f;
|
col[0] = .85f; col[1] = .40f; col[2] = .40f;
|
||||||
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
||||||
DrawCircle(planeshandle);
|
DrawCircle(planeshandle);
|
||||||
|
|
||||||
glPopMatrix ();
|
glPopMatrix ();
|
||||||
glPopAttrib ();
|
glPopAttrib ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEMPORARY drawing section
|
// TEMPORARY drawing section
|
||||||
|
@ -778,8 +734,8 @@ void DrawUglyLetter(Trackball * tb,std::vector<Point3f> ugly_letter)
|
||||||
|
|
||||||
glBegin(GL_LINE_STRIP);
|
glBegin(GL_LINE_STRIP);
|
||||||
for(unsigned int i=0;i<ugly_letter.size();i++){
|
for(unsigned int i=0;i<ugly_letter.size();i++){
|
||||||
glVertex(tb->camera.UnProject(center+(ugly_letter[i] * offset * 0.25)
|
glVertex(tb->camera.UnProject(center+(ugly_letter[i] * offset * 0.25)
|
||||||
+Point3f(-offset,-offset,0)));
|
+Point3f(-offset,-offset,0)));
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
glPopAttrib ();
|
glPopAttrib ();
|
||||||
|
|
|
@ -108,6 +108,7 @@ Note: mainly it is used only by the TrackBall.
|
||||||
|
|
||||||
template <class T> class View {
|
template <class T> class View {
|
||||||
public:
|
public:
|
||||||
|
View();
|
||||||
void GetView();
|
void GetView();
|
||||||
void SetView(const float *_proj, const float *_modelview, const int *_viewport);
|
void SetView(const float *_proj, const float *_modelview, const int *_viewport);
|
||||||
Point3<T> Project(const Point3<T> &p) const;
|
Point3<T> Project(const Point3<T> &p) const;
|
||||||
|
@ -134,15 +135,23 @@ public:
|
||||||
Matrix44<T> matrix;
|
Matrix44<T> matrix;
|
||||||
Matrix44<T> inverse;
|
Matrix44<T> inverse;
|
||||||
int viewport[4];
|
int viewport[4];
|
||||||
|
bool isOrtho;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> void View<T>::GetView() {
|
template <class T> View<T>::View() {
|
||||||
glGetv(GL_PROJECTION_MATRIX,proj);
|
isOrtho=false;
|
||||||
glGetv(GL_MODELVIEW_MATRIX,model);
|
}
|
||||||
glGetIntegerv(GL_VIEWPORT, (GLint*)viewport);
|
|
||||||
|
|
||||||
matrix = proj*model;
|
template <class T> void View<T>::GetView() {
|
||||||
inverse = vcg::Inverse(matrix);
|
glGetv(GL_PROJECTION_MATRIX,proj);
|
||||||
|
glGetv(GL_MODELVIEW_MATRIX,model);
|
||||||
|
glGetIntegerv(GL_VIEWPORT, (GLint*)viewport);
|
||||||
|
|
||||||
|
if(proj[3][3]==0) isOrtho = false;
|
||||||
|
else isOrtho = true;
|
||||||
|
|
||||||
|
matrix = proj*model;
|
||||||
|
inverse = vcg::Inverse(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> void View<T>::SetView(const float *_proj,
|
template <class T> void View<T>::SetView(const float *_proj,
|
||||||
|
@ -161,6 +170,7 @@ template <class T> void View<T>::SetView(const float *_proj,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> Point3<T> View<T>::ViewPoint() const {
|
template <class T> Point3<T> View<T>::ViewPoint() const {
|
||||||
|
if(isOrtho) return vcg::Inverse(model)* Point3<T>(0, 0, 3);
|
||||||
return vcg::Inverse(model)* Point3<T>(0, 0, 0);
|
return vcg::Inverse(model)* Point3<T>(0, 0, 0);
|
||||||
}
|
}
|
||||||
// Note that p it is assumed to be in model coordinate.
|
// Note that p it is assumed to be in model coordinate.
|
||||||
|
@ -179,22 +189,33 @@ template <class T> Plane3<T> View<T>::ViewPlaneFromModel(const Point3<T> &p)
|
||||||
// Note that p it is assumed to be in model coordinate.
|
// Note that p it is assumed to be in model coordinate.
|
||||||
template <class T> Line3<T> View<T>::ViewLineFromModel(const Point3<T> &p)
|
template <class T> Line3<T> View<T>::ViewLineFromModel(const Point3<T> &p)
|
||||||
{
|
{
|
||||||
Point3<T> vp=ViewPoint();
|
|
||||||
Line3<T> line;
|
Line3<T> line;
|
||||||
line.SetOrigin(vp);
|
Point3<T> vp=ViewPoint();
|
||||||
line.SetDirection(p - vp);
|
if(isOrtho){
|
||||||
|
line.SetOrigin(p);
|
||||||
|
line.SetDirection(- vp );
|
||||||
|
} else {
|
||||||
|
line.SetOrigin(vp);
|
||||||
|
line.SetDirection(p - vp);
|
||||||
|
}
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that p it is assumed to be in window coordinate.
|
// Note that p it is assumed to be in window coordinate.
|
||||||
template <class T> Line3<T> View<T>::ViewLineFromWindow(const Point3<T> &p)
|
template <class T> Line3<T> View<T>::ViewLineFromWindow(const Point3<T> &p)
|
||||||
{
|
{
|
||||||
Line3<T> ln; // plane perpedicular to view direction and passing through manip center
|
Line3<T> line; // plane perpedicular to view direction and passing through manip center
|
||||||
Point3<T> vp=ViewPoint();
|
Point3<T> vp=ViewPoint();
|
||||||
Point3<T> pp=UnProject(p);
|
Point3<T> pp=UnProject(p);
|
||||||
ln.SetOrigin(vp);
|
|
||||||
ln.SetDirection(pp-vp);
|
if(isOrtho){
|
||||||
return ln;
|
line.SetOrigin(pp);
|
||||||
|
line.SetDirection(- vp );
|
||||||
|
} else {
|
||||||
|
line.SetOrigin(vp);
|
||||||
|
line.SetDirection(pp-vp);
|
||||||
|
}
|
||||||
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> Point3<T> View<T>::Project(const Point3<T> &p) const {
|
template <class T> Point3<T> View<T>::Project(const Point3<T> &p) const {
|
||||||
|
|
Loading…
Reference in New Issue