V-ART
dof.cpp
Go to the documentation of this file.
1 
5 #include "vart/dof.h"
6 #include "vart/joint.h"
7 #include "vart/modifier.h"
8 #include <algorithm>
9 
10 using namespace std;
11 #ifdef VISUAL_JOINTS
12 float VART::Dof::axisSize = 0.5;
13 #endif
14 list<VART::Dof*> VART::Dof::instanceList;
15 
17 {
18  ownerJoint = NULL;
19  evoluta = NULL;
20  rangeModifier = NULL;
21 
22  // These initializations are needed in order to make a joint automatically compute
23  // its transform when setting dofs. They could be removed if the application programmer
24  // is forced to tell when a joint is ready to compute its transform.
25  axis.SetXYZW(0,0,1,0);
26  position.SetXYZW(0,0,0,1);
27  lim.MakeIdentity();
28 
29  // FixMe: (by Bruno) Not sure if the folowing initializations are needed...
30  minAngle = 0;
31  maxAngle = 0;
32  currentPosition = 0;
33  restPosition = 0;
34  instanceList.push_back(this);
35 }
36 
38 : MemoryObj(dof)
39 {
40  description = dof.description;
41  position = dof.position;
42  axis = dof.axis;
43  evoluta = dof.evoluta; //FixMe: Maybe a new evoluta should be created
44  lim = dof.lim;
45  minAngle = dof.minAngle;
46  maxAngle = dof.maxAngle;
47  currentMinAngle = dof.currentMinAngle;
48  currentMaxAngle = dof.currentMaxAngle;
49  confortMinAngle = dof.confortMinAngle;
50  confortMaxAngle = dof.confortMaxAngle;
51  rangeModifier = dof.rangeModifier;
52  currentPosition = dof.currentPosition;
53  restPosition = dof.restPosition;
54  ownerJoint = dof.ownerJoint;
55  instanceList.push_back(this);
56 }
57 
58 VART::Dof::Dof(const VART::Point4D& vec, const VART::Point4D& pos, float min, float max)
59 {
60  ownerJoint = NULL;
61  evoluta = NULL;
62  rangeModifier = NULL;
63  axis = vec;
64  position = pos;
65  minAngle = min;
66  currentMinAngle = min;
67  maxAngle = max;
68  currentMaxAngle = max;
69  currentPosition = (0-min)/(max-min);
70  axis.Normalize();
71  ComputeLIM();
72  instanceList.push_back(this);
73 }
74 
76 {
77  // remove itself from list of instances
78  list<VART::Dof*>::iterator iter = find(instanceList.begin(), instanceList.end(), this);
79  instanceList.erase(iter);
80 }
81 
83 {
84  description = dof.description;
85  position = dof.position;
86  axis = dof.axis;
87  evoluta = dof.evoluta; //FixMe: Maybe a new evoluta should be created
88  lim = dof.lim;
89  minAngle = dof.minAngle;
90  maxAngle = dof.maxAngle;
91  currentMinAngle = dof.currentMinAngle;
92  currentMaxAngle = dof.currentMaxAngle;
93  confortMinAngle = dof.confortMinAngle;
94  confortMaxAngle = dof.confortMaxAngle;
95  rangeModifier = dof.rangeModifier;
96  currentPosition = dof.currentPosition;
97  restPosition = dof.restPosition;
98  ownerJoint = dof.ownerJoint;
99  return *this;
100 }
101 
102 void VART::Dof::Set(const VART::Point4D& vec, const VART::Point4D& pos, float min, float max)
103 {
104  axis = vec;
105  position = pos;
106  minAngle = min;
107  currentMinAngle = min;
108  maxAngle = max;
109  currentMaxAngle = max;
110  // Note (by Bruno): Although not stated anywhere, it seems that when DOFs are
111  // created, their current position is that of zero rotation
112  currentPosition = (0-min)/(max-min);
113  axis.Normalize();
114  // After been set, a dof should be ready to draw
115  ComputeLIM();
116 }
117 
118 void VART::Dof::SetDescription(const string& desc)
119 {
120  description = desc;
121 }
122 
124 {
125  return axis;
126 }
127 
129 {
130  VART::Point4D result;
131  lim.GetTranslation(&result);
132  return result;
133 }
134 
136 {
137  return lim;
138 }
139 
141 {
142  resultPtr->CopyMatrix(lim);
143 }
144 
145 //~ VART::Matrix
146 //~ VART::Dof::GetBim() {
147  //~ /// Build BIM.
148  //~ axis.vpNormalize();
149  //~ VART::Vector3D vx = VART::Vector3D(1, 0, 0);
150  //~ VART::Vector3D vy = axis.vpCrossProduct(vx);
151  //~ // Verify linearity
152  //~ if (vy == VART::Vector3D(0, 0, 0)) {
153  //~ vx = VART::Vector3D(0, 0, 1);
154  //~ vy = axis.vpCrossProduct(vx);
155  //~ }
156  //~ vy.vpNormalize();
157  //~ vx = vy.vpCrossProduct(axis);
158  //~ vx.vpNormalize();
159  //~ float fm[4][4];
160 
161  //~ fm[0][0] = vx.vpGetX();
162  //~ fm[1][0] = vx.vpGetY();
163  //~ fm[2][0] = vx.vpGetZ();
164  //~ fm[3][0] = 0;
165 
166  //~ fm[0][1] = vy.vpGetX();
167  //~ fm[1][1] = vy.vpGetY();
168  //~ fm[2][1] = vy.vpGetZ();
169  //~ fm[3][1] = 0;
170 
171  //~ fm[0][2] = axis.vpGetX();
172  //~ fm[1][2] = axis.vpGetY();
173  //~ fm[2][2] = axis.vpGetZ();
174  //~ fm[3][2] = 0;
175 
176  //~ fm[0][3] = 0;
177  //~ fm[1][3] = 0;
178  //~ fm[2][3] = 0;
179  //~ fm[3][3] = 1;
180 
181  //~ VART::Matrix lBim = VART::Matrix(fm);
182  //~ return lBim;
183 //~ }
184 
185 float VART::Dof::GetMin() const
186 {
187  return minAngle;
188 }
189 
190 float VART::Dof::GetMax() const
191 {
192  return maxAngle;
193 }
194 
196 {
197  float minModif = minAngle;
198  if (rangeModifier)
199  minModif = rangeModifier->GetMin();
200  if (minAngle < minModif)
201  return minModif;
202  return minAngle;
203 }
204 
206 {
207  float maxModif = maxAngle;
208  if (rangeModifier)
209  maxModif = rangeModifier->GetMax();
210  if (maxAngle > maxModif)
211  return maxModif;
212  return maxAngle;
213 }
214 
216 {
217  return currentPosition;
218 }
219 
220 float VART::Dof::GetRest() const
221 {
222  return restPosition;
223 }
224 
226 {
227  return ownerJoint;
228 }
229 
231 {
232  axis = vec;
233 }
234 
236 {
237  evoluta = evol;
238 }
239 
240 // FixMe: There should not exist a "SetLim" because computing it is probably the
241 // main reason for the class to exist...
243 {
244  lim = t;
245 }
246 
247 void VART::Dof::SetMin(float min)
248 {
249  minAngle = min;
250 }
251 
252 void VART::Dof::SetMax(float max)
253 {
254  maxAngle = max;
255 }
256 
257 void VART::Dof::MoveTo(float pos)
258 {
259  // Avoid values out of range
260  if (pos > 1.0) pos = 1.0;
261  if (pos < 0.0) pos = 0.0;
262 
263  // Find angles by interpolation
264  double newAngle = currentMinAngle + pos * (currentMaxAngle - currentMinAngle);
265  //double currentAngle = currentMinAngle + currentPosition * (currentMaxAngle - currentMinAngle);
266 
267  // Find center of rotation
268  VART::Point4D center = position;
269  if (evoluta)
270  { // Compute "center", if necessary.
271  VART::Point4D bezierPoint;
272  evoluta->GetPoint(currentPosition, &bezierPoint);
273  bezierPoint.SetW(0); // Turn it into translation vector
274  center = position + bezierPoint;
275  }
276 
277  // Update Local Instance Matrix
278  currentPosition = pos;
279  lim.MakeRotation(center, axis, newAngle);
280 
281  // Update external (joint) state
282  ownerJoint->MakeLim();
283 }
284 
285 void VART::Dof::MoveTo(float pos, unsigned int newPriority)
286 {
287  if (newPriority > priority)
288  {
289  //~ if (description == "flexthoraxJoint")
290  //~ cout << "pos: "<<pos<<" NEW priority: "<<newPriority<<" priority: "<<priority<<endl;
291  priority = newPriority;
292  MoveTo(pos);
293  }
294 }
295 
297 {
298  // Find angle by interpolation
299  double angle = currentMinAngle + currentPosition * (currentMaxAngle - currentMinAngle);
300 
301  // Find center of rotation
302  VART::Point4D center;
303  if (evoluta)
304  {
305  VART::Point4D bezierPoint;
306  evoluta->GetPoint(currentPosition, &bezierPoint);
307  bezierPoint.SetW(0); // Turn it into translation vector
308  center = position + bezierPoint;
309  }
310  else
311  center = position;
312  // Update Local Instance Matrix
313  lim.MakeRotation(center, axis, angle);
314 }
315 
317 {
318  ownerJoint = ow;
319 }
320 
321 void VART::Dof::SetRest(float rest)
322 {
323  restPosition = rest;
324 }
325 
327 {
328  MoveTo(restPosition);
329 }
330 
332 {
333  rangeModifier = m;
334 }
335 
337 {
338  return rangeModifier;
339 }
340 
342 {
343  ptrTrans->CopyMatrix(lim * (*ptrTrans));
344 }
345 
346 void VART::Dof::Reconfigure(const Point4D& state, const Point4D& target)
347 {
348  // put target in the plane defined by current axis of rotation
349  Point4D newTarget = axis.CrossProduct(target.CrossProduct(axis));
350  Point4D realState = axis.CrossProduct( state.CrossProduct(axis));
351  // find the absolute value of the desired correction
352  double radians = acos(newTarget.DotProduct(realState));
353  // To find the signal, we check the cross product between state and target. A positive rotation
354  // is indicated by having axis (not -axis) as the result.
355  // FixMe: != is a strong operator. Use something more flexible.
356  if (realState.CrossProduct(newTarget) != axis)
357  radians = -radians;
358 // cout << "radians: " << radians;
359  // find current angle of rotation
360  double angle = currentMinAngle + currentPosition * (currentMaxAngle - currentMinAngle);
361 // cout << " angle: " << angle;
362  double newAngle = angle + radians;
363  if (newAngle < currentMinAngle)
364  newAngle = currentMinAngle;
365  else {
366  if (newAngle > currentMaxAngle)
367  newAngle = currentMaxAngle;
368  }
369 // cout << " new angle: " << newAngle << endl;
370  // find new configuration
371  MoveTo(newAngle/(currentMaxAngle - currentMinAngle));
372 }
373 
374 #ifdef VISUAL_JOINTS
375 bool VART::Dof::DrawInstanceOGL() const
376 {
377 #ifdef VART_OGL
378  float width = axisSize * 0.04; // width of the axis line
379  VART::Transform axisRotation; // a rotation around the axis
380  VART::Point4D scaledAxis; // a vector from base to tip
381  VART::Point4D baseVector; // rotating this vector on the base, we get base vertices
382  VART::Point4D vertexVector[4]; // vertices
383 
384  scaledAxis = axis * axisSize;
385  if ((1 - axis.DotProduct(VART::Point4D::Y())) < 0.01)
386  // axis is too close to Y
387  baseVector = VART::Point4D::X() * width;
388  else
389  // axis is not close to Y
390  baseVector = VART::Point4D::Y() * width;
391  axisRotation.MakeRotation(axis, 1.57079632679489661923); // set the rotation
392  vertexVector[0] = position + baseVector;
393  vertexVector[1] = vertexVector[0] + scaledAxis;
394 
395  glBegin(GL_QUADS);
396  for (int i = 1; i < 5; ++i)
397  {
398  axisRotation.ApplyTo(&baseVector);
399  vertexVector[2] = (position + scaledAxis) + baseVector;
400  vertexVector[3] = position + baseVector;
401 
402  glVertex4dv(vertexVector[3].VetXYZW());
403  glVertex4dv(vertexVector[2].VetXYZW());
404  glVertex4dv(vertexVector[1].VetXYZW());
405  glVertex4dv(vertexVector[0].VetXYZW());
406 
407  vertexVector[0] = vertexVector[3];
408  vertexVector[1] = vertexVector[2];
409  }
410  glEnd();
411  return true;
412 #else
413  return false;
414 #endif // VART_OGL
415 }
416 #endif // VISUAL_JOINTS
417 
419 // static method
420 {
421  list<VART::Dof*>::iterator iter;
422  for (iter = instanceList.begin(); iter != instanceList.end(); ++iter)
423  (*iter)->priority = 0;
424 }
425 
426 void VART::Dof::XmlPrintOn(ostream& os, unsigned int indent) const
427 // virtual method
428 {
429  string indentStr(indent,' ');
430 
431  os << indentStr << "<dof description=\"" << description << "\">\n"
432  << indentStr << " <position x=\"" << position.GetX() << "\" y=\"" << position.GetY()
433  << "\" z=\"" << position.GetZ() << "\"/>\n"
434  << indentStr << " <axis x=\"" << axis.GetX() << "\" y=\"" << axis.GetY()
435  << "\" z=\"" << axis.GetZ() << "\"/>\n"
436  << indentStr << " <range min=\"" << minAngle << "\" max=\"" << maxAngle
437  << "\" rest=\"" << restPosition << "\"/>\n"
438  << indentStr << "</dof>\n";
439  os << flush;
440 }
A modifier controls how one DOF influences other DOF.
Definition: modifier.h:16
Header file for V-ART class "Dof".
void Reconfigure(const Point4D &state, const Point4D &target)
Reconfigure DOF to match a target direction.
Definition: dof.cpp:346
Representation of joints.
Definition: joint.h:34
Points and vectors using homogeneous coordinates.
Definition: point4d.h:22
void SetEvoluta(Bezier *evol)
Definition: dof.cpp:235
static const Point4D & Y()
The Y vector (0,1,0,0).
Definition: point4d.cpp:43
void MakeRotation(const Point4D &refVec, const float radians)
Turns transform into a rotation (around some reference vetor).
Definition: transform.cpp:171
void SetW(double w)
Definition: point4d.h:115
void ApplyTo(Point4D *ptPoint) const
Applies tranformation to a point.
Definition: transform.cpp:149
A "Memory Object" is a V-ART object that has some memory allocation attributes, allowing V-ART to aut...
Definition: memoryobj.h:27
void Rest()
Definition: dof.cpp:326
float GetCurrentMax() const
Definition: dof.cpp:205
Point4D GetOrigin() const
Definition: dof.cpp:128
static void ClearPriorities()
Resets priorities of all DOF instances.
Definition: dof.cpp:418
void Normalize()
Normalizes the point/vector.
Definition: point4d.cpp:88
float GetRest() const
Returns DOF's rest position.
Definition: dof.cpp:220
void SetAxis(Point4D vec)
Definition: dof.cpp:230
void SetOwnerJoint(Joint *ow)
Definition: dof.cpp:316
float GetMin() const
Definition: dof.cpp:185
void SetDescription(const std::string &desc)
Definition: dof.cpp:118
A Bezier curve.
Definition: bezier.h:16
Header file for V-ART class "Modifier".
float GetCurrentMin() const
Definition: dof.cpp:195
Geometric transformations.
Definition: transform.h:24
void SetLim(const Transform &t)
Definition: dof.cpp:242
Point4D CrossProduct(const Point4D &p) const
Computes the cross product between "this" and "p".
Definition: point4d.cpp:121
Header file for V-ART class "Joint".
Point4D axis
Together with "position", defines the rotation axis. Relative to the parent reference system...
Definition: dof.h:155
Modifier * GetRangeModifier()
Definition: dof.cpp:336
static const Point4D & X()
The X vector (1,0,0,0).
Definition: point4d.cpp:37
Dof()
Definition: dof.cpp:16
Point4D GetAxis() const
Definition: dof.cpp:123
void MoveTo(float pos)
Sets DOF's current position.
Definition: dof.cpp:257
~Dof()
Definition: dof.cpp:75
float GetCurrent() const
Gets DOF's current position.
Definition: dof.cpp:215
void SetRangeModifier(Modifier *m)
Definition: dof.cpp:331
const Transform & GetLim() const
Definition: dof.cpp:135
double DotProduct(const Point4D &p) const
Computes the dot product between "this" and "p".
Definition: point4d.cpp:116
void CopyMatrix(const Transform &t)
Copies matrix data from another transform.
Definition: transform.cpp:138
float GetMax() const
Definition: dof.cpp:190
void SetMin(float min)
Sets DOF's minimal state.
Definition: dof.cpp:247
Joint * GetOwnerJoint() const
Definition: dof.cpp:225
void SetRest(float rest)
Definition: dof.cpp:321
void SetMax(float max)
Sets DOF's maximal state.
Definition: dof.cpp:252
Point4D position
Together with "axis", defines the rotation axis. Relative to the parent reference system...
Definition: dof.h:153
void ApplyTransformTo(Transform *ptrTrans) const
Apply internal transform to some external transform.
Definition: dof.cpp:341
Degree Of Freedom - basic component of a Joint.
Definition: dof.h:28
void XmlPrintOn(std::ostream &os, unsigned int indent) const
Outputs XML representation of the scene.
Definition: dof.cpp:426
void Set(const Point4D &vec, const Point4D &pos, float min, float max)
Initializes a DOF previouly created with default constructor.
Definition: dof.cpp:102
void ComputeLIM()
Definition: dof.cpp:296
Dof & operator=(const Dof &dof)
Definition: dof.cpp:82