Show
Ignore:
Timestamp:
11/26/07 22:53:32 (1 year ago)
Author:
vossg
Message:

changed: more flexible navigators, allow user navigator (thanks to M. Spindler for the code)

: add _d when pulling windows dlls

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Source/System/Window/Utilities/OSGNavigator.cpp

    r840 r1021  
    4646#include "OSGNavigator.h" 
    4747 
     48#include "OSGNavigatorEngine.h" 
     49#include "OSGTrackballEngine.h" 
     50#include "OSGFlyEngine.h" 
     51#include "OSGWalkEngine.h" 
     52#include "OSGNoneEngine.h" 
     53 
    4854OSG_USING_NAMESPACE 
    4955 
     
    139145*/ 
    140146 
    141 /*! \var Navigator::_ip 
    142      
    143     Temporary hit point for intersection testing. 
    144 */ 
    145  
    146 /*! \var Navigator::_dir 
    147  
    148     Temporary ray direction for intersection testing. 
    149 */ 
    150  
    151147/*------------------------- constructors ----------------------------------*/ 
    152148 
    153 Navigator::Navigator() :  
     149Navigator::Navigator() : 
     150    _engine(NULL), // pointer to current engine 
     151 
     152    _trackballEngine(new TrackballEngine), 
     153    _flyEngine(new FlyEngine), 
     154    _walkEngine(new WalkEngine), 
     155    _noneEngine(new NoneEngine), 
     156    _userEngine(new TrackballEngine), 
     157 
    154158    _rRotationAngle(0.04908739f), 
    155159    _rMotionFactor(1.f), 
    156     _currentState(IDLE), 
    157     _currentMode(TRACKBALL), 
    158160    _absolute(true), 
    159161    _vp(NullFC), 
     
    163165    _clickNoIntersect(false), 
    164166    _lastX(0), 
    165     _lastY(0), 
    166     _ip(0,0,0) 
    167 
     167    _lastY(0) 
     168
     169    addRef(_trackballEngine); 
     170    addRef(_flyEngine); 
     171    addRef(_walkEngine); 
     172    addRef(_noneEngine); 
     173    addRef(_userEngine); 
     174 
     175    setMode(TRACKBALL); // use trackball as default 
    168176} 
    169177 
     
    173181{ 
    174182    OSG::subRef(_cartN); 
     183 
     184    subRef(_engine); 
     185    subRef(_trackballEngine); 
     186    subRef(_flyEngine); 
     187    subRef(_walkEngine); 
     188    subRef(_noneEngine); 
     189    subRef(_userEngine); 
    175190} 
    176191 
     
    184199    _moved = false; 
    185200 
    186     switch (_currentMode) 
    187     { 
    188     case NONE: 
    189         _currentState = IDLE; 
    190         break; 
    191  
    192     case TRACKBALL: 
    193  
    194         switch (button) 
    195         { 
    196         case LEFT_MOUSE  :  _currentState = ROTATING;          
    197                             break; 
    198                              
    199         case RIGHT_MOUSE :  _currentState = TRANSLATING_Z;     
    200                             break; 
    201   
    202         case MIDDLE_MOUSE:  _currentState = TRANSLATING_XY; 
    203                             getIntersectionPoint(x,y);       
    204                             break; 
    205  
    206         case UP_MOUSE    :  _currentState = IDLE; 
    207                             _trackball.translateZ(-_rMotionFactor); 
    208                             break; 
    209  
    210         case DOWN_MOUSE  :  _currentState = IDLE; 
    211                             _trackball.translateZ(_rMotionFactor); 
    212                             break; 
    213  
    214         default:            FNOTICE(("Navigator: buttonPress, unknown button\n")); 
    215                             break; 
    216         } 
    217         break; 
    218  
    219     case FLY: 
    220  
    221         switch (button) 
    222         { 
    223         case LEFT_MOUSE  :  _currentState = TRANSLATING_ZPLUS;   
    224                             break; 
    225                              
    226         case MIDDLE_MOUSE:  _currentState = ROTATING;            
    227                             break; 
    228                              
    229         case RIGHT_MOUSE :  _currentState = TRANSLATING_ZMINUS;  
    230                             break; 
    231                              
    232         case UP_MOUSE    :  _currentState = IDLE; 
    233                             _flyer.forward(-_rMotionFactor); 
    234                             break; 
    235                              
    236         case DOWN_MOUSE  :  _currentState = IDLE; 
    237                             _flyer.forward(_rMotionFactor); 
    238                             break; 
    239                              
    240         default:            FNOTICE(("Navigator: buttonPress, unknown button\n")); 
    241                             break; 
    242         } 
    243         break; 
    244  
    245     case WALK: 
    246  
    247         switch (button) 
    248         { 
    249         case LEFT_MOUSE  :  _currentState = TRANSLATING_ZPLUS;   
    250                             break; 
    251                              
    252         case MIDDLE_MOUSE:  _currentState = ROTATING;            
    253                             break; 
    254                              
    255         case RIGHT_MOUSE :  _currentState = TRANSLATING_ZMINUS;  
    256                             break; 
    257                              
    258         case UP_MOUSE    :  _currentState = IDLE; 
    259                             _walker.forward(-_rMotionFactor); 
    260                             break; 
    261                              
    262         case DOWN_MOUSE  :  _currentState = IDLE; 
    263                             _walker.forward(_rMotionFactor); 
    264                             break; 
    265                              
    266         default:            FNOTICE(("Navigator: buttonPress, unknown button\n")); 
    267                             break; 
    268         } 
    269         break; 
    270  
    271     default:  
    272      
    273         FNOTICE(("Navigator: buttonPress, unknown mode\n")); 
    274         break; 
    275     } 
     201    _engine->buttonPress(button, x, y, this); 
    276202} 
    277203 
    278204/*! Mouse button release handler. 
    279205*/ 
    280 void Navigator::buttonRelease(Int16 , Int16 x, Int16 y) 
    281 
    282     switch (_currentMode) 
    283     { 
    284     case NONE:      break; 
    285  
    286     case TRACKBALL: if (!_moved && _clickCenter) 
    287                     { 
    288                         IntersectAction * act  =  IntersectAction::create(); 
    289                         Line line; 
    290                         _vp->getCamera()->calcViewRay(line, x, y, *_vp); 
    291  
    292                         Pnt3f lp1 = line.getPosition(); 
    293                         Vec3f ld1 = line.getDirection(); 
    294  
    295                         act->setLine(line); 
    296                         act->apply(_vp->getRoot()); 
    297                         if (act->didHit()) 
    298                         { 
    299                             Pnt3f p1 = act->getHitPoint(); 
    300                             _trackball.setAt(p1); 
    301                         } 
    302  
    303                         delete act; 
    304                     } 
    305                     break; 
    306          
    307     case FLY:       break; 
    308     case WALK:      break; 
    309  
    310     default:        FNOTICE(("Navigator: buttonRelease, unknown mode\n")); 
    311                     break; 
    312     } 
    313     _currentState=IDLE; 
     206void Navigator::buttonRelease(Int16 button, Int16 x, Int16 y) 
     207
     208    _engine->buttonRelease(button, x, y, this); 
    314209} 
    315210 
    316211/*! Key press handler. 
    317212*/ 
    318 void Navigator::keyPress(Int16 key, Int16 , Int16 ) 
    319 
    320     switch (_currentMode) 
    321     { 
    322     case NONE: 
    323         break; 
    324  
    325     case TRACKBALL: 
    326  
    327         switch (key) 
    328         { 
    329         case LEFT      : /*undefined*/ break; 
    330         case RIGHT     : /*undefined*/ break; 
    331         case FORWARDS  : _trackball.translateZ(-_rMotionFactor); break; 
    332         case BACKWARDS : _trackball.translateZ(_rMotionFactor);  break; 
    333         default        : FNOTICE(("Navigator: keyPress, unknown key\n")); 
    334         } 
    335         break; 
    336  
    337     case FLY:        
    338      
    339         switch (key) 
    340         { 
    341         case LEFTROT   : _flyer.rotate(-_rRotationAngle, 0);  break; 
    342         case RIGHTROT  : _flyer.rotate( _rRotationAngle, 0);  break; 
    343         case LEFT      : _flyer.right( _rMotionFactor);  break; 
    344         case RIGHT     : _flyer.right(-_rMotionFactor);  break; 
    345         case FORWARDS  : _flyer.forward(-_rMotionFactor); break; 
    346         case BACKWARDS : _flyer.forward( _rMotionFactor);  break; 
    347         default        : FNOTICE(("Navigator: keyPress, unknown key\n")); 
    348         } 
    349         break; 
    350  
    351     case WALK:       
    352      
    353         switch (key) 
    354         { 
    355         case LEFTROT   : _walker.rotate(-_rRotationAngle, 0);  break; 
    356         case RIGHTROT  : _walker.rotate( _rRotationAngle, 0);  break; 
    357         case LEFT      : _walker.right( _rMotionFactor);   break; 
    358         case RIGHT     : _walker.right(-_rMotionFactor);   break; 
    359         case FORWARDS  : _walker.forward(-_rMotionFactor); break; 
    360         case BACKWARDS : _walker.forward( _rMotionFactor);  break; 
    361         default        : FNOTICE(("Navigator: keyPress, unknown key\n")); 
    362         } 
    363         break; 
    364  
    365     default:         
    366      
    367         FNOTICE(("Navigator: keyPress, unknown mode\n")); 
    368         break; 
    369     } 
     213void Navigator::keyPress(Int16 key, Int16 x, Int16 y) 
     214
     215    _engine->keyPress(key, x, y, this); 
    370216} 
    371217 
     
    376222    _moved = true; 
    377223 
    378     Real32 width  = Real32(_vp->getPixelWidth()); 
    379     Real32 height = Real32(_vp->getPixelHeight()); 
    380  
    381     if(width <= 0 || height <= 0) 
    382         return; 
    383  
    384     WindowPtr par = _vp->getParent(); 
    385     Real32 winHeight; 
    386      
    387     if(par != NullFC) 
    388         winHeight = (Real32)par->getHeight(); 
    389     else 
    390         winHeight = height; 
    391          
    392     Real32 fromX = (2.0f * (_lastX - _vp->getPixelLeft())- width)/  width; 
    393     Real32 fromY = (2.0f * (winHeight - _lastY - _vp->getPixelBottom())  
    394                                 - height)  / height; 
    395     Real32 toX   = (2.0f * (x - _vp->getPixelLeft()) - width) / width; 
    396     Real32 toY   = (2.0f * (winHeight - y - _vp->getPixelBottom())  
    397                                 - height)/height; 
    398     switch (_currentMode) 
    399     { 
    400     case NONE: 
    401         FNOTICE(("Navigator: moveTo NONE mode\n")); 
    402         break; 
    403  
    404     case TRACKBALL:  
    405      
    406         switch (_currentState) 
    407         { 
    408         case ROTATING      :_trackball.rotate(fromX, fromY, toX, toY); 
    409                             break; 
    410  
    411         case TRANSLATING_XY:{ 
    412                             Real32 distanceX = 0,distanceY = 0; 
    413                             calcDeltas(Int16(_lastX), Int16(_lastY), x, y,  
    414                                        distanceX, distanceY); 
    415                             _trackball.translateXY(distanceX, distanceY); 
    416                             } 
    417                             break; 
    418  
    419         case TRANSLATING_Z: { 
    420                             Real32 distance = osgSgn(toY-fromY)* 
    421                                               100.f *  
    422                                               osgPow(osgAbs(toY-fromY),2.f); 
    423                             _trackball.translateZ(distance * _rMotionFactor); 
    424                             } 
    425                             break; 
    426  
    427         default            :;//IDLE                         
    428         } 
    429          
    430         break; 
    431  
    432     case FLY: 
    433       
    434         { 
    435         Real32 distanceX = -(fromX-toX); 
    436         Real32 distanceY =  (fromY-toY); 
    437         _flyer.rotate(distanceX, distanceY); 
    438  
    439         switch (_currentState) 
    440         { 
    441         case TRANSLATING_ZPLUS:     _flyer.forward(-_rMotionFactor); 
    442                                     break; 
    443                                      
    444         case TRANSLATING_ZMINUS:    _flyer.forward(_rMotionFactor); 
    445                                     break; 
    446                                      
    447         case ROTATING:              break; 
    448          
    449         default:                    ;//IDLE 
    450         } 
    451         } 
    452         break; 
    453  
    454     case WALK: 
    455      
    456         { 
    457         Real32 distanceX = -(fromX-toX); 
    458         Real32 distanceY =  (fromY-toY); 
    459         _walker.rotate(distanceX, distanceY); 
    460  
    461         switch (_currentState) 
    462         { 
    463         case TRANSLATING_ZPLUS:     _walker.forward(-_rMotionFactor); 
    464                                     break; 
    465                                  
    466         case TRANSLATING_ZMINUS:    _walker.forward(_rMotionFactor); 
    467                                     break; 
    468                                      
    469         case ROTATING:              break; 
    470          
    471         default:                    ;//IDLE 
    472         } 
    473         } 
    474         break; 
    475  
    476     default:  
    477  
    478         FNOTICE(("Navigator: moveTo, unknown mode\n")); 
    479         break; 
    480     } 
     224    Real32 fromX, fromY, toX, toY; 
     225    if (!calcFromTo(x, y, fromX, fromY, toX, toY)) return; 
     226 
     227    _engine->moveTo(x, y, this); 
     228 
    481229    _lastX = x; 
    482230    _lastY = y; 
     
    487235void Navigator::idle(Int16 buttons, Int16 x, Int16 y) 
    488236{ 
    489     switch (_currentMode) 
    490     { 
    491         case NONE: 
    492         case TRACKBALL: 
    493                         break; 
    494         case FLY: 
    495         case WALK: 
    496                         if (buttons) 
    497                             moveTo(x,y); 
    498                         break; 
    499     } 
     237    _engine->idle(buttons, x, y, this); 
    500238} 
    501239 
     
    512250    } 
    513251 
    514     switch(_currentMode) 
    515     { 
    516     case NONE:      theMatrix.mult(_NoneMatrix);            break; 
    517     case TRACKBALL: theMatrix.mult(_trackball.getMatrix()); break; 
    518     case FLY:       theMatrix.mult(_flyer    .getMatrix()); break; 
    519     case WALK:      theMatrix.mult(_walker   .getMatrix()); break; 
    520     default:        FNOTICE(("Navigator: updateCamTrans, unknown mode\n")); 
    521                     break; 
    522     } 
     252    theMatrix.mult(_engine->getMatrix()); 
    523253 
    524254    if(_cartN != NullFC) 
     
    549279void Navigator::setMode(Navigator::Mode new_mode) 
    550280{ 
    551     if (_currentMode == new_mode) return; 
    552  
    553     _currentMode = new_mode; 
     281    NavigatorEngine* engine = _trackballEngine; 
     282 
     283    switch (new_mode) { 
     284        case TRACKBALL: engine = _trackballEngine; break; 
     285        case FLY:       engine = _flyEngine;       break; 
     286        case WALK:      engine = _walkEngine;      break; 
     287        case NONE:      engine = _noneEngine;      break; 
     288        case USER:      engine = _userEngine;      break; 
     289        default: 
     290            FWARNING (("Navigator: unknown mode. Fallback to trackball.\n")); 
     291    } 
     292 
     293    assert(engine); 
     294 
     295    if (engine != _engine) { 
     296        subRef(_engine); 
     297        _engine = engine; 
     298        addRef(_engine); 
     299    } 
    554300} 
    555301 
     
    573319{ 
    574320    _vp=new_viewport; 
    575     _walker.setGround(_vp->getRoot()); 
    576     _walker.setWorld (_vp->getRoot()); 
    577 
    578  
    579 /*! Set the navigation parameters in case of NONE mode 
    580 */ 
    581 void Navigator::setNoneMatrix(Pnt3f new_from, Pnt3f new_at, Vec3f new_up) 
    582 
    583     bool b = MatrixLookAt(_NoneMatrix, new_at, new_at+(new_at-new_from), new_up); 
    584  
    585     if (b) FNOTICE(("Navigator: set(.,.,.) failed\n")); 
     321    _engine->onViewportChanged(_vp); 
    586322} 
    587323 
     
    590326void Navigator::setFrom(Pnt3f new_from) 
    591327{ 
    592     switch (_currentMode) 
    593     { 
    594     case NONE: 
    595         setNoneMatrix( new_from, 
    596                       (Pnt3f)(_NoneMatrix[3]-_NoneMatrix[2]), 
    597                       (Vec3f) _NoneMatrix[1] ); 
    598         break; 
    599     case TRACKBALL:     _trackball.setFrom(new_from);   break; 
    600     case FLY:           _flyer    .setFrom(new_from);   break; 
    601     case WALK:          _walker   .setFrom(new_from);   break; 
    602     default:            FNOTICE(("Navigator: setFrom, unknown mode")); 
    603                         break; 
    604     } 
     328    _engine->setFrom(new_from); 
    605329} 
    606330 
     
    609333void Navigator::setAt(Pnt3f new_at) 
    610334{ 
    611     switch (_currentMode) 
    612     { 
    613     case NONE: 
    614         setNoneMatrix((Pnt3f)_NoneMatrix[3], new_at, (Vec3f)_NoneMatrix[1]); 
    615         break; 
    616     case TRACKBALL:     _trackball.setAt(new_at);   break; 
    617     case FLY:           _flyer    .setAt(new_at);   break; 
    618     case WALK:          _walker   .setAt(new_at);   break; 
    619     default:            FNOTICE(("Navigator: setAt, unknown mode")); 
    620                         break; 
    621     } 
     335    _engine->setAt(new_at); 
    622336} 
    623337 
     
    626340void Navigator::setDistance(Real32 new_distance) 
    627341{ 
    628     switch (_currentMode) 
    629     { 
    630     case NONE:          break; 
    631  
    632     case TRACKBALL:     _trackball.setDistance(new_distance); 
    633                         break; 
    634                          
    635     case FLY:           _flyer.forward(new_distance); 
    636                         break; 
    637                          
    638     case WALK:          _walker.forward(new_distance); 
    639                         break; 
    640                                  
    641     default:            FNOTICE(("Navigator: setDistance, unknown mode")); 
    642                         break; 
    643     } 
     342    _engine->setDistance(new_distance); 
    644343} 
    645344 
     
    649348void Navigator::setUp(Vec3f new_up) 
    650349{ 
    651     switch (_currentMode) 
    652     { 
    653     case NONE: 
    654         setNoneMatrix((Pnt3f) _NoneMatrix[3], 
    655                       (Pnt3f)(_NoneMatrix[3]-_NoneMatrix[2]), 
    656                        new_up ); 
    657         break; 
    658  
    659     case TRACKBALL:     _trackball.setUp(new_up); 
    660                         break; 
    661                          
    662     case FLY:           _flyer.setUp(new_up); 
    663                         break; 
    664                          
    665     case WALK:          _walker.setUp(new_up); 
    666                         break;         
    667  
    668     default:            FNOTICE(("Navigator: setUp, unknown mode")); 
    669                         break; 
    670     } 
     350    _engine->setUp(new_up); 
    671351} 
    672352 
     
    675355void Navigator::set(Pnt3f new_from, Pnt3f new_at, Vec3f new_up) 
    676356{ 
    677     switch (_currentMode) 
    678     { 
    679     case NONE:          setNoneMatrix(new_from, new_at, new_up); 
    680                         break; 
    681  
    682     case TRACKBALL:     _trackball.set(new_from, new_at, new_up); 
    683                         break; 
    684                          
    685     case FLY:           _flyer.set(new_from, new_at, new_up); 
    686                         break; 
    687                          
    688     case WALK:          _walker.set(new_from, new_at, new_up); 
    689                         break;  
    690             
    691     default:            FNOTICE(("Navigator: set, unknown mode")); 
    692                         break; 
    693     } 
     357    _engine->set(new_from, new_at, new_up); 
    694358} 
    695359 
     
    698362void Navigator::set(const Matrix & new_matrix) 
    699363{ 
    700     switch (_currentMode) 
    701     { 
    702     case NONE:          //setNoneMatrix((Pnt3f) new_matrix[3], 
    703                         //              (Pnt3f)(new_matrix[3]-new_matrix[2]), 
    704                         //              (Vec3f) new_matrix[1]); 
    705                         _NoneMatrix = new_matrix; 
    706                         break; 
    707  
    708     case TRACKBALL:     _trackball.set(new_matrix); 
    709                         break; 
    710                          
    711     case FLY:           _flyer.set(new_matrix); 
    712                         break; 
    713                          
    714     case WALK:          _walker.set(new_matrix); 
    715                         break;         
    716                          
    717     default:            FNOTICE(("Navigator: set(Matrix), unknown mode")); 
    718                         break; 
    719     } 
     364    _engine->set(new_matrix); 
    720365} 
    721366 
     
    739384const Matrix &Navigator::getMatrix(void) 
    740385{ 
    741     switch (_currentMode) 
    742     { 
    743     case NONE:      return _NoneMatrix; 
    744     case TRACKBALL: return _trackball.getMatrix(); 
    745     case FLY:       return _flyer    .getMatrix(); 
    746     case WALK:      return _walker   .getMatrix();         
    747     default:        FNOTICE(("Navigator: getMatrix, unknown mode")); 
    748                     break; 
    749     } 
    750  
    751     return Matrix::identity(); 
     386    return _engine->getMatrix(); 
    752387} 
    753388 
     
    756391const Pnt3f  &Navigator::getFrom(void) 
    757392{ 
    758     static Pnt3f returnValue(0.f, 0.f, 0.f); 
    759     returnValue = (Pnt3f)_NoneMatrix[3]; 
    760  
    761     switch (_currentMode) 
    762     { 
    763     case NONE:      return returnValue; 
    764     case TRACKBALL: return _trackball.getFrom(); 
    765     case FLY:       return _flyer    .getFrom(); 
    766     case WALK:      return _walker   .getFrom(); 
    767     default:        FNOTICE(("Navigator: getFrom, unknown mode")); 
    768                     break; 
    769     } 
    770  
    771     return returnValue; 
     393    return _engine->getFrom(); 
    772394} 
    773395 
     
    776398const Pnt3f  &Navigator::getAt(void) 
    777399{ 
    778     static Pnt3f returnValue(0.f, 0.f, 0.f); 
    779     returnValue = (Pnt3f)(_NoneMatrix[3] - _NoneMatrix[2]); 
    780  
    781     switch (_currentMode) 
    782     { 
    783     case NONE:      return returnValue; 
    784     case TRACKBALL: return _trackball.getAt(); 
    785     case FLY:       return _flyer    .getAt(); 
    786     case WALK:      return _walker   .getAt(); 
    787     default:        FNOTICE(("Navigator: getAt, unknown mode")); 
    788                     break; 
    789     } 
    790  
    791     return returnValue; 
     400    return _engine->getAt(); 
    792401} 
    793402 
     
    796405const Vec3f  &Navigator::getUp(void) 
    797406{ 
    798     static Vec3f returnValue(0.f, 0.f, 0.f); 
    799     returnValue = (Vec3f)_NoneMatrix[1]; 
    800  
    801     switch (_currentMode) 
    802     { 
    803     case NONE:      return returnValue; 
    804     case TRACKBALL: return _trackball.getUp(); 
    805     case FLY:       return _flyer    .getUp(); 
    806     case WALK:      return _walker   .getUp(); 
    807     default:        FNOTICE(("NavigUpor: getUp, unknown mode")); 
    808                     break; 
    809     } 
    810  
    811     return returnValue; 
     407    return _engine->getUp(); 
    812408} 
    813409 
     
    817413Real32 Navigator::getDistance(void) 
    818414{ 
    819     Real32 distance = 0.0f; 
    820     switch (_currentMode) 
    821     { 
    822     case NONE:          break; 
    823  
    824     case TRACKBALL:     distance = _trackball.getDistance(); 
    825                         break; 
    826                          
    827     case FLY:           break; 
    828                          
    829     case WALK:          break; 
    830                                  
    831     default:            FNOTICE(("Navigator: setDistance, unknown mode")); 
    832                         break; 
    833     } 
    834  
    835     return distance; 
     415    return _engine->getDistance(); 
    836416} 
    837417 
     
    840420Navigator::State Navigator::getState(void) 
    841421{ 
    842     return _currentState
     422    return _engine->getState()
    843423} 
    844424 
     
    847427Navigator::Mode Navigator::getMode(void) 
    848428{ 
    849     return _currentMode; 
     429    if (_engine == _trackballEngine) return TRACKBALL; 
     430    if (_engine == _flyEngine)       return FLY; 
     431    if (_engine == _walkEngine)      return WALK; 
     432    if (_engine == _noneEngine)      return NONE; 
     433 
     434    return USER; 
    850435} 
    851436 
     
    884469    return _clickNoIntersect; 
    885470} 
     471 
     472 
     473bool Navigator::getMoved(void) 
     474{  
     475    return _moved; 
     476} 
     477 
     478ViewportPtr Navigator::getViewport(void) 
     479{ 
     480    return _vp; 
     481} 
     482 
     483Real32 Navigator::getLastX(void) 
     484{ 
     485    return _lastX; 
     486} 
     487 
     488Real32 Navigator::getLastY(void) 
     489{ 
     490    return _lastY; 
     491} 
     492 
     493TrackballEngine* Navigator::getTrackballNavigator(void) 
     494{  
     495    return _trackballEngine;  
     496} 
     497 
     498FlyEngine* Navigator::getFlyNavigator(void) 
     499{  
     500    return _flyEngine; 
     501} 
     502 
     503WalkEngine* Navigator::getWalkNavigator() 
     504{  
     505    return _walkEngine; 
     506} 
     507 
     508NavigatorEngine* Navigator::getUserNavigator(void) 
     509{ 
     510    return _userEngine; 
     511} 
     512 
     513void Navigator::setUserEngine(NavigatorEngine* userEngine) 
     514{ 
     515    if (userEngine == NULL) return; 
     516 
     517    if (userEngine != _userEngine) { 
     518        subRef(_userEngine); 
     519        _userEngine = userEngine; 
     520        addRef(_userEngine); 
     521    } 
     522} 
     523 
    886524 
    887525/*! Set the clickCenter current state. 
     
    915553} 
    916554 
    917 /*! Calculates the transformation matrix from CC to WC using the actual view 
    918     matrix. 
    919 */ 
    920 static void calcCCtoWCMatrix(Matrix &cctowc, const Matrix &view, 
    921                              const ViewportPtr port) 
    922 
    923     Matrix proj, projtrans; 
    924  
    925     port->getCamera()->getProjection( proj, port->getPixelWidth(), 
    926                                             port->getPixelHeight()); 
    927     port->getCamera()->getProjectionTranslation( projtrans, 
    928                                                  port->getPixelWidth(), 
    929                                                  port->getPixelHeight()); 
    930  
    931     Matrix wctocc = proj; 
    932     wctocc.mult( projtrans ); 
    933     wctocc.mult( view ); 
    934  
    935     cctowc.invertFrom( wctocc ); 
    936 
    937  
    938 /*! Calculates the intersection point of a ray that starts at from and goes 
    939     through the position on the screen given by x,y with the world, if no 
    940     intersection point exists the intersection is set to (0,0,0) 
    941 */ 
    942 void Navigator::getIntersectionPoint(Int16 x, Int16 y) 
    943 
    944     IntersectAction * act = IntersectAction::create(); 
    945     Line line; 
     555bool Navigator::calcFromTo(Int16 x, Int16 y, 
     556                           Real32& fromX, Real32& fromY, 
     557                           Real32& toX,   Real32& toY) 
     558
     559    Real32 width  = Real32(_vp->getPixelWidth()); 
     560    Real32 height = Real32(_vp->getPixelHeight()); 
     561 
     562    if(width <= 0 || height <= 0) return false; 
     563 
     564    WindowPtr par = _vp->getParent(); 
     565    Real32 winHeight; 
    946566     
    947     _vp->getCamera()->calcViewRay(line, x, y, *_vp); 
    948      
    949     if(_clickNoIntersect) 
    950     { 
    951         Real32 u = (_dir.dot(Pnt3f(0.0f, 0.0f, 0.0f) - line.getPosition())) / 
    952                    (_dir.dot(line.getDirection())); 
    953         _ip = line.getPosition() + u * line.getDirection(); 
    954         return; 
    955     } 
    956  
    957     act->setLine(line); 
    958     act->apply(_vp->getRoot()); 
    959  
    960     Matrix cctowc,view; 
    961     Int16 width  = _vp->getPixelWidth(); 
    962     Int16 height = _vp->getPixelHeight(); 
    963  
    964     _vp->getCamera()->getViewing(view, width, height); 
    965  
    966     calcCCtoWCMatrix(cctowc, view, _vp); 
    967  
    968     Pnt3f at,to; 
    969  
    970     cctowc.multFullMatrixPnt( Pnt3f( 0, 0, 0.5f ), to ); 
    971     cctowc.multFullMatrixPnt( Pnt3f( 0, 0, 1    ), at ); 
    972  
    973     _dir = to - at; 
    974  
    975     if (act->didHit()) 
    976     { 
    977         _ip = act->getHitPoint(); 
    978     } 
     567    if(par != NullFC) 
     568        winHeight = (Real32)par->getHeight(); 
    979569    else 
    980     { 
    981         Real32 u = (_dir.dot(Pnt3f(0.0f, 0.0f, 0.0f) - line.getPosition())) / 
    982                    (_dir.dot(line.getDirection())); 
    983         _ip = line.getPosition() + u * line.getDirection(); 
    984     } 
    985  
    986     delete act; 
    987 
    988  
    989 /*! Calculate the real translation that has to be done, so that the 
    990     trackball can actually drag the object in the plane parallel to the 
    991     screen. 
    992 */ 
    993 void Navigator::calcDeltas(Int16 , Int16 , Int16 toX, Int16 toY, 
    994                            Real32 &distanceX, Real32 &distanceY) 
    995 
    996     Matrix view; 
    997  
    998     view=_trackball.getMatrix(); 
    999  
    1000     Pnt3f from( view[3][0], view[3][1], view[3][2] ); 
    1001  
    1002     view.invert(); 
    1003     Matrix cctowc; 
    1004     calcCCtoWCMatrix(cctowc, view, _vp); 
    1005  
    1006     Real32  rx = ( toX / (Real32) _vp->getPixelWidth() ) * 2.f - 1.f, 
    1007             ry = 1.f - ( toY / (Real32) _vp->getPixelHeight() ) * 2.f; 
    1008  
    1009     Pnt3f at; 
    1010     cctowc.multFullMatrixPnt( Pnt3f( rx, ry, 1 ), at ); 
    1011  
    1012     Line line2; 
    1013     line2.setValue(from, at-from); 
    1014  
    1015     Real32 u = (_dir.dot(_ip-line2.getPosition())) / 
    1016                (_dir.dot(line2.getDirection())); 
    1017  
    1018     Pnt3f p2 = line2.getPosition() + u * line2.getDirection(); 
    1019  
    1020     Vec3f transl; 
    1021     transl[0] = -p2[0] + _ip[0]; 
    1022     transl[1] = -p2[1] + _ip[1]; 
    1023     transl[2] = -p2[2] + _ip[2]; 
    1024  
    1025     view.multMatrixVec(transl); 
    1026  
    1027     distanceX = transl[0]; 
    1028     distanceY = transl[1]; 
    1029 
     570        winHeight = height; 
     571         
     572    fromX = (2.0f * (_lastX - _vp->getPixelLeft())- width) /  width; 
     573    fromY = (2.0f * (winHeight-_lastY-_vp->getPixelBottom())-height) / height; 
     574 
     575    toX   = (2.0f * (x - _vp->getPixelLeft()) - width) / width; 
     576    toY   = (2.0f * (winHeight - y - _vp->getPixelBottom()) - height) / height; 
     577 
     578    return true; 
     579
     580