V-ART
xmlaction.cpp
Go to the documentation of this file.
1 
5 #include "vart/xmlaction.h"
6 #include "vart/scene.h"
7 #include "vart/joint.h"
11 #include "vart/jointmover.h"
12 #include "vart/noisydofmover.h"
13 
14 #include <xercesc/util/OutOfMemoryException.hpp>
15 #include <xercesc/dom/DOMImplementation.hpp>
16 #include <xercesc/dom/DOMElement.hpp>
17 #include <xercesc/dom/DOMNodeList.hpp>
18 #include <xercesc/dom/DOMNamedNodeMap.hpp>
19 #include <xercesc/sax/SAXParseException.hpp>
20 
21 #include <sstream>
22 
23 using namespace std;
24 using namespace XERCES_CPP_NAMESPACE;
25 
27 {
28 }
29 
30 bool VART::XmlAction::LoadFromFile(const string& fileName, const VART::Scene& scene)
31 {
32  Source jointSource(scene);
33 
34  //~ cout << "xmlaction loading from " << fileName << endl;
35  if(ParseFile(fileName))
36  { //XML parser sucessfull
37  LoadAnimation(jointSource);
38  Terminate();
39  return true;
40  }
41  else
42  { //the parser has failled!
43  Terminate();
44  return false;
45  }
46 }
47 
48 bool VART::XmlAction::LoadFromFile(const string& fileName, const VART::SceneNode& sNode)
49 {
50  Source jointSource(sNode);
51 
52  //~ cout << "xmlaction loading from " << fileName << endl;
53  if(ParseFile(fileName))
54  { //XML parser sucessfull
55  LoadAnimation(jointSource);
56  Terminate();
57  return true;
58  }
59  else
60  { //the parser has failled!
61  Terminate();
62  return false;
63  }
64 }
65 
66 void VART::XmlAction::LoadAnimation(const Source& jointSource)
67 // Called by LoadFromFile after parsing to actually build the action from file.
68 {
69  static VART::LinearInterpolator linearInterpolator; // common interpolator for all joint movers
70  static VART::SineInterpolator sineInterpolator; // common interpolator for all joint movers
71  istringstream stream; // helper for converting strings to numbers
72  char* charAux; // helper for converting XMLStrings to C strings
73  unsigned int i, j, k; // loop counters (aaargh!)
74  float dur, speed; // duration and speed of the action
75  bool cycle; // cyclic status of the action
76  string dofIdentifier, jName, itplName;
77  XMLCh* xmlStr; // helper for converting C strings to XMLStrings
78  DOMNodeList* actionList;
79  DOMNamedNodeMap* attrAc; // attributes for the action
80  VART::JointMover* jointMPtr;
81 
82  // Get list of actions (but there should be only one!)
83  xmlStr = XMLString::transcode("action");
84  actionList = documentPtr->getElementsByTagName(xmlStr);
85  XMLString::release(&xmlStr);
86 
87  attrAc = documentPtr->getDocumentElement()->getAttributes();
88 
89  // Read speed value
90  xmlStr = XMLString::transcode("speed");
91  charAux = XMLString::transcode(attrAc->getNamedItem(xmlStr)->getNodeValue());
92  stream.clear();
93  stream.str(charAux);
94  stream >> speed;
95  XMLString::release(&xmlStr);
96  XMLString::release(&charAux);
97 
98  // Read cyclic value
99  xmlStr = XMLString::transcode("cycle");
100  charAux = XMLString::transcode(attrAc->getNamedItem(xmlStr)->getNodeValue());
101  cycle = (strcmp(charAux, "true") == 0);
102  XMLString::release(&xmlStr);
103  XMLString::release(&charAux);
104 
105  // Set action attributes
106  Set(speed, 1, cycle); //Priority default is 1.
107 
108  // For each action (but there should be only one!):
109  for (i = 0; i<actionList->getLength(); i++)
110  {
111  DOMNodeList* jointsL = actionList->item(i)->getChildNodes();
112 
113  // For each joint movement:
114  for (j = 0; j<jointsL->getLength(); j++)
115  {
116  bool isJointMovement;
117 
118  charAux = XMLString::transcode(jointsL->item(j)->getNodeName());
119  isJointMovement = (strcmp(charAux, "joint_movement") == 0);
120  XMLString::release(&charAux);
121 
122  if (isJointMovement)
123  {
124  Joint* jointPtr;
125  DOMNamedNodeMap* attrLt = jointsL->item(j)->getAttributes();
126 
127  // Read joint mover's duration value
128  xmlStr = XMLString::transcode("duration");
129  charAux = XMLString::transcode(attrLt->getNamedItem(xmlStr)->getNodeValue());
130  stream.clear();
131  stream.str(charAux);
132  stream >> dur;
133  XMLString::release(&xmlStr);
134  XMLString::release(&charAux);
135 
136  // Read joint mover's target joint name
137  xmlStr = XMLString::transcode("joint_name");
138  charAux = XMLString::transcode(attrLt->getNamedItem(xmlStr)->getNodeValue());
139  jName = charAux;
140  XMLString::release(&xmlStr);
141  XMLString::release(&charAux);
142 
143  jointPtr = jointSource.GetJointByName(jName);
144  if (jointPtr)
145  {
146  DOMNodeList* dofsL = jointsL->item(j)->getChildNodes();
147 
148  // It is now almost safe to create a joint mover :)
149  // Add an ease-in, ease-out interpolator as default. Change it when the
150  // interpolator gets known.
151  jointMPtr = AddJointMover(jointPtr, dur, sineInterpolator);
152 
153 
154  // For each element of a joint movement (may be interpolator or dof movement):
155  for(k = 0; k<dofsL->getLength(); k++)
156  {
157  bool isInterpolation;
158 
159  charAux = XMLString::transcode(dofsL->item(k)->getNodeName());
160  isInterpolation = (strcmp(charAux, "interpolation") == 0);
161  XMLString::release(&charAux);
162  if (isInterpolation)
163  {
164  DOMNamedNodeMap* attrInterpLt = dofsL->item(k)->getAttributes();
165 
166  // Read interpolation type
167  xmlStr = XMLString::transcode("type");
168  charAux = XMLString::transcode(attrInterpLt->getNamedItem(xmlStr)->getNodeValue());
169  itplName = charAux;
170  XMLString::release(&xmlStr);
171  XMLString::release(&charAux);
172 
173  // Change interpolator if it is different from default (ease-in/ease-out) value
174  if (itplName != "ease-in_ease-out")
175  {
176  if (itplName == "linear")
177  jointMPtr->SetInterpolator(linearInterpolator);
178  else if (itplName == "range_sine")
179  {
180  Interpolator* interpolatorPtr = new RangeSineInterpolator;
181  jointMPtr->SetInterpolator(*interpolatorPtr);
182  }
183  else
184  cerr << "Error: Unknown interpolator: '" << itplName
185  << "'. Using: 'ease-in_ease-out'." << endl;
186  }
187  }
188  else // item is not "interpolation"
189  {
190  charAux = XMLString::transcode(dofsL->item(k)->getNodeName());
191  if(strcmp(charAux, "dof_movement") == 0)
192  ParseDofMovement(jointMPtr, dofsL->item(k));
193  XMLString::release(&charAux);
194  }
195  }
196  }
197  else // the target joint was not found
198  {
199  cerr << "Error: Joint mover targeting at '" << jName
200  << "': No such scene node!" << endl;
201  }
202  }
203  }
204  }
205 }
206 
207 void VART::XmlAction::ParseDofMovement(JointMover* jointMPtr, DOMNode* dofMovItemPtr)
208 // Called by LoadAnimation to create a dof mover from a XML entry.
209 // FixMe: Memory allocated for the interpolators is never released.
210 {
211  DOMNodeList* dofMovElements;
212  DOMNamedNodeMap* attrPt;
213  XMLCh* xmlStr; // helper for converting C strings to XMLStrings
214  float inTime;
215  float fTime;
216  float fPos;
217  float noiseAmplitude;
218  float noiseWaveLenght;
219  float overshoot;
220  float offset;
221  float peakTime;
222  char* charAux;
223  char* cstr_nodeName; // a node name (as a C string)
224  istringstream stream;
225  VART::Joint::DofID dofID;
226  unsigned int count;
227  bool foundPositionalError = false; // any positional error elements found inside the dof mover?
228  bool foundNoise = false; // any noise elements found inside the dof mover?
229 
230  attrPt = dofMovItemPtr->getAttributes();
231 
232  xmlStr = XMLString::transcode("initialTime");
233  charAux = XMLString::transcode(attrPt->getNamedItem(xmlStr)->getNodeValue());
234  stream.str(charAux);
235  stream >> inTime;
236  XMLString::release(&xmlStr);
237  XMLString::release(&charAux);
238 
239  xmlStr = XMLString::transcode("finalTime");
240  charAux = XMLString::transcode(attrPt->getNamedItem(xmlStr)->getNodeValue());
241  stream.clear();
242  stream.str(charAux);
243  stream >> fTime;
244  XMLString::release(&xmlStr);
245  XMLString::release(&charAux);
246 
247  xmlStr = XMLString::transcode("finalPosition");
248  charAux = XMLString::transcode(attrPt->getNamedItem(xmlStr)->getNodeValue());
249  stream.clear();
250  stream.str(charAux);
251  stream >> fPos;
252  XMLString::release(&xmlStr);
253  XMLString::release(&charAux);
254 
255  // Read value for dofID
256  xmlStr = XMLString::transcode("dofID");
257  charAux = XMLString::transcode(attrPt->getNamedItem(xmlStr)->getNodeValue());
258  if ((strcmp(charAux, "FLEX") == 0) || (strcmp(charAux, "FLEXION") == 0))
259  dofID = VART::Joint::FLEXION;
260  else
261  {
262  if ((strcmp(charAux, "ADDUCT") == 0) || (strcmp(charAux, "ADDUCTION") == 0))
263  dofID = VART::Joint::ADDUCTION;
264  else
265  if (strcmp(charAux, "TWIST") == 0)
266  dofID = VART::Joint::TWIST;
267  else
268  {
269  cerr << "XmlAction::ParseDofMovement: Unknown DOF ID" << endl;
270  exit (1);
271  }
272  }
273  XMLString::release(&xmlStr);
274  XMLString::release(&charAux);
275 
276  dofMovElements = dofMovItemPtr->getChildNodes();
277 
278  // for each child node of the dof mover (may be "noise" or "error"):
279  for (count = 0; count < dofMovElements->getLength(); ++count)
280  {
281  cstr_nodeName = XMLString::transcode(dofMovElements->item(count)->getNodeName());
282  if (strcmp(cstr_nodeName, "noise") == 0)
283  {
284  attrPt = dofMovElements->item(count)->getAttributes();
285 
286  xmlStr = XMLString::transcode("amplitude");
287  charAux = XMLString::transcode(attrPt->getNamedItem(xmlStr)->getNodeValue());
288  stream.clear();
289  stream.str(charAux);
290  stream >> noiseAmplitude;
291  XMLString::release(&xmlStr);
292  XMLString::release(&charAux);
293 
294  xmlStr = XMLString::transcode("length");
295  charAux = XMLString::transcode(attrPt->getNamedItem(xmlStr)->getNodeValue());
296  stream.clear();
297  stream.str(charAux);
298  stream >> noiseWaveLenght;
299  XMLString::release(&xmlStr);
300  XMLString::release(&charAux);
301 
302  foundNoise = true;
303  }
304  else if (strcmp(cstr_nodeName, "error") == 0)
305  {
306  attrPt = dofMovElements->item(count)->getAttributes();
307 
308  xmlStr = XMLString::transcode("overshoot");
309  charAux = XMLString::transcode(attrPt->getNamedItem(xmlStr)->getNodeValue());
310  stream.clear();
311  stream.str(charAux);
312  stream >> overshoot;
313  XMLString::release(&xmlStr);
314  XMLString::release(&charAux);
315  NoisyDofMover::SetDefaultOvershoot(overshoot);
316 
317  xmlStr = XMLString::transcode("offset");
318  charAux = XMLString::transcode(attrPt->getNamedItem(xmlStr)->getNodeValue());
319  stream.clear();
320  stream.str(charAux);
321  stream >> offset;
322  XMLString::release(&xmlStr);
323  XMLString::release(&charAux);
324  NoisyDofMover::SetDefaultOffset(offset);
325 
326  xmlStr = XMLString::transcode("peak_time");
327  charAux = XMLString::transcode(attrPt->getNamedItem(xmlStr)->getNodeValue());
328  stream.clear();
329  stream.str(charAux);
330  stream >> peakTime;
331  XMLString::release(&xmlStr);
332  XMLString::release(&charAux);
333  NoisyDofMover::SetDefaultPeakTime(peakTime);
334 
335  foundPositionalError = true;
336  }
337  delete[] cstr_nodeName;
338  }
339 
340  // Ready to create a dof mover
341  if (foundPositionalError || foundNoise)
342  {
343  VART::NoisyDofMover* noisyDofMoverPtr;
344 
345  noisyDofMoverPtr = jointMPtr->AddNoisyDofMover(dofID, inTime, fTime, fPos);
346  if (foundNoise)
347  noisyDofMoverPtr->SetNoise(noiseAmplitude, noiseWaveLenght);
348  //~ if (foundPositionalError)
349  //~ {
350  //~ noisyDofMoverPtr->SetOvershoot(overshoot, peakTime);
351  //~ noisyDofMoverPtr->SetOffset(offset);
352  //~ }
353  }
354  else
355  jointMPtr->AddDofMover(dofID, inTime, fTime, fPos);
356 }
357 
359 {
360 }
361 
362 ostream& VART::operator<<(ostream& output, const VART::XmlAction& action)
363 {
364  list<JointMover*>::const_iterator iter = action.jointMoverList.begin();
365 
366  output << "<?xml version=\"1.0\"?>\n"
367  << "<!DOCTYPE action SYSTEM \"vartAnimation.dtd\">\n"
368  << "<action action_name=\"" << action.description << "\" speed=\"" << action.speed
369  << "\" cycle=\"" << boolalpha << action.cycle << "\">\n";
370  // for each joint mover
371  while (iter != action.jointMoverList.end())
372  {
373  output << (**iter);
374  ++iter;
375  }
376  output << "</action>\n";
377  return output;
378 }
379 
380 // Source Code for XmlAction::Source
381 
382 //~ VART::XmlAction::Source::Source()
383 //~ {
384  //~ scenePtr = NULL;
385  //~ sceneNodePtr = NULL;
386 //~ }
387 
389 {
390  scenePtr = &scene;
391  sceneNodePtr = NULL;
392 }
393 
395 {
396  scenePtr = NULL;
397  sceneNodePtr = &sNode;
398 }
399 
401 {
402  if (scenePtr)
403  {
404  return dynamic_cast<Joint*>(scenePtr->GetObjectRec(name));
405  }
406  else
407  {
408  return dynamic_cast<Joint*>(sceneNodePtr->FindChildByName(name));
409  }
410 }
Base class for objects that compose a scene graph.
Definition: scenenode.h:25
Representation of joints.
Definition: joint.h:34
Linear interpolation.
Source(const Scene &scene)
Definition: xmlaction.cpp:388
Smooth (sine function) interpolator.
bool cycle
Definition: action.h:124
std::ostream & operator<<(std::ostream &output, const Joint::DofID &dofId)
Header file for V-ART class "Scene".
std::string description
Textual description.
Definition: action.h:111
Header file for V-ART class "SineInterpolator".
Joint * GetJointByName(const std::string &name) const
Definition: xmlaction.cpp:400
Header file for V-ART class "JointMover".
float speed
Definition: action.h:128
void SetNoise(float newNoiseAmplitude, float newNoiseWaveLenght)
Sets the noise attributes.
Smooth (sine function) interpolator with range.
A set of objects, lights and cameras.
Definition: scene.h:35
Header file for V-ART class "Joint".
void LoadAnimation(const Source &jointSource)
Definition: xmlaction.cpp:66
Interpolator representation.
Definition: interpolator.h:17
Controllers for joint movement.
Definition: jointmover.h:22
Noisy Controller for DOF movement.
Definition: noisydofmover.h:17
std::list< JointMover * > jointMoverList
Definition: action.h:132
Parser and loader for xml files that describe an Action.
Definition: xmlaction.h:21
Header file for V-ART class "XmlAction".
Header file for V-ART class "NoisyDofMover".
Header file for V-ART class "LinearInterpolator".
Header file for V-ART class "SineInterpolator".
void SetInterpolator(const Interpolator &interp)
Changes the associated interpolator.
Definition: jointmover.h:64
void AddDofMover(Joint::DofID dof, float iniTime, float finTime, float finPos)
Creates a DofMover.
Definition: jointmover.cpp:59
bool LoadFromFile(const std::string &fileName, const Scene &scene)
Loads action from a XML file.
NoisyDofMover * AddNoisyDofMover(Joint::DofID dof, float iniTime, float finTime, float finPos)
Creates a noisy DofMover.
Definition: jointmover.cpp:72
void ParseDofMovement(JointMover *jointMPtr, XERCES_CPP_NAMESPACE::DOMNode *dofMovItemPtr)
Definition: xmlaction.cpp:207