diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 602f2c29e5f25cf046086332f7edb6745ad12884..7751ef87ee5317e1dc3eaf764a543af6e9c813c2 100755
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -4520,7 +4520,11 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
 		S32 tc_size = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF;
 			
 		LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size);
-		LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size);
+
+		if (src.mNormals)
+		{
+			LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size);
+		}
 
 		if(src.mTexCoords)
 		{
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index ef6eb75a6bc00d06bd5cbc9de70444a9f2c583f8..e236f98fe6fb5db5f02402d8eb22169d54f0fcf1 100755
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1122,6 +1122,43 @@ void LLModel::getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& tra
 	translation_out = mNormalizedTranslation;
 }
 
+LLVector3 LLModel::getTransformedCenter(const LLMatrix4& mat)
+{
+	LLVector3 ret;
+
+	if (!mVolumeFaces.empty())
+	{
+		LLMatrix4a m;
+		m.loadu(mat);
+
+		LLVector4a minv,maxv;
+
+		LLVector4a t;
+		m.affineTransform(mVolumeFaces[0].mPositions[0], t);
+		minv = maxv = t;
+
+		for (S32 i = 0; i < mVolumeFaces.size(); ++i)
+		{
+			LLVolumeFace& face = mVolumeFaces[i];
+
+			for (U32 j = 0; j < face.mNumVertices; ++j)
+			{
+				m.affineTransform(face.mPositions[j],t);
+				update_min_max(minv, maxv, t);
+			}
+		}
+
+		minv.add(maxv);
+		minv.mul(0.5f);
+
+		ret.set(minv.getF32ptr());
+	}
+
+	return ret;
+}
+
+
+
 void LLModel::setNumVolumeFaces(S32 count)
 {
 	mVolumeFaces.resize(count);
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 1cf528fd9f3a723b8bf5b8035a8471b5a5f25872..aaafc55258d51fac20b3016b7dea88c9d470fcb7 100755
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -173,13 +173,15 @@ public:
 	void optimizeVolumeFaces();
 	void offsetMesh( const LLVector3& pivotPoint );
 	void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out);
-	
+	LLVector3 getTransformedCenter(const LLMatrix4& mat);
+
 	//reorder face list based on mMaterialList in this and reference so 
 	//order matches that of reference (material ordering touchup)
 	bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
 	bool isMaterialListSubset( LLModel* ref );
 	bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
 	
+	
 	std::vector<std::string> mMaterialList;
 
 	//data used for skin weights
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 2e3a9119b83a1f79d694bdb767c8b7152a845483..31ab37f9703ad75b2cbbaafc14e386c5db7a85f9 100755
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -441,7 +441,7 @@ void LLDrawable::makeActive()
 	}
 
 	llassert(isAvatar() || isRoot() || mParent->isActive());
-	}
+}
 
 
 void LLDrawable::makeStatic(BOOL warning_enabled)
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 4608d16fec66cc1ccfb2cbe1916e41238d2cd91a..4420a34fae2d74b60d25ab0e5ee3cdb877222f53 100755
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -284,7 +284,6 @@ public:
  		NEARBY_LIGHT	= 0x00200000, // In gPipeline.mNearbyLightSet
 		BUILT			= 0x00400000,
 		FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned)
-		CLEAR_INVISIBLE = 0x01000000, // clear FORCE_INVISIBLE next draw frame
 		REBUILD_SHADOW =  0x02000000,
 		HAS_ALPHA		= 0x04000000,
 		RIGGED			= 0x08000000,
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 6fa16825df68f3906255a931d76be1a668e18a53..331744acb7f0f79dd555cee7eae55b231d0be4b9 100755
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -515,7 +515,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
 				// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow).  Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
 				if (current_shader && 
 					draw_glow_for_this_partition &&
-					params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
+					params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE) &&
+					(!params.mParticle || params.mHasGlow))
 				{
 					static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GLOW("Alpha Glow");
 					LLFastTimer t(FTM_RENDER_ALPHA_GLOW);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 9e07cedf18f28b89b65efd42440bc70e4a2b6a45..59333613b6effa391846cd76529c4353c8d016c2 100755
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -4652,7 +4652,8 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
 	mDistance(0.f),
 	mDrawMode(LLRender::TRIANGLES),
 	mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA),
-	mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA)
+	mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA),
+	mHasGlow(FALSE)
 {
 	mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
 	
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 08e77855c41c5ef91d924c2e7a4fcd6b35c6f78f..e9be93ce982c827c7b52ee07a19eecc5d64fad5e 100755
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -70,12 +70,12 @@ protected:
 public:
 	void* operator new(size_t size)
 	{
-		return ll_aligned_malloc_16(size);
+		return ll_aligned_malloc(size,64);
 	}
 
 	void operator delete(void* ptr)
 	{
-		ll_aligned_free_16(ptr);
+		ll_aligned_free(ptr);
 	}
 
 
@@ -121,6 +121,7 @@ public:
 	U32 mDrawMode;
 	U32 mBlendFuncSrc;
 	U32 mBlendFuncDst;
+	BOOL mHasGlow;
 
 	struct CompareTexture
 	{
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 9dc9932c868109b3abe7dba402f4267e4df4ec4d..e17b085eabb6786780ee24e5f688fb8a96e45401 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2137,7 +2137,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 		if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned)
 		{
 // 			lldebugs << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << llendl;
-			mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
+			mDrawable->clearState(LLDrawable::FORCE_INVISIBLE);
+			gPipeline.markRebuild( mDrawable, LLDrawable::REBUILD_ALL, TRUE );
 		}
 	}
 
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index fa79ac07e68c59969e8b9f00eb18e00862897c39..66615657d82a723d433c96b4e1fbeb1c688a5686 100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -2064,8 +2064,9 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
 			if (childp->mDrawable.notNull())
 			{
 				// Make the drawable visible again and set the drawable parent
- 				childp->mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
+				childp->mDrawable->clearState(LLDrawable::FORCE_INVISIBLE);
 				childp->setDrawableParent(objectp->mDrawable); // LLViewerObjectList::findOrphans()
+				gPipeline.markRebuild( childp->mDrawable, LLDrawable::REBUILD_ALL, TRUE );
 			}
 
 			// Make certain particles, icon and HUD aren't hidden
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 21f1d2619c1be4053d81f09a594e70336e29e3bb..96cd43a8abeae4e996647fd2e1a849505cef4393 100755
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -387,7 +387,7 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)
 		}
 
 		// Do glow interpolation
-		part->mGlow.mV[3] = (U8) (lerp(part->mStartGlow, part->mEndGlow, frac)*255.f);
+		part->mGlow.mV[3] = (U8) llround(lerp(part->mStartGlow, part->mEndGlow, frac)*255.f);
 
 		// Set the last update time to now.
 		part->mLastUpdateTime = cur_time;
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index 8c49ce646db84ae0701cc38eb764db6c51cd2a03..b6bbd6140dcf64c19fd42a18a83c91f0f5f148d5 100755
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -313,7 +313,7 @@ void LLViewerPartSourceScript::update(const F32 dt)
 
 			part->mStartGlow = mPartSysData.mPartData.mStartGlow;
 			part->mEndGlow = mPartSysData.mPartData.mEndGlow;
-			part->mGlow = LLColor4U(0, 0, 0, (U8) (part->mStartGlow*255.f));
+			part->mGlow = LLColor4U(0, 0, 0, (U8) llround(part->mStartGlow*255.f));
 			
 			if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_DROP)
 			{
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 99b3accda8da2132a99407ef63e193d3f6efe069..e2d1d2b45c9731b131822e4e85ba8712a582e33e 100755
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -273,6 +273,10 @@ void LLVOPartGroup::getBlendFunc(S32 idx, U32& src, U32& dst)
 		src = part->mBlendFuncSource;
 		dst = part->mBlendFuncDest;
 	}
+	else
+	{
+		llerrs << "WTF?" << llendl;
+	}
 }
 
 LLVector3 LLVOPartGroup::getCameraPosition() const
@@ -670,7 +674,7 @@ void LLVOPartGroup::getGeometry(S32 idx,
 		}
 		else 
 		{
-			pglow = LLColor4U(0, 0, 0, (U8) (255.f*part.mStartGlow));
+			pglow = LLColor4U(0, 0, 0, (U8) llround(255.f*part.mStartGlow));
 			pcolor = part.mStartColor;
 		}
 	}
@@ -685,10 +689,13 @@ void LLVOPartGroup::getGeometry(S32 idx,
 	*colorsp++ = color;
 	*colorsp++ = color;
 
-	*emissivep++ = pglow;
-	*emissivep++ = pglow;
-	*emissivep++ = part.mGlow;
-	*emissivep++ = part.mGlow;
+	//if (pglow.mV[3] || part.mGlow.mV[3])
+	{ //only write glow if it is not zero
+		*emissivep++ = pglow;
+		*emissivep++ = pglow;
+		*emissivep++ = part.mGlow;
+		*emissivep++ = part.mGlow;
+	}
 
 
 	if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK))
@@ -873,8 +880,17 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 		LLStrider<LLColor4U> cur_col = colorsp + geom_idx;
 		LLStrider<LLColor4U> cur_glow = emissivep + geom_idx;
 
+		LLColor4U* start_glow = cur_glow.get();
+
 		object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_glow, cur_idx);
 		
+		BOOL has_glow = FALSE;
+
+		if (cur_glow.get() != start_glow)
+		{
+			has_glow = TRUE;
+		}
+
 		llassert(facep->getGeomCount() == 4);
 		llassert(facep->getIndicesCount() == 6);
 
@@ -894,26 +910,32 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 
 		object->getBlendFunc(facep->getTEOffset(), bf_src, bf_dst);
 
-		if (idx >= 0 &&
-			draw_vec[idx]->mTexture == facep->getTexture() &&
-			draw_vec[idx]->mFullbright == fullbright &&
-			draw_vec[idx]->mBlendFuncDst == bf_dst &&
-			draw_vec[idx]->mBlendFuncSrc == bf_src)
+		
+		if (idx >= 0)
 		{
-			if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1)
-			{
-				batched = true;
-				draw_vec[idx]->mCount += facep->getIndicesCount();
-				draw_vec[idx]->mEnd += facep->getGeomCount();
-				draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
-			}
-			else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1)
+			LLDrawInfo* info = draw_vec[idx];
+
+			if (info->mTexture == facep->getTexture() &&
+				info->mHasGlow == has_glow &&
+				info->mFullbright == fullbright &&
+				info->mBlendFuncDst == bf_dst &&
+				info->mBlendFuncSrc == bf_src)
 			{
-				batched = true;
-				draw_vec[idx]->mCount += facep->getIndicesCount();
-				draw_vec[idx]->mStart -= facep->getGeomCount();
-				draw_vec[idx]->mOffset = facep->getIndicesStart();
-				draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+				if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1)
+				{
+					batched = true;
+					info->mCount += facep->getIndicesCount();
+					info->mEnd += facep->getGeomCount();
+					info->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+				}
+				else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1)
+				{
+					batched = true;
+					info->mCount += facep->getIndicesCount();
+					info->mStart -= facep->getGeomCount();
+					info->mOffset = facep->getIndicesStart();
+					info->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+				}
 			}
 		}
 
@@ -932,6 +954,8 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 			info->mVSize = vsize;
 			info->mBlendFuncDst = bf_dst;
 			info->mBlendFuncSrc = bf_src;
+			info->mHasGlow = has_glow;
+			info->mParticle = TRUE;
 			draw_vec.push_back(info);
 			//for alpha sorting
 			facep->setDrawInfo(info);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 442c3ef1246ee69969d9397d8455f1ef7326a586..16596f2574a9e8cb408dab1644091926a7a29c65 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3320,11 +3320,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
 		{
 			drawablep->setVisible(camera, NULL, FALSE);
 		}
-		else if (drawablep->isState(LLDrawable::CLEAR_INVISIBLE))
-		{
-			// clear invisible flag here to avoid single frame glitch
-			drawablep->clearState(LLDrawable::FORCE_INVISIBLE|LLDrawable::CLEAR_INVISIBLE);
-		}
 	}
 
 	if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)