Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6053 was 6048, checked in by bensch, 20 years ago

orxonox/trunk: some fixes, to PNode and world.

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