Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: debug.h some cleanup

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