Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: implemented PNode-functionality in Element2D,
update and debugDraw still missing

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