Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: some more classes now destroy themselves via virtual-destructors and call to predecessing destroy-function
also made
#include "stdincl.h" out of unnecessary h-files, so we got faster compile time.

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