Developer Documentation
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 //=============================================================================
void flyAnimationPerspective(QVariant _pos)
Slot called during flyTo Animation in perspective mode.
Vec3d eye() const
get eye point
Definition: GLState.cc:882
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x&#39;,y&#39;,z&#39;,1) = M * (x,y,z,1)
Definition: Matrix4x4T.cc:202
ACG::GLState * glstate_
Gl State.
bool pick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, unsigned int &_nodeIdx, unsigned int &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
bool updatePickCache_
Should the pick cache be updated.
void flyAnimationOrthogonal(QVariant _pos)
Slot called during flyTo Animation in orthogonal mode.
void flyAnimationPerspectiveFinished()
Slot called when flyTo perspective Animation finished.
double sceneRadius()
Get radius of the current scene.
double lastAnimationPos_
The last position of the animation to compute the difference vector.
int viewport_width() const
get viewport width
Definition: GLState.hh:825
virtual void flyTo(const QPoint &_pos, bool _moveBack)
Animated flight to or away from a given point.
ACG::Vec3d flyPosition_
The new position after the flyTo animation.
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:638
void flyAnimationOrthogonalFinished()
Slot called when flyTo orthogonal Animation finished.
Viewer::ViewerProperties & properties_
All properties for this viewer.
double orthoWidth()
Get width of the gl scene in orthogonal projection mode (defaults to 2.0)
QPropertyAnimation * flyAnimationOrthogonal_
The animation object for flyTo.
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Definition: GLState.cc:649
void updateProjectionMatrix(double _aspect=0.0)
updates projection matrix
double flyAngle_
The rotation angle (full angle) for fly to animation.
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
ACG::Vec3d trackballCenter()
Get virtual trackball center (rotation center when using mouse)
ACG::Vec3d flyTranslation_
Full translation between start and ed of animation.
ACG::Vec3d flyAxis_
The rotation axis for fly to animation.
double trackballRadius()
Get trackball radius (rotation sphere when using mouse)
void translate(const ACG::Vec3d &trans)
translate the scene and update modelview matrix
bool allowRotation_
mouse interaction position
QPropertyAnimation * flyAnimationPerspective_
The animation object for flyTo.
double flyOrthoWidthOriginal_
Original orthogonal width during flyTo in orthogonal mode.
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:794
void viewChanged()
This signal is emitted whenever the view is changed by the user.
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
int viewport_height() const
get viewport height
Definition: GLState.hh:827
bool flyMoveBack_
Flag for fly in orthogonal mode if we move back or forward.
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
Definition: GLState.hh:819
ACG::Vec3d flyCenter_
The new center after the flyTo animation.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x&#39;,y&#39;,z&#39;,0) = A * (x,y,z,0)
Definition: Matrix4x4T.cc:225
void rotate(const ACG::Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix