Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
QtBaseViewerFlyAnimation.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 //=============================================================================
54 //
55 // CLASS glViewer - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 
60 //== INCLUDES =================================================================
61 
62 #include "QtBaseViewer.hh"
63 #include <QPropertyAnimation>
64 
65 
66 //== NAMESPACES ===============================================================
67 
68 //== IMPLEMENTATION ==========================================================
69 
70 
71 void glViewer::flyTo(const QPoint& _pos, bool _moveBack)
72 {
73  makeCurrent();
74 
75  unsigned int nodeIdx, targetIdx;
76  ACG::Vec3d hitPoint;
77 
78  if (pick( ACG::SceneGraph::PICK_ANYTHING, _pos, nodeIdx, targetIdx, &hitPoint))
79  {
80  if (projectionMode_ == PERSPECTIVE_PROJECTION)
81  {
82  ACG::Vec3d eye(glstate_->eye());
83  ACG::Vec3d t = hitPoint - eye;
84  ACG::Vec3d e = eye + t * (_moveBack ? -0.5f : 0.5f);
85  flyTo(e, hitPoint, 300);
86  }
87  else
88  {
89  // Project hitpoint to get depth
90  ACG::Vec3d hitPointProjected = glstate_->project(hitPoint);
91 
92  // Create projected center point with same depth as hitpoint
93  ACG::Vec3d centerPointProjected = hitPointProjected;
94 
95  // Get viewport data
96  int w = 0, h = 0,left = 0, bottom = 0;
97  glstate_->get_viewport(left, bottom, w, h);
98 
99  // Compute the center point. Note that the project function includes the viewport matrix.
100  // As we have different viewports for the viewer but one global coord system,
101  // we need to set the real center coordinates and therefore add the lower left corner position
102  // which is the left and bottom of the viewport
103  centerPointProjected[0] = left + glstate_->viewport_width() / 2.0 ;
104  centerPointProjected[1] = bottom + glstate_->viewport_height() / 2.0 ;
105 
106  // unproject center point
107  ACG::Vec3d centerPointUnProjected = glstate_->unproject(centerPointProjected);
108 
109  // translation vector to make hit point project to center point (both need same depth)
110  ACG::Vec3d t = hitPoint - centerPointUnProjected;
111 
112  // Transform to correct translation vector with modelview.
114 
115  // remember originalWidth
117 
118  // Initialize as we start at 0.0
119  lastAnimationPos_ = 0.0;
120 
121  // store the direction for the actual animation
122  flyMoveBack_ = _moveBack;
123 
124  // Set the double click point as the new trackball center
125  // Rotations will use this point as the center.
126  properties_.trackballCenter( hitPoint );
127 
128  // Create animation object
129  if ( flyAnimationOrthogonal_ == 0) {
130  flyAnimationOrthogonal_ = new QPropertyAnimation(this, "currentAnimationPosition");
131 
132 
133  // Range is from 0 to one, as we linearly interpolate the animation
134  flyAnimationOrthogonal_->setStartValue(0.0);
135  flyAnimationOrthogonal_->setEndValue(1.0);
136 
137  // Connect signals for the animation and its end
138  connect(flyAnimationOrthogonal_, SIGNAL(valueChanged(QVariant)), this, SLOT(flyAnimationOrthogonal(QVariant)));
139  connect(flyAnimationOrthogonal_, SIGNAL(finished()), this, SLOT(flyAnimationOrthogonalFinished()));
140  }
141 
142  // Set duration
143  flyAnimationOrthogonal_->setDuration(300);
144 
145  // Start it
146  flyAnimationOrthogonal_->start();
147 
148  }
149  }
150 }
151 
152 void glViewer::flyAnimationOrthogonal(QVariant _pos) {
153 
154  const double pos = _pos.toDouble();
155 
156  // compute difference
157  const double diff = pos - lastAnimationPos_;
158 
159  // zoom back one frame
160  if ( flyMoveBack_ ) {
161  // Move back by factor 2
163  } else
164  // Move forward with factor 0.5
165  properties_.orthoWidth( flyOrthoWidthOriginal_ * (1.0 - 0.5 * pos ) );
166 
167  // apply translation
168  translate(- flyTranslation_ * diff );
169 
170  // Store our current position for next loop
171  lastAnimationPos_ = pos;
172 
173  // Pick cache is definitely invalid after that
174  updatePickCache_ = true;
175 
176  // update rendering
177  update();
178 }
179 
181 
182  const double pos = _pos.toDouble();
183 
184  // Animate pos from 0 to 1 so we need to calculate the difference and the resulting transformations
186  double a = (pos - lastAnimationPos_) * flyAngle_ ;
187 
188  translate(t);
189 
190  // Only rotate, if we have realistic values and if rotation is allowed
191  if ( allowRotation_ )
192  if (fabs(a) > FLT_MIN)
194 
195  // Pick cache is definitely invalid after that
196  updatePickCache_ = true;
197 
198  // Store our current position for next loop
199  lastAnimationPos_ = pos;
200 
201  // update rendering
202  update();
203 
204 }
205 
207 
208  // Update the projection matrix
210 
211  // Redraw scene
212  updateGL();
213 
214  // Inform others that the current view has changed
215  emit viewChanged();
216 
217 }
218 
220 
221  // Update the trackball to the final position
223  properties_.trackballRadius( std::max( properties_.sceneRadius(),( flyCenter_ - flyPosition_ ).norm() * 0.9f ) );
224 
225 }
226 
227 void glViewer::flyTo(const ACG::Vec3d& _position,
228  const ACG::Vec3d& _center,
229  int _time)
230 {
231  makeCurrent();
232 
233  // compute rotation
235  ACG::Vec3d p = glstate_->modelview().transform_point(_position);
236  ACG::Vec3d view =(p-c).normalize();
237  ACG::Vec3d z(0,0,1);
238 
239  flyAxis_ = (z % -view).normalize();
240 
241  flyAngle_ = acos(std::max(-1.0, std::min(1.0, (z | view)))) / M_PI * 180.0;
242 
243  if (flyAngle_ > 175)
244  flyAxis_ = ACG::Vec3d(0,1,0);
245 
246  // compute translation
247  ACG::Vec3d target = glstate_->modelview().transform_point(_center);
248  flyTranslation_ = ACG::Vec3d( -target[0], -target[1], -target[2] - (_position-_center).norm() );
249 
250  // Store other values for animation
251  flyCenter_ = _center;
252  flyPosition_ = _position;
253 
254  // Initialize as we start at 0.0
255  lastAnimationPos_ = 0.0;
256 
257  // Create animation object
258  if ( flyAnimationPerspective_ == 0) {
259  flyAnimationPerspective_ = new QPropertyAnimation(this, "currentAnimationPosition");
260 
261  // Range is from 0 to one, as we linearly interpolate the animation
262  flyAnimationPerspective_->setStartValue(0.0);
263  flyAnimationPerspective_->setEndValue(1.0);
264 
265  // Connect signals for the animation and its end
266  connect(flyAnimationPerspective_, SIGNAL(valueChanged(QVariant)), this, SLOT(flyAnimationPerspective(QVariant)));
267  connect(flyAnimationPerspective_, SIGNAL(finished()), this, SLOT(flyAnimationPerspectiveFinished()));
268  }
269 
270  // Set duration
271  flyAnimationPerspective_->setDuration(_time);
272 
273  // Start it
274  flyAnimationPerspective_->start();
275 }
276 
277 
278 //=============================================================================
279 
280 //=============================================================================
ACG::Vec3d flyPosition_
The new position after the flyTo animation.
bool flyMoveBack_
Flag for fly in orthogonal mode if we move back or forward.
double sceneRadius()
Get radius of the current scene.
virtual void flyTo(const QPoint &_pos, bool _moveBack)
Animated flight to or away from a given point.
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
double lastAnimationPos_
The last position of the animation to compute the difference vector.
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Definition: GLState.cc:649
double trackballRadius()
Get trackball radius (rotation sphere when using mouse)
QPropertyAnimation * flyAnimationPerspective_
The animation object for flyTo.
void translate(const ACG::Vec3d &trans)
translate the scene and update modelview matrix
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
void updateProjectionMatrix()
updates projection matrix
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:794
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
Definition: Matrix4x4T.cc:225
void flyAnimationOrthogonal(QVariant _pos)
Slot called during flyTo Animation in orthogonal mode.
double flyAngle_
The rotation angle (full angle) for fly to animation.
ACG::Vec3d flyTranslation_
Full translation between start and ed of animation.
int viewport_width() const
get viewport width
Definition: GLState.hh:825
bool pick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, unsigned int &_nodeIdx, unsigned int &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
ACG::Vec3d flyAxis_
The rotation axis for fly to animation.
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
void flyAnimationOrthogonalFinished()
Slot called when flyTo orthogonal Animation finished.
double orthoWidth()
Get width of the gl scene in orthogonal projection mode (defaults to 2.0)
ACG::GLState * glstate_
Gl State.
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
Definition: GLState.hh:819
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
Definition: Matrix4x4T.cc:202
bool updatePickCache_
Should the pick cache be updated.
void rotate(const ACG::Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix
bool allowRotation_
mouse interaction position
void flyAnimationPerspectiveFinished()
Slot called when flyTo perspective Animation finished.
QPropertyAnimation * flyAnimationOrthogonal_
The animation object for flyTo.
Viewer::ViewerProperties & properties_
All properties for this viewer.
void flyAnimationPerspective(QVariant _pos)
Slot called during flyTo Animation in perspective mode.
Vec3d eye() const
get eye point
Definition: GLState.cc:882
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:638
int viewport_height() const
get viewport height
Definition: GLState.hh:827
ACG::Vec3d trackballCenter()
Get virtual trackball center (rotation center when using mouse)
ACG::Vec3d flyCenter_
The new center after the flyTo animation.
void viewChanged()
This signal is emitted whenever the view is changed by the user.
double flyOrthoWidthOriginal_
Original orthogonal width during flyTo in orthogonal mode.