constraint.cpp
1 /****************************************************************************
2 
3  Copyright (C) 2002-2008 Gilles Debunne. All rights reserved.
4 
5  This file is part of the QGLViewer library version 2.3.10.
6 
7  http://www.libqglviewer.com - contact@libqglviewer.com
8 
9  This file may be used under the terms of the GNU General Public License
10  versions 2.0 or 3.0 as published by the Free Software Foundation and
11  appearing in the LICENSE file included in the packaging of this file.
12  In addition, as a special exception, Gilles Debunne gives you certain
13  additional rights, described in the file GPL_EXCEPTION in this package.
14 
15  libQGLViewer uses dual licensing. Commercial/proprietary software must
16  purchase a libQGLViewer Commercial License.
17 
18  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
19  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 
21 *****************************************************************************/
22 
23 #include "constraint.h"
24 #include "frame.h"
25 #include "camera.h"
26 
27 using namespace qglviewer;
28 using namespace std;
29 
31 // Constraint //
33 
39  : translationConstraintType_(FREE), rotationConstraintType_(FREE)
40 {
41  // Do not use set since setRotationConstraintType needs a read.
42 }
43 
46 {
49 }
50 
53 {
54  if ((translationConstraintType()!=AxisPlaneConstraint::FREE) && (translationConstraintType()!=AxisPlaneConstraint::FORBIDDEN))
55  {
56  const float norm = direction.norm();
57  if (norm < 1E-8)
58  {
59  qWarning("AxisPlaneConstraint::setTranslationConstraintDir: null vector for translation constraint");
60  translationConstraintType_ = AxisPlaneConstraint::FREE;
61  }
62  else
63  translationConstraintDir_ = direction/norm;
64  }
65 }
66 
69 {
72 }
73 
76 {
77  if ((rotationConstraintType()!=AxisPlaneConstraint::FREE) && (rotationConstraintType()!=AxisPlaneConstraint::FORBIDDEN))
78  {
79  float norm = direction.norm();
80  if (norm < 1E-8)
81  {
82  qWarning("AxisPlaneConstraint::setRotationConstraintDir: null vector for rotation constraint");
83  rotationConstraintType_ = AxisPlaneConstraint::FREE;
84  }
85  else
86  rotationConstraintDir_ = direction/norm;
87  }
88 }
89 
102 {
103  if (rotationConstraintType() == AxisPlaneConstraint::PLANE)
104  {
105  qWarning("AxisPlaneConstraint::setRotationConstraintType: the PLANE type cannot be used for a rotation constraints");
106  return;
107  }
108 
109  rotationConstraintType_ = type;
110 }
111 
112 
114 // LocalConstraint //
116 
120 void LocalConstraint::constrainTranslation(Vec& translation, Frame* const frame)
121 {
122  Vec proj;
123  switch (translationConstraintType())
124  {
125  case AxisPlaneConstraint::FREE:
126  break;
127  case AxisPlaneConstraint::PLANE:
129  translation.projectOnPlane(proj);
130  break;
131  case AxisPlaneConstraint::AXIS:
133  translation.projectOnAxis(proj);
134  break;
135  case AxisPlaneConstraint::FORBIDDEN:
136  translation = Vec(0.0, 0.0, 0.0);
137  break;
138  }
139 }
140 
145 {
146  switch (rotationConstraintType())
147  {
148  case AxisPlaneConstraint::FREE:
149  break;
150  case AxisPlaneConstraint::PLANE:
151  break;
152  case AxisPlaneConstraint::AXIS:
153  {
155  Vec quat = Vec(rotation[0], rotation[1], rotation[2]);
156  quat.projectOnAxis(axis);
157  rotation = Quaternion(quat, 2.0*acos(rotation[3]));
158  }
159  break;
160  case AxisPlaneConstraint::FORBIDDEN:
161  rotation = Quaternion(); // identity
162  break;
163  }
164 }
165 
167 // WorldConstraint //
169 
173 void WorldConstraint::constrainTranslation(Vec& translation, Frame* const frame)
174 {
175  Vec proj;
176  switch (translationConstraintType())
177  {
178  case AxisPlaneConstraint::FREE:
179  break;
180  case AxisPlaneConstraint::PLANE:
181  if (frame->referenceFrame())
182  {
184  translation.projectOnPlane(proj);
185  }
186  else
188  break;
189  case AxisPlaneConstraint::AXIS:
190  if (frame->referenceFrame())
191  {
193  translation.projectOnAxis(proj);
194  }
195  else
197  break;
198  case AxisPlaneConstraint::FORBIDDEN:
199  translation = Vec(0.0, 0.0, 0.0);
200  break;
201  }
202 }
203 
208 {
209  switch (rotationConstraintType())
210  {
211  case AxisPlaneConstraint::FREE:
212  break;
213  case AxisPlaneConstraint::PLANE:
214  break;
215  case AxisPlaneConstraint::AXIS:
216  {
217  Vec quat(rotation[0], rotation[1], rotation[2]);
219  quat.projectOnAxis(axis);
220  rotation = Quaternion(quat, 2.0*acos(rotation[3]));
221  break;
222  }
223  case AxisPlaneConstraint::FORBIDDEN:
224  rotation = Quaternion(); // identity
225  break;
226  }
227 }
228 
230 // CameraConstraint //
232 
236  : AxisPlaneConstraint(), camera_(camera)
237 {}
238 
242 void CameraConstraint::constrainTranslation(Vec& translation, Frame* const frame)
243 {
244  Vec proj;
245  switch (translationConstraintType())
246  {
247  case AxisPlaneConstraint::FREE:
248  break;
249  case AxisPlaneConstraint::PLANE:
251  if (frame->referenceFrame())
252  proj = frame->referenceFrame()->transformOf(proj);
253  translation.projectOnPlane(proj);
254  break;
255  case AxisPlaneConstraint::AXIS:
257  if (frame->referenceFrame())
258  proj = frame->referenceFrame()->transformOf(proj);
259  translation.projectOnAxis(proj);
260  break;
261  case AxisPlaneConstraint::FORBIDDEN:
262  translation = Vec(0.0, 0.0, 0.0);
263  break;
264  }
265 }
266 
271 {
272  switch (rotationConstraintType())
273  {
274  case AxisPlaneConstraint::FREE:
275  break;
276  case AxisPlaneConstraint::PLANE:
277  break;
278  case AxisPlaneConstraint::AXIS:
279  {
280  Vec axis = frame->transformOf(camera()->frame()->inverseTransformOf(rotationConstraintDirection()));
281  Vec quat = Vec(rotation[0], rotation[1], rotation[2]);
282  quat.projectOnAxis(axis);
283  rotation = Quaternion(quat, 2.0*acos(rotation[3]));
284  }
285  break;
286  case AxisPlaneConstraint::FORBIDDEN:
287  rotation = Quaternion(); // identity
288  break;
289  }
290 }