BsRenderable.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "BsRenderable.h"
  2. #include "BsRenderableRTTI.h"
  3. #include "CmSceneObject.h"
  4. #include "CmMesh.h"
  5. #include "CmRenderQueue.h"
  6. using namespace CamelotFramework;
  7. namespace BansheeEngine
  8. {
  9. Renderable::Renderable(const HSceneObject& parent)
  10. :Component(parent), mLayer(1)
  11. {
  12. mMaterials.resize(1);
  13. }
  14. void Renderable::setNumMaterials(CM::UINT32 numMaterials)
  15. {
  16. mMaterials.resize(numMaterials);
  17. }
  18. void Renderable::setMaterial(CM::UINT32 idx, CM::HMaterial material)
  19. {
  20. mMaterials[idx] = material;
  21. }
  22. void Renderable::render(CM::RenderQueue& renderQueue)
  23. {
  24. if(mMesh == nullptr || !mMesh.isLoaded())
  25. return;
  26. bool hasAtLeastOneMaterial = false;
  27. for(auto& material : mMaterials)
  28. {
  29. if(material != nullptr)
  30. {
  31. hasAtLeastOneMaterial = true;
  32. if(!material.isLoaded()) // We wait until all materials are loaded
  33. return;
  34. }
  35. }
  36. if(hasAtLeastOneMaterial)
  37. {
  38. for(UINT32 i = 0; i < mMesh->getNumSubMeshes(); i++)
  39. {
  40. HMaterial mat;
  41. if(i < mMaterials.size() && mMaterials[i] != nullptr)
  42. {
  43. mat = mMaterials[i];
  44. }
  45. else
  46. {
  47. for(auto& iter = mMaterials.rbegin(); iter != mMaterials.rend(); ++iter)
  48. {
  49. if((*iter) != nullptr)
  50. {
  51. mat = *iter;
  52. break;
  53. }
  54. }
  55. }
  56. renderQueue.add(mat, mMesh->getSubMeshData(i), mWorldBounds[i].getCenter());
  57. }
  58. }
  59. else
  60. return;
  61. }
  62. void Renderable::updateWorldBounds()
  63. {
  64. if(mMesh == nullptr || !mMesh.isLoaded())
  65. return;
  66. // TODO - This will likely need to be optimized in a more data friendly way
  67. // (e.g. store all bounds in a single array, and same with world matrices)
  68. mWorldBounds.resize(mMesh->getNumSubMeshes());
  69. for(UINT32 i = 0; i < (UINT32)mWorldBounds.size(); i++)
  70. {
  71. mWorldBounds[i] = mMesh->getBounds(i);
  72. mWorldBounds[i].transformAffine(SO()->getWorldTfrm());
  73. }
  74. }
  75. void Renderable::setLayer(UINT64 layer)
  76. {
  77. bool isPow2 = layer && !( (layer-1) & layer);
  78. if(!isPow2)
  79. CM_EXCEPT(InvalidParametersException, "Invalid layer provided. Only one layer bit may be set.");
  80. mLayer = layer;
  81. }
  82. RTTITypeBase* Renderable::getRTTIStatic()
  83. {
  84. return RenderableRTTI::instance();
  85. }
  86. RTTITypeBase* Renderable::getRTTI() const
  87. {
  88. return Renderable::getRTTIStatic();
  89. }
  90. }