PUParticleSystem3D* PUParticleSystem3D::create( const std::string &filePath ) { std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath); convertToUnixStylePath(fullPath); std::string::size_type pos = fullPath.find_last_of("/"); std::string materialFolder = "materials"; if (pos != std::string::npos){ std::string temp = fullPath.substr(0, pos); pos = temp.find_last_of("/"); if (pos != std::string::npos){ materialFolder = temp.substr(0, pos + 1) + materialFolder; } } static std::vector<std::string> loadedFolder; if (std::find(loadedFolder.begin(), loadedFolder.end(), materialFolder) == loadedFolder.end()) { PUMaterialCache::Instance()->loadMaterialsFromSearchPaths(materialFolder); loadedFolder.push_back(materialFolder); } PUParticleSystem3D* ps = PUParticleSystem3D::create(); if (!ps->initSystem(fullPath)){ CC_SAFE_DELETE(ps); } return ps; }
void PUParticleSystem3D::resumeParticleSystem() { if (_state == State::PAUSE) { //if (_emitter) //{ // auto emitter = static_cast<PUEmitter*>(_emitter); // emitter->notifyResume(); //} for (auto& it : _emitters) { auto emitter = static_cast<PUEmitter*>(it); emitter->notifyResume(); } for (auto& it : _affectors) { auto affector = static_cast<PUAffector*>(it); affector->notifyResume(); } _state = State::RUNNING; } for (auto iter : _children) { PUParticleSystem3D *system = dynamic_cast<PUParticleSystem3D *>(iter); if (system) system->resumeParticleSystem(); } }
void PUParticleSystem3D::initParticleForExpiration( PUParticle3D* particle, float timeElapsed ) { if (particle->particleType == PUParticle3D::PT_EMITTER){ PUEmitter *emitter = static_cast<PUEmitter *>(particle->particleEntityPtr); emitter->unPrepare(); }else if (particle->particleType == PUParticle3D::PT_TECHNIQUE){ PUParticleSystem3D *system = static_cast<PUParticleSystem3D *>(particle->particleEntityPtr); system->unPrepared(); } particle->initForExpiration(timeElapsed); for (auto it : _listeners){ it->particleExpired(this, particle); } ///** Externs are also called to perform expiration activities. If needed, affectors and emitters may be added, but at the moment // there is no reason for (and we donĀ“t want to waste cpu resources). //*/ //if (!mExterns.empty()) //{ // ExternIterator itExtern; // ExternIterator itExternEnd = mExterns.end(); // for (itExtern = mExterns.begin(); itExtern != itExternEnd; ++itExtern) // { // (*itExtern)->_initParticleForExpiration(particle); // } //} }
void PUEmitter::prepare() { if (!_emitsEntity){ if (_emitsType == PUParticle3D::PT_EMITTER){ auto emitter = static_cast<PUParticleSystem3D *>(_particleSystem)->getEmitter(_emitsName); if (emitter){ emitter->setMarkedForEmission(true); _emitsEntity = emitter; } } else if (_emitsType == PUParticle3D::PT_TECHNIQUE){ PUParticleSystem3D *system = static_cast<PUParticleSystem3D *>(_particleSystem)->getParentParticleSystem(); if (system){ auto children = system->getChildren(); for (auto it : children){ if (it->getName() == _emitsName) { static_cast<PUParticleSystem3D *>(it)->setMarkedForEmission(true); _emitsEntity = it; break; } } } } } _latestPosition = getDerivedPosition(); // V1.3.1 }
const Vec3& PUAffector::getDerivedPosition() { PUParticleSystem3D *ps = static_cast<PUParticleSystem3D *>(_particleSystem); if (ps){ Mat4 rotMat; Mat4::createRotation(ps->getDerivedOrientation(), &rotMat); _derivedPosition = ps->getDerivedPosition() + rotMat * Vec3(_position.x * _affectorScale.x, _position.y * _affectorScale.y, _position.z * _affectorScale.z); //_particleSystem->getNodeToWorldTransform().transformPoint(_position, &_derivedPosition); } else _derivedPosition = _position; return _derivedPosition; //if (mMarkedForEmission) //{ // // Use the affector position, because it is emitted // // If a particle is emitted, position and derived position are the same // _derivedPosition = position; //} //else //{ // // Add the techniques' derived position // _derivedPosition = mParentTechnique->getDerivedPosition() + // mParentTechnique->getParentSystem()->getDerivedOrientation() * (_mAffectorScale * position); //} //return _derivedPosition; }
//----------------------------------------------------------------------- void PUDoPlacementParticleEventHandler::handle (PUParticleSystem3D* particleSystem, PUParticle3D* particle, float timeElapsed) { if (!particle) return; if (!_found) { auto system = particleSystem; auto emitter = system->getEmitter(_forceEmitterName); //ParticleTechnique* technique = particleTechnique; //ParticleEmitter* emitter = particleTechnique->getEmitter(_forceEmitterName); if (!emitter) { // Search all techniques in this ParticleSystem for an emitter with the correct name PUParticleSystem3D* parentSystem = particleSystem->getParentParticleSystem(); if (parentSystem){ auto children = parentSystem->getChildren(); for(auto iter : children) { PUParticleSystem3D *child = dynamic_cast<PUParticleSystem3D *>(iter); if (child){ system = child; emitter = system->getEmitter(_forceEmitterName); if (emitter) { break; } } } } } if (emitter) { _system = system; _emitter = emitter; if (_system) { _system->addListener(this); } _found = true; } else { return; } } // Emit 1 or more particles if (_system) { _baseParticle = particle; _system->forceEmission(_emitter, _numberOfParticles); } _baseParticle = 0; }
PUParticleSystem3D* PUParticleSystem3D::clone() { auto ps = PUParticleSystem3D::create(); copyAttributesTo(ps); for (auto &iter : _children){ PUParticleSystem3D *child = dynamic_cast<PUParticleSystem3D *>(iter); if (child) ps->addChild(child->clone()); } return ps; }
const Vec3& PUEmitter::getDerivedPosition() { if (_isMarkedForEmission){ _derivedPosition = _position; }else { PUParticleSystem3D *ps = static_cast<PUParticleSystem3D *>(_particleSystem); Mat4 rotMat; Mat4::createRotation(ps->getDerivedOrientation(), &rotMat); _derivedPosition = ps->getDerivedPosition() + rotMat * Vec3(_position.x * _emitterScale.x, _position.y * _emitterScale.y, _position.z * _emitterScale.z); //_particleSystem->getNodeToWorldTransform().transformPoint(_position, &_derivedPosition); } return _derivedPosition; }
PUParticleSystem3D* PUParticleSystem3D::create( const std::string &filePath, const std::string &materialPath ) { std::string matfullPath = FileUtils::getInstance()->fullPathForFilename(materialPath); convertToUnixStylePath(matfullPath); PUMaterialCache::Instance()->loadMaterials(matfullPath); PUParticleSystem3D* ps = PUParticleSystem3D::create(); std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath); convertToUnixStylePath(fullPath); if (!ps->initSystem(fullPath)){ CC_SAFE_DELETE(ps); } return ps; }
void PUParticleSystem3D::stopParticleSystem() { if (_state != State::STOP) { _state = State::STOP; } for (auto iter : _children) { PUParticleSystem3D *system = dynamic_cast<PUParticleSystem3D *>(iter); if (system) system->stopParticleSystem(); } }
PUParticleSystem3D* PUParticleSystem3D::create( const std::string &filePath ) { PUParticleSystem3D *ret = new (std::nothrow) PUParticleSystem3D(); if (ret && ret->initWithFilePath(filePath)) { ret->autorelease(); return ret; } else { CC_SAFE_DELETE(ret); return nullptr; } }
void PUVortexAffector::preUpdateAffector( float deltaTime ) { PUParticleSystem3D* sys = static_cast<PUParticleSystem3D *>(_particleSystem); if (sys) { Mat4 rotMat; Mat4::createRotation(sys->getDerivedOrientation(), &rotMat); _rotation.set(rotMat * _rotationVector, float(calculateRotationSpeed() * deltaTime)); } else { _rotation.set(_rotationVector, float(calculateRotationSpeed() * deltaTime)); } getDerivedPosition(); }
Node* Particle3DReader::createNodeWithFlatBuffers(const flatbuffers::Table *particle3DOptions) { auto options = (Particle3DOptions*)particle3DOptions; auto fileData = options->fileData(); std::string path = fileData->path()->c_str(); PUParticleSystem3D* ret = PUParticleSystem3D::create(); if (FileUtils::getInstance()->isFileExist(path)) { ret->initWithFilePath(path); } setPropsWithFlatBuffers(ret, particle3DOptions); if(ret) { ret->startParticleSystem(); } return ret; }
//----------------------------------------------------------------------- void PUDoAffectorEventHandler::handle (PUParticleSystem3D* particleSystem, PUParticle3D* particle, float timeElapsed) { /** Search for the affector. */ PUParticleSystem3D* technique = 0; PUAffector* affector = particleSystem->getAffector(_affectorName); if (!affector) { // Search all techniques in this ParticleSystem for an affector with the correct name PUParticleSystem3D* system = particleSystem->getParentParticleSystem(); auto children = system->getChildren(); for(auto iter : children) { technique = dynamic_cast<PUParticleSystem3D *>(iter); if (technique){ affector = technique->getAffector(_affectorName); if (affector) { break; } } } } if (affector) { // Call the affector even if it has enabled set to 'false'. if (_prePost) { affector->preUpdateAffector(timeElapsed); affector->updatePUAffector(particle, timeElapsed); affector->postUpdateAffector(timeElapsed); } else { affector->updatePUAffector(particle, timeElapsed); } } }
void PUParticleSystem3D::startParticleSystem() { stopParticleSystem(); if (_state != State::RUNNING) { forceStopParticleSystem(); if (_render) _render->notifyStart(); for (auto &it : _observers){ it->notifyStart(); } for (auto& it : _emitters) { auto emitter = static_cast<PUEmitter*>(it); emitter->notifyStart(); } for (auto& it : _affectors) { auto affector = static_cast<PUAffector*>(it); affector->notifyStart(); } scheduleUpdate(); _state = State::RUNNING; _latestPosition = getDerivedPosition(); // V1.3.1 } for (auto iter : _children) { PUParticleSystem3D *system = dynamic_cast<PUParticleSystem3D *>(iter); if (system){ system->_parentParticleSystem = this; system->startParticleSystem(); } } }
void PUTechniqueTranslator::translate(PUScriptCompiler* compiler, PUAbstractNode *node) { PUObjectAbstractNode* obj = reinterpret_cast<PUObjectAbstractNode*>(node); PUObjectAbstractNode* parent = obj->parent ? reinterpret_cast<PUObjectAbstractNode*>(obj->parent) : 0; // Create the technique _system = PUParticleSystem3D::create(); //mTechnique = ParticleSystemManager::getSingletonPtr()->createTechnique(); //if (!mTechnique) //{ // compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); // return; //} if (parent && parent->context) { PUParticleSystem3D* system = static_cast<PUParticleSystem3D*>(parent->context); system->addChild(_system); } //else //{ // // It is an alias // mTechnique->setAliasName(parent->name); // PU 1.4 // ParticleSystemManager::getSingletonPtr()->addAlias(mTechnique); //} _system->setName(obj->name); obj->context = _system; // Add this to the context, because it is needed for the underlying emitters, affectors, ... // Get the name of the technique //if(!obj->name.empty()) // mTechnique->setName(obj->name); for(PUAbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) { if((*i)->type == ANT_PROPERTY) { PUPropertyAbstractNode* prop = reinterpret_cast<PUPropertyAbstractNode*>((*i)); if (prop->name == token[TOKEN_ENABLED]) { // Property: enabled if (passValidateProperty(compiler, prop, token[TOKEN_ENABLED], VAL_BOOL)) { bool val; if(getBoolean(*prop->values.front(), &val)) { _system->setEnabled(val); } } } else if (prop->name == token[TOKEN_POSITION]) { // Property: positon if (passValidateProperty(compiler, prop, token[TOKEN_POSITION], VAL_VECTOR3)) { Vec3 val; if(getVector3(prop->values.begin(), prop->values.end(), &val)) { _system->setPosition3D(val); } } } else if (prop->name == token[TOKEN_KEEP_LOCAL]) { // Property: keep_local if (passValidateProperty(compiler, prop, token[TOKEN_KEEP_LOCAL], VAL_BOOL)) { bool val; if(getBoolean(*prop->values.front(), &val)) { _system->setKeepLocal(val); } } } else if (prop->name == token[TOKEN_TECH_VISUAL_PARTICLE_QUOTA]) { // Property: visual_particle_quota if (passValidateProperty(compiler, prop, token[TOKEN_TECH_VISUAL_PARTICLE_QUOTA], VAL_UINT)) { unsigned int val = 0; if(getUInt(*prop->values.front(), &val)) { _system->setParticleQuota(val); } } } else if (prop->name == token[TOKEN_TECH_EMITTED_EMITTER_QUOTA]) { // Property: emitted_emitter_quota if (passValidateProperty(compiler, prop, token[TOKEN_TECH_EMITTED_EMITTER_QUOTA], VAL_UINT)) { unsigned int val = 0; if(getUInt(*prop->values.front(), &val)) { _system->setEmittedEmitterQuota(val); } } } else if (prop->name == token[TOKEN_TECH_EMITTED_AFFECTOR_QUOTA]) { //// Property: emitted_affector_quota //if (passValidateProperty(compiler, prop, token[TOKEN_TECH_EMITTED_AFFECTOR_QUOTA], VAL_UINT)) //{ // uint val = 0; // if(getUInt(prop->values.front(), &val)) // { // mTechnique->setEmittedAffectorQuota(val); // } //} } else if (prop->name == token[TOKEN_TECH_EMITTED_TECHNIQUE_QUOTA]) { // Property: emitted_technique_quota if (passValidateProperty(compiler, prop, token[TOKEN_TECH_EMITTED_TECHNIQUE_QUOTA], VAL_UINT)) { unsigned int val = 0; if(getUInt(*prop->values.front(), &val)) { _system->setEmittedSystemQuota(val); } } } else if (prop->name == token[TOKEN_TECH_EMITTED_SYSTEM_QUOTA]) { //// Property: emitted_system_quota //if (passValidateProperty(compiler, prop, token[TOKEN_TECH_EMITTED_SYSTEM_QUOTA], VAL_UINT)) //{ // uint val = 0; // if(getUInt(prop->values.front(), &val)) // { // mTechnique->setEmittedSystemQuota(val); // } //} } else if (prop->name == token[TOKEN_MATERIAL]) { // Property: material if (passValidateProperty(compiler, prop, token[TOKEN_MATERIAL], VAL_STRING)) { std::string val; if(getString(*prop->values.front(), &val)) { _system->setMaterialName(val); PUMaterial *material = PUMaterialCache::Instance()->getMaterial(val); if (material){ _system->setBlendFunc(material->blendFunc); } } } } else if (prop->name == token[TOKEN_TECH_LOD_INDEX]) { //// Property: lod_index //if (passValidateProperty(compiler, prop, token[TOKEN_TECH_LOD_INDEX], VAL_UINT)) //{ // uint val = 0; // if(getUInt(prop->values.front(), &val)) // { // mTechnique->setLodIndex(val); // } //} } else if (prop->name == token[TOKEN_TECH_DEFAULT_PARTICLE_WIDTH]) { // Property: default_particle_width if (passValidateProperty(compiler, prop, token[TOKEN_TECH_DEFAULT_PARTICLE_WIDTH], VAL_REAL)) { float val = 0.0f; if(getFloat(*prop->values.front(), &val)) { _system->setDefaultWidth(val); } } } else if (prop->name == token[TOKEN_TECH_DEFAULT_PARTICLE_HEIGHT]) { // Property: default_particle_height if (passValidateProperty(compiler, prop, token[TOKEN_TECH_DEFAULT_PARTICLE_HEIGHT], VAL_REAL)) { float val = 0.0f; if(getFloat(*prop->values.front(), &val)) { _system->setDefaultHeight(val); } } } else if (prop->name == token[TOKEN_TECH_DEFAULT_PARTICLE_DEPTH]) { // Property: default_particle_depth if (passValidateProperty(compiler, prop, token[TOKEN_TECH_DEFAULT_PARTICLE_DEPTH], VAL_REAL)) { float val = 0.0f; if(getFloat(*prop->values.front(), &val)) { _system->setDefaultDepth(val); } } } else if (prop->name == token[TOKEN_TECH_SPHASHING_CELL_DIMENSION]) { //// Property: spatial_hashing_cell_dimension //if (passValidateProperty(compiler, prop, token[TOKEN_TECH_SPHASHING_CELL_DIMENSION], VAL_UINT)) //{ // unsigned int val = 0; // if(getUInt(prop->values.front(), &val)) // { // mTechnique->setSpatialHashingCellDimension(val); // } //} } else if (prop->name == token[TOKEN_TECH_SPHASHING_CELL_OVERLAP]) { //// Property: spatial_hashing_cell_overlap //if (passValidateProperty(compiler, prop, token[TOKEN_TECH_SPHASHING_CELL_OVERLAP], VAL_UINT)) //{ // unsigned int val = 0; // if(getUInt(prop->values.front(), &val)) // { // mTechnique->setSpatialHashingCellOverlap(val); // } //} } else if (prop->name == token[TOKEN_TECH_SPHASHING_SIZE]) { //// Property: spatial_hashtable_size //if (passValidateProperty(compiler, prop, token[TOKEN_TECH_SPHASHING_SIZE], VAL_UINT)) //{ // unsigned int val = 0; // if(getUInt(prop->values.front(), &val)) // { // mTechnique->setSpatialHashTableSize(val); // } //} } else if (prop->name == token[TOKEN_TECH_SPHASHING_UPDATE_INTERVAL]) { //// Property: spatial_hashing_update_interval //if (passValidateProperty(compiler, prop, token[TOKEN_TECH_SPHASHING_UPDATE_INTERVAL], VAL_REAL)) //{ // float val = 0.0f; // if(getReal(prop->values.front(), &val)) // { // mTechnique->setSpatialHashingInterval(val); // } //} } else if (prop->name == token[TOKEN_TECH_MAX_VELOCITY]) { // Property: max_velocity if (passValidateProperty(compiler, prop, token[TOKEN_TECH_MAX_VELOCITY], VAL_REAL)) { float val = 0.0f; if(getFloat(*prop->values.front(), &val)) { _system->setMaxVelocity(val); } } } else if (prop->name == token[TOKEN_USE_ALIAS]) { //// Property: use_alias //if (passValidateProperty(compiler, prop, token[TOKEN_USE_ALIAS], VAL_STRING)) //{ // String val; // if(getString(prop->values.front(), &val)) // { // IAlias* alias = ParticleSystemManager::getSingletonPtr()->getAlias(val); // switch (alias->getAliasType()) // { // case IAlias::AT_RENDERER: // { // ParticleRenderer* renderer = static_cast<ParticleRenderer*>(alias); // ParticleRenderer* newRenderer = ParticleSystemManager::getSingletonPtr()->cloneRenderer(renderer); // mTechnique->setRenderer(newRenderer); // } // break; // // case IAlias::AT_EMITTER: // { // ParticleEmitter* emitter = static_cast<ParticleEmitter*>(alias); // ParticleEmitter* newEmitter = ParticleSystemManager::getSingletonPtr()->cloneEmitter(emitter); // mTechnique->addEmitter(newEmitter); // } // break; // // case IAlias::AT_AFFECTOR: // { // ParticleAffector* affector = static_cast<ParticleAffector*>(alias); // ParticleAffector* newAffector = ParticleSystemManager::getSingletonPtr()->cloneAffector(affector); // mTechnique->addAffector(newAffector); // } // break; // // case IAlias::AT_OBSERVER: // { // ParticleObserver* observer = static_cast<ParticleObserver*>(alias); // ParticleObserver* newObserver = ParticleSystemManager::getSingletonPtr()->cloneObserver(observer); // mTechnique->addObserver(newObserver); // } // break; // // case IAlias::AT_EXTERN: // { // Extern* externObject = static_cast<Extern*>(alias); // Extern* newExternObject = ParticleSystemManager::getSingletonPtr()->cloneExtern(externObject); // mTechnique->addExtern(newExternObject); // } // break; // // case IAlias::AT_BEHAVIOUR: // { // ParticleBehaviour* behaviour = static_cast<ParticleBehaviour*>(alias); // ParticleBehaviour* newBehaviour = ParticleSystemManager::getSingletonPtr()->cloneBehaviour(behaviour); // mTechnique->_addBehaviourTemplate(newBehaviour); // } // break; // } // } //} } else { errorUnexpectedProperty(compiler, prop); } } else if((*i)->type == ANT_OBJECT) { //ObjectAbstractNode* child = reinterpret_cast<ObjectAbstractNode*>((*i).get()); //if (child->cls == token[TOKEN_CAMERA_DEPENDENCY]) //{ // // Property: camera_dependency // CameraDependency* cameraDependency = PU_NEW_T(CameraDependency, MEMCATEGORY_SCRIPTING)(); // child->context = Any(cameraDependency); // CameraDependencyTranslator cameraDependencyTranslator; // cameraDependencyTranslator.translate(compiler, *i); // Real threshold = cameraDependency->getThreshold(); // bool increase = cameraDependency->isIncrease(); // if (child->name == token[TOKEN_TECH_DEFAULT_PARTICLE_WIDTH]) // { // mTechnique->setWidthCameraDependency(threshold * threshold, increase); // } // else if (child->name == token[TOKEN_TECH_DEFAULT_PARTICLE_HEIGHT]) // { // mTechnique->setHeightCameraDependency(threshold * threshold, increase); // } // else if (child->name == token[TOKEN_TECH_DEFAULT_PARTICLE_DEPTH]) // { // mTechnique->setDepthCameraDependency(threshold * threshold, increase); // } // // Delete the camera dependency // PU_DELETE_T(cameraDependency, CameraDependency, MEMCATEGORY_SCRIPTING); //} //else { processNode(compiler, *i); } } else { errorUnexpectedToken(compiler, *i); } } }
//------------------------------------------------------------------------- void PUAffectorTranslator::translate(PUScriptCompiler* compiler, PUAbstractNode *node) { PUObjectAbstractNode* obj = reinterpret_cast<PUObjectAbstractNode*>(node); PUObjectAbstractNode* parent = obj->parent ? reinterpret_cast<PUObjectAbstractNode*>(obj->parent) : 0; // The name of the obj is the type of the affector // Remark: This can be solved by using a listener, so that obj->values is filled with type + name. Something for later std::string type; if(!obj->name.empty()) { type = obj->name; } //// Get the factory //ParticleAffectorFactory* particleAffectorFactory = ParticleSystemManager::getSingletonPtr()->getAffectorFactory(type); //if (!particleAffectorFactory) //{ // compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); // return; //} PUScriptTranslator *particleAffectorTranlator = PUAffectorManager::Instance()->getTranslator(type); if (!particleAffectorTranlator) return; //// Create the affector //mAffector = ParticleSystemManager::getSingletonPtr()->createAffector(type); //if (!mAffector) //{ // compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); // return; //} _affector = PUAffectorManager::Instance()->createAffector(type); if (!_affector) return; _affector->setAffectorType(type); if (parent && parent->context) { PUParticleSystem3D* system = static_cast<PUParticleSystem3D*>(parent->context); system->addAffector(_affector); } // The first value is the (optional) name std::string name; if(!obj->values.empty()) { getString(*obj->values.front(), &name); _affector->setName(name); } // Set it in the context obj->context = _affector; // Run through properties for(PUAbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) { if((*i)->type == ANT_PROPERTY) { PUPropertyAbstractNode* prop = reinterpret_cast<PUPropertyAbstractNode*>((*i)); if (prop->name == token[TOKEN_ENABLED]) { // Property: enabled if (passValidateProperty(compiler, prop, token[TOKEN_ENABLED], VAL_BOOL)) { bool val; if(getBoolean(*prop->values.front(), &val)) { _affector->setEnabled(val); } } } else if (prop->name == token[TOKEN_POSITION]) { // Property: position if (passValidateProperty(compiler, prop, token[TOKEN_POSITION], VAL_VECTOR3)) { Vec3 val; if(getVector3(prop->values.begin(), prop->values.end(), &val)) { //mAffector->position = val; //mAffector->originalPosition = val; _affector->setLocalPosition(val); } } } else if (prop->name == token[TOKEN_AFFECTOR_MASS]) { if (passValidateProperty(compiler, prop, token[TOKEN_AFFECTOR_MASS], VAL_REAL)) { float val = 0.0f; if(getFloat(*prop->values.front(), &val)) { _affector->setMass(val); } } } else if (prop->name == token[TOKEN_AFFECTOR_SPECIALISATION]) { if (passValidateProperty(compiler, prop, token[TOKEN_AFFECTOR_SPECIALISATION], VAL_STRING)) { std::string val; if(getString(*prop->values.front(), &val)) { if (val == token[TOKEN_AFFECTOR_SPEC_DEFAULT]) { _affector->setAffectSpecialisation(PUAffector::AFSP_DEFAULT); } else if (val == token[TOKEN_AFFECTOR_SPEC_TTL_INCREASE]) { _affector->setAffectSpecialisation(PUAffector::AFSP_TTL_INCREASE); } else if (val == token[TOKEN_AFFECTOR_SPEC_TTL_DECREASE]) { _affector->setAffectSpecialisation(PUAffector::AFSP_TTL_DECREASE); } } } } else if (prop->name == token[TOKEN_AFFECTOR_EXCLUDE_EMITTER]) { if (passValidatePropertyNoValues(compiler, prop, token[TOKEN_AFFECTOR_EXCLUDE_EMITTER])) { for(PUAbstractNodeList::iterator j = prop->values.begin(); j != prop->values.end(); ++j) { std::string val; if(getString(**j, &val)) { _affector->addEmitterToExclude(val); } } } } else if (particleAffectorTranlator->translateChildProperty(compiler, *i)) { // Parsed the property by another translator; do nothing } else { errorUnexpectedProperty(compiler, prop); } } else if((*i)->type == ANT_OBJECT) { if (particleAffectorTranlator->translateChildObject(compiler, *i)) { // Parsed the object by another translator; do nothing } else { processNode(compiler, *i); } } else { errorUnexpectedToken(compiler, *i); } } }
void PUParticleSystem3D::prepared() { if (!_prepared){ //if (_emitter && _emitter->isEnabled()) //{ // auto emitter = static_cast<PUEmitter*>(_emitter); // emitter->prepare(); //} if (_render) static_cast<PURender *>(_render)->prepare(); for (auto it : _behaviourTemplates) { it->prepare(); } for (auto it : _emitters) { //if (it->isEnabled()) (static_cast<PUEmitter*>(it))->prepare(); } for (auto it : _affectors) { //if (it->isEnabled()) (static_cast<PUAffector*>(it))->prepare(); } if (!_poolPrepared){ for (auto it : _emitters) { //if (it->isEnabled()) PUEmitter *emitter = static_cast<PUEmitter*>(it); if (emitter->getEmitsType() == PUParticle3D::PT_EMITTER){ PUEmitter *emitted = static_cast<PUEmitter*>(emitter->getEmitsEntityPtr()); for (unsigned int i = 0; i < _emittedEmitterQuota; ++i){ auto p = new (std::nothrow) PUParticle3D(); p->particleType = PUParticle3D::PT_EMITTER; p->particleEntityPtr = emitted->clone(); p->particleEntityPtr->retain(); p->copyBehaviours(_behaviourTemplates); _emittedEmitterParticlePool[emitted->getName()].addData(p); } } else if (emitter->getEmitsType() == PUParticle3D::PT_TECHNIQUE){ PUParticleSystem3D *emitted = static_cast<PUParticleSystem3D*>(emitter->getEmitsEntityPtr()); for (unsigned int i = 0; i < _emittedSystemQuota; ++i){ PUParticleSystem3D *clonePS = emitted->clone(); auto p = new (std::nothrow) PUParticle3D(); p->particleType = PUParticle3D::PT_TECHNIQUE; p->particleEntityPtr = clonePS; p->particleEntityPtr->retain(); p->copyBehaviours(_behaviourTemplates); _emittedSystemParticlePool[emitted->getName()].addData(p); clonePS->prepared(); } //emitted->stopParticle(); } } for (unsigned int i = 0; i < _particleQuota; ++i){ auto p = new (std::nothrow) PUParticle3D(); p->copyBehaviours(_behaviourTemplates); _particlePool.addData(p); } _poolPrepared = true; } _prepared = true; _timeElapsedSinceStart = 0.0f; if (_parentParticleSystem){ _particleSystemScaleVelocity = _parentParticleSystem->getParticleSystemScaleVelocity(); } } notifyRescaled(getDerivedScale()); }
//------------------------------------------------------------------------- void PUBehaviourTranslator::translate(PUScriptCompiler* compiler, PUAbstractNode *node) { PUObjectAbstractNode* obj = reinterpret_cast<PUObjectAbstractNode*>(node); PUObjectAbstractNode* parent = obj->parent ? reinterpret_cast<PUObjectAbstractNode*>(obj->parent) : 0; // The name of the obj is the type of the Behaviour std::string type; if(!obj->name.empty()) { type = obj->name; } else { //compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); return; } //// Get the factory //ParticleBehaviourFactory* behaviourFactory = ParticleSystemManager::getSingletonPtr()->getBehaviourFactory(type); //if (!behaviourFactory) //{ // //compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); // return; //} PUScriptTranslator *particleBehaviourTranlator = PUBehaviourManager::Instance()->getTranslator(type); if (!particleBehaviourTranlator) return; // Create the Behaviour _behaviour = PUBehaviourManager::Instance()->createBehaviour(type); if (!_behaviour) { //compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); return; } _behaviour->setBehaviourType(type); if (parent && parent->context) { PUParticleSystem3D* system = static_cast<PUParticleSystem3D*>(parent->context); system->addBehaviourTemplate(_behaviour); } else { //// It is an alias //_behaviour->setAliasName(parent->name); //ParticleSystemManager::getSingletonPtr()->addAlias(mBehaviour); } // Set it in the context obj->context = _behaviour; // Run through properties for(PUAbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) { // No properties of its own if((*i)->type == ANT_PROPERTY) { PUPropertyAbstractNode* prop = reinterpret_cast<PUPropertyAbstractNode*>((*i)); if (particleBehaviourTranlator->translateChildProperty(compiler, *i)) { // Parsed the property by another translator; do nothing } else { errorUnexpectedProperty(compiler, prop); } } else if((*i)->type == ANT_OBJECT) { if (particleBehaviourTranlator->translateChildObject(compiler, *i)) { // Parsed the object by another translator; do nothing } else { processNode(compiler, *i); } } else { errorUnexpectedToken(compiler, *i); } } }
//----------------------------------------------------------------------- void PUDoEnableComponentEventHandler::handle (PUParticleSystem3D* particleSystem, PUParticle3D* /*particle*/, float /*timeElapsed*/) { /** Search for the component. */ //ParticleTechnique* technique = 0; switch (_componentType) { case CT_EMITTER: { PUEmitter* emitter = particleSystem->getEmitter(_componentName); if (!emitter) { // Search all techniques in this ParticleSystem for an emitter with the correct name PUParticleSystem3D* system = particleSystem->getParentParticleSystem(); if (system){ auto children = system->getChildren(); for(auto iter : children) { PUParticleSystem3D *child = dynamic_cast<PUParticleSystem3D *>(iter); if (child){ emitter = child->getEmitter(_componentName); if (emitter) { break; } } } } } if (emitter) { emitter->setEnabled(_componentEnabled); } } break; case CT_AFFECTOR: { PUAffector* affector = particleSystem->getAffector(_componentName); if (!affector) { // Search all techniques in this ParticleSystem for an emitter with the correct name PUParticleSystem3D* system = particleSystem->getParentParticleSystem(); if (system){ auto children = system->getChildren(); for(auto iter : children) { PUParticleSystem3D *child = dynamic_cast<PUParticleSystem3D *>(iter); if (child){ affector = child->getAffector(_componentName); if (affector) { break; } } } } } if (affector) { affector->setEnabled(_componentEnabled); } } break; case CT_OBSERVER: { PUObserver* observer = particleSystem->getObserver(_componentName); if (!observer) { // Search all techniques in this ParticleSystem for an emitter with the correct name PUParticleSystem3D* system = particleSystem->getParentParticleSystem(); if (system){ auto children = system->getChildren(); for(auto iter : children) { PUParticleSystem3D *child = dynamic_cast<PUParticleSystem3D *>(iter); if (child){ observer = child->getObserver(_componentName); if (observer) { break; } } } } } if (observer) { observer->setEnabled(_componentEnabled); } } break; case CT_TECHNIQUE: { // Search in this ParticleSystem for a technique with the correct name PUParticleSystem3D* system = particleSystem->getParentParticleSystem(); if (system){ auto children = system->getChildren(); for (auto iter : children){ PUParticleSystem3D *child = dynamic_cast<PUParticleSystem3D *>(iter); if (child && child->getName() == _componentName){ child->setEnabled(_componentEnabled); break; } } } } break; default: break; } }
//------------------------------------------------------------------------- void PUObserverTranslator::translate(PUScriptCompiler* compiler, PUAbstractNode *node) { PUObjectAbstractNode* obj = reinterpret_cast<PUObjectAbstractNode*>(node); PUObjectAbstractNode* parent = obj->parent ? reinterpret_cast<PUObjectAbstractNode*>(obj->parent) : 0; // The name of the obj is the type of the Observer // Remark: This can be solved by using a listener, so that obj->values is filled with type + name. Something for later std::string type; if(!obj->name.empty()) { type = obj->name; } else { //compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); return; } // Get the factory //ParticleObserverFactory* particleObserverFactory = ParticleSystemManager::getSingletonPtr()->getObserverFactory(type); //if (!particleObserverFactory) //{ // //compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); // return; //} PUScriptTranslator *particleObserverTranlator = PUObserverManager::Instance()->getTranslator(type); if (!particleObserverTranlator) return; // Create the Observer _observer = PUObserverManager::Instance()->createObserver(type); if (!_observer) { //compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, obj->file, obj->line); return; } _observer->setObserverType(type); if (parent && parent->context) { PUParticleSystem3D* system = static_cast<PUParticleSystem3D *>(parent->context); system->addObserver(_observer); } else { //// It is an alias //mObserver->setAliasName(parent->name); //ParticleSystemManager::getSingletonPtr()->addAlias(mObserver); } // The first value is the (optional) name std::string name; if(!obj->values.empty()) { getString(*obj->values.front(), &name); _observer->setName(name); } // Set it in the context obj->context = _observer; // Run through properties for(PUAbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) { if((*i)->type == ANT_PROPERTY) { PUPropertyAbstractNode* prop = reinterpret_cast<PUPropertyAbstractNode*>((*i)); if (prop->name == token[TOKEN_ENABLED]) { // Property: enabled if (passValidateProperty(compiler, prop, token[TOKEN_ENABLED], VAL_BOOL)) { bool val; if(getBoolean(*prop->values.front(), &val)) { _observer->setEnabled(val); } } } else if (prop->name == token[TOKEN_OBSERVE_PARTICLE_TYPE]) { // Property: observe_particle_type if (passValidateProperty(compiler, prop, token[TOKEN_OBSERVE_PARTICLE_TYPE], VAL_STRING)) { std::string val; if(getString(*prop->values.front(), &val)) { if (val == token[TOKEN_VISUAL_PARTICLE]) { _observer->setParticleTypeToObserve(PUParticle3D::PT_VISUAL); } else if (val == token[TOKEN_EMITTER_PARTICLE]) { _observer->setParticleTypeToObserve(PUParticle3D::PT_EMITTER); } else if (val == token[TOKEN_AFFECTOR_PARTICLE]) { _observer->setParticleTypeToObserve(PUParticle3D::PT_AFFECTOR); } else if (val == token[TOKEN_TECHNIQUE_PARTICLE]) { _observer->setParticleTypeToObserve(PUParticle3D::PT_TECHNIQUE); } else if (val == token[TOKEN_SYSTEM_PARTICLE]) { _observer->setParticleTypeToObserve(PUParticle3D::PT_SYSTEM); } } } } else if (prop->name == token[TOKEN_OBSERVE_INTERVAL]) { // Property: observe_interval if (passValidateProperty(compiler, prop, token[TOKEN_OBSERVE_INTERVAL], VAL_REAL)) { float val; if(getFloat(*prop->values.front(), &val)) { _observer->setObserverInterval(val); } } } else if (prop->name == token[TOKEN_OBSERVE_UNTIL_EVENT]) { // Property: observe_until_event if (passValidateProperty(compiler, prop, token[TOKEN_OBSERVE_UNTIL_EVENT], VAL_BOOL)) { bool val; if(getBoolean(*prop->values.front(), &val)) { _observer->setObserveUntilEvent(val); } } } else if (particleObserverTranlator->translateChildProperty(compiler, *i)) { // Parsed the property by another translator; do nothing } else { errorUnexpectedProperty(compiler, prop); } } else if((*i)->type == ANT_OBJECT) { if (particleObserverTranlator->translateChildObject(compiler, *i)) { // Parsed the object by another translator; do nothing } else { processNode(compiler, *i); } } else { errorUnexpectedToken(compiler, *i); } } }