diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
index 80e81936fb285c359e162c1a10b0a9b9b19f99e7..2cb4c65d7c49a197f1e871397c010a6038c6265f 100644
--- a/indra/llappearance/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -369,7 +369,8 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
 		{
 			if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName)
 			{
-				mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i],
+				mVolumeMorphs.push_back(
+					LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i],
 														  volume_info->mScale,
 														  volume_info->mPos));
 				break;
@@ -731,6 +732,20 @@ void	LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3
 	apply(mLastSex);
 }
 
+void LLPolyMorphTarget::applyVolumeChanges(F32 delta_weight)
+{
+    // now apply volume changes
+    for( volume_list_t::iterator iter = mVolumeMorphs.begin(); iter != mVolumeMorphs.end(); iter++ )
+    {
+        LLPolyVolumeMorph* volume_morph = &(*iter);
+        LLVector3 scale_delta = volume_morph->mScale * delta_weight;
+        LLVector3 pos_delta = volume_morph->mPos * delta_weight;
+		
+        volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta);
+        // SL-315
+        volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta);
+    }
+}
 
 //-----------------------------------------------------------------------------
 // LLPolyVertexMask()
diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h
index 3c2c68079c39d29169dbc3083b96ab77aaa3da93..c6133cd83119605a7f2085db8ea9e1f37966658b 100644
--- a/indra/llappearance/llpolymorph.h
+++ b/indra/llappearance/llpolymorph.h
@@ -182,6 +182,8 @@ class LLPolyMorphTarget : public LLViewerVisualParam
 	void	applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert);
 	void	addPendingMorphMask() { mNumMorphMasksPending++; }
 
+    void    applyVolumeChanges(F32 delta_weight); // SL-315 - for resetSkeleton()
+
 	void* operator new(size_t size)
 	{
 		return ll_aligned_malloc_16(size);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index e82f24a0693c8ed38302736ff1330c7639664489..9286a708861cd3c361166fadbadfc7585324e53d 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1859,7 +1859,7 @@ void LLVOAvatar::resetVisualParams()
 //-----------------------------------------------------------------------------
 void LLVOAvatar::resetSkeleton()
 {
-    LL_DEBUGS("Avatar") << avString() << LL_ENDL;
+    LL_DEBUGS("Avatar") << avString() << " reset starts" << LL_ENDL;
     if (!mLastProcessedAppearance)
     {
         LL_WARNS() << "Can't reset avatar; no appearance message has been received yet." << LL_ENDL;
@@ -1883,15 +1883,34 @@ void LLVOAvatar::resetSkeleton()
     bool ignore_hud_joints = true;
     initAttachmentPoints(ignore_hud_joints);
 
+    // Fix up collision volumes
+    for (LLVisualParam *param = getFirstVisualParam(); 
+         param;
+         param = getNextVisualParam())
+    {
+        LLPolyMorphTarget *poly_morph = dynamic_cast<LLPolyMorphTarget*>(param);
+        if (poly_morph)
+        {
+            // This is a kludgy way to correct for the fact that the
+            // collision volumes have been reset out from under the
+            // poly morph sliders.
+            F32 delta_weight = poly_morph->getLastWeight() - poly_morph->getDefaultWeight();
+            poly_morph->applyVolumeChanges(delta_weight);
+        }
+    }
+
     // Reset tweakable params to preserved state
     // Apply params
     applyParsedAppearanceMessage(*mLastProcessedAppearance);
+
     updateVisualParams();
 
     // Restore attachment pos overrides
     rebuildAttachmentPosOverrides();
 
     // Restart animations
+
+    LL_DEBUGS("Avatar") << avString() << " reset ends" << LL_ENDL;
 }
 
 //-----------------------------------------------------------------------------