Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: updated debug.h: now possibility to log per module (compile-time)

  1. write in the cc-file at the beginnig !!BEFORE ANY INCLUDES!!

#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_[MODULENAME]
where [MODULNAME] is a name of a module that can be defined in debug.h

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