1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000,2001 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 #include "OSGConfig.h"
40 #include "OSGBaseTypes.h"
41 #include "OSGMatrix.h"
42 #include "OSGMatrixUtility.h"
43 #include "OSGCamera.h"
44 #include "OSGTransform.h"
46 #include "OSGNavigator.h"
50 /***************************************************************************\
52 \***************************************************************************/
54 /*! \class OSG::Navigator
55 \ingroup GrpSystemWindowNavigators
57 The general Navigator helper class, see \ref
58 PageSystemWindowNavigatorsNavigator for a description.
64 /*! \enum OSG::NavigatorBase::Mode
66 The navigation mode, i.e. the actual active low-level navigator.
67 The NONE case is also used for the purpose of matrix consistency.
71 /*! \enum OSG::NavigatorBase::State
73 The navigation state, mainly needed for correct interpretation of mouse
74 motions, which have to be interpreted differently for different states.
75 Interpretation also depends on the currently active Navigator::Mode.
78 /*! \var NavigatorBase::State NavigatorBase::IDLE
83 /*! \var NavigatorBase::State NavigatorBase::ROTATING
85 State for in-place rotation.
88 /*! \var NavigatorBase::State NavigatorBase::TRANSLATING_XY
90 State for x/y translation, used by the Trackball case.
93 /*! \var NavigatorBase::State NavigatorBase::TRANSLATING_Z
95 State for z translation, used by the Trackball case.
98 /*! \var NavigatorBase::State NavigatorBase::TRANSLATING_ZPLUS
100 State for rotation with automatic forward motion. The standard fly forward
104 /*! \var NavigatorBase::State NavigatorBase::TRANSLATING_ZMINUS
106 State for rotation with automatic backwards motion. The standard fly
111 /*! \enum OSG::NavigatorBase::MouseButton
113 Abstraction enumeration for mouse buttons, to keep the Navigator
114 independent of the actual Window System.
117 /*! \var NavigatorBase::MouseButton NavigatorBase::UP_MOUSE
119 Mouse wheel up button.
122 /*! \var NavigatorBase::MouseButton NavigatorBase::DOWN_MOUSE
124 Mouse wheel down button.
128 /*! \enum OSG::NavigatorBase::Key
130 Abstraction enumeration for keys, to keep the Navigator
131 independent of the actual Window System.
136 /*! \var Navigator::_rMotionFactor
138 The motion factor, roughly equivalent to speed.
141 /*------------------------- constructors ----------------------------------*/
143 Navigator::Navigator() :
145 _engine (NULL
), // pointer to current engine
147 _trackballEngine (TrackballEngine::create()),
148 _flyEngine (FlyEngine ::create()),
149 _walkEngine (WalkEngine ::create()),
150 _navballEngine (NavballEngine ::create()),
151 _noneEngine (NoneEngine ::create()),
152 _userEngine (TrackballEngine::create()),
154 _rRotationAngle (0.04908739f
),
155 _rMotionFactor (1.f
),
160 _clickCenter (true ),
161 _clickNoIntersect(false ),
168 setMode(TRACKBALL
); // use trackball as default
171 /*-------------------------- destructors ----------------------------------*/
173 Navigator::~Navigator(void)
179 _trackballEngine
= NULL
;
182 _navballEngine
= NULL
;
187 /*-------------------------- Notificators ---------------------------------*/
189 /*! Mouse button press handler.
191 void Navigator::buttonPress(Int16 button
, Int16 x
, Int16 y
)
198 _engine
->buttonPress(button
, x
, y
, this);
201 /*! Mouse button release handler.
203 void Navigator::buttonRelease(Int16 button
, Int16 x
, Int16 y
)
205 _engine
->buttonRelease(button
, x
, y
, this);
208 /*! Key press handler.
210 void Navigator::keyPress(Int16 key
, Int16 x
, Int16 y
)
212 _engine
->keyPress(key
, x
, y
, this);
215 /*! Mouse motion handler.
217 void Navigator::moveTo(Int16 x
, Int16 y
)
221 Real32 fromX
, fromY
, toX
, toY
;
223 if(!calcFromTo(x
, y
, fromX
, fromY
, toX
, toY
))
226 _engine
->moveTo(x
, y
, this);
232 /*! Performs some idle operations, depending on the current navigation mode
234 void Navigator::idle(Int16 buttons
, Int16 x
, Int16 y
)
236 _engine
->idle(buttons
, x
, y
, this);
239 void Navigator::buttonPress(Int16 button
,
245 this->_width
= width
;
246 this->_height
= height
;
248 this->buttonPress(button
, x
, y
);
251 void Navigator::buttonRelease(Int16 button
,
257 this->_width
= width
;
258 this->_height
= height
;
260 this->buttonRelease(button
, x
, y
);
263 void Navigator::keyPress(Int16 key
,
269 this->_width
= width
;
270 this->_height
= height
;
272 this->keyPress(key
, x
, y
);
275 void Navigator::moveTo(Int16 x
,
280 this->_width
= width
;
281 this->_height
= height
;
286 void Navigator::idle(Int16 buttons
,
292 this->_width
= width
;
293 this->_height
= height
;
295 this->idle(buttons
, x
, y
);
299 /*! Updates the camera transformation matrix directly in the node specified as
302 void Navigator::updateCameraTransformation(void)
304 _theMatrix
.setIdentity();
306 if(_absolute
&& _cartN
!= NULL
&& _cartN
->getParent() != NULL
)
308 _cartN
->getParent()->getToWorld(_theMatrix
);
310 _theMatrix
.inverse(_theMatrix
);
313 _engine
->onUpdateCameraTransformation(this);
315 _theMatrix
.mult(_engine
->getMatrix());
319 Transform
*t
= dynamic_cast<Transform
*>(_cartN
->getCore());
323 FWARNING (("Navigator: updateCamTrans, "
324 "core is not TransformPtr\n"));
328 if(t
->getMatrix() != _theMatrix
)
330 t
->setMatrix(_theMatrix
);
336 FFATAL (("!_cartN in Navigator::updateCameraTrans\n"));
340 /*------------------------------ set --------------------------------------*/
342 /*! Set the navigator mode (Trackball/Flyer/Walker).
344 void Navigator::setMode(Navigator::Mode new_mode
, bool copyViewParams
)
346 NavigatorEngine
*engine
= _trackballEngine
;
351 engine
= _trackballEngine
;
359 engine
= _walkEngine
;
363 engine
= _navballEngine
;
367 engine
= _noneEngine
;
371 engine
= _userEngine
;
375 FWARNING (("Navigator: unknown mode. Fallback to trackball.\n"));
380 if(engine
!= _engine
)
382 if(copyViewParams
&& _engine
)
383 engine
->set(_engine
->getFrom(), _engine
->getAt(), _engine
->getUp());
387 _engine
->onActivation(this);
391 /*! Set the rotation angle.
393 void Navigator::setRotationAngle(Real32 new_angle
)
395 _rRotationAngle
= new_angle
;
398 /*! Set the motion factor.
400 void Navigator::setMotionFactor(Real32 new_factor
)
402 _rMotionFactor
= new_factor
;
405 /*! Set the viewport.
407 void Navigator::setViewport(Viewport
*new_viewport
)
411 _engine
->onViewportChanged(this);
414 /*! Set the from point, i.e. the viewer position.
416 void Navigator::setFrom(Pnt3f new_from
)
418 _engine
->setFrom(new_from
);
421 /*! Set the at point, i.e. the target position for the viewer.
423 void Navigator::setAt(Pnt3f new_at
)
425 _engine
->setAt(new_at
);
428 /*! Set the distance from the target position.
430 void Navigator::setDistance(Real32 new_distance
)
432 _engine
->setDistance(new_distance
);
436 /*! Set the up vector, i.e. the vertical direction on screen.
438 void Navigator::setUp(Vec3f new_up
)
440 _engine
->setUp(new_up
);
443 /*! Set the full navigator parameters.
445 void Navigator::set(Pnt3f new_from
, Pnt3f new_at
, Vec3f new_up
)
447 _engine
->set(new_from
, new_at
, new_up
);
450 /*! Set the full navigator parameters from a matrix.
452 void Navigator::set(const Matrix
& new_matrix
)
454 _engine
->set(new_matrix
);
458 /*! Set the camera transformation node.
460 void Navigator::setCameraTransformation(Node
* const new_cartn
)
462 if (new_cartn
== NULL
)
464 FWARNING (("Set _cartN in Navigator to NULL\n"));
470 /*------------------------------ get --------------------------------------*/
472 /*! Get the transformation matrix.
474 const Matrix
&Navigator::getMatrix(void)
476 return _engine
->getMatrix();
479 /*! Get the from point, i.e. the viewer position.
481 const Pnt3f
&Navigator::getFrom(void)
483 return _engine
->getFrom();
486 /*! Get the at point, i.e. the target position.
488 const Pnt3f
&Navigator::getAt(void)
490 return _engine
->getAt();
493 /*! Get the up vector.
495 const Vec3f
&Navigator::getUp(void)
497 return _engine
->getUp();
501 /*! Get the distance from the target position.
503 Real32
Navigator::getDistance(void)
505 return _engine
->getDistance();
508 /*! Get the navigator's current state.
510 Navigator::State
Navigator::getState(void)
512 return _engine
->getState();
515 /*! Get the navigator's current mode.
517 Navigator::Mode
Navigator::getMode(void)
519 if(_engine
== _trackballEngine
)
522 if(_engine
== _flyEngine
)
525 if(_engine
== _walkEngine
)
528 if(_engine
== _navballEngine
)
531 if(_engine
== _noneEngine
)
537 /*! Get the navigator's rotation angle.
539 Real32
Navigator::getRotationAngle(void)
541 return _rRotationAngle
;
544 /*! Get the navigator's motion factor
546 Real32
Navigator::getMotionFactor(void)
548 return _rMotionFactor
;
551 /*! Get the absolute current state.
553 bool Navigator::getAbsolute(void)
558 /*! Get the clickCenter current state.
560 bool Navigator::getClickCenter(void)
565 /*! Get the clickNoIntersect current state.
567 bool Navigator::getClickNoIntersect(void)
569 return _clickNoIntersect
;
573 bool Navigator::getMoved(void)
578 Viewport
*Navigator::getViewport(void)
583 Int16
Navigator::getLastX(void)
588 Int16
Navigator::getLastY(void)
593 NavballEngine
&Navigator::getNavballEngine(void)
595 return *_navballEngine
;
598 TrackballEngine
&Navigator::getTrackballEngine(void)
600 return *_trackballEngine
;
603 FlyEngine
&Navigator::getFlyEngine(void)
608 WalkEngine
&Navigator::getWalkEngine(void)
613 NoneEngine
&Navigator::getNoneEngine(void)
618 NavigatorEngine
&Navigator::getUserEngine(void)
623 void Navigator::setUserEngine(NavigatorEngine
*userEngine
)
625 if(userEngine
== NULL
)
628 if(userEngine
!= _userEngine
)
630 _userEngine
= userEngine
;
633 if(getMode() == USER
)
634 setMode(USER
); // assign userEngine to _engine
638 /*! Set the clickCenter current state.
640 bool Navigator::setClickCenter(bool state
)
642 bool old
= _clickCenter
;
644 _clickCenter
= state
;
649 /*! Set absolute mode.
651 bool Navigator::setAbsolute(bool state
)
653 bool old
= _absolute
;
660 /*! Set the clickCenter current state.
662 bool Navigator::setClickNoIntersect(bool state
)
664 bool old
= _clickNoIntersect
;
666 _clickNoIntersect
= state
;
671 bool Navigator::calcFromTo(Int16 x
, Int16 y
,
672 Real32
&fromX
, Real32
&fromY
,
673 Real32
&toX
, Real32
&toY
)
676 return this->calcFromTo(x
, y
, _width
, _height
, fromX
, fromY
, toX
, toY
);
678 Real32 width
= Real32(_vp
->calcPixelWidth ());
679 Real32 height
= Real32(_vp
->calcPixelHeight());
681 if(width
<= 0 || height
<= 0)
684 Window
*par
= _vp
->getParent();
689 winHeight
= Real32(par
->getHeight());
696 fromX
= (2.0f
* (_lastX
- _vp
->calcPixelLeft())- width
) / width
;
697 fromY
= (2.0f
* (winHeight
-_lastY
-_vp
->calcPixelBottom())-height
) / height
;
699 toX
= (2.0f
* (x
- _vp
->calcPixelLeft()) - width
) / width
;
700 toY
= (2.0f
* (winHeight
- y
- _vp
->calcPixelBottom()) - height
) / height
;
703 fprintf(stderr
, "%d %d | %f %f | %f %f | %f %f | %f %f\n",
708 Real32(_vp
->calcPixelLeft()),
709 Real32( _vp
->calcPixelBottom()),
719 bool Navigator::calcFromTo(Int16 x
, Int16 y
,
720 Real32 width
, Real32 height
,
721 Real32
&fromX
, Real32
&fromY
,
722 Real32
&toX
, Real32
&toY
)
724 fromX
= (2.0f
* ( _lastX
) - width
) / width
;
725 fromY
= (2.0f
* (height
- _lastY
) - height
) / height
;
727 toX
= (2.0f
* ( x
) - width
) / width
;
728 toY
= (2.0f
* (height
- y
) - height
) / height
;