Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6072 was 6071, checked in by bensch, 20 years ago

trunk: sync

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