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.
107 flyTranslation_ = glstate_->modelview().transform_vector(t);
108
109 // remember originalWidth
110 flyOrthoWidthOriginal_ = properties_.orthoWidth();
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
156 properties_.orthoWidth( flyOrthoWidthOriginal_ * (1.0 + pos ) );
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
174 void glViewer::flyAnimationPerspective(QVariant _pos) {
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
179 ACG::Vec3d t = (pos - lastAnimationPos_) * flyTranslation_ ;
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)
187 rotate(flyAxis_, a, flyCenter_);
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
200 void glViewer::flyAnimationOrthogonalFinished() {
201
202 // Update the projection matrix
203 updateProjectionMatrix();
204
205 // Redraw scene
206 updateGL();
207
208 // Inform others that the current view has changed
209 emit viewChanged();
210
211 }
212
213 void glViewer::flyAnimationPerspectiveFinished() {
214
215 // Update the trackball to the final position
216 properties_.trackballCenter( flyCenter_ );
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
228 ACG::Vec3d c = glstate_->modelview().transform_point(_center);
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 //=============================================================================
glViewer::flyTranslation_
ACG::Vec3d flyTranslation_
Full translation between start and ed of animation.
Definition: QtBaseViewer.hh:1049
glViewer::flyCenter_
ACG::Vec3d flyCenter_
The new center after the flyTo animation.
Definition: QtBaseViewer.hh:1069
Viewer::ViewerProperties::sceneRadius
double sceneRadius()
Get radius of the current scene.
Definition: ViewerProperties.cc:372
Viewer::ViewerProperties::trackballCenter
ACG::Vec3d trackballCenter()
Get virtual trackball center (rotation center when using mouse)
Definition: ViewerProperties.cc:381
ACG::SceneGraph::PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
glViewer::flyOrthoWidthOriginal_
double flyOrthoWidthOriginal_
Original orthogonal width during flyTo in orthogonal mode.
Definition: QtBaseViewer.hh:1078
glViewer::PERSPECTIVE_PROJECTION
perspective
Definition: QtBaseViewer.hh:198
ACG::GLState::viewport_width
int viewport_width() const
get viewport width
Definition: GLState.hh:822
glViewer::updateProjectionMatrix
void updateProjectionMatrix(double _aspect=0.0)
updates projection matrix
Definition: QtBaseViewer.cc:399
glViewer::rotate
void rotate(const ACG::Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix
Definition: QtBaseViewer.hh:342
glViewer::allowRotation_
bool allowRotation_
mouse interaction position
Definition: QtBaseViewer.hh:952
glViewer::updatePickCache_
bool updatePickCache_
Should the pick cache be updated.
Definition: QtBaseViewer.hh:882
ACG::Matrix4x4T::transform_point
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_impl.hh:196
glViewer::glstate_
ACG::GLState * glstate_
Gl State.
Definition: QtBaseViewer.hh:984
glViewer::flyAnimationPerspective_
QPropertyAnimation * flyAnimationPerspective_
The animation object for flyTo.
Definition: QtBaseViewer.hh:1045
glViewer::flyMoveBack_
bool flyMoveBack_
Flag for fly in orthogonal mode if we move back or forward.
Definition: QtBaseViewer.hh:1081
Viewer::ViewerProperties::trackballRadius
double trackballRadius()
Get trackball radius (rotation sphere when using mouse)
Definition: ViewerProperties.cc:390
ACG::GLState::unproject
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Definition: GLState.cc:651
ACG::GLState::project
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
glViewer::flyAnimationOrthogonal_
QPropertyAnimation * flyAnimationOrthogonal_
The animation object for flyTo.
Definition: QtBaseViewer.hh:1046
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
glViewer::properties_
Viewer::ViewerProperties & properties_
All properties for this viewer.
Definition: QtBaseViewer.hh:977
glViewer::updateGL
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
Definition: QtBaseViewer.cc:524
ACG::GLState::viewport_height
int viewport_height() const
get viewport height
Definition: GLState.hh:824
ACG::GLState::get_viewport
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
Definition: GLState.hh:816
glViewer::lastAnimationPos_
double lastAnimationPos_
The last position of the animation to compute the difference vector.
Definition: QtBaseViewer.hh:1058
ACG::GLState::eye
Vec3d eye() const
get eye point
Definition: GLState.cc:886
glViewer::flyAngle_
double flyAngle_
The rotation angle (full angle) for fly to animation.
Definition: QtBaseViewer.hh:1055
glViewer::viewChanged
void viewChanged()
This signal is emitted whenever the view is changed by the user.
glViewer::flyAnimationPerspective
void flyAnimationPerspective(QVariant _pos)
Slot called during flyTo Animation in perspective mode.
Definition: QtBaseViewerFlyAnimation.cc:174
ACG::GLState::modelview
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:791
glViewer::makeCurrent
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
Definition: QtBaseViewer.cc:228
OpenMesh::VectorT
Definition: Vector11T.hh:83
glViewer::flyPosition_
ACG::Vec3d flyPosition_
The new position after the flyTo animation.
Definition: QtBaseViewer.hh:1075
glViewer::flyAnimationOrthogonalFinished
void flyAnimationOrthogonalFinished()
Slot called when flyTo orthogonal Animation finished.
Definition: QtBaseViewerFlyAnimation.cc:200
glViewer::flyAnimationPerspectiveFinished
void flyAnimationPerspectiveFinished()
Slot called when flyTo perspective Animation finished.
Definition: QtBaseViewerFlyAnimation.cc:213
glViewer::flyTo
virtual void flyTo(const QPoint &_pos, bool _moveBack)
Animated flight to or away from a given point.
Definition: QtBaseViewerFlyAnimation.cc:65
glViewer::flyAnimationOrthogonal
void flyAnimationOrthogonal(QVariant _pos)
Slot called during flyTo Animation in orthogonal mode.
Definition: QtBaseViewerFlyAnimation.cc:146
glViewer::pick
bool pick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Definition: QtBaseViewerPicking.cc:71
Viewer::ViewerProperties::orthoWidth
double orthoWidth()
Get width of the gl scene in orthogonal projection mode (defaults to 2.0)
Definition: ViewerProperties.cc:339
ACG::Matrix4x4T::transform_vector
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_impl.hh:219
glViewer::translate
void translate(const ACG::Vec3d &trans)
translate the scene and update modelview matrix
Definition: QtBaseViewer.cc:1408
glViewer::flyAxis_
ACG::Vec3d flyAxis_
The rotation axis for fly to animation.
Definition: QtBaseViewer.hh:1052