Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/trackManager/src/track_manager.cc @ 3373

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

orxonox/branches/trackManager: patched:
problem with timeTable solved
self-producing start ofChildren in initChildren.

File size: 16.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
18
19#include "track_manager.h"
20#include <stdarg.h>
21#include "p_node.h"
22
23using namespace std;
24
25/**
26   \brief initializes a TrackElement (sets the default values)
27*/
28TrackElement::TrackElement(void)
29{
30  this->isFresh = true;
31  this->isHotPoint = false;
32  this->isSavePoint = false;
33  this->isFork = false;
34  this->isJoined = false;
35  this->mainJoin = false;
36  this->cond; //!< todo think!!
37  this->ID = -1;
38  this->startingTime = 0; //!< \todo eventually set this to the max time of TrackManager.
39  this->duration = 1;
40  this->endTime = 1;
41  this->jumpTime = 0;
42  this->curveType = BEZIERCURVE;
43  this->nodeCount = 0;
44  this->childCount = 0;
45  this->name = NULL;
46  this->curve = NULL;
47  this->children = NULL;
48}
49
50/**
51    \brief destroys all alocated memory)
52    \todo eventually when deleting a TrackElement you would not like to delete all its preceding TrackElements
53*/
54TrackElement::~TrackElement(void)
55{
56  if (this->name)
57    delete []name;
58  if (this->curve)
59    delete this->curve;
60  if ((!this->isJoined &&this->childCount > 0) || (this->isJoined && this->mainJoin))
61    {
62      for (int i=0; i < this->childCount; i++)
63        delete this->children[i];
64      delete this->children;
65    }
66}
67
68/**
69   \brief Searches through all the TrackElements for trackID.
70   \param trackID The ID to search for.
71   \returns The TrackElement if Found, NULL otherwise.
72   
73   \todo make this more modular, to search for different things
74*/
75TrackElement* TrackElement::findByID(unsigned int trackID)
76{
77  // return if Found.
78  if (this->ID == trackID)
79    return this;
80  // search on.
81  if (this->childCount > 0)
82    for (int i=0; i < this->childCount; i++)
83      {
84        TrackElement* tmpElem;
85        if ((tmpElem = this->children[i]->findByID(trackID)))
86          return tmpElem;
87      }
88  else return NULL;
89}
90
91
92
93
94
95/////////////////////////////////////
96///// TRACKMANAGER //////////////////
97/////////////////////////////////////
98/**
99   \brief standard constructor
100
101*/
102TrackManager::TrackManager(void)
103{
104  this->setClassName ("TrackManager");
105
106  PRINTF(3)("Initializing the TrackManager\n");
107  this->firstTrackElem = new TrackElement();
108  this->firstTrackElem->ID = 1;
109  this->currentTrackElem = firstTrackElem;
110  this->localTime = 0;
111  this->maxTime = 0;
112  this->trackElemCount = 1;
113  this->bindSlave = NULL;
114}
115
116
117/**
118   \brief standard destructor
119
120*/
121TrackManager::~TrackManager(void)
122{
123  PRINTF(3)("Destruct TrackManager\n");
124
125  PRINTF(3)("Deleting all the TrackElements\n");
126  delete this->firstTrackElem;
127
128  // we do not have a TrackManager anymore
129  singletonRef = NULL;
130}
131
132TrackManager* TrackManager::singletonRef = NULL;
133
134/**
135   \returns The reference on the TrackManager.
136
137   If the TrackManager does not exist, it will be created.
138*/
139TrackManager* TrackManager::getInstance(void) 
140{
141  if (singletonRef)
142    return singletonRef;
143  else
144    return singletonRef = new TrackManager();
145}
146
147/**
148   \brief reserves Space for childCount children
149   \param childCount The Count of children to make space for.
150*/
151void TrackManager::initChildren(unsigned int childCount)
152{
153  this->currentTrackElem->childCount = childCount;
154  this->currentTrackElem->children = new TrackElement*[childCount];
155  for (int i=0; i<childCount; i++)
156    {
157      this->currentTrackElem->children[i] = new TrackElement();
158      this->currentTrackElem->children[i]->ID = ++trackElemCount;
159      this->currentTrackElem->children[i]->startingTime = this->currentTrackElem->endTime;
160      this->addPoint(this->currentTrackElem->curve->getNode(this->currentTrackElem->curve->getNodeCount()), this->currentTrackElem->children[i]);
161      this->addPoint((this->currentTrackElem->children[i]->curve->getNode(0) *2) - this->currentTrackElem->curve->getNode(this->currentTrackElem->curve->getNodeCount()-1),  this->currentTrackElem->children[i]);
162    }
163}
164
165/**
166   \brief Searches for a given trackID.
167   \param trackID the trackID to search for.
168   \returns The TrackElement #trackID if found, NULL otherwise.
169*/
170TrackElement* TrackManager::findTrackElementByID(unsigned int trackID) const
171{
172  return firstTrackElem->findByID(trackID);
173}
174
175// INITIALIZE //
176
177/**
178   \brief Sets the trackID we are working on.
179   \param trackID the trackID we are working on
180*/
181void TrackManager::workOn(unsigned int trackID)
182{
183  TrackElement* tmpElem = findTrackElementByID(trackID);
184  if (tmpElem)
185    this->currentTrackElem = tmpElem;
186  else
187    printf("TrackElement not Found, leaving unchanged\n");
188  printf("now Working on %d\n", this->currentTrackElem->ID);
189
190}
191
192/**
193   \brief Sets the Type of the Curve
194   \brief curveType The Type to set
195*/
196void TrackManager::setCurveType(CurveType curveType, TrackElement* trackElem)
197{
198  if (!trackElem->isFresh)
199    {
200      PRINTF(2)("It is not possible to change the type of a Curve after you have have appended some points to it\n");
201      return;
202    }
203  trackElem->curveType = curveType;
204  switch (curveType)
205    {
206    case BEZIERCURVE:
207      trackElem->curve = new BezierCurve();
208      break;
209    case UPOINTCURVE:
210      trackElem->curve = new UPointCurve();
211      break;
212    }
213}
214
215/**
216   \brief Sets the duration of the current path in seconds.
217   \param time The duration in seconds.
218*/
219
220void TrackManager::setDuration(float time)
221{
222  this->currentTrackElem->duration = time;
223  this->currentTrackElem->endTime = this->currentTrackElem->startingTime + time;
224}
225
226/**
227   \brief adds a point to the current TrackElement
228   \param newPoint The point to add.
229*/
230bool TrackManager::addPoint(Vector newPoint)
231{
232  return this->addPoint(newPoint, this->currentTrackElem);
233}
234
235/**
236   \brief adds a point to trackElem
237   \param newPoint The point to add.
238   \param trackElem The TrackElement to add the Point to
239*/
240bool TrackManager::addPoint(Vector newPoint, TrackElement* trackElem)
241{
242  if (trackElem->isFresh)
243    {
244      this->setCurveType(BEZIERCURVE, trackElem);
245      trackElem->isFresh = false;
246    }
247  trackElem->curve->addNode(newPoint);
248  trackElem->nodeCount++;
249}
250
251/**
252   \brief adds save/splitpoint.
253   \param newPoint The point to add.
254   \returns A Pointer to a newly appended Curve
255*/
256int TrackManager::addHotPoint(Vector newPoint)
257{
258  printf("setting up a HotPoint\n");
259  if (this->currentTrackElem->isFresh)
260    {
261      this->setCurveType(BEZIERCURVE);
262      this->currentTrackElem->isFresh = false;
263    }
264
265  // \todo HotPoint Handling.
266  this->currentTrackElem->curve->addNode(newPoint);
267  this->currentTrackElem->nodeCount++;
268  this->initChildren(1);
269  this->currentTrackElem = this->currentTrackElem->children[0];
270}
271
272/**
273   \brief Sets the last HotPoint into a savePoint.
274   \returns A Pointer to a newly appended Curve
275   
276   If no HotPoint was defined the last added Point will be rendered into a savePoint. \n
277   If the HotPoint was defined as a fork the Point will \b not be set into a savePoint.
278*/
279int TrackManager::setSavePoint(void)
280{
281  printf("setting up a SavePoint.\n");
282  if (this->currentTrackElem->isFork || this->currentTrackElem->isSavePoint)
283    return this->currentTrackElem->children[1]->ID;
284  this->currentTrackElem->isSavePoint = true;
285  this->currentTrackElem->isHotPoint = true;
286
287  this->initChildren(1);
288  this->currentTrackElem = this->currentTrackElem->children[0];
289}
290
291/**
292   \brief adds some interessting non-linear movments through the level.
293   \param count The Count of childrens the current HotPoint will have.
294
295   If no HotPoint was defined the last added Point will be rendered into a fork. \n
296   If the HotPoint was defined as a savePoint the Point will \b not be set into a fork.
297*/
298void TrackManager::fork(unsigned int count, ...)
299{
300  int* trackIDs = new int[count];
301  this->forkV(count, trackIDs);
302  va_list ID;
303  va_start (ID, count);
304  for(int i = 0; i < count; i++)
305    {
306      *va_arg (ID, int*) = trackIDs[i];
307    }
308  va_end(ID); 
309  delete []trackIDs;
310}
311
312/**
313   \brief adds some interessting non-linear movments through the level.
314   \param count The Count of childrens the current HotPoint will have.
315   \param trackIDs A Pointer to an Array of ints which will hold the trackID's (the user will have to reserve space for this).
316
317   \see void TrackManager::fork(int count, ...)
318
319   \todo initialisation is wrong!! also in setSavePoint.
320*/
321void TrackManager::forkV(unsigned int count, int* trackIDs)
322{
323  printf("Forking with %d children\n", count);
324  if (this->currentTrackElem->isSavePoint)
325    return;
326  this->currentTrackElem->isFork = true;
327  this->currentTrackElem->isHotPoint = true;
328  for(int i = 0; i < count; i++)
329    trackIDs[i]=this->trackElemCount+1+i;
330  this->initChildren(count);
331}
332
333/**
334   \brief decides under what condition a certain Path will be chosen.
335   \param groupID the ID on which to choose the preceding move
336   \param cond \todo think about this
337*/
338void TrackManager::condition(unsigned int groupID, PathCondition cond)
339{
340 
341}
342
343/**
344   \brief joins some tracks together again.
345   \param count The count of Paths to join.
346
347   Join will set the localTime to the longest time a Path has to get to this Point. \n
348   Join will join all curves to the first curve, meaning that all the tangents will be matched.
349*/
350void TrackManager::join(unsigned int count, ...)
351{
352  int* trackIDs = new int [count];
353  va_list ID;
354  va_start (ID, count);
355  for(int i = 0; i < count; i++)
356    {
357      trackIDs[i] = va_arg (ID, int);
358    }
359  va_end(ID);
360  this->joinV(count, trackIDs);
361  delete []trackIDs;
362}
363
364/**
365   \brief joins some tracks together again.
366   \param count The count of Paths to join.
367   \param trackIDs an Array with the trackID's to join
368
369   \see void TrackManager::join(int count, ...)
370*/
371void TrackManager::joinV(unsigned int count, int* trackIDs)
372{
373  printf("Joining %d tracks to Track %d\n", count, trackIDs[0]);
374
375  // chanching work-on to temporary value. going back at the end.
376  int tmpCurrentWorkingID = this->currentTrackElem->ID;
377  this->workOn(trackIDs[0]);
378  float tmpLatestTime = this->currentTrackElem->endTime;
379
380  TrackElement* firstJoint = this->currentTrackElem;
381  Vector tmpEndPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount());
382  Vector tmpTangentPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-1); 
383  firstJoint->isJoined = true;
384  firstJoint->mainJoin = true;
385  if(!firstJoint->isHotPoint)
386    this->setSavePoint();
387  // Timing:
388  for (int i = 0; i < count; i++)
389    {
390      TrackElement* tmpJoinElem = this->findTrackElementByID(trackIDs[i]);
391      if (tmpJoinElem->childCount == 0
392          && tmpJoinElem->endTime > tmpLatestTime)
393            tmpLatestTime = tmpJoinElem->endTime;
394    }
395  // Joining:
396  for (int i = 1; i < count; i++)
397    {
398      TrackElement* tmpJoinElem = this->findTrackElementByID(trackIDs[i]);
399      if (tmpJoinElem->childCount > 0)
400        printf("!!This Curve has children, and as such will not be joined!!\n You can try joining other childless TrackElements to this one!");
401      else
402        {
403          this->addPoint(tmpTangentPoint, tmpJoinElem);
404          this->addPoint(tmpEndPoint, tmpJoinElem);
405          tmpJoinElem->jumpTime = tmpLatestTime - tmpJoinElem->endTime;
406         
407          //Copying Joint-Info
408          tmpJoinElem->children = firstJoint->children;
409          tmpJoinElem->childCount = firstJoint->childCount;
410          tmpJoinElem->isSavePoint = firstJoint->isSavePoint;
411          tmpJoinElem->isFork = firstJoint->isFork;
412
413          tmpJoinElem->isJoined = true;
414        }
415    }
416  if(currentTrackElem->children)
417    for(int i = 0; i > currentTrackElem->childCount; i++)
418      currentTrackElem->children[i]->startingTime = tmpLatestTime;
419
420  // returning to the TrackElement we were working on.
421  this->workOn(tmpCurrentWorkingID);
422}
423
424// RUNTIME //
425
426/**
427   \brief calculates the Position for the localTime of the Track.
428   \returns the calculated Position
429*/
430Vector TrackManager::calcPos() const
431{
432  //  PRINTF(0)("TrackElement:%d, localTime: %f\n",this->currentTrackElem->ID, this->localTime);
433  return this->currentTrackElem->curve->calcPos((this->localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
434}
435
436/**
437   \brief calculates the Rotation for the localTime of the Track.
438   \returns the calculated Rotation
439*/
440Vector TrackManager::calcDir() const
441{
442  return this->currentTrackElem->curve->calcDir((this->localTime - this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
443}
444
445/**
446   \brief Advances the local-time of the Track around dt
447   \param dt The time about which to advance.
448
449   This function also checks, if the TrackElement has to be changed.
450*/
451void TrackManager::tick(float dt)
452{
453  dt /= 1000;
454  printf("CurrentTrackID: %d, LocalTime is: %f, timestep is: %f\n", this->currentTrackElem->ID, this->localTime, dt);
455  if (this->localTime <= this->firstTrackElem->duration)
456    this->jumpTo(this->localTime);
457  this->localTime += dt;
458  if (this->localTime > this->currentTrackElem->endTime
459      && this->currentTrackElem->children)
460    {
461      if (this->currentTrackElem->jumpTime > 0) 
462        this->jumpTo(this->localTime + this->currentTrackElem->jumpTime);
463      this->currentTrackElem = this->currentTrackElem->children[0];
464    }
465  if (this->bindSlave)
466    {
467      Vector tmp = this->calcPos();
468      Quaternion quat = Quaternion(this->calcDir(), Vector(0,1,0)); 
469      this->bindSlave->setAbsCoor(&tmp);
470      this->bindSlave->setAbsDir(&quat);
471    }
472}
473
474/**
475   \brief Jumps to a certain point on the Track.
476   \param time The time on the Track to jump to.
477
478   This should be used to Jump backwards on a Track, because moving forward means to change between the Path. (it then tries to choose the default.)
479   Max is trackLengthMax.
480*/
481void TrackManager::jumpTo(float time)
482{
483  if (time == 0)
484    this->currentTrackElem = this->firstTrackElem;
485  this->localTime = time;
486}
487
488/**
489   \brief a Function that decides which Path we should follow.
490   \param graphID The Path to choose.
491   
492*/
493void TrackManager::choosePath(int graphID)
494{
495
496}
497
498/**
499   \brief Sets the PNode, that should be moved along the Tack
500   \param bindSlave the PNode to set
501*/
502void TrackManager::setBindSlave(PNode* bindSlave)
503{
504  if (!this->bindSlave)
505    this->bindSlave = bindSlave;
506}
507
508
509// DEBUG //
510
511/**
512   \brief Imports a model of the Graph into the OpenGL-environment.
513   \param dt The Iterator used in seconds for Painting the Graph.
514
515   This is for testing facility only. Do this if you want to see the Path inside the Level.
516   eventually this will all be packed into a gl-list.
517*/
518void TrackManager::drawGraph(float dt) const
519{
520
521  for (int i = 1; i <= trackElemCount; i++)
522    {
523      glBegin(GL_LINE_STRIP);
524      TrackElement* tmpElem = this->findTrackElementByID(i);
525      if (tmpElem->curve)
526        for(float f = 0.0; f < 1.0; f+=dt)
527          {
528            //      printf("%f, %f, %f\n",trackManager->calcPos().x, trackManager->calcPos().y, trackManager->calcPos().z);
529            Vector tmpVector = tmpElem->curve->calcPos(f);
530            glVertex3f(tmpVector.x, tmpVector.y, tmpVector.z);
531          }
532  glEnd();
533    }
534}
535
536void TrackManager::debug(unsigned int level) const
537{
538  printf("::CLASS TRACKMANAGER::debug information::\n");
539  //  printf("Status is: %
540  printf(" Consists of %d elements\n", this->trackElemCount);
541  printf(" localTime is: %f\n", this->localTime);
542  if (level >= 2)
543    {
544      for (int i = 1; i <= trackElemCount; i++)
545        {
546          TrackElement* tmpElem = this->findTrackElementByID(i);
547          printf("  ::TrackElement:%i::", tmpElem->ID);
548          if(tmpElem->name)
549            printf("name:%s::", tmpElem->name);
550          if(tmpElem->isFresh)
551            printf("   has not jet eddited in any way\n");
552          printf("\n   TimeTable: startingTime=%f; endTime=%f; duration=%f; jumpTime=%f\n", tmpElem->startingTime, tmpElem->endTime, tmpElem->duration, tmpElem->jumpTime);
553          printf("   consists of %d Points\n", tmpElem->nodeCount);
554          if (tmpElem->childCount == 0)
555            printf("   has no child\n");           
556          else if (tmpElem->childCount == 1)
557            printf("   has 1 child: ==%d==\n", tmpElem->children[0]->ID);
558          else if (tmpElem->childCount > 1)
559            {
560              printf("   has %d children: ", tmpElem->childCount);
561              for(int i = 0; i < tmpElem->childCount; i++)
562                printf("=%d= ", tmpElem->children[i]->ID);
563              printf("\n");
564            }
565
566          if(tmpElem->isHotPoint)
567            printf("   is a special Point:\n");
568          if(tmpElem->isSavePoint)
569            printf("    is a SavePoint\n");
570          if(tmpElem->isFork)
571            {
572              printf("    is A Fork with with %d children.", tmpElem->childCount);
573            }
574          if(tmpElem->isJoined)
575            printf("   is Joined at the End\n");
576        }
577    }
578}
Note: See TracBrowser for help on using the repository browser.