Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trank: worked on removing alg. from pnode and changed a little on camera for the new tackmanager

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