Browse Source

Re-added ParticleSystem:setQuads(q1, q2, ...). Active particles use the quads based on the particle's lifetime in a similar style to ParticleSystem:setColors and ParticleSystem:setSizes.

Alex Szpakowski 11 years ago
parent
commit
b9cd93e071

+ 47 - 0
src/modules/graphics/opengl/ParticleSystem.cpp

@@ -146,12 +146,16 @@ ParticleSystem::ParticleSystem(const ParticleSystem &p)
 	, offsetX(p.offsetX)
 	, offsetX(p.offsetX)
 	, offsetY(p.offsetY)
 	, offsetY(p.offsetY)
 	, colors(p.colors)
 	, colors(p.colors)
+	, quads(p.quads)
 	, relativeRotation(p.relativeRotation)
 	, relativeRotation(p.relativeRotation)
 {
 {
 	setBufferSize(maxParticles);
 	setBufferSize(maxParticles);
 
 
 	if (texture != nullptr)
 	if (texture != nullptr)
 		texture->retain();
 		texture->retain();
+
+	for (Quad *quad : quads)
+		quad->retain();
 }
 }
 
 
 ParticleSystem::~ParticleSystem()
 ParticleSystem::~ParticleSystem()
@@ -159,6 +163,9 @@ ParticleSystem::~ParticleSystem()
 	if (texture != nullptr)
 	if (texture != nullptr)
 		texture->release();
 		texture->release();
 
 
+	for (Quad *quad : quads)
+		quad->release();
+
 	deleteBuffers();
 	deleteBuffers();
 }
 }
 
 
@@ -305,6 +312,8 @@ void ParticleSystem::initParticle(Particle *p, float t)
 		p->angle += atan2f(p->velocity.y, p->velocity.x);
 		p->angle += atan2f(p->velocity.y, p->velocity.x);
 
 
 	p->color = colors[0];
 	p->color = colors[0];
+
+	p->quadIndex = 0;
 }
 }
 
 
 void ParticleSystem::insertTop(Particle *p)
 void ParticleSystem::insertTop(Particle *p)
@@ -721,6 +730,30 @@ std::vector<Color> ParticleSystem::getColor() const
 	return ncolors;
 	return ncolors;
 }
 }
 
 
+void ParticleSystem::setQuads(const std::vector<Quad *> &newQuads)
+{
+	for (Quad *quad : newQuads)
+		quad->retain();
+
+	for (Quad *quad : quads)
+		quad->release();
+
+	quads = newQuads;
+}
+
+void ParticleSystem::setQuads()
+{
+	for (Quad *quad : quads)
+		quad->release();
+
+	quads.clear();
+}
+
+const std::vector<Quad *> &ParticleSystem::getQuads() const
+{
+	return quads;
+}
+
 void ParticleSystem::setRelativeRotation(bool enable)
 void ParticleSystem::setRelativeRotation(bool enable)
 {
 {
 	relativeRotation = enable;
 	relativeRotation = enable;
@@ -820,9 +853,14 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
 	Vertex *pVerts = particleVerts;
 	Vertex *pVerts = particleVerts;
 	Particle *p = pHead;
 	Particle *p = pHead;
 
 
+	bool useQuads = !quads.empty();
+
 	// set the vertex data for each particle (transformation, texcoords, color)
 	// set the vertex data for each particle (transformation, texcoords, color)
 	while (p)
 	while (p)
 	{
 	{
+		if (useQuads)
+			textureVerts = quads[p->quadIndex]->getVertices();
+
 		// particle vertices are image vertices transformed by particle information
 		// particle vertices are image vertices transformed by particle information
 		t.setTransformation(p->position[0], p->position[1], p->angle, 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);
 		t.transform(pVerts, textureVerts, 4);
@@ -948,6 +986,15 @@ void ParticleSystem::update(float dt)
 			s -= (float)i;                            // 0 <= s <= 1
 			s -= (float)i;                            // 0 <= s <= 1
 			p->color = colors[i] * (1.0f - s) + colors[k] * s;
 			p->color = colors[i] * (1.0f - s) + colors[k] * s;
 
 
+			// Update the quad index.
+			k = quads.size();
+			if (k > 0)
+			{
+				s = t * (float) k; // [0:numquads-1] (clamped below)
+				i = (s > 0.0f) ? (size_t) s : 0;
+				p->quadIndex = (i < k) ? i : k - 1;
+			}
+
 			// Next particle.
 			// Next particle.
 			p = p->next;
 			p = p->next;
 		}
 		}

+ 17 - 0
src/modules/graphics/opengl/ParticleSystem.h

@@ -27,6 +27,7 @@
 #include "common/Vector.h"
 #include "common/Vector.h"
 #include "graphics/Drawable.h"
 #include "graphics/Drawable.h"
 #include "graphics/Color.h"
 #include "graphics/Color.h"
+#include "graphics/Quad.h"
 #include "Texture.h"
 #include "Texture.h"
 
 
 // STL
 // STL
@@ -421,6 +422,17 @@ public:
 	 **/
 	 **/
 	std::vector<Color> getColor() const;
 	std::vector<Color> getColor() const;
 
 
+	/**
+	 * Sets a list of Quads to use for particles over their lifetime.
+	 **/
+	void setQuads(const std::vector<Quad *> &newQuads);
+	void setQuads();
+
+	/**
+	 * Gets the Quads used when drawing the particles.
+	 **/
+	const std::vector<Quad *> &getQuads() const;
+
 	/**
 	/**
 	 * sets whether particle angles & rotations are relative to their velocities.
 	 * sets whether particle angles & rotations are relative to their velocities.
 	 **/
 	 **/
@@ -531,6 +543,8 @@ protected:
 		float spinEnd;
 		float spinEnd;
 
 
 		Colorf color;
 		Colorf color;
+
+		int quadIndex;
 	};
 	};
 
 
 	// Pointer to the beginning of the allocated memory.
 	// Pointer to the beginning of the allocated memory.
@@ -625,6 +639,9 @@ protected:
 	// Color.
 	// Color.
 	std::vector<Colorf> colors;
 	std::vector<Colorf> colors;
 
 
+	// Quads.
+	std::vector<Quad *> quads;
+
 	bool relativeRotation;
 	bool relativeRotation;
 
 
 	void createBuffers(size_t size);
 	void createBuffers(size_t size);

+ 49 - 0
src/modules/graphics/opengl/wrap_ParticleSystem.cpp

@@ -569,6 +569,53 @@ int w_ParticleSystem_getColors(lua_State *L)
 	return colors.size();
 	return colors.size();
 }
 }
 
 
+int w_ParticleSystem_setQuads(lua_State *L)
+{
+	ParticleSystem *t = luax_checkparticlesystem(L, 1);
+	std::vector<Quad *> quads;
+
+	if (lua_istable(L, 2))
+	{
+		for (size_t i = 1; i <= lua_objlen(L, 2); i++)
+		{
+			lua_rawgeti(L, 2, i);
+
+			Quad *q = luax_checktype<Quad>(L, -1, "Quad", GRAPHICS_QUAD_T);
+			quads.push_back(q);
+
+			lua_pop(L, 1);
+		}
+	}
+	else
+	{
+		for (int i = 2; i <= lua_gettop(L); i++)
+		{
+			Quad *q = luax_checktype<Quad>(L, i, "Quad", GRAPHICS_QUAD_T);
+			quads.push_back(q);
+		}
+	}
+
+	t->setQuads(quads);
+	return 0;
+}
+
+int w_ParticleSystem_getQuads(lua_State *L)
+{
+	ParticleSystem *t = luax_checkparticlesystem(L, 1);
+	const std::vector<Quad *> quads = t->getQuads();
+
+	lua_createtable(L, (int) quads.size(), 0);
+
+	for (size_t i = 0; i < quads.size(); i++)
+	{
+		quads[i]->retain();
+		luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quads[i]);
+		lua_rawseti(L, -2, i + 1);
+	}
+
+	return 1;
+}
+
 int w_ParticleSystem_setRelativeRotation(lua_State *L)
 int w_ParticleSystem_setRelativeRotation(lua_State *L)
 {
 {
 	ParticleSystem *t = luax_checkparticlesystem(L, 1);
 	ParticleSystem *t = luax_checkparticlesystem(L, 1);
@@ -699,6 +746,8 @@ static const luaL_Reg functions[] =
 	{ "getSpinVariation", w_ParticleSystem_getSpinVariation },
 	{ "getSpinVariation", w_ParticleSystem_getSpinVariation },
 	{ "setColors", w_ParticleSystem_setColors },
 	{ "setColors", w_ParticleSystem_setColors },
 	{ "getColors", w_ParticleSystem_getColors },
 	{ "getColors", w_ParticleSystem_getColors },
+	{ "setQuads", w_ParticleSystem_setQuads },
+	{ "getQuads", w_ParticleSystem_getQuads },
 	{ "setOffset", w_ParticleSystem_setOffset },
 	{ "setOffset", w_ParticleSystem_setOffset },
 	{ "getOffset", w_ParticleSystem_getOffset },
 	{ "getOffset", w_ParticleSystem_getOffset },
 	{ "setRelativeRotation", w_ParticleSystem_setRelativeRotation },
 	{ "setRelativeRotation", w_ParticleSystem_setRelativeRotation },

+ 2 - 0
src/modules/graphics/opengl/wrap_ParticleSystem.h

@@ -75,6 +75,8 @@ int w_ParticleSystem_setSpinVariation(lua_State *L);
 int w_ParticleSystem_getSpinVariation(lua_State *L);
 int w_ParticleSystem_getSpinVariation(lua_State *L);
 int w_ParticleSystem_setColors(lua_State *L);
 int w_ParticleSystem_setColors(lua_State *L);
 int w_ParticleSystem_getColors(lua_State *L);
 int w_ParticleSystem_getColors(lua_State *L);
+int w_ParticleSystem_setQuads(lua_State *L);
+int w_ParticleSystem_getQuads(lua_State *L);
 int w_ParticleSystem_setOffset(lua_State *L);
 int w_ParticleSystem_setOffset(lua_State *L);
 int w_ParticleSystem_getOffset(lua_State *L);
 int w_ParticleSystem_getOffset(lua_State *L);
 int w_ParticleSystem_setRelativeRotation(lua_State *L);
 int w_ParticleSystem_setRelativeRotation(lua_State *L);