Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/levelloader/src/lib/coord/p_node.cc @ 3605

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

orxonox/trunk: merged trunk back to levelloader
merged with command:
svn merge -r 3499:HEAD trunk branches/levelloader

Conflicts in
C track_manager.h
C world_entities/player.cc
C world_entities/player.h
C world_entities/environment.h
C lib/coord/p_node.cc
C defs/debug.h
C track_manager.cc
C story_entities/campaign.h

solved in merge-favouring. It was quite easy because Chris only worked on the headers, and he didi it quite clean. Thats the spirit :)

Conflits in world.cc are a MESS: fix it

File size: 12.5 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  this->objectName = NULL;
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  if( this->objectName) delete this->objectName;
80  /* there is currently a problem with cleaning up - fix*/
81
82  PNode* pn = this->children->enumerate();
83  while( pn != NULL) 
84    { 
85      delete pn;
86      pn = this->children->nextElement();
87
88    }
89   
90  /* this deletes all children in the list */
91  delete this->children;
92
93  delete []this->objectName;
94}
95
96void PNode::init(PNode* parent)
97{
98  this->children = new tList<PNode>();
99  this->bRelCoorChanged = true;
100  this->bAbsCoorChanged = false;
101  this->bRelDirChanged = true;
102  this->bAbsDirChanged = false;
103  this->parent = parent; 
104  this->objectName = NULL;
105}
106
107/**
108   \brief deletes the hole pnode tree
109
110   cleans up all pnodes
111*/
112/*
113void PNode::destroy ()
114{
115  PNode* pn = this->children->enumerate();
116  while( pn != NULL)
117    {
118      pn->destroy ();
119      pn = this->children->nextElement();
120    }
121  // this deletes all children in the list
122  this->children->destroy ();
123
124  static_cast<BaseObject*>(this)->destroy();
125}
126*/
127
128/**
129   \brief get relative coordinates
130   \returns relative coordinates to its parent
131*/
132Vector PNode::getRelCoor ()
133{
134  Vector r = this->relCoordinate; /* return a copy, so it can't be modified */
135  return r;
136}
137
138
139/**
140   \brief set relative coordinates
141   \param relCoord relative coordinates to its parent
142
143   it is very importand, that you use this function, if you want to update the
144   relCoordinates. If you don't use this, the PNode won't recognize, that something
145   has changed and won't update the children Nodes.
146*/
147void PNode::setRelCoor (Vector* relCoord)
148{
149  this->bRelCoorChanged = true;
150  this->relCoordinate = *relCoord;
151}
152
153
154/**
155   \brief get absolute coordinates
156   \returns absolute coordinates from (0,0,0)
157*/
158Vector PNode::getAbsCoor ()
159{
160  return this->absCoordinate;
161}
162
163
164/**
165   \param absCoord set absolute coordinate
166
167   it is very importand, that you use this function, if you want to update the
168   absCoordinates. If you don't use this, the PNode won't recognize, that something
169   has changed and won't update the children Nodes.
170*/
171void PNode::setAbsCoor (Vector* absCoord)
172{
173  this->bAbsCoorChanged = true;
174  this->absCoordinate = *absCoord;
175}
176
177
178/**
179   \brief shift coordinate (abs and rel)
180   \param shift vector
181
182   this function shifts the current coordinates about the vector shift. this is
183   usefull because from some place else you can:
184   PNode* someNode = ...;
185   Vector objectMovement = calculateShift();
186   someNode->shiftCoor(objectMovement);
187
188   elsewhere you would have to:
189   PNode* someNode = ...;
190   Vector objectMovement = calculateShift();
191   Vector currentCoor = someNode->getRelCoor();
192   Vector newCoor = currentCoor + objectMovement;
193   someNode->setRelCoor(newCoor);
194   
195   yea right... shorter...
196
197*/
198void PNode::shiftCoor (Vector* shift)
199{
200  if( this->bAbsCoorChanged)
201    {
202      this->absCoordinate = this->absCoordinate + *shift;
203    }
204  else 
205    {
206      this->relCoordinate = this->relCoordinate + *shift;
207      this->bRelCoorChanged = true;
208    }
209}
210
211
212
213/**
214   \brief get relative direction
215   \returns relative direction to its parent
216*/
217Quaternion PNode::getRelDir ()
218{
219  return this->relDirection;
220}
221
222
223/**
224   \brief set relative direction
225   \param relDir to its parent
226
227   it is very importand, that you use this function, if you want to update the
228   relDirection. If you don't use this, the PNode won't recognize, that something
229   has changed and won't update the children Nodes.
230*/
231void PNode::setRelDir (Quaternion* relDir)
232{
233  this->bRelCoorChanged = true;
234  this->relDirection = *relDir;
235}
236
237
238/**
239   \brief gets the absolute direction (0,0,1)
240   \returns absolute coordinates
241*/
242Quaternion PNode::getAbsDir ()
243{
244  return this->absDirection;
245}
246
247
248/**
249   \brief sets the absolute direction (0,0,1)
250   \param absDir absolute coordinates
251
252   it is very importand, that you use this function, if you want to update the
253   absDirection. If you don't use this, the PNode won't recognize, that something
254   has changed and won't update the children Nodes.
255*/
256void PNode::setAbsDir (Quaternion* absDir)
257{
258  this->bAbsDirChanged = true;
259  this->absDirection = *absDir;
260}
261
262
263/**
264   \brief shift coordinate (abs and rel)
265   \param shift vector
266
267   this function shifts the current coordinates about the vector shift. this is
268   usefull because from some place else you can:
269   PNode* someNode = ...;
270   Quaternion objectMovement = calculateShift();
271   someNode->shiftCoor(objectMovement);
272
273   elsewhere you would have to:
274   PNode* someNode = ...;
275   Quaternion objectMovement = calculateShift();
276   Quaternion currentCoor = someNode->getRelCoor();
277   Quaternion newCoor = currentCoor + objectMovement;
278   someNode->setRelCoor(newCoor);
279   
280   yea right... shorter...
281
282   \todo implement this
283*/
284void PNode::shiftDir (Quaternion* shift)
285{}
286
287/**
288   \brief adds a child and makes this node to a parent
289   \param pNode child reference
290
291   use this to add a child to this node.
292*/
293void PNode::addChild (PNode* pNode)
294{
295  this->addChild(pNode, DEFAULT_MODE);
296}
297
298
299/**
300   \brief adds a child and makes this node to a parent
301   \param pNode child reference
302   \param mode on which changes the child should also change ist state
303
304   use this to add a child to this node.
305*/
306void PNode::addChild (PNode* pNode, int parentingMode)
307{
308  if( pNode->parent != NULL )
309    {
310      PRINTF(2)("PNode::addChild() - reparenting node: removing it and adding it again\n");
311      pNode->parent->children->remove(pNode);
312    }
313  pNode->mode = parentingMode;
314  pNode->parent = this;
315  this->children->add(pNode);
316}
317
318
319/**
320   \brief removes a child from the node
321   \param pNode the child to remove from this pNode.
322
323   Children from pNode will not be lost, they are referenced to NullPointer
324*/
325void PNode::removeChild (PNode* pNode)
326{
327  pNode->remove();
328  this->children->remove (pNode);
329  pNode->parent = NULL;
330}
331
332
333/**
334   \brief remove this pnode from the tree and adds all following to NullParent
335
336   this can be the case, if an entity in the world is been destroyed.
337*/
338void PNode::remove()
339{
340  NullParent* np = NullParent::getInstance();
341  PNode* pn = this->children->enumerate();
342  while( pn != NULL) 
343    { 
344      this->children->remove(pn);
345      np->addChild(pn, pn->getMode());
346      pn = this->children->nextElement();
347    }
348}
349
350
351/**
352   \brief sets the parent of this PNode
353   \param parent the Parent to set
354*/
355void PNode::setParent (PNode* parent)
356{
357  parent->addChild(this);
358}
359
360
361/**
362   \brief set the mode of this parent manualy
363   \param mode the mode of the bind-type.
364*/
365void PNode::setMode (int parentingMode)
366{
367  this->mode = parentingMode;
368}
369
370
371/**
372   \brief gets the mode of this parent manualy
373   \return the mode of the bind-type.
374*/
375int PNode::getMode()
376{
377  return this->mode;
378}
379
380/**
381   \brief has to be called, if the parent coordinate has changed
382   
383   normaly this will be done by the parent itself automaticaly. If you call this, you
384   will force an update of the coordinated of the node.
385*/
386void PNode::parentCoorChanged ()
387{
388  this->bRelCoorChanged = true;
389}
390
391
392/**
393   \brief has to be called, if the parent direction has changed
394   
395   normaly this will be done by the parent itself automaticaly. If you call this, you
396   will force an update of the direction of the node.
397*/
398void PNode::parentDirChanged ()
399{
400  this->bRelDirChanged = true;
401}
402
403
404/**
405   \brief updates the absCoordinate/absDirection
406   \param timeStamp The timestanp used for to look if calculations should be done
407
408   this is used to go through the parent-tree to update all the absolute coordinates
409   and directions. this update should be done by the engine, so you don't have to
410   worry, normaly...
411*/
412void PNode::update ()
413{
414  PRINTF(2)("PNode::update - %s - (%f, %f, %f)\n", this->objectName, this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
415  // printf("%s", this->objectName);
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        \todo Error free assignment of name by copying the string instead of keeping just the pointer
519       
520  for debug purposes realy usefull, not used to work properly
521*/
522void PNode::setName (const char* newName)
523{
524  if (this->objectName)
525    delete []this->objectName;
526  this->objectName = new char[strlen(newName)+1];
527  strcpy(this->objectName,newName);
528}
529
530
531/**
532  \brief gets the name of the node
533*/
534const char* PNode::getName ()
535{
536  return this->objectName;
537}
538
Note: See TracBrowser for help on using the repository browser.