Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: parenting revisited. fixed some bugs some missunderstandings. made it a little more secure to use. still dev

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