ParticleEntityRenderer.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include "core/particles/renderer/ParticleEntityRenderer.h"
  2. #include <OgreEntity.h>
  3. #include <OgreRoot.h>
  4. #include "core/particles/ParticleSystem.h"
  5. #include "core/particles/ParticleTechnique.h"
  6. #include "core/particles/ParticleVisual.h"
  7. //------------------------------------------------------------------------------
  8. ParticleEntityRendererDictionary::MeshName ParticleEntityRenderer::m_MeshNameDictionary;
  9. //------------------------------------------------------------------------------
  10. ParticleEntityRenderer::ParticleEntityRenderer():
  11. ParticleRenderer(),
  12. m_MeshName(Ogre::StringUtil::BLANK)
  13. {
  14. m_RendererType = "Entity";
  15. if (createParamDictionary("ParticleEntityRenderer"))
  16. {
  17. Ogre::ParamDictionary* dict = getParamDictionary();
  18. dict->addParameter(Ogre::ParameterDef("mesh_name", "", Ogre::PT_STRING), &m_MeshNameDictionary);
  19. }
  20. }
  21. //------------------------------------------------------------------------------
  22. ParticleEntityRenderer::~ParticleEntityRenderer()
  23. {
  24. if (m_ParentTechnique == nullptr)
  25. {
  26. return;
  27. }
  28. Clear();
  29. }
  30. //------------------------------------------------------------------------------
  31. void
  32. ParticleEntityRenderer::CopyAttributesTo(ParticleRenderer* renderer)
  33. {
  34. // First copy parent attributes
  35. ParticleRenderer::CopyAttributesTo(renderer);
  36. // First cast to ParticleEntityRenderer
  37. ParticleEntityRenderer* entity_renderer = static_cast<ParticleEntityRenderer*>(renderer);
  38. // Copy attributes in case there is a entityRenderer (which should be available)
  39. entity_renderer->m_MeshName = m_MeshName;
  40. }
  41. //------------------------------------------------------------------------------
  42. const Ogre::String&
  43. ParticleEntityRenderer::GetMeshName() const
  44. {
  45. return m_MeshName;
  46. }
  47. //------------------------------------------------------------------------------
  48. void
  49. ParticleEntityRenderer::SetMeshName(const Ogre::String& mesh_name)
  50. {
  51. m_MeshName = mesh_name;
  52. m_RendererInitialised = false; // Retriggers the _prepare function
  53. Clear(); // Delete all nodes en entities, they will be rebuild
  54. }
  55. //------------------------------------------------------------------------------
  56. void
  57. ParticleEntityRenderer::Clear()
  58. {
  59. if (m_ParentTechnique == nullptr)
  60. {
  61. return;
  62. }
  63. // Note: The created ChildSceneNodes are destroyed when the ParticleSystem is destroyed
  64. std::vector<ParticleEntityAdditionalData*>::const_iterator it;
  65. std::vector<ParticleEntityAdditionalData*>::const_iterator itEnd = m_AllAdditionalData.end();
  66. for (it = m_AllAdditionalData.begin(); it != itEnd; ++it)
  67. {
  68. delete (*it);
  69. }
  70. m_AllAdditionalData.clear();
  71. m_UnassignedAdditionalData.clear();
  72. // Destroy the Entities. Do it like this, because it must be assured that the entity still exists
  73. // and has not already been destroyed.
  74. Ogre::SceneManager* scene_manager = Ogre::Root::getSingleton().getSceneManager("Scene");
  75. for( unsigned int i = 0; i < m_Entities.size(); i++ )
  76. {
  77. scene_manager->destroyEntity( m_Entities[ i ] );
  78. }
  79. m_Entities.clear();
  80. // Reset the visual data in the pool
  81. m_ParentTechnique->ResetVisualParticles();
  82. }
  83. //------------------------------------------------------------------------------
  84. void
  85. ParticleEntityRenderer::SetVisible(bool visible)
  86. {
  87. std::vector<ParticleEntityAdditionalData*>::const_iterator it;
  88. std::vector<ParticleEntityAdditionalData*>::const_iterator itEnd = m_AllAdditionalData.end();
  89. for (it = m_AllAdditionalData.begin(); it != itEnd; ++it)
  90. {
  91. (*it)->node->setVisible(visible);
  92. }
  93. }
  94. //------------------------------------------------------------------------------
  95. void
  96. ParticleEntityRenderer::Initialize()
  97. {
  98. // Use the given technique, although it should be the same as mParentTechnique (must be set already)
  99. if (!m_ParentTechnique || m_RendererInitialised)
  100. {
  101. return;
  102. }
  103. std::stringstream ss;
  104. ss << this;
  105. Ogre::String entity_name = m_MeshName + ss.str();
  106. int quota = m_ParentTechnique->GetVisualParticlesQuota();
  107. Ogre::SceneNode* parent_node = m_ParentTechnique->GetParentSystem()->getParentSceneNode();
  108. if (parent_node)
  109. {
  110. // Create number of visual_data objects including SceneNodes
  111. for (int i = 0; i < quota; i++)
  112. {
  113. ParticleEntityAdditionalData* visual_data = new ParticleEntityAdditionalData(parent_node->createChildSceneNode());
  114. m_AllAdditionalData.push_back(visual_data); // Used to assign to a particle
  115. m_UnassignedAdditionalData.push_back(visual_data); // Managed by this renderer
  116. }
  117. // Create number of Entities
  118. Ogre::Entity* entity = Ogre::Root::getSingleton().getSceneManager("Scene")->createEntity(entity_name, m_MeshName); // Base entity
  119. for( unsigned int i = 0; i < m_AllAdditionalData.size(); ++i )
  120. {
  121. Ogre::Entity* cloned_entity = entity->clone( entity_name + Ogre::StringConverter::toString( i ) );
  122. m_Entities.push_back( cloned_entity );
  123. m_AllAdditionalData[ i ]->node->attachObject( cloned_entity );
  124. }
  125. Ogre::Root::getSingleton().getSceneManager( "Scene" )->destroyEntity( entity_name );
  126. }
  127. SetVisible(false);
  128. m_RendererInitialised = true;
  129. }
  130. //------------------------------------------------------------------------------
  131. void
  132. ParticleEntityRenderer::UpdateRenderQueue(Ogre::RenderQueue* queue, ParticlePool<VisualParticle>& pool)
  133. {
  134. // Fast check to determine whether there are visual particles
  135. if (pool.IsEmpty())
  136. {
  137. return;
  138. }
  139. VisualParticle* particle = pool.GetFirst();
  140. while (!pool.End())
  141. {
  142. if (particle)
  143. {
  144. if (!particle->additional_data && !m_UnassignedAdditionalData.empty())
  145. {
  146. particle->additional_data = m_UnassignedAdditionalData.back();
  147. m_UnassignedAdditionalData.pop_back();
  148. }
  149. if (particle->additional_data)
  150. {
  151. Ogre::SceneNode* node = (static_cast<ParticleEntityAdditionalData*>(particle->additional_data))->node;
  152. if (node)
  153. {
  154. node->setPosition(particle->position);
  155. node->setVisible(true);
  156. }
  157. }
  158. }
  159. particle = pool.GetNext();
  160. }
  161. }
  162. //------------------------------------------------------------------------------