diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index bd24a46e8d175d38bd7b98ce9c48b4fe51691f7f..6f0b4b241062ce7aacca98cf55b752ffcb161769 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -4575,6 +4575,7 @@ LLVolumeFace::LLVolumeFace() :
 	mTexCoords(NULL),
 	mIndices(NULL),
 	mWeights(NULL),
+    mWeightsScrubbed(FALSE),
 	mOctree(NULL),
 	mOptimized(FALSE)
 {
@@ -4600,6 +4601,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
 	mTexCoords(NULL),
 	mIndices(NULL),
 	mWeights(NULL),
+    mWeightsScrubbed(FALSE),
 	mOctree(NULL)
 { 
 	mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
@@ -4671,6 +4673,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
 			ll_aligned_free_16(mWeights);
 			mWeights = NULL;
 		}
+        mWeightsScrubbed = src.mWeightsScrubbed;
 	}
 
 	if (mNumIndices)
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 1da2d0c6b15f9ea47bed4f9c8b64b693625ddb3d..d66004cdadbc7ef370966497a0351fab69d0a28d 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -953,6 +953,8 @@ class LLVolumeFace
 	// mWeights.size() should be empty or match mVertices.size()  
 	LLVector4a* mWeights;
 
+    mutable BOOL mWeightsScrubbed;
+    
 	LLOctreeNode<LLVolumeTriangle>* mOctree;
 
 	//whether or not face has been cache optimized
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 10311044d2d9ef3d62f35528cbc02136a370a979..499cf76bffe384fa463faecfd4344f3122609fa4 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1544,8 +1544,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
     LLVolume* volume,
     const LLVolumeFace& vol_face)
 {
-	LLVector4a* weight = vol_face.mWeights;
-	if (!weight)
+	LLVector4a* weights = vol_face.mWeights;
+	if (!weights)
 	{
 		return;
 	}
@@ -1556,6 +1556,12 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
 	LLDrawable* drawable = face->getDrawable();
 
 	U32 data_mask = face->getRiggedVertexBufferDataMask();
+
+    if (!vol_face.mWeightsScrubbed)
+    {
+        LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin);
+        vol_face.mWeightsScrubbed = TRUE;
+    }
 	
 	if (buffer.isNull() || 
 		buffer->getTypeMask() != data_mask ||
@@ -1610,7 +1616,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
 		LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
         U32 count = LLSkinningUtil::getMeshJointCount(skin);
         LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
-        LLSkinningUtil::checkSkinWeights(weight, buffer->getNumVerts(), skin);
+        LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin);
 
 		LLMatrix4a bind_shape_matrix;
 		bind_shape_matrix.loadu(skin->mBindShapeMatrix);
@@ -1619,7 +1625,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
 		for (U32 j = 0; j < buffer->getNumVerts(); ++j)
 		{
 			LLMatrix4a final_mat;
-            LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints);
+            LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints);
 			
 			LLVector4a& v = vol_face.mPositions[j];
 
diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp
index b2fd1744bc78ddda8849dabb651705d9106165b8..cf09f6f9785a0c086b9aaf3c56cda128011e54da 100644
--- a/indra/newview/llskinningutil.cpp
+++ b/indra/newview/llskinningutil.cpp
@@ -64,6 +64,7 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin
         // needed for handling of any legacy bad data.
         if (!avatar->getJoint(skin->mJointNames[j]))
         {
+            LL_DEBUGS("Avatar") << "Mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL;
             skin->mJointNames[j] = "mPelvis";
         }
     }
@@ -140,6 +141,24 @@ void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, con
 #endif
 }
 
+void LLSkinningUtil::scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin)
+{
+    const S32 max_joints = skin->mJointNames.size();
+    for (U32 j=0; j<num_vertices; j++)
+    {
+        F32 *w = weights[j].getF32ptr();
+
+        for (U32 k=0; k<4; ++k)
+        {
+            S32 i = llfloor(w[k]);
+            F32 f = w[k]-i;
+            i = llclamp(i,0,max_joints-1);
+            w[k] = i + f;
+        }
+    }
+	checkSkinWeights(weights, num_vertices, skin);
+}
+
 // static
 void LLSkinningUtil::getPerVertexSkinMatrix(
     F32* weights,
diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h
index 6a6091114c2c8ed0543a59b36c2344f3ab86d2d3..135b25d4d21c5d280e6764c758d5b8f6cc5d28df 100644
--- a/indra/newview/llskinningutil.h
+++ b/indra/newview/llskinningutil.h
@@ -40,6 +40,7 @@ class LLSkinningUtil
     static void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin);
     static void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar);
     static void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
+    static void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
     static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);
 };