Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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. }