Animation3D.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "Animation3D.h"
  2. #include "Model3D.h"
  3. using namespace Framework;
  4. // löscht eine KnochenData Struktur
  5. void Animation3D::deleteKnochenData( KnochenData *d )
  6. {
  7. if( d->next != 0 )
  8. deleteKnochenData( d->next );
  9. delete d;
  10. }
  11. // Inhalt der Animation3D Klasse aus Animation3D.h
  12. // Konstruktor
  13. Animation3D::Animation3D()
  14. : ReferenceCounter()
  15. {
  16. for( int i = 0; i < MAX_KNOCHEN_ANZ; i++ )
  17. kd[ i ] = 0;
  18. maxTime = 0;
  19. }
  20. // Destructor
  21. Animation3D::~Animation3D()
  22. {
  23. for( int i = 0; i < MAX_KNOCHEN_ANZ; i++ )
  24. deleteKnochenData( kd[ i ] );
  25. }
  26. // Fügt für einen bestimmten Knochen ein Keyframe hinzu
  27. // kId: Die Id des Knochens
  28. // time: Die Zeit, die vergehen soll bis der Knochen die Position und die Rotation des Keyframes follständig erreicht hat
  29. // pos: Die Position des Knochens die erreicht werden soll in Modellkoordinaten
  30. // rot: Die Rotation des Knochens um seine Position die erreicht werden soll
  31. void Animation3D::addKeyFrame( int kId, double time, Vec3<float> pos, Vec3<float> rot )
  32. {
  33. KnochenData *d = kd[ kId ];
  34. if( !d )
  35. {
  36. kd[ kId ] = new KnochenData();
  37. kd[ kId ]->next = 0;
  38. kd[ kId ]->time = time;
  39. kd[ kId ]->pos = pos;
  40. kd[ kId ]->rot = rot;
  41. return;
  42. }
  43. while( d->next )
  44. d = d->next;
  45. d->next = new KnochenData();
  46. d->next->next = 0;
  47. d->next->time = time;
  48. d->next->pos = pos;
  49. d->next->rot = rot;
  50. }
  51. // Wendet die Animation auf ein bestimmtes Skelett an
  52. // zS: Das Skelett
  53. // timeOffset: zeit in sekunden, die diese Animation bereits auf dem Skelett angewendet wurde. Wird automatisch von der Animation aktualisiert.
  54. // sec: zeit in Sekunden, die vergangen ist seit dem diese Methode zuletzt für das Skelett aufgerufen wurde
  55. void Animation3D::apply( Skelett *zS, double &timeOffset, double sec ) const
  56. {
  57. if( zS->k )
  58. apply( zS->k, timeOffset, sec );
  59. timeOffset += sec;
  60. if( timeOffset > maxTime )
  61. timeOffset -= maxTime;
  62. }
  63. // Wendet die Animation auf ein bestimmten Knochen an
  64. // zS: Der Knochen
  65. // timeOffset: zeit in sekunden, die diese Animation bereits auf dem Knochen angewendet wurde.
  66. // sec: zeit in Sekunden, die vergangen ist seit dem diese Methode zuletzt für dem Knochen aufgerufen wurde
  67. void Animation3D::apply( Knochen *zK, double timeOffset, double sec ) const
  68. {
  69. if( zK->geschwister )
  70. apply( zK->geschwister, timeOffset, sec );
  71. if( zK->kinder )
  72. apply( zK->kinder, timeOffset, sec );
  73. KnochenData *d = kd[ zK->id ];
  74. if( d )
  75. {
  76. while( timeOffset > d->time )
  77. {
  78. timeOffset -= d->time;
  79. d = d->next;
  80. if( !d )
  81. d = kd[ zK->id ];
  82. }
  83. while( sec > 0 )
  84. {
  85. double left = d->time - timeOffset;
  86. if( left > 0 )
  87. {
  88. float proc = (float)MIN( sec / left, 1 );
  89. zK->pos += ( d->pos - zK->pos ) * proc;
  90. zK->winkel += ( d->rot - zK->winkel ) * proc;
  91. sec -= left;
  92. }
  93. else
  94. {
  95. zK->pos = d->pos;
  96. zK->winkel = d->rot;
  97. sec -= d->time;
  98. }
  99. timeOffset = 0;
  100. d = d->next;
  101. if( !d )
  102. d = kd[ zK->id ];
  103. }
  104. }
  105. }