Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4152 was 4145, checked in by bensch, 20 years ago

orxonox/trunk: every world-entity saves the speed of its own

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