ParticleEmitter* ParticleEmitter::create(Properties* properties)
{
    if (!properties || strcmp(properties->getNamespace(), "particle") != 0)
    {
        GP_ERROR("Properties object must be non-null and have namespace equal to 'particle'.");
        return NULL;
    }

    Properties* sprite = properties->getNextNamespace();
    if (!sprite || strcmp(sprite->getNamespace(), "sprite") != 0)
    {
        GP_ERROR("Failed to load particle emitter: required namespace 'sprite' is missing.");
        return NULL;
    }

    // Load sprite properties.
    // Path to image file is required.
    const char* texturePath = sprite->getString("path");
    if (!texturePath || strlen(texturePath) == 0)
    {
        GP_ERROR("Failed to load particle emitter: required image file path ('path') is missing.");
        return NULL;
    }

    const char* blendingString = sprite->getString("blending");
    TextureBlending textureBlending = getTextureBlendingFromString(blendingString);
    int spriteWidth = sprite->getInt("width");
    int spriteHeight = sprite->getInt("height");
    bool spriteAnimated = sprite->getBool("animated");
    bool spriteLooped = sprite->getBool("looped");
    int spriteFrameCount = sprite->getInt("frameCount");
    int spriteFrameRandomOffset = sprite->getInt("frameRandomOffset");
    float spriteFrameDuration = sprite->getFloat("frameDuration");

    // Emitter properties.
    unsigned int particleCountMax = (unsigned int)properties->getInt("particleCountMax");
    if (particleCountMax == 0)
    {
        // Set sensible default.
        particleCountMax = PARTICLE_COUNT_MAX;
    }

    unsigned int emissionRate = (unsigned int)properties->getInt("emissionRate");
    if (emissionRate == 0)
    {
        emissionRate = PARTICLE_EMISSION_RATE;
    }

    bool ellipsoid = properties->getBool("ellipsoid");
    float sizeStartMin = properties->getFloat("sizeStartMin");
    float sizeStartMax = properties->getFloat("sizeStartMax");
    float sizeEndMin = properties->getFloat("sizeEndMin");
    float sizeEndMax = properties->getFloat("sizeEndMax");
    long energyMin = properties->getLong("energyMin");
    long energyMax = properties->getLong("energyMax");

    Vector4 colorStart;
    Vector4 colorStartVar;
    Vector4 colorEnd;
    Vector4 colorEndVar;
    properties->getVector4("colorStart", &colorStart);
    properties->getVector4("colorStartVar", &colorStartVar);
    properties->getVector4("colorEnd", &colorEnd);
    properties->getVector4("colorEndVar", &colorEndVar);

    Vector3 position;
    Vector3 positionVar;
    Vector3 velocity;
    Vector3 velocityVar;
    Vector3 acceleration;
    Vector3 accelerationVar;
    Vector3 rotationAxis;
    Vector3 rotationAxisVar;
    properties->getVector3("position", &position);
    properties->getVector3("positionVar", &positionVar);
    properties->getVector3("velocity", &velocity);
    properties->getVector3("velocityVar", &velocityVar);
    properties->getVector3("acceleration", &acceleration);
    properties->getVector3("accelerationVar", &accelerationVar);
    float rotationPerParticleSpeedMin = properties->getFloat("rotationPerParticleSpeedMin");
    float rotationPerParticleSpeedMax = properties->getFloat("rotationPerParticleSpeedMax");
    float rotationSpeedMin = properties->getFloat("rotationSpeedMin");
    float rotationSpeedMax = properties->getFloat("rotationSpeedMax");
    properties->getVector3("rotationAxis", &rotationAxis);
    properties->getVector3("rotationAxisVar", &rotationAxisVar);
    bool orbitPosition = properties->getBool("orbitPosition");
    bool orbitVelocity = properties->getBool("orbitVelocity");
    bool orbitAcceleration = properties->getBool("orbitAcceleration");

    // Apply all properties to a newly created ParticleEmitter.
    ParticleEmitter* emitter = ParticleEmitter::create(texturePath, textureBlending, particleCountMax);
    if (!emitter)
    {
        GP_ERROR("Failed to create particle emitter.");
        return NULL;
    }
    emitter->setEmissionRate(emissionRate);
    emitter->setEllipsoid(ellipsoid);
    emitter->setSize(sizeStartMin, sizeStartMax, sizeEndMin, sizeEndMax);
    emitter->setEnergy(energyMin, energyMax);
    emitter->setColor(colorStart, colorStartVar, colorEnd, colorEndVar);
    emitter->setPosition(position, positionVar);
    emitter->setVelocity(velocity, velocityVar);
    emitter->setAcceleration(acceleration, accelerationVar);
    emitter->setRotationPerParticle(rotationPerParticleSpeedMin, rotationPerParticleSpeedMax);
    emitter->setRotation(rotationSpeedMin, rotationSpeedMax, rotationAxis, rotationAxisVar);

    emitter->setSpriteAnimated(spriteAnimated);
    emitter->setSpriteLooped(spriteLooped);
    emitter->setSpriteFrameRandomOffset(spriteFrameRandomOffset);
    emitter->setSpriteFrameDuration(spriteFrameDuration);
    emitter->setSpriteFrameCoords(spriteFrameCount, spriteWidth, spriteHeight);

    emitter->setOrbit(orbitPosition, orbitVelocity, orbitAcceleration);

    return emitter;
}
Beispiel #2
0
void ParticlesGame::controlEvent(Control* control, EventType evt)
{
    std::string id = control->getId();

    // Handle UI events.
    ParticleEmitter* emitter = _particleEmitterNode->getParticleEmitter();
    switch(evt)
    {
    case Listener::VALUE_CHANGED:
        if (control == _startRed)
        {
            Vector4 startColor = emitter->getColorStart();
            startColor.x = _startRed->getValue();
            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
        }
        else if (control == _startGreen)
        {
            Vector4 startColor = emitter->getColorStart();
            startColor.y = _startGreen->getValue();
            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
        }
        else if (control == _startBlue)
        {
            Vector4 startColor = emitter->getColorStart();
            startColor.z = _startBlue->getValue();
            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
        }
        else if (control == _startAlpha)
        {
            Vector4 startColor = emitter->getColorStart();
            startColor.w = _startAlpha->getValue();
            emitter->setColor(startColor, emitter->getColorStartVariance(), emitter->getColorEnd(), emitter->getColorEndVariance());
        }
        else if (control == _endRed)
        {
            Vector4 endColor = emitter->getColorEnd();
            endColor.x = _endRed->getValue();
            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
        }
        else if (control == _endGreen)
        {
            Vector4 endColor = emitter->getColorEnd();
            endColor.y = _endGreen->getValue();
            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
        }
        else if (control == _endBlue)
        {
            Vector4 endColor = emitter->getColorEnd();
            endColor.z = _endBlue->getValue();
            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
        }
        else if (control == _endAlpha)
        {
            Vector4 endColor = emitter->getColorEnd();
            endColor.w = _endAlpha->getValue();
            emitter->setColor(emitter->getColorStart(), emitter->getColorStartVariance(), endColor, emitter->getColorEndVariance());
        }
        else if (control == _startMin)
        {
            emitter->setSize(_startMin->getValue(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
        }
        else if (control == _startMax)
        {
            emitter->setSize(emitter->getSizeStartMin(), _startMax->getValue(), emitter->getSizeEndMin(), emitter->getSizeEndMax());
        }
        else if (control == _endMin)
        {
            emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), _endMin->getValue(), emitter->getSizeEndMax());
        }
        else if (control == _endMax)
        {
            emitter->setSize(emitter->getSizeStartMin(), emitter->getSizeStartMax(), emitter->getSizeEndMin(), _endMax->getValue());
        }
        else if (control == _energyMin)
        {
            emitter->setEnergy(_energyMin->getValue(), emitter->getEnergyMax());
        }
        else if (control == _energyMax)
        {
            emitter->setEnergy(emitter->getEnergyMin(), _energyMax->getValue());
        }
        else if (control == _emissionRate)
        {
            emitter->setEmissionRate(_emissionRate->getValue());
        }
        else if (id == "posX")
        {
            Vector3 pos(emitter->getPosition());
            pos.x = ((Slider*)control)->getValue();
            emitter->setPosition(pos, emitter->getPositionVariance());
        }
        else if (id == "posY")
        {
            Vector3 pos(emitter->getPosition());
            pos.y = ((Slider*)control)->getValue();
            emitter->setPosition(pos, emitter->getPositionVariance());
        }
        else if (id == "posZ")
        {
            Vector3 pos(emitter->getPosition());
            pos.z = ((Slider*)control)->getValue();
            emitter->setPosition(pos, emitter->getPositionVariance());
        }
        else if (control == _posVarX)
        {
            Vector3 posVar = emitter->getPositionVariance();
            posVar.x = _posVarX->getValue();
            emitter->setPosition(emitter->getPosition(), posVar);
        }
        else if (control == _posVarY)
        {
            Vector3 posVar = emitter->getPositionVariance();
            posVar.y = _posVarY->getValue();
            emitter->setPosition(emitter->getPosition(), posVar);
        }
        else if (control == _posVarZ)
        {
            Vector3 posVar = emitter->getPositionVariance();
            posVar.z = _posVarZ->getValue();
            emitter->setPosition(emitter->getPosition(), posVar);
        }
        else if (control == _velX)
        {
            Vector3 vel = emitter->getVelocity();
            vel.x = _velX->getValue();
            emitter->setVelocity(vel, emitter->getVelocityVariance());
        }
        else if (control == _velY)
        {
            Vector3 vel = emitter->getVelocity();
            vel.y = _velY->getValue();
            emitter->setVelocity(vel, emitter->getVelocityVariance());
        }
        else if (control == _velZ)
        {
            Vector3 vel = emitter->getVelocity();
            vel.z = _velZ->getValue();
            emitter->setVelocity(vel, emitter->getVelocityVariance());
        }
        else if (control == _velVarX)
        {
            Vector3 velVar = emitter->getVelocityVariance();
            velVar.x = _velVarX->getValue();
            emitter->setVelocity(emitter->getVelocity(), velVar);
        }
        else if (control == _velVarY)
        {
            Vector3 velVar = emitter->getVelocityVariance();
            velVar.y = _velVarY->getValue();
            emitter->setVelocity(emitter->getVelocity(), velVar);
        }
        else if (control == _velVarZ)
        {
            Vector3 velVar = emitter->getVelocityVariance();
            velVar.z = _velVarZ->getValue();
            emitter->setVelocity(emitter->getVelocity(), velVar);
        }
        else if (control == _accelX)
        {
            Vector3 accel = emitter->getAcceleration();
            accel.x = _accelX->getValue();
            emitter->setAcceleration(accel, emitter->getAccelerationVariance());
        }
        else if (control == _accelY)
        {
            Vector3 accel = emitter->getAcceleration();
            accel.y = _accelY->getValue();
            emitter->setAcceleration(accel, emitter->getAccelerationVariance());
        }
        else if (control == _accelZ)
        {
            Vector3 accel = emitter->getAcceleration();
            accel.z = _accelZ->getValue();
            emitter->setAcceleration(accel, emitter->getAccelerationVariance());
        }
        else if (control == _accelVarX)
        {
            Vector3 accelVar = emitter->getAccelerationVariance();
            accelVar.x = _accelVarX->getValue();
            emitter->setAcceleration(emitter->getAcceleration(), accelVar);
        }
        else if (control == _accelVarY)
        {
            Vector3 accelVar = emitter->getAccelerationVariance();
            accelVar.y = _accelVarY->getValue();
            emitter->setAcceleration(emitter->getAcceleration(), accelVar);
        }
        else if (control == _accelVarZ)
        {
            Vector3 accelVar = emitter->getAccelerationVariance();
            accelVar.z = _accelVarZ->getValue();
            emitter->setAcceleration(emitter->getAcceleration(), accelVar);
        }
        else if (control == _spinSpeedMin)
        {
            emitter->setRotationPerParticle(_spinSpeedMin->getValue(), emitter->getRotationPerParticleSpeedMax());
        }
        else if (control == _spinSpeedMax)
        {
            emitter->setRotationPerParticle(emitter->getRotationPerParticleSpeedMin(), _spinSpeedMax->getValue());
        }
        else if (control == _axisX)
        {
            Vector3 axis = emitter->getRotationAxis();
            axis.x = _axisX->getValue();
            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
        }
        else if (control == _axisY)
        {
            Vector3 axis = emitter->getRotationAxis();
            axis.y = _axisY->getValue();
            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
        }
        else if (control == _axisZ)
        {
            Vector3 axis = emitter->getRotationAxis();
            axis.z = _axisZ->getValue();
            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), axis, emitter->getRotationAxisVariance());
        }
        else if (control == _axisVarX)
        {
            Vector3 axisVar = emitter->getRotationAxisVariance();
            axisVar.x = _axisVarX->getValue();
            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
        }
        else if (control == _axisVarY)
        {
            Vector3 axisVar = emitter->getRotationAxisVariance();
            axisVar.y = _axisVarY->getValue();
            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
        }
        else if (control == _axisVarZ)
        {
            Vector3 axisVar = emitter->getRotationAxisVariance();
            axisVar.z = _axisVarZ->getValue();
            emitter->setRotation(emitter->getRotationSpeedMin(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), axisVar);
        }
        else if (control == _rotationSpeedMin)
        {
            emitter->setRotation(_rotationSpeedMin->getValue(), emitter->getRotationSpeedMax(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
        }
        else if (control == _rotationSpeedMax)
        {
            emitter->setRotation(emitter->getRotationSpeedMin(), _rotationSpeedMax->getValue(), emitter->getRotationAxis(), emitter->getRotationAxisVariance());
        }
        else if (control == _started)
        {
            if (_started->isChecked())
            {
                emitter->start();
            }
            else
            {
                emitter->stop();
            }
        }
        else if (control == _vsync)
        {
            Game::getInstance()->setVsync(_vsync->isChecked());
        }
        else if (id == "additive")
        {
            if (((RadioButton*)control)->isSelected())
                emitter->setTextureBlending(ParticleEmitter::BLEND_ADDITIVE);
        }
        else if (id == "transparent")
        {
            if (((RadioButton*)control)->isSelected())
                emitter->setTextureBlending(ParticleEmitter::BLEND_TRANSPARENT);
        }
        else if (id == "multiply")
        {
            if (((RadioButton*)control)->isSelected())
                emitter->setTextureBlending(ParticleEmitter::BLEND_MULTIPLIED);
        }
        else if (id == "opaque")
        {
            if (((RadioButton*)control)->isSelected())
                emitter->setTextureBlending(ParticleEmitter::BLEND_OPAQUE);
        }
        break;
    case Listener::CLICK:
        if (control == _reset)
        {
            // Re-load the current emitter and reset the view
            _particleEmitter = ParticleEmitter::create(_url.c_str());
            emitterChanged();
        }
        else if (control == _emit)
        {
            // Emit a burst of particles.
            unsigned int burstSize = (unsigned int)_burstSize->getValue();
            emitter->emitOnce(burstSize);
        }
        else if (id == "sprite")
        {
            updateTexture();
        }
        else if (id == "updateFrames")
        {
            updateFrames();
        }
        break;
    case Listener::PRESS:
        if (control == _zoomIn)
        {
            _wDown = true;
        }
        else if (control == _zoomOut)
        {
            _sDown = true;
        }
        break;
    case Listener::RELEASE:
        if (control == _zoomIn)
        {
            _wDown = false;
        }
        else if (control == _zoomOut)
        {
            _sDown = false;
        }
        else if (control == _save)
        {
            Game::getInstance()->pause();
            saveFile();
            Game::getInstance()->resume();
        }
        else if (control == _load)
        {
            Game::getInstance()->pause();
            std::string filename = FileSystem::displayFileDialog(FileSystem::OPEN, "Select Particle File", "Particle Files", "particle", "res");
            if (filename.length() > 0)
            {
                _url = filename;
                _particleEmitter = ParticleEmitter::create(_url.c_str());
                emitterChanged();
            }
            Game::getInstance()->resume();
        }
        break;
    }
}