Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/trackManager/src/track_manager.cc @ 3516

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

orxonox/branches/trackManager: now nearest works… this was rather strange
what is important is, that the nearest node is not too far from the center (if there is a 3-fork :)

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