Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: MUCH better algorithm for the QuaternionSlerp in PNodes rotate-to function
also updated the Quaternion class, to now hold dot-product and distance

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