Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: zero-loop problem in pnode, dynamic pnode realocation. unstable, segfault when changing level.

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