Browse Source

Added ParticleSystem:clone()

Alex Szpakowski 11 years ago
parent
commit
bccac13432

+ 90 - 38
src/modules/graphics/opengl/ParticleSystem.cpp

@@ -58,28 +58,12 @@ float calculate_variation(float inner, float outer, float var)
 
 
 } // anonymous namespace
 } // anonymous namespace
 
 
-StringMap<ParticleSystem::AreaSpreadDistribution, ParticleSystem::DISTRIBUTION_MAX_ENUM>::Entry ParticleSystem::distributionsEntries[] = {
-	{ "none",     ParticleSystem::DISTRIBUTION_NONE },
-	{ "uniform",  ParticleSystem::DISTRIBUTION_UNIFORM },
-	{ "normal",   ParticleSystem::DISTRIBUTION_NORMAL },
-};
-StringMap<ParticleSystem::AreaSpreadDistribution, ParticleSystem::DISTRIBUTION_MAX_ENUM> ParticleSystem::distributions(ParticleSystem::distributionsEntries, sizeof(ParticleSystem::distributionsEntries));
-
-StringMap<ParticleSystem::InsertMode, ParticleSystem::INSERT_MODE_MAX_ENUM>::Entry ParticleSystem::insertModesEntries[] =
-{
-	{ "top",    ParticleSystem::INSERT_MODE_TOP },
-	{ "bottom", ParticleSystem::INSERT_MODE_BOTTOM },
-	{ "random", ParticleSystem::INSERT_MODE_RANDOM },
-};
-StringMap<ParticleSystem::InsertMode, ParticleSystem::INSERT_MODE_MAX_ENUM> ParticleSystem::insertModes(ParticleSystem::insertModesEntries, sizeof(ParticleSystem::insertModesEntries));
-
-
 ParticleSystem::ParticleSystem(Image *image, uint32 size)
 ParticleSystem::ParticleSystem(Image *image, uint32 size)
-	: pMem(NULL)
-	, pFree(NULL)
-	, pHead(NULL)
-	, pTail(NULL)
-	, particleVerts(NULL)
+	: pMem(nullptr)
+	, pFree(nullptr)
+	, pHead(nullptr)
+	, pTail(nullptr)
+	, particleVerts(nullptr)
 	, image(image)
 	, image(image)
 	, active(true)
 	, active(true)
 	, insertMode(INSERT_MODE_TOP)
 	, insertMode(INSERT_MODE_TOP)
@@ -120,14 +104,64 @@ ParticleSystem::ParticleSystem(Image *image, uint32 size)
 	image->retain();
 	image->retain();
 }
 }
 
 
+ParticleSystem::ParticleSystem(const ParticleSystem &p)
+	: pMem(nullptr)
+	, pFree(nullptr)
+	, pHead(nullptr)
+	, pTail(nullptr)
+	, particleVerts(nullptr)
+	, image(p.image)
+	, active(p.active)
+	, insertMode(p.insertMode)
+	, maxParticles(p.maxParticles)
+	, activeParticles(0)
+	, emissionRate(p.emissionRate)
+	, emitCounter(0.0f)
+	, areaSpreadDistribution(p.areaSpreadDistribution)
+	, lifetime(p.lifetime)
+	, life(p.lifetime) // Initialize with the maximum life time.
+	, particleLifeMin(p.particleLifeMin)
+	, particleLifeMax(p.particleLifeMax)
+	, direction(p.direction)
+	, spread(p.spread)
+	, speedMin(p.speedMin)
+	, speedMax(p.speedMax)
+	, linearAccelerationMin(p.linearAccelerationMin)
+	, linearAccelerationMax(p.linearAccelerationMax)
+	, radialAccelerationMin(p.radialAccelerationMin)
+	, radialAccelerationMax(p.radialAccelerationMax)
+	, tangentialAccelerationMin(p.tangentialAccelerationMin)
+	, tangentialAccelerationMax(p.tangentialAccelerationMax)
+	, sizes(p.sizes)
+	, sizeVariation(p.sizeVariation)
+	, rotationMin(p.rotationMin)
+	, rotationMax(p.rotationMax)
+	, spinStart(p.spinStart)
+	, spinEnd(p.spinEnd)
+	, spinVariation(p.spinVariation)
+	, offsetX(p.offsetX)
+	, offsetY(p.offsetY)
+	, colors(p.colors)
+{
+	setBufferSize(maxParticles);
+
+	if (image != nullptr)
+		image->retain();
+}
+
 ParticleSystem::~ParticleSystem()
 ParticleSystem::~ParticleSystem()
 {
 {
-	if (this->image != 0)
-		this->image->release();
+	if (image != nullptr)
+		image->release();
 
 
 	deleteBuffers();
 	deleteBuffers();
 }
 }
 
 
+ParticleSystem *ParticleSystem::clone()
+{
+	return new ParticleSystem(*this);
+}
+
 void ParticleSystem::createBuffers(size_t size)
 void ParticleSystem::createBuffers(size_t size)
 {
 {
 	try
 	try
@@ -149,8 +183,8 @@ void ParticleSystem::deleteBuffers()
 	delete[] pMem;
 	delete[] pMem;
 	delete[] particleVerts;
 	delete[] particleVerts;
 
 
-	pMem = NULL;
-	particleVerts = NULL;
+	pMem = nullptr;
+	particleVerts = nullptr;
 	maxParticles = 0;
 	maxParticles = 0;
 	activeParticles = 0;
 	activeParticles = 0;
 }
 }
@@ -263,33 +297,33 @@ void ParticleSystem::initParticle(particle *p)
 
 
 void ParticleSystem::insertTop(particle *p)
 void ParticleSystem::insertTop(particle *p)
 {
 {
-	if (pHead == NULL)
+	if (pHead == nullptr)
 	{
 	{
 		pHead = p;
 		pHead = p;
-		p->prev = NULL;
+		p->prev = nullptr;
 	}
 	}
 	else
 	else
 	{
 	{
 		pTail->next = p;
 		pTail->next = p;
 		p->prev = pTail;
 		p->prev = pTail;
 	}
 	}
-	p->next = NULL;
+	p->next = nullptr;
 	pTail = p;
 	pTail = p;
 }
 }
 
 
 void ParticleSystem::insertBottom(particle *p)
 void ParticleSystem::insertBottom(particle *p)
 {
 {
-	if (pTail == NULL)
+	if (pTail == nullptr)
 	{
 	{
 		pTail = p;
 		pTail = p;
-		p->next = NULL;
+		p->next = nullptr;
 	}
 	}
 	else
 	else
 	{
 	{
 		pHead->prev = p;
 		pHead->prev = p;
 		p->next = pHead;
 		p->next = pHead;
 	}
 	}
-	p->prev = NULL;
+	p->prev = nullptr;
 	pHead = p;
 	pHead = p;
 }
 }
 
 
@@ -304,7 +338,7 @@ void ParticleSystem::insertRandom(particle *p)
 		particle *pA = pHead;
 		particle *pA = pHead;
 		if (pA)
 		if (pA)
 			pA->prev = p;
 			pA->prev = p;
-		p->prev = NULL;
+		p->prev = nullptr;
 		p->next = pA;
 		p->next = pA;
 		pHead = p;
 		pHead = p;
 		return;
 		return;
@@ -327,7 +361,7 @@ ParticleSystem::particle *ParticleSystem::removeParticle(particle *p)
 	// The linked list is updated in this function and old pointers may be
 	// The linked list is updated in this function and old pointers may be
 	// invalidated. The returned pointer will inform the caller of the new
 	// invalidated. The returned pointer will inform the caller of the new
 	// pointer to the next particle.
 	// pointer to the next particle.
-	particle *pNext = NULL;
+	particle *pNext = nullptr;
 
 
 	// Removes the particle from the linked list.
 	// Removes the particle from the linked list.
 	if (p->prev)
 	if (p->prev)
@@ -691,12 +725,12 @@ void ParticleSystem::pause()
 
 
 void ParticleSystem::reset()
 void ParticleSystem::reset()
 {
 {
-	if (pMem == NULL)
+	if (pMem == nullptr)
 		return;
 		return;
 
 
 	pFree = pMem;
 	pFree = pMem;
-	pHead = NULL;
-	pTail = NULL;
+	pHead = nullptr;
+	pTail = nullptr;
 	activeParticles = 0;
 	activeParticles = 0;
 	life = lifetime;
 	life = lifetime;
 	emitCounter = 0;
 	emitCounter = 0;
@@ -741,7 +775,7 @@ bool ParticleSystem::isFull() const
 void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
 void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
 {
 {
 	uint32 pCount = getCount();
 	uint32 pCount = getCount();
-	if (pCount == 0 || image == NULL || pMem == NULL || particleVerts == NULL)
+	if (pCount == 0 || image == nullptr || pMem == nullptr || particleVerts == nullptr)
 		return;
 		return;
 
 
 	Color curcolor = gl.getColor();
 	Color curcolor = gl.getColor();
@@ -805,7 +839,7 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
 
 
 void ParticleSystem::update(float dt)
 void ParticleSystem::update(float dt)
 {
 {
-	if (pMem == NULL || dt == 0.0f)
+	if (pMem == nullptr || dt == 0.0f)
 		return;
 		return;
 
 
 	// Make some more particles.
 	// Make some more particles.
@@ -923,6 +957,24 @@ bool ParticleSystem::getConstant(InsertMode in, const char *&out)
 	return insertModes.find(in, out);
 	return insertModes.find(in, out);
 }
 }
 
 
+StringMap<ParticleSystem::AreaSpreadDistribution, ParticleSystem::DISTRIBUTION_MAX_ENUM>::Entry ParticleSystem::distributionsEntries[] =
+{
+	{ "none",    ParticleSystem::DISTRIBUTION_NONE },
+	{ "uniform", ParticleSystem::DISTRIBUTION_UNIFORM },
+	{ "normal",  ParticleSystem::DISTRIBUTION_NORMAL },
+};
+
+StringMap<ParticleSystem::AreaSpreadDistribution, ParticleSystem::DISTRIBUTION_MAX_ENUM> ParticleSystem::distributions(ParticleSystem::distributionsEntries, sizeof(ParticleSystem::distributionsEntries));
+
+StringMap<ParticleSystem::InsertMode, ParticleSystem::INSERT_MODE_MAX_ENUM>::Entry ParticleSystem::insertModesEntries[] =
+{
+	{ "top",    ParticleSystem::INSERT_MODE_TOP },
+	{ "bottom", ParticleSystem::INSERT_MODE_BOTTOM },
+	{ "random", ParticleSystem::INSERT_MODE_RANDOM },
+};
+
+StringMap<ParticleSystem::InsertMode, ParticleSystem::INSERT_MODE_MAX_ENUM> ParticleSystem::insertModes(ParticleSystem::insertModesEntries, sizeof(ParticleSystem::insertModesEntries));
+
 } // opengl
 } // opengl
 } // graphics
 } // graphics
 } // love
 } // love

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

@@ -79,12 +79,20 @@ public:
 	 * Creates a particle system with the specified buffersize and image.
 	 * Creates a particle system with the specified buffersize and image.
 	 **/
 	 **/
 	ParticleSystem(Image *image, uint32 buffer);
 	ParticleSystem(Image *image, uint32 buffer);
+	ParticleSystem(const ParticleSystem &p);
 
 
 	/**
 	/**
 	 * Deletes any allocated memory.
 	 * Deletes any allocated memory.
 	 **/
 	 **/
 	virtual ~ParticleSystem();
 	virtual ~ParticleSystem();
 
 
+	/**
+	 * Creates an identical copy of this ParticleSystem. The clone does not
+	 * duplicate any existing particles from this ParticleSystem, just the
+	 * settable parameters.
+	 **/
+	ParticleSystem *clone();
+
 	/**
 	/**
 	 * Sets the image used in the particle system.
 	 * Sets the image used in the particle system.
 	 * @param image The new image.
 	 * @param image The new image.

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

@@ -36,6 +36,17 @@ ParticleSystem *luax_checkparticlesystem(lua_State *L, int idx)
 	return luax_checktype<ParticleSystem>(L, idx, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T);
 	return luax_checktype<ParticleSystem>(L, idx, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T);
 }
 }
 
 
+int w_ParticleSystem_clone(lua_State *L)
+{
+	ParticleSystem *t = luax_checkparticlesystem(L, 1);
+
+	ParticleSystem *clone = nullptr;
+	EXCEPT_GUARD(clone = t->clone();)
+
+	luax_pushtype(L, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T, clone);
+	return 1;
+}
+
 int w_ParticleSystem_setImage(lua_State *L)
 int w_ParticleSystem_setImage(lua_State *L)
 {
 {
 	ParticleSystem *t = luax_checkparticlesystem(L, 1);
 	ParticleSystem *t = luax_checkparticlesystem(L, 1);
@@ -604,6 +615,7 @@ int w_ParticleSystem_update(lua_State *L)
 
 
 static const luaL_Reg functions[] =
 static const luaL_Reg functions[] =
 {
 {
+	{ "clone", w_ParticleSystem_clone },
 	{ "setImage", w_ParticleSystem_setImage },
 	{ "setImage", w_ParticleSystem_setImage },
 	{ "getImage", w_ParticleSystem_getImage },
 	{ "getImage", w_ParticleSystem_getImage },
 	{ "setBufferSize", w_ParticleSystem_setBufferSize },
 	{ "setBufferSize", w_ParticleSystem_setBufferSize },

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

@@ -34,6 +34,7 @@ namespace opengl
 {
 {
 
 
 ParticleSystem *luax_checkparticlesystem(lua_State *L, int idx);
 ParticleSystem *luax_checkparticlesystem(lua_State *L, int idx);
+int w_ParticleSystem_clone(lua_State *L);
 int w_ParticleSystem_setImage(lua_State *L);
 int w_ParticleSystem_setImage(lua_State *L);
 int w_ParticleSystem_getImage(lua_State *L);
 int w_ParticleSystem_getImage(lua_State *L);
 int w_ParticleSystem_setBufferSize(lua_State *L);
 int w_ParticleSystem_setBufferSize(lua_State *L);