Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: baseObject now implements loading of objectNames

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