| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- #include "core/particles/renderer/ParticleEntityRenderer.h"
- #include <OgreEntity.h>
- #include <OgreRoot.h>
- #include "core/particles/ParticleSystem.h"
- #include "core/particles/ParticleTechnique.h"
- #include "core/particles/ParticleVisual.h"
- //------------------------------------------------------------------------------
- ParticleEntityRendererDictionary::MeshName ParticleEntityRenderer::m_MeshNameDictionary;
- //------------------------------------------------------------------------------
- ParticleEntityRenderer::ParticleEntityRenderer():
- ParticleRenderer(),
- m_MeshName(Ogre::StringUtil::BLANK)
- {
- m_RendererType = "Entity";
- if (createParamDictionary("ParticleEntityRenderer"))
- {
- Ogre::ParamDictionary* dict = getParamDictionary();
- dict->addParameter(Ogre::ParameterDef("mesh_name", "", Ogre::PT_STRING), &m_MeshNameDictionary);
- }
- }
- //------------------------------------------------------------------------------
- ParticleEntityRenderer::~ParticleEntityRenderer()
- {
- if (m_ParentTechnique == nullptr)
- {
- return;
- }
- Clear();
- }
- //------------------------------------------------------------------------------
- void
- ParticleEntityRenderer::CopyAttributesTo(ParticleRenderer* renderer)
- {
- // First copy parent attributes
- ParticleRenderer::CopyAttributesTo(renderer);
- // First cast to ParticleEntityRenderer
- ParticleEntityRenderer* entity_renderer = static_cast<ParticleEntityRenderer*>(renderer);
- // Copy attributes in case there is a entityRenderer (which should be available)
- entity_renderer->m_MeshName = m_MeshName;
- }
- //------------------------------------------------------------------------------
- const Ogre::String&
- ParticleEntityRenderer::GetMeshName() const
- {
- return m_MeshName;
- }
- //------------------------------------------------------------------------------
- void
- ParticleEntityRenderer::SetMeshName(const Ogre::String& mesh_name)
- {
- m_MeshName = mesh_name;
- m_RendererInitialised = false; // Retriggers the _prepare function
- Clear(); // Delete all nodes en entities, they will be rebuild
- }
- //------------------------------------------------------------------------------
- void
- ParticleEntityRenderer::Clear()
- {
- if (m_ParentTechnique == nullptr)
- {
- return;
- }
- // Note: The created ChildSceneNodes are destroyed when the ParticleSystem is destroyed
- std::vector<ParticleEntityAdditionalData*>::const_iterator it;
- std::vector<ParticleEntityAdditionalData*>::const_iterator itEnd = m_AllAdditionalData.end();
- for (it = m_AllAdditionalData.begin(); it != itEnd; ++it)
- {
- delete (*it);
- }
- m_AllAdditionalData.clear();
- m_UnassignedAdditionalData.clear();
- // Destroy the Entities. Do it like this, because it must be assured that the entity still exists
- // and has not already been destroyed.
- Ogre::SceneManager* scene_manager = Ogre::Root::getSingleton().getSceneManager("Scene");
- for( unsigned int i = 0; i < m_Entities.size(); i++ )
- {
- scene_manager->destroyEntity( m_Entities[ i ] );
- }
- m_Entities.clear();
- // Reset the visual data in the pool
- m_ParentTechnique->ResetVisualParticles();
- }
- //------------------------------------------------------------------------------
- void
- ParticleEntityRenderer::SetVisible(bool visible)
- {
- std::vector<ParticleEntityAdditionalData*>::const_iterator it;
- std::vector<ParticleEntityAdditionalData*>::const_iterator itEnd = m_AllAdditionalData.end();
- for (it = m_AllAdditionalData.begin(); it != itEnd; ++it)
- {
- (*it)->node->setVisible(visible);
- }
- }
- //------------------------------------------------------------------------------
- void
- ParticleEntityRenderer::Initialize()
- {
- // Use the given technique, although it should be the same as mParentTechnique (must be set already)
- if (!m_ParentTechnique || m_RendererInitialised)
- {
- return;
- }
- std::stringstream ss;
- ss << this;
- Ogre::String entity_name = m_MeshName + ss.str();
- int quota = m_ParentTechnique->GetVisualParticlesQuota();
- Ogre::SceneNode* parent_node = m_ParentTechnique->GetParentSystem()->getParentSceneNode();
- if (parent_node)
- {
- // Create number of visual_data objects including SceneNodes
- for (int i = 0; i < quota; i++)
- {
- ParticleEntityAdditionalData* visual_data = new ParticleEntityAdditionalData(parent_node->createChildSceneNode());
- m_AllAdditionalData.push_back(visual_data); // Used to assign to a particle
- m_UnassignedAdditionalData.push_back(visual_data); // Managed by this renderer
- }
- // Create number of Entities
- Ogre::Entity* entity = Ogre::Root::getSingleton().getSceneManager("Scene")->createEntity(entity_name, m_MeshName); // Base entity
- for( unsigned int i = 0; i < m_AllAdditionalData.size(); ++i )
- {
- Ogre::Entity* cloned_entity = entity->clone( entity_name + Ogre::StringConverter::toString( i ) );
- m_Entities.push_back( cloned_entity );
- m_AllAdditionalData[ i ]->node->attachObject( cloned_entity );
- }
- Ogre::Root::getSingleton().getSceneManager( "Scene" )->destroyEntity( entity_name );
- }
- SetVisible(false);
- m_RendererInitialised = true;
- }
- //------------------------------------------------------------------------------
- void
- ParticleEntityRenderer::UpdateRenderQueue(Ogre::RenderQueue* queue, ParticlePool<VisualParticle>& pool)
- {
- // Fast check to determine whether there are visual particles
- if (pool.IsEmpty())
- {
- return;
- }
- VisualParticle* particle = pool.GetFirst();
- while (!pool.End())
- {
- if (particle)
- {
- if (!particle->additional_data && !m_UnassignedAdditionalData.empty())
- {
- particle->additional_data = m_UnassignedAdditionalData.back();
- m_UnassignedAdditionalData.pop_back();
- }
- if (particle->additional_data)
- {
- Ogre::SceneNode* node = (static_cast<ParticleEntityAdditionalData*>(particle->additional_data))->node;
- if (node)
- {
- node->setPosition(particle->position);
- node->setVisible(true);
- }
- }
- }
- particle = pool.GetNext();
- }
- }
- //------------------------------------------------------------------------------
|