Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: setMode → setParentMode

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