Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3552 was 3552, checked in by bensch, 19 years ago

orxonox/trunk: added init-function to PNode and chars now get copied and deleted instead of just the reference

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