Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged branches/particleEngine into the trunk, because of the new vector class
merged with command:
svn merge -r 3922:HEAD particleEngine/ ../trunk/

not merged src/story_entities/world.cc. will do this at a later time (do not forget)

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