Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3536 was 3535, checked in by bensch, 20 years ago

orxonox/trunk: player connected to the track.
There is some strange error about this, that I do not quite understand.

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