summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilipp Sehmisch <tmw@crushnet.org>2008-10-26 01:46:40 +0000
committerPhilipp Sehmisch <tmw@crushnet.org>2008-10-26 01:46:40 +0000
commit56410d9ff28448a73be7a7d115d54c1ee578972c (patch)
treeb9a7b56222610d08215eaf29cb921635b9e3081b /src
parentc650e2b6338cf4b18b0968623d12ef95a7b820fc (diff)
downloadmana-56410d9ff28448a73be7a7d115d54c1ee578972c.tar.gz
mana-56410d9ff28448a73be7a7d115d54c1ee578972c.tar.bz2
mana-56410d9ff28448a73be7a7d115d54c1ee578972c.tar.xz
mana-56410d9ff28448a73be7a7d115d54c1ee578972c.zip
Implemented particle emitters with properties which change over time according to wave functions.
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/particle.cpp2
-rw-r--r--src/particleemitter.cpp100
-rw-r--r--src/particleemitter.h37
-rw-r--r--src/particleemitterprop.h112
-rw-r--r--src/utils/minmax.h50
7 files changed, 193 insertions, 112 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 20f2f761..94ee854a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -265,7 +265,6 @@ SET(SRCS
utils/base64.h
utils/dtor.h
utils/fastsqrt.h
- utils/minmax.h
utils/strprintf.cpp
utils/strprintf.h
utils/tostring.h
@@ -328,6 +327,7 @@ SET(SRCS
particle.h
particleemitter.cpp
particleemitter.h
+ particleemitterprop.h
player.cpp
player.h
player_relations.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 340f1947..867953ab 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -215,7 +215,6 @@ tmw_SOURCES = gui/widgets/resizegrip.cpp \
utils/base64.h \
utils/dtor.h \
utils/fastsqrt.h \
- utils/minmax.h \
utils/strprintf.cpp \
utils/strprintf.h \
utils/tostring.h \
@@ -278,6 +277,7 @@ tmw_SOURCES = gui/widgets/resizegrip.cpp \
particle.h \
particleemitter.cpp \
particleemitter.h \
+ particleemitterprop.h \
player.cpp \
player.h \
player_relations.cpp \
diff --git a/src/particle.cpp b/src/particle.cpp
index 8591838f..1521e75b 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -181,7 +181,7 @@ Particle::update()
e++
)
{
- Particles newParticles = (*e)->createParticles();
+ Particles newParticles = (*e)->createParticles(mLifetimePast);
for ( ParticleIterator p = newParticles.begin();
p != newParticles.end();
p++
diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp
index 816a5d28..bb4a7c6e 100644
--- a/src/particleemitter.cpp
+++ b/src/particleemitter.cpp
@@ -74,20 +74,22 @@ ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map *
if (name == "position-x")
{
- mParticlePosX = readMinMax(propertyNode, 0.0f);
+ mParticlePosX = readParticleEmitterProp(propertyNode, 0.0f);
}
else if (name == "position-y")
{
- mParticlePosY = readMinMax(propertyNode, 0.0f);
+ mParticlePosY = readParticleEmitterProp(propertyNode, 0.0f);
mParticlePosY.minVal *= SIN45;
mParticlePosY.maxVal *= SIN45;
+ mParticlePosY.changeAmplitude *= SIN45;
}
else if (name == "position-z")
{
- mParticlePosZ = readMinMax(propertyNode, 0.0f);
+ mParticlePosZ = readParticleEmitterProp(propertyNode, 0.0f);
mParticlePosZ.minVal *= SIN45;
mParticlePosZ.maxVal *= SIN45;
+ mParticlePosZ.changeAmplitude *= SIN45;
}
else if (name == "image")
{
@@ -101,70 +103,72 @@ ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map *
}
else if (name == "horizontal-angle")
{
- mParticleAngleHorizontal = readMinMax(propertyNode, 0.0f);
+ mParticleAngleHorizontal = readParticleEmitterProp(propertyNode, 0.0f);
mParticleAngleHorizontal.minVal *= DEG_RAD_FACTOR;
mParticleAngleHorizontal.maxVal *= DEG_RAD_FACTOR;
+ mParticleAngleHorizontal.changeAmplitude *= DEG_RAD_FACTOR;
}
else if (name == "vertical-angle")
{
- mParticleAngleVertical = readMinMax(propertyNode, 0.0f);
+ 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 = readMinMax(propertyNode, 0.0f);
+ mParticlePower = readParticleEmitterProp(propertyNode, 0.0f);
}
else if (name == "gravity")
{
- mParticleGravity = readMinMax(propertyNode, 0.0f);
+ mParticleGravity = readParticleEmitterProp(propertyNode, 0.0f);
}
else if (name == "randomnes" || name == "randomness") // legacy bug
{
- mParticleRandomness = readMinMax(propertyNode, 0);
+ mParticleRandomness = readParticleEmitterProp(propertyNode, 0);
}
else if (name == "bounce")
{
- mParticleBounce = readMinMax(propertyNode, 0.0f);
+ mParticleBounce = readParticleEmitterProp(propertyNode, 0.0f);
}
else if (name == "lifetime")
{
- mParticleLifetime = readMinMax(propertyNode, 0);
+ mParticleLifetime = readParticleEmitterProp(propertyNode, 0);
mParticleLifetime.minVal += 1;
}
else if (name == "output")
{
- mOutput = readMinMax(propertyNode, 0);
+ mOutput = readParticleEmitterProp(propertyNode, 0);
mOutput.maxVal +=1;
}
else if (name == "output-pause")
{
- mOutputPause = readMinMax(propertyNode, 0);
- mOutputPauseLeft = mOutputPause.value();
+ mOutputPause = readParticleEmitterProp(propertyNode, 0);
+ mOutputPauseLeft = mOutputPause.value(0);
}
else if (name == "acceleration")
{
- mParticleAcceleration = readMinMax(propertyNode, 0.0f);
+ mParticleAcceleration = readParticleEmitterProp(propertyNode, 0.0f);
}
else if (name == "die-distance")
{
- mParticleDieDistance = readMinMax(propertyNode, 0.0f);
+ mParticleDieDistance = readParticleEmitterProp(propertyNode, 0.0f);
}
else if (name == "momentum")
{
- mParticleMomentum = readMinMax(propertyNode, 1.0f);
+ mParticleMomentum = readParticleEmitterProp(propertyNode, 1.0f);
}
else if (name == "fade-out")
{
- mParticleFadeOut = readMinMax(propertyNode, 0);
+ mParticleFadeOut = readParticleEmitterProp(propertyNode, 0);
}
else if (name == "fade-in")
{
- mParticleFadeIn = readMinMax(propertyNode, 0);
+ mParticleFadeIn = readParticleEmitterProp(propertyNode, 0);
}
else if (name == "alpha")
{
- mParticleAlpha = readMinMax(propertyNode, 1.0f);
+ mParticleAlpha = readParticleEmitterProp(propertyNode, 1.0f);
}
else if (name == "follow-parent")
{
@@ -299,21 +303,35 @@ ParticleEmitter::~ParticleEmitter()
}
-template <typename T> MinMax<T>
-ParticleEmitter::readMinMax(xmlNodePtr propertyNode, T def)
+template <typename T> ParticleEmitterProp<T>
+ParticleEmitter::readParticleEmitterProp(xmlNodePtr propertyNode, T def)
{
- MinMax<T> retval;
+ ParticleEmitterProp<T> retval;
def = (T) XML::getFloatProperty(propertyNode, "value", (double) def);
retval.set((T) XML::getFloatProperty(propertyNode, "min", (double) def),
(T) XML::getFloatProperty(propertyNode, "max", (double) def));
+ std::string change = XML::getProperty(propertyNode, "change-func", "none");
+ T amplitude = (T) XML::getFloatProperty(propertyNode, "change-amplitude", 0.0);
+ int period = XML::getProperty(propertyNode, "change-period", 0);
+ int phase = XML::getProperty(propertyNode, "change-phase", 0);
+ if (change == "saw" || change == "sawtooth") {
+ retval.setFunction(FUNC_SAW, amplitude, period, phase);
+ } else if (change == "sine" || change == "sinewave") {
+ retval.setFunction(FUNC_SINE, amplitude, period, phase);
+ } else if (change == "triangle") {
+ retval.setFunction(FUNC_TRIANGLE, amplitude, period, phase);
+ } else if (change == "square"){
+ retval.setFunction(FUNC_SQUARE, amplitude, period, phase);
+ }
+
return retval;
}
std::list<Particle *>
-ParticleEmitter::createParticles()
+ParticleEmitter::createParticles(int tick)
{
std::list<Particle *> newParticles;
@@ -322,9 +340,9 @@ ParticleEmitter::createParticles()
mOutputPauseLeft--;
return newParticles;
}
- mOutputPauseLeft = mOutputPause.value();
+ mOutputPauseLeft = mOutputPause.value(tick);
- for (int i = mOutput.value(); i > 0; i--)
+ for (int i = mOutput.value(tick); i > 0; i--)
{
// Limit maximum particles
if (Particle::particleCount > Particle::maxCount) break;
@@ -346,33 +364,33 @@ ParticleEmitter::createParticles()
newParticle->setPosition(
- mParticlePosX.value(),
- mParticlePosY.value(),
- mParticlePosZ.value());
+ mParticlePosX.value(tick),
+ mParticlePosY.value(tick),
+ mParticlePosZ.value(tick));
- float angleH = mParticleAngleHorizontal.value();
- float angleV = mParticleAngleVertical.value();
- float power = mParticlePower.value();
+ float angleH = mParticleAngleHorizontal.value(tick);
+ float angleV = mParticleAngleVertical.value(tick);
+ float power = mParticlePower.value(tick);
newParticle->setVelocity(
cos(angleH) * cos(angleV) * power,
sin(angleH) * cos(angleV) * power,
sin(angleV) * power);
- newParticle->setRandomness(mParticleRandomness.value());
- newParticle->setGravity(mParticleGravity.value());
- newParticle->setBounce(mParticleBounce.value());
+ newParticle->setRandomness(mParticleRandomness.value(tick));
+ newParticle->setGravity(mParticleGravity.value(tick));
+ newParticle->setBounce(mParticleBounce.value(tick));
newParticle->setFollow(mParticleFollow);
newParticle->setDestination(mParticleTarget,
- mParticleAcceleration.value(),
- mParticleMomentum.value()
+ mParticleAcceleration.value(tick),
+ mParticleMomentum.value(tick)
);
- newParticle->setDieDistance(mParticleDieDistance.value());
+ newParticle->setDieDistance(mParticleDieDistance.value(tick));
- newParticle->setLifetime(mParticleLifetime.value());
- newParticle->setFadeOut(mParticleFadeOut.value());
- newParticle->setFadeIn(mParticleFadeIn.value());
- newParticle->setAlpha(mParticleAlpha.value());
+ newParticle->setLifetime(mParticleLifetime.value(tick));
+ newParticle->setFadeOut(mParticleFadeOut.value(tick));
+ newParticle->setFadeIn(mParticleFadeIn.value(tick));
+ newParticle->setAlpha(mParticleAlpha.value(tick));
for (std::list<ParticleEmitter>::iterator i = mParticleChildEmitters.begin();
i != mParticleChildEmitters.end();
diff --git a/src/particleemitter.h b/src/particleemitter.h
index 5cf3fd46..4ef088f6 100644
--- a/src/particleemitter.h
+++ b/src/particleemitter.h
@@ -27,10 +27,11 @@
#include <list>
#include "utils/xml.h"
-#include "utils/minmax.h"
#include "resources/animation.h"
+#include "particleemitterprop.h"
+
class Image;
class Map;
class Particle;
@@ -66,7 +67,7 @@ class ParticleEmitter
* Spawns new particles
* @return: a list of created particles
*/
- std::list<Particle *> createParticles();
+ std::list<Particle *> createParticles(int tick);
/**
* Sets the target of the particles that are created
@@ -76,50 +77,50 @@ class ParticleEmitter
{ mParticleTarget = target; };
private:
- template <typename T> MinMax<T> readMinMax(xmlNodePtr propertyNode, T def);
+ template <typename T> ParticleEmitterProp<T> readParticleEmitterProp(xmlNodePtr propertyNode, T def);
/**
* initial position of particles:
*/
- MinMax<float> mParticlePosX, mParticlePosY, mParticlePosZ;
+ ParticleEmitterProp<float> mParticlePosX, mParticlePosY, mParticlePosZ;
/**
* initial vector of particles:
*/
- MinMax<float> mParticleAngleHorizontal, mParticleAngleVertical;
+ ParticleEmitterProp<float> mParticleAngleHorizontal, mParticleAngleVertical;
/**
* Initial velocity of particles
*/
- MinMax<float> mParticlePower;
+ ParticleEmitterProp<float> mParticlePower;
/*
* Vector changing of particles:
*/
- MinMax<float> mParticleGravity;
- MinMax<int> mParticleRandomness;
- MinMax<float> mParticleBounce;
+ ParticleEmitterProp<float> mParticleGravity;
+ ParticleEmitterProp<int> mParticleRandomness;
+ ParticleEmitterProp<float> mParticleBounce;
bool mParticleFollow;
/*
* Properties of targeting particles:
*/
Particle *mParticleTarget;
- MinMax<float> mParticleAcceleration;
- MinMax<float> mParticleDieDistance;
- MinMax<float> mParticleMomentum;
+ ParticleEmitterProp<float> mParticleAcceleration;
+ ParticleEmitterProp<float> mParticleDieDistance;
+ ParticleEmitterProp<float> mParticleMomentum;
/*
* Behavior over time of the particles:
*/
- MinMax<int> mParticleLifetime;
- MinMax<int> mParticleFadeOut;
- MinMax<int> mParticleFadeIn;
+ ParticleEmitterProp<int> mParticleLifetime;
+ ParticleEmitterProp<int> mParticleFadeOut;
+ ParticleEmitterProp<int> mParticleFadeIn;
Map *mMap; /**< Map the particles are spawned on */
- MinMax<int> mOutput; /**< Number of particles spawned per update */
- MinMax<int> mOutputPause; /**< Pause in frames between two spawns */
+ ParticleEmitterProp<int> mOutput; /**< Number of particles spawned per update */
+ ParticleEmitterProp<int> mOutputPause; /**< Pause in frames between two spawns */
int mOutputPauseLeft;
/*
@@ -127,7 +128,7 @@ class ParticleEmitter
*/
Image *mParticleImage; /**< Particle image, if used */
Animation mParticleAnimation; /**< Filename of particle animation file */
- MinMax<float> mParticleAlpha; /**< Opacity of the graphical representation of the particles */
+ ParticleEmitterProp<float> mParticleAlpha; /**< Opacity of the graphical representation of the particles */
/** List of emitters the spawned particles are equipped with */
std::list<ParticleEmitter> mParticleChildEmitters;
diff --git a/src/particleemitterprop.h b/src/particleemitterprop.h
new file mode 100644
index 00000000..e645c169
--- /dev/null
+++ b/src/particleemitterprop.h
@@ -0,0 +1,112 @@
+/*
+ * The Mana World
+ * Copyright 2006 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#include <cstdlib>
+#include <cmath>
+
+/**
+ * Returns a random numeric value that is larger than or equal min and smaller
+ * than max
+ */
+
+enum ChangeFunc
+{
+ FUNC_NONE,
+ FUNC_SINE,
+ FUNC_SAW,
+ FUNC_TRIANGLE,
+ FUNC_SQUARE
+};
+
+template <typename T> struct ParticleEmitterProp
+{
+ ParticleEmitterProp():
+ changeFunc(FUNC_NONE)
+ {
+ }
+
+ void set(T min, T max)
+ {
+ minVal=min; maxVal=max;
+ }
+
+ void set(T val)
+ {
+ set(val, val);
+ }
+
+ void setFunction(ChangeFunc func, T amplitude, int period, int phase)
+ {
+ changeFunc = func;
+ changeAmplitude = amplitude;
+ changePeriod = period;
+ changePhase = phase;
+ }
+
+ T value(int tick)
+ {
+ tick += changePhase;
+ T val = (T) (minVal + (maxVal - minVal) * (rand() / ((double) RAND_MAX + 1)));
+
+ switch (changeFunc)
+ {
+ case FUNC_SINE:
+ val += (T) std::sin(M_PI * 2 * ((double)(tick%changePeriod) / (double)changePeriod)) * changeAmplitude;
+ break;
+ case FUNC_SAW:
+ val += (T) (changeAmplitude * ((double)(tick%changePeriod) / (double)changePeriod)) * 2 - changeAmplitude;
+ break;
+ case FUNC_TRIANGLE:
+ if ((tick%changePeriod) * 2 < changePeriod)
+ {
+ val += changeAmplitude - (T)((tick%changePeriod) / (double)changePeriod) * changeAmplitude * 4;
+ } else {
+ val += changeAmplitude * -3 + (T)((tick%changePeriod) / (double)changePeriod) * changeAmplitude * 4;
+ // I have no idea why this works but it does
+ }
+ break;
+ case FUNC_SQUARE:
+ if ((tick%changePeriod) * 2 < changePeriod)
+ {
+ val += changeAmplitude;
+ } else {
+ val -= changeAmplitude;
+ }
+ break;
+ case FUNC_NONE:
+ default:
+ //nothing
+ break;
+ }
+
+ return val;
+ }
+
+ T minVal;
+ T maxVal;
+
+ ChangeFunc changeFunc;
+ T changeAmplitude;
+ int changePeriod;
+ int changePhase;
+};
diff --git a/src/utils/minmax.h b/src/utils/minmax.h
deleted file mode 100644
index 427c5da7..00000000
--- a/src/utils/minmax.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * The Mana World
- * Copyright 2006 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * The Mana World is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- */
-
-#include <cstdlib>
-
-/**
- * Returns a random numeric value that is larger than or equal min and smaller
- * than max
- */
-
-template <typename T> struct MinMax
-{
- void set(T min, T max)
- {
- minVal=min; maxVal=max;
- }
-
- void set(T val)
- {
- set(val, val);
- }
-
- T value()
- {
- return (T)(minVal + (maxVal - minVal) * (rand() / ((double) RAND_MAX + 1)));
- }
-
- T minVal;
- T maxVal;
-};