constraint.cpp
1 /****************************************************************************
2 
3  Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
4 
5  This file is part of the QGLViewer library version 2.5.2.
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 #include "manipulatedCameraFrame.h"
27 
28 using namespace qglviewer;
29 using namespace std;
30 
32 // Constraint //
34 
40  : translationConstraintType_(FREE), rotationConstraintType_(FREE)
41 {
42  // Do not use set since setRotationConstraintType needs a read.
43 }
44 
47 {
50 }
51 
54 {
55  if ((translationConstraintType()!=AxisPlaneConstraint::FREE) && (translationConstraintType()!=AxisPlaneConstraint::FORBIDDEN))
56  {
57  const float norm = direction.norm();
58  if (norm < 1E-8)
59  {
60  qWarning("AxisPlaneConstraint::setTranslationConstraintDir: null vector for translation constraint");
61  translationConstraintType_ = AxisPlaneConstraint::FREE;
62  }
63  else
64  translationConstraintDir_ = direction/norm;
65  }
66 }
67 
70 {
73 }
74 
77 {
78  if ((rotationConstraintType()!=AxisPlaneConstraint::FREE) && (rotationConstraintType()!=AxisPlaneConstraint::FORBIDDEN))
79  {
80  float norm = direction.norm();
81  if (norm < 1E-8)
82  {
83  qWarning("AxisPlaneConstraint::setRotationConstraintDir: null vector for rotation constraint");
84  rotationConstraintType_ = AxisPlaneConstraint::FREE;
85  }
86  else
87  rotationConstraintDir_ = direction/norm;
88  }
89 }
90 
103 {
104  if (rotationConstraintType() == AxisPlaneConstraint::PLANE)
105  {
106  qWarning("AxisPlaneConstraint::setRotationConstraintType: the PLANE type cannot be used for a rotation constraints");
107  return;
108  }
109 
110  rotationConstraintType_ = type;
111 }
112 
113 
115 // LocalConstraint //
117 
121 void LocalConstraint::constrainTranslation(Vec& translation, Frame* const frame)
122 {
123  Vec proj;
124  switch (translationConstraintType())
125  {
126  case AxisPlaneConstraint::FREE:
127  break;
128  case AxisPlaneConstraint::PLANE:
130  translation.projectOnPlane(proj);
131  break;
132  case AxisPlaneConstraint::AXIS:
134  translation.projectOnAxis(proj);
135  break;
136  case AxisPlaneConstraint::FORBIDDEN:
137  translation = Vec(0.0, 0.0, 0.0);
138  break;
139  }
140 }
141 
146 {
147  switch (rotationConstraintType())
148  {
149  case AxisPlaneConstraint::FREE:
150  break;
151  case AxisPlaneConstraint::PLANE:
152  break;
153  case AxisPlaneConstraint::AXIS:
154  {
156  Vec quat = Vec(rotation[0], rotation[1], rotation[2]);
157  quat.projectOnAxis(axis);
158  rotation = Quaternion(quat, 2.0*acos(rotation[3]));
159  }
160  break;
161  case AxisPlaneConstraint::FORBIDDEN:
162  rotation = Quaternion(); // identity
163  break;
164  }
165 }
166 
168 // WorldConstraint //
170 
174 void WorldConstraint::constrainTranslation(Vec& translation, Frame* const frame)
175 {
176  Vec proj;
177  switch (translationConstraintType())
178  {
179  case AxisPlaneConstraint::FREE:
180  break;
181  case AxisPlaneConstraint::PLANE:
182  if (frame->referenceFrame())
183  {
185  translation.projectOnPlane(proj);
186  }
187  else
189  break;
190  case AxisPlaneConstraint::AXIS:
191  if (frame->referenceFrame())
192  {
194  translation.projectOnAxis(proj);
195  }
196  else
198  break;
199  case AxisPlaneConstraint::FORBIDDEN:
200  translation = Vec(0.0, 0.0, 0.0);
201  break;
202  }
203 }
204 
209 {
210  switch (rotationConstraintType())
211  {
212  case AxisPlaneConstraint::FREE:
213  break;
214  case AxisPlaneConstraint::PLANE:
215  break;
216  case AxisPlaneConstraint::AXIS:
217  {
218  Vec quat(rotation[0], rotation[1], rotation[2]);
220  quat.projectOnAxis(axis);
221  rotation = Quaternion(quat, 2.0*acos(rotation[3]));
222  break;
223  }
224  case AxisPlaneConstraint::FORBIDDEN:
225  rotation = Quaternion(); // identity
226  break;
227  }
228 }
229 
231 // CameraConstraint //
233 
237  : AxisPlaneConstraint(), camera_(camera)
238 {}
239 
243 void CameraConstraint::constrainTranslation(Vec& translation, Frame* const frame)
244 {
245  Vec proj;
246  switch (translationConstraintType())
247  {
248  case AxisPlaneConstraint::FREE:
249  break;
250  case AxisPlaneConstraint::PLANE:
252  if (frame->referenceFrame())
253  proj = frame->referenceFrame()->transformOf(proj);
254  translation.projectOnPlane(proj);
255  break;
256  case AxisPlaneConstraint::AXIS:
258  if (frame->referenceFrame())
259  proj = frame->referenceFrame()->transformOf(proj);
260  translation.projectOnAxis(proj);
261  break;
262  case AxisPlaneConstraint::FORBIDDEN:
263  translation = Vec(0.0, 0.0, 0.0);
264  break;
265  }
266 }
267 
272 {
273  switch (rotationConstraintType())
274  {
275  case AxisPlaneConstraint::FREE:
276  break;
277  case AxisPlaneConstraint::PLANE:
278  break;
279  case AxisPlaneConstraint::AXIS:
280  {
281  Vec axis = frame->transformOf(camera()->frame()->inverseTransformOf(rotationConstraintDirection()));
282  Vec quat = Vec(rotation[0], rotation[1], rotation[2]);
283  quat.projectOnAxis(axis);
284  rotation = Quaternion(quat, 2.0*acos(rotation[3]));
285  }
286  break;
287  case AxisPlaneConstraint::FORBIDDEN:
288  rotation = Quaternion(); // identity
289  break;
290  }
291 }