diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 133313b87603b57bcf5423048d8b51697e3512a3..1941744b79aca4d49c41c01811fe08406ec7bd58 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -1473,6 +1473,12 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
 			}
 		}
 
+		model->mSkinInfo.mInvBindShapeMatrix.resize(llmin(model->mSkinInfo.mInvBindMatrix.size(), (size_t)216));
+		for (U32 i = 0; i < model->mSkinInfo.mInvBindShapeMatrix.size(); ++i)
+		{
+			matMulUnsafe(model->mSkinInfo.mInvBindMatrix[i], model->mSkinInfo.mBindShapeMatrix, model->mSkinInfo.mInvBindShapeMatrix[i]);
+		}
+
 		//Now that we've parsed the joint array, let's determine if we have a full rig
 		//(which means we have all the joint sthat are required for an avatar versus
 		//a skinned asset attached to a node in a file that contains an entire skeleton,
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index e4e107cd7ed5d0f759d110a704bf761fc864cf9c..7a3696c48c0ece58d0c63574b49fbb73a8f0e21c 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1445,6 +1445,12 @@ void LLMeshSkinInfo::fromLLSD(const LLSD& skin)
 		mBindShapeMatrix.loadu(mat);
 	}
 
+	mInvBindShapeMatrix.resize(llmin(mInvBindMatrix.size(), (size_t)216));
+	for (U32 i = 0; i < mInvBindShapeMatrix.size(); ++i)
+	{
+		matMulUnsafe(mInvBindMatrix[i], mBindShapeMatrix, mInvBindShapeMatrix[i]);
+	}
+
 	if (skin.has("alt_inverse_bind_matrix"))
 	{
 		const auto& alt_inv_bind_mat = skin["alt_inverse_bind_matrix"];
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index aa17d453970ee188950ea6e4efae15ed830e37f9..9b71618b7f75f4b2dd2126ff41590a51aa4cf56f 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -62,6 +62,7 @@ class LLMeshSkinInfo : public LLRefCount
 
     // bones/joints position overrides
 	matrix_list_t mAlternateBindMatrix;
+	matrix_list_t mInvBindShapeMatrix;
 
 	LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
 
diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp
index 130f344bbf9388c39dfa0905978ced0b6ab268f1..e87073386b699438bc79194487313a0c3b1ef952 100644
--- a/indra/newview/llskinningutil.cpp
+++ b/indra/newview/llskinningutil.cpp
@@ -292,12 +292,6 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
                 //S32 active_verts = 0;
                 vol_face.mJointRiggingInfoTab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS);
                 LLJointRiggingInfoTab &rig_info_tab = vol_face.mJointRiggingInfoTab;
-                const LLMatrix4a& bind_shape = skin->mBindShapeMatrix;
-                LLMatrix4a matrixPalette[LL_CHARACTER_MAX_ANIMATED_JOINTS];
-                for (U32 i = 0; i < llmin(skin->mInvBindMatrix.size(), (size_t)LL_CHARACTER_MAX_ANIMATED_JOINTS); ++i)
-                {
-                    matrixPalette[i].setMul(skin->mInvBindMatrix[i], bind_shape);
-                }
                 for (S32 i=0; i<vol_face.mNumVertices; i++)
                 {
                     LLVector4a& pos = vol_face.mPositions[i];
@@ -329,8 +323,9 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
                             if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS)
                             {
                                 rig_info_tab[joint_num].setIsRiggedTo(true);
+
                                 LLVector4a pos_joint_space;
-                                matrixPalette[joint_index].affineTransform(pos, pos_joint_space);
+                                skin->mInvBindShapeMatrix[joint_index].affineTransform(pos, pos_joint_space);
                                 pos_joint_space.mul(wght[k]);
 
                                 LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents();