mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
Added ParticleSystem:setRelativeRotation. If enabled, particle rotations and angles will be relative to their current velocities.
This commit is contained in:
@@ -94,6 +94,7 @@ ParticleSystem::ParticleSystem(Texture *texture, uint32 size)
|
||||
, spinVariation(0)
|
||||
, offsetX(float(texture->getWidth())*0.5f)
|
||||
, offsetY(float(texture->getHeight())*0.5f)
|
||||
, relativeRotation(false)
|
||||
{
|
||||
if (size == 0 || size > MAX_PARTICLES)
|
||||
throw love::Exception("Invalid ParticleSystem size.");
|
||||
@@ -145,6 +146,7 @@ ParticleSystem::ParticleSystem(const ParticleSystem &p)
|
||||
, offsetX(p.offsetX)
|
||||
, offsetY(p.offsetY)
|
||||
, colors(p.colors)
|
||||
, relativeRotation(p.relativeRotation)
|
||||
{
|
||||
setBufferSize(maxParticles);
|
||||
|
||||
@@ -169,7 +171,7 @@ void ParticleSystem::createBuffers(size_t size)
|
||||
{
|
||||
try
|
||||
{
|
||||
pFree = pMem = new particle[size];
|
||||
pFree = pMem = new Particle[size];
|
||||
particleVerts = new love::Vertex[size * 4];
|
||||
maxParticles = (uint32) size;
|
||||
}
|
||||
@@ -212,7 +214,7 @@ void ParticleSystem::addParticle(float t)
|
||||
return;
|
||||
|
||||
// Gets a free particle and updates the allocation pointer.
|
||||
particle *p = pFree++;
|
||||
Particle *p = pFree++;
|
||||
initParticle(p, t);
|
||||
|
||||
switch (insertMode)
|
||||
@@ -232,7 +234,7 @@ void ParticleSystem::addParticle(float t)
|
||||
activeParticles++;
|
||||
}
|
||||
|
||||
void ParticleSystem::initParticle(particle *p, float t)
|
||||
void ParticleSystem::initParticle(Particle *p, float t)
|
||||
{
|
||||
float min,max;
|
||||
|
||||
@@ -298,10 +300,14 @@ void ParticleSystem::initParticle(particle *p, float t)
|
||||
p->spinEnd = calculate_variation(spinEnd, spinStart, spinVariation);
|
||||
p->rotation = (float) rng.random(min, max);
|
||||
|
||||
p->angle = p->rotation;
|
||||
if (relativeRotation)
|
||||
p->angle += atan2f(p->speed.y, p->speed.x);
|
||||
|
||||
p->color = colors[0];
|
||||
}
|
||||
|
||||
void ParticleSystem::insertTop(particle *p)
|
||||
void ParticleSystem::insertTop(Particle *p)
|
||||
{
|
||||
if (pHead == nullptr)
|
||||
{
|
||||
@@ -317,7 +323,7 @@ void ParticleSystem::insertTop(particle *p)
|
||||
pTail = p;
|
||||
}
|
||||
|
||||
void ParticleSystem::insertBottom(particle *p)
|
||||
void ParticleSystem::insertBottom(Particle *p)
|
||||
{
|
||||
if (pTail == nullptr)
|
||||
{
|
||||
@@ -333,7 +339,7 @@ void ParticleSystem::insertBottom(particle *p)
|
||||
pHead = p;
|
||||
}
|
||||
|
||||
void ParticleSystem::insertRandom(particle *p)
|
||||
void ParticleSystem::insertRandom(Particle *p)
|
||||
{
|
||||
// Nonuniform, but 64-bit is so large nobody will notice. Hopefully.
|
||||
uint64 pos = rng.rand() % ((int64) activeParticles + 1);
|
||||
@@ -341,7 +347,7 @@ void ParticleSystem::insertRandom(particle *p)
|
||||
// Special case where the particle gets inserted before the head.
|
||||
if (pos == activeParticles)
|
||||
{
|
||||
particle *pA = pHead;
|
||||
Particle *pA = pHead;
|
||||
if (pA)
|
||||
pA->prev = p;
|
||||
p->prev = nullptr;
|
||||
@@ -351,8 +357,8 @@ void ParticleSystem::insertRandom(particle *p)
|
||||
}
|
||||
|
||||
// Inserts the particle after the randomly selected particle.
|
||||
particle *pA = pMem + pos;
|
||||
particle *pB = pA->next;
|
||||
Particle *pA = pMem + pos;
|
||||
Particle *pB = pA->next;
|
||||
pA->next = p;
|
||||
if (pB)
|
||||
pB->prev = p;
|
||||
@@ -362,12 +368,12 @@ void ParticleSystem::insertRandom(particle *p)
|
||||
p->next = pB;
|
||||
}
|
||||
|
||||
ParticleSystem::particle *ParticleSystem::removeParticle(particle *p)
|
||||
ParticleSystem::Particle *ParticleSystem::removeParticle(Particle *p)
|
||||
{
|
||||
// The linked list is updated in this function and old pointers may be
|
||||
// invalidated. The returned pointer will inform the caller of the new
|
||||
// pointer to the next particle.
|
||||
particle *pNext = nullptr;
|
||||
Particle *pNext = nullptr;
|
||||
|
||||
// Removes the particle from the linked list.
|
||||
if (p->prev)
|
||||
@@ -715,6 +721,16 @@ std::vector<Color> ParticleSystem::getColor() const
|
||||
return ncolors;
|
||||
}
|
||||
|
||||
void ParticleSystem::setRelativeRotation(bool enable)
|
||||
{
|
||||
relativeRotation = enable;
|
||||
}
|
||||
|
||||
bool ParticleSystem::hasRelativeRotation() const
|
||||
{
|
||||
return relativeRotation;
|
||||
}
|
||||
|
||||
uint32 ParticleSystem::getCount() const
|
||||
{
|
||||
return activeParticles;
|
||||
@@ -802,13 +818,13 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
|
||||
|
||||
const Vertex *textureVerts = texture->getVertices();
|
||||
Vertex *pVerts = particleVerts;
|
||||
particle *p = pHead;
|
||||
Particle *p = pHead;
|
||||
|
||||
// set the vertex data for each particle (transformation, texcoords, color)
|
||||
while (p)
|
||||
{
|
||||
// particle vertices are image vertices transformed by particle information
|
||||
t.setTransformation(p->position[0], p->position[1], p->rotation, p->size, p->size, offsetX, offsetY, 0.0f, 0.0f);
|
||||
t.setTransformation(p->position[0], p->position[1], p->angle, p->size, p->size, offsetX, offsetY, 0.0f, 0.0f);
|
||||
t.transform(pVerts, textureVerts, 4);
|
||||
|
||||
// set the texture coordinate and color data for particle vertices
|
||||
@@ -858,7 +874,7 @@ void ParticleSystem::update(float dt)
|
||||
return;
|
||||
|
||||
// Traverse all particles and update.
|
||||
particle *p = pHead;
|
||||
Particle *p = pHead;
|
||||
|
||||
while (p)
|
||||
{
|
||||
@@ -903,7 +919,12 @@ void ParticleSystem::update(float dt)
|
||||
const float t = 1.0f - p->life / p->lifetime;
|
||||
|
||||
// Rotate.
|
||||
p->rotation += (p->spinStart * (1.0f - t) + p->spinEnd * t)*dt;
|
||||
p->rotation += (p->spinStart * (1.0f - t) + p->spinEnd * t) * dt;
|
||||
|
||||
p->angle = p->rotation;
|
||||
|
||||
if (relativeRotation)
|
||||
p->angle += atan2f(p->speed.y, p->speed.x);
|
||||
|
||||
// Change size according to given intervals:
|
||||
// i = 0 1 2 3 n-1
|
||||
|
||||
@@ -421,6 +421,12 @@ public:
|
||||
**/
|
||||
std::vector<Color> getColor() const;
|
||||
|
||||
/**
|
||||
* sets whether particle angles & rotations are relative to their velocities.
|
||||
**/
|
||||
void setRelativeRotation(bool enable);
|
||||
bool hasRelativeRotation() const;
|
||||
|
||||
/**
|
||||
* Returns the amount of particles that are currently active in the system.
|
||||
**/
|
||||
@@ -494,11 +500,12 @@ public:
|
||||
static bool getConstant(InsertMode in, const char *&out);
|
||||
|
||||
protected:
|
||||
|
||||
// Represents a single particle.
|
||||
struct particle
|
||||
struct Particle
|
||||
{
|
||||
particle *prev;
|
||||
particle *next;
|
||||
Particle *prev;
|
||||
Particle *next;
|
||||
|
||||
float lifetime;
|
||||
float life;
|
||||
@@ -518,7 +525,8 @@ protected:
|
||||
float sizeOffset;
|
||||
float sizeIntervalSize;
|
||||
|
||||
float rotation;
|
||||
float rotation; // Amount of rotation applied to the final angle.
|
||||
float angle;
|
||||
float spinStart;
|
||||
float spinEnd;
|
||||
|
||||
@@ -526,16 +534,16 @@ protected:
|
||||
};
|
||||
|
||||
// Pointer to the beginning of the allocated memory.
|
||||
particle *pMem;
|
||||
Particle *pMem;
|
||||
|
||||
// Pointer to a free particle.
|
||||
particle *pFree;
|
||||
Particle *pFree;
|
||||
|
||||
// Pointer to the start of the linked list.
|
||||
particle *pHead;
|
||||
Particle *pHead;
|
||||
|
||||
// Pointer to the end of the linked list.
|
||||
particle *pTail;
|
||||
Particle *pTail;
|
||||
|
||||
// array of transformed vertex data for all particles, for drawing
|
||||
Vertex *particleVerts;
|
||||
@@ -617,17 +625,19 @@ protected:
|
||||
// Color.
|
||||
std::vector<Colorf> colors;
|
||||
|
||||
bool relativeRotation;
|
||||
|
||||
void createBuffers(size_t size);
|
||||
void deleteBuffers();
|
||||
|
||||
void addParticle(float t);
|
||||
particle *removeParticle(particle *p);
|
||||
Particle *removeParticle(Particle *p);
|
||||
|
||||
// Called by addParticle.
|
||||
void initParticle(particle *p, float t);
|
||||
void insertTop(particle *p);
|
||||
void insertBottom(particle *p);
|
||||
void insertRandom(particle *p);
|
||||
void initParticle(Particle *p, float t);
|
||||
void insertTop(Particle *p);
|
||||
void insertBottom(Particle *p);
|
||||
void insertRandom(Particle *p);
|
||||
|
||||
static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM>::Entry distributionsEntries[];
|
||||
static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM> distributions;
|
||||
|
||||
@@ -569,6 +569,20 @@ int w_ParticleSystem_getColors(lua_State *L)
|
||||
return colors.size();
|
||||
}
|
||||
|
||||
int w_ParticleSystem_setRelativeRotation(lua_State *L)
|
||||
{
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
t->setRelativeRotation(luax_toboolean(L, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_hasRelativeRotation(lua_State *L)
|
||||
{
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
luax_pushboolean(L, t->hasRelativeRotation());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_getCount(lua_State *L)
|
||||
{
|
||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||
@@ -687,6 +701,8 @@ static const luaL_Reg functions[] =
|
||||
{ "getColors", w_ParticleSystem_getColors },
|
||||
{ "setOffset", w_ParticleSystem_setOffset },
|
||||
{ "getOffset", w_ParticleSystem_getOffset },
|
||||
{ "setRelativeRotation", w_ParticleSystem_setRelativeRotation },
|
||||
{ "hasRelativeRotation", w_ParticleSystem_hasRelativeRotation },
|
||||
{ "getCount", w_ParticleSystem_getCount },
|
||||
{ "start", w_ParticleSystem_start },
|
||||
{ "stop", w_ParticleSystem_stop },
|
||||
|
||||
@@ -77,6 +77,8 @@ int w_ParticleSystem_setColors(lua_State *L);
|
||||
int w_ParticleSystem_getColors(lua_State *L);
|
||||
int w_ParticleSystem_setOffset(lua_State *L);
|
||||
int w_ParticleSystem_getOffset(lua_State *L);
|
||||
int w_ParticleSystem_setRelativeRotation(lua_State *L);
|
||||
int w_ParticleSystem_hasRelativeRotation(lua_State *L);
|
||||
int w_ParticleSystem_getCount(lua_State *L);
|
||||
int w_ParticleSystem_start(lua_State *L);
|
||||
int w_ParticleSystem_stop(lua_State *L);
|
||||
|
||||
Reference in New Issue
Block a user