Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: valgrind's second fruits….. the char-arrays
some time in the near future i will hopefully be faster in interpreting this WALLgrind… but it is great, i can tell you (or at least anyone that reads this :))

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