#include "core/particles/renderer/ParticleEntityRenderer.h" #include #include #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(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::const_iterator it; std::vector::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::const_iterator it; std::vector::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& 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(particle->additional_data))->node; if (node) { node->setPosition(particle->position); node->setVisible(true); } } } particle = pool.GetNext(); } } //------------------------------------------------------------------------------