//------------------------------------------------------------------------------ void ParticleEmitterTranslator::translate(Ogre::ScriptCompiler *compiler, const Ogre::AbstractNodePtr &node) { Ogre::ObjectAbstractNode *obj = reinterpret_cast<Ogre::ObjectAbstractNode*>(node.get()); // name can't be empty because we get renderer type from it if(obj->name.empty()) { compiler->addError(Ogre::ScriptCompiler::CE_OBJECTNAMEEXPECTED, obj->file, obj->line); return; } ParticleTechnique* tech = Ogre::any_cast<ParticleTechnique*>(obj->parent->context); ParticleEmitter* emitter = tech->CreateEmitter(obj->name); if (emitter == NULL) { compiler->addError(Ogre::ScriptCompiler::CE_OBJECTALLOCATIONERROR, obj->file, obj->line); return; } Ogre::LogManager::getSingletonPtr()->logMessage("ParticleEmitterTranslator: create emitter."); for (Ogre::AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) { if ((*i)->type == Ogre::ANT_PROPERTY) { Ogre::PropertyAbstractNode *prop = reinterpret_cast<Ogre::PropertyAbstractNode*>((*i).get()); Ogre::String value = prop->getValue(); /* // Glob the values together for (Ogre::AbstractNodeList::iterator i = prop->values.begin(); i != prop->values.end(); ++i) { if((*i)->type == Ogre::ANT_ATOM) { if (value.empty()) { value = ((Ogre::AtomAbstractNode*)(*i).get())->value; } else { value = value + " " + ((Ogre::AtomAbstractNode*)(*i).get())->value; } } else { compiler->addError(Ogre::ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); break; } } */ Ogre::LogManager::getSingletonPtr()->logMessage("ParticleEmitterTranslator: Set param '" + prop->name + "' to '" + value + "'."); if (!emitter->setParameter(prop->name, value)) { compiler->addError(Ogre::ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); } } } }
//----------------------------------------------------------------------- void SlaveEmitter::_unprepare(ParticleTechnique* particleTechnique) { ParticleSystem* system = particleTechnique->getParentSystem(); if (system) { ParticleTechnique* masterTechnique = system->getTechnique(mMasterTechniqueName); if (masterTechnique) { masterTechnique->removeTechniqueListener(this); } } }
//----------------------------------------------------------------------- void SlaveEmitter::_prepare(ParticleTechnique* particleTechnique) { ParticleSystem* system = particleTechnique->getParentSystem(); if (system) { ParticleTechnique* masterTechnique = system->getTechnique(mMasterTechniqueName); if (masterTechnique) { masterTechnique->addTechniqueListener(this); } mEnabled = false; } }
//----------------------------------------------------------------------- void ParticleSystem::stopFade(void) { size_t i; size_t j; size_t numTechniques = getNumTechniques(); size_t numEmitters; ParticleTechnique* technique; ParticleEmitter* emitter; for (i = 0; i < numTechniques; ++i) { technique = getTechnique(i); numEmitters = getTechnique(i)->getNumEmitters(); for (j = 0; j < numEmitters; ++j) { emitter = technique->getEmitter(j); emitter->setEnabled(false); } } mStopFadeSet = true; }
//----------------------------------------------------------------------- void ParticlePool::_increaseParticleTechniquePool(size_t size, Particle::ParticleBehaviourList& behaviours, ParticleSystem* system) { size_t oldSize = mTechniques.size(); if (size < oldSize) return; // Create new techniques, based on the techniques in the particle system and which are marked for emission. size_t numberOfEmittedTechniques = system->getNumEmittedTechniques(); if (numberOfEmittedTechniques == 0) return; ParticleTechnique* existingTechnique = 0; ParticleTechnique* clonedTechnique = 0; size_t numTechniques = system->getNumTechniques(); // Distribute size equally size_t increment = (size-oldSize) / numberOfEmittedTechniques; // Run through techniques of the system for (size_t techniqueCount = 0; techniqueCount < numTechniques; techniqueCount++) { existingTechnique = system->getTechnique(techniqueCount); if (existingTechnique->_isMarkedForEmission()) { // Clone the technique 'increment' times and add to the pool for (size_t i = 0; i < increment; i++) { clonedTechnique = ParticleSystemManager::getSingletonPtr()->cloneTechnique(existingTechnique); clonedTechnique->_setMarkedForEmission(true); clonedTechnique->copyBehaviours(behaviours); mParticleTechniquePool.addElement(clonedTechnique->getName(), clonedTechnique); mTechniques.push_back(clonedTechnique); /** Important note: Calling the _prepare() function of the cloned techniques must not be done here. It is handled in the _update() function which is called when processing all particles in the pool. */ } } } }
//------------------------------------------------------------------------- void ExternTranslator::translate(ScriptCompiler* compiler, const AbstractNodePtr &node) { ObjectAbstractNode* obj = reinterpret_cast<ObjectAbstractNode*>(node.get()); ObjectAbstractNode* parent = obj->parent ? reinterpret_cast<ObjectAbstractNode*>(obj->parent) : 0; // The name of the obj is the type of the Extern // Remark: This can be solved by using a listener, so that obj->values is filled with type + name. Something for later String type; if(!obj->name.empty()) { type = obj->name; } else { compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); return; } // Get the factory ExternFactory* externFactory = ParticleSystemManager::getSingletonPtr()->getExternFactory(type); if (!externFactory) { compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); return; } // Create the Extern mExtern = ParticleSystemManager::getSingletonPtr()->createExtern(type); if (!mExtern) { compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); return; } if (!obj->parent->context.isEmpty()) { ParticleTechnique* technique = any_cast<ParticleTechnique*>(obj->parent->context); technique->addExtern(mExtern); } else { // It is an alias mExtern->setAliasName(parent->name); ParticleSystemManager::getSingletonPtr()->addAlias(mExtern); } // The first value is the (optional) name String name; if(!obj->values.empty()) { getString(obj->values.front(), &name); mExtern->setName(name); } // Set it in the context obj->context = Any(mExtern); // Run through properties for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) { // No properties of its own if((*i)->type == ANT_PROPERTY) { PropertyAbstractNode* prop = reinterpret_cast<PropertyAbstractNode*>((*i).get()); if (externFactory->translateChildProperty(compiler, *i)) { // Parsed the property by another translator; do nothing } else { errorUnexpectedProperty(compiler, prop); } } else if((*i)->type == ANT_OBJECT) { if (externFactory->translateChildObject(compiler, *i)) { // Parsed the object by another translator; do nothing } else { processNode(compiler, *i); } } else { errorUnexpectedToken(compiler, *i); } } }
//----------------------------------------------------------------------- void DoEnableComponentEventHandler::_handle (ParticleTechnique* particleTechnique, Particle* particle, Real timeElapsed) { /** Search for the component. */ ParticleTechnique* technique = 0; switch (mComponentType) { case CT_EMITTER: { ParticleEmitter* emitter = particleTechnique->getEmitter(mComponentName); if (!emitter) { // Search all techniques in this ParticleSystem for an emitter with the correct name ParticleSystem* system = particleTechnique->getParentSystem(); size_t size = system->getNumTechniques(); for(size_t i = 0; i < size; ++i) { technique = system->getTechnique(i); emitter = technique->getEmitter(mComponentName); if (emitter) { break; } } } if (emitter) { emitter->setEnabled(mComponentEnabled); } } break; case CT_AFFECTOR: { ParticleAffector* affector = particleTechnique->getAffector(mComponentName); if (!affector) { // Search all techniques in this ParticleSystem for an affector with the correct name ParticleSystem* system = particleTechnique->getParentSystem(); size_t size = system->getNumTechniques(); for(size_t i = 0; i < size; ++i) { technique = system->getTechnique(i); affector = technique->getAffector(mComponentName); if (affector) { break; } } } if (affector) { affector->setEnabled(mComponentEnabled); } } break; case CT_OBSERVER: { ParticleObserver* observer = particleTechnique->getObserver(mComponentName); if (!observer) { // Search all techniques in this ParticleSystem for an observer with the correct name ParticleSystem* system = particleTechnique->getParentSystem(); size_t size = system->getNumTechniques(); for(size_t i = 0; i < size; ++i) { technique = system->getTechnique(i); observer = technique->getObserver(mComponentName); if (observer) { break; } } } if (observer) { observer->setEnabled(mComponentEnabled); } } break; case CT_TECHNIQUE: { // Search in this ParticleSystem for a technique with the correct name ParticleSystem* system = particleTechnique->getParentSystem(); technique = system->getTechnique(mComponentName); if (technique) { technique->setEnabled(mComponentEnabled); } } break; } }