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 
45 
46 
47 //=============================================================================
48 //
49 // CLASS glViewer - IMPLEMENTATION
50 //
51 //=============================================================================
52 
53 
54 //== INCLUDES =================================================================
55 
56 #include "QtBaseViewer.hh"
57 #include <QPropertyAnimation>
58 
59 
60 //== NAMESPACES ===============================================================
61 
62 //== IMPLEMENTATION ==========================================================
63 
64 
65 void glViewer::flyTo(const QPoint& _pos, bool _moveBack)
66 {
67  makeCurrent();
68 
69  size_t nodeIdx, targetIdx;
70  ACG::Vec3d hitPoint;
71 
72  if (pick( ACG::SceneGraph::PICK_ANYTHING, _pos, nodeIdx, targetIdx, &hitPoint))
73  {
74  if (projectionMode_ == PERSPECTIVE_PROJECTION)
75  {
76  ACG::Vec3d eye(glstate_->eye());
77  ACG::Vec3d t = hitPoint - eye;
78  ACG::Vec3d e = eye + t * (_moveBack ? -0.5f : 0.5f);
79  flyTo(e, hitPoint, 300);
80  }
81  else
82  {
83  // Project hitpoint to get depth
84  ACG::Vec3d hitPointProjected = glstate_->project(hitPoint);
85 
86  // Create projected center point with same depth as hitpoint
87  ACG::Vec3d centerPointProjected = hitPointProjected;
88 
89  // Get viewport data
90  int w = 0, h = 0,left = 0, bottom = 0;
91  glstate_->get_viewport(left, bottom, w, h);
92 
93  // Compute the center point. Note that the project function includes the viewport matrix.
94  // As we have different viewports for the viewer but one global coord system,
95  // we need to set the real center coordinates and therefore add the lower left corner position
96  // which is the left and bottom of the viewport
97  centerPointProjected[0] = left + glstate_->viewport_width() / 2.0 ;
98  centerPointProjected[1] = bottom + glstate_->viewport_height() / 2.0 ;
99 
100  // unproject center point
101  ACG::Vec3d centerPointUnProjected = glstate_->unproject(centerPointProjected);
102 
103  // translation vector to make hit point project to center point (both need same depth)
104  ACG::Vec3d t = hitPoint - centerPointUnProjected;
105 
106  // Transform to correct translation vector with modelview.
108 
109  // remember originalWidth
111 
112  // Initialize as we start at 0.0
113  lastAnimationPos_ = 0.0;
114 
115  // store the direction for the actual animation
116  flyMoveBack_ = _moveBack;
117 
118  // Set the double click point as the new trackball center
119  // Rotations will use this point as the center.
120  properties_.trackballCenter( hitPoint );
121 
122  // Create animation object
123  if ( flyAnimationOrthogonal_ == 0) {
124  flyAnimationOrthogonal_ = new QPropertyAnimation(this, "currentAnimationPosition");
125 
126 
127  // Range is from 0 to one, as we linearly interpolate the animation
128  flyAnimationOrthogonal_->setStartValue(0.0);
129  flyAnimationOrthogonal_->setEndValue(1.0);
130 
131  // Connect signals for the animation and its end
132  connect(flyAnimationOrthogonal_, SIGNAL(valueChanged(QVariant)), this, SLOT(flyAnimationOrthogonal(QVariant)));
133  connect(flyAnimationOrthogonal_, SIGNAL(finished()), this, SLOT(flyAnimationOrthogonalFinished()));
134  }
135 
136  // Set duration
137  flyAnimationOrthogonal_->setDuration(300);
138 
139  // Start it
140  flyAnimationOrthogonal_->start();
141 
142  }
143  }
144 }
145 
146 void glViewer::flyAnimationOrthogonal(QVariant _pos) {
147 
148  const double pos = _pos.toDouble();
149 
150  // compute difference
151  const double diff = pos - lastAnimationPos_;
152 
153  // zoom back one frame
154  if ( flyMoveBack_ ) {
155  // Move back by factor 2
157  } else
158  // Move forward with factor 0.5
159  properties_.orthoWidth( flyOrthoWidthOriginal_ * (1.0 - 0.5 * pos ) );
160 
161  // apply translation
162  translate(- flyTranslation_ * diff );
163 
164  // Store our current position for next loop
165  lastAnimationPos_ = pos;
166 
167  // Pick cache is definitely invalid after that
168  updatePickCache_ = true;
169 
170  // update rendering
171  update();
172 }
173 
175 
176  const double pos = _pos.toDouble();
177 
178  // Animate pos from 0 to 1 so we need to calculate the difference and the resulting transformations
180  double a = (pos - lastAnimationPos_) * flyAngle_ ;
181 
182  translate(t);
183 
184  // Only rotate, if we have realistic values and if rotation is allowed
185  if ( allowRotation_ )
186  if (fabs(a) > FLT_MIN)
188 
189  // Pick cache is definitely invalid after that
190  updatePickCache_ = true;
191 
192  // Store our current position for next loop
193  lastAnimationPos_ = pos;
194 
195  // update rendering
196  update();
197 
198 }
199 
201 
202  // Update the projection matrix
204 
205  // Redraw scene
206  updateGL();
207 
208  // Inform others that the current view has changed
209  emit viewChanged();
210 
211 }
212 
214 
215  // Update the trackball to the final position
217  properties_.trackballRadius( std::max( properties_.sceneRadius(),( flyCenter_ - flyPosition_ ).norm() * 0.9f ) );
218 
219 }
220 
221 void glViewer::flyTo(const ACG::Vec3d& _position,
222  const ACG::Vec3d& _center,
223  int _time)
224 {
225  makeCurrent();
226 
227  // compute rotation
229  ACG::Vec3d p = glstate_->modelview().transform_point(_position);
230  ACG::Vec3d view =(p-c).normalize();
231  ACG::Vec3d z(0,0,1);
232 
233  flyAxis_ = (z % -view).normalize();
234 
235  flyAngle_ = acos(std::max(-1.0, std::min(1.0, (z | view)))) / M_PI * 180.0;
236 
237  if (flyAngle_ > 175)
238  flyAxis_ = ACG::Vec3d(0,1,0);
239 
240  // compute translation
241  ACG::Vec3d target = glstate_->modelview().transform_point(_center);
242  flyTranslation_ = ACG::Vec3d( -target[0], -target[1], -target[2] - (_position-_center).norm() );
243 
244  // Store other values for animation
245  flyCenter_ = _center;
246  flyPosition_ = _position;
247 
248  // Initialize as we start at 0.0
249  lastAnimationPos_ = 0.0;
250 
251  // Create animation object
252  if ( flyAnimationPerspective_ == 0) {
253  flyAnimationPerspective_ = new QPropertyAnimation(this, "currentAnimationPosition");
254 
255  // Range is from 0 to one, as we linearly interpolate the animation
256  flyAnimationPerspective_->setStartValue(0.0);
257  flyAnimationPerspective_->setEndValue(1.0);
258 
259  // Connect signals for the animation and its end
260  connect(flyAnimationPerspective_, SIGNAL(valueChanged(QVariant)), this, SLOT(flyAnimationPerspective(QVariant)));
261  connect(flyAnimationPerspective_, SIGNAL(finished()), this, SLOT(flyAnimationPerspectiveFinished()));
262  }
263 
264  // Set duration
265  flyAnimationPerspective_->setDuration(_time);
266 
267  // Start it
268  flyAnimationPerspective_->start();
269 }
270 
271 
272 //=============================================================================
273 
274 //=============================================================================
ACG::Vec3d flyTranslation_
Full translation between start and ed of animation.
ACG::Vec3d flyCenter_
The new center after the flyTo animation.
double sceneRadius()
Get radius of the current scene.
ACG::Vec3d trackballCenter()
Get virtual trackball center (rotation center when using mouse)
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
double flyOrthoWidthOriginal_
Original orthogonal width during flyTo in orthogonal mode.
int viewport_width() const
get viewport width
Definition: GLState.hh:822
void updateProjectionMatrix(double _aspect=0.0)
updates projection matrix
void rotate(const ACG::Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix
bool allowRotation_
mouse interaction position
bool updatePickCache_
Should the pick cache be updated.
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)
ACG::GLState * glstate_
Gl State.
QPropertyAnimation * flyAnimationPerspective_
The animation object for flyTo.
bool flyMoveBack_
Flag for fly in orthogonal mode if we move back or forward.
double trackballRadius()
Get trackball radius (rotation sphere when using mouse)
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Definition: GLState.cc:651
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
QPropertyAnimation * flyAnimationOrthogonal_
The animation object for flyTo.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
Viewer::ViewerProperties & properties_
All properties for this viewer.
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
int viewport_height() const
get viewport height
Definition: GLState.hh:824
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
Definition: GLState.hh:816
double lastAnimationPos_
The last position of the animation to compute the difference vector.
Vec3d eye() const
get eye point
Definition: GLState.cc:886
double flyAngle_
The rotation angle (full angle) for fly to animation.
void viewChanged()
This signal is emitted whenever the view is changed by the user.
void flyAnimationPerspective(QVariant _pos)
Slot called during flyTo Animation in perspective mode.
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:791
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
ACG::Vec3d flyPosition_
The new position after the flyTo animation.
void flyAnimationOrthogonalFinished()
Slot called when flyTo orthogonal Animation finished.
void flyAnimationPerspectiveFinished()
Slot called when flyTo perspective Animation finished.
virtual void flyTo(const QPoint &_pos, bool _moveBack)
Animated flight to or away from a given point.
void flyAnimationOrthogonal(QVariant _pos)
Slot called during flyTo Animation in orthogonal mode.
bool pick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
double orthoWidth()
Get width of the gl scene in orthogonal projection mode (defaults to 2.0)
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)
void translate(const ACG::Vec3d &trans)
translate the scene and update modelview matrix
ACG::Vec3d flyAxis_
The rotation axis for fly to animation.