MeshSkin.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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), _rootNode(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 (unsigned int)_joints.size();
  28. }
  29. Joint* MeshSkin::getJoint(unsigned int index) const
  30. {
  31. GP_ASSERT(index < _joints.size());
  32. return _joints[index];
  33. }
  34. Joint* MeshSkin::getJoint(const char* id) const
  35. {
  36. GP_ASSERT(id);
  37. for (size_t 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. MeshSkin* MeshSkin::clone(NodeCloneContext &context) const
  48. {
  49. MeshSkin* skin = new MeshSkin();
  50. skin->_bindShape = _bindShape;
  51. if (_rootNode && _rootJoint)
  52. {
  53. const unsigned int jointCount = getJointCount();
  54. skin->setJointCount(jointCount);
  55. GP_ASSERT(skin->_rootNode == NULL);
  56. // Check if the root node has already been cloned.
  57. if (Node* rootNode = context.findClonedNode(_rootNode))
  58. {
  59. skin->_rootNode = rootNode;
  60. rootNode->addRef();
  61. }
  62. else
  63. {
  64. skin->_rootNode = _rootNode->cloneRecursive(context);
  65. }
  66. Node* node = NULL;
  67. if (strcmp(skin->_rootNode->getId(), _rootJoint->getId()) == 0)
  68. {
  69. node = skin->_rootNode;
  70. }
  71. else
  72. {
  73. node = skin->_rootNode->findNode(_rootJoint->getId());
  74. }
  75. GP_ASSERT(node);
  76. skin->_rootJoint = static_cast<Joint*>(node);
  77. for (unsigned int i = 0; i < jointCount; ++i)
  78. {
  79. Joint* oldJoint = getJoint(i);
  80. GP_ASSERT(oldJoint);
  81. Joint* newJoint = static_cast<Joint*>(skin->_rootNode->findNode(oldJoint->getId()));
  82. if (!newJoint)
  83. {
  84. if (strcmp(skin->_rootJoint->getId(), oldJoint->getId()) == 0)
  85. newJoint = static_cast<Joint*>(skin->_rootJoint);
  86. }
  87. GP_ASSERT(newJoint);
  88. skin->setJoint(newJoint, i);
  89. }
  90. }
  91. return skin;
  92. }
  93. void MeshSkin::setJointCount(unsigned int jointCount)
  94. {
  95. // Erase the joints vector and release all joints.
  96. clearJoints();
  97. // Resize the joints vector and initialize to NULL.
  98. _joints.resize(jointCount);
  99. for (unsigned int i = 0; i < jointCount; i++)
  100. {
  101. _joints[i] = NULL;
  102. }
  103. // Rebuild the matrix palette. Each matrix is 3 rows of Vector4.
  104. SAFE_DELETE_ARRAY(_matrixPalette);
  105. if (jointCount > 0)
  106. {
  107. _matrixPalette = new Vector4[jointCount * PALETTE_ROWS];
  108. for (unsigned int i = 0; i < jointCount * PALETTE_ROWS; i+=PALETTE_ROWS)
  109. {
  110. _matrixPalette[i+0].set(1.0f, 0.0f, 0.0f, 0.0f);
  111. _matrixPalette[i+1].set(0.0f, 1.0f, 0.0f, 0.0f);
  112. _matrixPalette[i+2].set(0.0f, 0.0f, 1.0f, 0.0f);
  113. }
  114. }
  115. }
  116. void MeshSkin::setJoint(Joint* joint, unsigned int index)
  117. {
  118. GP_ASSERT(index < _joints.size());
  119. if (_joints[index])
  120. {
  121. _joints[index]->removeSkin(this);
  122. SAFE_RELEASE(_joints[index]);
  123. }
  124. _joints[index] = joint;
  125. if (joint)
  126. {
  127. joint->addRef();
  128. joint->addSkin(this);
  129. }
  130. }
  131. Vector4* MeshSkin::getMatrixPalette() const
  132. {
  133. GP_ASSERT(_matrixPalette);
  134. for (size_t i = 0, count = _joints.size(); i < count; i++)
  135. {
  136. GP_ASSERT(_joints[i]);
  137. _joints[i]->updateJointMatrix(getBindShape(), &_matrixPalette[i * PALETTE_ROWS]);
  138. }
  139. return _matrixPalette;
  140. }
  141. unsigned int MeshSkin::getMatrixPaletteSize() const
  142. {
  143. return (unsigned int)_joints.size() * PALETTE_ROWS;
  144. }
  145. Model* MeshSkin::getModel() const
  146. {
  147. return _model;
  148. }
  149. Joint* MeshSkin::getRootJoint() const
  150. {
  151. return _rootJoint;
  152. }
  153. void MeshSkin::setRootJoint(Joint* joint)
  154. {
  155. if (_rootJoint)
  156. {
  157. if (_rootJoint->getParent())
  158. {
  159. _rootJoint->getParent()->removeListener(this);
  160. }
  161. }
  162. _rootJoint = joint;
  163. // If the root joint has a parent node, register for its transformChanged event
  164. if (_rootJoint && _rootJoint->getParent())
  165. {
  166. _rootJoint->getParent()->addListener(this, 1);
  167. }
  168. Node* newRootNode = _rootJoint;
  169. if (newRootNode)
  170. {
  171. // Find the top level parent node of the root joint
  172. for (Node* node = newRootNode->getParent(); node != NULL; node = node->getParent())
  173. {
  174. if (node->getParent() == NULL)
  175. {
  176. newRootNode = node;
  177. break;
  178. }
  179. }
  180. }
  181. setRootNode(newRootNode);
  182. }
  183. void MeshSkin::transformChanged(Transform* transform, long cookie)
  184. {
  185. switch (cookie)
  186. {
  187. case 1:
  188. // The direct parent of our joint hierarchy has changed.
  189. // Dirty the bounding volume for our model's node. This special
  190. // case allows us to have much tighter bounding volumes for
  191. // skinned meshes by only considering local skin/joint transformations
  192. // during bounding volume computation instead of fully resolved
  193. // joint transformations.
  194. if (_model && _model->getNode())
  195. {
  196. _model->getNode()->setBoundsDirty();
  197. }
  198. break;
  199. }
  200. }
  201. int MeshSkin::getJointIndex(Joint* joint) const
  202. {
  203. for (size_t i = 0, count = _joints.size(); i < count; ++i)
  204. {
  205. if (_joints[i] == joint)
  206. {
  207. return (int)i;
  208. }
  209. }
  210. return -1;
  211. }
  212. void MeshSkin::setRootNode(Node* node)
  213. {
  214. if (_rootNode != node)
  215. {
  216. SAFE_RELEASE(_rootNode);
  217. _rootNode = node;
  218. if (_rootNode)
  219. {
  220. _rootNode->addRef();
  221. }
  222. }
  223. }
  224. void MeshSkin::clearJoints()
  225. {
  226. setRootJoint(NULL);
  227. for (size_t i = 0, count = _joints.size(); i < count; ++i)
  228. {
  229. SAFE_RELEASE(_joints[i]);
  230. }
  231. _joints.clear();
  232. }
  233. }