diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4c72b03b2e2a6751faceb933f5d5dfcefe651c21..107f98071ccd9f4005ac3954cf849c1f24adbd69 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5418,6 +5418,50 @@
       <key>Value</key>
       <real>0.0</real>
     </map>
+  <key>ObjectCostHighThreshold</key>
+  <map>
+    <key>Comment</key>
+    <string>Threshold at which object cost is considered high (displayed in red).</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>128.0</real>
+  </map>
+  <key>ObjectCostLowColor</key>
+  <map>
+    <key>Comment</key>
+    <string>Color for object with a low object cost.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color4</string>
+    <key>Value</key>
+    <array>
+      <real>0.0</real>
+      <real>0.5</real>
+      <real>1.0</real>
+      <real>0.5</real>
+    </array>
+  </map>
+  <key>ObjectCostHighColor</key>
+  <map>
+    <key>Comment</key>
+    <string>Color for object a high object cost.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color4</string>
+    <key>Value</key>
+    <array>
+      <real>1.0</real>
+      <real>0.0</real>
+      <real>0.0</real>
+      <real>0.75</real>
+    </array>
+  </map>
+  
     <key>ParcelMediaAutoPlayEnable</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index a8172bbfaef7ae7075d37ca88489f1b3053372d9..30d2a02b5b9b3e4e15191bab43d25a0718bb2c10 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -419,12 +419,12 @@ void LLFloaterTools::refresh()
 
 	// Refresh object and prim count labels
 	LLLocale locale(LLLocale::USER_LOCALE);
-	std::string obj_count_string;
-	LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount());
-	childSetTextArg("obj_count",  "[COUNT]", obj_count_string);	
-	std::string prim_count_string;
-	LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount(TRUE));
-	childSetTextArg("prim_count", "[COUNT]", prim_count_string);
+	
+	F32 obj_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost();
+	F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost();
+
+	childSetTextArg("obj_count",  "[COUNT]", llformat("%.1f", obj_cost));	
+	childSetTextArg("prim_count", "[COUNT]", llformat("%.1f", link_cost));
 
 	// calculate selection rendering cost
 	if (sShowObjectCost)
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index e66be1023d18eb20d2e26e66bb4bbbf8aebb0a6c..5acbae0c77007914e32d4c16a3fd85fce7bb659e 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6183,6 +6183,53 @@ S32 LLObjectSelection::getObjectCount(BOOL mesh_adjust)
 	return count;
 }
 
+F32 LLObjectSelection::getSelectedObjectCost()
+{
+	cleanupNodes();
+	F32 cost = 0.f;
+
+	for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+	{
+		LLSelectNode* node = *iter;
+		LLViewerObject* object = node->getObject();
+		
+		if (object)
+		{
+			cost += object->getObjectCost();
+		}
+	}
+
+	return cost;
+}
+
+F32 LLObjectSelection::getSelectedLinksetCost()
+{
+	cleanupNodes();
+	F32 cost = 0.f;
+
+	std::set<LLViewerObject*> me_roots;
+
+	for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+	{
+		LLSelectNode* node = *iter;
+		LLViewerObject* object = node->getObject();
+		
+		if (object)
+		{
+			LLViewerObject* root = static_cast<LLViewerObject*>(object->getRoot());
+			if (root)
+			{
+				if (me_roots.find(root) == me_roots.end())
+				{
+					me_roots.insert(root);
+					cost += root->getLinksetCost();
+				}
+			}
+		}
+	}
+
+	return cost;
+}
 
 //-----------------------------------------------------------------------------
 // getTECount()
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 34f2082b825dd78328ded47218d6f919712a2516..5302cfae683d51f92cd03de91d44d21c3ef09c64 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -292,6 +292,9 @@ class LLObjectSelection : public LLRefCount
 
 	// count members
 	S32 getObjectCount(BOOL mesh_adjust = FALSE);
+	F32 getSelectedObjectCost();
+	F32 getSelectedLinksetCost();
+
 	S32 getTECount();
 	S32 getRootObjectCount();
 
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index f11195303e46123c864a06960fb7ec81481d0079..1290e6b9a656c116c868f3e259d3dd8ead8da348 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2294,6 +2294,14 @@ void pushVerts(LLFace* face, U32 mask)
 	}
 }
 
+void pushVerts(LLDrawable* drawable, U32 mask)
+{
+	for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+	{
+		pushVerts(drawable->getFace(i), mask);
+	}
+}
+
 void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
 {
 	if (buffer)
@@ -2664,36 +2672,35 @@ void renderPhysicsShape(LLDrawable* drawable)
 	LLVOVolume* volume = drawable->getVOVolume();
 	if (volume)
 	{
+		F32 threshold = gSavedSettings.getF32("ObjectCostHighThreshold");
+		F32 cost = volume->getObjectCost();
+
+		LLColor4 low = gSavedSettings.getColor4("ObjectCostLowColor");
+		LLColor4 high = gSavedSettings.getColor4("ObjectCostHighColor");
+
+		LLColor4 color = lerp(low, high, cost/threshold);
+
+		U32 data_mask = LLVertexBuffer::MAP_VERTEX;
+
 		if (volume->isMesh())
-		{
+		{			
 			LLUUID mesh_id = volume->getVolume()->getParams().getSculptID();
 			const LLMeshDecomposition* decomp = gMeshRepo.getDecomposition(mesh_id);
 			if (decomp)
 			{
-				if (volume->getObjectCost() == -1)
-				{
-					gObjectList.updateObjectCost(volume);
-				}
-
 				gGL.pushMatrix();
 				glMultMatrixf((F32*) volume->getRelativeXform().mMatrix);
-				static std::vector<LLColor4U> color;
-
+				
 				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 				for (U32 i = 0; i < decomp->mHull.size(); ++i)
-				{
-					if (color.size() <= i)
-					{
-						color.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255));
-					}
-					
+				{		
 					LLVertexBuffer* buff = decomp->mMesh[i];
 
-					buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+					buff->setBuffer(data_mask);
 
 					glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-					glColor3ub(color[i].mV[0], color[i].mV[1], color[i].mV[2]);
+					glColor3fv(color.mV);
 					buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts());
 					glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 
@@ -2701,14 +2708,24 @@ void renderPhysicsShape(LLDrawable* drawable)
 						LLGLEnable blend(GL_BLEND);
 						gGL.setSceneBlendType(LLRender::BT_ALPHA);
 						LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-						glColor4ub(color[i].mV[0], color[i].mV[1], color[i].mV[2], 64);
+						glColor4fv(color.mV);
 						buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts());
 					}
 				}
 
 				gGL.popMatrix();
+
+				return;
 			}
 		}
+
+		//push faces
+		glColor3fv(color.mV);
+		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+		pushVerts(drawable, data_mask);
+		glColor4fv(color.mV);
+		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+		pushVerts(drawable, data_mask);
 	}
 }
 
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 38a29ba4326ac12de049b2f052bda5c4408308f1..ff5d7e9c178b920b781228862f421ddd8a73b1e2 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -232,7 +232,9 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mState(0),
 	mMedia(NULL),
 	mClickAction(0),
-	mObjectCost(-1),
+	mObjectCost(0.f),
+	mLinksetCost(0.f),
+	mCostStale(true),
 	mAttachmentItemID(LLUUID::null)
 {
 	if (!is_global)
@@ -829,6 +831,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 #ifdef DEBUG_UPDATE_TYPE
 				llinfos << "Full:" << getID() << llendl;
 #endif
+				//clear cost and linkset cost
+				mCostStale = true;
+
 				LLUUID audio_uuid;
 				LLUUID owner_id;	// only valid if audio_uuid or particle system is not null
 				F32    gain;
@@ -1394,6 +1399,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 #ifdef DEBUG_UPDATE_TYPE
 				llinfos << "CompFull:" << getID() << llendl;
 #endif
+				mCostStale = true;
+
 				dp->unpackU32(crc, "CRC");
 				mTotalCRC = crc;
 				dp->unpackU8(material, "Material");
@@ -2864,6 +2871,39 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped)
 	}
 }
 
+void LLViewerObject::setObjectCost(F32 cost)
+{
+	mObjectCost = cost;
+	mCostStale = false;
+}
+
+void LLViewerObject::setLinksetCost(F32 cost)
+{
+	mLinksetCost = cost;
+	mCostStale = false;
+}
+
+
+F32 LLViewerObject::getObjectCost()
+{
+	if (mCostStale)
+	{
+		gObjectList.updateObjectCost(this);
+	}
+	
+	return mObjectCost;
+}
+
+F32 LLViewerObject::getLinksetCost()
+{
+	if (mCostStale)
+	{
+		gObjectList.updateObjectCost(this);
+	}
+
+	return mLinksetCost;
+}
+
 void LLViewerObject::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
 {
 	LLVector3 center = getRenderPosition();
@@ -4970,7 +5010,7 @@ void LLViewerObject::updateFlags()
 
 	if (getPhysicsShapeType() != 0)
 	{
-		llwarns << "sent non default physics rep" << llendl;
+		llwarns << "sent non default physics rep " << (S32) getPhysicsShapeType() << llendl;
 	}
 }
 
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index d2e465fe5a85753bfd1efe457254079070ebfa26..15fabc9f82139469ad71fbbd59d95264cf95e85d 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -334,8 +334,11 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	
 	virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE);
 
-	void setObjectCost(S32 cost) { mObjectCost = cost; }
-	S32 getObjectCost() { return mObjectCost; }
+	void setObjectCost(F32 cost);
+	F32 getObjectCost();
+	void setLinksetCost(F32 cost);
+	F32 getLinksetCost();
+	
 
 	void sendShapeUpdate();
 
@@ -671,7 +674,9 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	U8				mState;	// legacy
 	LLViewerObjectMedia* mMedia;	// NULL if no media associated
 	U8 mClickAction;
-	S32 mObjectCost; //resource cost of this object or -1 if unknown
+	F32 mObjectCost; //resource cost of this object or -1 if unknown
+	F32 mLinksetCost;
+	bool mCostStale;
 
 	static			U32			sNumZombieObjects;			// Objects which are dead, but not deleted
 
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 422ac4e84fe42514a29ef77b2fddd586602b0f2e..9d41e2a530d4d7df86976aec5552104428219e18 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -665,8 +665,8 @@ class LLObjectCostResponder : public LLCurl::Responder
 		for (LLSD::map_const_iterator iter = content.beginMap(); iter != content.endMap(); ++iter)
 		{
 			LLUUID object_id = LLUUID(iter->first);
-			S32 link_cost = iter->second["LinkResourceCost"].asInteger();
-			S32 prim_cost = iter->second["PrimResourceCost"].asInteger();
+			F32 link_cost = iter->second["LinksetResourceCost"].asReal();
+			F32 prim_cost = iter->second["PrimResourceCost"].asReal();
 
 			gObjectList.updateObjectCost(object_id, prim_cost, link_cost);
 		}
@@ -1099,7 +1099,7 @@ void LLViewerObjectList::updateObjectCost(LLViewerObject* object)
 	mStaleObjectCost.insert(object->getID());
 }
 
-void LLViewerObjectList::updateObjectCost(LLUUID object_id, S32 prim_cost, S32 link_cost)
+void LLViewerObjectList::updateObjectCost(LLUUID object_id, F32 prim_cost, F32 link_cost)
 {
 	mPendingObjectCost.erase(object_id);
 
@@ -1107,6 +1107,7 @@ void LLViewerObjectList::updateObjectCost(LLUUID object_id, S32 prim_cost, S32 l
 	if (object)
 	{
 		object->setObjectCost(prim_cost);
+		object->setLinksetCost(link_cost);
 	}
 }
 
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index db9324bdbdd3b6d953a5f07f766a63b3590f4b3d..4064a68eb21004fb17b5b7a516a9f3c5bb54deb2 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -92,7 +92,7 @@ class LLViewerObjectList
 	void update(LLAgent &agent, LLWorld &world);
 
 	void updateObjectCost(LLViewerObject* object);
-	void updateObjectCost(LLUUID object_id, S32 prim_cost, S32 link_cost);
+	void updateObjectCost(LLUUID object_id, F32 prim_cost, F32 link_cost);
 
 	void shiftObjects(const LLVector3 &offset);