home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5257 / source.7z / x_skel.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2012-03-18  |  6.3 KB  |  208 lines

  1. #include "xentax.h"
  2. #include "x_skel.h"
  3.  
  4. SKELETON::TREENODE::TREENODE()
  5. {
  6. }
  7.  
  8. SKELETON::TREENODE::TREENODE(const SKELETON::TREENODE& node)
  9. {
  10.  joint = node.joint;
  11.  children.insert(children.end(), node.children.begin(), node.children.end());
  12. }
  13.  
  14. SKELETON::TREENODE::~TREENODE()
  15. {
  16. }
  17.  
  18. SKELETON::TREENODE& SKELETON::TREENODE::operator =(const SKELETON::TREENODE& node)
  19. {
  20.  if(this == &node) return *this;
  21.  children.clear();
  22.  joint = node.joint;
  23.  children.insert(children.end(), node.children.begin(), node.children.end());
  24.  return *this;
  25. }
  26.  
  27. SKELETON::SKELETON(const char* name) : id(name)
  28. {
  29.  root = INVALID_JOINT;
  30. }
  31.  
  32. SKELETON::~SKELETON()
  33. {
  34. }
  35.  
  36. bool SKELETON::insert(uint32 index, const JOINT& joint)
  37. {
  38.  // check if already inserted
  39.  tree_t::iterator temp = tree.find(index);
  40.  if(temp != tree.end()) return error("InsertJoint: Joint already exists.");
  41.  
  42.  // insert root
  43.  if(joint.parent == INVALID_JOINT) {
  44.     node_t node;
  45.     node.joint = joint;
  46.     tree.insert(tree_t::value_type(index, node));
  47.     root = index;
  48.     return true;
  49.    }
  50.  
  51.  // find parent
  52.  tree_t::iterator parent = tree.find(joint.parent);
  53.  if(parent == tree.end()) return error("InsertJoint: Can't find parent joint.");
  54.  
  55.  // insert node
  56.  node_t node;
  57.  node.joint = joint;
  58.  tree.insert(tree_t::value_type(index, node));
  59.  
  60.  // insert into parent's adjacency list
  61.  parent->second.children.push_back(index);
  62.  return true;
  63. }
  64.  
  65. bool SKELETON::remove(uint32 index)
  66. {
  67.  // TODO
  68.  return true;
  69. }
  70.  
  71. void SKELETON::PrintJointTree(std::stringstream& ss)const
  72. {
  73.  PrintJointTree(ss, root, 0);
  74. }
  75.  
  76. void SKELETON::PrintJointTree(std::stringstream& ss, uint32 index, uint32 level)const
  77. {
  78.  // find node
  79.  const_tree_iterator iter = tree.find(index);
  80.  if(iter == tree.end()) return;
  81.  
  82.  // build string
  83.  const node_t& node = iter->second;
  84.  for(size_t i = 0; i < level; i++) ss << " ";
  85.  ss << node.joint.name << std::endl;
  86.  
  87.  // visit children of joint tree node
  88.  for(size_t i = 0; i < node.children.size(); i++) PrintJointTree(ss, node.children[i], level + 1);
  89. }
  90.  
  91. void SKELETON::PrintColladaNodeHeirarchy(const std::string& id, std::stringstream& ss)const
  92. {
  93.  PrintColladaNodeHeirarchy(id, ss, root, 0);
  94. }
  95.  
  96. void SKELETON::PrintColladaNodeHeirarchy(const std::string& id, std::stringstream& ss, uint32 index, uint32 level)const
  97. {
  98.  // NOTES:
  99.  // Unlike in Collada specification, you must have id attributes for all joint nodes if you want to see the
  100.  // names in 3DS MAX. Solution is to just define id and sid together at the same time.
  101.  
  102.  // find node
  103.  const_tree_iterator iter = tree.find(index);
  104.  if(iter == tree.end()) return;
  105.  
  106.  // determine spacing
  107.  std::string spacing = "  ";
  108.  for(size_t i = 0; i < level; i++) spacing += ' ';
  109.  
  110.  // print node
  111.  const node_t& node = iter->second;
  112.  if(index == root) ss << spacing << "<node id=\"" << id << "\" sid=\"" << node.joint.name << "\">" << std::endl;
  113.  else ss << spacing << "<node id=\"" << node.joint.name << "\" sid=\"" << node.joint.name << "\" type=\"JOINT\">" << std::endl;
  114.  
  115.  // position node
  116.  ss << spacing << " <matrix>" << std::endl;
  117.  ss << spacing << "  " << "1 0 0 " << node.joint.rel_x << std::endl;
  118.  ss << spacing << "  " << "0 1 0 " << node.joint.rel_y << std::endl;
  119.  ss << spacing << "  " << "0 0 1 " << node.joint.rel_z << std::endl;
  120.  ss << spacing << "  " << "0 0 0 1" << std::endl;
  121.  ss << spacing << " </matrix>" << std::endl;
  122.  
  123.  // print children
  124.  for(size_t i = 0; i < node.children.size(); i++)
  125.      PrintColladaNodeHeirarchy(id, ss, node.children[i], level + 1);
  126.  
  127.  // finish node
  128.  ss << spacing << "</node>" << std::endl;
  129. }
  130.  
  131. void SKELETON::PrintColladaJoints(const std::string& id, std::stringstream& ss)const
  132. {
  133.  ss << "    <source id=\"" << id << "_joints\">" << std::endl;
  134.  
  135.  ss << "     <Name_array count=\"" << tree.size() << "\">" << std::endl;
  136.  PrintColladaJoints(ss, root);
  137.  ss << "     </Name_array>" << std::endl;
  138.  
  139.  ss << "     <technique_common>" << std::endl;
  140.  ss << "      <acessor source=\"#" << id << "_joints\" count=\"" << tree.size() << "\" stride=\"1\">" << std::endl;
  141.  ss << "       <param name=\"JOINT\" type=\"name\" />" << std::endl;
  142.  ss << "      </acessor>" << std::endl;
  143.  ss << "     </technique_common>" << std::endl;
  144.  
  145.  ss << "    </source>" << std::endl;
  146. }
  147.  
  148. void SKELETON::PrintColladaJoints(std::stringstream& ss, uint32 index)const
  149. {
  150.  // find node
  151.  const_tree_iterator iter = tree.find(index);
  152.  if(iter == tree.end()) return;
  153.  
  154.  // print node
  155.  const node_t& node = iter->second;
  156.  ss << "      " << node.joint.name << std::endl;
  157.  
  158.  // print children
  159.  for(size_t i = 0; i < node.children.size(); i++)
  160.      PrintColladaJoints(ss, node.children[i]);
  161. }
  162.  
  163. void SKELETON::PrintColladaBindMatrices(const std::string& id, std::stringstream& ss)const
  164. {
  165.  ss << "    <source id=\"" << id << "_matrices\">" << std::endl;
  166.  ss << "     <float_array count=\"" << 16*tree.size() << "\">" << std::endl;
  167.  PrintColladaBindMatrices(ss, root);
  168.  ss << "     </float_array>" << std::endl;
  169.  
  170.  ss << "     <technique_common>" << std::endl;
  171.  ss << "      <acessor source=\"#" << id << "_matrices\" count=\"" << tree.size() << "\" stride=\"16\">" << std::endl;
  172.  ss << "       <param name=\"INV_BIND_MATRIX\" type=\"float4x4\" />" << std::endl;
  173.  ss << "      </acessor>" << std::endl;
  174.  ss << "     </technique_common>" << std::endl;
  175.  
  176.  ss << "    </source>" << std::endl;
  177. }
  178.  
  179. void SKELETON::PrintColladaBindMatrices(std::stringstream& ss, uint32 index)const
  180. {
  181.  // find node
  182.  const_tree_iterator iter = tree.find(index);
  183.  if(iter == tree.end()) return;
  184.  
  185.  // print node
  186.  const node_t& node = iter->second;
  187.  ss << "      ";
  188.  ss << node.joint.matrix[ 0] << " ";
  189.  ss << node.joint.matrix[ 1] << " ";
  190.  ss << node.joint.matrix[ 2] << " ";
  191.  ss << node.joint.matrix[ 3] << " ";
  192.  ss << node.joint.matrix[ 4] << " ";
  193.  ss << node.joint.matrix[ 5] << " ";
  194.  ss << node.joint.matrix[ 6] << " ";
  195.  ss << node.joint.matrix[ 7] << " ";
  196.  ss << node.joint.matrix[ 8] << " ";
  197.  ss << node.joint.matrix[ 9] << " ";
  198.  ss << node.joint.matrix[10] << " ";
  199.  ss << node.joint.matrix[11] << " ";
  200.  ss << node.joint.matrix[12] << " ";
  201.  ss << node.joint.matrix[13] << " ";
  202.  ss << node.joint.matrix[14] << " ";
  203.  ss << node.joint.matrix[14] << " " << std::endl;
  204.  
  205.  // print children
  206.  for(size_t i = 0; i < node.children.size(); i++)
  207.      PrintColladaBindMatrices(ss, node.children[i]);
  208. }