Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/levelloader/src/lib/coord/p_node.cc @ 3557

Last change on this file since 3557 was 3557, checked in by chris, 19 years ago

orxonox/branches/levelloader: Rolling toward bug-free-ness

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