Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches: added branche trackManager.

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