Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/track_manager.cc @ 3588

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

orxonox/trunk: name-fix for TrackManager and minor fix in Curve.
There has also been a little fix in the light-class: light is a BaseObject not a World-Entity

File size: 23.6 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16
17#include "track_manager.h"
18
19#include "p_node.h"
20
21#include "track_node.h"
22
23#include <stdarg.h>
24
25using namespace std;
26
27/**
28   \brief initializes a TrackElement (sets the default values)
29*/
30TrackElement::TrackElement(void)
31{
32  this->isFresh = true;
33  this->isHotPoint = false;
34  this->isSavePoint = false;
35  this->isFork = false;
36  this->isJoined = false;
37  this->mainJoin = false;
38  this->ID = -1;
39  this->startingTime = 0;
40  this->duration = TMAN_DEFAULT_DURATION;
41  this->endTime = 1;
42  this->jumpTime = 0;
43  this->nodeCount = 0;
44  this->childCount = 0;
45  this->name = NULL;
46  this->curve = NULL;
47  this->children = NULL;
48
49  this->history = NULL;
50
51  this->condFunc = &TrackElement::random;
52}
53
54/**
55    \brief destroys all alocated memory)
56    \todo eventually when deleting a TrackElement you would not like to delete all its preceding TrackElements
57*/
58TrackElement::~TrackElement(void)
59{
60  if (this->name)
61    delete []name;
62  if (this->curve)
63    delete this->curve;
64  if ((!this->isJoined &&this->childCount > 0) || (this->isJoined && this->mainJoin))
65    {
66      for (int i=0; i < this->childCount; i++)
67        delete this->children[i];
68      delete this->children;
69    }
70}
71
72/**
73   \brief Searches through all the TrackElements for trackID.
74   \param trackID The ID to search for.
75   \returns The TrackElement if Found, NULL otherwise.
76   
77   \todo make this more modular, to search for different things
78*/
79TrackElement* TrackElement::findByID(unsigned int trackID)
80{
81  // return if Found.
82  if (this->ID == trackID)
83    return this;
84  // search on.
85  if (this->childCount > 0)
86    for (int i=0; i < this->childCount; i++)
87      {
88        TrackElement* tmpElem;
89        if ((tmpElem = this->children[i]->findByID(trackID)))
90          return tmpElem;
91      }
92  else return NULL;
93}
94
95
96/**
97   \brief checks if there are any BackLoops in the Track
98   \param trackElem the trackElement to check about
99   it simply does this by looking if the current trackElem is found again somewhere else in the Track
100*/
101bool TrackElement::backLoopCheck(TrackElement* trackElem)
102{
103  if (this->childCount == 0)
104    return true;
105  else
106    {
107      for (int i = 0; i < this->childCount; i++)
108        if(!this->children[i]->backLoopCheck(trackElem))
109          return false;
110     
111      return true;
112    }
113}
114
115/**
116   \param name the Name to set.
117*/
118void TrackElement::setName(const char* name)
119{
120  //  delete the old name
121  if (this->name)
122    delete []this->name;
123  // if a name was given already.
124  if (name)
125    {
126      this->name = new char[strlen(name)+1];
127      strcpy(this->name, name);
128    }
129  else 
130    this->name = NULL;
131}
132
133/**
134   \returns The name of this TrackElement
135*/
136char* TrackElement::getName(void) const
137{
138  return this->name;
139}
140
141
142/**
143   \brief CONDITION that chooses the first child for the decision (static)
144   \param nothing Nothing in this function
145   \returns the chosen child
146*/
147int TrackElement::lowest(void* nothing)
148{
149  return 0;
150}
151
152/**
153   \brief CONDITION that chooses the last child for the decision (static)
154   \param nothing Nothing in this function
155   \returns the chosen child
156*/
157int TrackElement::highest(void* nothing)
158{ 
159  return this->childCount-1;
160}
161
162/**
163   \brief CONDITION that chooses a random child for the decision (static)
164   \param nothing Nothing in this function
165   \returns the chosen child
166*/
167int TrackElement::random(void* nothing)
168{
169  int i = (int)floor ((float)rand()/(float)RAND_MAX * (float)this->childCount);
170  if (i >= this->childCount)
171    return this->childCount-1;
172  else 
173    return i;
174}
175
176/**
177   \brief CONDITION that chooses child 0, if the node(probably Player)
178   is left of its parent (z<0)) and 1/right otherwise.
179   \param node The node to act upon.
180   \returns the chosen child
181*/
182int TrackElement::leftRight(void* node)
183{
184  PNode* tmpNode = (PNode*)node;
185
186  if (tmpNode->getRelCoor().z < 0)
187    return 0;
188  else 
189    return 1;
190}
191
192
193/**
194   \brief CONDITION that chooses the child, that has the nearest distance to the node (probably player).
195   \param node The node to act upon.
196   \returns the chosen child
197
198   This is rather dangerous, because one must carefully set the points on the curve.
199   The best Way is to set the nodes as wide away of each other as possible,
200   but take into consideration, that if the nodes are to far from a center node, the center will be chosen.
201   (play with this!!).
202*/
203int TrackElement::nearest(void* node)
204{
205  PNode* tmpNode = (PNode*)node;
206
207  Vector nodeRelCoord = tmpNode->getRelCoor();
208  float minDist = 100000000;
209  int nodeNumber = 0;
210  for (int i = 0; i < this->childCount; i++)
211    {
212      float dist = (nodeRelCoord - this->children[i]->curve->getNode(4)).len();
213      if (dist < minDist)
214        {
215          minDist = dist;
216          nodeNumber = i;
217        }
218    }
219  PRINTF(3)("PathDecision with nearest algorithm: %d\n", nodeNumber);
220  return nodeNumber;
221}
222
223
224
225/////////////////////////////////////
226///// TRACKMANAGER //////////////////
227/////////////////////////////////////
228/**
229   \brief standard constructor
230
231*/
232TrackManager::TrackManager(void)
233{
234  this->setClassName ("TrackManager");
235 
236  singletonRef = this;
237
238  PRINTF(3)("Initializing the TrackManager\n");
239  this->firstTrackElem = new TrackElement();
240  this->firstTrackElem->ID = 1;
241  this->currentTrackElem = firstTrackElem;
242  this->localTime = 0;
243  this->maxTime = 0;
244  this->trackElemCount = 1;
245  this->bindSlave = this->trackNode = new TrackNode();
246}
247
248
249/**
250   \brief standard destructor
251*/
252TrackManager::~TrackManager(void)
253{
254  PRINTF(3)("Destruct TrackManager\n");
255
256  PRINTF(3)("Deleting all the TrackElements\n");
257  delete this->firstTrackElem;
258
259  // we do not have a TrackManager anymore
260  singletonRef = NULL;
261}
262
263//! Singleton Reference to TrackManager
264TrackManager* TrackManager::singletonRef = NULL;
265
266/**
267   \returns The reference on the TrackManager.
268
269   If the TrackManager does not exist, it will be created.
270*/
271TrackManager* TrackManager::getInstance(void) 
272{
273  if (!singletonRef)
274    singletonRef = new TrackManager();
275  return singletonRef;
276}
277
278/**
279   \brief reserves Space for childCount children
280   \param childCount The Count of children to make space for.
281*/
282void TrackManager::initChildren(unsigned int childCount)
283{
284  this->currentTrackElem->childCount = childCount;
285  this->currentTrackElem->mainJoin = true;
286  this->currentTrackElem->children = new TrackElement*[childCount];
287  for (int i=0; i<childCount; i++)
288    {
289      this->currentTrackElem->children[i] = new TrackElement();
290      this->currentTrackElem->children[i]->ID = ++trackElemCount;
291      this->currentTrackElem->children[i]->startingTime = this->currentTrackElem->endTime + this->currentTrackElem->jumpTime;
292      this->addPoint(this->currentTrackElem->curve->getNode(this->currentTrackElem->curve->getNodeCount()), this->currentTrackElem->children[i]);
293    }
294  if (childCount == 1)
295    this->currentTrackElem->children[0]->setName(this->currentTrackElem->getName());
296}
297
298/**
299   \brief Searches for a given trackID.
300   \param trackID the trackID to search for.
301   \returns The TrackElement #trackID if found, NULL otherwise.
302*/
303TrackElement* TrackManager::findTrackElementByID(unsigned int trackID) const
304{
305  return firstTrackElem->findByID(trackID);
306}
307
308// INITIALIZE //
309
310/**
311   \brief Sets the trackID we are working on.
312   \param trackID the trackID we are working on
313*/
314void TrackManager::workOn(unsigned int trackID)
315{
316  TrackElement* tmpElem = findTrackElementByID(trackID);
317  if (tmpElem)
318    this->currentTrackElem = tmpElem;
319  else
320    printf("TrackElement not Found, leaving unchanged\n");
321  printf("now Working on %d\n", this->currentTrackElem->ID);
322
323}
324
325/**
326   \brief Sets the Type of the Curve
327   \param curveType The Type to set
328   \param trackElem the TrackElement that should get a new Curve.
329*/
330void TrackManager::setCurveType(CurveType curveType, TrackElement* trackElem)
331{
332  if (!trackElem->isFresh)
333    {
334      PRINTF(2)("It is not possible to change the type of a Curve after you have have appended some points to it\n");
335      return;
336    }
337  this->curveType = curveType;
338  switch (curveType)
339    {
340    case BEZIERCURVE:
341      trackElem->curve = new BezierCurve();
342      break;
343    case UPOINTCURVE:
344      trackElem->curve = new UPointCurve();
345      break;
346    }
347}
348
349/**
350   \brief Sets the duration of the current path in seconds.
351   \param time The duration in seconds.
352*/
353
354void TrackManager::setDuration(float time)
355{
356  this->currentTrackElem->duration = time;
357  this->currentTrackElem->endTime = this->currentTrackElem->startingTime + time;
358}
359
360/**
361   \brief adds a point to the current TrackElement
362   \param newPoint The point to add.
363*/
364bool TrackManager::addPoint(Vector newPoint)
365{
366  return this->addPoint(newPoint, this->currentTrackElem);
367}
368
369/**
370   \brief adds a point to trackElem
371   \param newPoint The point to add.
372   \param trackElem The TrackElement to add the Point to
373*/
374bool TrackManager::addPoint(Vector newPoint, TrackElement* trackElem)
375{
376  if (trackElem->isFresh)
377    {
378      this->setCurveType(TMAN_DEFAULT_CURVETYPE, trackElem);
379      trackElem->isFresh = false;
380    }
381  trackElem->curve->addNode(newPoint);
382  trackElem->nodeCount++;
383}
384
385/**
386   \brief adds save/splitpoint.
387   \param newPoint The point to add.
388   \returns A Pointer to a newly appended Curve
389*/
390int TrackManager::addHotPoint(Vector newPoint)
391{
392  printf("setting up a HotPoint\n");
393  if (this->currentTrackElem->isFresh)
394    {
395      this->setCurveType(BEZIERCURVE);
396      this->currentTrackElem->isFresh = false;
397    }
398
399  // \todo HotPoint Handling.
400  this->currentTrackElem->curve->addNode(newPoint);
401  this->currentTrackElem->nodeCount++;
402  this->initChildren(1);
403  this->currentTrackElem = this->currentTrackElem->children[0];
404}
405
406/**
407   \brief Sets the last HotPoint into a savePoint.
408   \returns A Pointer to a newly appended Curve
409   
410   If no HotPoint was defined the last added Point will be rendered into a savePoint. \n
411   If the HotPoint was defined as a fork the Point will \b not be set into a savePoint.
412*/
413int TrackManager::setSavePoint(void)
414{
415  printf("setting up a SavePoint.\n");
416  if (this->currentTrackElem->isFork || this->currentTrackElem->isSavePoint)
417    return this->currentTrackElem->children[1]->ID;
418  this->currentTrackElem->isSavePoint = true;
419  this->currentTrackElem->isHotPoint = true;
420
421  this->initChildren(1);
422  this->currentTrackElem = this->currentTrackElem->children[0];
423}
424
425/**
426   \brief adds some interessting non-linear movments through the level.
427   \param count The Count of childrens the current HotPoint will have.
428
429   If no HotPoint was defined the last added Point will be rendered into a fork. \n
430   If the HotPoint was defined as a savePoint the Point will \b not be set into a fork.
431*/
432void TrackManager::fork(unsigned int count, ...)
433{
434  int* trackIDs = new int[count];
435  this->forkV(count, trackIDs);
436  va_list ID;
437  va_start (ID, count);
438  for(int i = 0; i < count; i++)
439    {
440      *va_arg (ID, int*) = trackIDs[i];
441    }
442  va_end(ID); 
443  delete []trackIDs;
444}
445
446/**
447   \brief adds some interessting non-linear movments through the level.
448   \param count The Count of childrens the current HotPoint will have.
449   \param trackIDs A Pointer to an Array of ints which will hold the trackID's (the user will have to reserve space for this).
450
451   \see void TrackManager::fork(int count, ...)
452
453   \todo initialisation is wrong!! also in setSavePoint.
454*/
455void TrackManager::forkV(unsigned int count, int* trackIDs)
456{
457  printf("Forking with %d children\n", count);
458  if (this->currentTrackElem->isSavePoint)
459    return;
460  this->currentTrackElem->isFork = true;
461  this->currentTrackElem->isHotPoint = true;
462  for(int i = 0; i < count; i++)
463    trackIDs[i]=this->trackElemCount+1+i;
464  this->initChildren(count);
465}
466
467/**
468   \brief decides under what condition a certain Path will be chosen.
469   \param cond the CONDITION of the decision
470   \param subject the Subject that will be decided upon with CONDITION cond.
471*/
472void TrackManager::condition(CONDITION cond, void* subject)
473{
474  this->condition(this->currentTrackElem->ID, cond, subject);
475}
476/**
477   \brief decides under what condition a certain Path will be chosen.
478   \param groupID the ID on which to choose the preceding move
479   \param cond the CONDITION of the decision
480   \param subject the Subject that will be decided upon with CONDITION cond.
481*/
482void TrackManager::condition(unsigned int groupID, CONDITION cond, void* subject)
483{
484  TrackElement* tmpElem = this->findTrackElementByID(groupID);
485 
486  switch (cond)
487    {
488    case LOWEST:
489      tmpElem->condFunc = &TrackElement::lowest;
490      break;
491    case HIGHEST:
492      tmpElem->condFunc = &TrackElement::highest;
493      break;
494    case RANDOM: 
495      tmpElem->condFunc = &TrackElement::random;
496      break;
497    case LEFTRIGHT:
498      tmpElem->condFunc = &TrackElement::leftRight;
499      break;
500    case NEAREST:
501      tmpElem->condFunc = &TrackElement::nearest;
502      break;
503    case ENEMYKILLED:
504      break;
505    }
506  tmpElem->subject=subject;
507}
508
509
510/**
511   \brief joins some tracks together again.
512   \param count The count of Paths to join.
513
514   Join will set the localTime to the longest time a Path has to get to this Point. \n
515   Join will join all curves to the first curve, meaning that all the tangents will be matched.
516*/
517void TrackManager::join(unsigned int count, ...)
518{
519  int* trackIDs = new int [count];
520  va_list ID;
521  va_start (ID, count);
522  for(int i = 0; i < count; i++)
523    {
524      trackIDs[i] = va_arg (ID, int);
525    }
526  va_end(ID);
527  this->joinV(count, trackIDs);
528  delete []trackIDs;
529}
530
531/**
532   \brief joins some tracks together again.
533   \param count The count of Paths to join.
534   \param trackIDs an Array with the trackID's to join
535
536   \see void TrackManager::join(int count, ...)
537*/
538void TrackManager::joinV(unsigned int count, int* trackIDs)
539{
540  printf("Joining %d tracks and merging to Track %d\n", count, trackIDs[0]);
541
542  // checking if there is a back-loop-connection and ERROR if it is.
543  TrackElement* tmpTrackElem = this->findTrackElementByID(trackIDs[0]);
544  if (!tmpTrackElem->backLoopCheck(tmpTrackElem))
545    PRINTF(1)("Backloop connection detected at joining trackElements\n");
546
547  // chanching work-on to temporary value. going back at the end.
548  int tmpCurrentWorkingID = this->currentTrackElem->ID;
549  this->workOn(trackIDs[0]);
550  TrackElement* firstJoint = this->currentTrackElem;
551  float tmpLatestTime = firstJoint->endTime;
552
553  Vector tmpEndPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount());
554  Vector tmpTangentPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-1);
555  Vector tmpc2Point = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-2);
556  firstJoint->isJoined = true;
557  //  firstJoint->mainJoin = true;
558  if(!firstJoint->isHotPoint)
559    this->setSavePoint();
560  // Timing:
561  for (int i = 0; i < count; i++)
562    {
563      TrackElement* tmpJoinElem = this->findTrackElementByID(trackIDs[i]);
564      if (tmpJoinElem->childCount == 0
565          && tmpJoinElem->endTime > tmpLatestTime)
566        tmpLatestTime = tmpJoinElem->endTime;
567    }
568  // time the main Join.
569  firstJoint->jumpTime = tmpLatestTime - firstJoint->endTime;
570 
571  // Joining:
572  for (int i = 1; i < count; i++)
573    {
574      TrackElement* tmpJoinElem = this->findTrackElementByID(trackIDs[i]);
575      if (tmpJoinElem->childCount > 0)
576        printf("!!This Curve has children, and as such will not be joined!!\n You can try joining other childless TrackElements to this one!");
577      else
578        {
579          this->addPoint(tmpc2Point, tmpJoinElem);
580          this->addPoint(tmpTangentPoint, tmpJoinElem);
581          this->addPoint(tmpEndPoint, tmpJoinElem);
582          // time all other Joins
583          tmpJoinElem->jumpTime = tmpLatestTime - tmpJoinElem->endTime;
584         
585          //Copying Joint-Info
586          tmpJoinElem->children = firstJoint->children;
587          tmpJoinElem->childCount = firstJoint->childCount;
588          tmpJoinElem->isSavePoint = firstJoint->isSavePoint;
589          tmpJoinElem->isFork = firstJoint->isFork;
590
591          tmpJoinElem->isJoined = true;
592        }
593    }
594  if(firstJoint->childCount > 0)
595    for(int i = 0; i < firstJoint->childCount; i++)
596      {
597        printf("Setting startingTime of %d to %f.\n", firstJoint->children[i]->ID, tmpLatestTime);
598        firstJoint->children[i]->startingTime = tmpLatestTime;
599        firstJoint->children[i]->endTime = tmpLatestTime+firstJoint->children[i]->duration;
600      } 
601
602  // returning to the TrackElement we were working on.
603  this->workOn(tmpCurrentWorkingID);
604}
605
606/**
607   \brief finalizes the TrackSystem. after this it will not be editable anymore
608
609   \todo check for any inconsistencies, output errors
610*/
611void TrackManager::finalize(void)
612{
613  for (int i = 1; i<= trackElemCount ;i++)
614    {
615      TrackElement* tmpElem = findTrackElementByID(i);
616      if (tmpElem->childCount>0 && tmpElem->mainJoin)
617        {
618          for (int j = 0; j < tmpElem->childCount; j++)
619            {
620             
621              // c1-continuity
622              tmpElem->children[j]->curve->addNode(tmpElem->children[j]->curve->getNode(0) +
623                                                   ((tmpElem->children[j]->curve->getNode(0) - 
624                                                    tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-1))
625                                                    ),2);
626              tmpElem->children[j]->nodeCount++;
627              // c2-continuity
628              tmpElem->children[j]->curve->addNode((tmpElem->curve->getNode(tmpElem->curve->getNodeCount())-
629                                                    tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-1)) * 4 +
630                                                   tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-2), 3);
631              tmpElem->children[j]->nodeCount++;                                                   
632              printf("accelerations: %d-in: count: %d, %f, %f, %f\n                  %d-out: count: %d %f, %f, %f\n",
633                     tmpElem->ID, tmpElem->nodeCount,
634                     tmpElem->curve->calcAcc(0.999).x, tmpElem->curve->calcAcc(0.999).y, tmpElem->curve->calcAcc(0.999).z,
635                     tmpElem->children[j]->ID, tmpElem->children[j]->nodeCount,
636                     tmpElem->children[j]->curve->calcAcc(0).x, tmpElem->children[j]->curve->calcAcc(0).y, tmpElem->children[j]->curve->calcAcc(0).z);
637            }
638        }
639    }
640}
641
642
643// RUNTIME //
644
645/**
646   \brief calculates the Position for the localTime of the Track.
647   \returns the calculated Position
648*/
649Vector TrackManager::calcPos() const
650{
651  //  PRINTF(0)("TrackElement:%d, localTime: %f\n",this->currentTrackElem->ID, this->localTime);
652  return this->currentTrackElem->curve->calcPos((this->localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
653}
654
655/**
656   \brief calculates the Rotation for the localTime of the Track.
657   \returns the calculated Rotation
658*/
659Vector TrackManager::calcDir() const
660{
661  return this->currentTrackElem->curve->calcDir((this->localTime - this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
662}
663
664/**
665   \brief Advances the local-time of the Track around dt
666   \param dt The time about which to advance.
667
668   This function also checks, if the TrackElement has to be changed.
669*/
670void TrackManager::tick(float dt)
671{
672  dt /= 1000;
673  printf("CurrentTrackID: %d, LocalTime is: %f, timestep is: %f\n", this->currentTrackElem->ID, this->localTime, dt);
674  if (this->localTime <= this->firstTrackElem->duration)
675    this->jumpTo(this->localTime);
676  this->localTime += dt;
677  if (this->localTime > this->currentTrackElem->endTime
678      && this->currentTrackElem->children)
679    {
680      if (this->currentTrackElem->jumpTime != 0.0)
681        this->jumpTo(this->localTime + this->currentTrackElem->jumpTime);
682      // jump to the next TrackElement and also set the history of the new Element to the old one.
683      TrackElement* tmpHistoryElem = this->currentTrackElem;
684      this->currentTrackElem = this->currentTrackElem->children[this->choosePath(this->currentTrackElem)];
685      this->currentTrackElem->history = tmpHistoryElem;
686    }
687  if (this->bindSlave)
688    {
689      Vector tmp = this->calcPos();
690      Quaternion quat = Quaternion(this->calcDir(), Vector(this->currentTrackElem->curve->calcAcc((localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration).x,1,this->currentTrackElem->curve->calcAcc((localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration).z)); 
691
692      Vector v(0.0, 1.0, 0.0);
693      Quaternion q(-PI/2, v);
694      quat = quat * q;
695
696      this->bindSlave->setAbsCoor(&tmp);
697      this->bindSlave->setAbsDir(&quat);
698    }
699}
700
701/**
702   \brief Jumps to a certain point on the Track.
703   \param time The time on the Track to jump to.
704
705   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.)
706   Max is trackLengthMax.
707*/
708void TrackManager::jumpTo(float time)
709{
710  if (time == 0)
711    this->currentTrackElem = this->firstTrackElem;
712  this->localTime = time;
713}
714
715/**
716   \brief a Function that decides which Path we should follow.
717   \param trackElem The Path to choose.
718   
719*/
720int TrackManager::choosePath(TrackElement* trackElem)
721{
722  return (trackElem->*(trackElem->condFunc))(trackElem->subject);
723}
724
725/**
726   \brief Sets the PNode, that should be moved along the Tack
727   \param bindSlave the PNode to set
728*/
729void TrackManager::setBindSlave(PNode* bindSlave)
730{
731  this->bindSlave = bindSlave;
732}
733
734/**
735   \returns the main TrackNode
736*/
737PNode* TrackManager::getTrackNode(void)
738{
739  return this->trackNode;
740}
741
742// DEBUG //
743
744/**
745   \brief Imports a model of the Graph into the OpenGL-environment.
746   \param dt The Iterator used in seconds for Painting the Graph.
747
748   This is for testing facility only. Do this if you want to see the Path inside the Level.
749   eventually this will all be packed into a gl-list.
750*/
751void TrackManager::drawGraph(float dt) const
752{
753
754  for (int i = 1; i <= trackElemCount; i++)
755    {
756      glBegin(GL_LINE_STRIP);
757      TrackElement* tmpElem = this->findTrackElementByID(i);
758      if (tmpElem->curve)
759        for(float f = 0.0; f < 1.0; f+=dt)
760          {
761            //      printf("%f, %f, %f\n",trackManager->calcPos().x, trackManager->calcPos().y, trackManager->calcPos().z);
762            Vector tmpVector = tmpElem->curve->calcPos(f);
763            glVertex3f(tmpVector.x, tmpVector.y, tmpVector.z);
764          }
765  glEnd();
766    }
767}
768
769/**
770   \brief outputs debug information about the trackManager
771   \param level how much debug
772*/
773void TrackManager::debug(unsigned int level) const
774{
775  PRINT(0)("=========================================\n");
776  PRINT(0)("= CLASS TRACKMANAGER::debug information =\n");
777  PRINT(0)("=========================================\n");
778  //  PRINT(0)("Status is: %
779  PRINT(0)(" Consists of %d elements\n", this->trackElemCount);
780  PRINT(0)(" localTime is: %f\n", this->localTime);
781  if (level >= 2)
782    {
783      for (int i = 1; i <= trackElemCount; i++)
784        {
785          TrackElement* tmpElem = this->findTrackElementByID(i);
786          PRINT(0)("--== TrackElement:%i ==--", tmpElem->ID);
787          if(tmpElem->getName())
788            PRINT(0)("Name: %s::", tmpElem->getName());
789          if(tmpElem->isFresh)
790            PRINT(0)("  -- has not jet eddited in any way --\n");
791          PRINT(0)("\n   TimeTable: startingTime=%f; endTime=%f; duration=%f; jumpTime=%f\n", tmpElem->startingTime, tmpElem->endTime, tmpElem->duration, tmpElem->jumpTime);
792          PRINT(0)("   consists of %d Points\n", tmpElem->nodeCount);
793          if (tmpElem->childCount == 0)
794            PRINT(0)("   has no child\n");
795          else if (tmpElem->childCount == 1)
796            PRINT(0)("   has 1 child: =%d=\n", tmpElem->children[0]->ID);
797          else if (tmpElem->childCount > 1)
798            {
799              PRINT(0)("   has %d children: ", tmpElem->childCount);
800              for(int i = 0; i < tmpElem->childCount; i++)
801                PRINT(0)("=%d= ", tmpElem->children[i]->ID);
802              PRINT(0)("\n");
803            }
804
805          if(tmpElem->isHotPoint)
806            PRINT(0)("   is a special Point:\n");
807          if(tmpElem->isSavePoint)
808            PRINT(0)("    is a SavePoint\n");
809          if(tmpElem->isFork)
810            {
811              PRINT(0)("    is A Fork with with %d children.\n", tmpElem->childCount);
812            }
813          if(tmpElem->isJoined)
814            PRINT(0)("   is Joined at the End\n");
815
816          if(!tmpElem->backLoopCheck(tmpElem)) /* this should not happen */
817            PRINT(2)(" THERE IS A BACKLOOP TO THIS ELEMENT\n");
818        }
819    }
820  PRINT(0)("-----------------------------------------\n");
821}
Note: See TracBrowser for help on using the repository browser.