fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / Window / Utilities / OSGNavigator.cpp
blob0846d9de814ed12297bdf18afdeccb2961400468
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000,2001 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
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"
48 OSG_USING_NAMESPACE
50 /***************************************************************************\
51 * Description *
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
80 Inactive state.
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
101 state.
104 /*! \var NavigatorBase::State NavigatorBase::TRANSLATING_ZMINUS
106 State for rotation with automatic backwards motion. The standard fly
107 backwards state.
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 ),
156 _absolute (true ),
157 _vp (NULL ),
158 _cartN (NULL ),
159 _moved (false ),
160 _clickCenter (true ),
161 _clickNoIntersect(false ),
162 _lastX (0 ),
163 _lastY (0 ),
164 _width (0 ),
165 _height (0 ),
166 _theMatrix ( )
168 setMode(TRACKBALL); // use trackball as default
171 /*-------------------------- destructors ----------------------------------*/
173 Navigator::~Navigator(void)
175 _cartN = NULL;
176 _vp = NULL;
178 _engine = NULL;
179 _trackballEngine = NULL;
180 _flyEngine = NULL;
181 _walkEngine = NULL;
182 _navballEngine = NULL;
183 _noneEngine = NULL;
184 _userEngine = NULL;
187 /*-------------------------- Notificators ---------------------------------*/
189 /*! Mouse button press handler.
191 void Navigator::buttonPress(Int16 button, Int16 x, Int16 y)
193 _lastX = x;
194 _lastY = y;
196 _moved = false;
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)
219 _moved = true;
221 Real32 fromX, fromY, toX, toY;
223 if(!calcFromTo(x, y, fromX, fromY, toX, toY))
224 return;
226 _engine->moveTo(x, y, this);
228 _lastX = x;
229 _lastY = y;
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,
240 Int16 x,
241 Int16 y,
242 Int16 width,
243 Int16 height )
245 this->_width = width;
246 this->_height = height;
248 this->buttonPress(button, x, y);
251 void Navigator::buttonRelease(Int16 button,
252 Int16 x,
253 Int16 y,
254 Int16 width,
255 Int16 height )
257 this->_width = width;
258 this->_height = height;
260 this->buttonRelease(button, x, y);
263 void Navigator::keyPress(Int16 key,
264 Int16 x,
265 Int16 y,
266 Int16 width,
267 Int16 height )
269 this->_width = width;
270 this->_height = height;
272 this->keyPress(key, x, y);
275 void Navigator::moveTo(Int16 x,
276 Int16 y,
277 Int16 width,
278 Int16 height )
280 this->_width = width;
281 this->_height = height;
283 this->moveTo(x, y);
286 void Navigator::idle(Int16 buttons,
287 Int16 x,
288 Int16 y,
289 Int16 width,
290 Int16 height )
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
300 the cart.
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());
317 if(_cartN != NULL)
319 Transform *t = dynamic_cast<Transform *>(_cartN->getCore());
321 if(t == NULL)
323 FWARNING (("Navigator: updateCamTrans, "
324 "core is not TransformPtr\n"));
326 else
328 if(t->getMatrix() != _theMatrix)
330 t->setMatrix(_theMatrix);
334 else
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;
348 switch (new_mode)
350 case TRACKBALL:
351 engine = _trackballEngine;
352 break;
354 case FLY:
355 engine = _flyEngine;
356 break;
358 case WALK:
359 engine = _walkEngine;
360 break;
362 case NAVBALL:
363 engine = _navballEngine;
364 break;
366 case NONE:
367 engine = _noneEngine;
368 break;
370 case USER:
371 engine = _userEngine;
372 break;
374 default:
375 FWARNING (("Navigator: unknown mode. Fallback to trackball.\n"));
378 assert(engine);
380 if(engine != _engine)
382 if(copyViewParams && _engine)
383 engine->set(_engine->getFrom(), _engine->getAt(), _engine->getUp());
385 _engine = engine;
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)
409 _vp = 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"));
467 _cartN = new_cartn;
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)
520 return TRACKBALL;
522 if(_engine == _flyEngine)
523 return FLY;
525 if(_engine == _walkEngine)
526 return WALK;
528 if(_engine == _navballEngine)
529 return NAVBALL;
531 if(_engine == _noneEngine)
532 return NONE;
534 return USER;
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)
555 return _absolute;
558 /*! Get the clickCenter current state.
560 bool Navigator::getClickCenter(void)
562 return _clickCenter;
565 /*! Get the clickNoIntersect current state.
567 bool Navigator::getClickNoIntersect(void)
569 return _clickNoIntersect;
573 bool Navigator::getMoved(void)
575 return _moved;
578 Viewport *Navigator::getViewport(void)
580 return _vp;
583 Int16 Navigator::getLastX(void)
585 return _lastX;
588 Int16 Navigator::getLastY(void)
590 return _lastY;
593 NavballEngine &Navigator::getNavballEngine(void)
595 return *_navballEngine;
598 TrackballEngine &Navigator::getTrackballEngine(void)
600 return *_trackballEngine;
603 FlyEngine &Navigator::getFlyEngine(void)
605 return *_flyEngine;
608 WalkEngine &Navigator::getWalkEngine(void)
610 return *_walkEngine;
613 NoneEngine &Navigator::getNoneEngine(void)
615 return *_noneEngine;
618 NavigatorEngine &Navigator::getUserEngine(void)
620 return *_userEngine;
623 void Navigator::setUserEngine(NavigatorEngine *userEngine)
625 if(userEngine == NULL)
626 return;
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;
646 return old;
649 /*! Set absolute mode.
651 bool Navigator::setAbsolute(bool state)
653 bool old = _absolute;
655 _absolute = state;
657 return old;
660 /*! Set the clickCenter current state.
662 bool Navigator::setClickNoIntersect(bool state)
664 bool old = _clickNoIntersect;
666 _clickNoIntersect = state;
668 return old;
671 bool Navigator::calcFromTo(Int16 x, Int16 y,
672 Real32 &fromX, Real32 &fromY,
673 Real32 &toX, Real32 &toY)
675 if(_vp == NULL)
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)
682 return false;
684 Window *par = _vp->getParent();
685 Real32 winHeight;
687 if(par != NULL)
689 winHeight = Real32(par->getHeight());
691 else
693 winHeight = height;
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;
702 #if 0
703 fprintf(stderr, "%d %d | %f %f | %f %f | %f %f | %f %f\n",
704 UInt32(x),
705 UInt32(y),
706 width,
707 height,
708 Real32(_vp->calcPixelLeft()),
709 Real32( _vp->calcPixelBottom()),
710 fromX,
711 fromY,
712 toX,
713 toY );
714 #endif
716 return true;
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;
730 return true;