Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: renamed all timing functions to tick() - cleanede up world

File size: 13.0 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  this->children = new tList<PNode>();
37  this->bRelCoorChanged = true;
38  this->bAbsCoorChanged = false;
39  this->bRelDirChanged = true;
40  this->bAbsDirChanged = false;
41  this->parent = NULL;
42  this->objectName = NULL;
43
44  NullParent* np = NullParent::getInstance();
45  np->addChild(this);
46}
47
48
49/**
50   \brief constructor with coodinates
51   \param absCoordinate the Absolute coordinate of the Object
52   \param parent The parent-node of this node.
53*/
54PNode::PNode (Vector* absCoordinate, PNode* parent )
55{
56  this->absCoordinate = *absCoordinate;
57  this->relCoordinate = this->absCoordinate - parent->getAbsCoor ();
58 
59  this->children = new tList<PNode>();
60  this->bRelCoorChanged = true;
61  this->bAbsCoorChanged = false;
62  this->bRelDirChanged = true;
63  this->bAbsDirChanged = false;
64  this->parent = parent;
65  this->objectName = NULL;
66
67  parent->addChild (this);
68}
69
70
71/**
72   \brief this constructor is very special.
73   \param with the name of the class
74
75   this constuctor exists, because there was a little issue with a
76   PNode<->NullPointer relation. It is crutial, that this construcor
77   exists, and is never used except from the NullParent itself. If you
78   delete it, there will probably be a endless loop, because in the
79   default constcutor of PNode NullPointer is generated, and NullPointer
80   gerenates itself again and again...
81   dont't think about it...
82   \todo patrick think about this one here...
83*/
84PNode::PNode(char* name)
85{
86  this->children = new tList<PNode>();
87  this->bRelCoorChanged = true;
88  this->bAbsCoorChanged = false;
89  this->bRelDirChanged = true;
90  this->bAbsDirChanged = false;
91  this->parent = NULL; 
92  this->objectName = NULL;
93}
94
95/**
96   \brief standard deconstructor
97
98   \todo this deconstructor is not jet implemented - do it
99*/
100PNode::~PNode () 
101{
102  /*
103  delete &this->children;
104  delete &this->relCoordinate;
105  delete &this->absCoordinate;
106  delete &this->relDirection;
107  delete &this->absDirection;
108  */
109  //this->parent = NULL;
110  /* there is currently a problem with cleaning up - fix*/
111
112 
113  PNode* pn = this->children->enumerate();
114  while( pn != NULL) 
115    { 
116      pn = this->children->nextElement();
117      delete pn;
118    }
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->children->remove(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
342   Children from pNode will not be lost, they are referenced to NullPointer
343*/
344void PNode::removeChild (PNode* pNode)
345{
346  pNode->remove();
347  this->children->remove (pNode);
348  pNode->parent = NULL;
349}
350
351
352/**
353   \brief remove this pnode from the tree and adds all following to NullParent
354
355   this can be the case, if an entity in the world is been destroyed.
356*/
357void PNode::remove()
358{
359  NullParent* np = NullParent::getInstance();
360  PNode* pn = this->children->enumerate();
361  while( pn != NULL) 
362    { 
363      this->children->remove(pn);
364      np->addChild(pn, pn->getMode());
365      pn = this->children->nextElement();
366    }
367}
368
369
370/**
371   \brief sets the parent of this PNode
372   \param parent the Parent to set
373*/
374void PNode::setParent (PNode* parent)
375{
376  parent->addChild(this);
377}
378
379
380/**
381   \brief set the mode of this parent manualy
382   \param mode the mode of the bind-type.
383*/
384void PNode::setMode (parentingMode mode)
385{
386  this->mode = mode;
387}
388
389
390/**
391   \brief gets the mode of this parent manualy
392   \return the mode of the bind-type.
393*/
394parentingMode PNode::getMode()
395{
396  return this->mode;
397}
398
399/**
400   \brief has to be called, if the parent coordinate has changed
401   
402   normaly this will be done by the parent itself automaticaly. If you call this, you
403   will force an update of the coordinated of the node.
404*/
405void PNode::parentCoorChanged ()
406{
407  this->bRelCoorChanged = true;
408}
409
410
411/**
412   \brief has to be called, if the parent direction has changed
413   
414   normaly this will be done by the parent itself automaticaly. If you call this, you
415   will force an update of the direction of the node.
416*/
417void PNode::parentDirChanged ()
418{
419  this->bRelDirChanged = true;
420}
421
422
423/**
424   \brief updates the absCoordinate/absDirection
425   \param timeStamp The timestanp used for to look if calculations should be done
426
427   this is used to go through the parent-tree to update all the absolute coordinates
428   and directions. this update should be done by the engine, so you don't have to
429   worry, normaly...
430*/
431void PNode::update ()
432{
433  PRINTF(2)("PNode::update - %s - (%f, %f, %f)\n", this->objectName, this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
434  // printf("%s", this->objectName);
435
436      if( this->mode == MOVEMENT )
437        {
438          if( this->bAbsCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
439            {
440              /* if you have set the absolute coordinates this overrides all other changes */
441              this->relCoordinate = this->absCoordinate - parent->getAbsCoor ();
442            }
443          else if( this->bRelCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
444            {
445              /*this is bad style... must be deleted later - just for testing*/
446              if( this->parent == NULL)
447                {
448                this->absCoordinate = this->relCoordinate;
449                }
450              else
451                this->absCoordinate = parent->getAbsCoor() + this->relCoordinate;             /* update the current absCoordinate */
452            }
453        }
454     
455      if( this->mode == ROTATION || this->mode == ALL)
456        {
457          if( this->bAbsDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
458            {
459              /* if you have set the absolute coordinates this overrides all other changes */
460              this->relDirection = this->absDirection - parent->getAbsDir();
461            }
462          else if( this->bRelDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
463            {
464              /* update the current absDirection - remember * means rotation around sth.*/
465              this->absDirection = parent->getAbsDir() * this->relDirection;
466            }
467        }
468     
469      if( this->mode == ALL)
470        {
471          if( this->bAbsCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
472            {
473              /* if you have set the absolute coordinates this overrides all other changes */
474              this->relCoordinate = this->absCoordinate - parent->getAbsCoor ();
475            }
476          else if( this->bRelCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
477            {
478              /*this is bad style... must be deleted later - just for testing*/
479              if( this->parent == NULL)
480                this->absCoordinate = this->relCoordinate;
481              else
482                this->absCoordinate = parent->getAbsCoor() + parent->getAbsDir().apply(this->relCoordinate);          /* update the current absCoordinate */
483            }
484        }
485
486
487  PNode* pn = this->children->enumerate();
488  while( pn != NULL) 
489    { 
490      /* if this node has changed, make sure, that all children are updated also */
491      if( this->bRelCoorChanged || this->bAbsCoorChanged)
492        pn->parentCoorChanged ();
493      if( this->bRelDirChanged || this->bAbsDirChanged)
494        pn->parentDirChanged ();
495      pn->update();
496      pn = this->children->nextElement();
497    }
498
499  this->timeStamp = timeStamp;
500  this->bRelCoorChanged = false;
501  this->bAbsCoorChanged = false;
502  this->bRelDirChanged = false;
503  this->bAbsDirChanged = false;
504}
505
506
507/**
508  \brief tick
509  \param dt time to tick
510*/
511void PNode::processTick (float dt)
512{
513  //this->tick (dt);
514  PNode* pn = this->children->enumerate();
515  while( pn != NULL) 
516    { 
517      pn->processTick (dt);
518      pn = this->children->nextElement();
519    } 
520}
521
522
523/**
524   \brief displays some information about this pNode
525*/
526void PNode::debug()
527{
528  PRINTF(2)("PNode::debug() - absCoord: (%f, %f, %f)\n", 
529         this->absCoordinate.x, 
530         this->absCoordinate.y,
531         this->absCoordinate.z);
532}
533
534
535/**
536  \brief set the name of the node
537
538  for debug purposes realy usefull, not used to work properly
539*/
540void PNode::setName (char* newName)
541{
542  this->objectName = newName;
543}
544
545
546/**
547  \brief gets the name of the node
548*/
549char* PNode::getName ()
550{
551  return this->objectName;
552}
553
Note: See TracBrowser for help on using the repository browser.