From e9262080987cfd003a5f457b7bb13ae21442d18e Mon Sep 17 00:00:00 2001
From: Drake Arconis <drake@alchemyviewer.org>
Date: Mon, 3 Aug 2015 22:41:12 -0400
Subject: [PATCH] Fix a few bugs in the particle system and a small crash due
 to vs2013/5 codegen bugs

---
 indra/newview/llviewerpartsim.cpp    |  7 +++----
 indra/newview/llviewerpartsim.h      |  7 +++----
 indra/newview/llviewerpartsource.cpp | 12 ++++++------
 3 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 0815376840..4aac38a90c 100755
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -74,7 +74,6 @@ LLViewerPart::LLViewerPart() :
 	mPartID(0),
 	mLastUpdateTime(0.f),
 	mSkipOffset(0.f),
-	mVPCallback(NULL),
 	mImagep(NULL)
 {
 	mPartSourcep = NULL;
@@ -108,7 +107,7 @@ LLViewerPart::~LLViewerPart()
 	--LLViewerPartSim::sParticleCount2 ;
 }
 
-void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, LLVPCallback cb)
+void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, vp_callback_t cb)
 {
 	mPartID = LLViewerPart::sNextPartID;
 	LLViewerPart::sNextPartID++;
@@ -302,9 +301,9 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)
 		}
 
 		// Do a custom callback if we have one...
-		if (part->mVPCallback)
+		if (!part->mVPCallback.empty())
 		{
-			(*part->mVPCallback)(*part, dt);
+			part->mVPCallback(*part, dt);
 		}
 
 		if (part->mFlags & LLPartData::LL_PART_WIND_MASK)
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index 40e8e1d45d..87ef625737 100755
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -39,8 +39,6 @@ class LLVOPartGroup;
 
 #define LL_MAX_PARTICLE_COUNT 8192
 
-typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt);
-
 ///////////////////
 //
 // An individual particle
@@ -50,18 +48,19 @@ typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt);
 class LLViewerPart : public LLPartData
 {
 public:
+	typedef boost::function<void(LLViewerPart&, const F32)>	vp_callback_t;
 	~LLViewerPart();
 public:
 	LLViewerPart();
 
-	void init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, LLVPCallback cb);
+	void init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, vp_callback_t cb = 0);
 
 
 	U32					mPartID;					// Particle ID used primarily for moving between groups
 	F32					mLastUpdateTime;			// Last time the particle was updated
 	F32					mSkipOffset;				// Offset against current group mSkippedTime
 
-	LLVPCallback		mVPCallback;				// Callback function for more complicated behaviors
+	vp_callback_t mVPCallback;						// Callback function for more complicated behaviors
 	LLPointer<LLViewerPartSource> mPartSourcep;		// Particle source used for this object
 
 	LLViewerPart*		mParent;					// particle to connect to if this is part of a particle ribbon
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index c458b96a3b..7548f5e974 100755
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -278,7 +278,7 @@ void LLViewerPartSourceScript::update(const F32 dt)
 
 			LLViewerPart* part = new LLViewerPart();
 
-			part->init(this, mImagep, NULL);
+			part->init(this, mImagep);
 			part->mFlags = mPartSysData.mPartData.mFlags;
 			if (!mSourceObjectp.isNull() && mSourceObjectp->isHUDAttachment())
 			{
@@ -609,7 +609,7 @@ void LLViewerPartSourceSpiral::update(const F32 dt)
 			mPosAgent = mSourceObjectp->getRenderPosition();
 		}
 		LLViewerPart* part = new LLViewerPart();
-		part->init(this, mImagep, updatePart);
+		part->init(this, mImagep, boost::bind(&LLViewerPartSourceSpiral::updatePart, _1, _2));
 		part->mStartColor = mColor;
 		part->mEndColor = mColor;
 		part->mEndColor.mV[3] = 0.f;
@@ -668,8 +668,6 @@ void LLViewerPartSourceBeam::setColor(const LLColor4 &color)
 
 void LLViewerPartSourceBeam::updatePart(LLViewerPart &part, const F32 dt)
 {
-	F32 frac = part.mLastUpdateTime/part.mMaxAge;
-
 	LLViewerPartSource *ps = (LLViewerPartSource*)part.mPartSourcep;
 	LLViewerPartSourceBeam *psb = (LLViewerPartSourceBeam *)ps;
 	if (psb->mSourceObjectp.isNull())
@@ -698,6 +696,7 @@ void LLViewerPartSourceBeam::updatePart(LLViewerPart &part, const F32 dt)
 		target_pos_agent = psb->mTargetObjectp->getRenderPosition();
 	}
 
+	F32 frac = part.mLastUpdateTime / part.mMaxAge;
 	part.mPosAgent = (1.f - frac) * source_pos_agent;
 	if (psb->mTargetObjectp.isNull())
 	{
@@ -758,7 +757,8 @@ void LLViewerPartSourceBeam::update(const F32 dt)
 		}
 
 		LLViewerPart* part = new LLViewerPart();
-		part->init(this, mImagep, NULL);
+		part->init(this, mImagep, boost::bind(&LLViewerPartSourceBeam::updatePart, _1, _2));
+
 
 		part->mFlags = LLPartData::LL_PART_INTERP_COLOR_MASK |
 						LLPartData::LL_PART_INTERP_SCALE_MASK |
@@ -876,7 +876,7 @@ void LLViewerPartSourceChat::update(const F32 dt)
 			mPosAgent = mSourceObjectp->getRenderPosition();
 		}
 		LLViewerPart* part = new LLViewerPart();
-		part->init(this, mImagep, updatePart);
+		part->init(this, mImagep, boost::bind(&LLViewerPartSourceChat::updatePart, _1, _2));
 		part->mStartColor = mColor;
 		part->mEndColor = mColor;
 		part->mEndColor.mV[3] = 0.f;
-- 
GitLab