Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/coord/p_node.cc @ 5211

Last change on this file since 5211 was 5211, checked in by bensch, 19 years ago

orxonox/trunk: valgrind mem-leak-recovered

File size: 21.2 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Patrick Boenzli
13   co-programmer:
14
15   @todo Smooth-Parent: delay, speed
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PNODE
19
20#include "p_node.h"
21#include "null_parent.h"
22
23#include "load_param.h"
24#include "class_list.h"
25
26#include "stdincl.h"
27#include "compiler.h"
28#include "error.h"
29#include "debug.h"
30#include "list.h"
31#include "vector.h"
32
33//#include "vector.h"
34//#include "quaternion.h"
35
36using namespace std;
37
38
39/**
40 *  standard constructor
41*/
42PNode::PNode ()
43{
44  init(NULL);
45
46  NullParent::getInstance()->addChild(this);
47}
48
49/**
50 * @param root the load-Element for the PNode
51*/
52PNode::PNode(const TiXmlElement* root)
53{
54  this->init(NULL);
55  this->loadParams(root);
56
57  NullParent::getInstance()->addChild(this);
58}
59
60/**
61 *  constructor with coodinates
62 * @param absCoordinate the Absolute coordinate of the Object
63 * @param parent The parent-node of this node.
64*/
65PNode::PNode (const Vector& absCoor, PNode* parent )
66{
67  this->init(parent);
68
69  if (likely(parent != NULL))
70    parent->addChild (this);
71
72  this->setAbsCoor(absCoor);
73}
74
75/**
76 *  standard deconstructor
77*/
78PNode::~PNode ()
79{
80  tIterator<PNode>* iterator = this->children->getIterator();
81  PNode* pn = iterator->firstElement();
82  while( pn != NULL)
83    {
84      delete pn;
85      pn = iterator->nextElement();
86    }
87  delete iterator;
88  /* this deletes all children in the list */
89  delete this->children;
90  if (this->parent)
91    this->parent->removeChild(this);
92
93  if (this->toCoordinate != NULL)
94    delete this->toCoordinate;
95  if (this->toDirection != NULL)
96    delete this->toDirection;
97}
98
99/**
100 *  initializes a PNode
101 * @param parent the parent for this PNode
102*/
103void PNode::init(PNode* parent)
104{
105  this->setClassID(CL_PARENT_NODE, "PNode");
106
107  this->children = new tList<PNode>();
108  this->bRelCoorChanged = true;
109  this->bRelDirChanged = true;
110  this->parent = parent;
111  this->parentMode = PNODE_PARENT_MODE_DEFAULT;
112
113  // iterators
114  this->toCoordinate = NULL;
115  this->toDirection = NULL;
116  this->bias = 1.0;
117}
118
119/**
120 *  loads parameters of the PNode
121 * @param root the XML-element to load the properties of
122*/
123void PNode::loadParams(const TiXmlElement* root)
124{
125  static_cast<BaseObject*>(this)->loadParams(root);
126
127  LoadParam<PNode>(root, "rel-coor", this, &PNode::setRelCoor)
128      .describe("Sets The relative position of the Node to its parent.");
129
130  LoadParam<PNode>(root, "abs-coor", this, &PNode::setAbsCoor)
131      .describe("Sets The absolute Position of the Node.");
132
133  LoadParam<PNode>(root, "rel-dir", this, &PNode::setRelDir)
134      .describe("Sets The relative rotation of the Node to its parent.");
135
136  LoadParam<PNode>(root, "abs-dir", this, &PNode::setAbsDir)
137      .describe("Sets The absolute rotation of the Node.");
138
139  LoadParam<PNode>(root, "parent", this, &PNode::setParent)
140      .describe("the Name of the Parent of this PNode");
141
142  LoadParam<PNode>(root, "parent-mode", this, &PNode::setParentMode)
143      .describe("the mode to connect this node to its parent ()");
144
145  // cycling properties
146  if (root != NULL)
147  {
148    const TiXmlElement* element = root->FirstChildElement();
149    while (element != NULL)
150    {
151      LoadParam<PNode>(element, "parent", this, &PNode::addChild, true)
152          .describe("adds a new Child to the current Node.");
153
154      element = element->NextSiblingElement();
155    }
156  }
157}
158
159/**
160 *  set relative coordinates
161 * @param relCoord relative coordinates to its parent
162
163   it is very importand, that you use this function, if you want to update the
164   relCoordinates. If you don't use this, the PNode won't recognize, that something
165   has changed and won't update the children Nodes.
166*/
167void PNode::setRelCoor (const Vector& relCoord)
168{
169  if (this->toCoordinate!= NULL)
170  {
171    delete this->toCoordinate;
172    this->toCoordinate = NULL;
173  }
174
175  this->relCoordinate = relCoord;
176  this->bRelCoorChanged = true;
177}
178
179/**
180 *  set relative coordinates
181 * @param x x-relative coordinates to its parent
182 * @param y y-relative coordinates to its parent
183 * @param z z-relative coordinates to its parent
184 * @see  void PNode::setRelCoor (const Vector& relCoord)
185*/
186void PNode::setRelCoor (float x, float y, float z)
187{
188  this->setRelCoor(Vector(x, y, z));
189}
190
191/**
192 * sets a new relative position smoothely
193 * @param relCoordSoft the new Position to iterate to
194 * @param bias how fast to iterate to this position
195 */
196void PNode::setRelCoorSoft(const Vector& relCoordSoft, float bias)
197{
198  if (likely(this->toCoordinate == NULL))
199    this->toCoordinate = new Vector();
200
201  *this->toCoordinate = relCoordSoft;
202  this->bias = bias;
203}
204
205
206/**
207 *  set relative coordinates smoothely
208 * @param x x-relative coordinates to its parent
209 * @param y y-relative coordinates to its parent
210 * @param z z-relative coordinates to its parent
211 * @see  void PNode::setRelCoorSoft (const Vector&, float)
212 */
213void PNode::setRelCoorSoft (float x, float y, float z, float bias)
214{
215  this->setRelCoorSoft(Vector(x, y, z), bias);
216}
217
218/**
219 * @param absCoord set absolute coordinate
220 */
221void PNode::setAbsCoor (const Vector& absCoord)
222{
223  if (this->toCoordinate!= NULL)
224  {
225    delete this->toCoordinate;
226    this->toCoordinate = NULL;
227  }
228
229  if( likely(this->parentMode & PNODE_MOVEMENT))
230  {
231      /* if you have set the absolute coordinates this overrides all other changes */
232    if (likely(this->parent != NULL))
233      this->relCoordinate = absCoord - parent->getAbsCoor ();
234    else
235      this->relCoordinate = absCoord;
236  }
237  if( this->parentMode & PNODE_ROTATE_MOVEMENT)
238  {
239    if (likely(this->parent != NULL))
240      this->relCoordinate = absCoord - parent->getAbsCoor ();
241    else
242      this->relCoordinate = absCoord;
243  }
244
245  this->bRelCoorChanged = true;
246//  this->absCoordinate = absCoord;
247}
248
249/**
250 * @param x x-coordinate.
251 * @param y y-coordinate.
252 * @param z z-coordinate.
253 * @see void PNode::setAbsCoor (const Vector& absCoord)
254 */
255void PNode::setAbsCoor(float x, float y, float z)
256{
257  this->setAbsCoor(Vector(x, y, z));
258}
259
260/**
261 *  shift coordinate relative
262 * @param shift shift vector
263
264   this function shifts the current coordinates about the vector shift. this is
265   usefull because from some place else you can:
266   PNode* someNode = ...;
267   Vector objectMovement = calculateShift();
268   someNode->shiftCoor(objectMovement);
269
270   elsewhere you would have to:
271   PNode* someNode = ...;
272   Vector objectMovement = calculateShift();
273   Vector currentCoor = someNode->getRelCoor();
274   Vector newCoor = currentCoor + objectMovement;
275   someNode->setRelCoor(newCoor);
276
277   yea right... shorter...
278 *
279*/
280void PNode::shiftCoor (const Vector& shift)
281{
282  this->relCoordinate += shift;
283  this->bRelCoorChanged = true;
284}
285
286/**
287 *  set relative direction
288 * @param relDir to its parent
289 */
290void PNode::setRelDir (const Quaternion& relDir)
291{
292  if (this->toDirection!= NULL)
293  {
294    delete this->toDirection;
295    this->toDirection = NULL;
296  }
297  this->relDirection = relDir;
298  this->bRelCoorChanged = true;
299}
300
301/**
302 * @see void PNode::setRelDir (const Quaternion& relDir)
303 * @param x the x direction
304 * @param y the y direction
305 * @param z the z direction
306 *
307 * main difference is, that here you give a directional vector, that will be translated into a Quaternion
308 */
309void PNode::setRelDir (float x, float y, float z)
310{
311  this->setRelDir(Quaternion(Vector(x,y,z), Vector(0,1,0)));
312}
313
314
315/**
316 * sets the Relative Direction of this node to its parent in a Smoothed way
317 * @param relDirSoft the direction to iterate to smoothely.
318 * @param bias how fast to iterate to the new Direction
319 */
320void PNode::setRelDirSoft(const Quaternion& relDirSoft, float bias)
321{
322  if (likely(this->toDirection == NULL))
323    this->toDirection = new Quaternion();
324
325  *this->toDirection = relDirSoft;
326  this->bias = bias;
327}
328
329/**
330 * @see void PNode::setRelDirSoft (const Quaternion& relDir)
331 * @param x the x direction
332 * @param y the y direction
333 * @param z the z direction
334 *
335 * main difference is, that here you give a directional vector, that will be translated into a Quaternion
336 */
337void PNode::setRelDirSoft(float x, float y, float z, float bias)
338{
339  this->setRelDirSoft(Quaternion(Vector(x,y,z), Vector(0,1,0)), bias);
340}
341
342/**
343 *  sets the absolute direction
344 * @param absDir absolute coordinates
345 */
346void PNode::setAbsDir (const Quaternion& absDir)
347{
348  if (this->toDirection!= NULL)
349  {
350    delete this->toDirection;
351    this->toDirection = NULL;
352  }
353
354  if (likely(this->parent != NULL))
355    this->relDirection = absDir / this->parent->getAbsDir();
356  else
357   this->relDirection = absDir;
358
359  this->bRelDirChanged = true;
360}
361
362/**
363 * @see void PNode::setAbsDir (const Quaternion& relDir)
364 * @param x the x direction
365 * @param y the y direction
366 * @param z the z direction
367 *
368 * main difference is, that here you give a directional vector, that will be translated into a Quaternion
369 */
370void PNode::setAbsDir (float x, float y, float z)
371{
372  this->setAbsDir(Quaternion(Vector(x,y,z), Vector(0,1,0)));
373}
374
375/**
376 * shift Direction
377 * @param shift the direction around which to shift.
378 */
379void PNode::shiftDir (const Quaternion& shift)
380{
381  this->relDirection = this->relDirection * shift;
382  this->bRelDirChanged = true;
383}
384
385/**
386 *  adds a child and makes this node to a parent
387 * @param child child reference
388 * @param parentMode on which changes the child should also change ist state
389 *
390 * use this to add a child to this node.
391*/
392void PNode::addChild (PNode* child, int parentMode)
393{
394  if( likely(child->parent != NULL))
395    {
396      PRINTF(4)("PNode::addChild() - reparenting node: removing it and adding it again\n");
397      child->parent->children->remove(child);
398    }
399  child->parentMode = parentMode;
400  child->parent = this;
401  this->children->add(child);
402  child->parentCoorChanged();
403}
404
405/**
406 * @see PNode::addChild(PNode* child);
407 * @param childName the name of the child to add to this PNode
408 */
409void PNode::addChild (const char* childName)
410{
411  PNode* childNode = dynamic_cast<PNode*>(ClassList::getObject(childName, CL_PARENT_NODE));
412  if (childNode != NULL)
413    this->addChild(childNode);
414}
415
416/**
417 *  removes a child from the node
418 * @param child the child to remove from this pNode.
419 *
420 * Children from pNode will not be lost, they are referenced to NullPointer
421*/
422void PNode::removeChild (PNode* child)
423{
424  child->remove();
425  this->children->remove(child);
426  child->parent = NULL;
427}
428
429/**
430 *  remove this pnode from the tree and adds all following to NullParent
431
432   this can be the case, if an entity in the world is being destroyed.
433*/
434void PNode::remove()
435{
436  NullParent* nullParent = NullParent::getInstance();
437
438  tIterator<PNode>* iterator = this->children->getIterator();
439  PNode* pn = iterator->firstElement();
440
441  while( pn != NULL)
442    {
443      nullParent->addChild(pn, pn->getParentMode());
444      pn = iterator->nextElement();
445    }
446  delete iterator;
447  this->parent->children->remove(this);
448}
449
450/**
451 * sets the parent of this PNode
452 * @param parent the Parent to set
453*/
454void PNode::setParent (PNode* parent)
455{
456  parent->addChild(this);
457}
458
459/**
460 * @see PNode::setParent(PNode* parent);
461 * @param parentName the name of the Parent to set to this PNode
462 */
463void PNode::setParent (const char* parentName)
464{
465  PNode* parentNode = dynamic_cast<PNode*>(ClassList::getObject(parentName, CL_PARENT_NODE));
466  if (parentNode != NULL)
467    parentNode->addChild(this);
468}
469
470/**
471 * does the reparenting in a very smooth way
472 * @param parentNode the new Node to connect this node to.
473 * @param bias the speed to iterate to this new Positions
474 */
475void PNode::softReparent(PNode* parentNode, float bias)
476{
477  if (this->parent == parentNode)
478    return;
479
480  if (likely(this->toCoordinate == NULL))
481  {
482    this->toCoordinate = new Vector();
483    *this->toCoordinate = this->getRelCoor();
484  }
485  if (likely(this->toDirection == NULL))
486  {
487    this->toDirection = new Quaternion();
488    *this->toDirection = this->getRelDir();
489  }
490  this->bias = bias;
491
492
493  Vector tmpV = this->getAbsCoor();
494  Quaternion tmpQ = this->getAbsDir();
495
496  parentNode->addChild(this);
497
498 if (this->parentMode & PNODE_ROTATE_MOVEMENT)
499   this->setRelCoor(this->parent->getAbsDir().inverse().apply(tmpV - this->parent->getAbsCoor()));
500 else
501   this->setRelCoor(tmpV - parentNode->getAbsCoor());
502
503  this->setRelDir(tmpQ / parentNode->getAbsDir());
504}
505
506/**
507 * does the reparenting in a very smooth way
508 * @param parentName the name of the Parent to reconnect to
509 * @param bias the speed to iterate to this new Positions
510 */
511void PNode::softReparent(const char* parentName, float bias)
512{
513  PNode* parentNode = dynamic_cast<PNode*>(ClassList::getObject(parentName, CL_PARENT_NODE));
514  if (parentNode != NULL)
515    this->softReparent(parentNode, bias);
516}
517
518/**
519 *  sets the mode of this parent manually
520 * @param parentMode a String representing this parentingMode
521 */
522void PNode::setParentMode (const char* parentingMode)
523{
524  this->setParentMode(PNode::charToParentingMode(parentingMode));
525}
526
527/**
528 *  updates the absCoordinate/absDirection
529 * @param dt The time passed since the last update
530
531   this is used to go through the parent-tree to update all the absolute coordinates
532   and directions. this update should be done by the engine, so you don't have to
533   worry, normaly...
534*/
535void PNode::update (float dt)
536{
537  if( likely(this->parent != NULL))
538    {
539      // movement for nodes with smoothMove enabled
540      if (unlikely(this->toCoordinate != NULL))
541      {
542        Vector moveVect = (*this->toCoordinate - this->getRelCoor()) *dt*bias;
543
544        if (likely(moveVect.len() >= PNODE_ITERATION_DELTA))
545        {
546          this->shiftCoor(moveVect);
547        }
548        else
549        {
550          delete this->toCoordinate;
551          this->toCoordinate = NULL;
552          PRINTF(5)("SmoothMove of %s finished\n", this->getName());
553        }
554      }
555      if (unlikely(this->toDirection != NULL))
556      {
557        Quaternion rotQuat = Quaternion::quatSlerp(Quaternion(), (*this->toDirection / this->relDirection), dt*this->bias);
558        if (likely(rotQuat.getSpacialAxisAngle() > PNODE_ITERATION_DELTA))
559        {
560          this->shiftDir(rotQuat);
561        }
562        else
563        {
564          delete this->toDirection;
565          this->toDirection = NULL;
566          PRINTF(5)("SmoothRotate of %s finished\n", this->getName());
567        }
568      }
569
570      // MAIN UPDATE /////////////////////////////////////
571      this->lastAbsCoordinate = this->absCoordinate;
572
573      PRINTF(5)("PNode::update - %s - (%f, %f, %f)\n", this->getName(), this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
574
575
576      if( this->parentMode & PNODE_LOCAL_ROTATE && this->bRelDirChanged)
577      {
578        /* update the current absDirection - remember * means rotation around sth.*/
579        this->prevRelCoordinate = this->relCoordinate;
580        this->absDirection = this->relDirection * parent->getAbsDir();;
581      }
582
583      if(likely(this->parentMode & PNODE_MOVEMENT && this->bRelCoorChanged))
584      {
585        /* update the current absCoordinate */
586        this->prevRelCoordinate = this->relCoordinate;
587        this->absCoordinate = this->parent->getAbsCoor() + this->relCoordinate;
588      }
589      else if( this->parentMode & PNODE_ROTATE_MOVEMENT && this->bRelCoorChanged)
590      {
591        /* update the current absCoordinate */
592        this->prevRelCoordinate = this->relCoordinate;
593        this->absCoordinate = this->parent->getAbsCoor() + parent->getAbsDir().apply(this->relCoordinate);
594      }
595      /////////////////////////////////////////////////
596   }
597  else
598    {
599      PRINTF(4)("NullParent::update - (%f, %f, %f)\n", this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
600      if (this->bRelCoorChanged)
601      {
602        this->prevRelCoordinate = this->relCoordinate;
603        this->absCoordinate = this->relCoordinate;
604      }
605      if (this->bRelDirChanged)
606      {
607        this->prevRelDirection = this->relDirection;
608        this->absDirection = this->getAbsDir () * this->relDirection;
609      }
610    }
611
612    if(this->children->getSize() > 0)
613    {
614      tIterator<PNode>* iterator = this->children->getIterator();
615      PNode* pn = iterator->firstElement();
616      while( pn != NULL)
617      {
618        /* if this node has changed, make sure, that all children are updated also */
619        if( likely(this->bRelCoorChanged))
620          pn->parentCoorChanged ();
621        if( likely(this->bRelDirChanged))
622          pn->parentDirChanged ();
623
624        pn->update(dt);
625        pn = iterator->nextElement();
626      }
627      delete iterator;
628    }
629    this->velocity = (this->absCoordinate - this->lastAbsCoordinate) / dt;
630    this->bRelCoorChanged = false;
631    this->bRelDirChanged = false;
632}
633
634/**
635 *  displays some information about this pNode
636 * @param depth The deph into which to debug the children of this PNode to.
637 * (0: all children will be debugged, 1: only this PNode, 2: this and direct children...)
638 * @param level The n-th level of the Node we draw (this is internal and only for nice output)
639*/
640void PNode::debug(unsigned int depth, unsigned int level) const
641{
642  for (unsigned int i = 0; i < level; i++)
643    PRINT(0)(" |");
644  if (this->children->getSize() > 0)
645    PRINT(0)(" +");
646  else
647    PRINT(0)(" -");
648  PRINT(0)("PNode(%s::%s) - absCoord: (%0.2f, %0.2f, %0.2f), relCoord(%0.2f, %0.2f, %0.2f), direction(%0.2f, %0.2f, %0.2f) - %s\n",
649           this->getClassName(),
650           this->getName(),
651           this->absCoordinate.x,
652           this->absCoordinate.y,
653           this->absCoordinate.z,
654           this->relCoordinate.x,
655           this->relCoordinate.y,
656           this->relCoordinate.z,
657           this->getAbsDirV().x,
658           this->getAbsDirV().y,
659           this->getAbsDirV().z,
660           this->parentingModeToChar(parentMode));
661  if (depth >= 2 || depth == 0)
662  {
663    tIterator<PNode>* iterator = this->children->getIterator();
664      //PNode* pn = this->children->enumerate ();
665    PNode* pn = iterator->firstElement();
666    while( pn != NULL)
667    {
668      if (depth == 0)
669        pn->debug(0, level + 1);
670      else
671        pn->debug(depth - 1, level +1);
672      pn = iterator->nextElement();
673    }
674    delete iterator;
675  }
676}
677#include "color.h"
678
679/**
680   displays the PNode at its position with its rotation as a cube.
681*/
682void PNode::debugDraw(unsigned int depth, float size, Vector color) const
683{
684  glMatrixMode(GL_MODELVIEW);
685  glPushMatrix();
686  glDisable(GL_LIGHTING);
687
688  /* translate */
689  glTranslatef (this->getAbsCoor ().x,
690                this->getAbsCoor ().y,
691                this->getAbsCoor ().z);
692  /* rotate */
693//  this->getAbsDir ().matrix (matrix);
694//  glMultMatrixf((float*)matrix);
695
696  Vector tmpRot = this->getAbsDir().getSpacialAxis();
697  glColor3f(color.x, color.y, color.z);
698  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
699  {
700    glBegin(GL_LINE_STRIP);
701    glVertex3f(-.5*size, -.5*size,  -.5*size);
702    glVertex3f(+.5*size, -.5*size,  -.5*size);
703    glVertex3f(+.5*size, -.5*size,  +.5*size);
704    glVertex3f(-.5*size, -.5*size,  +.5*size);
705    glVertex3f(-.5*size, -.5*size,  -.5*size);
706    glEnd();
707    glBegin(GL_LINE_STRIP);
708    glVertex3f(-.5*size, +.5*size,  -.5*size);
709    glVertex3f(+.5*size, +.5*size,  -.5*size);
710    glVertex3f(+.5*size, +.5*size,  +.5*size);
711    glVertex3f(-.5*size, +.5*size,  +.5*size);
712    glVertex3f(-.5*size, +.5*size,  -.5*size);
713    glEnd();
714
715    glBegin(GL_LINES);
716    glVertex3f(-.5*size, -.5*size,  -.5*size);
717    glVertex3f(-.5*size, +.5*size,  -.5*size);
718    glVertex3f(+.5*size, -.5*size,  -.5*size);
719    glVertex3f(+.5*size, +.5*size,  -.5*size);
720    glVertex3f(+.5*size, -.5*size,  +.5*size);
721    glVertex3f(+.5*size, +.5*size,  +.5*size);
722    glVertex3f(-.5*size, -.5*size,  +.5*size);
723    glVertex3f(-.5*size, +.5*size,  +.5*size);
724    glEnd();
725  }
726
727  glPopMatrix();
728  glEnable(GL_LIGHTING);
729  if (depth >= 2 || depth == 0)
730  {
731    Vector childColor =  Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(20,0,.0));
732
733    tIterator<PNode>* iterator = this->children->getIterator();
734    PNode* pn = iterator->firstElement();
735    while( pn != NULL)
736    {
737      if (depth == 0)
738        pn->debugDraw(0, size, childColor);
739      else
740        pn->debugDraw(depth - 1, size, childColor);
741      pn = iterator->nextElement();
742    }
743    delete iterator;
744  }
745}
746
747
748
749/////////////////////
750// HELPER_FUCTIONS //
751/////////////////////
752
753/**
754 * converts a parentingMode into a string that is the name of it
755 * @param parentingMode the ParentingMode to convert
756 * @return the converted string
757 */
758const char* PNode::parentingModeToChar(int parentingMode)
759{
760  if (parentingMode == PNODE_LOCAL_ROTATE)
761    return "local-rotate";
762  else if (parentingMode == PNODE_ROTATE_MOVEMENT)
763    return "rotate-movement";
764  else if (parentingMode == PNODE_MOVEMENT)
765    return "movement";
766  else if (parentingMode == PNODE_ALL)
767    return "all";
768  else if (parentingMode == PNODE_ROTATE_AND_MOVE)
769    return "rotate-and-move";
770}
771
772/**
773 * converts a parenting-mode-string into a int
774 * @param parentingMode the string naming the parentingMode
775 * @return the int corresponding to the named parentingMode
776 */
777PARENT_MODE PNode::charToParentingMode(const char* parentingMode)
778{
779  if (!strcmp(parentingMode, "local-rotate"))
780    return (PNODE_LOCAL_ROTATE);
781  else  if (!strcmp(parentingMode, "rotate-movement"))
782    return (PNODE_ROTATE_MOVEMENT);
783  else  if (!strcmp(parentingMode, "movement"))
784    return (PNODE_MOVEMENT);
785  else  if (!strcmp(parentingMode, "all"))
786    return (PNODE_ALL);
787  else  if (!strcmp(parentingMode, "rotate-and-move"))
788    return (PNODE_ROTATE_AND_MOVE);
789}
Note: See TracBrowser for help on using the repository browser.