Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: now the delete-process is as inteded by c++
virtual ~ClassName extends deletion and deletes also the MasterClass

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