mirror of
https://github.com/love2d/love.git
synced 2026-08-18 19:54:22 +02:00
Rename ParticleSystem:setAreaSpread to setEmissionArea, and move the functionality from setAreaSpreadAngle/setAreSpreadIsRelativeDirection into setEmissionArea. Resolves issue #1311.
This commit is contained in:
@@ -65,9 +65,9 @@ ParticleSystem::ParticleSystem(Texture *texture, uint32 size)
|
||||
, activeParticles(0)
|
||||
, emissionRate(0)
|
||||
, emitCounter(0)
|
||||
, areaSpreadDistribution(DISTRIBUTION_NONE)
|
||||
, areaSpreadAngle(0)
|
||||
, areaSpreadIsRelativeDirection(false)
|
||||
, emissionAreaDistribution(DISTRIBUTION_NONE)
|
||||
, emissionAreaAngle(0)
|
||||
, directionRelativeToEmissionCenter(false)
|
||||
, lifetime(-1)
|
||||
, life(0)
|
||||
, particleLifeMin(0)
|
||||
@@ -122,10 +122,10 @@ ParticleSystem::ParticleSystem(const ParticleSystem &p)
|
||||
, emitCounter(0.0f)
|
||||
, position(p.position)
|
||||
, prevPosition(p.prevPosition)
|
||||
, areaSpreadDistribution(p.areaSpreadDistribution)
|
||||
, areaSpread(p.areaSpread)
|
||||
, areaSpreadAngle(p.areaSpreadAngle)
|
||||
, areaSpreadIsRelativeDirection(p.areaSpreadIsRelativeDirection)
|
||||
, emissionAreaDistribution(p.emissionAreaDistribution)
|
||||
, emissionArea(p.emissionArea)
|
||||
, emissionAreaAngle(p.emissionAreaAngle)
|
||||
, directionRelativeToEmissionCenter(p.directionRelativeToEmissionCenter)
|
||||
, lifetime(p.lifetime)
|
||||
, life(p.lifetime) // Initialize with the maximum life time.
|
||||
, particleLifeMin(p.particleLifeMin)
|
||||
@@ -275,61 +275,67 @@ void ParticleSystem::initParticle(Particle *p, float t)
|
||||
// In this switch statement, variables 'rand_y', 'min', and 'max'
|
||||
// are sometimes reused as data stores for performance reasons
|
||||
float rand_x, rand_y;
|
||||
switch (areaSpreadDistribution)
|
||||
float c, s;
|
||||
switch (emissionAreaDistribution)
|
||||
{
|
||||
case DISTRIBUTION_UNIFORM:
|
||||
rand_x = (float) rng.random(-areaSpread.x, areaSpread.x);
|
||||
rand_y = (float) rng.random(-areaSpread.y, areaSpread.y);
|
||||
p->position.x += cosf(areaSpreadAngle) * rand_x - sinf(areaSpreadAngle) * rand_y;
|
||||
p->position.y += sinf(areaSpreadAngle) * rand_x + cosf(areaSpreadAngle) * rand_y;
|
||||
c = cosf(emissionAreaAngle); s = sinf(emissionAreaAngle);
|
||||
rand_x = (float) rng.random(-emissionArea.x, emissionArea.x);
|
||||
rand_y = (float) rng.random(-emissionArea.y, emissionArea.y);
|
||||
p->position.x += c * rand_x - s * rand_y;
|
||||
p->position.y += s * rand_x + c * rand_y;
|
||||
break;
|
||||
case DISTRIBUTION_NORMAL:
|
||||
rand_x = (float) rng.randomNormal(areaSpread.x);
|
||||
rand_y = (float) rng.randomNormal(areaSpread.y);
|
||||
p->position.x += cosf(areaSpreadAngle) * rand_x - sinf(areaSpreadAngle) * rand_y;
|
||||
p->position.y += sinf(areaSpreadAngle) * rand_x + cosf(areaSpreadAngle) * rand_y;
|
||||
c = cosf(emissionAreaAngle); s = sinf(emissionAreaAngle);
|
||||
rand_x = (float) rng.randomNormal(emissionArea.x);
|
||||
rand_y = (float) rng.randomNormal(emissionArea.y);
|
||||
p->position.x += c * rand_x - s * rand_y;
|
||||
p->position.y += s * rand_x + c * rand_y;
|
||||
break;
|
||||
case DISTRIBUTION_ELLIPSE:
|
||||
c = cosf(emissionAreaAngle); s = sinf(emissionAreaAngle);
|
||||
rand_x = (float) rng.random(-1, 1);
|
||||
rand_y = (float) rng.random(-1, 1);
|
||||
min = areaSpread.x * (rand_x * sqrt(1 - 0.5f*pow(rand_y, 2)));
|
||||
max = areaSpread.y * (rand_y * sqrt(1 - 0.5f*pow(rand_x, 2)));
|
||||
p->position.x += cosf(areaSpreadAngle) * min - sinf(areaSpreadAngle) * max;
|
||||
p->position.y += sinf(areaSpreadAngle) * min + cosf(areaSpreadAngle) * max;
|
||||
min = emissionArea.x * (rand_x * sqrt(1 - 0.5f*pow(rand_y, 2)));
|
||||
max = emissionArea.y * (rand_y * sqrt(1 - 0.5f*pow(rand_x, 2)));
|
||||
p->position.x += c * min - s * max;
|
||||
p->position.y += s * min + c * max;
|
||||
break;
|
||||
case DISTRIBUTION_BORDER_ELLIPSE:
|
||||
c = cosf(emissionAreaAngle); s = sinf(emissionAreaAngle);
|
||||
rand_x = (float) rng.random(0, LOVE_M_PI * 2);
|
||||
min = cosf(rand_x) * areaSpread.x;
|
||||
max = sinf(rand_x) * areaSpread.y;
|
||||
p->position.x += cosf(areaSpreadAngle) * min - sinf(areaSpreadAngle) * max;
|
||||
p->position.y += sinf(areaSpreadAngle) * min + cosf(areaSpreadAngle) * max;
|
||||
min = cosf(rand_x) * emissionArea.x;
|
||||
max = sinf(rand_x) * emissionArea.y;
|
||||
p->position.x += c * min - s * max;
|
||||
p->position.y += s * min + c * max;
|
||||
break;
|
||||
case DISTRIBUTION_BORDER_RECTANGLE:
|
||||
rand_x = (float) rng.random((areaSpread.x + areaSpread.y) * -2, (areaSpread.x + areaSpread.y) * 2);
|
||||
rand_y = areaSpread.y * 2;
|
||||
c = cosf(emissionAreaAngle); s = sinf(emissionAreaAngle);
|
||||
rand_x = (float) rng.random((emissionArea.x + emissionArea.y) * -2, (emissionArea.x + emissionArea.y) * 2);
|
||||
rand_y = emissionArea.y * 2;
|
||||
if (rand_x < -rand_y)
|
||||
{
|
||||
min = rand_x + rand_y + areaSpread.x;
|
||||
p->position.x += cosf(areaSpreadAngle) * min - sinf(areaSpreadAngle) * -areaSpread.y;
|
||||
p->position.y += sinf(areaSpreadAngle) * min + cosf(areaSpreadAngle) * -areaSpread.y;
|
||||
min = rand_x + rand_y + emissionArea.x;
|
||||
p->position.x += c * min - s * -emissionArea.y;
|
||||
p->position.y += s * min + c * -emissionArea.y;
|
||||
}
|
||||
else if (rand_x < 0)
|
||||
{
|
||||
max = rand_x + areaSpread.y;
|
||||
p->position.x += cosf(areaSpreadAngle) * -areaSpread.x - sinf(areaSpreadAngle) * max;
|
||||
p->position.y += sinf(areaSpreadAngle) * -areaSpread.x + cosf(areaSpreadAngle) * max;
|
||||
max = rand_x + emissionArea.y;
|
||||
p->position.x += c * -emissionArea.x - s * max;
|
||||
p->position.y += s * -emissionArea.x + c * max;
|
||||
}
|
||||
else if (rand_x < rand_y)
|
||||
{
|
||||
max = rand_x - areaSpread.y;
|
||||
p->position.x += cosf(areaSpreadAngle) * areaSpread.x - sinf(areaSpreadAngle) * max;
|
||||
p->position.y += sinf(areaSpreadAngle) * areaSpread.x + cosf(areaSpreadAngle) * max;
|
||||
max = rand_x - emissionArea.y;
|
||||
p->position.x += c * emissionArea.x - s * max;
|
||||
p->position.y += s * emissionArea.x + c * max;
|
||||
}
|
||||
else
|
||||
{
|
||||
min = rand_x - rand_y - areaSpread.x;
|
||||
p->position.x += cosf(areaSpreadAngle) * min - sinf(areaSpreadAngle) * areaSpread.y;
|
||||
p->position.y += sinf(areaSpreadAngle) * min + cosf(areaSpreadAngle) * areaSpread.y;
|
||||
min = rand_x - rand_y - emissionArea.x;
|
||||
p->position.x += c * min - s * emissionArea.y;
|
||||
p->position.y += s * min + c * emissionArea.y;
|
||||
}
|
||||
break;
|
||||
case DISTRIBUTION_NONE:
|
||||
@@ -338,7 +344,7 @@ void ParticleSystem::initParticle(Particle *p, float t)
|
||||
}
|
||||
|
||||
// Determine if the origin of each particle is the center of the area
|
||||
if (areaSpreadIsRelativeDirection)
|
||||
if (directionRelativeToEmissionCenter)
|
||||
dir += atan2(p->position.y - pos.y, p->position.x - pos.x);
|
||||
|
||||
p->origin = pos;
|
||||
@@ -571,40 +577,20 @@ void ParticleSystem::moveTo(float x, float y)
|
||||
position = love::Vector2(x, y);
|
||||
}
|
||||
|
||||
void ParticleSystem::setAreaSpread(AreaSpreadDistribution distribution, float x, float y)
|
||||
void ParticleSystem::setEmissionArea(AreaSpreadDistribution distribution, float x, float y, float angle, bool directionRelativeToCenter)
|
||||
{
|
||||
areaSpread = love::Vector2(x, y);
|
||||
areaSpreadDistribution = distribution;
|
||||
emissionArea = love::Vector2(x, y);
|
||||
emissionAreaDistribution = distribution;
|
||||
emissionAreaAngle = angle;
|
||||
directionRelativeToEmissionCenter = directionRelativeToCenter;
|
||||
}
|
||||
|
||||
ParticleSystem::AreaSpreadDistribution ParticleSystem::getAreaSpreadDistribution() const
|
||||
ParticleSystem::AreaSpreadDistribution ParticleSystem::getEmissionArea(love::Vector2 ¶ms, float &angle, bool &directionRelativeToCenter) const
|
||||
{
|
||||
return areaSpreadDistribution;
|
||||
}
|
||||
|
||||
const love::Vector2 &ParticleSystem::getAreaSpreadParameters() const
|
||||
{
|
||||
return areaSpread;
|
||||
}
|
||||
|
||||
void ParticleSystem::setAreaSpreadAngle(float angle)
|
||||
{
|
||||
areaSpreadAngle = angle;
|
||||
}
|
||||
|
||||
float ParticleSystem::getAreaSpreadAngle() const
|
||||
{
|
||||
return areaSpreadAngle;
|
||||
}
|
||||
|
||||
void ParticleSystem::setAreaSpreadIsRelativeDirection(bool isRelativeDirection)
|
||||
{
|
||||
areaSpreadIsRelativeDirection = isRelativeDirection;
|
||||
}
|
||||
|
||||
bool ParticleSystem::getAreaSpreadIsRelativeDirection() const
|
||||
{
|
||||
return areaSpreadIsRelativeDirection;
|
||||
params = emissionArea;
|
||||
angle = emissionAreaAngle;
|
||||
directionRelativeToCenter = directionRelativeToEmissionCenter;
|
||||
return emissionAreaDistribution;
|
||||
}
|
||||
|
||||
void ParticleSystem::setDirection(float direction)
|
||||
|
||||
@@ -202,45 +202,19 @@ public:
|
||||
* * Normal: Parameters denote the standard deviation in x and y direction. x and y are assumed to be uncorrelated.
|
||||
* * borderellipse: Parameter causes particle distribution around outside of ellipse
|
||||
* * borderrectangle: Parameter causes particle distribution around outside of rectangle
|
||||
* @param distribution Distribution type
|
||||
* @param x First parameter. Interpretation depends on distribution type.
|
||||
* @param y Second parameter. Interpretation depends on distribution type.
|
||||
* @param distribution Distribution type
|
||||
* @param angle The angle of the emission area (in radians).
|
||||
* @param directionRelativeToCenter whether the initial direction of
|
||||
* particles points away from the center of the emission area.
|
||||
**/
|
||||
void setAreaSpread(AreaSpreadDistribution distribution, float x, float y);
|
||||
|
||||
/**
|
||||
* Returns area spread distribution type.
|
||||
**/
|
||||
AreaSpreadDistribution getAreaSpreadDistribution() const;
|
||||
void setEmissionArea(AreaSpreadDistribution distribution, float x, float y, float angle, bool directionRelativeToCenter);
|
||||
|
||||
/**
|
||||
* Returns area spread parameters.
|
||||
**/
|
||||
const love::Vector2 &getAreaSpreadParameters() const;
|
||||
|
||||
/**
|
||||
* Returns the angle of the area distribution (in radians).
|
||||
**/
|
||||
float getAreaSpreadAngle() const;
|
||||
|
||||
/**
|
||||
* Sets the angle of the area distribution
|
||||
* @param angle The angle (in radians).
|
||||
**/
|
||||
void setAreaSpreadAngle(float angle);
|
||||
|
||||
/**
|
||||
* Returns true if particles spawn relative to the center of the
|
||||
* shape area or false if they will use the setDirection parameter
|
||||
**/
|
||||
bool getAreaSpreadIsRelativeDirection() const;
|
||||
|
||||
/**
|
||||
* Sets if particles starting direction is away from the center of the
|
||||
* area spread or the setDirection parameter
|
||||
* @param isRelativeDirection boolean use relative direction from center
|
||||
**/
|
||||
void setAreaSpreadIsRelativeDirection(bool isRelativeDirection);
|
||||
AreaSpreadDistribution getEmissionArea(love::Vector2 ¶ms, float &angle, bool &directionRelativeToCenter) const;
|
||||
|
||||
/**
|
||||
* Sets the direction of the particle emitter.
|
||||
@@ -636,10 +610,10 @@ private:
|
||||
love::Vector2 prevPosition;
|
||||
|
||||
// Emission area spread.
|
||||
AreaSpreadDistribution areaSpreadDistribution;
|
||||
love::Vector2 areaSpread;
|
||||
float areaSpreadAngle;
|
||||
bool areaSpreadIsRelativeDirection;
|
||||
AreaSpreadDistribution emissionAreaDistribution;
|
||||
love::Vector2 emissionArea;
|
||||
float emissionAreaAngle;
|
||||
bool directionRelativeToEmissionCenter;
|
||||
|
||||
// The lifetime of the particle emitter (-1 means infinite) and the life it has left.
|
||||
float lifetime;
|
||||
|
||||
@@ -196,14 +196,16 @@ int w_ParticleSystem_moveTo(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_setAreaSpread(lua_State *L)
|
||||
int w_ParticleSystem_setEmissionArea(lua_State *L)
|
||||
{
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
|
||||
ParticleSystem::AreaSpreadDistribution distribution = ParticleSystem::DISTRIBUTION_NONE;
|
||||
float x = 0.f, y = 0.f;
|
||||
float angle = 0.0f;
|
||||
bool directionRelativeToCenter = false;
|
||||
|
||||
const char *str = lua_isnoneornil(L, 2) ? 0 : luaL_checkstring(L, 2);
|
||||
const char *str = lua_isnoneornil(L, 2) ? nullptr : luaL_checkstring(L, 2);
|
||||
if (str && !ParticleSystem::getConstant(str, distribution))
|
||||
return luax_enumerror(L, "particle distribution", ParticleSystem::getConstants(distribution), str);
|
||||
|
||||
@@ -213,55 +215,32 @@ int w_ParticleSystem_setAreaSpread(lua_State *L)
|
||||
y = (float) luaL_checknumber(L, 4);
|
||||
if (x < 0.0f || y < 0.0f)
|
||||
return luaL_error(L, "Invalid area spread parameters (must be >= 0)");
|
||||
|
||||
angle = (float) luaL_optnumber(L, 5, 0.0f);
|
||||
directionRelativeToCenter = luax_optboolean(L, 6, false);
|
||||
}
|
||||
|
||||
t->setAreaSpread(distribution, x, y);
|
||||
t->setEmissionArea(distribution, x, y, angle, directionRelativeToCenter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_getAreaSpread(lua_State *L)
|
||||
int w_ParticleSystem_getEmissionArea(lua_State *L)
|
||||
{
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
ParticleSystem::AreaSpreadDistribution distribution = t-> getAreaSpreadDistribution();
|
||||
love::Vector2 p;
|
||||
float angle;
|
||||
bool directionRelativeToCenter;
|
||||
ParticleSystem::AreaSpreadDistribution distribution = t->getEmissionArea(p, angle, directionRelativeToCenter);
|
||||
const char *str;
|
||||
ParticleSystem::getConstant(distribution, str);
|
||||
const love::Vector2 &p = t->getAreaSpreadParameters();
|
||||
|
||||
lua_pushstring(L, str);
|
||||
lua_pushnumber(L, p.x);
|
||||
lua_pushnumber(L, p.y);
|
||||
lua_pushnumber(L, angle);
|
||||
luax_pushboolean(L, directionRelativeToCenter);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_setAreaSpreadAngle(lua_State *L)
|
||||
{
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
float arg1 = (float)luaL_checknumber(L, 2);
|
||||
t->setAreaSpreadAngle(arg1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_getAreaSpreadAngle(lua_State *L)
|
||||
{
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
lua_pushnumber(L, t->getAreaSpreadAngle());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_setAreaSpreadIsRelativeDirection(lua_State *L)
|
||||
{
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
bool arg1 = luax_checkboolean(L, 2);
|
||||
t->setAreaSpreadIsRelativeDirection(arg1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_getAreaSpreadIsRelativeDirection(lua_State *L)
|
||||
{
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
luax_pushboolean(L, t->getAreaSpreadIsRelativeDirection());
|
||||
return 1;
|
||||
return 5;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_setDirection(lua_State *L)
|
||||
@@ -734,6 +713,52 @@ int w_ParticleSystem_update(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Deprecated functions.
|
||||
|
||||
int w_ParticleSystem_setAreaSpread(lua_State *L)
|
||||
{
|
||||
luax_markdeprecated(L, "ParticleSystem:setAreaSpread", API_METHOD, DEPRECATED_REPLACED, "ParticleSystem:setEmissionArea");
|
||||
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
|
||||
ParticleSystem::AreaSpreadDistribution distribution = ParticleSystem::DISTRIBUTION_NONE;
|
||||
float x = 0.f, y = 0.f;
|
||||
|
||||
const char *str = lua_isnoneornil(L, 2) ? 0 : luaL_checkstring(L, 2);
|
||||
if (str && !ParticleSystem::getConstant(str, distribution))
|
||||
return luax_enumerror(L, "particle distribution", ParticleSystem::getConstants(distribution), str);
|
||||
|
||||
if (distribution != ParticleSystem::DISTRIBUTION_NONE)
|
||||
{
|
||||
x = (float) luaL_checknumber(L, 3);
|
||||
y = (float) luaL_checknumber(L, 4);
|
||||
if (x < 0.0f || y < 0.0f)
|
||||
return luaL_error(L, "Invalid area spread parameters (must be >= 0)");
|
||||
}
|
||||
|
||||
t->setEmissionArea(distribution, x, y, 0.0f, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_getAreaSpread(lua_State *L)
|
||||
{
|
||||
luax_markdeprecated(L, "ParticleSystem:getAreaSpread", API_METHOD, DEPRECATED_REPLACED, "ParticleSystem:getEmissionArea");
|
||||
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
love::Vector2 p;
|
||||
float angle;
|
||||
bool unused;
|
||||
ParticleSystem::AreaSpreadDistribution distribution = t->getEmissionArea(p, angle, unused);
|
||||
const char *str;
|
||||
ParticleSystem::getConstant(distribution, str);
|
||||
|
||||
lua_pushstring(L, str);
|
||||
lua_pushnumber(L, p.x);
|
||||
lua_pushnumber(L, p.y);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
static const luaL_Reg w_ParticleSystem_functions[] =
|
||||
{
|
||||
{ "clone", w_ParticleSystem_clone },
|
||||
@@ -752,12 +777,8 @@ static const luaL_Reg w_ParticleSystem_functions[] =
|
||||
{ "setPosition", w_ParticleSystem_setPosition },
|
||||
{ "getPosition", w_ParticleSystem_getPosition },
|
||||
{ "moveTo", w_ParticleSystem_moveTo },
|
||||
{ "setAreaSpread", w_ParticleSystem_setAreaSpread },
|
||||
{ "getAreaSpread", w_ParticleSystem_getAreaSpread },
|
||||
{ "setAreaSpreadAngle", w_ParticleSystem_setAreaSpreadAngle },
|
||||
{ "getAreaSpreadAngle", w_ParticleSystem_getAreaSpreadAngle },
|
||||
{ "setAreaSpreadIsRelativeDirection", w_ParticleSystem_setAreaSpreadIsRelativeDirection },
|
||||
{ "getAreaSpreadIsRelativeDirection", w_ParticleSystem_getAreaSpreadIsRelativeDirection },
|
||||
{ "setEmissionArea", w_ParticleSystem_setEmissionArea },
|
||||
{ "getEmissionArea", w_ParticleSystem_getEmissionArea },
|
||||
{ "setDirection", w_ParticleSystem_setDirection },
|
||||
{ "getDirection", w_ParticleSystem_getDirection },
|
||||
{ "setSpread", w_ParticleSystem_setSpread },
|
||||
@@ -800,6 +821,11 @@ static const luaL_Reg w_ParticleSystem_functions[] =
|
||||
{ "isPaused", w_ParticleSystem_isPaused },
|
||||
{ "isStopped", w_ParticleSystem_isStopped },
|
||||
{ "update", w_ParticleSystem_update },
|
||||
|
||||
// Deprecated.
|
||||
{ "setAreaSpread", w_ParticleSystem_setAreaSpread },
|
||||
{ "getAreaSpread", w_ParticleSystem_getAreaSpread },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user