//void ParticleEngine::addEmitter(Ship* ship, int particleType){ void ParticleEngine::addEmitter(btVector3* pos, EmitterType type, bool onlyActiveWhenFast, bool timed, int imageIndex) { if(imageIndex == -1) imageIndex = type; ParticleEmitter newEmitter(pos, particleShaders[0], particleImages[imageIndex], this->width, onlyActiveWhenFast, type); emitters.push_back(newEmitter); }
ParticleParameters::ParticleParameters(QWidget *parent) : QWidget(parent), ui(new Ui::ParticleParameters) { ui->setupUi(this); m_applyAutomatically = false; ui->ApplyAutoCheckbox->setChecked(false); newEmitter(); }
void addExamples() { int db = 50; for (int i = 1; i < 50; i += 12 + rand()%10) for (int j = 1; j < 50; j += 12 + rand()%10) addEmitter(newEmitter("smoke", 80 * 1000, 0, "smoke", 100, 400 + i, 400 + j, 0, 360, 0, 10, 14)); addEmitter(newEmitter("ball", 0, 0, "ball", 100, 0, 0, 0, 0, 0, 0, 0)); addEmitterGroup("img/siva.png", .4, .4, .01, newEmitter("siva", 0, 0, "siva", 1, (1-.618) * w.width, .618 * w.height, 0, 360, 0, 0, 0)); int wait = 50 * 1000; addEmitter(newEmitter("sun", wait, 0, "sun", 1000, .618 * w.width, (1-.618) * w.height, 0, 360, 50, 30, 100)); addEmitter(newEmitter("sun", wait, 0, "sun", 100, .618 * w.width - 20, (1-.618) * w.height -20, 0, 360, 0, 10, 10)); addEmitter(newEmitter("sun", wait, 0, "sun", 100, .618 * w.width + 20, (1-.618) * w.height - 20, 0, 360, 0, 10, 10)); addEmitter(newEmitter("sun", wait, 0, "sun", 100, .618 * w.width, (1-.618) * w.height + 20, 0, 360, 10, 10, 10)); for(int i = 1; i <= 4; i++) { char str[20]; sprintf(str, "img/idezet%i.png", i); addEmitterGroup(str, 2, 2, .003, newEmitter(str, i * 8 * 1000, 0, "siva", 1, w.width / 2.0, w.height / 2.0, 0, 360, 0, 0, 0)); } //for(int j = 1; j <= 60; j+=50) // for(int i = 1; i <= w.width; i+=50) // addEmitter(newEmitter("water", rand()%1000, 0, "water", 1, i, .9 * w.height + j, 0, 0, 0, 3, 6)); //addEmitter(newEmitter("smoke", 0 * 1000, 4, "smoke", 10, 400, 200, 0, 360, 0, 5, 10)); for (int i = 1; i <= 4; i++) addEmitter(newEmitter("demoBoubleGroup", 0 * 1000, 0, "bouble", db, i * 100, i * 100, 0, 360, 0, 50, 50)); addEmitter(newEmitter("demoBoubleGroup5", 40 * 1000, 0, "bouble", 2 * db, 300, 600, 0, 260, 0, 150, 200)); addEmitter(newEmitter("centeredBouble", 40 * 1000, 0, "bouble", db, w.width / 2.0, w.height / 2.0, 0, 360, 0, 50, 50)); addEmitter(newEmitter("centeredWind", 40 * 1000, 0, "wind", db, w.width / 2, w.height / 2, 45, 4, 0, 400, 400)); }
ParticleEmitter::ParticleEmitter(const xmlNodePtr &emitterNode, Particle *target, Map *map, const int rotation): mOutputPauseLeft(0), mParticleImage(0) { mMap = map; mParticleTarget = target; // Initializing default values mParticlePosX.set(0.0f); mParticlePosY.set(0.0f); mParticlePosZ.set(0.0f); mParticleAngleHorizontal.set(0.0f); mParticleAngleVertical.set(0.0f); mParticlePower.set(0.0f); mParticleGravity.set(0.0f); mParticleRandomness.set(0); mParticleBounce.set(0.0f); mParticleFollow = false; mParticleAcceleration.set(0.0f); mParticleDieDistance.set(-1.0f); mParticleMomentum.set(1.0f); mParticleLifetime.set(-1); mParticleFadeOut.set(0); mParticleFadeIn.set(0); mOutput.set(1); mOutputPause.set(0); mParticleAlpha.set(1.0f); for_each_xml_child_node(propertyNode, emitterNode) { if (xmlStrEqual(propertyNode->name, BAD_CAST "property")) { std::string name = XML::getProperty(propertyNode, "name", ""); if (name == "position-x") mParticlePosX = readParticleEmitterProp(propertyNode, 0.0f); else if (name == "position-y") { mParticlePosY = readParticleEmitterProp(propertyNode, 0.0f); mParticlePosY.minVal *= SIN45; mParticlePosY.maxVal *= SIN45; mParticlePosY.changeAmplitude *= SIN45; } else if (name == "position-z") { mParticlePosZ = readParticleEmitterProp(propertyNode, 0.0f); mParticlePosZ.minVal *= SIN45; mParticlePosZ.maxVal *= SIN45; mParticlePosZ.changeAmplitude *= SIN45; } else if (name == "image") { std::string image = XML::getProperty(propertyNode, "value", ""); // Don't leak when multiple images are defined if (!image.empty() && !mParticleImage) { ResourceManager *resman = ResourceManager::getInstance(); mParticleImage = resman->getImage(image); } } else if (name == "horizontal-angle") { mParticleAngleHorizontal = readParticleEmitterProp(propertyNode, 0.0f); mParticleAngleHorizontal.minVal += rotation; mParticleAngleHorizontal.minVal *= DEG_RAD_FACTOR; mParticleAngleHorizontal.maxVal += rotation; mParticleAngleHorizontal.maxVal *= DEG_RAD_FACTOR; mParticleAngleHorizontal.changeAmplitude *= DEG_RAD_FACTOR; } else if (name == "vertical-angle") { mParticleAngleVertical = readParticleEmitterProp(propertyNode, 0.0f); mParticleAngleVertical.minVal *= DEG_RAD_FACTOR; mParticleAngleVertical.maxVal *= DEG_RAD_FACTOR; mParticleAngleVertical.changeAmplitude *= DEG_RAD_FACTOR; } else if (name == "power") mParticlePower = readParticleEmitterProp(propertyNode, 0.0f); else if (name == "gravity") mParticleGravity = readParticleEmitterProp(propertyNode, 0.0f); else if (name == "randomnes" || name == "randomness") // legacy bug mParticleRandomness = readParticleEmitterProp(propertyNode, 0); else if (name == "bounce") mParticleBounce = readParticleEmitterProp(propertyNode, 0.0f); else if (name == "lifetime") { mParticleLifetime = readParticleEmitterProp(propertyNode, 0); mParticleLifetime.minVal += 1; } else if (name == "output") { mOutput = readParticleEmitterProp(propertyNode, 0); mOutput.maxVal +=1; } else if (name == "output-pause") { mOutputPause = readParticleEmitterProp(propertyNode, 0); mOutputPauseLeft = mOutputPause.value(0); } else if (name == "acceleration") mParticleAcceleration = readParticleEmitterProp(propertyNode, 0.0f); else if (name == "die-distance") mParticleDieDistance = readParticleEmitterProp(propertyNode, 0.0f); else if (name == "momentum") mParticleMomentum = readParticleEmitterProp(propertyNode, 1.0f); else if (name == "fade-out") mParticleFadeOut = readParticleEmitterProp(propertyNode, 0); else if (name == "fade-in") mParticleFadeIn = readParticleEmitterProp(propertyNode, 0); else if (name == "alpha") mParticleAlpha = readParticleEmitterProp(propertyNode, 1.0f); else if (name == "follow-parent") mParticleFollow = true; else { logger->log("Particle Engine: Warning, unknown emitter property \"%s\"", name.c_str()); } } else if (xmlStrEqual(propertyNode->name, BAD_CAST "emitter")) { ParticleEmitter newEmitter(propertyNode, mParticleTarget, map); mParticleChildEmitters.push_back(newEmitter); } else if (xmlStrEqual(propertyNode->name, BAD_CAST "rotation")) { ImageSet *imageset = ResourceManager::getInstance()->getImageSet( XML::getProperty(propertyNode, "imageset", ""), XML::getProperty(propertyNode, "width", 0), XML::getProperty(propertyNode, "height", 0)); // Get animation frames for_each_xml_child_node(frameNode, propertyNode) { int delay = XML::getProperty(frameNode, "delay", 0); int offsetX = XML::getProperty(frameNode, "offsetX", 0); int offsetY = XML::getProperty(frameNode, "offsetY", 0); offsetY -= imageset->getHeight() - mMap->getTileHeight(); offsetX -= (imageset->getWidth() - mMap->getTileWidth()) / 2; if (xmlStrEqual(frameNode->name, BAD_CAST "frame")) { int index = XML::getProperty(frameNode, "index", -1); if (index < 0) { logger->log("No valid value for 'index'"); continue; } Image *img = imageset->get(index); if (!img) { logger->log("No image at index %d", index); continue; } mParticleRotation.addFrame(img, delay, offsetX, offsetY); } else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence")) { int start = XML::getProperty(frameNode, "start", -1); int end = XML::getProperty(frameNode, "end", -1); if (start < 0 || end < 0) { logger->log("No valid value for 'start' or 'end'"); continue; } while (end >= start) { Image *img = imageset->get(start); if (!img) { logger->log("No image at index %d", start); continue; } mParticleRotation.addFrame(img, delay, offsetX, offsetY); start++; } } else if (xmlStrEqual(frameNode->name, BAD_CAST "end")) mParticleRotation.addTerminator(); } // for frameNode }
ParticleEmitter::ParticleEmitter(const XmlNodePtrConst emitterNode, Particle *const target, Map *const map, const int rotation, const std::string& dyePalettes) : mParticleTarget(target), mMap(map), mParticleImage(nullptr), mOutputPauseLeft(0), mDeathEffectConditions(0), mParticleFollow(false) { // Initializing default values mParticlePosX.set(0.0F); mParticlePosY.set(0.0F); mParticlePosZ.set(0.0F); mParticleAngleHorizontal.set(0.0F); mParticleAngleVertical.set(0.0F); mParticlePower.set(0.0F); mParticleGravity.set(0.0F); mParticleRandomness.set(0); mParticleBounce.set(0.0F); mParticleAcceleration.set(0.0F); mParticleDieDistance.set(-1.0F); mParticleMomentum.set(1.0F); mParticleLifetime.set(-1); mParticleFadeOut.set(0); mParticleFadeIn.set(0); mOutput.set(1); mOutputPause.set(0); mParticleAlpha.set(1.0F); for_each_xml_child_node(propertyNode, emitterNode) { if (xmlNameEqual(propertyNode, "property")) { const std::string name = XML::getProperty( propertyNode, "name", ""); if (name == "position-x") { mParticlePosX = readParticleEmitterProp(propertyNode, 0.0F); } else if (name == "position-y") { mParticlePosY = readParticleEmitterProp(propertyNode, 0.0F); mParticlePosY.minVal *= SIN45; mParticlePosY.maxVal *= SIN45; mParticlePosY.changeAmplitude *= SIN45; } else if (name == "position-z") { mParticlePosZ = readParticleEmitterProp(propertyNode, 0.0F); mParticlePosZ.minVal *= SIN45; mParticlePosZ.maxVal *= SIN45; mParticlePosZ.changeAmplitude *= SIN45; } else if (name == "image") { std::string image = XML::getProperty( propertyNode, "value", ""); // Don't leak when multiple images are defined if (!image.empty() && !mParticleImage) { if (!dyePalettes.empty()) Dye::instantiate(image, dyePalettes); ResourceManager *const resman = ResourceManager::getInstance(); mParticleImage = resman->getImage(image); } } else if (name == "subimage") { std::string image = XML::getProperty( propertyNode, "value", ""); // Don't leak when multiple images are defined if (!image.empty() && !mParticleImage) { if (!dyePalettes.empty()) Dye::instantiate(image, dyePalettes); ResourceManager *const resman = ResourceManager::getInstance(); Image *img = resman->getImage(image); if (img) { mParticleImage = resman->getSubImage(img, XML::getProperty(propertyNode, "x", 0), XML::getProperty(propertyNode, "y", 0), XML::getProperty(propertyNode, "width", 0), XML::getProperty(propertyNode, "height", 0)); img->decRef(); } else { mParticleImage = nullptr; } } } else if (name == "horizontal-angle") { mParticleAngleHorizontal = readParticleEmitterProp(propertyNode, 0.0F); mParticleAngleHorizontal.minVal += static_cast<float>(rotation); mParticleAngleHorizontal.minVal *= DEG_RAD_FACTOR; mParticleAngleHorizontal.maxVal += static_cast<float>(rotation); mParticleAngleHorizontal.maxVal *= DEG_RAD_FACTOR; mParticleAngleHorizontal.changeAmplitude *= DEG_RAD_FACTOR; } else if (name == "vertical-angle") { mParticleAngleVertical = readParticleEmitterProp(propertyNode, 0.0F); mParticleAngleVertical.minVal *= DEG_RAD_FACTOR; mParticleAngleVertical.maxVal *= DEG_RAD_FACTOR; mParticleAngleVertical.changeAmplitude *= DEG_RAD_FACTOR; } else if (name == "power") { mParticlePower = readParticleEmitterProp(propertyNode, 0.0F); } else if (name == "gravity") { mParticleGravity = readParticleEmitterProp(propertyNode, 0.0F); } else if (name == "randomnes" || name == "randomness") // legacy bug { mParticleRandomness = readParticleEmitterProp(propertyNode, 0); } else if (name == "bounce") { mParticleBounce = readParticleEmitterProp(propertyNode, 0.0F); } else if (name == "lifetime") { mParticleLifetime = readParticleEmitterProp(propertyNode, 0); mParticleLifetime.minVal += 1; } else if (name == "output") { mOutput = readParticleEmitterProp(propertyNode, 0); mOutput.maxVal += 1; } else if (name == "output-pause") { mOutputPause = readParticleEmitterProp(propertyNode, 0); mOutputPauseLeft = mOutputPause.value(0); } else if (name == "acceleration") { mParticleAcceleration = readParticleEmitterProp( propertyNode, 0.0F); } else if (name == "die-distance") { mParticleDieDistance = readParticleEmitterProp( propertyNode, 0.0F); } else if (name == "momentum") { mParticleMomentum = readParticleEmitterProp( propertyNode, 1.0F); } else if (name == "fade-out") { mParticleFadeOut = readParticleEmitterProp(propertyNode, 0); } else if (name == "fade-in") { mParticleFadeIn = readParticleEmitterProp(propertyNode, 0); } else if (name == "alpha") { mParticleAlpha = readParticleEmitterProp(propertyNode, 1.0F); } else if (name == "follow-parent") { const std::string value = XML::getProperty(propertyNode, "value", "0"); if (value == "1" || value == "true") mParticleFollow = true; } else { logger->log("Particle Engine: Warning, " "unknown emitter property \"%s\"", name.c_str()); } } else if (xmlNameEqual(propertyNode, "emitter")) { ParticleEmitter newEmitter(propertyNode, mParticleTarget, map, rotation, dyePalettes); mParticleChildEmitters.push_back(newEmitter); } else if (xmlNameEqual(propertyNode, "rotation") || xmlNameEqual(propertyNode, "animation")) { ImageSet *const imageset = getImageSet(propertyNode); if (!imageset) { logger->log1("Error: no valid imageset"); continue; } mTempSets.push_back(imageset); Animation &animation = (xmlNameEqual(propertyNode, "rotation")) ? mParticleRotation : mParticleAnimation; // Get animation frames for_each_xml_child_node(frameNode, propertyNode) { const int delay = XML::getIntProperty( frameNode, "delay", 0, 0, 100000); const int offsetX = XML::getProperty(frameNode, "offsetX", 0) - imageset->getWidth() / 2 + mapTileSize / 2; const int offsetY = XML::getProperty(frameNode, "offsetY", 0) - imageset->getHeight() + mapTileSize; const int rand = XML::getIntProperty( frameNode, "rand", 100, 0, 100); if (xmlNameEqual(frameNode, "frame")) { const int index = XML::getProperty(frameNode, "index", -1); if (index < 0) { logger->log1("No valid value for 'index'"); continue; } Image *const img = imageset->get(index); if (!img) { logger->log("No image at index %d", index); continue; } animation.addFrame(img, delay, offsetX, offsetY, rand); } else if (xmlNameEqual(frameNode, "sequence")) { int start = XML::getProperty(frameNode, "start", -1); const int end = XML::getProperty(frameNode, "end", -1); if (start < 0 || end < 0) { logger->log1("No valid value for 'start' or 'end'"); continue; } while (end >= start) { Image *const img = imageset->get(start); if (!img) { logger->log("No image at index %d", start); continue; } animation.addFrame(img, delay, offsetX, offsetY, rand); start ++; } } else if (xmlNameEqual(frameNode, "end")) { animation.addTerminator(rand); } } // for frameNode } else if (xmlNameEqual(propertyNode, "deatheffect"))