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);
    //	}
    //}
}
Example #4
0
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;
}
Example #8
0
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;
    }
}
Example #12
0
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();
}
Example #13
0
 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);
        }
    }
}