Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3597 was 3596, checked in by bensch, 20 years ago

orxonox/trunk: borders for the Player, so he cannot move out of the line

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