Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: renamed class LoadParam to CLoadParam and Macro LoadParamNew to LoadParam

File size: 24.6 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(root, "rel-coor", this, PNode, setRelCoor)
144      .describe("Sets The relative position of the Node to its parent.");
145
146  LoadParam(root, "abs-coor", this, PNode, setAbsCoor)
147      .describe("Sets The absolute Position of the Node.");
148
149  LoadParam(root, "rel-dir", this, PNode, setRelDir)
150      .describe("Sets The relative rotation of the Node to its parent.");
151
152  LoadParam(root, "abs-dir", this, PNode, setAbsDir)
153      .describe("Sets The absolute rotation of the Node.");
154
155  LoadParam(root, "parent", this, PNode, setParent)
156      .describe("the Name of the Parent of this PNode");
157
158  LoadParam(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    LOAD_PARAM_START_CYCLE(root, element);
165    {
166      LoadParam_CYCLE(element, "parent", this, PNode, addChild)
167          .describe("adds a new Child to the current Node.");
168
169    }
170    LOAD_PARAM_END_CYCLE(element);
171  }
172}
173
174/**
175 *  set relative coordinates
176 * @param relCoord relative coordinates to its parent
177 *
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 * this is the internal method of:
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 this is the first Element we draw
765  if (level == 0)
766  {
767    glPushAttrib(GL_ENABLE_BIT); // save the Enable-attributes
768    glMatrixMode(GL_MODELVIEW);  // goto the ModelView Matrix
769
770    glDisable(GL_LIGHTING);      // disable lighting (we do not need them for just lighting)
771    glDisable(GL_BLEND);         // ''
772    glDisable(GL_TEXTURE_2D);    // ''
773    glDisable(GL_DEPTH_TEST);    // ''
774  }
775
776  glPushMatrix();                // repush the Matrix-stack
777  /* translate */
778  glTranslatef (this->getAbsCoor ().x,
779                this->getAbsCoor ().y,
780                this->getAbsCoor ().z);
781//  this->getAbsDir ().matrix (matrix);
782
783  /* rotate */
784  Vector tmpRot = this->getAbsDir().getSpacialAxis();
785  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
786  /* set the new Color */
787  glColor3f(color.x, color.y, color.z);
788  { /* draw a cube of size size */
789    glBegin(GL_LINE_STRIP);
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    glVertex3f(-.5*size, -.5*size,  -.5*size);
795    glEnd();
796    glBegin(GL_LINE_STRIP);
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    glVertex3f(-.5*size, +.5*size,  -.5*size);
802    glEnd();
803
804    glBegin(GL_LINES);
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    glVertex3f(-.5*size, +.5*size,  +.5*size);
813    glEnd();
814  }
815
816  glPopMatrix();
817  if (depth >= 2 || depth == 0)
818  {
819    /* rotate the current color in HSV space around 20 degree */
820    Vector childColor =  Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(20,0,.0));
821    tIterator<PNode>* iterator = this->children->getIterator();
822    PNode* pn = iterator->firstElement();
823    while( pn != NULL)
824    {
825      // drawing the Dependency graph
826     if (this != NullParent::getInstance())
827      {
828       glBegin(GL_LINES);
829       glColor3f(color.x, color.y, color.z);
830       glVertex3f(this->getAbsCoor ().x,
831                  this->getAbsCoor ().y,
832                  this->getAbsCoor ().z);
833        glColor3f(childColor.x, childColor.y, childColor.z);
834        glVertex3f(pn->getAbsCoor ().x,
835                   pn->getAbsCoor ().y,
836                   pn->getAbsCoor ().z);
837        glEnd();
838      }
839      /* if we want to draw the children too */
840      if (depth == 0) /* -> all of them */
841        pn->debugDraw(0, size, childColor, level+1);
842      else            /* -> only the Next one */
843        pn->debugDraw(depth - 1, size, childColor, level +1);
844      pn = iterator->nextElement();
845    }
846    delete iterator;
847  }
848  if (level == 0)
849    glPopAttrib(); /* pop the saved attributes back out */
850}
851
852
853
854/////////////////////
855// HELPER_FUCTIONS //
856/////////////////////
857
858/**
859 * converts a parentingMode into a string that is the name of it
860 * @param parentingMode the ParentingMode to convert
861 * @return the converted string
862 */
863const char* PNode::parentingModeToChar(int parentingMode)
864{
865  if (parentingMode == PNODE_LOCAL_ROTATE)
866    return "local-rotate";
867  else if (parentingMode == PNODE_ROTATE_MOVEMENT)
868    return "rotate-movement";
869  else if (parentingMode == PNODE_MOVEMENT)
870    return "movement";
871  else if (parentingMode == PNODE_ALL)
872    return "all";
873  else if (parentingMode == PNODE_ROTATE_AND_MOVE)
874    return "rotate-and-move";
875}
876
877/**
878 * converts a parenting-mode-string into a int
879 * @param parentingMode the string naming the parentingMode
880 * @return the int corresponding to the named parentingMode
881 */
882PARENT_MODE PNode::charToParentingMode(const char* parentingMode)
883{
884  if (!strcmp(parentingMode, "local-rotate"))
885    return (PNODE_LOCAL_ROTATE);
886  else  if (!strcmp(parentingMode, "rotate-movement"))
887    return (PNODE_ROTATE_MOVEMENT);
888  else  if (!strcmp(parentingMode, "movement"))
889    return (PNODE_MOVEMENT);
890  else  if (!strcmp(parentingMode, "all"))
891    return (PNODE_ALL);
892  else  if (!strcmp(parentingMode, "rotate-and-move"))
893    return (PNODE_ROTATE_AND_MOVE);
894}
Note: See TracBrowser for help on using the repository browser.