Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: major fix in PNode/Element2D… the Children were removed twice when deleting an Instance

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