diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
index 587b2f2a896f896a494006b6ffbbbffe7728c7bf..45236284f45e9c96a9a9303b5a7966d601004c12 100644
--- a/indra/newview/app_settings/high_graphics.xml
+++ b/indra/newview/app_settings/high_graphics.xml
@@ -4,6 +4,8 @@
 	<RenderAvatarCloth value="FALSE"/>
 	<!--Default for now-->
 	<RenderAvatarLODFactor value="1.0"/>
+  <!--Default for now-->
+  <RenderAvatarPhysicsLODFactor value=".9"/>
 	<!--NO SHADERS-->
 	<RenderAvatarVP value="TRUE"/>
 	<!--Short Range-->
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
index a5bbdfc1d0b9611351a9c86701b01aad0638ccf7..ad0073dfac548cd8ac8b4e16f8381a7aa533585b 100644
--- a/indra/newview/app_settings/low_graphics.xml
+++ b/indra/newview/app_settings/low_graphics.xml
@@ -5,6 +5,8 @@
 	<!--Default for now-->
 	<RenderAvatarLODFactor value="0.5"/>
   <!--Default for now-->
+  <RenderAvatarPhysicsLODFactor value="0.0"/>
+  <!--Default for now-->
   <RenderAvatarMaxVisible value="3"/>
 	<!--NO SHADERS-->
 	<RenderAvatarVP value="FALSE"/>
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
index a1430a58f985d22bc551880f25f5d0c6d2ed006d..d9d8682055e9349aa5e87741ebf53f0fbc2282fe 100644
--- a/indra/newview/app_settings/mid_graphics.xml
+++ b/indra/newview/app_settings/mid_graphics.xml
@@ -4,6 +4,8 @@
 	<RenderAvatarCloth value="FALSE"/>
 	<!--Default for now-->
 	<RenderAvatarLODFactor value="0.5"/>
+  <!--Default for now-->
+  <RenderAvatarPhysicsLODFactor value=".75"/>
 	<!--NO SHADERS-->
 	<RenderAvatarVP value="TRUE"/>
 	<!--Short Range-->
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8310c50b1e9a5331b100d533ae0d11f15ec09e22..d190ac7136db1dcf4037f9433fdb6c28bc4e5587 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -607,7 +607,17 @@
       <key>Value</key>
       <integer>10</integer>
     </map>
-
+    <key>AvatarPhysics</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable avatar physics, such as breast physics.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>AvatarSex</key>
     <map>
       <key>Comment</key>
@@ -620,16 +630,16 @@
       <integer>0</integer>
     </map>
 
-    <key>AvatarPhysics</key>
+    <key>RenderAvatarPhysicsLODFactor</key>
     <map>
       <key>Comment</key>
-      <string>Enable avatar physics, such as breast physics.</string>
+      <string>Controls level of detail of avatar physics (such as breast physics).</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
-      <string>Boolean</string>
+      <string>F32</string>
       <key>Value</key>
-      <integer>1</integer>
+      <integer>1.0</integer>
     </map>
 
     <key>BackgroundYieldTime</key>
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
index f741089ca2b6098ad6068a1b621182a3a4b46d63..3d588cf57d0d01cfd94994614bb6949a771831ca 100644
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ b/indra/newview/app_settings/ultra_graphics.xml
@@ -4,6 +4,8 @@
 	<RenderAvatarCloth value="TRUE"/>
 	<!--Default for now-->
 	<RenderAvatarLODFactor value="1.0"/>
+  <!--Default for now-->
+  <RenderAvatarPhysicsLODFactor value="1.0"/>
 	<!--NO SHADERS-->
 	<RenderAvatarVP value="TRUE"/>
 	<!--Short Range-->
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index bfe3e52657019fbb34f4f832005bf51a5706d821..15e91b57facabecbdb3722c419d77f001f9b587b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -443,6 +443,7 @@ static void settings_to_globals()
 	LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
 	LLVOTree::sTreeFactor				= gSavedSettings.getF32("RenderTreeLODFactor");
 	LLVOAvatar::sLODFactor				= gSavedSettings.getF32("RenderAvatarLODFactor");
+	LLVOAvatar::sPhysicsLODFactor		= gSavedSettings.getF32("RenderAvatarPhysicsLODFactor");
 	LLVOAvatar::sMaxVisible				= (U32)gSavedSettings.getS32("RenderAvatarMaxVisible");
 	LLVOAvatar::sVisibleInFirstPerson	= gSavedSettings.getBOOL("FirstPersonAvatarVisible");
 	// clamp auto-open time to some minimum usable value
diff --git a/indra/newview/llbreastmotion.cpp b/indra/newview/llbreastmotion.cpp
index 036aa2ff3964c523870d1f959189b5f3e6c39437..2c8a38710aef4397683a5b78e5f5b76c591b0a6a 100644
--- a/indra/newview/llbreastmotion.cpp
+++ b/indra/newview/llbreastmotion.cpp
@@ -76,6 +76,7 @@ LLBreastMotion::LLBreastMotion(const LLUUID &id) :
 	mCharLastVelocity_local_vec = LLVector3(0,0,0);
 	mCharLastAcceleration_local_vec = LLVector3(0,0,0);
 	mBreastLastPosition_local_pt = LLVector3(0,0,0);
+	mBreastLastUpdatePosition_local_pt = LLVector3(0,0,0);
 	mBreastVelocity_local_vec = LLVector3(0,0,0);
 }
 
@@ -236,6 +237,12 @@ BOOL LLBreastMotion::onUpdate(F32 time, U8* joint_mask)
 		return TRUE;
 	}
 
+	const F32 lod_factor = LLVOAvatar::sPhysicsLODFactor;
+	if (lod_factor == 0)
+	{
+		return TRUE;
+	}
+
 	/* TEST:
 	   1. Change outfits
 	   2. FPS effect
@@ -354,8 +361,20 @@ BOOL LLBreastMotion::onUpdate(F32 time, U8* joint_mask)
 				mBreastMassParam
 			);
 	}
-		
+	
+	LLVector3 position_diff = mBreastLastUpdatePosition_local_pt-new_local_pt;
+	for (U32 i=0; i < 3; i++)
+	{
+		const F32 min_delta = (1.0-lod_factor)*(mBreastParamsMax[i]-mBreastParamsMin[i])/2.0;
+		if (llabs(position_diff[i]) > min_delta)
+		{
+			mCharacter->updateVisualParams();
+			mBreastLastUpdatePosition_local_pt = new_local_pt;
+			break;
+		}
+	}
+
 	mBreastLastPosition_local_pt = new_local_pt;
-	mCharacter->updateVisualParams();
+
 	return TRUE;
 }
diff --git a/indra/newview/llbreastmotion.h b/indra/newview/llbreastmotion.h
index 7dbe604a7664b2c953762e591e049a2986caec9b..6a2e3788ada8e6428ce1164b8db7ff9d873afe92 100644
--- a/indra/newview/llbreastmotion.h
+++ b/indra/newview/llbreastmotion.h
@@ -138,6 +138,7 @@ class LLBreastMotion :
 
 	LLVector3           mBreastLastPosition_local_pt; // Last parameters for breast
 	LLVector3           mBreastVelocity_local_vec; // How fast the breast params are moving
+	LLVector3           mBreastLastUpdatePosition_local_pt; // Last parameters when visual update was sent
 
 
 	F32 mBreastMassParam;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3804a1b85840db0d9959b06eb1f4786ca830e5d3..dbc50ddbea2e7fea2583bfa1ccc8da4046ac9886 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1064,6 +1064,7 @@ void LLFloaterPreference::refresh()
 	updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail",	true), getChild<LLTextBox>("FlexibleMeshDetailText",	true));
 	updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail",		true), getChild<LLTextBox>("TreeMeshDetailText",		true));
 	updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail",		true), getChild<LLTextBox>("AvatarMeshDetailText",		true));
+	updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail",	true), getChild<LLTextBox>("AvatarPhysicsDetailText",		true));
 	updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail",	true), getChild<LLTextBox>("TerrainMeshDetailText",		true));
 	updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess",	true), getChild<LLTextBox>("PostProcessText",			true));
 	updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail",		true), getChild<LLTextBox>("SkyMeshDetailText",			true));
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 522b5a7dfa5838424bb6139dcf1dff278c5c773e..df5a37663120ff559444421760ee27ebc3423a6a 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -144,6 +144,12 @@ static bool handleAvatarLODChanged(const LLSD& newvalue)
 	return true;
 }
 
+static bool handleAvatarPhysicsLODChanged(const LLSD& newvalue)
+{
+	LLVOAvatar::sPhysicsLODFactor = (F32) newvalue.asReal();
+	return true;
+}
+
 static bool handleAvatarMaxVisibleChanged(const LLSD& newvalue)
 {
 	LLVOAvatar::sMaxVisible = (U32) newvalue.asInteger();
@@ -509,6 +515,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("RenderAvatarMaxVisible")->getSignal()->connect(boost::bind(&handleAvatarMaxVisibleChanged, _2));
 	gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
 	gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
+	gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));
 	gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2));
 	gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2));
 	gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2));
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b98c64310d3f5897f16268dccd0a1b353e14c552..be55c5b5c242fd8b37d9cf3a9a4f3955e5a90d2b 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -619,6 +619,7 @@ BOOL LLVOAvatar::sShowAnimationDebug = FALSE;
 BOOL LLVOAvatar::sShowFootPlane = FALSE;
 BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
 F32 LLVOAvatar::sLODFactor = 1.f;
+F32 LLVOAvatar::sPhysicsLODFactor = 1.f;
 BOOL LLVOAvatar::sUseImpostors = FALSE;
 BOOL LLVOAvatar::sJointDebug = FALSE;
 
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index c522af7d5532bbb76924c75d7eba8caafbc37ee0..4417e37abbaf3469ddd85d7d51585be42e361a4a 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -230,6 +230,7 @@ class LLVOAvatar :
 	static BOOL		sDebugInvisible;
 	static BOOL		sShowAttachmentPoints;
 	static F32		sLODFactor; // user-settable LOD factor
+	static F32		sPhysicsLODFactor; // user-settable physics LOD factor
 	static BOOL		sJointDebug; // output total number of joints being touched for each avatar
 	static BOOL		sDebugAvatarRotation;
 
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 113d5fb6dc37dc89f365320d441218d29063417f..23024cd0eba1f6090f847bead07823ed2e431829 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -2,7 +2,7 @@
 <panel
  border="true"
  follows="left|top|right|bottom"
- height="408"
+ height="418"
  label="Graphics"
  layout="topleft"
  left="102"
@@ -482,6 +482,24 @@
             parameter="AvatarMeshDetailText" />
         </slider>
         <slider
+        control_name="RenderAvatarPhysicsLODFactor"
+        follows="left|top"
+        height="16"
+        increment="0.125"
+        initial_value="160"
+        label="  Avatar Physics:"
+        label_width="185"
+        layout="topleft"
+        left_delta="0"
+        name="AvatarPhysicsDetail"
+        show_text="false"
+        top_pad="4"
+        width="264">
+           <slider.commit_callback
+            function="Pref.UpdateSliderText"
+            parameter="AvatarPhysicsDetailText" />
+        </slider>
+        <slider
         control_name="RenderTerrainLODFactor"
         follows="left|top"
         height="16"
@@ -590,6 +608,18 @@
         height="12"
         layout="topleft"
         left_delta="0"
+        name="AvatarPhysicsDetailText"
+        top_pad="8"
+        width="128">
+           Low
+        </text>
+        <text
+        type="string"
+        length="1"
+        follows="left|top"
+        height="12"
+        layout="topleft"
+        left_delta="0"
         name="TerrainMeshDetailText"
         top_pad="8"
         width="128">
@@ -662,7 +692,7 @@
         left="358"
         left_pad="-30"
         name="TerrainDetailText"
-        top="226"
+        top="250"
         width="155">
            Terrain detail:
         </text>
@@ -700,7 +730,7 @@
      layout="topleft"
      left="10"
      name="Apply"
-     top="383"
+     top="390"
      width="115"
       >
         <button.commit_callback
@@ -713,7 +743,7 @@
      layout="topleft"
      left_pad="3"
      name="Defaults"
-     top="383"
+     top="390"
      width="115">
         <button.commit_callback
          function="Pref.HardwareDefaults" />