Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3622 was 3617, checked in by bensch, 20 years ago

orxonox/trunk: little fix to graphicsEngine, now the different resolution-types are outputted. also there is a fix from debug.h all warnings are shown now

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