DrawSkeleton.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include "DrawSkeleton.h"
  2. #define POSITION_BINDING 0
  3. #define COLOUR_BINDING 1
  4. #include "Logger.h"
  5. #include "common/TypeDefine.h"
  6. float* pPos;
  7. u32 cur_index;
  8. u16* idata;
  9. Ogre::SubMesh* sub_mesh;
  10. void
  11. DrawSkeleton( const Skeleton& skeleton, const Ogre::MeshPtr& mesh )
  12. {
  13. if( skeleton.size() == 0 )
  14. {
  15. return;
  16. }
  17. sub_mesh = mesh->createSubMesh( "Skeleton" );
  18. sub_mesh->setMaterialName( "Skeleton" );
  19. sub_mesh->useSharedVertices = false;
  20. sub_mesh->operationType = Ogre::RenderOperation::OT_LINE_LIST;
  21. // Allocate and prepare vertex data
  22. sub_mesh->vertexData = new Ogre::VertexData();
  23. sub_mesh->vertexData->vertexStart = 0;
  24. sub_mesh->vertexData->vertexCount = static_cast< size_t >( skeleton.size() * 2 );
  25. sub_mesh->indexData = new Ogre::IndexData();
  26. sub_mesh->indexData->indexStart = 0;
  27. sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
  28. sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
  29. Ogre::HardwareIndexBuffer::IT_16BIT,
  30. sub_mesh->indexData->indexCount,
  31. Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
  32. idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
  33. cur_index = 0;
  34. Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
  35. Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
  36. // 1st buffer
  37. decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
  38. Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
  39. decl->getVertexSize( POSITION_BINDING ),
  40. sub_mesh->vertexData->vertexCount,
  41. Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
  42. bind->setBinding( POSITION_BINDING, vbuf0 );
  43. // 2nd buffer
  44. decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
  45. Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
  46. decl->getVertexSize( COLOUR_BINDING ),
  47. sub_mesh->vertexData->vertexCount,
  48. Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
  49. // Set vertex buffer binding so buffer 1 is bound to our colour buffer
  50. bind->setBinding( COLOUR_BINDING, vbuf1 );
  51. pPos = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
  52. std::vector<Ogre::RGBA> colours(sub_mesh->vertexData->vertexCount);
  53. DrawBone( skeleton, -1, colours.data() );
  54. vbuf0->unlock();
  55. vbuf1->writeData(0, vbuf1->getSizeInBytes(), colours.data(), true);
  56. sub_mesh->indexData->indexBuffer->unlock();
  57. sub_mesh->indexData->optimiseVertexCacheTriList();
  58. }
  59. void
  60. DrawBone( const Skeleton& skeleton, int parent_index, Ogre::RGBA* colours )
  61. {
  62. for( size_t i = 0; i < skeleton.size(); ++i )
  63. {
  64. if( skeleton[ i ].parent_id == parent_index )
  65. {
  66. *pPos++ = 0; *pPos++ = 0; *pPos++ = 0;
  67. *pPos++ = 0; *pPos++ = 0; *pPos++ = 0;
  68. Ogre::ColourValue colour1 = Ogre::ColourValue( 1, 0, 0 );
  69. Ogre::ColourValue colour2 = Ogre::ColourValue( 1, 1, 0 );
  70. Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
  71. rs->convertColourValue( colour1, colours + cur_index + 0 );
  72. rs->convertColourValue( colour2, colours + cur_index + 1 );
  73. idata[ cur_index + 0 ] = cur_index + 0;
  74. idata[ cur_index + 1 ] = cur_index + 1;
  75. Ogre::VertexBoneAssignment vba;
  76. vba.vertexIndex = cur_index + 0;
  77. vba.boneIndex = ( parent_index == -1 ) ? 1 : parent_index * 2 + 3;
  78. vba.weight = 1.0f;
  79. sub_mesh->addBoneAssignment( vba );
  80. vba.vertexIndex = cur_index + 1;
  81. vba.boneIndex = i * 2 + 3;
  82. vba.weight = 1.0f;
  83. sub_mesh->addBoneAssignment( vba );
  84. cur_index += 2;
  85. DrawBone( skeleton, i, colours );
  86. }
  87. }
  88. }