Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: modiefied PNode to match Element2D's removal methods.
see destructor header for more detail

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