Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: fixed another bug in list-template and added patch from bensch to the pnode to enable the different rotation modes

File size: 12.7 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  this->children->remove (pNode);
337  pNode->parent = NULL;
338}
339
340
341/**
342   \brief sets the parent of this PNode
343   \param parent the Parent to set
344*/
345/*
346void PNode::setParent (PNode* parent)
347{
348  parent->addChild(this);
349}
350*/
351
352/**
353   \brief set the mode of this parent manualy
354   \param mode the mode of the bind-type.
355*/
356void PNode::setMode (parentingMode mode)
357{
358  this->mode = mode;
359}
360
361/**
362   \brief has to be called, if the parent coordinate has changed
363   
364   normaly this will be done by the parent itself automaticaly. If you call this, you
365   will force an update of the coordinated of the node.
366*/
367void PNode::parentCoorChanged ()
368{
369  this->bRelCoorChanged = true;
370}
371
372
373/**
374   \brief has to be called, if the parent direction has changed
375   
376   normaly this will be done by the parent itself automaticaly. If you call this, you
377   will force an update of the direction of the node.
378*/
379void PNode::parentDirChanged ()
380{
381  this->bRelDirChanged = true;
382}
383
384
385/**
386   \brief updates the absCoordinate/absDirection
387   \param timeStamp The timestanp used for to look if calculations should be done
388
389   this is used to go through the parent-tree to update all the absolute coordinates
390   and directions. this update should be done by the engine, so you don't have to
391   worry, normaly...
392*/
393void PNode::update (float timeStamp)
394{
395  //printf ("PNode::update - %s - (%f, %f, %f)\n", this->objectName, this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
396  // printf("%s", this->objectName);
397
398      if( this->mode == MOVEMENT )
399        {
400          if( this->bAbsCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
401            {
402              printf("PNode::update () - this->bAbsCoorChanged = true\n");
403              /* if you have set the absolute coordinates this overrides all other changes */
404              this->relCoordinate = this->absCoordinate - parent->getAbsCoor ();
405            }
406          else if( this->bRelCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
407            {
408              /*this is bad style... must be deleted later - just for testing*/
409              if( this->parent == NULL)
410                {
411                this->absCoordinate = this->relCoordinate;
412                }
413              else
414                this->absCoordinate = parent->getAbsCoor() + this->relCoordinate;             /* update the current absCoordinate */
415            }
416        }
417     
418      if( this->mode == ROTATION || this->mode == ALL)
419        {
420          if( this->bAbsDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
421            {
422              /* if you have set the absolute coordinates this overrides all other changes */
423              this->relDirection = this->absDirection - parent->getAbsDir();
424            }
425          else if( this->bRelDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
426            {
427              /* update the current absDirection - remember * means rotation around sth.*/
428              this->absDirection = parent->getAbsDir() * this->relDirection;
429            }
430        }
431     
432      if( this->mode == ALL)
433        {
434          if( this->bAbsCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
435            {
436              printf("PNode::update () - this->bAbsCoorChanged = true\n");
437              /* if you have set the absolute coordinates this overrides all other changes */
438              this->relCoordinate = this->absCoordinate - parent->getAbsCoor ();
439            }
440          else if( this->bRelCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
441            {
442              /*this is bad style... must be deleted later - just for testing*/
443              if( this->parent == NULL)
444                this->absCoordinate = this->relCoordinate;
445              else
446                this->absCoordinate = parent->getAbsCoor() + parent->getAbsDir().apply(this->relCoordinate);          /* update the current absCoordinate */
447            }
448        }
449
450
451  PNode* pn = this->children->enumerate();
452  while( pn != NULL) 
453    { 
454      /* if this node has changed, make sure, that all children are updated also */
455      if( this->bRelCoorChanged || this->bAbsCoorChanged)
456        pn->parentCoorChanged ();
457      if( this->bRelDirChanged || this->bAbsDirChanged)
458        pn->parentDirChanged ();
459      pn->update(timeStamp);
460      pn = this->children->nextElement();
461    }
462
463  this->timeStamp = timeStamp;
464  this->bRelCoorChanged = false;
465  this->bAbsCoorChanged = false;
466  this->bRelDirChanged = false;
467  this->bAbsDirChanged = false;
468}
469
470
471/**
472  \brief tick
473  \param dt time to tick
474*/
475void PNode::processTick (float dt)
476{
477  this->tick (dt);
478  PNode* pn = this->children->enumerate();
479  while( pn != NULL) 
480    { 
481      pn->processTick (dt);
482      pn = this->children->nextElement();
483    } 
484}
485
486/**
487   \param dt time to tick
488*/
489void PNode::tick (float dt)
490{}
491
492/**
493   \brief displays some information about this pNode
494*/
495void PNode::debug()
496{
497  printf("PNode::debug() - absCoord: (%f, %f, %f)\n", 
498         this->absCoordinate.x, 
499         this->absCoordinate.y,
500         this->absCoordinate.z);
501}
502
503
504/**
505  \brief set the name of the node
506
507  for debug purposes realy usefull, not used to work properly
508*/
509void PNode::setName (char* newName)
510{
511  this->objectName = newName;
512}
513
514
515/**
516  \brief gets the name of the node
517*/
518char* PNode::getName ()
519{
520  return this->objectName;
521}
522
Note: See TracBrowser for help on using the repository browser.