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; }
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; } }