Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: stdincl was still included everywhere. removed it out of the stdincl.h file to enable the possibility of compile-speedup. added some testclasses for vector/quaternion.

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