Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/parenting/src/track_manager.cc @ 3354

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

orxonox/branches/parenting: :TrackManager: now better join is implemented

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