Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
GLTrackball.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 * $Author$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50
51
52 //=============================================================================
53 //
54 // CLASS GLTrackball - IMPLEMENTATION
55 //
56 //=============================================================================
57
58 //== INCLUDES =================================================================
59
60
61 #include "GLTrackball.hh"
62
63
64 //== NAMESPACES ===============================================================
65
66
67 namespace ACG {
68
69
70 //== IMPLEMENTATION ==========================================================
71
72
73 GLTrackball::
74 GLTrackball(GLState& _state)
75 : glstate_(_state),
76 center_(0,0,0) ,
77 last_point_ok_(false),
78 action_(ROTATION)
79 {
80 for (int i=0; i<10; ++i)
81 button_down_[i] = false;
82 }
83
84
85 //-----------------------------------------------------------------------------
86
87
88 void
89 GLTrackball::mouse_press(int button, int x, int y)
90 {
91 last_point_2D_ = ACG::Vec2i(x, y);
92 last_point_ok_ = map_to_sphere(last_point_2D_, last_point_3D_);
93
94 button_down_[button] = true;
95 }
96
97
98 //-----------------------------------------------------------------------------
99
100
101 void
102 GLTrackball::mouse_release(int button, int /* x */ , int /* y */ )
103 {
104 last_point_ok_ = false;
105 button_down_[button] = false;
106
107 // GLUT: button 3 or 4 -> mouse wheel clicked
108 if (button == 3)
109 zoom(0, (int)(last_point_2D_[1] - 0.05*glstate_.viewport_width()));
110 else if (button == 4)
111 zoom(0, (int)(last_point_2D_[1] + 0.05*glstate_.viewport_width()));
112 }
113
114
115 //-----------------------------------------------------------------------------
116
117
118 void
119 GLTrackball::mouse_move(int x, int y)
120 {
121 if (button_down_[0] && button_down_[1])
122 action_ = ZOOM;
123 else if (button_down_[0])
124 action_ = ROTATION;
125 else if (button_down_[1])
126 action_ = TRANSLATION;
127
128 switch (action_)
129 {
130 case ROTATION: rotation(x, y); break;
131 case TRANSLATION: translation(x, y); break;
132 case ZOOM: zoom(x, y); break;
133 }
134
135 last_point_2D_ = ACG::Vec2i(x, y);
136 last_point_ok_ = map_to_sphere(last_point_2D_, last_point_3D_);
137 }
138
139
140 //-----------------------------------------------------------------------------
141
142
143 void
144 GLTrackball::rotation(int x, int y)
145 {
146 if (last_point_ok_)
147 {
148 Vec2i new_point_2D_;
149 Vec3f new_point_3D_;
150 bool new_point_ok_;
151
152 new_point_2D_ = ACG::Vec2i(x, y);
153 new_point_ok_ = map_to_sphere(new_point_2D_, new_point_3D_);
154
155 if (new_point_ok_)
156 {
157 Vec3f axis = (last_point_3D_ % new_point_3D_);
158 float cos_angle = (last_point_3D_ | new_point_3D_);
159
160 if (fabs(cos_angle) < 1.0)
161 {
162 double angle = 2.0*acos(cos_angle) * 180.0 / M_PI;
163
164 Vec3d t = glstate_.modelview().transform_point(center_);
165 glstate_.translate(-t[0], -t[1], -t[2], MULT_FROM_LEFT);
166 glstate_.rotate(angle, axis[0], axis[1], axis[2], MULT_FROM_LEFT);
167 glstate_.translate( t[0], t[1], t[2], MULT_FROM_LEFT);
168 }
169 }
170 }
171 }
172
173
174 //-----------------------------------------------------------------------------
175
176
177 void
178 GLTrackball::translation(int x, int y)
179 {
180 double dx = double(x - last_point_2D_[0]);
181 double dy = double(y - last_point_2D_[1]);
182
183 double z = glstate_.modelview().transform_point(center_)[2];
184 double w = double(glstate_.viewport_width());
185 double h = double(glstate_.viewport_height());
186 double fovy = double(glstate_.fovy());
187 double nearpl = double(glstate_.near_plane());
188
189 double aspect = w / h;
190 double top = double(tan(fovy/2.0*M_PI/180.0) * nearpl);
191 double right = aspect*top;
192
193 glstate_.translate(-2.0*dx/w*right/nearpl*z,
194 2.0*dy/h*top/nearpl*z,
195 0.0,
196 MULT_FROM_LEFT);
197 }
198
199
200 //-----------------------------------------------------------------------------
201
202
203 void
204 GLTrackball::zoom(int /* x */ , int y)
205 {
206 double dy = double(y - last_point_2D_[1]);
207 double z = glstate_.modelview().transform_point(center_)[2];
208 double h = double(glstate_.viewport_height());
209
210 glstate_.translate(0.0,
211 0.0,
212 -2.0*dy/h*z,
213 MULT_FROM_LEFT);
214 }
215
216
217 //-----------------------------------------------------------------------------
218
219
220 bool
221 GLTrackball::map_to_sphere(const Vec2i& _point, Vec3f& _result)
222 {
223 float width = float(glstate_.viewport_width());
224 float height = float(glstate_.viewport_height());
225
226 if ( (_point[0] >= 0) && (_point[0] <= width) &&
227 (_point[1] >= 0) && (_point[1] <= height) )
228 {
229 double x = (_point[0] - 0.5*width) / width;
230 double y = (0.5*height - _point[1]) / height;
231 double sinx = sin(M_PI * x * 0.5);
232 double siny = sin(M_PI * y * 0.5);
233 double sinx2siny2 = sinx * sinx + siny * siny;
234
235 _result[0] = float(sinx);
236 _result[1] = float(siny);
237 _result[2] = sinx2siny2 < 1.0 ? float( sqrt(1.0 - sinx2siny2) ) : 0.0f;
238
239 return true;
240 }
241 else return false;
242 }
243
244
245 //=============================================================================
246 } // namespace ACG
247 //=============================================================================
ACG
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
ACG::Vec2i
VectorT< signed int, 2 > Vec2i
Definition: VectorT.hh:104
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
PluginFunctions::fovy
DLLEXPORT double fovy(int _viewer)
Get field of view angle.
Definition: PluginFunctions.cc:931
OpenVolumeMesh::Geometry::VectorT
Definition: Vector11T.hh:78
OpenMesh::angle
T angle(T _cos_angle, T _sin_angle)
Definition: MathDefs.hh:145