Trackball Improvement. Now it works well also for ortho views
This commit is contained in:
parent
63046a8bab
commit
1ff3a301ec
|
@ -8,7 +8,7 @@
|
|||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
|
@ -41,8 +41,8 @@ void TrackMode::SetAction (){}
|
|||
|
||||
void TrackMode::Reset (){}
|
||||
|
||||
bool TrackMode::IsAnimating(const Trackball *){
|
||||
return false;
|
||||
bool TrackMode::IsAnimating(const Trackball *){
|
||||
return false;
|
||||
}
|
||||
|
||||
void TrackMode::Animate(unsigned int, Trackball *){
|
||||
|
@ -58,12 +58,12 @@ void TrackMode::Undo(){}
|
|||
void InactiveMode::Draw(Trackball * tb){
|
||||
DrawSphereIcon(tb,false);
|
||||
}
|
||||
|
||||
|
||||
// Sphere mode implementation.
|
||||
// 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
|
||||
// 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)
|
||||
{
|
||||
|
@ -72,9 +72,13 @@ void SphereMode::Apply (Trackball * tb, Point3f new_point)
|
|||
tb->Hits.push_back (hitNew);
|
||||
Point3f center = tb->center;
|
||||
Point3f axis = (hitNew - center) ^ (hitOld - center);
|
||||
vcg::Normalize(axis);
|
||||
|
||||
// Figure out how much to rotate around that axis.
|
||||
float phi = Distance (hitNew, hitOld) / tb->radius;
|
||||
// tb->track.rot = tb->last_track.rot * Quaternionf (-phi, axis);
|
||||
// float phi = Distance (hitNew, hitOld) / tb->radius;
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -120,7 +124,7 @@ void ScaleMode::Apply (Trackball * tb, float WheelNotch)
|
|||
{
|
||||
tb->track.sca *= pow (1.2f, -WheelNotch);
|
||||
}
|
||||
|
||||
|
||||
void ScaleMode::Apply (Trackball * tb, Point3f new_point)
|
||||
{
|
||||
tb->track.sca = tb->last_track.sca * pow (3.0f, -(getDeltaY(tb,new_point)));
|
||||
|
@ -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 > hitNew = HitPlane(tb,new_point,plane);
|
||||
if(hitOld.second && hitNew.second){
|
||||
tb->Translate (hitNew.first - hitOld.first);
|
||||
tb->Translate (hitNew.first - hitOld.first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,7 +174,7 @@ void PlaneMode::Draw(Trackball * tb){
|
|||
void CylinderMode::Apply (Trackball * tb, float WheelNotch)
|
||||
{
|
||||
const float PI2=6.283185307179586232f;
|
||||
float angle= (snap==0.0) ? WheelNotch/(tb->radius * PI2) : WheelNotch * snap;
|
||||
float angle= (snap==0.0) ? WheelNotch/(tb->radius * PI2) : WheelNotch * snap;
|
||||
tb->track.rot = tb->last_track.rot * Quaternionf (angle,axis.Direction());
|
||||
}
|
||||
|
||||
|
@ -182,12 +186,12 @@ void CylinderMode::Apply (Trackball * tb, Point3f new_point)
|
|||
float angle;
|
||||
const float EPSILON=0.005f; // this IS scale independent
|
||||
if(axisproj.Direction().Norm() < EPSILON){
|
||||
angle=(10.0f * getDeltaY(tb,new_point)) / tb->radius;
|
||||
angle=(10.0f * getDeltaY(tb,new_point)) / tb->radius;
|
||||
} else {
|
||||
Point3f hitOld = HitViewPlane (tb, tb->last_point);
|
||||
Point3f hitNew = HitViewPlane (tb, new_point);
|
||||
axisproj.Normalize();
|
||||
Point3f plusdir= viewplane.Direction() ^ axisproj.Direction();
|
||||
Point3f plusdir= viewplane.Direction() ^ axisproj.Direction();
|
||||
float distOld = signedDistance(axisproj,hitOld,plusdir);
|
||||
float distNew = signedDistance(axisproj,hitNew,plusdir);
|
||||
angle= (distNew-distOld) / tb->radius;
|
||||
|
@ -239,31 +243,31 @@ Point3f PathMode::SetStartNear(Point3f point)
|
|||
Point3f p0,p1;
|
||||
float nearest_state=0;
|
||||
Point3f nearest_point=points[0];
|
||||
float nearest_distance=Distance(nearest_point,point);
|
||||
float nearest_distance=Distance(nearest_point,point);
|
||||
unsigned int npts = int(points.size());
|
||||
for(unsigned int i = 1;i <= npts;i++){
|
||||
if( i == npts){
|
||||
if (wrap){
|
||||
p0=points[npts-1];
|
||||
p1=points[0];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
p0=points[i-1];
|
||||
p1=points[i];
|
||||
}
|
||||
if( i == npts){
|
||||
if (wrap){
|
||||
p0=points[npts-1];
|
||||
p1=points[0];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
p0=points[i-1];
|
||||
p1=points[i];
|
||||
}
|
||||
//Point3f segment_point=ClosestPoint(Segment3f(p0,p1),point);
|
||||
Point3f segment_point;
|
||||
float distance;
|
||||
vcg::SegmentPointDistance<float>(Segment3f(p0,p1),point,segment_point,distance);
|
||||
// float distance=Distance(segment_point,point);
|
||||
Point3f segment_point;
|
||||
float distance;
|
||||
vcg::SegmentPointDistance<float>(Segment3f(p0,p1),point,segment_point,distance);
|
||||
// float distance=Distance(segment_point,point);
|
||||
if(distance<nearest_distance){
|
||||
nearest_point=segment_point;
|
||||
nearest_distance=distance;
|
||||
nearest_state=p0_state+(Distance(p0,nearest_point)/path_length);
|
||||
}
|
||||
float segment_norm= Distance(p0,p1) / path_length;
|
||||
}
|
||||
float segment_norm= Distance(p0,p1) / path_length;
|
||||
p0_state+=segment_norm;
|
||||
}
|
||||
assert( nearest_state >= 0.0 );
|
||||
|
@ -278,22 +282,22 @@ Point3f PathMode::SetStartNear(Point3f point)
|
|||
void PathMode::GetPoints(float state, Point3f & point, Point3f & prev_point, Point3f & next_point)
|
||||
{
|
||||
assert(state >= 0.0f);
|
||||
assert(state <= 1.0f);
|
||||
float remaining_norm=state;
|
||||
assert(state <= 1.0f);
|
||||
float remaining_norm=state;
|
||||
Point3f p0(0,0,0),p1(0,0,0);
|
||||
unsigned int npts = int(points.size());
|
||||
for(unsigned int i = 1;i <= npts;i++){
|
||||
if( i == npts){
|
||||
if (wrap){
|
||||
p0=points[npts-1];
|
||||
p1=points[0];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
p0=points[i-1];
|
||||
p1=points[i];
|
||||
}
|
||||
if( i == npts){
|
||||
if (wrap){
|
||||
p0=points[npts-1];
|
||||
p1=points[0];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
p0=points[i-1];
|
||||
p1=points[i];
|
||||
}
|
||||
float segment_norm= Distance(p0,p1) / path_length;
|
||||
if (segment_norm < remaining_norm){
|
||||
remaining_norm -= segment_norm;
|
||||
|
@ -303,28 +307,28 @@ void PathMode::GetPoints(float state, Point3f & point, Point3f & prev_point, Poi
|
|||
next_point = p1;
|
||||
float ratio= remaining_norm / segment_norm;
|
||||
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){
|
||||
point=prev_point;
|
||||
if (i > 1){
|
||||
prev_point=points[i-2];
|
||||
prev_point=points[i-2];
|
||||
} else if (wrap){
|
||||
prev_point=points[npts-1];
|
||||
}
|
||||
}
|
||||
} else if (Distance(point,next_point) < EPSILON){
|
||||
point=next_point;
|
||||
if( i < (npts-1)){
|
||||
next_point=points[i+1];
|
||||
next_point=points[i+1];
|
||||
} else {
|
||||
if (wrap){
|
||||
next_point=points[1];
|
||||
} else {
|
||||
next_point=points[npts-1];
|
||||
}
|
||||
}
|
||||
if (wrap){
|
||||
next_point=points[1];
|
||||
} else {
|
||||
next_point=points[npts-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// rounding errors can lead out of the for..
|
||||
prev_point = p0;
|
||||
point = p1;
|
||||
|
@ -346,7 +350,7 @@ void PathMode::Apply (Trackball * tb, float WheelNotch)
|
|||
GetPoints(current_state,old_point,prev_point,next_point);
|
||||
current_state=Normalize(current_state+delta);
|
||||
GetPoints(current_state,new_point,prev_point,next_point);
|
||||
tb->Translate (new_point - old_point);
|
||||
tb->Translate (new_point - old_point);
|
||||
}
|
||||
|
||||
float PathMode::Normalize(float state)
|
||||
|
@ -360,9 +364,9 @@ float PathMode::Normalize(float state)
|
|||
return fractpart;
|
||||
}
|
||||
if ( state < 0.0f )
|
||||
return 0.0f;
|
||||
return 0.0f;
|
||||
if ( state > 1.0f )
|
||||
return 1.0f;
|
||||
return 1.0f;
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -401,7 +405,7 @@ float PathMode::HitPoint(float state, Ray3fN ray, Point3f &hit_point)
|
|||
{
|
||||
Point3f current_point, next_point, prev_point;
|
||||
GetPoints(state,current_point,prev_point,next_point);
|
||||
|
||||
|
||||
Point3f closest_point;
|
||||
closest_point=ray.ClosestPoint(current_point);
|
||||
int verse=Verse(closest_point,current_point,prev_point,next_point);
|
||||
|
@ -409,26 +413,26 @@ float PathMode::HitPoint(float state, Ray3fN ray, Point3f &hit_point)
|
|||
hit_point=current_point;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
||||
Segment3f active_segment;
|
||||
if (verse > 0){
|
||||
active_segment=Segment3f(current_point,next_point);
|
||||
active_segment=Segment3f(current_point,next_point);
|
||||
} else {
|
||||
active_segment= Segment3f(current_point,prev_point);
|
||||
}
|
||||
}
|
||||
|
||||
//hit_point=ClosestPoint(active_segment,closest_point);
|
||||
float dist;
|
||||
vcg::SegmentPointDistance<float>(active_segment,closest_point,hit_point,dist);
|
||||
float dist;
|
||||
vcg::SegmentPointDistance<float>(active_segment,closest_point,hit_point,dist);
|
||||
|
||||
return verse * ((hit_point-current_point).Norm() / path_length);
|
||||
}
|
||||
}
|
||||
|
||||
void PathMode::SetAction (){
|
||||
Point3f temp1,temp2;
|
||||
Point3f temp1,temp2;
|
||||
GetPoints(current_state,old_hitpoint,temp1,temp2);
|
||||
}
|
||||
|
||||
|
||||
void PathMode::Apply (Trackball * tb, Point3f new_point)
|
||||
{
|
||||
undo_current_state=current_state;
|
||||
|
@ -462,7 +466,7 @@ void PathMode::Draw(Trackball * tb){
|
|||
void AreaMode::Init(const std::vector < Point3f > &pts)
|
||||
{
|
||||
unsigned int npts = int(pts.size());
|
||||
|
||||
|
||||
assert(npts >= 3);
|
||||
//get the plane
|
||||
Point3f p0=pts[0];
|
||||
|
@ -471,38 +475,38 @@ void AreaMode::Init(const std::vector < Point3f > &pts)
|
|||
bool pts_not_in_line=false;
|
||||
Point3f a,b;
|
||||
for(unsigned int i=0;i<onethird;i++){
|
||||
a=(pts[(i+ onethird )%npts] - pts[i%npts]).normalized();
|
||||
b=(pts[(i+(2*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();
|
||||
pts_not_in_line = (a ^ b).Norm() > EPSILON;
|
||||
if(pts_not_in_line){
|
||||
plane.Init( pts[i%npts],
|
||||
pts[(i+(onethird))%npts],
|
||||
plane.Init( pts[i%npts],
|
||||
pts[(i+(onethird))%npts],
|
||||
pts[(i+(2*onethird))%npts]);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(pts_not_in_line);
|
||||
assert(pts_not_in_line);
|
||||
float ncx,ncy,ncz;
|
||||
ncx=fabs(plane.Direction()[0]);
|
||||
ncy=fabs(plane.Direction()[1]);
|
||||
ncz=fabs(plane.Direction()[2]);
|
||||
ncz=fabs(plane.Direction()[2]);
|
||||
if(( ncx > ncy ) && ( ncx > ncz )){
|
||||
first_coord_kept=1;
|
||||
second_coord_kept=2;
|
||||
} else if(( ncy > ncx ) && ( ncy > ncz)){
|
||||
first_coord_kept=0;
|
||||
second_coord_kept=2;
|
||||
} else {
|
||||
} else {
|
||||
first_coord_kept=0;
|
||||
second_coord_kept=1;
|
||||
}
|
||||
points.reserve(npts);
|
||||
points.reserve(npts);
|
||||
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]);
|
||||
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;
|
||||
}
|
||||
|
@ -523,26 +527,26 @@ void AreaMode::Apply (Trackball * tb, Point3f new_point)
|
|||
undo_path_index=path.size();
|
||||
|
||||
if(begin_action){
|
||||
delta_mouse=tb->camera.Project(status)-new_point;
|
||||
begin_action=false;
|
||||
}
|
||||
delta_mouse=tb->camera.Project(status)-new_point;
|
||||
begin_action=false;
|
||||
}
|
||||
std::pair< Point3f, bool > hitNew = HitPlane(tb,new_point+delta_mouse,plane);
|
||||
if(! hitNew.second){
|
||||
return;
|
||||
return;
|
||||
}
|
||||
Point3f hit_point=hitNew.first;
|
||||
Point3f hit_point=hitNew.first;
|
||||
Point3f delta_status=Move(status,hit_point);
|
||||
status += delta_status;
|
||||
tb->Translate (status - old_status);
|
||||
tb->Translate (status - old_status);
|
||||
rubberband_handle=hit_point;
|
||||
}
|
||||
|
||||
|
||||
void AreaMode::SetAction ()
|
||||
{
|
||||
begin_action=true;
|
||||
begin_action=true;
|
||||
old_status=status;
|
||||
|
||||
|
||||
path.clear();
|
||||
path.push_back(status);
|
||||
rubberband_handle=status;
|
||||
|
@ -555,44 +559,44 @@ Point3f AreaMode::Move(Point3f start,Point3f end)
|
|||
bool done=false;
|
||||
bool end_inside=Inside(end);
|
||||
while(!done){
|
||||
path.push_back(pt);
|
||||
path.push_back(pt);
|
||||
Segment3f segment(pt,end);
|
||||
bool p_on_side = false;
|
||||
bool hit=false;
|
||||
|
||||
|
||||
Point3f pside(0,0,0),phit(0,0,0);
|
||||
bool slide=false,mid_inside=false;
|
||||
|
||||
|
||||
int np = int(points.size()), i, j;
|
||||
for (i = 0, j = np-1; i < np; j = i++) {
|
||||
Segment3f side(points[i],points[j]);
|
||||
Point3f pseg,psid;
|
||||
//std::pair<float,bool> res=SegmentSegmentDistance(segment,side,pseg,psid);
|
||||
std::pair<float,bool> res;
|
||||
vcg::SegmentSegmentDistance(segment,side,res.first,res.second,pseg,psid);
|
||||
std::pair<float,bool> res;
|
||||
vcg::SegmentSegmentDistance(segment,side,res.first,res.second,pseg,psid);
|
||||
if(res.first < EPSILON && ! res.second){
|
||||
float dist= Distance(pt,pseg);
|
||||
if(dist < EPSILON){
|
||||
float dist= Distance(pt,pseg);
|
||||
if(dist < EPSILON){
|
||||
//Point3f pn=ClosestPoint(side,end);
|
||||
Point3f pn;
|
||||
float dist;
|
||||
vcg::SegmentPointDistance<float>(side,end,pn,dist);
|
||||
Point3f pn;
|
||||
float dist;
|
||||
vcg::SegmentPointDistance<float>(side,end,pn,dist);
|
||||
if(!p_on_side || (Distance(pn,end)<Distance(end,pside))){
|
||||
pside=pn;
|
||||
p_on_side=true;
|
||||
}
|
||||
} else {
|
||||
if (!hit || Distance(pt,pseg) < Distance(pt,phit)){
|
||||
phit=pseg;
|
||||
hit=true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!hit || Distance(pt,pseg) < Distance(pt,phit)){
|
||||
phit=pseg;
|
||||
hit=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p_on_side)
|
||||
slide = Distance(pside,pt) > EPSILON;
|
||||
|
||||
if (hit)
|
||||
|
||||
if (hit)
|
||||
mid_inside = Inside( pt + ( ( phit - pt ) / 2) );
|
||||
|
||||
if ( !hit && end_inside ){
|
||||
|
@ -600,16 +604,16 @@ Point3f AreaMode::Move(Point3f start,Point3f end)
|
|||
done = true;
|
||||
} else if ( hit && (!p_on_side || (p_on_side && mid_inside))) {
|
||||
pt = phit;
|
||||
} else if ( p_on_side && slide) {
|
||||
} else if ( p_on_side && slide) {
|
||||
pt = pside;
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
path.push_back(pt);
|
||||
path.push_back(pt);
|
||||
return pt - start;
|
||||
}
|
||||
|
||||
|
||||
// adapted from the original C code by W. Randolph Franklin
|
||||
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
bool AreaMode::Inside(Point3f point)
|
||||
|
@ -620,15 +624,15 @@ bool AreaMode::Inside(Point3f point)
|
|||
float yi, yj, xi, xj;
|
||||
int i, j, np=int(points.size());
|
||||
for (i = 0, j = np-1; i < np; j = i++) {
|
||||
xi=points[i][first_coord_kept];
|
||||
yi=points[i][second_coord_kept];
|
||||
xj=points[j][first_coord_kept];
|
||||
yj=points[j][second_coord_kept];
|
||||
xi=points[i][first_coord_kept];
|
||||
yi=points[i][second_coord_kept];
|
||||
xj=points[j][first_coord_kept];
|
||||
yj=points[j][second_coord_kept];
|
||||
if ( ( ( (yi<=y) && (y<yj) ) || ( (yj<=y) && (y<yi) ) ) &&
|
||||
( x < ( xj - xi ) * ( y - yi ) / ( yj - yi ) + xi ) )
|
||||
{
|
||||
inside=!inside;
|
||||
}
|
||||
inside=!inside;
|
||||
}
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
|
@ -641,19 +645,19 @@ Point3f AreaMode::SetStartNear(Point3f point)
|
|||
return initial_status;
|
||||
}
|
||||
Point3f nearest_point=initial_status;
|
||||
float nearest_distance=Distance(nearest_point,candidate);
|
||||
float nearest_distance=Distance(nearest_point,candidate);
|
||||
int i, j, np=int(points.size());
|
||||
for (i = 0, j = np-1; i < np; j = i++) {
|
||||
Segment3f side(points[i],points[j]);
|
||||
//Point3f side_point=ClosestPoint(side,candidate);
|
||||
//float distance=Distance(side_point,candidate);
|
||||
Point3f side_point;
|
||||
float distance;
|
||||
vcg::SegmentPointDistance<float>(side,candidate,side_point,distance);
|
||||
Point3f side_point;
|
||||
float distance;
|
||||
vcg::SegmentPointDistance<float>(side,candidate,side_point,distance);
|
||||
if( distance < nearest_distance ){
|
||||
nearest_point=side_point;
|
||||
nearest_distance=distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
initial_status=nearest_point;
|
||||
return initial_status;
|
||||
|
@ -696,7 +700,7 @@ void PolarMode::Apply (Trackball * tb, Point3f new_point)
|
|||
endb = beta + angley;
|
||||
if(endb > top) endb = top;
|
||||
if(endb < -top) endb = -top;
|
||||
tb->track.rot = Quaternionf (endb, Point3f(1,0,0)) *
|
||||
tb->track.rot = Quaternionf (endb, Point3f(1,0,0)) *
|
||||
Quaternionf (enda, Point3f(0,1,0)) ;
|
||||
|
||||
}
|
||||
|
@ -718,20 +722,20 @@ void PolarMode::Draw(Trackball * tb){
|
|||
|
||||
// Navigator WASD implementation
|
||||
|
||||
NavigatorWasdMode::NavigatorWasdMode() {
|
||||
NavigatorWasdMode::NavigatorWasdMode() {
|
||||
_flipH=1; _flipV=1;
|
||||
SetTopSpeedsAndAcc(1,1,4);
|
||||
step_height = step_length = 0;
|
||||
Reset();
|
||||
step_height = step_length = 0;
|
||||
Reset();
|
||||
};
|
||||
|
||||
void NavigatorWasdMode::Reset() {
|
||||
alpha=0;
|
||||
beta=0;
|
||||
current_speed.SetZero();
|
||||
step_x=0.0f;
|
||||
beta=0;
|
||||
current_speed.SetZero();
|
||||
step_x=0.0f;
|
||||
|
||||
step_current = step_last = 0.0;
|
||||
step_current = step_last = 0.0;
|
||||
}
|
||||
|
||||
void NavigatorWasdMode::FlipH(){
|
||||
|
@ -744,56 +748,56 @@ void NavigatorWasdMode::FlipV(){
|
|||
|
||||
|
||||
void NavigatorWasdMode::SetAction() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool NavigatorWasdMode::IsAnimating(const Trackball * tb){
|
||||
const unsigned int MOVEMENT_KEY_MASK = (const unsigned int)(~Trackball::MODIFIER_MASK);
|
||||
if (tb->current_button & MOVEMENT_KEY_MASK) return true;
|
||||
if (current_speed!=Point3f(0,0,0)) return true;
|
||||
if (step_current>0.0) return true;
|
||||
return false;
|
||||
const unsigned int MOVEMENT_KEY_MASK = (const unsigned int)(~Trackball::MODIFIER_MASK);
|
||||
if (tb->current_button & MOVEMENT_KEY_MASK) return true;
|
||||
if (current_speed!=Point3f(0,0,0)) return true;
|
||||
if (step_current>0.0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void NavigatorWasdMode::Animate(unsigned int msec, Trackball * tb){
|
||||
vcg::Point3f acc(0,0,0);
|
||||
|
||||
float sa = sin(-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_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_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_PGDOWN) acc += vcg::Point3f( 0,1, 0)*accZ;
|
||||
|
||||
float sec = msec/1.0f;
|
||||
current_speed += acc*sec;
|
||||
tb->track.tra+=current_speed*sec;
|
||||
|
||||
// compute step height.
|
||||
Point3f current_speed_h = current_speed;
|
||||
current_speed_h[1]=0;
|
||||
float vel = current_speed_h.Norm();
|
||||
if (vel<topSpeedH*0.05) {
|
||||
vcg::Point3f acc(0,0,0);
|
||||
|
||||
float sa = sin(-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_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_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_PGDOWN) acc += vcg::Point3f( 0,1, 0)*accZ;
|
||||
|
||||
float sec = msec/1.0f;
|
||||
current_speed += acc*sec;
|
||||
tb->track.tra+=current_speed*sec;
|
||||
|
||||
// compute step height.
|
||||
Point3f current_speed_h = current_speed;
|
||||
current_speed_h[1]=0;
|
||||
float vel = current_speed_h.Norm();
|
||||
if (vel<topSpeedH*0.05) {
|
||||
// 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;}
|
||||
} else {
|
||||
// running: rise step heigth
|
||||
vel = current_speed.Norm();
|
||||
step_x += vel*sec;
|
||||
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;
|
||||
}
|
||||
step_x += vel*sec;
|
||||
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;
|
||||
}
|
||||
|
||||
current_speed*=pow(dumping,sec);
|
||||
if (current_speed.Norm()<topSpeedH*0.005) current_speed.SetZero(); // full stop
|
||||
current_speed*=pow(dumping,sec);
|
||||
if (current_speed.Norm()<topSpeedH*0.005) current_speed.SetZero(); // full stop
|
||||
|
||||
tb->track.tra[1]+=step_last;
|
||||
tb->track.tra[1]-=step_current;
|
||||
step_last=step_current;
|
||||
|
||||
step_last=step_current;
|
||||
|
||||
//tb->track.tra[1]+=0.01;
|
||||
}
|
||||
|
||||
|
@ -801,7 +805,7 @@ void NavigatorWasdMode::Apply (Trackball * tb, Point3f new_point)
|
|||
{
|
||||
Point3f hitOld = tb->last_point;
|
||||
Point3f hitNew = new_point;
|
||||
tb->last_point=new_point;
|
||||
tb->last_point=new_point;
|
||||
float dx = (hitNew.X() - hitOld.X());
|
||||
float dy = (hitNew.Y() - hitOld.Y());
|
||||
|
||||
|
@ -816,15 +820,15 @@ void NavigatorWasdMode::Apply (Trackball * tb, Point3f new_point)
|
|||
if(beta < -top) beta = -top;
|
||||
|
||||
Point3f viewpoint = tb->track.InverseMatrix()*Point3f(0,0,0);
|
||||
tb->track.tra = tb->track.rot.Inverse().Rotate(tb->track.tra + viewpoint ) ;
|
||||
tb->track.rot = Quaternionf (beta , Point3f(1,0,0)) *
|
||||
tb->track.tra = tb->track.rot.Inverse().Rotate(tb->track.tra + viewpoint ) ;
|
||||
tb->track.rot = Quaternionf (beta , Point3f(1,0,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;
|
||||
|
||||
step_last=step_current;
|
||||
|
||||
step_last=step_current;
|
||||
|
||||
}
|
||||
|
||||
|
@ -833,7 +837,7 @@ void NavigatorWasdMode::SetTopSpeedsAndAcc(float hspeed, float vspeed, float acc
|
|||
hspeed /= 1000;
|
||||
vspeed /= 1000;
|
||||
acc /= 1000000;
|
||||
|
||||
|
||||
accX = accY = acc;
|
||||
dumping = hspeed / ( hspeed + acc );
|
||||
accZ = ( vspeed / dumping ) - vspeed;
|
||||
|
@ -843,11 +847,11 @@ void NavigatorWasdMode::SetTopSpeedsAndAcc(float hspeed, float vspeed, float acc
|
|||
dumping=0.0;
|
||||
}
|
||||
topSpeedH = hspeed; topSpeedV=vspeed;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void NavigatorWasdMode::SetStepOnWalk(float width, float height){
|
||||
step_length = width;
|
||||
step_length = width;
|
||||
step_height = height;
|
||||
}
|
||||
|
||||
|
@ -858,5 +862,5 @@ void NavigatorWasdMode::Apply (Trackball * tb, float WheelNotch)
|
|||
|
||||
|
||||
bool NavigatorWasdMode::isSticky(){
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -20,51 +20,7 @@
|
|||
* 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
|
||||
#define TRACKUTILS_H
|
||||
|
@ -144,24 +100,24 @@ Point3f HitViewPlane (Trackball * tb, const Point3f & p)
|
|||
|
||||
<br>The original documentation (in italian) follows:
|
||||
<pre>
|
||||
dato un punto in coordinate di schermo e.g. in pixel stile opengl
|
||||
calcola il punto di intersezione tra la viewline che passa per
|
||||
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
|
||||
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
|
||||
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
|
||||
y = - ----------- * x + hitplane.y
|
||||
viewpoint.x
|
||||
|
||||
eq hiperboloide di raggio r (e.g. che passa per (r/sqrt2,r/sqrt2)
|
||||
eq hiperboloide di raggio r (e.g. che passa per (r/sqrt2,r/sqrt2)
|
||||
|
||||
1
|
||||
y = --- * (r^2 /2.0)
|
||||
x
|
||||
x
|
||||
|
||||
hitplane.y
|
||||
----------- * x^2 - hitplane.y *x + (r^2/2.0) == 0
|
||||
|
@ -214,16 +170,16 @@ bool HitHyper (Point3f center, float radius, Point3f viewpoint, Plane3f vp,
|
|||
|
||||
<br>The original documentation (in italian) follows:
|
||||
<pre>
|
||||
dato un punto in coordinate di schermo e.g. in pixel stile opengl
|
||||
restituisce un punto in coordinate di mondo sulla superficie
|
||||
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
|
||||
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
|
||||
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
|
||||
X 0 sqrt(1/2) 1
|
||||
eq sfera: y=sqrt(1-x*x); 1 sqrt(1/2) 0
|
||||
eq iperboloide : y=1/2*x; inf sqrt(1/2) 1/2
|
||||
eq cono y=x+sqrt(2);
|
||||
</pre>
|
||||
|
@ -235,12 +191,12 @@ eq cono y=x+sqrt(2);
|
|||
Point3f HitSphere (Trackball * tb, const Point3f & p)
|
||||
{
|
||||
Point3f center = tb->center;
|
||||
Line3fN ln = tb->camera.ViewLineFromWindow (Point3f (p[0], p[1], 0));
|
||||
Line3fN ln = tb->camera.ViewLineFromWindow (Point3f (p[0], p[1], 0));
|
||||
Plane3f vp = GetViewPlane (tb->camera, center);
|
||||
Point3f hitPlane(0,0,0), //intersection view plane with point touched
|
||||
hitSphere(0,0,0),
|
||||
hitSphere1(0,0,0),
|
||||
hitSphere2(0,0,0),
|
||||
hitSphere(0,0,0),
|
||||
hitSphere1(0,0,0),
|
||||
hitSphere2(0,0,0),
|
||||
hitHyper(0,0,0);
|
||||
IntersectionPlaneLine < float >(vp, ln, hitPlane);
|
||||
|
||||
|
@ -297,7 +253,7 @@ Point3f HitSphere (Trackball * tb, const Point3f & p)
|
|||
// if(d > d2) hit = hit2;
|
||||
// hit -= tb->center;
|
||||
//} else {
|
||||
// if(d > 2.99 * Thr)
|
||||
// if(d > 2.99 * Thr)
|
||||
// d = 2.99 * Thr;
|
||||
// Point3f norm = (hit - tb->center)^(viewpoint - tb->center);
|
||||
// norm.Normalize();
|
||||
|
@ -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 EPSILON = 0.00001f;
|
||||
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 b2= (p0 - q0).dot(Vq);
|
||||
|
@ -351,7 +307,7 @@ std::pair< float, bool > LineLineDistance(const Line3f & P,const Line3f & Q,Poin
|
|||
/*!
|
||||
@brief Calculates the minimal distance between a ray and a line.
|
||||
|
||||
R is the ray and Q is the line, R_s and Q_t are set to be the closest points on
|
||||
R is the ray and Q is the line, R_s and Q_t are set to be the closest points on
|
||||
the ray and the line.
|
||||
|
||||
it's returned the distance from R_s and Q_t, and a boolean value which is true
|
||||
|
@ -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 EPSILON = 0.00001f;
|
||||
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 b2= (r0 - q0).dot(Vq);
|
||||
|
@ -381,7 +337,7 @@ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3
|
|||
float t = ( (VRVQ * b1) + (VRVR * b2) ) / det;
|
||||
if(s<0){
|
||||
R_s = r0;
|
||||
Q_t = ClosestPoint(Q,R_s);
|
||||
Q_t = ClosestPoint(Q,R_s);
|
||||
}else {
|
||||
R_s = r0 + (Vr * s);
|
||||
Q_t = q0 + (Vq * t);
|
||||
|
@ -392,7 +348,7 @@ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3
|
|||
///*!
|
||||
// @brief Calculates the minimal distance between 2 segments.
|
||||
//
|
||||
// R e Q are the segments, R_s and Q_t are set to be the closest points on
|
||||
// R e Q are the segments, R_s and Q_t are set to be the closest points on
|
||||
// the segments.
|
||||
//
|
||||
// it's returned the distance from R_s and Q_t, and a boolean value which is true
|
||||
|
@ -407,7 +363,7 @@ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3
|
|||
//{
|
||||
// float R_len=Distance(R.P0(),R.P1());
|
||||
// float Q_len=Distance(Q.P0(),Q.P1());
|
||||
// const float EPSILON_LENGTH = std::max(R_len,Q_len)*0.0001f;
|
||||
// const float EPSILON_LENGTH = std::max(R_len,Q_len)*0.0001f;
|
||||
// if(R_len < EPSILON_LENGTH){
|
||||
// R_s=R.P0();
|
||||
// Q_t=ClosestPoint(Q,R_s);
|
||||
|
@ -417,7 +373,7 @@ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3
|
|||
// Q_t=Q.P0();
|
||||
// R_s=ClosestPoint(R,Q_t);
|
||||
// return std::make_pair(Distance(R_s,Q_t),true);
|
||||
// }
|
||||
// }
|
||||
// Point3f r0 = R.P0(), Vr = (R.P1()-R.P0()).normalized();
|
||||
// Point3f q0 = Q.P0(), Vq = (Q.P1()-Q.P0()).normalized();
|
||||
// float VRVR = Vr.dot(Vr);
|
||||
|
@ -450,7 +406,7 @@ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3
|
|||
// assert(0);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return std::make_pair(Distance(R_s,Q_t),true);
|
||||
// }
|
||||
// float b1= (q0 - r0).dot(Vr);
|
||||
|
@ -465,7 +421,7 @@ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3
|
|||
// R_s = r0 + (Vr * s);
|
||||
// }
|
||||
// if( t < 0){
|
||||
// Q_t = Q.P0();
|
||||
// Q_t = Q.P0();
|
||||
// }else if ( t > Q_len ){
|
||||
// Q_t = Q.P1();
|
||||
// }else{
|
||||
|
@ -477,7 +433,7 @@ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3
|
|||
/*!
|
||||
@brief Compute the point on a line closest to the ray projection of a window coordinate point.
|
||||
|
||||
Given a window coordinate point, computes a ray starting from the manipulator
|
||||
Given a window coordinate point, computes a ray starting from the manipulator
|
||||
camera eye and passing through the point's projection on the viewplane, then uses RayLineDistance()
|
||||
to get the closest point to ray on a given line.
|
||||
@see RayLineDistance(const Ray3f & R,const Line3f & Q,Point3f & R_s, Point3f & Q_t)
|
||||
|
@ -489,10 +445,10 @@ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3
|
|||
std::pair< Point3f,bool > HitNearestPointOnAxis (Trackball * tb,Line3f axis, Point3f point)
|
||||
{
|
||||
Ray3fN ray = line2ray(tb->camera.ViewLineFromWindow (point));
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
@ -570,7 +526,7 @@ template<class T>
|
|||
/*!
|
||||
@brief Project a window coordinate point on a plane.
|
||||
|
||||
Given a window coordinate point, computes a ray starting from the manipulator
|
||||
Given a window coordinate point, computes a ray starting from the manipulator
|
||||
camera eye and passing through the point's projection on the viewplane, then uses IntersectionRayPlane()
|
||||
to get the ray intersection with a given plane.
|
||||
|
||||
|
@ -684,7 +640,7 @@ void DrawCircle (bool planehandle=true)
|
|||
@param active boolean to be set to true if the icon is active.
|
||||
*/
|
||||
void DrawSphereIcon (Trackball * tb, bool active, bool planeshandle=false)
|
||||
{
|
||||
{
|
||||
glPushAttrib(GL_TRANSFORM_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix ();
|
||||
|
@ -693,7 +649,7 @@ void DrawSphereIcon (Trackball * tb, bool active, bool planeshandle=false)
|
|||
Point3f center = tb->center + tb->track.InverseMatrix()*Point3f(0, 0, 0);
|
||||
glTranslate(center);
|
||||
glScale (tb->radius/tb->track.sca);
|
||||
|
||||
|
||||
float amb[4] = { .35f, .35f, .35f, 1.0f };
|
||||
float col[4] = { .5f, .5f, .8f, 1.0f };
|
||||
glEnable (GL_LINE_SMOOTH);
|
||||
|
@ -709,10 +665,10 @@ void DrawSphereIcon (Trackball * tb, bool active, bool planeshandle=false)
|
|||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor (DH.color);
|
||||
glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, amb);
|
||||
|
||||
|
||||
col[0] = .40f; col[1] = .40f; col[2] = .85f;
|
||||
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
||||
DrawCircle(planeshandle);
|
||||
DrawCircle(planeshandle);
|
||||
|
||||
glRotatef (90, 1, 0, 0);
|
||||
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);
|
||||
col[0] = .85f; col[1] = .40f; col[2] = .40f;
|
||||
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
||||
DrawCircle(planeshandle);
|
||||
|
||||
glPopMatrix ();
|
||||
glPopAttrib ();
|
||||
DrawCircle(planeshandle);
|
||||
|
||||
glPopMatrix ();
|
||||
glPopAttrib ();
|
||||
}
|
||||
|
||||
// TEMPORARY drawing section
|
||||
|
@ -762,7 +718,7 @@ void prepare_attrib()
|
|||
void DrawUglyLetter(Trackball * tb,std::vector<Point3f> ugly_letter)
|
||||
{
|
||||
Point3f center=tb->camera.Project(tb->center);
|
||||
float offset=0;
|
||||
float offset=0;
|
||||
offset=(std::max)(offset,Distance(center,tb->camera.Project(tb->center+(Point3f(1,0,0) * tb->radius))));
|
||||
offset=(std::max)(offset,Distance(center,tb->camera.Project(tb->center+(Point3f(0,1,0) * tb->radius))));
|
||||
offset=(std::max)(offset,Distance(center,tb->camera.Project(tb->center+(Point3f(0,0,1) * tb->radius))));
|
||||
|
@ -775,12 +731,12 @@ void DrawUglyLetter(Trackball * tb,std::vector<Point3f> ugly_letter)
|
|||
prepare_attrib();
|
||||
glColor3f(1,1,1);
|
||||
glLineWidth(4.0);
|
||||
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for(unsigned int i=0;i<ugly_letter.size();i++){
|
||||
glVertex(tb->camera.UnProject(center+(ugly_letter[i] * offset * 0.25)
|
||||
+Point3f(-offset,-offset,0)));
|
||||
}
|
||||
glVertex(tb->camera.UnProject(center+(ugly_letter[i] * offset * 0.25)
|
||||
+Point3f(-offset,-offset,0)));
|
||||
}
|
||||
glEnd();
|
||||
glPopAttrib ();
|
||||
glPopMatrix();
|
||||
|
@ -800,9 +756,9 @@ void DrawUglyPanMode(Trackball * tb)
|
|||
ugly_p.push_back(Point3f(-1,-1,0));
|
||||
ugly_p.push_back(Point3f(-1,1,0));
|
||||
ugly_p.push_back(Point3f(1,1,0));
|
||||
ugly_p.push_back(Point3f(1,0,0));
|
||||
ugly_p.push_back(Point3f(-1,0,0));
|
||||
|
||||
ugly_p.push_back(Point3f(1,0,0));
|
||||
ugly_p.push_back(Point3f(-1,0,0));
|
||||
|
||||
DrawUglyLetter(tb,ugly_p);
|
||||
}
|
||||
|
||||
|
@ -915,7 +871,7 @@ void DrawUglyPlaneMode(Trackball * tb,Plane3f plane)
|
|||
glVertex(p0+(d1*f0)+(d2*f1));
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
glColor3f(0.9f, 0.9f, 0.2f);
|
||||
glPointSize(8.0f);
|
||||
glBegin(GL_POINTS);
|
||||
|
@ -968,7 +924,7 @@ void DrawUglyCylinderMode(Trackball * tb,Line3f axis)
|
|||
glVertex(axis.Origin()+p0+(norm*float(i))+(d1*f0)+(d2*f1));
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
glLineWidth(3.0);
|
||||
glColor3f(0.2f, 0.2f, 0.9f);
|
||||
glBegin(GL_LINES);
|
||||
|
@ -1126,15 +1082,15 @@ void DrawUglyAreaMode(Trackball * tb,const std::vector < Point3f > &points,
|
|||
glVertex(p0+(d1*f0)+(d2*f1));
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glPopAttrib ();
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
} //end namespace trackutils
|
||||
|
||||
|
||||
} //end namespace vcg
|
||||
|
||||
#endif //TRACKUTILS_H
|
||||
|
|
|
@ -108,6 +108,7 @@ Note: mainly it is used only by the TrackBall.
|
|||
|
||||
template <class T> class View {
|
||||
public:
|
||||
View();
|
||||
void GetView();
|
||||
void SetView(const float *_proj, const float *_modelview, const int *_viewport);
|
||||
Point3<T> Project(const Point3<T> &p) const;
|
||||
|
@ -134,15 +135,23 @@ public:
|
|||
Matrix44<T> matrix;
|
||||
Matrix44<T> inverse;
|
||||
int viewport[4];
|
||||
bool isOrtho;
|
||||
};
|
||||
|
||||
template <class T> void View<T>::GetView() {
|
||||
glGetv(GL_PROJECTION_MATRIX,proj);
|
||||
glGetv(GL_MODELVIEW_MATRIX,model);
|
||||
glGetIntegerv(GL_VIEWPORT, (GLint*)viewport);
|
||||
template <class T> View<T>::View() {
|
||||
isOrtho=false;
|
||||
}
|
||||
|
||||
matrix = proj*model;
|
||||
inverse = vcg::Inverse(matrix);
|
||||
template <class T> void View<T>::GetView() {
|
||||
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,
|
||||
|
@ -161,6 +170,7 @@ template <class T> void View<T>::SetView(const float *_proj,
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// 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.
|
||||
template <class T> Line3<T> View<T>::ViewLineFromModel(const Point3<T> &p)
|
||||
{
|
||||
Point3<T> vp=ViewPoint();
|
||||
Line3<T> line;
|
||||
line.SetOrigin(vp);
|
||||
line.SetDirection(p - vp);
|
||||
Point3<T> vp=ViewPoint();
|
||||
if(isOrtho){
|
||||
line.SetOrigin(p);
|
||||
line.SetDirection(- vp );
|
||||
} else {
|
||||
line.SetOrigin(vp);
|
||||
line.SetDirection(p - vp);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
// Note that p it is assumed to be in window coordinate.
|
||||
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
|
||||
Point3<T> vp=ViewPoint();
|
||||
Point3<T> pp=UnProject(p);
|
||||
ln.SetOrigin(vp);
|
||||
ln.SetDirection(pp-vp);
|
||||
return ln;
|
||||
Line3<T> line; // plane perpedicular to view direction and passing through manip center
|
||||
Point3<T> vp=ViewPoint();
|
||||
Point3<T> pp=UnProject(p);
|
||||
|
||||
if(isOrtho){
|
||||
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 {
|
||||
|
|
Loading…
Reference in New Issue