Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: derivations work.
now the only thing to do is specify all the classes, and DO it CLEAN.

@patrick: is it ok, how i treated your ObjectManager??

File size: 14.5 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer:
16
17   \todo Smooth-Parent: delay, speed
18*/
19
20#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PNODE
21
22#include "p_node.h"
23#include "stdincl.h"
24#include "compiler.h"
25
26#include "error.h"
27#include "debug.h"
28#include "list.h"
29#include "vector.h"
30#include "null_parent.h"
31#include "load_param.h"
32
33//#include "vector.h"
34//#include "quaternion.h"
35
36using namespace std;
37
38
39/**
40   \brief standard constructor
41*/
42PNode::PNode ()
43{
44  init(NULL);
45
46  NullParent::getInstance()->addChild(this);
47}
48
49/**
50   \param root the load-Element for the PNode
51*/
52PNode::PNode(const TiXmlElement* root)
53{
54  this->init(NULL);
55  this->loadParams(root);
56
57  NullParent::getInstance()->addChild(this);
58}
59
60
61/**
62   \brief constructor with coodinates
63   \param absCoordinate the Absolute coordinate of the Object
64   \param parent The parent-node of this node.
65*/
66PNode::PNode (const Vector& absCoordinate, PNode* parent )
67{
68  this->init(parent);
69
70  this->absCoordinate = absCoordinate;
71
72  if (likely(parent != NULL))
73  {
74    this->relCoordinate = this->absCoordinate - parent->getAbsCoor();
75    parent->addChild (this);
76  }
77}
78
79/**
80   \brief standard deconstructor
81*/
82PNode::~PNode ()
83{
84  tIterator<PNode>* iterator = this->children->getIterator();
85  PNode* pn = iterator->nextElement();
86  while( pn != NULL)
87    {
88      delete pn;
89      pn = iterator->nextElement();
90    }
91  delete iterator;
92  /* this deletes all children in the list */
93  delete this->children;
94  this->parent = NULL;
95}
96
97/**
98   \brief initializes a PNode
99   \param parent the parent for this PNode
100*/
101void PNode::init(PNode* parent)
102{
103  this->setClassID(CL_PARENT_NODE);
104  this->children = new tList<PNode>();
105  this->bRelCoorChanged = true;
106  this->bAbsCoorChanged = false;
107  this->bRelDirChanged = true;
108  this->bAbsDirChanged = false;
109  this->parent = parent;
110}
111
112/**
113   \brief loads parameters of the PNode
114   \param root the XML-element to load the properties of
115*/
116void PNode::loadParams(const TiXmlElement* root)
117{
118  static_cast<BaseObject*>(this)->loadParams(root);
119}
120
121/**
122   \brief set relative coordinates
123   \param relCoord relative coordinates to its parent
124
125   it is very importand, that you use this function, if you want to update the
126   relCoordinates. If you don't use this, the PNode won't recognize, that something
127   has changed and won't update the children Nodes.
128*/
129void PNode::setRelCoor (const Vector& relCoord)
130{
131  this->bRelCoorChanged = true;
132  this->relCoordinate = relCoord;
133}
134
135/**
136   \param absCoord set absolute coordinate
137
138   it is very importand, that you use this function, if you want to update the
139   absCoordinates. If you don't use this, the PNode won't recognize, that something
140   has changed and won't update the children Nodes.
141*/
142void PNode::setAbsCoor (const Vector& absCoord)
143{
144  this->bAbsCoorChanged = true;
145  this->absCoordinate = absCoord;
146}
147
148/**
149   \brief shift coordinate (abs and rel)
150   \param shift shift vector
151
152   this function shifts the current coordinates about the vector shift. this is
153   usefull because from some place else you can:
154   PNode* someNode = ...;
155   Vector objectMovement = calculateShift();
156   someNode->shiftCoor(objectMovement);
157
158   elsewhere you would have to:
159   PNode* someNode = ...;
160   Vector objectMovement = calculateShift();
161   Vector currentCoor = someNode->getRelCoor();
162   Vector newCoor = currentCoor + objectMovement;
163   someNode->setRelCoor(newCoor);
164
165   yea right... shorter...
166
167*/
168void PNode::shiftCoor (const Vector& shift)
169{
170
171  if( unlikely(this->bAbsCoorChanged))
172    {
173      this->absCoordinate += shift;
174    }
175  else
176    {
177      this->relCoordinate += shift;
178      this->bRelCoorChanged = true;
179    }
180}
181
182/**
183   \brief set relative direction
184   \param relDir to its parent
185
186   it is very importand, that you use this function, if you want to update the
187   relDirection. If you don't use this, the PNode won't recognize, that something
188   has changed and won't update the children Nodes.
189*/
190void PNode::setRelDir (const Quaternion& relDir)
191{
192  this->bRelCoorChanged = true;
193  this->relDirection = relDir;
194}
195
196/**
197   \brief sets the absolute direction (0,0,1)
198   \param absDir absolute coordinates
199
200   it is very importand, that you use this function, if you want to update the
201   absDirection. If you don't use this, the PNode won't recognize, that something
202   has changed and won't update the children Nodes.
203*/
204void PNode::setAbsDir (const Quaternion& absDir)
205{
206  this->bAbsDirChanged = true;
207  this->absDirection = absDir;
208}
209
210/**
211   \brief shift coordinate (abs and rel)
212   \param shift vector
213
214   this function shifts the current coordinates about the vector shift. this is
215   usefull because from some place else you can:
216   PNode* someNode = ...;
217   Quaternion objectMovement = calculateShift();
218   someNode->shiftCoor(objectMovement);
219
220   elsewhere you would have to:
221   PNode* someNode = ...;
222   Quaternion objectMovement = calculateShift();
223   Quaternion currentCoor = someNode->getRelCoor();
224   Quaternion newCoor = currentCoor + objectMovement;
225   someNode->setRelCoor(newCoor);
226
227   yea right... shorter...
228
229   \todo implement this
230*/
231void PNode::shiftDir (const Quaternion& shift)
232{
233  this->bRelDirChanged = true;
234  this->relDirection = this->relDirection * shift;
235}
236
237/**
238   \brief adds a child and makes this node to a parent
239   \param pNode child reference
240   \param parentMode on which changes the child should also change ist state
241
242   use this to add a child to this node.
243*/
244void PNode::addChild (PNode* pNode, int parentMode)
245{
246  if( likely(pNode->parent != NULL))
247    {
248      PRINTF(3)("PNode::addChild() - reparenting node: removing it and adding it again\n");
249      pNode->parent->children->remove(pNode);
250    }
251  pNode->parentMode = parentMode;
252  pNode->parent = this;
253  this->children->add(pNode);
254}
255
256/**
257   \brief removes a child from the node
258   \param pNode the child to remove from this pNode.
259
260   Children from pNode will not be lost, they are referenced to NullPointer
261*/
262void PNode::removeChild (PNode* pNode)
263{
264  pNode->remove();
265  this->children->remove (pNode);
266  pNode->parent = NULL;
267}
268
269
270/**
271   \brief remove this pnode from the tree and adds all following to NullParent
272
273   this can be the case, if an entity in the world is been destroyed.
274*/
275void PNode::remove()
276{
277  NullParent* nullParent = NullParent::getInstance();
278
279  tIterator<PNode>* iterator = this->children->getIterator();
280  PNode* pn = iterator->nextElement();
281
282  while( pn != NULL)
283    {
284      nullParent->addChild(pn, pn->getParentMode());
285      pn = iterator->nextElement();
286    }
287  delete iterator;
288  this->parent->children->remove(this);
289}
290
291
292/**
293   \brief sets the parent of this PNode
294   \param parent the Parent to set
295*/
296void PNode::setParent (PNode* parent)
297{
298  parent->addChild(this);
299}
300
301
302/**
303   \brief set the mode of this parent manualy
304   \param parentMode the mode of the bind-type.
305*/
306void PNode::setParentMode (unsigned int parentMode)
307{
308  this->parentMode = parentMode;
309}
310
311
312/**
313   \brief has to be called, if the parent coordinate has changed
314
315   normaly this will be done by the parent itself automaticaly. If you call this, you
316   will force an update of the coordinated of the node.
317*/
318/*
319void PNode::parentCoorChanged ()
320{
321  this->bRelCoorChanged = true;
322}
323*/
324
325/**
326   \brief updates the absCoordinate/absDirection
327   \param dt The time passed since the last update
328
329   this is used to go through the parent-tree to update all the absolute coordinates
330   and directions. this update should be done by the engine, so you don't have to
331   worry, normaly...
332*/
333void PNode::update (float dt)
334{
335  if( likely(this->parent != NULL))
336    {
337      this->lastAbsCoordinate = this->absCoordinate;
338
339      PRINTF(4)("PNode::update - %s - (%f, %f, %f)\n", this->getName(), this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
340
341
342      if( likely(this->parentMode & PNODE_MOVEMENT))
343        {
344          if( unlikely(this->bAbsCoorChanged) /*&& this->timeStamp != DataTank::timeStamp*/)
345            {
346              /* if you have set the absolute coordinates this overrides all other changes */
347              this->relCoordinate = this->absCoordinate - parent->getAbsCoor ();
348            }
349          if( likely(this->bRelCoorChanged) /*&& this->timeStamp != DataTank::timeStamp*/)
350
351            {
352              /*this is bad style... must be deleted later - just for testing*/
353
354              /*
355                if( unlikely(this->parent == NULL))
356                {
357                *this->absCoordinate = *this->relCoordinate;
358                }
359                else */
360              this->absCoordinate = parent->getAbsCoor() + this->relCoordinate;       /* update the current absCoordinate */
361            }
362        }
363
364      if( this->parentMode & PNODE_LOCAL_ROTATE)
365        {
366          if( unlikely(this->bAbsDirChanged) /*&& this->timeStamp != DataTank::timeStamp*/)
367            {
368              /* if you have set the absolute coordinates this overrides all other changes */
369              this->relDirection = this->absDirection - parent->getAbsDir();
370            }
371          else if( likely(this->bRelDirChanged) /*&& this->timeStamp != DataTank::timeStamp*/)
372            {
373              /* update the current absDirection - remember * means rotation around sth.*/
374              this->absDirection = parent->getAbsDir() * this->relDirection;
375            }
376        }
377
378      if( this->parentMode & PNODE_ROTATE_MOVEMENT)
379        {
380          if( unlikely(this->bAbsCoorChanged) /*&& this->timeStamp != DataTank::timeStamp*/)
381            {
382              /* if you have set the absolute coordinates this overrides all other changes */
383              this->relCoordinate = this->absCoordinate - parent->getAbsCoor ();
384            }
385          else if( likely(this->bRelCoorChanged) /*&& this->timeStamp != DataTank::timeStamp*/)
386            {
387              /*this is bad style... must be deleted later - just for testing*/
388              /*if( this->parent == NULL)
389               *this->absCoordinate = *this->relCoordinate;
390               else*/
391              this->absCoordinate = parent->getAbsCoor() + parent->getAbsDir().apply(this->relCoordinate);            /* update the current absCoordinate */
392            }
393        }
394
395
396      tIterator<PNode>* iterator = this->children->getIterator();
397      //PNode* pn = this->children->enumerate();
398      PNode* pn = iterator->nextElement();
399      while( pn != NULL)
400        {
401          /* if this node has changed, make sure, that all children are updated also */
402          if( likely(this->bRelCoorChanged || this->bAbsCoorChanged))
403            pn->parentCoorChanged ();
404          if( likely(this->bRelDirChanged || this->bAbsDirChanged))
405            pn->parentDirChanged ();
406
407          pn->update(dt);
408          //pn = this->children->nextElement();
409          pn = iterator->nextElement();
410        }
411      delete iterator;
412
413      this->velocity = (this->absCoordinate - this->lastAbsCoordinate) / dt;
414      this->bRelCoorChanged = false;
415      this->bAbsCoorChanged = false;
416      this->bRelDirChanged = false;
417      this->bAbsDirChanged = false;
418    }
419  else
420    {
421      PRINTF(4)("NullParent::update - (%f, %f, %f)\n", this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
422      this->absCoordinate = this->relCoordinate;
423      this->absDirection = this->getAbsDir () * this->relDirection;
424
425      tIterator<PNode>* iterator = this->children->getIterator();
426      //PNode* pn = this->children->enumerate ();
427      PNode* pn = iterator->nextElement();
428      while( pn != NULL)
429      {
430        /* if this node has changed, make sure, that all children are updated also */
431          if( this->bRelCoorChanged || this->bAbsCoorChanged)
432            pn->parentCoorChanged ();
433          if( this->bRelDirChanged || this->bAbsDirChanged)
434            pn->parentDirChanged ();
435          pn->update (dt);
436          //pn = this->children->nextElement ();
437          pn = iterator->nextElement();
438        }
439      delete iterator;
440      this->bRelCoorChanged = false;
441      this->bAbsCoorChanged = false;
442      this->bRelDirChanged = false;
443      this->bAbsDirChanged = false;
444    }
445}
446
447/**
448   \brief displays some information about this pNode
449   \param depth The deph into which to debug the children of this PNode to.
450  (0: all children will be debugged, 1: only this PNode, 2: this and direct children...)
451   \param level The n-th level of the Node we draw (this is internal and only for nice output)
452*/
453void PNode::debug(unsigned int depth, unsigned int level) const
454{
455  for (unsigned int i = 0; i < level; i++)
456    PRINT(0)(" |");
457  if (this->children->getSize() > 0)
458    PRINT(0)(" +");
459  else
460    PRINT(0)(" -");
461  PRINT(0)("PNode(%s::%s) - absCoord: (%0.2f, %0.2f, %0.2f), relCoord(%0.2f, %0.2f, %0.2f)\n",
462           this->getClassName(),
463           this->getName(),
464           this->absCoordinate.x,
465           this->absCoordinate.y,
466           this->absCoordinate.z,
467           this->relCoordinate.x,
468           this->relCoordinate.y,
469           this->relCoordinate.z );
470  if (depth >= 2 || depth == 0)
471  {
472    tIterator<PNode>* iterator = this->children->getIterator();
473      //PNode* pn = this->children->enumerate ();
474    PNode* pn = iterator->nextElement();
475    while( pn != NULL)
476    {
477      if (depth == 0)
478        pn->debug(0, level + 1);
479      else
480        pn->debug(depth - 1, level +1);
481      pn = iterator->nextElement();
482    }
483    delete iterator;
484  }
485}
486
487/**
488  @brief displays the PNode at its position with its rotation as a cube.
489*/
490void PNode::debugDraw(float size) const
491{
492  glMatrixMode(GL_MODELVIEW);
493  glPushMatrix();
494  float matrix[4][4];
495
496  /* translate */
497  glTranslatef (this->getAbsCoor ().x,
498                this->getAbsCoor ().y,
499                this->getAbsCoor ().z);
500  /* rotate */
501  this->getAbsDir ().matrix (matrix);
502  glMultMatrixf((float*)matrix);
503  {
504    glBegin(GL_LINE_STRIP);
505    glVertex3f( .5,  .5, -.5);
506    glVertex3f( .5,  .5,  .5);
507    glVertex3f(-.5,  .5,  .5);
508    glVertex3f(-.5, -.5,  .5);
509    glVertex3f( .5,  .5, -.5);
510    glVertex3f( .5, -.5, -.5);
511    glVertex3f(-.5, -.5, -.5);
512    glVertex3f(-.5,  .5, -.5);
513    glEnd();
514    glBegin(GL_LINE_STRIP);
515    glVertex3f(-.5, -.5, -.5);
516    glVertex3f(-.5, -.5,  .5);
517    glVertex3f( .5, -.5,  .5);
518    glVertex3f( .5, -.5, -.5);
519    glEnd();
520    glBegin(GL_LINES);
521    glVertex3f( .5, -.5,  .5);
522    glVertex3f( .5,  .5,  .5);
523    glVertex3f(-.5, -.5,  .5);
524    glVertex3f(-.5,  .5,  .5);
525    glEnd();
526  }
527
528  glPopMatrix();
529}
Note: See TracBrowser for help on using the repository browser.