Animation3D.cpp 3.1 KB

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