Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: moved some stuff from TrackManager to TrackElement

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