Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3560 was 3560, checked in by patrick, 19 years ago

orxonox/trunk: fixed a bug, that stopped orxonox from deleting all entities clearly. Needed long time to find it, ddd is your friend

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