Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/parenting: :TrackManager: forking works.

File size: 12.8 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->isSavePoint = false;
32  this->isFork = false;
33  this->isJoined = false;
34  this->cond; //!< todo think!!
35  this->ID = -1;
36  this->startingTime = 0; //!< \todo eventually set this to the max time of TrackManager.
37  this->duration = 1;
38  this->curveType = BEZIERCURVE;
39  this->nodeCount = 0;
40  this->childCount = 0;
41  this->name = NULL;
42  this->startPoint = Vector(0,0,0);
43  this->startTangentPoint = Vector(0,0,0);
44  this->curve = NULL;
45  this->children = NULL;
46}
47
48/**
49    \brief destroys all alocated memory)
50    \todo eventually when deleting a TrackElement you would not like to delete all its preceding TrackElements
51*/
52TrackElement::~TrackElement(void)
53{
54  if (this->name)
55    delete []name;
56  if (this->curve)
57    delete this->curve;
58  if (this->childCount > 0)
59    {
60      for (int i=0; i < this->childCount; i++)
61        delete this->children[i];
62    }
63  if (children)
64    delete children;
65}
66
67/**
68   \brief Searches through all the TrackElements for trackID.
69   \param trackID The ID to search for.
70   \returns The TrackElement if Found, NULL otherwise.
71   
72   \todo make this more modular, to search for different things
73*/
74TrackElement* TrackElement::findByID(unsigned int trackID)
75{
76  // return if Found.
77  if (this->ID == trackID)
78    return this;
79  // search on.
80  if (this->childCount > 0)
81    for (int i=0; i < this->childCount; i++)
82      {
83        TrackElement* tmpElem;
84        if ((tmpElem = this->children[i]->findByID(trackID)))
85          return tmpElem;
86      }
87  else return NULL;
88}
89
90
91
92
93
94/////////////////////////////////////
95///// TRACKMANAGER //////////////////
96/////////////////////////////////////
97/**
98   \brief standard constructor
99
100*/
101TrackManager::TrackManager () 
102{
103  this->setClassName ("TrackManager");
104
105  PRINTF(3)("Initializing the TrackManager\n");
106  this->firstTrackElem = new TrackElement();
107  this->firstTrackElem->ID = 1;
108  this->currentTrackElem = firstTrackElem;
109  this->localTime = 0;
110  this->maxTime = 0;
111  this->trackElemCount = 1;
112}
113
114
115/**
116   \brief standard destructor
117
118*/
119TrackManager::~TrackManager () 
120{
121  PRINTF(3)("Destruct TrackManager\n");
122
123  PRINTF(3)("Deleting all the TrackElements\n");
124  delete this->firstTrackElem;
125
126  // we do not have a TrackManager anymore
127  singletonRef = NULL;
128}
129
130TrackManager* TrackManager::singletonRef = NULL;
131
132/**
133   \returns The reference on the TrackManager.
134
135   If the TrackManager does not exist, it will be created.
136*/
137TrackManager* TrackManager::getInstance(void) 
138{
139  if (singletonRef)
140    return singletonRef;
141  else
142    return singletonRef = new TrackManager();
143}
144
145/**
146   \brief reserves Space for childCount children
147   \param childCount The Count of children to make space for.
148*/
149void TrackManager::initChildren(unsigned int childCount)
150{
151  this->currentTrackElem->childCount = childCount;
152  this->currentTrackElem->children = new TrackElement*[childCount];
153  for (int i=0; i<childCount; i++)
154    {
155      this->currentTrackElem->children[i] = new TrackElement();
156      this->currentTrackElem->children[i]->ID = ++trackElemCount;
157      this->currentTrackElem->children[i]->startingTime = this->currentTrackElem->startingTime+this->currentTrackElem->duration;
158      this->currentTrackElem->children[i]->startPoint = this->currentTrackElem->curve->getNode(this->currentTrackElem->curve->getNodeCount());
159      this->currentTrackElem->children[i]->startTangentPoint = (this->currentTrackElem->children[i]->startPoint *2) - this->currentTrackElem->curve->getNode(this->currentTrackElem->curve->getNodeCount()-1);
160    }
161}
162
163/**
164   \brief Searches for a given trackID.
165   \param trackID the trackID to search for.
166   \returns The TrackElement #trackID if found, NULL otherwise.
167*/
168TrackElement* TrackManager::findTrackElementByID(unsigned int trackID) const
169{
170  return firstTrackElem->findByID(trackID);
171}
172
173// INITIALIZE //
174
175/**
176   \brief Sets the trackID we are working on.
177   \param trackID the trackID we are working on
178*/
179void TrackManager::workOn(unsigned int trackID)
180{
181  this->currentTrackElem = findTrackElementByID(trackID);
182}
183
184/**
185   \brief Sets the Type of the Curve
186   \brief curveType The Type to set
187*/
188void TrackManager::setCurveType(CurveType curveType)
189{
190  if (!this->currentTrackElem->isFresh)
191    {
192      PRINTF(2)("It is not possible to change the type of a Curve after you have have appended some points to it\n");
193      return;
194    }
195  this->currentTrackElem->curveType = curveType;
196  switch (curveType)
197    {
198    case BEZIERCURVE:
199      this->currentTrackElem->curve = new BezierCurve();
200      break;
201    case UPOINTCURVE:
202      this->currentTrackElem->curve = new UPointCurve();
203      break;
204    }
205}
206
207/**
208   \brief Sets the duration of the current path in seconds.
209   \param time The duration in seconds.
210*/
211
212void TrackManager::setDuration(float time)
213{
214  this->currentTrackElem->duration = time;
215}
216
217/**
218   \brief adds a point to the current TrackElement
219   \param newPoint The point to add.
220*/
221bool TrackManager::addPoint(Vector newPoint)
222{
223  if (this->currentTrackElem->isFresh)
224    {
225      this->setCurveType(BEZIERCURVE);
226      this->currentTrackElem->isFresh = false;
227      if(this->currentTrackElem != this->firstTrackElem)
228        {
229          this->addPoint(this->currentTrackElem->startPoint);
230          this->addPoint(this->currentTrackElem->startTangentPoint);
231        }
232    }
233  this->currentTrackElem->curve->addNode(newPoint);
234  this->currentTrackElem->nodeCount++;
235}
236
237/**
238   \brief adds save/splitpoint.
239   \param newPoint The point to add.
240   \returns A Pointer to a newly appended Curve
241*/
242int TrackManager::addHotPoint(Vector newPoint)
243{
244  if (this->currentTrackElem->isFresh)
245    {
246      this->setCurveType(BEZIERCURVE);
247      this->currentTrackElem->isFresh = false;
248    }
249
250  // \todo HotPoint Handling.
251  this->currentTrackElem->curve->addNode(newPoint);
252  this->currentTrackElem->nodeCount++;
253}
254
255/**
256   \brief Sets the last HotPoint into a savePoint.
257   \returns A Pointer to a newly appended Curve
258   
259   If no HotPoint was defined the last added Point will be rendered into a savePoint. \n
260   If the HotPoint was defined as a fork the Point will \b not be set into a savePoint.
261*/
262int TrackManager::setSavePoint(void)
263{
264  if (this->currentTrackElem->isFork || this->currentTrackElem->isSavePoint)
265    return this->currentTrackElem->children[1]->ID;
266  this->currentTrackElem->isSavePoint = true;
267
268  this->initChildren(1);
269  this->currentTrackElem = this->currentTrackElem->children[0];
270}
271
272/**
273   \brief adds some interessting non-linear movments through the level.
274   \param count The Count of childrens the current HotPoint will have.
275
276   If no HotPoint was defined the last added Point will be rendered into a fork. \n
277   If the HotPoint was defined as a savePoint the Point will \b not be set into a fork.
278*/
279void TrackManager::fork(unsigned int count, ...)
280{
281  int* trackIDs = new int[count];
282  this->forkV(count, trackIDs);
283  va_list ID;
284  va_start (ID, count);
285  for(int i = 0; i < count; i++)
286    {
287      *va_arg (ID, int*) = trackIDs[i];
288    }
289  va_end(ID); 
290  delete []trackIDs;
291}
292
293/**
294   \brief adds some interessting non-linear movments through the level.
295   \param count The Count of childrens the current HotPoint will have.
296   \param trackIDs A Pointer to an Array of ints which will hold the trackID's (the user will have to reserve space for this).
297
298   \see void TrackManager::fork(int count, ...)
299
300   \todo initialisation is wrong!! also in setSavePoint.
301*/
302void TrackManager::forkV(unsigned int count, int* trackIDs)
303{
304  if (this->currentTrackElem->isSavePoint)
305    return;
306  this->currentTrackElem->isFork = true;
307  for(int i = 0; i < count; i++)
308    trackIDs[i]=this->trackElemCount+1+i;
309  this->initChildren(count);
310}
311
312/**
313   \brief decides under what condition a certain Path will be chosen.
314   \param groupID the ID on which to choose the preceding move
315   \param cond \todo think about this
316*/
317void TrackManager::condition(unsigned int groupID, PathCondition cond)
318{
319 
320}
321
322/**
323   \brief joins some tracks together again.
324   \param count The count of Paths to join.
325
326   Join will set the localTime to the longest time a Path has to get to this Point. \n
327   Join will join all curves to the first curve.
328*/
329void TrackManager::join(unsigned int count, ...)
330{
331  int* trackIDs = new int [count];
332  va_list ID;
333  va_start (ID, count);
334  for(int i = 0; i < count; i++)
335    {
336      trackIDs[i] = va_arg (ID, int);
337    }
338  va_end(ID);
339  this->joinV(count, trackIDs);
340  delete []trackIDs;
341}
342
343/**
344   \brief joins some tracks together again.
345   \param count The count of Paths to join.
346   \param trackIDs an Array with the trackID's to join
347
348   \see void TrackManager::join(int count, ...)
349*/
350void TrackManager::joinV(unsigned int count, int* trackIDs)
351{
352  //! \todo this
353}
354
355// RUNTIME //
356
357/**
358   \brief calculates the Position for the localTime of the Track.
359   \returns the calculated Position
360*/
361Vector TrackManager::calcPos() const
362{
363  //  PRINTF(0)("TrackElement:%d, localTime: %f\n",this->currentTrackElem->ID, this->localTime);
364  return this->currentTrackElem->curve->calcPos((this->localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
365}
366
367/**
368   \brief calculates the Rotation for the localTime of the Track.
369   \returns the calculated Rotation
370*/
371Vector TrackManager::calcDir() const
372{
373  return this->currentTrackElem->curve->calcDir((this->localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
374}
375
376/**
377   \brief Advances the local-time of the Track around dt
378   \param dt The time about which to advance.
379
380   This function also checks, if the TrackElement has to be changed.
381*/
382void TrackManager::tick(float dt)
383{
384  if (this->localTime <= this->firstTrackElem->duration)
385    this->jumpTo(this->localTime);
386  this->localTime += dt;
387  if (this->localTime > this->currentTrackElem->startingTime + this->currentTrackElem->duration && this->currentTrackElem->childCount > 0)
388    this->currentTrackElem = this->currentTrackElem->children[0];
389}
390
391/**
392   \brief Jumps to a certain point on the Track.
393   \param time The time on the Track to jump to.
394
395   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.)
396   Max is trackLengthMax.
397*/
398void TrackManager::jumpTo(float time)
399{
400  if (time == 0)
401    this->currentTrackElem = this->firstTrackElem;
402  this->localTime = time;
403}
404
405/**
406   \brief a Function that decides which Path we should follow.
407   \param graphID The Path to choose.
408   
409*/
410void TrackManager::choosePath(int graphID)
411{
412
413}
414
415
416
417// DEBUG //
418
419/**
420   \brief Imports a model of the Graph into the OpenGL-environment.
421   \param dt The Iterator used in seconds for Painting the Graph.
422
423   This is for testing facility only. Do this if you want to see the Path inside the Level.
424   eventually this will all be packed into a gl-list.
425*/
426void TrackManager::drawGraph(float dt) const
427{
428  glBegin(GL_LINES);
429  for (int i = 1; i <= trackElemCount; i++)
430    {
431      TrackElement* tmpElem = this->findTrackElementByID(i);
432      printf("Element: %i\n", tmpElem->ID);
433      if (tmpElem->curve)
434        for(float f = 0.0; f < 1.0; f+=dt)
435          {
436            //      printf("%f, %f, %f\n",trackManager->calcPos().x, trackManager->calcPos().y, trackManager->calcPos().z);
437            Vector tmpVector = tmpElem->curve->calcPos(f);
438            glVertex3f(tmpVector.x, tmpVector.y, tmpVector.z);
439          }
440    }
441  glEnd();
442 
443 
444}
445
446void TrackManager::debug(unsigned int level) const
447{
448  printf("::CLASS TRACKMANAGER::debug information::\n");
449  //  printf("Status is: %
450  printf(" Consists of %d elements\n", this->trackElemCount);
451  printf(" localTime is: %f\n", this->localTime);
452  if (level >= 2)
453    {
454      for (int i = 1; i <= trackElemCount; i++)
455        {
456          TrackElement* tmpElem = this->findTrackElementByID(i);
457          printf("  ::TrackElement:%i::", tmpElem->ID);
458          if(tmpElem->name)
459            printf("name:%s::", tmpElem->name);
460          printf("\n   TimeTable: starting at = %f; ends at = %f; duration = %f\n", tmpElem->startingTime, tmpElem->startingTime+tmpElem->duration, tmpElem->duration);
461          printf("   consists of %d Points\n", tmpElem->nodeCount);
462
463          if(tmpElem->isFresh)
464            printf("   has not jet eddited in any way\n");
465          if(tmpElem->isSavePoint)
466            printf("   is a SavePoint\n");
467          if(tmpElem->isFork)
468            {
469              printf("   is A Fork with with %d children: ", tmpElem->childCount);
470              for(int i = 0; i < tmpElem->childCount; i++)
471                printf("=%d= ", tmpElem->children[i]->ID);
472              printf("\n");
473            }
474          if(tmpElem->isJoined)
475            printf("   is Joined at the End\n");
476
477                   
478        }
479    }
480}
Note: See TracBrowser for help on using the repository browser.