Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3693 was 3687, checked in by bensch, 20 years ago

orxonox/trunk: lastAbsCoord was not set

File size: 16.2 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#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PNODE
21
22#include "p_node.h"
23#include "stdincl.h"
24
25#include "error.h"
26#include "debug.h"
27#include "list.h"
28#include "vector.h"
29#include "null_parent.h"
30
31
32//#include "vector.h"
33//#include "quaternion.h"
34
35using namespace std;
36
37
38/**
39   \brief standard constructor
40
41   \todo this constructor is not jet implemented - do it
42*/
43PNode::PNode () 
44{
45  init(NULL);
46
47  NullParent* np = NullParent::getInstance();
48  np->addChild(this);
49}
50
51
52/**
53   \brief constructor with coodinates
54   \param absCoordinate the Absolute coordinate of the Object
55   \param parent The parent-node of this node.
56*/
57PNode::PNode (Vector* absCoordinate, PNode* parent )
58{
59  this->init(parent);
60
61  *this->absCoordinate = *absCoordinate;
62  if (parent != NULL)
63    {
64      *this->relCoordinate = *this->absCoordinate - parent->getAbsCoor ();
65      parent->addChild (this);
66    }
67  else 
68    this->relCoordinate = new Vector(0,0,0);
69}
70
71/**
72   \brief standard deconstructor
73
74   \todo this deconstructor is not jet implemented - do it
75*/
76PNode::~PNode () 
77{
78  /*
79  delete &this->children;
80  delete &this->relCoordinate;
81  delete &this->absCoordinate;
82  delete &this->relDirection;
83  delete &this->absDirection;
84  */
85  //this->parent = NULL;
86  /* there is currently a problem with cleaning up - fix*/
87
88  PNode* pn = this->children->enumerate();
89  while( pn != NULL) 
90    { 
91      delete pn;
92      pn = this->children->nextElement();
93
94    }
95   
96  /* this deletes all children in the list */
97  delete this->children;
98
99  delete []this->objectName;
100}
101
102
103void PNode::init(PNode* parent)
104{
105  this->children = new tList<PNode>();
106  this->bRelCoorChanged = true;
107  this->bAbsCoorChanged = false;
108  this->bRelDirChanged = true;
109  this->bAbsDirChanged = false;
110  this->parent = parent; 
111  this->objectName = NULL;
112
113  this->absCoordinate = new Vector();
114  this->relCoordinate = new Vector();
115  this->absDirection = new Quaternion();
116  this->relDirection = new Quaternion();
117  this->lastAbsCoordinate = new Vector();
118}
119
120/**
121   \brief deletes the hole pnode tree
122
123   cleans up all pnodes
124*/
125/*
126void PNode::destroy ()
127{
128  PNode* pn = this->children->enumerate();
129  while( pn != NULL)
130    {
131      pn->destroy ();
132      pn = this->children->nextElement();
133    }
134  // this deletes all children in the list
135  this->children->destroy ();
136
137  static_cast<BaseObject*>(this)->destroy();
138}
139*/
140
141/**
142   \brief get relative coordinates
143   \returns relative coordinates to its parent
144   
145   the reference that is returned is a pointer to the real relCoor, so don't
146   change it unless you realy know what you are doing.
147*/
148Vector* PNode::getRelCoor ()
149{
150  //Vector r = *this->relCoordinate; /* return a copy, so it can't be modified */
151  return this->relCoordinate;
152}
153
154
155/**
156   \brief set relative coordinates
157   \param relCoord relative coordinates to its parent
158
159   it is very importand, that you use this function, if you want to update the
160   relCoordinates. If you don't use this, the PNode won't recognize, that something
161   has changed and won't update the children Nodes.
162*/
163void PNode::setRelCoor (Vector* relCoord)
164{
165  this->bRelCoorChanged = true;
166  *this->relCoordinate = *relCoord;
167}
168
169
170/**
171   \brief set relative coordinates
172   \param relCoord relative coordinates to its parent
173
174   it is very importand, that you use this function, if you want to update the
175   relCoordinates. If you don't use this, the PNode won't recognize, that something
176   has changed and won't update the children Nodes.
177*/
178void PNode::setRelCoor (Vector relCoord)
179{
180  this->bRelCoorChanged = true;
181  *this->relCoordinate = relCoord;
182}
183
184
185/**
186   \brief get absolute coordinates
187   \returns absolute coordinates from (0,0,0)
188*/
189Vector PNode::getAbsCoor ()
190{
191  return *this->absCoordinate;
192}
193
194
195/**
196   \param absCoord set absolute coordinate
197
198   it is very importand, that you use this function, if you want to update the
199   absCoordinates. If you don't use this, the PNode won't recognize, that something
200   has changed and won't update the children Nodes.
201*/
202void PNode::setAbsCoor (Vector* absCoord)
203{
204  this->bAbsCoorChanged = true;
205  *this->absCoordinate = *absCoord;
206}
207
208
209
210/**
211   \param absCoord set absolute coordinate
212
213   it is very importand, that you use this function, if you want to update the
214   absCoordinates. If you don't use this, the PNode won't recognize, that something
215   has changed and won't update the children Nodes.
216*/
217void PNode::setAbsCoor (Vector absCoord)
218{
219  this->bAbsCoorChanged = true;
220  *this->absCoordinate = absCoord;
221}
222
223
224/**
225   \brief shift coordinate (abs and rel)
226   \param shift vector
227
228   this function shifts the current coordinates about the vector shift. this is
229   usefull because from some place else you can:
230   PNode* someNode = ...;
231   Vector objectMovement = calculateShift();
232   someNode->shiftCoor(objectMovement);
233
234   elsewhere you would have to:
235   PNode* someNode = ...;
236   Vector objectMovement = calculateShift();
237   Vector currentCoor = someNode->getRelCoor();
238   Vector newCoor = currentCoor + objectMovement;
239   someNode->setRelCoor(newCoor);
240   
241   yea right... shorter...
242
243*/
244void PNode::shiftCoor (Vector* shift)
245{
246  if( this->bAbsCoorChanged)
247    {
248      *this->absCoordinate = *this->absCoordinate + *shift;
249    }
250  else 
251    {
252      *this->relCoordinate = *this->relCoordinate + *shift;
253      this->bRelCoorChanged = true;
254    }
255}
256
257
258
259/**
260   \brief shift coordinate (abs and rel)
261   \param shift vector
262
263   this function shifts the current coordinates about the vector shift. this is
264   usefull because from some place else you can:
265   PNode* someNode = ...;
266   Vector objectMovement = calculateShift();
267   someNode->shiftCoor(objectMovement);
268
269   elsewhere you would have to:
270   PNode* someNode = ...;
271   Vector objectMovement = calculateShift();
272   Vector currentCoor = someNode->getRelCoor();
273   Vector newCoor = currentCoor + objectMovement;
274   someNode->setRelCoor(newCoor);
275   
276   yea right... shorter...
277
278*/
279void PNode::shiftCoor (Vector shift)
280{
281  if( this->bAbsCoorChanged)
282    {
283      *this->absCoordinate = *this->absCoordinate + shift;
284    }
285  else 
286    {
287      *this->relCoordinate = *this->relCoordinate + shift;
288      this->bRelCoorChanged = true;
289    }
290}
291
292
293
294/**
295   \brief get relative direction
296   \returns relative direction to its parent
297*/
298Quaternion PNode::getRelDir ()
299{
300  return *this->relDirection;
301}
302
303
304/**
305   \brief set relative direction
306   \param relDir to its parent
307
308   it is very importand, that you use this function, if you want to update the
309   relDirection. If you don't use this, the PNode won't recognize, that something
310   has changed and won't update the children Nodes.
311*/
312void PNode::setRelDir (Quaternion* relDir)
313{
314  this->bRelCoorChanged = true;
315  *this->relDirection = *relDir;
316}
317
318
319void PNode::setRelDir (Quaternion relDir)
320{
321  this->bRelCoorChanged = true;
322  *this->relDirection = relDir;
323}
324
325
326/**
327   \brief gets the absolute direction (0,0,1)
328   \returns absolute coordinates
329*/
330Quaternion PNode::getAbsDir ()
331{
332  return *this->absDirection;
333}
334
335
336/**
337   \brief sets the absolute direction (0,0,1)
338   \param absDir absolute coordinates
339
340   it is very importand, that you use this function, if you want to update the
341   absDirection. If you don't use this, the PNode won't recognize, that something
342   has changed and won't update the children Nodes.
343*/
344void PNode::setAbsDir (Quaternion* absDir)
345{
346  this->bAbsDirChanged = true;
347  *this->absDirection = *absDir;
348}
349
350
351
352/**
353   \brief sets the absolute direction (0,0,1)
354   \param absDir absolute coordinates
355
356   it is very importand, that you use this function, if you want to update the
357   absDirection. If you don't use this, the PNode won't recognize, that something
358   has changed and won't update the children Nodes.
359*/
360void PNode::setAbsDir (Quaternion absDir)
361{
362  this->bAbsDirChanged = true;
363  *this->absDirection = absDir;
364}
365
366
367
368/**
369   \brief shift coordinate (abs and rel)
370   \param shift vector
371
372   this function shifts the current coordinates about the vector shift. this is
373   usefull because from some place else you can:
374   PNode* someNode = ...;
375   Quaternion objectMovement = calculateShift();
376   someNode->shiftCoor(objectMovement);
377
378   elsewhere you would have to:
379   PNode* someNode = ...;
380   Quaternion objectMovement = calculateShift();
381   Quaternion currentCoor = someNode->getRelCoor();
382   Quaternion newCoor = currentCoor + objectMovement;
383   someNode->setRelCoor(newCoor);
384   
385   yea right... shorter...
386
387   \todo implement this
388*/
389void PNode::shiftDir (Quaternion* shift)
390{}
391
392
393/**
394   \brief shift coordinate (abs and rel)
395   \param shift vector
396
397   this function shifts the current coordinates about the vector shift. this is
398   usefull because from some place else you can:
399   PNode* someNode = ...;
400   Quaternion objectMovement = calculateShift();
401   someNode->shiftCoor(objectMovement);
402
403   elsewhere you would have to:
404   PNode* someNode = ...;
405   Quaternion objectMovement = calculateShift();
406   Quaternion currentCoor = someNode->getRelCoor();
407   Quaternion newCoor = currentCoor + objectMovement;
408   someNode->setRelCoor(newCoor);
409   
410   yea right... shorter...
411
412   \todo implement this
413*/
414void PNode::shiftDir (Quaternion shift)
415{}
416
417
418/**
419   \brief this calculates the current movement speed of the node
420*/
421float PNode::getSpeed()
422{
423  if(this->time == 0)
424    return 1000;
425  Vector diff;
426  diff = *this->absCoordinate - *this->lastAbsCoordinate;
427  float x = diff.len();
428  return x / this->time;
429}
430
431
432/**
433   \brief adds a child and makes this node to a parent
434   \param pNode child reference
435
436   use this to add a child to this node.
437*/
438void PNode::addChild (PNode* pNode)
439{
440  this->addChild(pNode, DEFAULT_MODE);
441}
442
443
444/**
445   \brief adds a child and makes this node to a parent
446   \param pNode child reference
447   \param mode on which changes the child should also change ist state
448
449   use this to add a child to this node.
450*/
451void PNode::addChild (PNode* pNode, int parentingMode)
452{
453  if( pNode->parent != NULL )
454    {
455      PRINTF(3)("PNode::addChild() - reparenting node: removing it and adding it again\n");
456      pNode->parent->children->remove(pNode);
457    }
458  pNode->mode = parentingMode;
459  pNode->parent = this;
460  this->children->add(pNode);
461}
462
463
464/**
465   \brief removes a child from the node
466   \param pNode the child to remove from this pNode.
467
468   Children from pNode will not be lost, they are referenced to NullPointer
469*/
470void PNode::removeChild (PNode* pNode)
471{
472  pNode->remove();
473  this->children->remove (pNode);
474  pNode->parent = NULL;
475}
476
477
478/**
479   \brief remove this pnode from the tree and adds all following to NullParent
480
481   this can be the case, if an entity in the world is been destroyed.
482*/
483void PNode::remove()
484{
485  NullParent* nullParent = NullParent::getInstance();
486
487  tIterator<PNode>* iterator = this->children->getIterator();
488  PNode* pn = iterator->nextElement();
489 
490  while( pn != NULL) 
491    { 
492      //this->children->remove(pn);
493      nullParent->addChild(pn, pn->getMode());
494      pn = iterator->nextElement();
495    }
496  delete iterator;
497  this->parent->children->remove(this);
498}
499
500
501/**
502   \brief sets the parent of this PNode
503   \param parent the Parent to set
504*/
505void PNode::setParent (PNode* parent)
506{
507  parent->addChild(this);
508}
509
510
511/**
512   \brief set the mode of this parent manualy
513   \param mode the mode of the bind-type.
514*/
515void PNode::setMode (int parentingMode)
516{
517  this->mode = parentingMode;
518}
519
520
521/**
522   \brief gets the mode of this parent manualy
523   \return the mode of the bind-type.
524*/
525int PNode::getMode()
526{
527  return this->mode;
528}
529
530/**
531   \brief has to be called, if the parent coordinate has changed
532   
533   normaly this will be done by the parent itself automaticaly. If you call this, you
534   will force an update of the coordinated of the node.
535*/
536void PNode::parentCoorChanged ()
537{
538  this->bRelCoorChanged = true;
539}
540
541
542/**
543   \brief has to be called, if the parent direction has changed
544   
545   normaly this will be done by the parent itself automaticaly. If you call this, you
546   will force an update of the direction of the node.
547*/
548void PNode::parentDirChanged ()
549{
550  this->bRelDirChanged = true;
551}
552
553
554/**
555   \brief updates the absCoordinate/absDirection
556   \param timeStamp The timestanp used for to look if calculations should be done
557
558   this is used to go through the parent-tree to update all the absolute coordinates
559   and directions. this update should be done by the engine, so you don't have to
560   worry, normaly...
561*/
562void PNode::update (float dt)
563{
564  *this->lastAbsCoordinate = *this->absCoordinate;
565  this->time = dt;
566  PRINTF(4)("PNode::update - %s - (%f, %f, %f)\n", this->objectName, this->absCoordinate->x, this->absCoordinate->y, this->absCoordinate->z);
567  // printf("%s", this->objectName);
568  if(this->mode & PNODE_MOVEMENT )
569    {
570      if( this->bAbsCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
571        {
572          /* if you have set the absolute coordinates this overrides all other changes */
573          *this->relCoordinate = *this->absCoordinate - parent->getAbsCoor ();
574        }
575      else if( this->bRelCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
576        {
577          /*this is bad style... must be deleted later - just for testing*/
578          if( this->parent == NULL)
579            {
580              *this->absCoordinate = *this->relCoordinate;
581            }
582          else
583            *this->absCoordinate = parent->getAbsCoor() + *this->relCoordinate;       /* update the current absCoordinate */
584        }
585    }
586 
587  if( this->mode & PNODE_LOCAL_ROTATE)
588    {
589      if( this->bAbsDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
590        {
591          /* if you have set the absolute coordinates this overrides all other changes */
592          *this->relDirection = *this->absDirection - parent->getAbsDir();
593        }
594      else if( this->bRelDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
595        {
596          /* update the current absDirection - remember * means rotation around sth.*/
597          *this->absDirection = parent->getAbsDir() * *this->relDirection;
598        }
599    }
600 
601  if( this->mode & PNODE_ROTATE_MOVEMENT)
602    {
603      if( this->bAbsCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
604        {
605          /* if you have set the absolute coordinates this overrides all other changes */
606          *this->relCoordinate = *this->absCoordinate - parent->getAbsCoor ();
607        }
608      else if( this->bRelCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
609        {
610          /*this is bad style... must be deleted later - just for testing*/
611          if( this->parent == NULL)
612            *this->absCoordinate = *this->relCoordinate;
613          else
614            *this->absCoordinate = parent->getAbsCoor() + parent->getAbsDir().apply(*this->relCoordinate);            /* update the current absCoordinate */
615        }
616    }
617 
618 
619  tIterator<PNode>* iterator = this->children->getIterator();
620  //PNode* pn = this->children->enumerate();
621  PNode* pn = iterator->nextElement();
622  while( pn != NULL) 
623    { 
624      /* if this node has changed, make sure, that all children are updated also */
625      if( this->bRelCoorChanged || this->bAbsCoorChanged)
626        pn->parentCoorChanged ();
627      if( this->bRelDirChanged || this->bAbsDirChanged)
628        pn->parentDirChanged ();
629
630      pn->update(dt);
631      //pn = this->children->nextElement();
632      pn = iterator->nextElement();
633    }
634  delete iterator;
635
636  this->timeStamp = timeStamp;
637  this->bRelCoorChanged = false;
638  this->bAbsCoorChanged = false;
639  this->bRelDirChanged = false;
640  this->bAbsDirChanged = false;
641}
642
643
644/**
645  \brief tick
646  \param dt time to tick
647*/
648void PNode::processTick (float dt)
649{
650  //this->tick (dt);
651  PNode* pn = this->children->enumerate();
652  while( pn != NULL) 
653    { 
654      pn->processTick (dt);
655      pn = this->children->nextElement();
656    } 
657}
658
659
660/**
661   \brief displays some information about this pNode
662*/
663void PNode::debug()
664{
665  PRINTF(2)("PNode::debug() - absCoord: (%f, %f, %f)\n", 
666         this->absCoordinate->x, 
667         this->absCoordinate->y,
668         this->absCoordinate->z);
669}
670
671
672/**
673  \brief set the name of the node
674
675  for debug purposes realy usefull, not used to work properly
676*/
677void PNode::setName (char* newName)
678{
679  this->objectName = new char[strlen(newName)+1];
680  strcpy(this->objectName,newName);
681}
682
683
684/**
685  \brief gets the name of the node
686*/
687char* PNode::getName ()
688{
689  return this->objectName;
690}
691
Note: See TracBrowser for help on using the repository browser.