MeshSkin.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include "Base.h"
  2. #include "MeshSkin.h"
  3. #include "Joint.h"
  4. // The number of rows in each palette matrix.
  5. #define PALETTE_ROWS 3
  6. namespace gameplay
  7. {
  8. MeshSkin::MeshSkin()
  9. : _rootJoint(NULL), _matrixPalette(NULL), _model(NULL)
  10. {
  11. }
  12. MeshSkin::~MeshSkin()
  13. {
  14. clearJoints();
  15. SAFE_DELETE_ARRAY(_matrixPalette);
  16. }
  17. const Matrix& MeshSkin::getBindShape() const
  18. {
  19. return _bindShape;
  20. }
  21. void MeshSkin::setBindShape(const float* matrix)
  22. {
  23. _bindShape.set(matrix);
  24. }
  25. unsigned int MeshSkin::getJointCount() const
  26. {
  27. return _joints.size();
  28. }
  29. Joint* MeshSkin::getJoint(unsigned int index) const
  30. {
  31. assert(index < _joints.size());
  32. return _joints[index];
  33. }
  34. Joint* MeshSkin::getJoint(const char* id) const
  35. {
  36. assert(id);
  37. for (unsigned int i = 0, count = _joints.size(); i < count; ++i)
  38. {
  39. Joint* j = _joints[i];
  40. if (j && j->getId() != NULL && strcmp(j->getId(), id) == 0)
  41. {
  42. return j;
  43. }
  44. }
  45. return NULL;
  46. }
  47. void MeshSkin::setJointCount(unsigned int jointCount)
  48. {
  49. // Erase the joints vector and release all joints
  50. clearJoints();
  51. // Resize the joints vector and initialize to NULL
  52. _joints.resize(jointCount);
  53. for (unsigned int i = 0; i < jointCount; i++)
  54. {
  55. _joints[i] = NULL;
  56. }
  57. // Rebuild the matrix palette. Each matrix is 3 rows of Vector4.
  58. SAFE_DELETE_ARRAY(_matrixPalette);
  59. if (jointCount > 0)
  60. {
  61. _matrixPalette = new Vector4[jointCount * PALETTE_ROWS];
  62. for (unsigned int i = 0; i < jointCount * PALETTE_ROWS; i+=PALETTE_ROWS)
  63. {
  64. _matrixPalette[i+0].set(1.0f, 0.0f, 0.0f, 0.0f);
  65. _matrixPalette[i+1].set(0.0f, 1.0f, 0.0f, 0.0f);
  66. _matrixPalette[i+2].set(0.0f, 0.0f, 1.0f, 0.0f);
  67. }
  68. }
  69. }
  70. void MeshSkin::setJoint(Joint* joint, unsigned int index)
  71. {
  72. assert(index < _joints.size());
  73. if (_joints[index])
  74. {
  75. _joints[index]->_skinCount--;
  76. SAFE_RELEASE(_joints[index]);
  77. }
  78. _joints[index] = joint;
  79. if (joint)
  80. {
  81. joint->addRef();
  82. joint->_skinCount++;
  83. }
  84. }
  85. Vector4* MeshSkin::getMatrixPalette() const
  86. {
  87. unsigned int count = _joints.size();
  88. for (unsigned int i = 0; i < count; i++)
  89. {
  90. _joints[i]->updateJointMatrix(getBindShape(), &_matrixPalette[i * PALETTE_ROWS]);
  91. }
  92. return _matrixPalette;
  93. }
  94. unsigned int MeshSkin::getMatrixPaletteSize() const
  95. {
  96. return _joints.size() * PALETTE_ROWS;
  97. }
  98. Model* MeshSkin::getModel() const
  99. {
  100. return _model;
  101. }
  102. Joint* MeshSkin::getRootJoint() const
  103. {
  104. return _rootJoint;
  105. }
  106. void MeshSkin::setRootJoint(Joint* joint)
  107. {
  108. if (_rootJoint)
  109. {
  110. if (_rootJoint->getParent())
  111. {
  112. _rootJoint->getParent()->removeListener(this);
  113. }
  114. }
  115. _rootJoint = joint;
  116. // If the root joint has a parent node, register for its transformChanged event
  117. if (_rootJoint && _rootJoint->getParent())
  118. {
  119. _rootJoint->getParent()->addListener(this, 1);
  120. }
  121. }
  122. void MeshSkin::transformChanged(Transform* transform, long cookie)
  123. {
  124. switch (cookie)
  125. {
  126. case 1:
  127. // The direct parent of our joint hierarchy has changed.
  128. // Dirty the bounding volume for our model's node. This special
  129. // case allows us to have much tighter bounding volumes for
  130. // skinned meshes by only considering local skin/joint transformations
  131. // during bounding volume computation instead of fully resolved
  132. // joint transformations.
  133. if (_model && _model->getNode())
  134. {
  135. _model->getNode()->setBoundsDirty();
  136. }
  137. break;
  138. }
  139. }
  140. int MeshSkin::getJointIndex(Joint* joint) const
  141. {
  142. for (unsigned int i = 0, count = _joints.size(); i < count; ++i)
  143. {
  144. if (_joints[i] == joint)
  145. {
  146. return (int)i;
  147. }
  148. }
  149. return -1;
  150. }
  151. void MeshSkin::clearJoints()
  152. {
  153. setRootJoint(NULL);
  154. for (unsigned int i = 0, count = _joints.size(); i < count; ++i)
  155. {
  156. SAFE_RELEASE(_joints[i]);
  157. }
  158. _joints.clear();
  159. }
  160. }