diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 41ee3941ac77a6e4ab75de7e1ca3f600289dbdc7..79c134da3046cb757f2c401c107e56a56ffa8e31 100755
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2536,6 +2536,8 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 
 					U32 cur_influence = 0;
 					LLVector4 wght(0,0,0,0);
+                    U32 joints[4] = {0,0,0,0};
+					LLVector4 joints_with_weights(0,0,0,0);
 
 					while (joint != END_INFLUENCES && idx < weights.size())
 					{
@@ -2543,7 +2545,9 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 						influence |= ((U16) weights[idx++] << 8);
 
 						F32 w = llclamp((F32) influence / 65535.f, 0.f, 0.99999f);
-						wght.mV[cur_influence++] = (F32) joint + w;
+						wght.mV[cur_influence] = w;
+						joints[cur_influence] = joint;
+						cur_influence++;
 
 						if (cur_influence >= 4)
 						{
@@ -2554,8 +2558,16 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 							joint = weights[idx++];
 						}
 					}
-
-					face.mWeights[cur_vertex].loadua(wght.mV);
+                    F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW];
+                    if (wsum <= 0.f)
+                    {
+                        wght = LLVector4(0.99999f,0.f,0.f,0.f);
+                    }
+                    for (U32 k=0; k<4; k++)
+                    {
+                        joints_with_weights[k] = (F32) joints[k] + wght[k];
+                    }
+					face.mWeights[cur_vertex].loadua(joints_with_weights.mV);
 
 					cur_vertex++;
 				}
diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
index 6cd38d8ef50661c632fbfe7249052ce8237ad097..3060307b2113920734afcb18b7afca250ec86cde 100755
--- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
@@ -37,8 +37,7 @@ mat4 getObjectSkinnedTransform()
 		 index = min(index, vec4(51.0));
 		 index = max(index, vec4( 0.0));
 
-	float scale = 1.0/(w.x+w.y+w.z+w.w);
-	w *= scale;
+    w *= 1.0/(w.x+w.y+w.z+w.w);
 	
 	int i1 = int(index.x);
 	int i2 = int(index.y);
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index f828b56f7f587099f82a574740acc58cf82c2485..8bbc5292447ce96ebff8ea4abbce6382aba5afc8 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1553,7 +1553,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 		(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
 	{
 		if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
-		{ //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
+		{
+            //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
 			for (S32 i = 0; i < drawable->getNumFaces(); ++i)
 			{
 				LLFace* facep = drawable->getFace(i);
@@ -1570,13 +1571,15 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 			buffer = face->getVertexBuffer();
 		}
 		else
-		{ //just rebuild this face
+		{
+			//just rebuild this face
 			getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face);
 		}
 	}
 
 	if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
-	{ //perform software vertex skinning for this face
+	{
+		//perform software vertex skinning for this face
 		LLStrider<LLVector3> position;
 		LLStrider<LLVector3> normal;
 
@@ -1604,10 +1607,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 			{
 				joint = avatar->getJoint("mPelvis");
 			}
-			if (!joint)
-			{
-				LL_DEBUGS("Avatar") << "Failed to find " << skin->mJointNames[j] << LL_ENDL;
-			}
 			if (joint)
 			{
 				mat[j] = skin->mInvBindMatrix[j];
@@ -1632,12 +1631,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 			{
 				F32 w = weight[j][k];
 
-				idx[k] = llclamp((S32) floorf(w), 0, JOINT_COUNT-1);
+				idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)JOINT_COUNT-1);
 
 				wght[k] = w - floorf(w);
 				scale += wght[k];
 			}
-
+            // This is enforced  in unpackVolumeFaces()
+            llassert(scale>0.f);
 			wght *= 1.f/scale;
 
 			for (U32 k = 0; k < 4; k++)
@@ -1737,6 +1737,10 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 				for (U32 i = 0; i < count; ++i)
 				{
 					LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
+                    if (!joint)
+                    {
+                        joint = avatar->getJoint("mPelvis");
+                    }
 					if (joint)
 					{
 						mat[i] = skin->mInvBindMatrix[i];
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index fb34d6f588960474da59ff5dfc7638795836df27..19d61f6e33ab455a48b5cda2b8378871840f1474 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4175,7 +4175,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
 	}
 
 	//build matrix palette
-	static const size_t kMaxJoints = 64;
+	static const size_t kMaxJoints = 52;
 
 	LLMatrix4a mp[kMaxJoints];
 	LLMatrix4* mat = (LLMatrix4*) mp;
@@ -4195,12 +4195,6 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
 			mat[j] = skin->mInvBindMatrix[j];
 			mat[j] *= joint->getWorldMatrix();
 		}
-		else
-		{
-            // This shouldn't be possible unless the avatar skeleton
-            // is corrupt.
-			llassert(false);
-		}
 	}
 
 	for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
@@ -4240,21 +4234,9 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
 						wght[k] = w - floorf(w);
 						scale += wght[k];
 					}
-					if (scale > 0.f)
-					{
-						wght *= 1.f / scale;
-					}
-                    else
-                    {
-                        // Complete weighting fail - all zeroes.  Just
-                        // pick some values that add up to 1.0 so we
-                        // don't wind up with garbage vertices
-                        // pointing off at (0,0,0)
-                        wght[0] = 1.f;
-                        wght[1] = 0.f;
-                        wght[2] = 0.f;
-                        wght[3] = 0.f;
-                    }
+                    // This is enforced  in unpackVolumeFaces()
+                    llassert(scale>0.f);
+                    wght *= 1.f / scale;
 
 					for (U32 k = 0; k < 4; k++)
 					{
@@ -4263,7 +4245,8 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
 						LLMatrix4a src;
 						// Insure ref'd bone is in our clamped array of mats
 						// clamp idx to maxJoints to avoid reading garbage off stack in release
-						src.setMul(mp[(idx[k]<maxJoints)?idx[k]:0], w);
+                        S32 index = llclamp((S32)idx[k],(S32)0,(S32)kMaxJoints-1);
+						src.setMul(mp[index], w);
 						final_mat.add(src);
 					}