Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: fixed a bug in the update phase, added real debug output bensch style

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