V-ARTContributions
human.cpp
Go to the documentation of this file.
1 
5 #include "vart/contrib/human.h"
6 #include "vart/xmlscene.h"
7 #include "vart/xmljointaction.h"
8 #include "vart/collector.h"
9 #include "vart/action.h"
10 #include "vart/meshobject.h"
11 #include "vart/dot.h"
12 #include "vart/snlocator.h"
13 
14 #include <iostream>
15 #include <cassert>
16 
17 using namespace std;
18 
19 // Class StepManager ===============================================================================
20 
21 VART::Human::StepManager::StepManager(Human* human) : humanPtr(human), steppingRight(true)
22 {
23 }
24 
25 //virtual
27 // Change moving leg
28 {
29  if (steppingRight)
30  {
31  // The right foot was moving, make it stick to ground
32  humanPtr->StickRightFoot();
33  humanPtr->moveLeftLegPtr->Activate();
34  }
35  else
36  {
37  // The left foot was moving, make it stick to ground
38  humanPtr->StickLeftFoot();
39  humanPtr->moveRightLegPtr->Activate();
40  }
41  steppingRight = !steppingRight;
42 }
43 
44 // Class Human =====================================================================================
45 
47  moveLeftLegPtr(NULL), moveRightLegPtr(NULL), restPtr(NULL), breathePtr(NULL),
48  stepManager(this), forward(0,0,1,0), maxStepRotation(0.007), isWalking(false)
49 {
50  //~ position.MakeIdentity();
51  position.SetDescription("position");
52  //~ adjustment.MakeIdentity();
53  adjustment.SetDescription("adjustment");
54  //~ orientation.MakeXRotation(-1.570796327);
55  orientation.SetDescription("orientation");
56  adjustment.AddChild(position);
57  position.AddChild(orientation);
58  // Note that general human hierarchy is:
59  // adjustment -> position -> orientation -> hipJoint
60 }
61 
62 VART::Human::Human(VART::Human& human) : stepManager(this), forward(human.forward),
63  maxStepRotation(human.maxStepRotation),
64  isWalking(human.isWalking)
65 {
66  SceneNode* rootJointPtr;
67 
68  position.CopyMatrix(human.position);
69  orientation.CopyMatrix(human.orientation);
70  rootJointPtr = ( *human.childList.begin() )->RecursiveCopy();
71  AddChild(*rootJointPtr);
72  SetDescription(human.GetDescription());
73 }
74 
76 {
77 }
78 
79 float VART::Human::AngleToPosition(const Point4D& pos, float* totalAngle) const
80 // Compute Angle to a position (pos) in World coordinates
81 {
82  static const float delta = 3.5; // distances smaller than delta are to small to make sharp turns
83 
84  Point4D direction = pos - Position();
85  direction.SetY(0);
86  float stepAngle = maxStepRotation;
87  if (direction.Length() < delta) // if too close to destination, make only a small adjustment
88  stepAngle *= 0.01;
89  float angle = direction.GenericAngleTo(forward);
90  // Compute the Y coordinate of the cross product (we are working on world coordinates)
91  // between forward and direction. If it is negative, the angle is also negative.
92  if ((forward.GetZ()*direction.GetX() - forward.GetX()*direction.GetZ()) < 0)
93  { // Negative angle
94  if (totalAngle)
95  *totalAngle = -angle;
96  if (angle > stepAngle)
97  return -stepAngle;
98  else
99  return -angle;
100  }
101  else
102  { // Positive angle
103  if (totalAngle)
104  *totalAngle = angle;
105  if (angle > stepAngle)
106  return stepAngle;
107  else
108  return angle;
109  }
110 }
111 
112 void VART::Human::ChangeAdjustment(const Point4D& displacement)
113 {
114  Transform translation;
115  translation.MakeTranslation(displacement);
116  adjustment.CopyMatrix(translation * adjustment);
117 }
118 
119 VART::SceneNode* VART::Human::Copy()
120 {
121  assert(false && "VART::Human::Copy() not implemented!");
122  return NULL;
123 }
124 
126 {
127  assert(false && "VART::Human::ComputeBoundingBox() not implemented!");
128 }
129 
131 {
132  // Left foot is backwards. Adjustment brings it forward, so...
133  position.CopyMatrix(adjustment * position); // ...save current adjustment to human position
134  pathToStickPosPtr = &pathToRFoot;
135  stickPositionPtr = &rfFront; // now the right foot sticks to ground, but it is forward ...
136  // ... adjustment will bring it backwards, so we compute how ...
137  Point4D rightFootOffset; // ... much forward it is
138  ComputeLocalStickPosition(&rightFootOffset); // ... and add to position as well
139  Transform trans;
140  Point4D forward = position * orientation * (rightFootOffset - rfFront);
141  forward.SetY(-adjustment.GetData()[13]);
142  trans.MakeTranslation(forward);
143  position.CopyMatrix(trans * position);
144 }
145 
147 {
148  // Right foot is backwards. Adjustment brings it forward, so...
149  position.CopyMatrix(adjustment * position); // ...save current adjustment to human position
150  pathToStickPosPtr = &pathToLFoot;
151  stickPositionPtr = &lfFront; // now the left foot sticks to ground, but it is forward ...
152  // ... adjustment will bring it backwards, so we compute how ...
153  Point4D leftFootOffset; // ... much forward it is
154  ComputeLocalStickPosition(&leftFootOffset); // ... and add to position as well ...
155  Transform trans; // ... as vector, under influence of the human's orientation.
156  Point4D forward = position * orientation * (leftFootOffset - lfFront);
157  forward.SetY(-adjustment.GetData()[13]);
158  trans.MakeTranslation(forward);
159  position.CopyMatrix(trans * position);
160 }
161 
162 //virtual
163 void VART::Human::TraverseDepthFirst(SNOperator* operatorPtr)
164 {
165  position.TraverseDepthFirst(operatorPtr);
166  SceneNode::TraverseDepthFirst(operatorPtr);
167 }
168 
169 // virtual
170 void VART::Human::LocateDepthFirst(SNLocator* locatorPtr) const
171 {
172  // FixMe: Not sure what to do here.
173  orientation.LocateDepthFirst(locatorPtr);
174  if (locatorPtr->NotFinished())
175  SceneNode::LocateDepthFirst(locatorPtr);
176 }
177 
178 //virtual
180 {
181  glLoadName(pickName); // store human pickName for hierarchy information
182  glPushName(pickName); // push, saving previous name
183  adjustment.DrawForPicking();
184  glPopName();
185 }
186 
187 bool VART::Human::LoadFromFile(const string& fileName)
188 {
189  XmlScene scene;
190  bool result = scene.LoadFromFile(fileName);
191  if (result) // if no read errors
192  {
193  // Detach human's root joint from local scene and add it to self
194  hipJointPtr = dynamic_cast<Joint*>(scene.GetObjects().front());
195  orientation.AddChild(*hipJointPtr);
196  scene.Unreference(hipJointPtr);
197 
198  // Find smaller vertex on front right foot
199  MeshObject* rightFootFingersMeshPtr =
200  dynamic_cast<MeshObject*>(hipJointPtr->FindChildByName("R_footfingersMesh"));
201  assert(rightFootFingersMeshPtr != NULL);
202  hipJointPtr->FindPathTo(rightFootFingersMeshPtr, &pathToRFoot);
203  Point4D::xWeight = 0.1;
204  Point4D::yWeight = 3;
205  Point4D::zWeight = 2;
206  Point4D::operatorLess = &Point4D::WeightedLess;
207  rightFootFingersMeshPtr->SmallerVertex(&rfFront); // Compute right foot front
208  ResetPosition();
209 
210  // Find smaller vertex on front left foot
211  MeshObject* leftFootFingersMeshPtr =
212  dynamic_cast<MeshObject*>(hipJointPtr->FindChildByName("L_footfingersMesh"));
213  assert(leftFootFingersMeshPtr != NULL);
214  hipJointPtr->FindPathTo(leftFootFingersMeshPtr, &pathToLFoot);
215  Point4D::xWeight = -0.1;
216  Point4D::yWeight = 3;
217  Point4D::zWeight = 2;
218  leftFootFingersMeshPtr->SmallerVertex(&lfFront); // Compute left foot front
219  Point4D::operatorLess = &Point4D::LexicographicalLess;
220  Dot* leftFootFrontDotPtr = new Dot(lfFront); // debug only
221  leftFootFrontDotPtr->color = Color::RED();
222  leftFootFingersMeshPtr->AddChild(*leftFootFrontDotPtr);
223  stickPositionPtr = &lfFront;
224  pathToStickPosPtr = &pathToLFoot;
225 
226  // Load Rest Action
227  restPtr = LoadAction("rest.xml");
228  if (restPtr)
229  {
230  restPtr->SetPriority(1);
231  restPtr->Activate();
232  //~ restPtr->SetSpeed(3);
233  }
234  // Load Breeth Action
235  breathePtr = LoadAction("breathe.xml");
236  if (breathePtr)
237  {
238  breathePtr->SetPriority(2);
239  breathePtr->Activate();
240  }
241  }
242  return result;
243 }
244 
245 //virtual
247 {
248 #ifdef VART_OGL
249  return adjustment.DrawOGL();
250 #else
251  return false;
252 #endif
253 }
254 
256 {
257  if (breathePtr) // if breathePtr != NULL
258  {
259  if (status) // if status == true
260  breathePtr->Activate();
261  else
262  breathePtr->Deactivate();
263  }
264 }
265 
267 {
268  if (restPtr) // if restPtr != NULL
269  {
270  if (status) // if status == true
271  restPtr->Activate();
272  else
273  restPtr->Deactivate();
274  }
275 }
276 
277 void VART::Human::Move(const Point4D& offset)
278 {
279  Transform translation;
280  translation.MakeTranslation(offset);
281  position.CopyMatrix(translation * position);
282 }
283 
284 void VART::Human::RotateOnY(float radians)
285 {
286  // Modify the position transform
287  Transform rotation;
288  Point4D rotCenter;
289  ComputeStickPosition(&rotCenter);
290  rotation.MakeRotation(rotCenter, Point4D::Y(), radians);
291  position.CopyMatrix(rotation * position);
292  // Modify the forward vector
293  rotation.ApplyTo(&forward);
294 }
295 
297 {
298  static const float delta = 1.4;
299  Point4D location = adjustment * position * orientation * Point4D::ORIGIN();
300  Point4D distanceVector = destination - location;
301  //cout << "From " << location << " to " << destination << "\n";
302  distanceVector.SetY(0);
303  float distance = abs(distanceVector.Length());
304  //~ cout << "distance: " << distance << "\n";
305  return (distance < delta);
306 }
307 
309 {
310  orientation.MakeXRotation(-1.5707963267948966192313216916398);
311  Transform translation;
312  translation.MakeTranslation(0, -rfFront.GetZ(), 0); // Floor is on World Y=0
313  orientation.CopyMatrix(translation * orientation);
314  position.MakeIdentity();
315  adjustment.MakeIdentity();
316 }
317 
318 VART::Point4D VART::Human::Position() const
319 {
320  return adjustment * position * orientation * Point4D::ORIGIN();
321 }
322 
323 void VART::Human::PutIntoScene(Scene* scenePtr)
324 {
325  scenePtr->AddObject(this);
326 }
327 
328 VART::XmlJointAction* VART::Human::LoadAction(const std::string& fileName)
329 {
330  assert(hipJointPtr != NULL);
331  XmlJointAction* actionPtr = new XmlJointAction;
332  if (actionPtr->LoadFromFile(fileName, *hipJointPtr))
333  {
334  cerr << "Human::LoadAction (" << fileName << ") OK" << endl;
335  actionList.push_back(actionPtr);
336  if (fileName == "right_front.xml")
337  {
338  moveRightLegPtr = actionPtr;
339  actionPtr->SetPriority(50);
340  }
341  if (fileName == "left_front.xml")
342  {
343  moveLeftLegPtr = actionPtr;
344  actionPtr->SetPriority(50);
345  }
346  return actionPtr;
347  }
348  else
349  {
350  cerr << "Human::LoadAction (" << fileName << ") FAILED!" << endl;
351  delete actionPtr;
352  return NULL;
353  }
354 }
355 
357 // Returns the stick position, on Local Coordinates, ignoring human position.
358 {
359  Transform transform;
360  pathToStickPosPtr->GetTransform(&transform);
361  *resultPtr = transform * (*stickPositionPtr);
362 }
363 
364 void VART::Human::ComputeStickPosition(Point4D* resultPtr)
365 // Return the real stick position, on World Coordinates.
366 {
367  ComputeLocalStickPosition(resultPtr);
368  *resultPtr = adjustment * position * orientation * *resultPtr;
369 }
370 
372 {
373  Point4D stickPosition;
374  ComputeLocalStickPosition(&stickPosition);
375  // Compute the vector from stickPosition to *stickPositionPtr, i.e.: the displacement
376  // vetor of the stick position due to current articulations state. Then put the vector
377  // in World Coordinates.
378  adjustment.MakeTranslation(position * orientation * (*stickPositionPtr - stickPosition));
379 }
380 
381 void VART::Human::ComputeTransform(Transform* transPtr)
382 {
383  transPtr->CopyMatrix(adjustment * position * orientation);
384 }
385 
386 void VART::Human::Walk(bool status)
387 {
388  if (status)
389  { // start walking
390  StickLeftFoot();
391  cout << "Start walking" << endl;
392  moveLeftLegPtr->callbackPtr = &stepManager;
393  moveRightLegPtr->callbackPtr = &stepManager;
394  moveRightLegPtr->Activate();
395  cout << "stick position: " << *stickPositionPtr << endl;
396  restPtr->Deactivate();
397  isWalking = true;
398  }
399  else
400  { // stop walking
401  if (moveLeftLegPtr->IsActive())
402  StickLeftFoot();
403  else
404  StickRightFoot();
405  cout << "Stop walking" << endl;
406  moveLeftLegPtr->callbackPtr = NULL;
407  moveLeftLegPtr->Deactivate();
408  moveRightLegPtr->callbackPtr = NULL;
409  moveRightLegPtr->Deactivate();
410  restPtr->Activate();
411  isWalking = false;
412  }
413 }
414 
415 bool VART::Human::WalkTo(const Point4D& dest, const Point4D& orientation)
416 // FixMe: orientation is currently being ignored
417 {
418  destination = dest;
419  float angle = AngleToPosition(dest, NULL);
420  RotateOnY(angle);
421  return true; // FixMe, check if sucessfull
422 }
423 
424 void VART::Human::ModifyActions(DMModifier& modifier)
425 {
426  list<JointAction*>::iterator iter = actionList.begin();
427  for(; iter != actionList.end(); ++iter)
428  {
429  (*iter)->ModifyDofMovers(modifier);
430  }
431 }
virtual void LocateDepthFirst(SNLocator *locatorPtr) const
Definition: human.cpp:170
void AdjustPosition()
Definition: human.cpp:371
void Walk(bool status)
Definition: human.cpp:386
void ModifyActions(DMModifier &modifier)
Modifies registered actions.
Definition: human.cpp:424
XmlJointAction * LoadAction(const std::string &fileName)
Loads action from given file name.
Definition: human.cpp:328
virtual void DrawForPicking() const
Definition: human.cpp:179
virtual void Activate()
Definition: human.cpp:26
SGPath * pathToStickPosPtr
Definition: human.h:147
Transform adjustment
A transform that makes a point on human's geometry to stick at the ground.
Definition: human.h:140
Transform position
A transform that puts the human at his position and orientation.
Definition: human.h:138
void RotateOnY(float radians)
Definition: human.cpp:284
Joint * hipJointPtr
Definition: human.h:144
virtual bool DrawInstanceOGL() const
Definition: human.cpp:246
void StickRightFoot()
Definition: human.cpp:130
JointAction * moveRightLegPtr
Definition: human.h:149
JointAction * restPtr
Definition: human.h:150
void ActivateBreatheAction(bool status)
Definition: human.cpp:255
Transform orientation
A transform that puts the human vertical on Y, scales him to the right size and puts his feet at Y = ...
Definition: human.h:143
float AngleToPosition(const Point4D &pos, float *totalAngle) const
Builds its internal map of dof movers.
Definition: human.cpp:79
Articulated object for humanoid representation.
Definition: human.h:28
void ChangeAdjustment(const Point4D &displacement)
Definition: human.cpp:112
void StickLeftFoot()
Definition: human.cpp:146
StepManager stepManager
Definition: human.h:152
void ComputeStickPosition(Point4D *resultPtr)
Definition: human.cpp:364
virtual void ComputeBoundingBox()
Definition: human.cpp:125
Header file for V-ART class "Human" (contrib).
void ComputeTransform(Transform *transPtr)
Definition: human.cpp:381
Point4D Position() const
Definition: human.cpp:318
void Move(const Point4D &offset)
Definition: human.cpp:277
JointAction * breathePtr
Definition: human.h:151
bool isWalking
currently walking?
Definition: human.h:159
void ActivateRestAction(bool status)
Definition: human.cpp:266
bool LoadFromFile(const std::string &fileName)
Loads from a XML file.
Definition: human.cpp:187
virtual SceneNode * Copy()
Definition: human.cpp:119
Point4D forward
A vector that points forward on the floor plane (world coordinates)
Definition: human.h:154
void ComputeLocalStickPosition(Point4D *resultPtr)
Computes and returns the position of the right foot front.
Definition: human.cpp:356
Point4D * stickPositionPtr
Definition: human.h:136
bool WalkTo(const Point4D &dest, const Point4D &orientation)
Definition: human.cpp:415
bool ReachedDestiantion() const
Returns true if the human has reached its destination.
Definition: human.cpp:296
void ResetPosition()
Definition: human.cpp:308
JointAction * moveLeftLegPtr
Definition: human.h:148
Human()
Creates an uninitialized humanoid.
Definition: human.cpp:46
void PutIntoScene(Scene *scenePtr)
Adds the humanoid to a scene.
Definition: human.cpp:323
virtual void TraverseDepthFirst(SNOperator *operatorPtr)
Definition: human.cpp:163
StepManager(Human *human)
Definition: human.cpp:21
float maxStepRotation
Maximal rotation (radians) during a single step.
Definition: human.h:156