Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

SkeletalModel.cpp 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*!
  2. * \file src/SkeletalModel.cpp
  3. * \brief Moveable Mesh Geometry
  4. *
  5. * \author Mongoose
  6. * \author xythobuz
  7. */
  8. #include "global.h"
  9. #include "Log.h"
  10. #include "SkeletalModel.h"
  11. #include "World.h"
  12. #include <glm/gtc/matrix_transform.hpp>
  13. void BoneTag::display(glm::mat4 MVP, ShaderTexture* shaderTexture) {
  14. getWorld().getMesh(mesh).display(MVP, shaderTexture);
  15. }
  16. // ----------------------------------------------------------------------------
  17. BoneFrame::~BoneFrame() {
  18. for (unsigned long i = 0; i < tag.size(); i++)
  19. delete tag[i];
  20. }
  21. unsigned long BoneFrame::size() {
  22. return tag.size();
  23. }
  24. BoneTag& BoneFrame::get(unsigned long i) {
  25. orAssertLessThan(i, tag.size());
  26. return *tag.at(i);
  27. }
  28. void BoneFrame::add(BoneTag* t) {
  29. tag.push_back(t);
  30. }
  31. // ----------------------------------------------------------------------------
  32. AnimationFrame::~AnimationFrame() {
  33. for (unsigned long i = 0; i < frame.size(); i++)
  34. delete frame[i];
  35. }
  36. unsigned long AnimationFrame::size() {
  37. return frame.size();
  38. }
  39. BoneFrame& AnimationFrame::get(unsigned long i) {
  40. orAssertLessThan(i, frame.size());
  41. return *frame.at(i);
  42. }
  43. void AnimationFrame::add(BoneFrame* f) {
  44. frame.push_back(f);
  45. }
  46. // ----------------------------------------------------------------------------
  47. class MatrixStack {
  48. public:
  49. MatrixStack(glm::mat4 start) : startVal(start) { stack.push_back(startVal); }
  50. void push() {
  51. //orAssertGreaterThan(stack.size(), 0);
  52. if (stack.size() > 0)
  53. stack.push_back(stack.at(stack.size() - 1));
  54. }
  55. void pop() {
  56. //orAssertGreaterThan(stack.size(), 0);
  57. if (stack.size() > 0)
  58. stack.pop_back();
  59. }
  60. glm::mat4 get() {
  61. //orAssertGreaterThan(stack.size(), 0);
  62. if (stack.size() > 0)
  63. return stack.at(stack.size() - 1);
  64. return startVal;
  65. }
  66. private:
  67. std::vector<glm::mat4> stack;
  68. glm::mat4 startVal;
  69. };
  70. // ----------------------------------------------------------------------------
  71. SkeletalModel::~SkeletalModel() {
  72. for (unsigned long i = 0; i < animation.size(); i++)
  73. delete animation[i];
  74. }
  75. //#define DEBUG_MODELS
  76. #ifdef DEBUG_MODELS
  77. #include <bitset>
  78. #endif
  79. void SkeletalModel::display(glm::mat4 MVP, int aframe, int bframe, ShaderTexture* shaderTexture) {
  80. orAssertLessThan(aframe, size());
  81. orAssertLessThan(bframe, get(aframe).size());
  82. AnimationFrame& anim = get(aframe);
  83. BoneFrame& boneframe = anim.get(bframe);
  84. glm::vec3 pos = boneframe.getPosition();
  85. glm::mat4 frameTrans = glm::translate(glm::mat4(1.0f), glm::vec3(pos.x, -pos.y, pos.z));
  86. MatrixStack stack(MVP * frameTrans);
  87. #ifdef DEBUG_MODELS
  88. Log::get(LOG_DEBUG) << "Starting SkeletalModel:" << Log::endl;
  89. int cnt = 0;
  90. #endif
  91. for (unsigned int a = 0; a < boneframe.size(); a++) {
  92. BoneTag& tag = boneframe.get(a);
  93. glm::mat4 translate(1.0f);
  94. if (a != 0) {
  95. if (tag.getFlag() & 0x01) {
  96. stack.pop();
  97. #ifdef DEBUG_MODELS
  98. Log::get(LOG_DEBUG) << " --> pop" << Log::endl;
  99. cnt--;
  100. #endif
  101. }
  102. if (tag.getFlag() & 0x02) {
  103. stack.push();
  104. #ifdef DEBUG_MODELS
  105. Log::get(LOG_DEBUG) << " --> push" << Log::endl;
  106. cnt++;
  107. #endif
  108. }
  109. #ifdef DEBUG_MODELS
  110. if (tag.getFlag() & ~0x03) {
  111. std::bitset<8> bs(tag.getFlag());
  112. Log::get(LOG_DEBUG) << " Unexpected flag " << bs << Log::endl;
  113. }
  114. #endif
  115. glm::vec3 off = tag.getOffset();
  116. translate = glm::translate(glm::mat4(1.0f), glm::vec3(off.x, -off.y, off.z));
  117. }
  118. glm::vec3 rot = tag.getRotation();
  119. glm::mat4 rotY = glm::rotate(glm::mat4(1.0f), rot[1], glm::vec3(0.0f, 1.0f, 0.0f));
  120. glm::mat4 rotX = glm::rotate(glm::mat4(1.0f), rot[0], glm::vec3(1.0f, 0.0f, 0.0f));
  121. glm::mat4 rotZ = glm::rotate(glm::mat4(1.0f), rot[2], glm::vec3(0.0f, 0.0f, 1.0f));
  122. glm::mat4 rotate = rotZ * rotX * rotY;
  123. glm::mat4 mod = translate * rotate;
  124. tag.display(stack.get() * mod, shaderTexture);
  125. #ifdef DEBUG_MODELS
  126. Log::get(LOG_DEBUG) << " --> get (" << cnt << ")" << Log::endl;
  127. #endif
  128. }
  129. #ifdef DEBUG_MODELS
  130. Log::get(LOG_DEBUG) << "Done!" << Log::endl;
  131. #endif
  132. }
  133. unsigned long SkeletalModel::size() {
  134. return animation.size();
  135. }
  136. AnimationFrame& SkeletalModel::get(unsigned long i) {
  137. orAssertLessThan(i, animation.size());
  138. return *animation.at(i);
  139. }
  140. void SkeletalModel::add(AnimationFrame* f) {
  141. animation.push_back(f);
  142. }