Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: glmenu progressbar corrected, pnode modifications

File size: 14.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 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 get relative direction
261   \returns relative direction to its parent
262*/
263Quaternion PNode::getRelDir ()
264{
265  return *this->relDirection;
266}
267
268
269/**
270   \brief set relative direction
271   \param relDir to its parent
272
273   it is very importand, that you use this function, if you want to update the
274   relDirection. If you don't use this, the PNode won't recognize, that something
275   has changed and won't update the children Nodes.
276*/
277void PNode::setRelDir (Quaternion* relDir)
278{
279  this->bRelCoorChanged = true;
280  *this->relDirection = *relDir;
281}
282
283
284void PNode::setRelDir (Quaternion relDir)
285{
286  this->bRelCoorChanged = true;
287  *this->relDirection = relDir;
288}
289
290
291/**
292   \brief gets the absolute direction (0,0,1)
293   \returns absolute coordinates
294*/
295Quaternion PNode::getAbsDir ()
296{
297  return *this->absDirection;
298}
299
300
301/**
302   \brief sets the absolute direction (0,0,1)
303   \param absDir absolute coordinates
304
305   it is very importand, that you use this function, if you want to update the
306   absDirection. If you don't use this, the PNode won't recognize, that something
307   has changed and won't update the children Nodes.
308*/
309void PNode::setAbsDir (Quaternion* absDir)
310{
311  this->bAbsDirChanged = true;
312  *this->absDirection = *absDir;
313}
314
315
316
317/**
318   \brief sets the absolute direction (0,0,1)
319   \param absDir absolute coordinates
320
321   it is very importand, that you use this function, if you want to update the
322   absDirection. If you don't use this, the PNode won't recognize, that something
323   has changed and won't update the children Nodes.
324*/
325void PNode::setAbsDir (Quaternion absDir)
326{
327  this->bAbsDirChanged = true;
328  *this->absDirection = absDir;
329}
330
331
332
333/**
334   \brief shift coordinate (abs and rel)
335   \param shift vector
336
337   this function shifts the current coordinates about the vector shift. this is
338   usefull because from some place else you can:
339   PNode* someNode = ...;
340   Quaternion objectMovement = calculateShift();
341   someNode->shiftCoor(objectMovement);
342
343   elsewhere you would have to:
344   PNode* someNode = ...;
345   Quaternion objectMovement = calculateShift();
346   Quaternion currentCoor = someNode->getRelCoor();
347   Quaternion newCoor = currentCoor + objectMovement;
348   someNode->setRelCoor(newCoor);
349   
350   yea right... shorter...
351
352   \todo implement this
353*/
354void PNode::shiftDir (Quaternion* shift)
355{}
356
357
358/**
359   \brief this calculates the current movement speed of the node
360*/
361float PNode::getSpeed()
362{
363  if(this->time == 0)
364    return 0;
365  Vector* diff = new Vector();
366  *diff = *this->absCoordinate - *this->lastAbsCoordinate;
367  float x = diff->len();
368  return x / this->time;
369}
370
371
372/**
373   \brief adds a child and makes this node to a parent
374   \param pNode child reference
375
376   use this to add a child to this node.
377*/
378void PNode::addChild (PNode* pNode)
379{
380  this->addChild(pNode, DEFAULT_MODE);
381}
382
383
384/**
385   \brief adds a child and makes this node to a parent
386   \param pNode child reference
387   \param mode on which changes the child should also change ist state
388
389   use this to add a child to this node.
390*/
391void PNode::addChild (PNode* pNode, int parentingMode)
392{
393  if( pNode->parent != NULL )
394    {
395      PRINTF(3)("PNode::addChild() - reparenting node: removing it and adding it again\n");
396      pNode->parent->children->remove(pNode);
397    }
398  pNode->mode = parentingMode;
399  pNode->parent = this;
400  this->children->add(pNode);
401}
402
403
404/**
405   \brief removes a child from the node
406   \param pNode the child to remove from this pNode.
407
408   Children from pNode will not be lost, they are referenced to NullPointer
409*/
410void PNode::removeChild (PNode* pNode)
411{
412  pNode->remove();
413  this->children->remove (pNode);
414  pNode->parent = NULL;
415}
416
417
418/**
419   \brief remove this pnode from the tree and adds all following to NullParent
420
421   this can be the case, if an entity in the world is been destroyed.
422*/
423void PNode::remove()
424{
425  NullParent* nullParent = NullParent::getInstance();
426
427  tIterator<PNode>* iterator = this->children->getIterator();
428  PNode* pn = iterator->nextElement();
429 
430  while( pn != NULL) 
431    { 
432      //this->children->remove(pn);
433      nullParent->addChild(pn, pn->getMode());
434      pn = iterator->nextElement();
435    }
436  delete iterator;
437  this->parent->children->remove(this);
438}
439
440
441/**
442   \brief sets the parent of this PNode
443   \param parent the Parent to set
444*/
445void PNode::setParent (PNode* parent)
446{
447  parent->addChild(this);
448}
449
450
451/**
452   \brief set the mode of this parent manualy
453   \param mode the mode of the bind-type.
454*/
455void PNode::setMode (int parentingMode)
456{
457  this->mode = parentingMode;
458}
459
460
461/**
462   \brief gets the mode of this parent manualy
463   \return the mode of the bind-type.
464*/
465int PNode::getMode()
466{
467  return this->mode;
468}
469
470/**
471   \brief has to be called, if the parent coordinate has changed
472   
473   normaly this will be done by the parent itself automaticaly. If you call this, you
474   will force an update of the coordinated of the node.
475*/
476void PNode::parentCoorChanged ()
477{
478  this->bRelCoorChanged = true;
479}
480
481
482/**
483   \brief has to be called, if the parent direction has changed
484   
485   normaly this will be done by the parent itself automaticaly. If you call this, you
486   will force an update of the direction of the node.
487*/
488void PNode::parentDirChanged ()
489{
490  this->bRelDirChanged = true;
491}
492
493
494/**
495   \brief updates the absCoordinate/absDirection
496   \param timeStamp The timestanp used for to look if calculations should be done
497
498   this is used to go through the parent-tree to update all the absolute coordinates
499   and directions. this update should be done by the engine, so you don't have to
500   worry, normaly...
501*/
502void PNode::update (float dt)
503{
504  this->time = dt;
505  PRINTF(4)("PNode::update - %s - (%f, %f, %f)\n", this->objectName, this->absCoordinate->x, this->absCoordinate->y, this->absCoordinate->z);
506  // printf("%s", this->objectName);
507  if(this->mode & PNODE_MOVEMENT )
508    {
509      if( this->bAbsCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
510        {
511          /* if you have set the absolute coordinates this overrides all other changes */
512          *this->relCoordinate = *this->absCoordinate - parent->getAbsCoor ();
513        }
514      else if( this->bRelCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
515        {
516          /*this is bad style... must be deleted later - just for testing*/
517          if( this->parent == NULL)
518            {
519              *this->absCoordinate = *this->relCoordinate;
520            }
521          else
522            *this->absCoordinate = parent->getAbsCoor() + *this->relCoordinate;       /* update the current absCoordinate */
523        }
524    }
525 
526  if( this->mode & PNODE_LOCAL_ROTATE)
527    {
528      if( this->bAbsDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
529        {
530          /* if you have set the absolute coordinates this overrides all other changes */
531          *this->relDirection = *this->absDirection - parent->getAbsDir();
532        }
533      else if( this->bRelDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
534        {
535          /* update the current absDirection - remember * means rotation around sth.*/
536          *this->absDirection = parent->getAbsDir() * *this->relDirection;
537        }
538    }
539 
540  if( this->mode & PNODE_ROTATE_MOVEMENT)
541    {
542      if( this->bAbsCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
543        {
544          /* if you have set the absolute coordinates this overrides all other changes */
545          *this->relCoordinate = *this->absCoordinate - parent->getAbsCoor ();
546        }
547      else if( this->bRelCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
548        {
549          /*this is bad style... must be deleted later - just for testing*/
550          if( this->parent == NULL)
551            *this->absCoordinate = *this->relCoordinate;
552          else
553            *this->absCoordinate = parent->getAbsCoor() + parent->getAbsDir().apply(*this->relCoordinate);            /* update the current absCoordinate */
554        }
555    }
556 
557 
558  tIterator<PNode>* iterator = this->children->getIterator();
559  //PNode* pn = this->children->enumerate();
560  PNode* pn = iterator->nextElement();
561  while( pn != NULL) 
562    { 
563      /* if this node has changed, make sure, that all children are updated also */
564      if( this->bRelCoorChanged || this->bAbsCoorChanged)
565        pn->parentCoorChanged ();
566      if( this->bRelDirChanged || this->bAbsDirChanged)
567        pn->parentDirChanged ();
568
569      pn->update(dt);
570      //pn = this->children->nextElement();
571      pn = iterator->nextElement();
572    }
573  delete iterator;
574
575  this->timeStamp = timeStamp;
576  this->bRelCoorChanged = false;
577  this->bAbsCoorChanged = false;
578  this->bRelDirChanged = false;
579  this->bAbsDirChanged = false;
580}
581
582
583/**
584  \brief tick
585  \param dt time to tick
586*/
587void PNode::processTick (float dt)
588{
589  //this->tick (dt);
590  PNode* pn = this->children->enumerate();
591  while( pn != NULL) 
592    { 
593      pn->processTick (dt);
594      pn = this->children->nextElement();
595    } 
596}
597
598
599/**
600   \brief displays some information about this pNode
601*/
602void PNode::debug()
603{
604  PRINTF(2)("PNode::debug() - absCoord: (%f, %f, %f)\n", 
605         this->absCoordinate->x, 
606         this->absCoordinate->y,
607         this->absCoordinate->z);
608}
609
610
611/**
612  \brief set the name of the node
613
614  for debug purposes realy usefull, not used to work properly
615*/
616void PNode::setName (char* newName)
617{
618  this->objectName = new char[strlen(newName)+1];
619  strcpy(this->objectName,newName);
620}
621
622
623/**
624  \brief gets the name of the node
625*/
626char* PNode::getName ()
627{
628  return this->objectName;
629}
630
Note: See TracBrowser for help on using the repository browser.