Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/levelloader/src/track_manager.cc @ 3603

Last change on this file since 3603 was 3562, checked in by chris, 20 years ago

orxonox/branches/levelloader: Managed to get through the whole loading sequence… still not generating a valid world though…

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