diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp
index fd08df02d800880f47c9e5aaafbe03689d6bf903..18b15e08c4c89b3f62ce36d3cb4c9621f0110d72 100644
--- a/indra/llmath/v3math.cpp
+++ b/indra/llmath/v3math.cpp
@@ -134,6 +134,21 @@ BOOL LLVector3::clampLength( F32 length_limit )
 	return changed;
 }
 
+BOOL LLVector3::clamp(const LLVector3 &min_vec, const LLVector3 &max_vec)
+{
+	BOOL ret = FALSE;
+
+	if (mV[0] < min_vec[0]) { mV[0] = min_vec[0]; ret = TRUE; }
+	if (mV[1] < min_vec[1]) { mV[1] = min_vec[1]; ret = TRUE; }
+	if (mV[2] < min_vec[2]) { mV[2] = min_vec[2]; ret = TRUE; }
+
+	if (mV[0] > max_vec[0]) { mV[0] = max_vec[0]; ret = TRUE; }
+	if (mV[1] > max_vec[1]) { mV[1] = max_vec[1]; ret = TRUE; }
+	if (mV[2] > max_vec[2]) { mV[2] = max_vec[2]; ret = TRUE; }
+
+	return ret;
+}
+
 
 // Sets all values to absolute value of their original values
 // Returns TRUE if data changed
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index dbd38c1c3f03d202845029bfd0e70533c4bc6446..d3fc6fcb2f55507a6aded703cafa34e877acdf28 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -69,6 +69,7 @@ class LLVector3
 
 		inline BOOL isFinite() const;									// checks to see if all values of LLVector3 are finite
 		BOOL		clamp(F32 min, F32 max);		// Clamps all values to (min,max), returns TRUE if data changed
+		BOOL		clamp(const LLVector3 &min_vec, const LLVector3 &max_vec); // Scales vector by another vector
 		BOOL		clampLength( F32 length_limit );					// Scales vector to limit length to a value
 
 		void		quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);	// changes the vector to reflect quatization
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index a9b4ff02c5a872280149aed393dee873a4db3c11..cdb368403436035104150daeebdf014c366c0063 100644
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -612,7 +612,7 @@
      id="36"
      group="0"
      name="Shoulders"
-   label="Shoulders"
+     label="Shoulders"
      wearable="shape"
      edit_group="shape_torso"
      edit_group_order="4"
@@ -4047,11 +4047,10 @@
      id="507"
      group="0"
      sex="female"
-     name="Breast_Gravity"
+     name="Breast_Gravity_Driven"
      label="Breast Buoyancy"
      wearable="shape"
-     edit_group="shape_torso"
-     edit_group_order="7"
+     edit_group="driven"
      label_min="Less Gravity"
      label_max="More Gravity"
      value_default="0"
@@ -4116,11 +4115,10 @@
      id="684"
      group="0"
      sex="female"
-     name="Breast_Female_Cleavage"
+     name="Breast_Female_Cleavage_Driven"
      label="Breast Cleavage"
      wearable="shape"
-     edit_group="shape_torso"
-     edit_group_order="8"
+     edit_group="driven"
      label_min="Separate"
      label_max="Join"
      value_default="0"
@@ -9074,12 +9072,290 @@ render_pass="bump">
 
   <!-- =========================================================== -->
   <driver_parameters>
+
+    <param
+     id="1074"
+     group="0"
+     sex="female"
+     name="Breast_Physics_Mass"
+     label="Breast Physics Mass"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default="1"
+     value_min="1"
+     value_max="5"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+    <param
+     id="1075"
+     group="0"
+     sex="female"
+     name="Breast_Physics_Smoothing"
+     label="Breast Physics Smoothing"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default="2"
+     value_min="1"
+     value_max="10"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+    <param
+     id="1076"
+     group="0"
+     sex="female"
+     name="Breast_Physics_Gravity"
+     label="Breast Physics Gravity"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default="2"
+     value_min="0"
+     value_max="10"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+    <param
+     id="1077"
+     group="0"
+     sex="female"
+     name="Breast_Physics_Side_Spring"
+     label="Breast Physics Side Spring"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default="3"
+     value_min="0"
+     value_max="5"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+    <param
+     id="1078"
+     group="0"
+     sex="female"
+     name="Breast_Physics_Side_Bounce"
+     label="Breast Physics Side Bounce"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default="10"
+     value_min="0"
+     value_max="100"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+    <param
+     id="1079"
+     group="0"
+     sex="female"
+     name="Breast_Physics_Side_Damping"
+     label="Breast Physics Side Damping"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default=".5"
+     value_min="0"
+     value_max="1"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+   <param
+     id="1080"
+     group="0"
+     sex="female"
+     name="Breast_Physics_Side_Drag"
+     label="Breast Physics Side Drag"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default=".1"
+     value_min="0"
+     value_max="1"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+   <param
+     id="1081"
+     group="0"
+     sex="female"
+     name="Breast_Physics_Side_Range"
+     label="Breast Physics Side Range"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default="10"
+     value_min="0"
+     value_max="100"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+
+    <param
+     id="1082"
+     group="0"
+     sex="female"
+     name="Breast_Physics_UpDown_Spring"
+     label="Breast Physics UpDown Spring"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default="1.5"
+     value_min="0"
+     value_max="5"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+    <param
+     id="1083"
+     group="0"
+     sex="female"
+     name="Breast_Physics_UpDown_Bounce"
+     label="Breast Physics UpDown Bounce"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default="50"
+     value_min="0"
+     value_max="100"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+    <param
+     id="1084"
+     group="0"
+     sex="female"
+     name="Breast_Physics_UpDown_Damping"
+     label="Breast Physics UpDown Damping"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default=".1"
+     value_min="0"
+     value_max="1"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+   <param
+     id="1085"
+     group="0"
+     sex="female"
+     name="Breast_Physics_UpDown_Drag"
+     label="Breast Physics UpDown Drag"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default=".1"
+     value_min="0"
+     value_max="1"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+   <param
+     id="1086"
+     group="0"
+     sex="female"
+     name="Breast_Physics_UpDown_Range"
+     label="Breast Physics UpDown Range"
+     wearable="shape"
+     edit_group="shape_physics"
+     label_min="Less"
+     label_max="More"
+     value_default="10"
+     value_min="0"
+     value_max="100"
+     camera_elevation=".3"
+     camera_distance=".8">
+	 <param_driver />
+    </param>
+
+   <param
+     id="1087"
+     group="0"
+     sex="female"
+     name="Breast_Female_Cleavage"
+     label="Breast Cleavage"
+     wearable="shape"
+     edit_group="shape_torso"
+     label_min="Less"
+     label_max="More"
+     value_default="10"
+     value_min="-.3"
+     value_max="1.3"
+     camera_elevation=".3"
+     camera_distance=".8">
+      <param_driver>
+        <driven
+         id="684" />
+	</param_driver>
+    </param>
+
+   <param
+     id="1088"
+     group="0"
+     sex="female"
+     name="Breast_Gravity"
+     label="Breast Buoyancy"
+     wearable="shape"
+     edit_group="shape_torso"
+     label_min="Less"
+     label_max="More"
+     value_default="10"
+     value_min="-1.5"
+     value_max="2"
+     camera_elevation=".3"
+     camera_distance=".8">
+      <param_driver>
+        <driven
+         id="507" />
+	</param_driver>
+    </param>
+
     <param
      id="828"
      group="0"
      name="Loose Upper Clothing"
      label="Shirt Fit"
-   show_simple="true"
+	 show_simple="true"
      wearable="shirt"
      edit_group="shirt"
      edit_group_order="4"
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 68e408d3e4aa9264e31cc8f6f465cba1e4e8c8cc..01a4cce70070ceef87bf3817fee240c80cd49352 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -277,6 +277,7 @@ LLAgentCamera::~LLAgentCamera()
 //-----------------------------------------------------------------------------
 void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
 {
+	if (TRUE) return; // SERAPH DON'T CHECKIN
 	if (gAgent.getAutoPilot())
 	{
 		gAgent.stopAutoPilot(TRUE);
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 90ed8b9e587a106dca3b0330913081c165d139bf..bfe3aa0e61de35d16ee7916e7ca81700df4d3396 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -72,6 +72,7 @@ enum ESubpart {
 	SUBPART_SHAPE_MOUTH,
 	SUBPART_SHAPE_CHIN,
 	SUBPART_SHAPE_TORSO,
+	SUBPART_SHAPE_PHYSICS,
 	SUBPART_SHAPE_LEGS,
 	SUBPART_SHAPE_WHOLE,
 	SUBPART_SHAPE_DETAIL,
@@ -218,7 +219,7 @@ LLEditWearableDictionary::Wearables::Wearables()
 	// note the subpart that is listed first is treated as "default", regardless of what order is in enum.
 	// Please match the order presented in XUI. -Nyx
 	// this will affect what camera angle is shown when first editing a wearable
-	addEntry(LLWearableType::WT_SHAPE, 		new WearableEntry(LLWearableType::WT_SHAPE,"edit_shape_title","shape_desc_text",0,0,9,	SUBPART_SHAPE_WHOLE, SUBPART_SHAPE_HEAD,	SUBPART_SHAPE_EYES,	SUBPART_SHAPE_EARS,	SUBPART_SHAPE_NOSE,	SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS ));
+	addEntry(LLWearableType::WT_SHAPE, 		new WearableEntry(LLWearableType::WT_SHAPE,"edit_shape_title","shape_desc_text",0,0,10,	SUBPART_SHAPE_WHOLE, SUBPART_SHAPE_HEAD,	SUBPART_SHAPE_EYES,	SUBPART_SHAPE_EARS,	SUBPART_SHAPE_NOSE,	SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS, SUBPART_SHAPE_PHYSICS));
 	addEntry(LLWearableType::WT_SKIN, 		new WearableEntry(LLWearableType::WT_SKIN,"edit_skin_title","skin_desc_text",0,3,4, TEX_HEAD_BODYPAINT, TEX_UPPER_BODYPAINT, TEX_LOWER_BODYPAINT, SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL));
 	addEntry(LLWearableType::WT_HAIR, 		new WearableEntry(LLWearableType::WT_HAIR,"edit_hair_title","hair_desc_text",0,1,4, TEX_HAIR, SUBPART_HAIR_COLOR,	SUBPART_HAIR_STYLE,	SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL));
 	addEntry(LLWearableType::WT_EYES, 		new WearableEntry(LLWearableType::WT_EYES,"edit_eyes_title","eyes_desc_text",0,1,1, TEX_EYES_IRIS, SUBPART_EYES));
@@ -278,6 +279,7 @@ LLEditWearableDictionary::Subparts::Subparts()
 	addEntry(SUBPART_SHAPE_MOUTH, new SubpartEntry(SUBPART_SHAPE_MOUTH, "mHead", "shape_mouth", "shape_mouth_param_list", "shape_mouth_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
 	addEntry(SUBPART_SHAPE_CHIN, new SubpartEntry(SUBPART_SHAPE_CHIN, "mHead", "shape_chin", "shape_chin_param_list", "shape_chin_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
 	addEntry(SUBPART_SHAPE_TORSO, new SubpartEntry(SUBPART_SHAPE_TORSO, "mTorso", "shape_torso", "shape_torso_param_list", "shape_torso_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
+	addEntry(SUBPART_SHAPE_PHYSICS, new SubpartEntry(SUBPART_SHAPE_PHYSICS, "mTorso", "shape_physics", "shape_physics_param_list", "shape_physics_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_FEMALE));
 	addEntry(SUBPART_SHAPE_LEGS, new SubpartEntry(SUBPART_SHAPE_LEGS, "mPelvis", "shape_legs", "shape_legs_param_list", "shape_legs_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
 
 	addEntry(SUBPART_SKIN_COLOR, new SubpartEntry(SUBPART_SKIN_COLOR, "mHead", "skin_color", "skin_color_param_list", "skin_color_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
@@ -847,11 +849,11 @@ void LLPanelEditWearable::setVisible(BOOL visible)
 	LLPanel::setVisible(visible);
 }
 
-void LLPanelEditWearable::setWearable(LLWearable *wearable)
+void LLPanelEditWearable::setWearable(LLWearable *wearable, BOOL disable_camera_switch)
 {
-	showWearable(mWearablePtr, FALSE);
+	showWearable(mWearablePtr, FALSE, disable_camera_switch);
 	mWearablePtr = wearable;
-	showWearable(mWearablePtr, TRUE);
+	showWearable(mWearablePtr, TRUE, disable_camera_switch);
 }
 
 
@@ -1051,7 +1053,7 @@ void LLPanelEditWearable::revertChanges()
 	gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE);
 }
 
-void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show)
+void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch)
 {
 	if (!wearable)
 	{
@@ -1146,7 +1148,10 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show)
 	
 			updateScrollingPanelUI();
 		}
-		showDefaultSubpart();
+		if (!disable_camera_switch)
+		{
+			showDefaultSubpart();
+		}
 
 		updateVerbs();
 	}
@@ -1154,7 +1159,7 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show)
 
 void LLPanelEditWearable::showDefaultSubpart()
 {
-	changeCamera(0);
+	changeCamera(3);
 }
 
 void LLPanelEditWearable::onTabExpandedCollapsed(const LLSD& param, U8 index)
diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h
index 43513d8ab3fb4d61585d04f28bae7c06e9ff3e04..623101d8351cf73c535fd193b78ffb30884ec837 100644
--- a/indra/newview/llpaneleditwearable.h
+++ b/indra/newview/llpaneleditwearable.h
@@ -55,8 +55,11 @@ class LLPanelEditWearable : public LLPanel
 	/*virtual*/ BOOL		isDirty() const;	// LLUICtrl
 	/*virtual*/ void		draw();	
 
+	// changes camera angle to default for selected subpart
+	void				changeCamera(U8 subpart);
+
 	LLWearable* 		getWearable() { return mWearablePtr; }
-	void				setWearable(LLWearable *wearable);
+	void				setWearable(LLWearable *wearable, BOOL disable_camera_switch = FALSE);
 
 	void				saveChanges(bool force_save_as = false);
 	void				revertChanges();
@@ -77,7 +80,7 @@ class LLPanelEditWearable : public LLPanel
 private:
 	typedef std::map<F32, LLViewerVisualParam*> value_map_t;
 
-	void				showWearable(LLWearable* wearable, BOOL show);
+	void				showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch = FALSE);
 	void				updateScrollingPanelUI();
 	LLPanel*			getPanel(LLWearableType::EType type);
 	void				getSortedParams(value_map_t &sorted_params, const std::string &edit_group);
@@ -91,9 +94,6 @@ class LLPanelEditWearable : public LLPanel
 	void				toggleTypeSpecificControls(LLWearableType::EType type);
 	void				updateTypeSpecificControls(LLWearableType::EType type);
 
-	// changes camera angle to default for selected subpart
-	void				changeCamera(U8 subpart);
-
 	//alpha mask checkboxes
 	void configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name);
 	void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te);
diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp
index 363b0b8e9d18185969120fc4d24f7e091a9a70d6..2942f4befb2ed26e70f5021687084c0218c5d446 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/newview/llpolymesh.cpp
@@ -602,6 +602,12 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
 				}
 
 				mMorphData.insert(morph_data);
+				/*
+				if (std::string(morphName) == "Breast_Gravity")
+				{
+					LLPolyMorphData *morph_data_clone = new LLPolyMorphData(std::string(morphName));
+				}
+				*/
 			}
 
 			S32 numRemaps;
diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp
index 0ffe1c635f143a5780be304fbb4c7ffa3c4c055b..ec41ef08f5762e6bc3bc72beb46e51e01d80d430 100644
--- a/indra/newview/llpolymorph.cpp
+++ b/indra/newview/llpolymorph.cpp
@@ -287,10 +287,22 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
 		}
 	}
 
-	mMorphData = mMesh->getMorphData(getInfo()->mMorphName);
+	std::string morph_param_name = getInfo()->mMorphName;
+	
+	mMorphData = mMesh->getMorphData(morph_param_name);
+	if (!mMorphData)
+	{
+		const std::string driven_tag = "_Driven";
+		U32 pos = morph_param_name.find(driven_tag);
+		if (pos > 0)
+		{
+			morph_param_name = morph_param_name.substr(0,pos);
+			mMorphData = mMesh->getMorphData(morph_param_name);
+		}
+	}
 	if (!mMorphData)
 	{
-		llwarns << "No morph target named " << getInfo()->mMorphName << " found in mesh." << llendl;
+		llwarns << "No morph target named " << morph_param_name << " found in mesh." << llendl;
 		return FALSE;  // Continue, ignoring this tag
 	}
 	return TRUE;
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 7206e4fcaf936b81365ce21689552b1c68a381ce..333a463844960b9b7ae500b61c4537072a84bca3 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -176,6 +176,11 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)
 		{
 			showWearableEditPanel();
 		}
+		else if (type == "edit_physics")
+		{
+			showPhysicsEditPanel();
+		}
+
 	}
 
 	mOpened = true;
@@ -281,7 +286,7 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel()
 {
 	toggleWearableEditPanel(FALSE);
 	toggleOutfitEditPanel(FALSE);
-	togglMyOutfitsPanel(TRUE);
+	toggleMyOutfitsPanel(TRUE);
 }
 
 void LLSidepanelAppearance::showOutfitEditPanel()
@@ -295,19 +300,24 @@ void LLSidepanelAppearance::showOutfitEditPanel()
 		mOutfitEdit->resetAccordionState();
 	}
 
-	togglMyOutfitsPanel(FALSE);
+	toggleMyOutfitsPanel(FALSE);
 	toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode
 	toggleOutfitEditPanel(TRUE);
 }
 
-void LLSidepanelAppearance::showWearableEditPanel(LLWearable *wearable /* = NULL*/)
+void LLSidepanelAppearance::showWearableEditPanel(LLWearable *wearable /* = NULL*/, BOOL disable_camera_switch)
 {
-	togglMyOutfitsPanel(FALSE);
+	toggleMyOutfitsPanel(FALSE);
 	toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode
-	toggleWearableEditPanel(TRUE, wearable);
+	toggleWearableEditPanel(TRUE, wearable, disable_camera_switch);
+}
+
+void LLSidepanelAppearance::showPhysicsEditPanel(LLWearable *wearable /* = NULL*/)
+{
+	showWearableEditPanel(wearable, TRUE);
 }
 
-void LLSidepanelAppearance::togglMyOutfitsPanel(BOOL visible)
+void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible)
 {
 	if (!mPanelOutfitsInventory || mPanelOutfitsInventory->getVisible() == visible)
 	{
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index f28cdfa49a2564a2b383b2bd5e8c85e8059c0a5b..022280132e60418ed970616121bd42d90da03573 100644
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -59,7 +59,8 @@ class LLSidepanelAppearance : public LLPanel
 
 	void showOutfitsInventoryPanel();
 	void showOutfitEditPanel();
-	void showWearableEditPanel(LLWearable *wearable = NULL);
+	void showWearableEditPanel(LLWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);
+	void showPhysicsEditPanel(LLWearable *wearable = NULL);
 	void setWearablesLoading(bool val);
 	void showDefaultSubpart();
 	void updateScrollingPanelList();
@@ -71,7 +72,7 @@ class LLSidepanelAppearance : public LLPanel
 	void onOpenOutfitButtonClicked();
 	void onEditAppearanceButtonClicked();
 
-	void togglMyOutfitsPanel(BOOL visible);
+	void toggleMyOutfitsPanel(BOOL visible);
 	void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE);
 	void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index c2750680282233fb6d3cc0090e95b99ecbb31ff3..285cc857fb8367d502db9617efef074ce7cf104b 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3650,6 +3650,15 @@ class LLEnableEditShape : public view_listener_t
 	}
 };
 
+class LLEnableEditPhysics : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		//return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0);
+		return TRUE;
+	}
+};
+
 bool is_object_sittable()
 {
 	LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
@@ -5608,6 +5617,11 @@ void handle_edit_shape()
 	LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_shape"));
 }
 
+void handle_edit_physics()
+{
+	LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_physics"));
+}
+
 void handle_report_abuse()
 {
 	// Prevent menu from appearing in screen shot.
@@ -7843,9 +7857,11 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff");
 	view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar");
 	view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape");
+	view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics");
 	commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar));
 	commit.add("EditOutfit", boost::bind(&handle_edit_outfit));
 	commit.add("EditShape", boost::bind(&handle_edit_shape));
+	commit.add("EditPhysics", boost::bind(&handle_edit_physics));
 
 	// View menu
 	view_listener_t::addMenu(new LLViewMouselook(), "View.Mouselook");
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 9af1198df1d9e5ec1362da718bf81bb2ed077c25..f595a05a28c9c9b56d5d36a262aa8f740e9443cc 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -103,6 +103,8 @@ extern F32 ANIM_SPEED_MIN;
 
 #include <boost/lexical_cast.hpp>
 
+#define OUTPUT_BREAST_DATA
+
 using namespace LLVOAvatarDefines;
 
 //-----------------------------------------------------------------------------
@@ -118,6 +120,7 @@ const LLUUID ANIM_AGENT_HEAD_ROT = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"
 const LLUUID ANIM_AGENT_PELVIS_FIX = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b");  //"pelvis_fix"
 const LLUUID ANIM_AGENT_TARGET = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55");  //"target"
 const LLUUID ANIM_AGENT_WALK_ADJUST	= LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d");  //"walk_adjust"
+const LLUUID ANIM_AGENT_BREAST_MOTION = LLUUID("ce52c2b2-b62a-1e90-6152-7cd1efe2fd60");  //"breast_motion"
 
 
 //-----------------------------------------------------------------------------
@@ -573,6 +576,387 @@ class LLPelvisFixMotion :
 	LLCharacter*		mCharacter;
 };
 
+//-----------------------------------------------------------------------------
+// class LLBreatheMotionRot
+//-----------------------------------------------------------------------------
+class LLBreastMotion :
+	public LLMotion
+{
+public:
+	// Constructor
+	LLBreastMotion(const LLUUID &id) :
+		LLMotion(id),
+		mCharacter(NULL),
+		mFileWrite(NULL)
+	{
+		mName = "breast_motion";
+		mChestState = new LLJointState;
+
+		mBreastMassParam = (F32)1.0;
+		mBreastDragParam = LLVector3((F32)0.1, (F32)0.1, (F32)0.1);
+		mBreastSmoothingParam = (U32)2;
+		mBreastGravityParam = (F32)0.0;
+
+		mBreastSpringParam = LLVector3((F32)3.0, (F32)0.0, (F32)3.0);
+		mBreastAccelerationParam = LLVector3((F32)50.0, (F32)0.0, (F32)50.0);
+		mBreastDampingParam = LLVector3((F32)0.3, (F32)0.0, (F32)0.3);
+		mBreastMaxVelocityParam = LLVector3((F32)10.0, (F32)0.0, (F32)10.0);
+
+		mBreastParamsUser[0] = mBreastParamsUser[1] = mBreastParamsUser[2] = NULL;
+		mBreastParamsDriven[0] = mBreastParamsDriven[1] = mBreastParamsDriven[2] = NULL;
+
+		mCharLastPosition_world_pt = LLVector3(0,0,0);
+		mCharLastVelocity_local_vec = LLVector3(0,0,0);
+		mCharLastAcceleration_local_vec = LLVector3(0,0,0);
+		mBreastLastPosition_local_pt = LLVector3(0,0,0);
+		mBreastVelocity_local_vec = LLVector3(0,0,0);
+	}
+
+	// Destructor
+	virtual ~LLBreastMotion() {}
+
+public:
+	//-------------------------------------------------------------------------
+	// functions to support MotionController and MotionRegistry
+	//-------------------------------------------------------------------------
+	// static constructor
+	// all subclasses must implement such a function and register it
+	static LLMotion *create(const LLUUID &id) { return new LLBreastMotion(id); }
+
+public:
+	//-------------------------------------------------------------------------
+	// animation callbacks to be implemented by subclasses
+	//-------------------------------------------------------------------------
+
+	// motions must specify whether or not they loop
+	virtual BOOL getLoop() { return TRUE; }
+
+	// motions must report their total duration
+	virtual F32 getDuration() { return 0.0; }
+
+	// motions must report their "ease in" duration
+	virtual F32 getEaseInDuration() { return 0.0; }
+
+	// motions must report their "ease out" duration.
+	virtual F32 getEaseOutDuration() { return 0.0; }
+
+	// motions must report their priority
+	virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; }
+
+	virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; }
+
+	// called to determine when a motion should be activated/deactivated based on avatar pixel coverage
+	virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BREATHE; }
+
+	// run-time (post constructor) initialization,
+	// called after parameters have been set
+	// must return true to indicate success and be available for activation
+	virtual LLMotionInitStatus onInitialize(LLCharacter *character)
+	{		
+		mCharacter = character;
+		BOOL success = true;
+
+		if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) ) { success = false; }
+
+		if (!success)
+		{
+			return STATUS_FAILURE;
+		}
+		
+		mChestState->setUsage(LLJointState::ROT);
+		addJointState( mChestState );
+
+		// User-set params
+		static const std::string breast_param_names_user[3] =
+			{
+				"Breast_Female_Cleavage",
+				"",
+				"Breast_Gravity"
+			};
+
+		// Params driven by this algorithm
+		static const std::string breast_param_names_driven[3] =
+			{
+				"Breast_Female_Cleavage_Driven",
+				"",
+				"Breast_Gravity_Driven"
+			};
+		
+		for (U32 i=0; i < 3; i++)
+		{
+			mBreastParamsUser[i] = NULL;
+			mBreastParamsDriven[i] = NULL;
+			mBreastParamsMin[i] = 0;
+			mBreastParamsMax[i] = 0;
+			if (breast_param_names_user[i] != "" && breast_param_names_driven[i] != "")
+			{
+				mBreastParamsUser[i] = (LLViewerVisualParam*)mCharacter->getVisualParam(breast_param_names_user[i].c_str());
+				mBreastParamsDriven[i] = (LLViewerVisualParam*)mCharacter->getVisualParam(breast_param_names_driven[i].c_str());
+				if (mBreastParamsDriven[i])
+				{
+					mBreastParamsMin[i] = mBreastParamsDriven[i]->getMinWeight();
+					mBreastParamsMax[i] = mBreastParamsDriven[i]->getMaxWeight();
+				}
+			}
+		}
+
+#ifdef OUTPUT_BREAST_DATA
+		//if (mCharacter->getSex() == SEX_FEMALE)
+		if (dynamic_cast<LLVOAvatarSelf *>(mCharacter))
+		{
+			mFileWrite = fopen("c:\\temp\\data.txt","w");
+			if (mFileWrite != NULL)
+			{
+				fprintf(mFileWrite,"Pos\tParam\tNet\tVel\t\tAccel\tSpring\tDamp\n");
+			}
+		}
+#endif
+
+		mTimer.reset();
+		return STATUS_SUCCESS;
+	}
+
+	// called when a motion is activated
+	// must return TRUE to indicate success, or else
+	// it will be deactivated
+	virtual BOOL onActivate() { return TRUE; }
+
+	F32 calculateTimeDelta()
+	{
+		const F32 time = mTimer.getElapsedTimeF32();
+		const F32 time_delta = time - mLastTime;
+
+		mLastTime = time;
+
+		return time_delta;
+	}
+
+	LLVector3 toLocal(const LLVector3 &world_vector)
+	{
+		LLVector3 local_vec(0,0,0);
+
+		LLJoint *chest_joint = mChestState->getJoint();
+		const LLQuaternion world_rot = chest_joint->getWorldRotation();
+		
+		// -1 because cleavage param changes opposite to direction.
+		LLVector3 breast_dir_world_vec = LLVector3(-1,0,0) * world_rot;
+		breast_dir_world_vec.normalize();
+		local_vec[0] = world_vector * breast_dir_world_vec;
+
+		LLVector3 breast_up_dir_world_vec = LLVector3(0,0,1) * world_rot;
+		breast_up_dir_world_vec.normalize();
+		local_vec[2] = world_vector * breast_up_dir_world_vec;
+
+		/*
+		{
+			llinfos << "Dir: " << breast_dir_world_vec << "V: " << world_vector << "DP: " << local_vec[0] << " time: " << llendl;
+		}
+		*/
+
+		return local_vec;
+	}
+
+	LLVector3 calculateVelocity_local(const F32 time_delta)
+	{
+		LLJoint *chest_joint = mChestState->getJoint();
+		const LLVector3 world_pos_pt = chest_joint->getWorldPosition();
+		const LLQuaternion world_rot = chest_joint->getWorldRotation();
+		const LLVector3 last_world_pos_pt = mCharLastPosition_world_pt;
+		const LLVector3 char_velocity_world_vec = (world_pos_pt-last_world_pos_pt) / time_delta;
+		const LLVector3 char_velocity_local_vec = toLocal(char_velocity_world_vec);
+
+		return char_velocity_local_vec;
+	}
+
+	LLVector3 calculateAcceleration_local(const LLVector3 &new_char_velocity_local_vec,
+										  const F32 time_delta)
+	{
+		LLVector3 char_acceleration_local_vec = new_char_velocity_local_vec - mCharLastVelocity_local_vec;
+		
+		char_acceleration_local_vec = 
+			char_acceleration_local_vec * 1.0/mBreastSmoothingParam + 
+			mCharLastAcceleration_local_vec * (mBreastSmoothingParam-1.0)/mBreastSmoothingParam;
+
+		mCharLastAcceleration_local_vec = char_acceleration_local_vec;
+
+		char_acceleration_local_vec *= mBreastAccelerationParam;
+		return char_acceleration_local_vec;
+	}
+
+	// called per time step
+	// must return TRUE while it is active, and
+	// must return FALSE when the motion is completed.
+	virtual BOOL onUpdate(F32 time, U8* joint_mask)
+	{
+		/*
+		FILE *fread = fopen("c:\\temp\\breast_data.txt","r");
+		if (fread)
+		{
+			char dummy_str[255];
+			fscanf(fread,"%s %f\n",dummy_str, &mBreastMassParam);
+			fscanf(fread,"%s %f %f %f\n",dummy_str, &mBreastSpringParam[0],&mBreastSpringParam[1],&mBreastSpringParam[2]);
+			fscanf(fread,"%s %f %f %f\n",dummy_str, &mBreastAccelerationParam[0],&mBreastAccelerationParam[1],&mBreastAccelerationParam[2]);
+			fscanf(fread,"%s %f %f %f\n",dummy_str, &mBreastDampingParam[0],&mBreastDampingParam[1],&mBreastDampingParam[2]);
+			fscanf(fread,"%s %f %f %f\n",dummy_str, &mBreastMaxVelocityParam[0],&mBreastMaxVelocityParam[1],&mBreastMaxVelocityParam[2]);
+			fscanf(fread,"%s %f %f %f\n",dummy_str, &mBreastDragParam[0], &mBreastDragParam[1], &mBreastDragParam[2]);
+			fscanf(fread,"%s %d\n",dummy_str, &mBreastSmoothingParam);
+		}
+		fclose(fread);
+		*/
+		
+		/* TEST:
+		   1. Change outfits
+		   2. FPS effect
+		   3. Add disable
+		   4. Disappearing chests
+		   5. Overwrites breast params
+		   6. Threshold for not setting param
+		*/
+
+		mBreastMassParam = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_Mass"))->getWeight();
+		mBreastSmoothingParam = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_Smoothing"))->getWeight();
+		mBreastGravityParam = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_Gravity"))->getWeight();
+
+		mBreastSpringParam[0] =       ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_Side_Spring"))->getWeight();
+		mBreastAccelerationParam[0] = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_Side_Bounce"))->getWeight();
+		mBreastDampingParam[0] =      ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_Side_Damping"))->getWeight();
+		mBreastMaxVelocityParam[0] = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_Side_Range"))->getWeight();
+		mBreastDragParam[0] =        ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_Side_Drag"))->getWeight();
+
+		mBreastSpringParam[2] = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_UpDown_Spring"))->getWeight();
+		mBreastAccelerationParam[2] = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_UpDown_Bounce"))->getWeight();
+		mBreastDampingParam[2] = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_UpDown_Damping"))->getWeight();
+		mBreastMaxVelocityParam[2] = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_UpDown_Range"))->getWeight();
+		mBreastDragParam[2] = ((LLViewerVisualParam*)mCharacter->getVisualParam("Breast_Physics_UpDown_Drag"))->getWeight();
+
+		if (mCharacter->getSex() != SEX_FEMALE) return TRUE;
+		const F32 time_delta = calculateTimeDelta();
+		if (time_delta < .01 || time_delta > 10.0) return TRUE;
+
+		
+		LLVector3 breast_user_local_pt(0,0,0);
+		
+		for (U32 i=0; i < 3; i++)
+		{
+			if (mBreastParamsUser[i] != NULL)
+			{
+				breast_user_local_pt[i] = mBreastParamsUser[i]->getWeight();
+			}
+		}
+		
+		LLVector3 breast_current_local_pt = mBreastLastPosition_local_pt;
+		
+		const LLVector3 char_velocity_local_vec = calculateVelocity_local(time_delta);
+		const LLVector3 char_acceleration_local_vec = calculateAcceleration_local(char_velocity_local_vec, time_delta);
+		mCharLastVelocity_local_vec = char_velocity_local_vec;
+
+		LLJoint *chest_joint = mChestState->getJoint();
+		mCharLastPosition_world_pt = chest_joint->getWorldPosition();
+		
+
+		const LLVector3 spring_length_local = breast_current_local_pt-breast_user_local_pt;
+		LLVector3 force_spring_local_vec = -spring_length_local; force_spring_local_vec *= mBreastSpringParam;
+		const LLVector3 force_accel_local_vec = char_acceleration_local_vec * mBreastMassParam;
+		
+		const LLVector3 force_gravity_local_vec = toLocal(LLVector3(0,0,1))* mBreastGravityParam * mBreastMassParam;
+
+		LLVector3 force_damping_local_vec = -mBreastDampingParam; force_damping_local_vec *= mBreastVelocity_local_vec;
+
+		LLVector3 force_drag_local_vec = .5*char_velocity_local_vec; // should square char_velocity_vec
+		force_drag_local_vec[0] *= mBreastDragParam[0];
+		force_drag_local_vec[1] *= mBreastDragParam[1];
+		force_drag_local_vec[2] *= mBreastDragParam[2];
+
+		const LLVector3 force_net_local_vec = 
+			force_accel_local_vec + 
+			force_gravity_local_vec +
+			force_spring_local_vec + 
+			force_damping_local_vec + 
+			force_drag_local_vec;
+
+		LLVector3 acceleration_local_vec = force_net_local_vec / mBreastMassParam;
+		mBreastVelocity_local_vec += acceleration_local_vec;
+		mBreastVelocity_local_vec.clamp(-mBreastMaxVelocityParam, mBreastMaxVelocityParam);
+
+		LLVector3 new_local_pt = breast_current_local_pt + mBreastVelocity_local_vec*time_delta;
+		new_local_pt.clamp(mBreastParamsMin,mBreastParamsMax);
+		
+		for (U32 i=0; i < 3; i++)
+		{
+			if (mBreastParamsDriven[i])
+			{
+				mCharacter->setVisualParamWeight(mBreastParamsDriven[i],
+												 new_local_pt[i],
+												 FALSE);
+			}
+		}
+
+		if (mFileWrite != NULL)
+		{
+			fprintf(mFileWrite,"%f\t%f\t%f\t%f\t\t%f\t%f\t%f\t \t%f\t%f\t%f\t%f\t%f\t%f\n",
+					mCharLastPosition_world_pt[2],
+					breast_current_local_pt[2],
+					acceleration_local_vec[2],
+					mBreastVelocity_local_vec[2],
+					
+					force_accel_local_vec[2],
+					force_spring_local_vec[2],
+					force_damping_local_vec[2],
+					
+					force_accel_local_vec[2],
+					force_damping_local_vec[2],
+					force_drag_local_vec[2],
+					force_net_local_vec[2],
+					time_delta,
+					mBreastMassParam
+					);
+		}
+		
+		mBreastLastPosition_local_pt = new_local_pt;
+		mCharacter->updateVisualParams();
+		return TRUE;
+	}
+	
+	// called when a motion is deactivated
+	virtual void onDeactivate() {}
+
+private:
+	//-------------------------------------------------------------------------
+	// joint states to be animated
+	//-------------------------------------------------------------------------
+	LLPointer<LLJointState> mChestState;
+	LLCharacter*		mCharacter;
+
+	LLViewerVisualParam *mBreastParamsUser[3];
+	LLViewerVisualParam *mBreastParamsDriven[3];
+	LLVector3           mBreastParamsMin;
+	LLVector3           mBreastParamsMax;
+
+	LLVector3           mCharLastPosition_world_pt; // Last position of the avatar
+	LLVector3			mCharLastVelocity_local_vec; // How fast the character is moving
+	LLVector3           mCharLastAcceleration_local_vec; // Change in character velocity
+
+	LLVector3           mBreastLastPosition_local_pt; // Last parameters for breast
+	LLVector3           mBreastVelocity_local_vec; // How fast the breast params are moving
+
+
+	F32 mBreastMassParam;
+	F32 mBreastGravityParam;
+	U32 mBreastSmoothingParam;
+
+	LLVector3 mBreastSpringParam;
+	LLVector3 mBreastDampingParam;
+	LLVector3 mBreastAccelerationParam;
+	LLVector3 mBreastMaxVelocityParam;
+	LLVector3 mBreastDragParam;
+
+	LLFrameTimer	mTimer;
+	F32             mLastTime;
+	
+	FILE           *mFileWrite;
+	U32            mFileTicks;
+};
+
 /**
  **
  ** End LLVOAvatar Support classes
@@ -1137,6 +1521,7 @@ void LLVOAvatar::initClass()
 
 	gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise");
 	gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot");
+	gAnimLibrary.animStateSetString(ANIM_AGENT_BREAST_MOTION,"breast_motion");
 	gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING,"editing");
 	gAnimLibrary.animStateSetString(ANIM_AGENT_EYE,"eye");
 	gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST,"fly_adjust");
@@ -1275,6 +1660,7 @@ void LLVOAvatar::initInstance(void)
 		// motions without a start/stop bit
 		registerMotion( ANIM_AGENT_BODY_NOISE,				LLBodyNoiseMotion::create );
 		registerMotion( ANIM_AGENT_BREATHE_ROT,				LLBreatheMotionRot::create );
+		registerMotion( ANIM_AGENT_BREAST_MOTION,			LLBreastMotion::create );
 		registerMotion( ANIM_AGENT_EDITING,					LLEditingMotion::create	);
 		registerMotion( ANIM_AGENT_EYE,						LLEyeMotion::create	);
 		registerMotion( ANIM_AGENT_FEMALE_WALK,				LLKeyframeWalkMotion::create );
@@ -1688,6 +2074,7 @@ void LLVOAvatar::startDefaultMotions()
 	startMotion( ANIM_AGENT_EYE );
 	startMotion( ANIM_AGENT_BODY_NOISE );
 	startMotion( ANIM_AGENT_BREATHE_ROT );
+	startMotion( ANIM_AGENT_BREAST_MOTION );
 	startMotion( ANIM_AGENT_HAND_MOTION );
 	startMotion( ANIM_AGENT_PELVIS_FIX );
 
@@ -6097,14 +6484,10 @@ void LLVOAvatar::updateMeshTextures()
 			// When an avatar is changing clothes and not in Appearance mode,
 			// use the last-known good baked texture until it finish the first
 			// render of the new layerset.
-
-			const BOOL layerset_invalid = !mBakedTextureDatas[i].mTexLayerSet 
-										  || !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized()
-										  || !mBakedTextureDatas[i].mTexLayerSet->isLocalTextureDataAvailable();
-
 			use_lkg_baked_layer[i] = (!is_layer_baked[i] 
 									  && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) 
-									  && layerset_invalid);
+									  && mBakedTextureDatas[i].mTexLayerSet 
+									  && !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized());
 			if (use_lkg_baked_layer[i])
 			{
 				mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE);
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 6d9424c8beb4cf179cee13acf31f58ad08bcb517..c522af7d5532bbb76924c75d7eba8caafbc37ee0 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -48,6 +48,7 @@
 
 extern const LLUUID ANIM_AGENT_BODY_NOISE;
 extern const LLUUID ANIM_AGENT_BREATHE_ROT;
+extern const LLUUID ANIM_AGENT_BREAST_MOTION;
 extern const LLUUID ANIM_AGENT_EDITING;
 extern const LLUUID ANIM_AGENT_EYE;
 extern const LLUUID ANIM_AGENT_FLY_ADJUST;
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index e2348375d55b7a25b67a7a7ec1a0794315cfce77..acdecbad31210855bffa24ea7e610194b78af806 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -80,6 +80,14 @@ name="Edit Outfit">
     <menu_item_call.on_enable
      function="Edit.EnableEditShape" />
   </menu_item_call>
+  <menu_item_call label="Edit My Physics"
+  layout="topleft"
+  name="Edit My Physics">
+    <menu_item_call.on_click
+     function="EditPhysics" />
+    <menu_item_call.on_enable
+     function="Edit.EnableEditPhysics" />
+  </menu_item_call>
   <menu_item_call
     label="My Friends"
     layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index d5b993152a5374bbfafe973e9b8ebbd5e789abc8..71b8eea94ccd4c322e50ec58fe95fb0d29b1adfd 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -206,6 +206,14 @@
         function="EditShape" />
        <menu_item_call.on_enable
         function="Edit.EnableEditShape" />
+   </menu_item_call>
+    <menu_item_call label="Edit My Physics" 
+    layout="topleft"
+    name="Edit My Physics">
+       <menu_item_call.on_click
+        function="EditPhysics" />
+       <menu_item_call.on_enable
+        function="Edit.EnableEditPhysics" />
    </menu_item_call>
    <menu_item_call
      label="My Friends"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_shape.xml b/indra/newview/skins/default/xui/en/panel_edit_shape.xml
index d295f5fe4a7b496e57b5ce9f5bf02c6d3369bfdf..a7563d6f96b83dba0301e0d2cad530cec74a6f9c 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_shape.xml
@@ -175,6 +175,20 @@
 				top="0"
 				width="303" />
 		</accordion_tab>
+		<accordion_tab
+			layout="topleft"
+			min_height="150"
+			name="shape_physics_tab"
+            fit_panel="false"
+			title="Physics">
+           <scrolling_panel_list
+                layout="topleft"
+				follows="all"
+				left="0"
+				name="shape_physics_param_list"
+				top="0"
+				width="303" />
+		</accordion_tab>
 	</accordion>
     </panel>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 676bef2d0be736242a364a42d14c28dcd8fc4cce..e16bbfa5a53bebbe26c458e3d29e6c37500cefe0 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2471,6 +2471,20 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
 <string name="Bulbous">Bulbous</string>
 <string name="Bulbous Nose">Bulbous Nose</string>
 
+<string name="Breast Physics Mass">Breast Mass</string>
+<string name="Breast Physics Smoothing">Breast Smoothing</string>
+
+<string name="Breast Physics Side Spring">Breast Side Spring</string>
+<string name="Breast Physics Side Bounce">Breast Side Bounce</string>
+<string name="Breast Physics Side Damping">Breast Side Damping</string>
+<string name="Breast Physics Side Drag">Breast Side Drag</string>
+<string name="Breast Physics Side Range">Breast Side Max</string>
+
+<string name="Breast Physics UpDown Spring">Breast UpDown Spring</string>
+<string name="Breast Physics UpDown Bounce">Breast UpDown Bounce</string>
+<string name="Breast Physics UpDown Damping">Breast UpDown Damping</string>
+<string name="Breast Physics UpDown Drag">Breast UpDown Drag</string>
+<string name="Breast Physics UpDown Range">Breast UpDown Range</string>
 
 <string name="Bushy Eyebrows">Bushy Eyebrows</string>
 <string name="Bushy Hair">Bushy Hair</string>