From 303a59e7bc8537a63aee42f738fff8a79049c2a2 Mon Sep 17 00:00:00 2001
From: Loren Shih <seraph@lindenlab.com>
Date: Thu, 26 May 2011 14:16:56 -0400
Subject: dos2unix fixes for newview files.

---
 indra/newview/llaccountingquotamanager.cpp |   528 +-
 indra/newview/lldrawpoolbump.cpp           |     6 +-
 indra/newview/llfeaturemanager.cpp         |  1614 ++--
 indra/newview/llfloaterbuyland.cpp         |    18 +-
 indra/newview/llpanelobject.cpp            |  3998 +++++-----
 indra/newview/llviewermessage.cpp          |     8 +-
 indra/newview/llviewerobject.cpp           | 11424 +++++++++++++--------------
 indra/newview/llviewerobject.h             |  1650 ++--
 indra/newview/llviewerparcelmgr.cpp        |     6 +-
 indra/newview/llviewerprecompiledheaders.h |     4 +-
 indra/newview/llviewertexturelist.cpp      |     4 +-
 11 files changed, 9630 insertions(+), 9630 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llaccountingquotamanager.cpp b/indra/newview/llaccountingquotamanager.cpp
index ada74ea44c..d11b86db15 100644
--- a/indra/newview/llaccountingquotamanager.cpp
+++ b/indra/newview/llaccountingquotamanager.cpp
@@ -1,264 +1,264 @@
-/** 
- * @file LLAccountingQuotaManager.cpp
- * @ Handles the setting and accessing for costs associated with mesh 
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- * 
- * Copyright (c) 2001-2010, Linden Research, Inc.
- * 
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab.  Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- * 
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- * 
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- * 
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-#include "llaccountingquotamanager.h"
-#include "llagent.h"
-#include "llviewerregion.h"
-#include "llviewerobject.h"
-#include "llviewerobjectlist.h"
-#include "llviewerparcelmgr.h"
-#include "llparcel.h"
-
-//===============================================================================
-LLAccountingQuotaManager::LLAccountingQuotaManager()
-{	
-}
-//===============================================================================
-class LLAccountingQuotaResponder : public LLCurl::Responder
-{
-public:
-	LLAccountingQuotaResponder( const LLSD& objectIDs )
-	: mObjectIDs( objectIDs )
-	{
-	}
-		
-	void clearPendingRequests ( void )
-	{
-		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
-		{
-			LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( iter->asUUID() );
-		}
-	}
-	
-	void error( U32 statusNum, const std::string& reason )
-	{
-		llwarns	<< "Transport error "<<reason<<llendl;	
-		//prep#do we really want to remove all because of one failure - verify
-		clearPendingRequests();
-	}
-	
-	void result( const LLSD& content )
-	{
-		if ( !content.isMap() || content.has("error") )
-		{
-			llwarns	<< "Error on fetched data"<< llendl;
-			//prep#do we really want to remove all because of one failure - verify
-			clearPendingRequests();
-			return;
-		}
-		
-		//Differentiate what the incoming caps could be from the data
-		//bool VOContent  = content.has("Objects");
-		bool containsParcel    = content.has("parcel");
-		bool containsSelection = content.has("selected");
-		//bool VORegion   = content.has("region");
-				
-		//Loop over the stored object ids checking against the incoming data
-		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
-		{
-			LLUUID objectID = iter->asUUID();
-						
-			LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
-				
-			if ( containsParcel )
-			{
-					//Typically should be one
-					S32 dataCount = content["parcel"].size();
-					for(S32 i = 0; i < dataCount; i++)
-					{
-						//prep#todo verify that this is safe, otherwise just add a bool
-						S32 parcelId = 0;
-						S32 parcelOwner = 0;
-						if ( content["parcel"][i].has("parcel_id") )
-						{
-							parcelId = content["parcel"][i]["parcel_id"].asInteger();
-						}
-						if ( content["parcel"][i].has("parcel_owner") )
-						{
-							parcelOwner = content["parcel"][i]["parcel_owner"].asInteger();
-						}
-											
-						F32 ownerRenderCost		= 0;
-						F32 ownerPhysicsCost	= 0;
-						F32 ownerNetworkCost	= 0;
-						F32 ownerSimulationCost = 0;
-						
-						F32 groupRenderCost		= 0;
-						F32 groupPhysicsCost	= 0;
-						F32 groupNetworkCost	= 0;
-						F32 groupSimulationCost = 0;
-						
-						F32 otherRenderCost		= 0;
-						F32 otherPhysicsCost	= 0;
-						F32 otherNetworkCost	= 0;
-						F32 otherSimulationCost = 0;
-						
-						F32 totalRenderCost		= 0;
-						F32 totalPhysicsCost	= 0;
-						F32 totalNetworkCost	= 0;
-						F32 totalSimulationCost = 0;
-						
-						if ( content["parcel"][i].has("owner") )
-						{
-							ownerRenderCost		= content["parcel"][i]["owner"]["render"].asReal();
-							ownerPhysicsCost	= content["parcel"][i]["owner"]["physics"].asReal();
-							ownerNetworkCost	= content["parcel"][i]["owner"]["network"].asReal();
-							ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal();
-							
-						}
-						if ( content["parcel"][i].has("group") )
-						{
-							groupRenderCost		= content["parcel"][i]["group"]["render"].asReal();
-							groupPhysicsCost	= content["parcel"][i]["group"]["physics"].asReal();
-							groupNetworkCost	= content["parcel"][i]["group"]["network"].asReal();
-							groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal();
-							
-						}
-						if ( content["parcel"][i].has("other") )
-						{
-							otherRenderCost		= content["parcel"][i]["other"]["render"].asReal();
-							otherPhysicsCost	= content["parcel"][i]["other"]["physics"].asReal();
-							otherNetworkCost	= content["parcel"][i]["other"]["network"].asReal();
-							otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal();
-						}
-						
-						if ( content["parcel"][i].has("total") )
-						{
-							totalRenderCost		= content["parcel"][i]["total"]["render"].asReal();
-							totalPhysicsCost	= content["parcel"][i]["total"]["physics"].asReal();
-							totalNetworkCost	= content["parcel"][i]["total"]["network"].asReal();
-							totalSimulationCost = content["parcel"][i]["total"]["simulation"].asReal();
-							
-						}
-						
-						ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost,
-												 groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost,
-												 otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost,
-												 totalRenderCost, totalPhysicsCost, totalNetworkCost, totalSimulationCost );
-						//Update the Parcel						
-						LLParcel* pParcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
-						if ( pParcel )
-						{
-							pParcel->updateQuota( objectID, parcelQuota ); 
-						}
-					}					
-				}
-			else 
-			if ( containsSelection )
-			{
-				S32 dataCount = content["selected"].size();
-				for(S32 i = 0; i < dataCount; i++)
-				{
-					
-					F32 renderCost		= 0;
-					F32 physicsCost		= 0;
-					F32 networkCost		= 0;
-					F32 simulationCost	= 0;
-					
-					S32 localId = 0;
-					
-					localId			= content["selected"][i]["local_id"].asInteger();
-					renderCost		= content["selected"][i]["render"].asReal();
-					physicsCost		= content["selected"][i]["physics"].asReal();
-					networkCost		= content["selected"][i]["network"].asReal();
-					simulationCost	= content["selected"][i]["simulation"].asReal();
-					
-					SelectionQuota selectionQuota( localId, renderCost, physicsCost, networkCost, simulationCost );
-					
-					//Update the objects					
-					//gObjectList.updateQuota( localId, selectionQuota ); 
-					
-				}
-			}
-			else
-			{
-				//Nothing in string 
-				LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
-			}
-		}
-	}
-	
-private:
-	//List of posted objects
-	LLSD mObjectIDs;
-};
-//===============================================================================
-void LLAccountingQuotaManager::fetchQuotas( const std::string& url )
-{
-	// Invoking system must have already determined capability availability
-	if ( !url.empty() )
-	{
-		LLSD objectList;
-		U32  objectIndex = 0;
-		IDIt IDIter = mUpdateObjectQuota.begin();
-		IDIt IDIterEnd = mUpdateObjectQuota.end();
-		
-		for ( ; IDIter != IDIterEnd; ++IDIter )
-		{
-			// Check to see if a request for this object has already been made.
-			if ( mPendingObjectQuota.find( *IDIter ) ==	mPendingObjectQuota.end() )
-			{
-				mPendingObjectQuota.insert( *IDIter );	
-				objectList[objectIndex++] = *IDIter;
-			}
-		}
-	
-		mUpdateObjectQuota.clear();
-		
-		//Post results
-		if ( objectList.size() > 0 )
-		{
-			LLSD dataToPost = LLSD::emptyMap();			
-			dataToPost["object_ids"] = objectList;
-			LLHTTPClient::post( url, dataToPost, new LLAccountingQuotaResponder( objectList ));
-		}
-	}
-	else
-	{
-		//url was empty - warn & continue
-		llwarns<<"Supplied url is empty "<<llendl;
-		mUpdateObjectQuota.clear();
-		mPendingObjectQuota.clear();
-	}
-}
-//===============================================================================
-void LLAccountingQuotaManager::updateObjectCost( const LLUUID& objectID )
-{
-	mUpdateObjectQuota.insert( objectID );
-}
-//===============================================================================
-void LLAccountingQuotaManager::removePendingObjectQuota( const LLUUID& objectID )
-{
-	mPendingObjectQuota.erase( objectID );
-}
-//===============================================================================
+/** 
+ * @file LLAccountingQuotaManager.cpp
+ * @ Handles the setting and accessing for costs associated with mesh 
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llaccountingquotamanager.h"
+#include "llagent.h"
+#include "llviewerregion.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparcelmgr.h"
+#include "llparcel.h"
+
+//===============================================================================
+LLAccountingQuotaManager::LLAccountingQuotaManager()
+{	
+}
+//===============================================================================
+class LLAccountingQuotaResponder : public LLCurl::Responder
+{
+public:
+	LLAccountingQuotaResponder( const LLSD& objectIDs )
+	: mObjectIDs( objectIDs )
+	{
+	}
+		
+	void clearPendingRequests ( void )
+	{
+		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
+		{
+			LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( iter->asUUID() );
+		}
+	}
+	
+	void error( U32 statusNum, const std::string& reason )
+	{
+		llwarns	<< "Transport error "<<reason<<llendl;	
+		//prep#do we really want to remove all because of one failure - verify
+		clearPendingRequests();
+	}
+	
+	void result( const LLSD& content )
+	{
+		if ( !content.isMap() || content.has("error") )
+		{
+			llwarns	<< "Error on fetched data"<< llendl;
+			//prep#do we really want to remove all because of one failure - verify
+			clearPendingRequests();
+			return;
+		}
+		
+		//Differentiate what the incoming caps could be from the data
+		//bool VOContent  = content.has("Objects");
+		bool containsParcel    = content.has("parcel");
+		bool containsSelection = content.has("selected");
+		//bool VORegion   = content.has("region");
+				
+		//Loop over the stored object ids checking against the incoming data
+		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
+		{
+			LLUUID objectID = iter->asUUID();
+						
+			LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
+				
+			if ( containsParcel )
+			{
+					//Typically should be one
+					S32 dataCount = content["parcel"].size();
+					for(S32 i = 0; i < dataCount; i++)
+					{
+						//prep#todo verify that this is safe, otherwise just add a bool
+						S32 parcelId = 0;
+						S32 parcelOwner = 0;
+						if ( content["parcel"][i].has("parcel_id") )
+						{
+							parcelId = content["parcel"][i]["parcel_id"].asInteger();
+						}
+						if ( content["parcel"][i].has("parcel_owner") )
+						{
+							parcelOwner = content["parcel"][i]["parcel_owner"].asInteger();
+						}
+											
+						F32 ownerRenderCost		= 0;
+						F32 ownerPhysicsCost	= 0;
+						F32 ownerNetworkCost	= 0;
+						F32 ownerSimulationCost = 0;
+						
+						F32 groupRenderCost		= 0;
+						F32 groupPhysicsCost	= 0;
+						F32 groupNetworkCost	= 0;
+						F32 groupSimulationCost = 0;
+						
+						F32 otherRenderCost		= 0;
+						F32 otherPhysicsCost	= 0;
+						F32 otherNetworkCost	= 0;
+						F32 otherSimulationCost = 0;
+						
+						F32 totalRenderCost		= 0;
+						F32 totalPhysicsCost	= 0;
+						F32 totalNetworkCost	= 0;
+						F32 totalSimulationCost = 0;
+						
+						if ( content["parcel"][i].has("owner") )
+						{
+							ownerRenderCost		= content["parcel"][i]["owner"]["render"].asReal();
+							ownerPhysicsCost	= content["parcel"][i]["owner"]["physics"].asReal();
+							ownerNetworkCost	= content["parcel"][i]["owner"]["network"].asReal();
+							ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal();
+							
+						}
+						if ( content["parcel"][i].has("group") )
+						{
+							groupRenderCost		= content["parcel"][i]["group"]["render"].asReal();
+							groupPhysicsCost	= content["parcel"][i]["group"]["physics"].asReal();
+							groupNetworkCost	= content["parcel"][i]["group"]["network"].asReal();
+							groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal();
+							
+						}
+						if ( content["parcel"][i].has("other") )
+						{
+							otherRenderCost		= content["parcel"][i]["other"]["render"].asReal();
+							otherPhysicsCost	= content["parcel"][i]["other"]["physics"].asReal();
+							otherNetworkCost	= content["parcel"][i]["other"]["network"].asReal();
+							otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal();
+						}
+						
+						if ( content["parcel"][i].has("total") )
+						{
+							totalRenderCost		= content["parcel"][i]["total"]["render"].asReal();
+							totalPhysicsCost	= content["parcel"][i]["total"]["physics"].asReal();
+							totalNetworkCost	= content["parcel"][i]["total"]["network"].asReal();
+							totalSimulationCost = content["parcel"][i]["total"]["simulation"].asReal();
+							
+						}
+						
+						ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost,
+												 groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost,
+												 otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost,
+												 totalRenderCost, totalPhysicsCost, totalNetworkCost, totalSimulationCost );
+						//Update the Parcel						
+						LLParcel* pParcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
+						if ( pParcel )
+						{
+							pParcel->updateQuota( objectID, parcelQuota ); 
+						}
+					}					
+				}
+			else 
+			if ( containsSelection )
+			{
+				S32 dataCount = content["selected"].size();
+				for(S32 i = 0; i < dataCount; i++)
+				{
+					
+					F32 renderCost		= 0;
+					F32 physicsCost		= 0;
+					F32 networkCost		= 0;
+					F32 simulationCost	= 0;
+					
+					S32 localId = 0;
+					
+					localId			= content["selected"][i]["local_id"].asInteger();
+					renderCost		= content["selected"][i]["render"].asReal();
+					physicsCost		= content["selected"][i]["physics"].asReal();
+					networkCost		= content["selected"][i]["network"].asReal();
+					simulationCost	= content["selected"][i]["simulation"].asReal();
+					
+					SelectionQuota selectionQuota( localId, renderCost, physicsCost, networkCost, simulationCost );
+					
+					//Update the objects					
+					//gObjectList.updateQuota( localId, selectionQuota ); 
+					
+				}
+			}
+			else
+			{
+				//Nothing in string 
+				LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
+			}
+		}
+	}
+	
+private:
+	//List of posted objects
+	LLSD mObjectIDs;
+};
+//===============================================================================
+void LLAccountingQuotaManager::fetchQuotas( const std::string& url )
+{
+	// Invoking system must have already determined capability availability
+	if ( !url.empty() )
+	{
+		LLSD objectList;
+		U32  objectIndex = 0;
+		IDIt IDIter = mUpdateObjectQuota.begin();
+		IDIt IDIterEnd = mUpdateObjectQuota.end();
+		
+		for ( ; IDIter != IDIterEnd; ++IDIter )
+		{
+			// Check to see if a request for this object has already been made.
+			if ( mPendingObjectQuota.find( *IDIter ) ==	mPendingObjectQuota.end() )
+			{
+				mPendingObjectQuota.insert( *IDIter );	
+				objectList[objectIndex++] = *IDIter;
+			}
+		}
+	
+		mUpdateObjectQuota.clear();
+		
+		//Post results
+		if ( objectList.size() > 0 )
+		{
+			LLSD dataToPost = LLSD::emptyMap();			
+			dataToPost["object_ids"] = objectList;
+			LLHTTPClient::post( url, dataToPost, new LLAccountingQuotaResponder( objectList ));
+		}
+	}
+	else
+	{
+		//url was empty - warn & continue
+		llwarns<<"Supplied url is empty "<<llendl;
+		mUpdateObjectQuota.clear();
+		mPendingObjectQuota.clear();
+	}
+}
+//===============================================================================
+void LLAccountingQuotaManager::updateObjectCost( const LLUUID& objectID )
+{
+	mUpdateObjectQuota.insert( objectID );
+}
+//===============================================================================
+void LLAccountingQuotaManager::removePendingObjectQuota( const LLUUID& objectID )
+{
+	mPendingObjectQuota.erase( objectID );
+}
+//===============================================================================
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 29b50761d8..5f89d11391 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -889,9 +889,9 @@ void LLBumpImageList::destroyGL()
 
 void LLBumpImageList::restoreGL()
 {
-	if(!gTextureList.isInitialized())
-	{
-		return ;
+	if(!gTextureList.isInitialized())
+	{
+		return ;
 	}
 
 	LLStandardBumpmap::restoreGL();
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index d1bff9f423..83844048d1 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -1,807 +1,807 @@
-/** 
- * @file llfeaturemanager.cpp
- * @brief LLFeatureManager class implementation
- *
- * $LicenseInfo:firstyear=2003&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include <iostream>
-#include <fstream>
-
-#include <boost/regex.hpp>
-
-#include "llfeaturemanager.h"
-#include "lldir.h"
-
-#include "llsys.h"
-#include "llgl.h"
-#include "llsecondlifeurls.h"
-
-#include "llappviewer.h"
-#include "llhttpclient.h"
-#include "llnotificationsutil.h"
-#include "llviewercontrol.h"
-#include "llworld.h"
-#include "lldrawpoolterrain.h"
-#include "llviewertexturelist.h"
-#include "llversioninfo.h"
-#include "llwindow.h"
-#include "llui.h"
-#include "llcontrol.h"
-#include "llboost.h"
-#include "llweb.h"
-
-#if LL_WINDOWS
-#include "lldxhardware.h"
-#endif
-
-
-#if LL_DARWIN
-const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_mac.%s.txt";
-#elif LL_LINUX
-const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_linux.%s.txt";
-#elif LL_SOLARIS
-const char FEATURE_TABLE_FILENAME[] = "featuretable_solaris.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_solaris.%s.txt";
-#else
-const char FEATURE_TABLE_FILENAME[] = "featuretable%s.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable%s.%s.txt";
-#endif
-
-const char GPU_TABLE_FILENAME[] = "gpu_table.txt";
-const char GPU_TABLE_VER_FILENAME[] = "gpu_table.%s.txt";
-
-LLFeatureInfo::LLFeatureInfo(const std::string& name, const BOOL available, const F32 level)
-	: mValid(TRUE), mName(name), mAvailable(available), mRecommendedLevel(level)
-{
-}
-
-LLFeatureList::LLFeatureList(const std::string& name)
-	: mName(name)
-{
-}
-
-LLFeatureList::~LLFeatureList()
-{
-}
-
-void LLFeatureList::addFeature(const std::string& name, const BOOL available, const F32 level)
-{
-	if (mFeatures.count(name))
-	{
-		LL_WARNS("RenderInit") << "LLFeatureList::Attempting to add preexisting feature " << name << LL_ENDL;
-	}
-
-	LLFeatureInfo fi(name, available, level);
-	mFeatures[name] = fi;
-}
-
-BOOL LLFeatureList::isFeatureAvailable(const std::string& name)
-{
-	if (mFeatures.count(name))
-	{
-		return mFeatures[name].mAvailable;
-	}
-
-	LL_WARNS("RenderInit") << "Feature " << name << " not on feature list!" << LL_ENDL;
-	
-	// changing this to TRUE so you have to explicitly disable 
-	// something for it to be disabled
-	return TRUE;
-}
-
-F32 LLFeatureList::getRecommendedValue(const std::string& name)
-{
-	if (mFeatures.count(name) && isFeatureAvailable(name))
-	{
-		return mFeatures[name].mRecommendedLevel;
-	}
-
-	LL_WARNS("RenderInit") << "Feature " << name << " not on feature list or not available!" << LL_ENDL;
-	return 0;
-}
-
-BOOL LLFeatureList::maskList(LLFeatureList &mask)
-{
-	//llinfos << "Masking with " << mask.mName << llendl;
-	//
-	// Lookup the specified feature mask, and overlay it on top of the
-	// current feature mask.
-	//
-
-	LLFeatureInfo mask_fi;
-
-	feature_map_t::iterator feature_it;
-	for (feature_it = mask.mFeatures.begin(); feature_it != mask.mFeatures.end(); ++feature_it)
-	{
-		mask_fi = feature_it->second;
-		//
-		// Look for the corresponding feature
-		//
-		if (!mFeatures.count(mask_fi.mName))
-		{
-			LL_WARNS("RenderInit") << "Feature " << mask_fi.mName << " in mask not in top level!" << LL_ENDL;
-			continue;
-		}
-
-		LLFeatureInfo &cur_fi = mFeatures[mask_fi.mName];
-		if (mask_fi.mAvailable && !cur_fi.mAvailable)
-		{
-			LL_WARNS("RenderInit") << "Mask attempting to reenabling disabled feature, ignoring " << cur_fi.mName << LL_ENDL;
-			continue;
-		}
-		cur_fi.mAvailable = mask_fi.mAvailable;
-		cur_fi.mRecommendedLevel = llmin(cur_fi.mRecommendedLevel, mask_fi.mRecommendedLevel);
-		LL_DEBUGS("RenderInit") << "Feature mask " << mask.mName
-				<< " Feature " << mask_fi.mName
-				<< " Mask: " << mask_fi.mRecommendedLevel
-				<< " Now: " << cur_fi.mRecommendedLevel << LL_ENDL;
-	}
-
-	LL_DEBUGS("RenderInit") << "After applying mask " << mask.mName << std::endl;
-		// Will conditionally call dump only if the above message will be logged, thanks 
-		// to it being wrapped by the LL_DEBUGS and LL_ENDL macros.
-		dump();
-	LL_CONT << LL_ENDL;
-
-	return TRUE;
-}
-
-void LLFeatureList::dump()
-{
-	LL_DEBUGS("RenderInit") << "Feature list: " << mName << LL_ENDL;
-	LL_DEBUGS("RenderInit") << "--------------" << LL_ENDL;
-
-	LLFeatureInfo fi;
-	feature_map_t::iterator feature_it;
-	for (feature_it = mFeatures.begin(); feature_it != mFeatures.end(); ++feature_it)
-	{
-		fi = feature_it->second;
-		LL_DEBUGS("RenderInit") << fi.mName << "\t\t" << fi.mAvailable << ":" << fi.mRecommendedLevel << LL_ENDL;
-	}
-	LL_DEBUGS("RenderInit") << LL_ENDL;
-}
-
-LLFeatureList *LLFeatureManager::findMask(const std::string& name)
-{
-	if (mMaskList.count(name))
-	{
-		return mMaskList[name];
-	}
-
-	return NULL;
-}
-
-BOOL LLFeatureManager::maskFeatures(const std::string& name)
-{
-	LLFeatureList *maskp = findMask(name);
-	if (!maskp)
-	{
- 		LL_DEBUGS("RenderInit") << "Unknown feature mask " << name << LL_ENDL;
-		return FALSE;
-	}
-	LL_INFOS("RenderInit") << "Applying GPU Feature list: " << name << LL_ENDL;
-	return maskList(*maskp);
-}
-
-BOOL LLFeatureManager::loadFeatureTables()
-{
-	// *TODO - if I or anyone else adds something else to the skipped list
-	// make this data driven.  Put it in the feature table and parse it
-	// correctly
-	mSkippedFeatures.insert("RenderAnisotropic");
-	mSkippedFeatures.insert("RenderGamma");
-	mSkippedFeatures.insert("RenderVBOEnable");
-	mSkippedFeatures.insert("RenderFogRatio");
-
-	// first table is install with app
-	std::string app_path = gDirUtilp->getAppRODataDir();
-	app_path += gDirUtilp->getDirDelimiter();
-
-	std::string filename;
-	std::string http_filename; 
-#if LL_WINDOWS
-	std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
-	if (os_string.find("Microsoft Windows XP") == 0)
-	{
-		filename = llformat(FEATURE_TABLE_FILENAME, "_xp");
-		http_filename = llformat(FEATURE_TABLE_VER_FILENAME, "_xp", LLVersionInfo::getVersion().c_str());
-	}
-	else
-	{
-		filename = llformat(FEATURE_TABLE_FILENAME, "");
-		http_filename = llformat(FEATURE_TABLE_VER_FILENAME, "", LLVersionInfo::getVersion().c_str());
-	}
-#else
-	filename = FEATURE_TABLE_FILENAME;
-	http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
-#endif
-
-	app_path += filename;
-
-	
-	// second table is downloaded with HTTP
-	std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
-
-	// use HTTP table if it exists
-	std::string path;
-	if (gDirUtilp->fileExists(http_path))
-	{
-		path = http_path;
-	}
-	else
-	{
-		path = app_path;
-	}
-
-	
-	return parseFeatureTable(path);
-}
-
-
-BOOL LLFeatureManager::parseFeatureTable(std::string filename)
-{
-	llinfos << "Looking for feature table in " << filename << llendl;
-
-	llifstream file;
-	std::string name;
-	U32		version;
-	
-	file.open(filename); 	 /*Flawfinder: ignore*/
-
-	if (!file)
-	{
-		LL_WARNS("RenderInit") << "Unable to open feature table " << filename << LL_ENDL;
-		return FALSE;
-	}
-
-	// Check file version
-	file >> name;
-	file >> version;
-	if (name != "version")
-	{
-		LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL;
-		return FALSE;
-	}
-
-	mTableVersion = version;
-
-	LLFeatureList *flp = NULL;
-	while (file >> name)
-	{
-		char buffer[MAX_STRING];		 /*Flawfinder: ignore*/
-		
-		if (name.substr(0,2) == "//")
-		{
-			// This is a comment.
-			file.getline(buffer, MAX_STRING);
-			continue;
-		}
-
-		if (name == "list")
-		{
-			if (flp)
-			{
-				//flp->dump();
-			}
-			// It's a new mask, create it.
-			file >> name;
-			if (mMaskList.count(name))
-			{
-				LL_ERRS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL;
-			}
-
-			flp = new LLFeatureList(name);
-			mMaskList[name] = flp;
-		}
-		else
-		{
-			if (!flp)
-			{
-				LL_ERRS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
-				return FALSE;
-			}
-			S32 available;
-			F32 recommended;
-			file >> available >> recommended;
-			flp->addFeature(name, available, recommended);
-		}
-	}
-	file.close();
-
-	return TRUE;
-}
-
-void LLFeatureManager::loadGPUClass()
-{
-	// defaults
-	mGPUClass = GPU_CLASS_UNKNOWN;
-	mGPUString = gGLManager.getRawGLString();
-	mGPUSupported = FALSE;
-
-	// first table is in the app dir
-	std::string app_path = gDirUtilp->getAppRODataDir();
-	app_path += gDirUtilp->getDirDelimiter();
-	app_path += GPU_TABLE_FILENAME;
-	
-	// second table is downloaded with HTTP
-	std::string http_filename = llformat(GPU_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
-	std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
-
-	// use HTTP table if it exists
-	std::string path;
-	if (gDirUtilp->fileExists(http_path))
-	{
-		path = http_path;
-	}
-	else
-	{
-		path = app_path;
-	}
-
-	parseGPUTable(path);
-}
-
-	
-void LLFeatureManager::parseGPUTable(std::string filename)
-{
-	llifstream file;
-		
-	file.open(filename);
-
-	if (!file)
-	{
-		LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL;
-		return;
-	}
-
-	std::string rawRenderer = gGLManager.getRawGLString();
-	std::string renderer = rawRenderer;
-	for (std::string::iterator i = renderer.begin(); i != renderer.end(); ++i)
-	{
-		*i = tolower(*i);
-	}
-
-	bool gpuFound;
-	U32 lineNumber;
-	for (gpuFound = false, lineNumber = 0; !gpuFound && !file.eof(); lineNumber++)
-	{
-		char buffer[MAX_STRING];		 /*Flawfinder: ignore*/
-		buffer[0] = 0;
-
-		file.getline(buffer, MAX_STRING);
-		
-		if (strlen(buffer) >= 2 && 	 /*Flawfinder: ignore*/
-			buffer[0] == '/' && 
-			buffer[1] == '/')
-		{
-			// This is a comment.
-			continue;
-		}
-
-		if (strlen(buffer) == 0)	 /*Flawfinder: ignore*/
-		{
-			// This is a blank line
-			continue;
-		}
-
-		// setup the tokenizer
-		std::string buf(buffer);
-		std::string cls, label, expr, supported;
-		boost_tokenizer tokens(buf, boost::char_separator<char>("\t\n"));
-		boost_tokenizer::iterator token_iter = tokens.begin();
-
-		// grab the label, pseudo regular expression, and class
-		if(token_iter != tokens.end())
-		{
-			label = *token_iter++;
-		}
-		if(token_iter != tokens.end())
-		{
-			expr = *token_iter++;
-		}
-		if(token_iter != tokens.end())
-		{
-			cls = *token_iter++;
-		}
-		if(token_iter != tokens.end())
-		{
-			supported = *token_iter++;
-		}
-
-		if (label.empty() || expr.empty() || cls.empty() || supported.empty())
-		{
-			LL_WARNS("RenderInit") << "invald gpu_table.txt:" << lineNumber << ": '" << buffer << "'" << LL_ENDL;
-			continue;
-		}
-	
-		for (U32 i = 0; i < expr.length(); i++)	 /*Flawfinder: ignore*/
-		{
-			expr[i] = tolower(expr[i]);
-		}
-
-		// run the regular expression against the renderer
-		boost::regex re(expr.c_str());
-		if(boost::regex_search(renderer, re))
-		{
-			// if we found it, stop!
-			gpuFound = true;
-			mGPUString = label;
-			mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10);
-			mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10);
-		}
-	}
-	file.close();
-
-	if ( gpuFound )
-	{
-		LL_INFOS("RenderInit") << "GPU '" << rawRenderer << "' recognized as '" << mGPUString << "'" << LL_ENDL;
-		if (!mGPUSupported)
-		{
-			LL_INFOS("RenderInit") << "GPU '" << mGPUString << "' is not supported." << LL_ENDL;
-		}
-	}
-	else
-	{
-		LL_WARNS("RenderInit") << "GPU '" << rawRenderer << "' not recognized" << LL_ENDL;
-	}
-}
-
-// responder saves table into file
-class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder
-{
-public:
-
-	LLHTTPFeatureTableResponder(std::string filename) :
-		mFilename(filename)
-	{
-	}
-
-	
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
-	{
-		if (isGoodStatus(status))
-		{
-			// write to file
-
-			llinfos << "writing feature table to " << mFilename << llendl;
-			
-			S32 file_size = buffer->countAfter(channels.in(), NULL);
-			if (file_size > 0)
-			{
-				// read from buffer
-				U8* copy_buffer = new U8[file_size];
-				buffer->readAfter(channels.in(), NULL, copy_buffer, file_size);
-
-				// write to file
-				LLAPRFile out(mFilename, LL_APR_WB);
-				out.write(copy_buffer, file_size);
-				out.close();
-			}
-		}
-		
-	}
-	
-private:
-	std::string mFilename;
-};
-
-void fetch_feature_table(std::string table)
-{
-	const std::string base       = gSavedSettings.getString("FeatureManagerHTTPTable");
-
-#if LL_WINDOWS
-	std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
-	std::string filename;
-	if (os_string.find("Microsoft Windows XP") == 0)
-	{
-		filename = llformat(table.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
-	}
-	else
-	{
-		filename = llformat(table.c_str(), "", LLVersionInfo::getVersion().c_str());
-	}
-#else
-	const std::string filename   = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
-#endif
-
-	const std::string url        = base + "/" + filename;
-
-	const std::string path       = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
-
-	llinfos << "LLFeatureManager fetching " << url << " into " << path << llendl;
-	
-	LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
-}
-
-void fetch_gpu_table(std::string table)
-{
-	const std::string base       = gSavedSettings.getString("FeatureManagerHTTPTable");
-
-	const std::string filename   = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
-
-	const std::string url        = base + "/" + filename;
-
-	const std::string path       = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
-
-	llinfos << "LLFeatureManager fetching " << url << " into " << path << llendl;
-	
-	LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
-}
-
-// fetch table(s) from a website (S3)
-void LLFeatureManager::fetchHTTPTables()
-{
-	fetch_feature_table(FEATURE_TABLE_VER_FILENAME);
-	fetch_gpu_table(GPU_TABLE_VER_FILENAME);
-}
-
-
-void LLFeatureManager::cleanupFeatureTables()
-{
-	std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
-	mMaskList.clear();
-}
-
-void LLFeatureManager::init()
-{
-	// load the tables
-	loadFeatureTables();
-
-	// get the gpu class
-	loadGPUClass();
-
-	// apply the base masks, so we know if anything is disabled
-	applyBaseMasks();
-}
-
-void LLFeatureManager::applyRecommendedSettings()
-{
-	// apply saved settings
-	// cap the level at 2 (high)
-	S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_2));
-
-	llinfos << "Applying Recommended Features" << llendl;
-
-	setGraphicsLevel(level, false);
-	gSavedSettings.setU32("RenderQualityPerformance", level);
-
-	// now apply the tweaks to draw distance
-	// these are double negatives, because feature masks only work by
-	// downgrading values, so i needed to make a true value go to false
-	// for certain cards, thus the awkward name, "Disregard..."
-	if(!gSavedSettings.getBOOL("Disregard96DefaultDrawDistance"))
-	{
-		gSavedSettings.setF32("RenderFarClip", 96.0f);
-	}
-	else if(!gSavedSettings.getBOOL("Disregard128DefaultDrawDistance"))
-	{
-		gSavedSettings.setF32("RenderFarClip", 128.0f);
-	}
-}
-
-void LLFeatureManager::applyFeatures(bool skipFeatures)
-{
-	// see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	dump();
-#endif
-
-	// scroll through all of these and set their corresponding control value
-	for(feature_map_t::iterator mIt = mFeatures.begin(); 
-		mIt != mFeatures.end(); 
-		++mIt)
-	{
-		// skip features you want to skip
-		// do this for when you don't want to change certain settings
-		if(skipFeatures)
-		{
-			if(mSkippedFeatures.find(mIt->first) != mSkippedFeatures.end())
-			{
-				continue;
-			}
-		}
-
-		// get the control setting
-		LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first);
-		if(ctrl == NULL)
-		{
-			llwarns << "AHHH! Control setting " << mIt->first << " does not exist!" << llendl;
-			continue;
-		}
-
-		// handle all the different types
-		if(ctrl->isType(TYPE_BOOLEAN))
-		{
-			gSavedSettings.setBOOL(mIt->first, (BOOL)getRecommendedValue(mIt->first));
-		}
-		else if (ctrl->isType(TYPE_S32))
-		{
-			gSavedSettings.setS32(mIt->first, (S32)getRecommendedValue(mIt->first));
-		}
-		else if (ctrl->isType(TYPE_U32))
-		{
-			gSavedSettings.setU32(mIt->first, (U32)getRecommendedValue(mIt->first));
-		}
-		else if (ctrl->isType(TYPE_F32))
-		{
-			gSavedSettings.setF32(mIt->first, (F32)getRecommendedValue(mIt->first));
-		}
-		else
-		{
-			llwarns << "AHHH! Control variable is not a numeric type!" << llendl;
-		}
-	}
-}
-
-void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
-{
-	applyBaseMasks();
-
-	switch (level)
-	{
-		case 0:
-			maskFeatures("Low");			
-			break;
-		case 1:
-			maskFeatures("Mid");
-			break;
-		case 2:
-			maskFeatures("High");
-			break;
-		case 3:
-			maskFeatures("Ultra");
-			break;
-		default:
-			maskFeatures("Low");
-			break;
-	}
-
-	applyFeatures(skipFeatures);
-}
-
-void LLFeatureManager::applyBaseMasks()
-{
-	// reapply masks
-	mFeatures.clear();
-
-	LLFeatureList* maskp = findMask("all");
-	if(maskp == NULL)
-	{
-		LL_WARNS("RenderInit") << "AHH! No \"all\" in feature table!" << LL_ENDL;
-		return;
-	}
-
-	mFeatures = maskp->getFeatures();
-
-	// mask class
-	if (mGPUClass >= 0 && mGPUClass < 4)
-	{
-		const char* class_table[] =
-		{
-			"Class0",
-			"Class1",
-			"Class2",
-			"Class3"
-		};
-
-		LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL;
-		maskFeatures(class_table[mGPUClass]);
-	}
-	else
-	{
-		LL_INFOS("RenderInit") << "Setting GPU Class to Unknown" << LL_ENDL;
-		maskFeatures("Unknown");
-	}
-
-	// now all those wacky ones
-	if (!gGLManager.mHasFragmentShader)
-	{
-		maskFeatures("NoPixelShaders");
-	}
-	if (!gGLManager.mHasVertexShader)
-	{
-		maskFeatures("NoVertexShaders");
-	}
-	if (gGLManager.mIsNVIDIA)
-	{
-		maskFeatures("NVIDIA");
-	}
-	if (gGLManager.mIsGF2or4MX)
-	{
-		maskFeatures("GeForce2");
-	}
-	if (gGLManager.mIsATI)
-	{
-		maskFeatures("ATI");
-	}
-	if (gGLManager.mHasATIMemInfo && gGLManager.mVRAM < 256)
-	{
-		maskFeatures("ATIVramLT256");
-	}
-	if (gGLManager.mATIOldDriver)
-	{
-		maskFeatures("ATIOldDriver");
-	}
-	if (gGLManager.mIsGFFX)
-	{
-		maskFeatures("GeForceFX");
-	}
-	if (gGLManager.mIsIntel)
-	{
-		maskFeatures("Intel");
-	}
-	if (gGLManager.mGLVersion < 1.5f)
-	{
-		maskFeatures("OpenGLPre15");
-	}
-	if (gGLManager.mGLVersion < 3.f)
-	{
-		maskFeatures("OpenGLPre30");
-	}
-	if (gGLManager.mNumTextureImageUnits <= 8)
-	{
-		maskFeatures("TexUnit8orLess");
-	}
-
-	// now mask by gpu string
-	// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
-	std::string gpustr = mGPUString;
-	for (std::string::iterator iter = gpustr.begin(); iter != gpustr.end(); ++iter)
-	{
-		if (*iter == ' ')
-		{
-			*iter = '_';
-		}
-	}
-
-	//llinfos << "Masking features from gpu table match: " << gpustr << llendl;
-	maskFeatures(gpustr);
-
-	// now mask cpu type ones
-	if (gSysMemory.getPhysicalMemoryClamped() <= 256*1024*1024)
-	{
-		maskFeatures("RAM256MB");
-	}
-	
-#if LL_SOLARIS && defined(__sparc) 	//  even low MHz SPARCs are fast
-#error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here?
-	if (gSysCPU.getMHz() < 800)
-#else
-	if (gSysCPU.getMHz() < 1100)
-#endif
-	{
-		maskFeatures("CPUSlow");
-	}
-
-	if (isSafe())
-	{
-		maskFeatures("safe");
-	}
-}
+/** 
+ * @file llfeaturemanager.cpp
+ * @brief LLFeatureManager class implementation
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include <iostream>
+#include <fstream>
+
+#include <boost/regex.hpp>
+
+#include "llfeaturemanager.h"
+#include "lldir.h"
+
+#include "llsys.h"
+#include "llgl.h"
+#include "llsecondlifeurls.h"
+
+#include "llappviewer.h"
+#include "llhttpclient.h"
+#include "llnotificationsutil.h"
+#include "llviewercontrol.h"
+#include "llworld.h"
+#include "lldrawpoolterrain.h"
+#include "llviewertexturelist.h"
+#include "llversioninfo.h"
+#include "llwindow.h"
+#include "llui.h"
+#include "llcontrol.h"
+#include "llboost.h"
+#include "llweb.h"
+
+#if LL_WINDOWS
+#include "lldxhardware.h"
+#endif
+
+
+#if LL_DARWIN
+const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_mac.%s.txt";
+#elif LL_LINUX
+const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_linux.%s.txt";
+#elif LL_SOLARIS
+const char FEATURE_TABLE_FILENAME[] = "featuretable_solaris.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_solaris.%s.txt";
+#else
+const char FEATURE_TABLE_FILENAME[] = "featuretable%s.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable%s.%s.txt";
+#endif
+
+const char GPU_TABLE_FILENAME[] = "gpu_table.txt";
+const char GPU_TABLE_VER_FILENAME[] = "gpu_table.%s.txt";
+
+LLFeatureInfo::LLFeatureInfo(const std::string& name, const BOOL available, const F32 level)
+	: mValid(TRUE), mName(name), mAvailable(available), mRecommendedLevel(level)
+{
+}
+
+LLFeatureList::LLFeatureList(const std::string& name)
+	: mName(name)
+{
+}
+
+LLFeatureList::~LLFeatureList()
+{
+}
+
+void LLFeatureList::addFeature(const std::string& name, const BOOL available, const F32 level)
+{
+	if (mFeatures.count(name))
+	{
+		LL_WARNS("RenderInit") << "LLFeatureList::Attempting to add preexisting feature " << name << LL_ENDL;
+	}
+
+	LLFeatureInfo fi(name, available, level);
+	mFeatures[name] = fi;
+}
+
+BOOL LLFeatureList::isFeatureAvailable(const std::string& name)
+{
+	if (mFeatures.count(name))
+	{
+		return mFeatures[name].mAvailable;
+	}
+
+	LL_WARNS("RenderInit") << "Feature " << name << " not on feature list!" << LL_ENDL;
+	
+	// changing this to TRUE so you have to explicitly disable 
+	// something for it to be disabled
+	return TRUE;
+}
+
+F32 LLFeatureList::getRecommendedValue(const std::string& name)
+{
+	if (mFeatures.count(name) && isFeatureAvailable(name))
+	{
+		return mFeatures[name].mRecommendedLevel;
+	}
+
+	LL_WARNS("RenderInit") << "Feature " << name << " not on feature list or not available!" << LL_ENDL;
+	return 0;
+}
+
+BOOL LLFeatureList::maskList(LLFeatureList &mask)
+{
+	//llinfos << "Masking with " << mask.mName << llendl;
+	//
+	// Lookup the specified feature mask, and overlay it on top of the
+	// current feature mask.
+	//
+
+	LLFeatureInfo mask_fi;
+
+	feature_map_t::iterator feature_it;
+	for (feature_it = mask.mFeatures.begin(); feature_it != mask.mFeatures.end(); ++feature_it)
+	{
+		mask_fi = feature_it->second;
+		//
+		// Look for the corresponding feature
+		//
+		if (!mFeatures.count(mask_fi.mName))
+		{
+			LL_WARNS("RenderInit") << "Feature " << mask_fi.mName << " in mask not in top level!" << LL_ENDL;
+			continue;
+		}
+
+		LLFeatureInfo &cur_fi = mFeatures[mask_fi.mName];
+		if (mask_fi.mAvailable && !cur_fi.mAvailable)
+		{
+			LL_WARNS("RenderInit") << "Mask attempting to reenabling disabled feature, ignoring " << cur_fi.mName << LL_ENDL;
+			continue;
+		}
+		cur_fi.mAvailable = mask_fi.mAvailable;
+		cur_fi.mRecommendedLevel = llmin(cur_fi.mRecommendedLevel, mask_fi.mRecommendedLevel);
+		LL_DEBUGS("RenderInit") << "Feature mask " << mask.mName
+				<< " Feature " << mask_fi.mName
+				<< " Mask: " << mask_fi.mRecommendedLevel
+				<< " Now: " << cur_fi.mRecommendedLevel << LL_ENDL;
+	}
+
+	LL_DEBUGS("RenderInit") << "After applying mask " << mask.mName << std::endl;
+		// Will conditionally call dump only if the above message will be logged, thanks 
+		// to it being wrapped by the LL_DEBUGS and LL_ENDL macros.
+		dump();
+	LL_CONT << LL_ENDL;
+
+	return TRUE;
+}
+
+void LLFeatureList::dump()
+{
+	LL_DEBUGS("RenderInit") << "Feature list: " << mName << LL_ENDL;
+	LL_DEBUGS("RenderInit") << "--------------" << LL_ENDL;
+
+	LLFeatureInfo fi;
+	feature_map_t::iterator feature_it;
+	for (feature_it = mFeatures.begin(); feature_it != mFeatures.end(); ++feature_it)
+	{
+		fi = feature_it->second;
+		LL_DEBUGS("RenderInit") << fi.mName << "\t\t" << fi.mAvailable << ":" << fi.mRecommendedLevel << LL_ENDL;
+	}
+	LL_DEBUGS("RenderInit") << LL_ENDL;
+}
+
+LLFeatureList *LLFeatureManager::findMask(const std::string& name)
+{
+	if (mMaskList.count(name))
+	{
+		return mMaskList[name];
+	}
+
+	return NULL;
+}
+
+BOOL LLFeatureManager::maskFeatures(const std::string& name)
+{
+	LLFeatureList *maskp = findMask(name);
+	if (!maskp)
+	{
+ 		LL_DEBUGS("RenderInit") << "Unknown feature mask " << name << LL_ENDL;
+		return FALSE;
+	}
+	LL_INFOS("RenderInit") << "Applying GPU Feature list: " << name << LL_ENDL;
+	return maskList(*maskp);
+}
+
+BOOL LLFeatureManager::loadFeatureTables()
+{
+	// *TODO - if I or anyone else adds something else to the skipped list
+	// make this data driven.  Put it in the feature table and parse it
+	// correctly
+	mSkippedFeatures.insert("RenderAnisotropic");
+	mSkippedFeatures.insert("RenderGamma");
+	mSkippedFeatures.insert("RenderVBOEnable");
+	mSkippedFeatures.insert("RenderFogRatio");
+
+	// first table is install with app
+	std::string app_path = gDirUtilp->getAppRODataDir();
+	app_path += gDirUtilp->getDirDelimiter();
+
+	std::string filename;
+	std::string http_filename; 
+#if LL_WINDOWS
+	std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+	if (os_string.find("Microsoft Windows XP") == 0)
+	{
+		filename = llformat(FEATURE_TABLE_FILENAME, "_xp");
+		http_filename = llformat(FEATURE_TABLE_VER_FILENAME, "_xp", LLVersionInfo::getVersion().c_str());
+	}
+	else
+	{
+		filename = llformat(FEATURE_TABLE_FILENAME, "");
+		http_filename = llformat(FEATURE_TABLE_VER_FILENAME, "", LLVersionInfo::getVersion().c_str());
+	}
+#else
+	filename = FEATURE_TABLE_FILENAME;
+	http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
+#endif
+
+	app_path += filename;
+
+	
+	// second table is downloaded with HTTP
+	std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
+
+	// use HTTP table if it exists
+	std::string path;
+	if (gDirUtilp->fileExists(http_path))
+	{
+		path = http_path;
+	}
+	else
+	{
+		path = app_path;
+	}
+
+	
+	return parseFeatureTable(path);
+}
+
+
+BOOL LLFeatureManager::parseFeatureTable(std::string filename)
+{
+	llinfos << "Looking for feature table in " << filename << llendl;
+
+	llifstream file;
+	std::string name;
+	U32		version;
+	
+	file.open(filename); 	 /*Flawfinder: ignore*/
+
+	if (!file)
+	{
+		LL_WARNS("RenderInit") << "Unable to open feature table " << filename << LL_ENDL;
+		return FALSE;
+	}
+
+	// Check file version
+	file >> name;
+	file >> version;
+	if (name != "version")
+	{
+		LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL;
+		return FALSE;
+	}
+
+	mTableVersion = version;
+
+	LLFeatureList *flp = NULL;
+	while (file >> name)
+	{
+		char buffer[MAX_STRING];		 /*Flawfinder: ignore*/
+		
+		if (name.substr(0,2) == "//")
+		{
+			// This is a comment.
+			file.getline(buffer, MAX_STRING);
+			continue;
+		}
+
+		if (name == "list")
+		{
+			if (flp)
+			{
+				//flp->dump();
+			}
+			// It's a new mask, create it.
+			file >> name;
+			if (mMaskList.count(name))
+			{
+				LL_ERRS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL;
+			}
+
+			flp = new LLFeatureList(name);
+			mMaskList[name] = flp;
+		}
+		else
+		{
+			if (!flp)
+			{
+				LL_ERRS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
+				return FALSE;
+			}
+			S32 available;
+			F32 recommended;
+			file >> available >> recommended;
+			flp->addFeature(name, available, recommended);
+		}
+	}
+	file.close();
+
+	return TRUE;
+}
+
+void LLFeatureManager::loadGPUClass()
+{
+	// defaults
+	mGPUClass = GPU_CLASS_UNKNOWN;
+	mGPUString = gGLManager.getRawGLString();
+	mGPUSupported = FALSE;
+
+	// first table is in the app dir
+	std::string app_path = gDirUtilp->getAppRODataDir();
+	app_path += gDirUtilp->getDirDelimiter();
+	app_path += GPU_TABLE_FILENAME;
+	
+	// second table is downloaded with HTTP
+	std::string http_filename = llformat(GPU_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
+	std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
+
+	// use HTTP table if it exists
+	std::string path;
+	if (gDirUtilp->fileExists(http_path))
+	{
+		path = http_path;
+	}
+	else
+	{
+		path = app_path;
+	}
+
+	parseGPUTable(path);
+}
+
+	
+void LLFeatureManager::parseGPUTable(std::string filename)
+{
+	llifstream file;
+		
+	file.open(filename);
+
+	if (!file)
+	{
+		LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL;
+		return;
+	}
+
+	std::string rawRenderer = gGLManager.getRawGLString();
+	std::string renderer = rawRenderer;
+	for (std::string::iterator i = renderer.begin(); i != renderer.end(); ++i)
+	{
+		*i = tolower(*i);
+	}
+
+	bool gpuFound;
+	U32 lineNumber;
+	for (gpuFound = false, lineNumber = 0; !gpuFound && !file.eof(); lineNumber++)
+	{
+		char buffer[MAX_STRING];		 /*Flawfinder: ignore*/
+		buffer[0] = 0;
+
+		file.getline(buffer, MAX_STRING);
+		
+		if (strlen(buffer) >= 2 && 	 /*Flawfinder: ignore*/
+			buffer[0] == '/' && 
+			buffer[1] == '/')
+		{
+			// This is a comment.
+			continue;
+		}
+
+		if (strlen(buffer) == 0)	 /*Flawfinder: ignore*/
+		{
+			// This is a blank line
+			continue;
+		}
+
+		// setup the tokenizer
+		std::string buf(buffer);
+		std::string cls, label, expr, supported;
+		boost_tokenizer tokens(buf, boost::char_separator<char>("\t\n"));
+		boost_tokenizer::iterator token_iter = tokens.begin();
+
+		// grab the label, pseudo regular expression, and class
+		if(token_iter != tokens.end())
+		{
+			label = *token_iter++;
+		}
+		if(token_iter != tokens.end())
+		{
+			expr = *token_iter++;
+		}
+		if(token_iter != tokens.end())
+		{
+			cls = *token_iter++;
+		}
+		if(token_iter != tokens.end())
+		{
+			supported = *token_iter++;
+		}
+
+		if (label.empty() || expr.empty() || cls.empty() || supported.empty())
+		{
+			LL_WARNS("RenderInit") << "invald gpu_table.txt:" << lineNumber << ": '" << buffer << "'" << LL_ENDL;
+			continue;
+		}
+	
+		for (U32 i = 0; i < expr.length(); i++)	 /*Flawfinder: ignore*/
+		{
+			expr[i] = tolower(expr[i]);
+		}
+
+		// run the regular expression against the renderer
+		boost::regex re(expr.c_str());
+		if(boost::regex_search(renderer, re))
+		{
+			// if we found it, stop!
+			gpuFound = true;
+			mGPUString = label;
+			mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10);
+			mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10);
+		}
+	}
+	file.close();
+
+	if ( gpuFound )
+	{
+		LL_INFOS("RenderInit") << "GPU '" << rawRenderer << "' recognized as '" << mGPUString << "'" << LL_ENDL;
+		if (!mGPUSupported)
+		{
+			LL_INFOS("RenderInit") << "GPU '" << mGPUString << "' is not supported." << LL_ENDL;
+		}
+	}
+	else
+	{
+		LL_WARNS("RenderInit") << "GPU '" << rawRenderer << "' not recognized" << LL_ENDL;
+	}
+}
+
+// responder saves table into file
+class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder
+{
+public:
+
+	LLHTTPFeatureTableResponder(std::string filename) :
+		mFilename(filename)
+	{
+	}
+
+	
+	virtual void completedRaw(U32 status, const std::string& reason,
+							  const LLChannelDescriptors& channels,
+							  const LLIOPipe::buffer_ptr_t& buffer)
+	{
+		if (isGoodStatus(status))
+		{
+			// write to file
+
+			llinfos << "writing feature table to " << mFilename << llendl;
+			
+			S32 file_size = buffer->countAfter(channels.in(), NULL);
+			if (file_size > 0)
+			{
+				// read from buffer
+				U8* copy_buffer = new U8[file_size];
+				buffer->readAfter(channels.in(), NULL, copy_buffer, file_size);
+
+				// write to file
+				LLAPRFile out(mFilename, LL_APR_WB);
+				out.write(copy_buffer, file_size);
+				out.close();
+			}
+		}
+		
+	}
+	
+private:
+	std::string mFilename;
+};
+
+void fetch_feature_table(std::string table)
+{
+	const std::string base       = gSavedSettings.getString("FeatureManagerHTTPTable");
+
+#if LL_WINDOWS
+	std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+	std::string filename;
+	if (os_string.find("Microsoft Windows XP") == 0)
+	{
+		filename = llformat(table.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
+	}
+	else
+	{
+		filename = llformat(table.c_str(), "", LLVersionInfo::getVersion().c_str());
+	}
+#else
+	const std::string filename   = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
+#endif
+
+	const std::string url        = base + "/" + filename;
+
+	const std::string path       = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
+
+	llinfos << "LLFeatureManager fetching " << url << " into " << path << llendl;
+	
+	LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
+}
+
+void fetch_gpu_table(std::string table)
+{
+	const std::string base       = gSavedSettings.getString("FeatureManagerHTTPTable");
+
+	const std::string filename   = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
+
+	const std::string url        = base + "/" + filename;
+
+	const std::string path       = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
+
+	llinfos << "LLFeatureManager fetching " << url << " into " << path << llendl;
+	
+	LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
+}
+
+// fetch table(s) from a website (S3)
+void LLFeatureManager::fetchHTTPTables()
+{
+	fetch_feature_table(FEATURE_TABLE_VER_FILENAME);
+	fetch_gpu_table(GPU_TABLE_VER_FILENAME);
+}
+
+
+void LLFeatureManager::cleanupFeatureTables()
+{
+	std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
+	mMaskList.clear();
+}
+
+void LLFeatureManager::init()
+{
+	// load the tables
+	loadFeatureTables();
+
+	// get the gpu class
+	loadGPUClass();
+
+	// apply the base masks, so we know if anything is disabled
+	applyBaseMasks();
+}
+
+void LLFeatureManager::applyRecommendedSettings()
+{
+	// apply saved settings
+	// cap the level at 2 (high)
+	S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_2));
+
+	llinfos << "Applying Recommended Features" << llendl;
+
+	setGraphicsLevel(level, false);
+	gSavedSettings.setU32("RenderQualityPerformance", level);
+
+	// now apply the tweaks to draw distance
+	// these are double negatives, because feature masks only work by
+	// downgrading values, so i needed to make a true value go to false
+	// for certain cards, thus the awkward name, "Disregard..."
+	if(!gSavedSettings.getBOOL("Disregard96DefaultDrawDistance"))
+	{
+		gSavedSettings.setF32("RenderFarClip", 96.0f);
+	}
+	else if(!gSavedSettings.getBOOL("Disregard128DefaultDrawDistance"))
+	{
+		gSavedSettings.setF32("RenderFarClip", 128.0f);
+	}
+}
+
+void LLFeatureManager::applyFeatures(bool skipFeatures)
+{
+	// see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+	dump();
+#endif
+
+	// scroll through all of these and set their corresponding control value
+	for(feature_map_t::iterator mIt = mFeatures.begin(); 
+		mIt != mFeatures.end(); 
+		++mIt)
+	{
+		// skip features you want to skip
+		// do this for when you don't want to change certain settings
+		if(skipFeatures)
+		{
+			if(mSkippedFeatures.find(mIt->first) != mSkippedFeatures.end())
+			{
+				continue;
+			}
+		}
+
+		// get the control setting
+		LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first);
+		if(ctrl == NULL)
+		{
+			llwarns << "AHHH! Control setting " << mIt->first << " does not exist!" << llendl;
+			continue;
+		}
+
+		// handle all the different types
+		if(ctrl->isType(TYPE_BOOLEAN))
+		{
+			gSavedSettings.setBOOL(mIt->first, (BOOL)getRecommendedValue(mIt->first));
+		}
+		else if (ctrl->isType(TYPE_S32))
+		{
+			gSavedSettings.setS32(mIt->first, (S32)getRecommendedValue(mIt->first));
+		}
+		else if (ctrl->isType(TYPE_U32))
+		{
+			gSavedSettings.setU32(mIt->first, (U32)getRecommendedValue(mIt->first));
+		}
+		else if (ctrl->isType(TYPE_F32))
+		{
+			gSavedSettings.setF32(mIt->first, (F32)getRecommendedValue(mIt->first));
+		}
+		else
+		{
+			llwarns << "AHHH! Control variable is not a numeric type!" << llendl;
+		}
+	}
+}
+
+void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
+{
+	applyBaseMasks();
+
+	switch (level)
+	{
+		case 0:
+			maskFeatures("Low");			
+			break;
+		case 1:
+			maskFeatures("Mid");
+			break;
+		case 2:
+			maskFeatures("High");
+			break;
+		case 3:
+			maskFeatures("Ultra");
+			break;
+		default:
+			maskFeatures("Low");
+			break;
+	}
+
+	applyFeatures(skipFeatures);
+}
+
+void LLFeatureManager::applyBaseMasks()
+{
+	// reapply masks
+	mFeatures.clear();
+
+	LLFeatureList* maskp = findMask("all");
+	if(maskp == NULL)
+	{
+		LL_WARNS("RenderInit") << "AHH! No \"all\" in feature table!" << LL_ENDL;
+		return;
+	}
+
+	mFeatures = maskp->getFeatures();
+
+	// mask class
+	if (mGPUClass >= 0 && mGPUClass < 4)
+	{
+		const char* class_table[] =
+		{
+			"Class0",
+			"Class1",
+			"Class2",
+			"Class3"
+		};
+
+		LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL;
+		maskFeatures(class_table[mGPUClass]);
+	}
+	else
+	{
+		LL_INFOS("RenderInit") << "Setting GPU Class to Unknown" << LL_ENDL;
+		maskFeatures("Unknown");
+	}
+
+	// now all those wacky ones
+	if (!gGLManager.mHasFragmentShader)
+	{
+		maskFeatures("NoPixelShaders");
+	}
+	if (!gGLManager.mHasVertexShader)
+	{
+		maskFeatures("NoVertexShaders");
+	}
+	if (gGLManager.mIsNVIDIA)
+	{
+		maskFeatures("NVIDIA");
+	}
+	if (gGLManager.mIsGF2or4MX)
+	{
+		maskFeatures("GeForce2");
+	}
+	if (gGLManager.mIsATI)
+	{
+		maskFeatures("ATI");
+	}
+	if (gGLManager.mHasATIMemInfo && gGLManager.mVRAM < 256)
+	{
+		maskFeatures("ATIVramLT256");
+	}
+	if (gGLManager.mATIOldDriver)
+	{
+		maskFeatures("ATIOldDriver");
+	}
+	if (gGLManager.mIsGFFX)
+	{
+		maskFeatures("GeForceFX");
+	}
+	if (gGLManager.mIsIntel)
+	{
+		maskFeatures("Intel");
+	}
+	if (gGLManager.mGLVersion < 1.5f)
+	{
+		maskFeatures("OpenGLPre15");
+	}
+	if (gGLManager.mGLVersion < 3.f)
+	{
+		maskFeatures("OpenGLPre30");
+	}
+	if (gGLManager.mNumTextureImageUnits <= 8)
+	{
+		maskFeatures("TexUnit8orLess");
+	}
+
+	// now mask by gpu string
+	// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
+	std::string gpustr = mGPUString;
+	for (std::string::iterator iter = gpustr.begin(); iter != gpustr.end(); ++iter)
+	{
+		if (*iter == ' ')
+		{
+			*iter = '_';
+		}
+	}
+
+	//llinfos << "Masking features from gpu table match: " << gpustr << llendl;
+	maskFeatures(gpustr);
+
+	// now mask cpu type ones
+	if (gSysMemory.getPhysicalMemoryClamped() <= 256*1024*1024)
+	{
+		maskFeatures("RAM256MB");
+	}
+	
+#if LL_SOLARIS && defined(__sparc) 	//  even low MHz SPARCs are fast
+#error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here?
+	if (gSysCPU.getMHz() < 800)
+#else
+	if (gSysCPU.getMHz() < 1100)
+#endif
+	{
+		maskFeatures("CPUSlow");
+	}
+
+	if (isSafe())
+	{
+		maskFeatures("safe");
+	}
+}
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 50b19a4221..610142b5a9 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -461,15 +461,15 @@ void LLFloaterBuyLandUI::updateParcelInfo()
 
 		if (!authorizedBuyer.isNull() && buyer != authorizedBuyer)
 		{
-			// Maybe the parcel is set for sale to a group we are in.
-			bool authorized_group =
-				gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_DEED)
-				&& gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_SET_SALE_INFO);
-
-			if (!authorized_group)
-			{
-				mCannotBuyReason = getString("set_to_sell_to_other");
-				return;
+			// Maybe the parcel is set for sale to a group we are in.
+			bool authorized_group =
+				gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_DEED)
+				&& gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_SET_SALE_INFO);
+
+			if (!authorized_group)
+			{
+				mCannotBuyReason = getString("set_to_sell_to_other");
+				return;
 			}
 		}
 	}
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 74f48907d2..34a92cd0ac 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -1,1999 +1,1999 @@
-/** 
- * @file llpanelobject.cpp
- * @brief Object editing (position, scale, etc.) in the tools floater
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-// file include
-#include "llpanelobject.h"
-
-// linden library includes
-#include "lleconomy.h"
-#include "llerror.h"
-#include "llfontgl.h"
-#include "llpermissionsflags.h"
-#include "llstring.h"
-#include "llvolume.h"
-#include "m3math.h"
-
-// project includes
-#include "llagent.h"
-#include "llbutton.h"
-#include "llcheckboxctrl.h"
-#include "llcolorswatch.h"
-#include "llcombobox.h"
-#include "llfocusmgr.h"
-#include "llmanipscale.h"
-#include "llpreviewscript.h"
-#include "llresmgr.h"
-#include "llselectmgr.h"
-#include "llspinctrl.h"
-#include "lltexturectrl.h"
-#include "lltextbox.h"
-#include "lltool.h"
-#include "lltoolcomp.h"
-#include "lltoolmgr.h"
-#include "llui.h"
-#include "llviewerobject.h"
-#include "llviewerregion.h"
-#include "llviewerwindow.h"
-#include "llvovolume.h"
-#include "llworld.h"
-#include "pipeline.h"
-#include "llviewercontrol.h"
-#include "lluictrlfactory.h"
-//#include "llfirstuse.h"
-
-#include "lldrawpool.h"
-
-//
-// Constants
-//
-enum {
-	MI_BOX,
-	MI_CYLINDER,
-	MI_PRISM,
-	MI_SPHERE,
-	MI_TORUS,
-	MI_TUBE,
-	MI_RING,
-	MI_SCULPT,
-	MI_NONE,
-	MI_VOLUME_COUNT
-};
-
-enum {
-	MI_HOLE_SAME,
-	MI_HOLE_CIRCLE,
-	MI_HOLE_SQUARE,
-	MI_HOLE_TRIANGLE,
-	MI_HOLE_COUNT
-};
-
-//static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright");
-
-BOOL	LLPanelObject::postBuild()
-{
-	setMouseOpaque(FALSE);
-	
-	//--------------------------------------------------------
-	// Top
-	//--------------------------------------------------------
-	
-	// Lock checkbox
-	mCheckLock = getChild<LLCheckBoxCtrl>("checkbox locked");
-	childSetCommitCallback("checkbox locked",onCommitLock,this);
-
-	// Physical checkbox
-	mCheckPhysics = getChild<LLCheckBoxCtrl>("Physical Checkbox Ctrl");
-	childSetCommitCallback("Physical Checkbox Ctrl",onCommitPhysics,this);
-
-	// Temporary checkbox
-	mCheckTemporary = getChild<LLCheckBoxCtrl>("Temporary Checkbox Ctrl");
-	childSetCommitCallback("Temporary Checkbox Ctrl",onCommitTemporary,this);
-
-	// Phantom checkbox
-	mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl");
-	childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this);
-       
-
-	// Position
-	mLabelPosition = getChild<LLTextBox>("label position");
-	mCtrlPosX = getChild<LLSpinCtrl>("Pos X");
-	childSetCommitCallback("Pos X",onCommitPosition,this);
-	mCtrlPosY = getChild<LLSpinCtrl>("Pos Y");
-	childSetCommitCallback("Pos Y",onCommitPosition,this);
-	mCtrlPosZ = getChild<LLSpinCtrl>("Pos Z");
-	childSetCommitCallback("Pos Z",onCommitPosition,this);
-
-	// Scale
-	mLabelSize = getChild<LLTextBox>("label size");
-	mCtrlScaleX = getChild<LLSpinCtrl>("Scale X");
-	childSetCommitCallback("Scale X",onCommitScale,this);
-
-	// Scale Y
-	mCtrlScaleY = getChild<LLSpinCtrl>("Scale Y");
-	childSetCommitCallback("Scale Y",onCommitScale,this);
-
-	// Scale Z
-	mCtrlScaleZ = getChild<LLSpinCtrl>("Scale Z");
-	childSetCommitCallback("Scale Z",onCommitScale,this);
-
-	// Rotation
-	mLabelRotation = getChild<LLTextBox>("label rotation");
-	mCtrlRotX = getChild<LLSpinCtrl>("Rot X");
-	childSetCommitCallback("Rot X",onCommitRotation,this);
-	mCtrlRotY = getChild<LLSpinCtrl>("Rot Y");
-	childSetCommitCallback("Rot Y",onCommitRotation,this);
-	mCtrlRotZ = getChild<LLSpinCtrl>("Rot Z");
-	childSetCommitCallback("Rot Z",onCommitRotation,this);
-
-	//--------------------------------------------------------
-		
-	// Base Type
-	mComboBaseType = getChild<LLComboBox>("comboBaseType");
-	childSetCommitCallback("comboBaseType",onCommitParametric,this);
-
-	// Cut
-	mLabelCut = getChild<LLTextBox>("text cut");
-	mSpinCutBegin = getChild<LLSpinCtrl>("cut begin");
-	childSetCommitCallback("cut begin",onCommitParametric,this);
-	mSpinCutBegin->setValidateBeforeCommit( precommitValidate );
-	mSpinCutEnd = getChild<LLSpinCtrl>("cut end");
-	childSetCommitCallback("cut end",onCommitParametric,this);
-	mSpinCutEnd->setValidateBeforeCommit( &precommitValidate );
-
-	// Hollow / Skew
-	mLabelHollow = getChild<LLTextBox>("text hollow");
-	mLabelSkew = getChild<LLTextBox>("text skew");
-	mSpinHollow = getChild<LLSpinCtrl>("Scale 1");
-	childSetCommitCallback("Scale 1",onCommitParametric,this);
-	mSpinHollow->setValidateBeforeCommit( &precommitValidate );
-	mSpinSkew = getChild<LLSpinCtrl>("Skew");
-	childSetCommitCallback("Skew",onCommitParametric,this);
-	mSpinSkew->setValidateBeforeCommit( &precommitValidate );
-	mLabelHoleType = getChild<LLTextBox>("Hollow Shape");
-
-	// Hole Type
-	mComboHoleType = getChild<LLComboBox>("hole");
-	childSetCommitCallback("hole",onCommitParametric,this);
-
-	// Twist
-	mLabelTwist = getChild<LLTextBox>("text twist");
-	mSpinTwistBegin = getChild<LLSpinCtrl>("Twist Begin");
-	childSetCommitCallback("Twist Begin",onCommitParametric,this);
-	mSpinTwistBegin->setValidateBeforeCommit( precommitValidate );
-	mSpinTwist = getChild<LLSpinCtrl>("Twist End");
-	childSetCommitCallback("Twist End",onCommitParametric,this);
-	mSpinTwist->setValidateBeforeCommit( &precommitValidate );
-
-	// Scale
-	mSpinScaleX = getChild<LLSpinCtrl>("Taper Scale X");
-	childSetCommitCallback("Taper Scale X",onCommitParametric,this);
-	mSpinScaleX->setValidateBeforeCommit( &precommitValidate );
-	mSpinScaleY = getChild<LLSpinCtrl>("Taper Scale Y");
-	childSetCommitCallback("Taper Scale Y",onCommitParametric,this);
-	mSpinScaleY->setValidateBeforeCommit( &precommitValidate );
-
-	// Shear
-	mLabelShear = getChild<LLTextBox>("text topshear");
-	mSpinShearX = getChild<LLSpinCtrl>("Shear X");
-	childSetCommitCallback("Shear X",onCommitParametric,this);
-	mSpinShearX->setValidateBeforeCommit( &precommitValidate );
-	mSpinShearY = getChild<LLSpinCtrl>("Shear Y");
-	childSetCommitCallback("Shear Y",onCommitParametric,this);
-	mSpinShearY->setValidateBeforeCommit( &precommitValidate );
-
-	// Path / Profile
-	mCtrlPathBegin = getChild<LLSpinCtrl>("Path Limit Begin");
-	childSetCommitCallback("Path Limit Begin",onCommitParametric,this);
-	mCtrlPathBegin->setValidateBeforeCommit( &precommitValidate );
-	mCtrlPathEnd = getChild<LLSpinCtrl>("Path Limit End");
-	childSetCommitCallback("Path Limit End",onCommitParametric,this);
-	mCtrlPathEnd->setValidateBeforeCommit( &precommitValidate );
-
-	// Taper
-	mLabelTaper = getChild<LLTextBox>("text taper2");
-	mSpinTaperX = getChild<LLSpinCtrl>("Taper X");
-	childSetCommitCallback("Taper X",onCommitParametric,this);
-	mSpinTaperX->setValidateBeforeCommit( precommitValidate );
-	mSpinTaperY = getChild<LLSpinCtrl>("Taper Y");
-	childSetCommitCallback("Taper Y",onCommitParametric,this);
-	mSpinTaperY->setValidateBeforeCommit( precommitValidate );
-	
-	// Radius Offset / Revolutions
-	mLabelRadiusOffset = getChild<LLTextBox>("text radius delta");
-	mLabelRevolutions = getChild<LLTextBox>("text revolutions");
-	mSpinRadiusOffset = getChild<LLSpinCtrl>("Radius Offset");
-	childSetCommitCallback("Radius Offset",onCommitParametric,this);
-	mSpinRadiusOffset->setValidateBeforeCommit( &precommitValidate );
-	mSpinRevolutions = getChild<LLSpinCtrl>("Revolutions");
-	childSetCommitCallback("Revolutions",onCommitParametric,this);
-	mSpinRevolutions->setValidateBeforeCommit( &precommitValidate );
-
-	// Sculpt
-	mCtrlSculptTexture = getChild<LLTextureCtrl>("sculpt texture control");
-	if (mCtrlSculptTexture)
-	{
-		mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE));
-		mCtrlSculptTexture->setCommitCallback( boost::bind(&LLPanelObject::onCommitSculpt, this, _2 ));
-		mCtrlSculptTexture->setOnCancelCallback( boost::bind(&LLPanelObject::onCancelSculpt, this, _2 ));
-		mCtrlSculptTexture->setOnSelectCallback( boost::bind(&LLPanelObject::onSelectSculpt, this, _2 ));
-		mCtrlSculptTexture->setDropCallback( boost::bind(&LLPanelObject::onDropSculpt, this, _2 ));
-		// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
-		mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-		// Allow any texture to be used during non-immediate mode.
-		mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
-		LLAggregatePermissions texture_perms;
-		if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
-		{
-			BOOL can_copy =
-				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
-				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
-			BOOL can_transfer =
-				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
-				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
-			mCtrlSculptTexture->setCanApplyImmediately(can_copy && can_transfer);
-		}
-		else
-		{
-			mCtrlSculptTexture->setCanApplyImmediately(FALSE);
-		}
-	}
-
-	mLabelSculptType = getChild<LLTextBox>("label sculpt type");
-	mCtrlSculptType = getChild<LLComboBox>("sculpt type control");
-	childSetCommitCallback("sculpt type control", onCommitSculptType, this);
-	mCtrlSculptMirror = getChild<LLCheckBoxCtrl>("sculpt mirror control");
-	childSetCommitCallback("sculpt mirror control", onCommitSculptType, this);
-	mCtrlSculptInvert = getChild<LLCheckBoxCtrl>("sculpt invert control");
-	childSetCommitCallback("sculpt invert control", onCommitSculptType, this);
-	
-	// Start with everyone disabled
-	clearCtrls();
-
-	return TRUE;
-}
-
-LLPanelObject::LLPanelObject()
-:	LLPanel(),
-	mIsPhysical(FALSE),
-	mIsTemporary(FALSE),
-	mIsPhantom(FALSE),
-	mCastShadows(TRUE),
-	mSelectedType(MI_BOX),
-	mSculptTextureRevert(LLUUID::null),
-	mSculptTypeRevert(0)
-{
-}
-
-
-LLPanelObject::~LLPanelObject()
-{
-	// Children all cleaned up by default view destructor.
-}
-
-void LLPanelObject::getState( )
-{
-	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
-	LLViewerObject* root_objectp = objectp;
-	if(!objectp)
-	{
-		objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
-		// *FIX: shouldn't we just keep the child?
-		if (objectp)
-		{
-			LLViewerObject* parentp = objectp->getRootEdit();
-
-			if (parentp)
-			{
-				root_objectp = parentp;
-			}
-			else
-			{
-				root_objectp = objectp;
-			}
-		}
-	}
-
-	LLVOVolume *volobjp = NULL;
-	if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
-	{
-		volobjp = (LLVOVolume *)objectp;
-	}
-
-	if( !objectp )
-	{
-		//forfeit focus
-		if (gFocusMgr.childHasKeyboardFocus(this))
-		{
-			gFocusMgr.setKeyboardFocus(NULL);
-		}
-
-		// Disable all text input fields
-		clearCtrls();
-		return;
-	}
-
-	// can move or rotate only linked group with move permissions, or sub-object with move and modify perms
-	BOOL enable_move	= objectp->permMove() && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
-	BOOL enable_scale	= objectp->permMove() && objectp->permModify();
-	BOOL enable_rotate	= objectp->permMove() && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
-
-	S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
-	BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
-						 && (selected_count == 1);
-
-	if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 1)
-	{
-		enable_move = FALSE;
-		enable_scale = FALSE;
-		enable_rotate = FALSE;
-	}
-
-	LLVector3 vec;
-	if (enable_move)
-	{
-		vec = objectp->getPositionEdit();
-		mCtrlPosX->set( vec.mV[VX] );
-		mCtrlPosY->set( vec.mV[VY] );
-		mCtrlPosZ->set( vec.mV[VZ] );
-	}
-	else
-	{
-		mCtrlPosX->clear();
-		mCtrlPosY->clear();
-		mCtrlPosZ->clear();
-	}
-
-
-	mLabelPosition->setEnabled( enable_move );
-	mCtrlPosX->setEnabled(enable_move);
-	mCtrlPosY->setEnabled(enable_move);
-	mCtrlPosZ->setEnabled(enable_move);
-
-	if (enable_scale)
-	{
-		vec = objectp->getScale();
-		mCtrlScaleX->set( vec.mV[VX] );
-		mCtrlScaleY->set( vec.mV[VY] );
-		mCtrlScaleZ->set( vec.mV[VZ] );
-	}
-	else
-	{
-		mCtrlScaleX->clear();
-		mCtrlScaleY->clear();
-		mCtrlScaleZ->clear();
-	}
-
-	mLabelSize->setEnabled( enable_scale );
-	mCtrlScaleX->setEnabled( enable_scale );
-	mCtrlScaleY->setEnabled( enable_scale );
-	mCtrlScaleZ->setEnabled( enable_scale );
-
-	LLQuaternion object_rot = objectp->getRotationEdit();
-	object_rot.getEulerAngles(&(mCurEulerDegrees.mV[VX]), &(mCurEulerDegrees.mV[VY]), &(mCurEulerDegrees.mV[VZ]));
-	mCurEulerDegrees *= RAD_TO_DEG;
-	mCurEulerDegrees.mV[VX] = fmod(llround(mCurEulerDegrees.mV[VX], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
-	mCurEulerDegrees.mV[VY] = fmod(llround(mCurEulerDegrees.mV[VY], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
-	mCurEulerDegrees.mV[VZ] = fmod(llround(mCurEulerDegrees.mV[VZ], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
-
-	if (enable_rotate)
-	{
-		mCtrlRotX->set( mCurEulerDegrees.mV[VX] );
-		mCtrlRotY->set( mCurEulerDegrees.mV[VY] );
-		mCtrlRotZ->set( mCurEulerDegrees.mV[VZ] );
-	}
-	else
-	{
-		mCtrlRotX->clear();
-		mCtrlRotY->clear();
-		mCtrlRotZ->clear();
-	}
-
-	mLabelRotation->setEnabled( enable_rotate );
-	mCtrlRotX->setEnabled( enable_rotate );
-	mCtrlRotY->setEnabled( enable_rotate );
-	mCtrlRotZ->setEnabled( enable_rotate );
-
-	BOOL owners_identical;
-	LLUUID owner_id;
-	std::string owner_name;
-	owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
-
-	// BUG? Check for all objects being editable?
-	S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
-	BOOL editable = root_objectp->permModify();
-
-	// Select Single Message
-	getChildView("select_single")->setVisible( FALSE);
-	getChildView("edit_object")->setVisible( FALSE);
-	if (!editable || single_volume || selected_count <= 1)
-	{
-		getChildView("edit_object")->setVisible( TRUE);
-		getChildView("edit_object")->setEnabled(TRUE);
-	}
-	else
-	{
-		getChildView("select_single")->setVisible( TRUE);
-		getChildView("select_single")->setEnabled(TRUE);
-	}
-	// Lock checkbox - only modifiable if you own the object.
-	BOOL self_owned = (gAgent.getID() == owner_id);
-	mCheckLock->setEnabled( roots_selected > 0 && self_owned );
-
-	// More lock and debit checkbox - get the values
-	BOOL valid;
-	U32 owner_mask_on;
-	U32 owner_mask_off;
-	valid = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER, &owner_mask_on, &owner_mask_off);
-
-	if(valid)
-	{
-		if(owner_mask_on & PERM_MOVE)
-		{
-			// owner can move, so not locked
-			mCheckLock->set(FALSE);
-			mCheckLock->setTentative(FALSE);
-		}
-		else if(owner_mask_off & PERM_MOVE)
-		{
-			// owner can't move, so locked
-			mCheckLock->set(TRUE);
-			mCheckLock->setTentative(FALSE);
-		}
-		else
-		{
-			// some locked, some not locked
-			mCheckLock->set(FALSE);
-			mCheckLock->setTentative(TRUE);
-		}
-	}
-
-	BOOL is_flexible = volobjp && volobjp->isFlexible();
-
-	// Physics checkbox
-	mIsPhysical = root_objectp->usePhysics();
-	mCheckPhysics->set( mIsPhysical );
-	mCheckPhysics->setEnabled( roots_selected>0 
-								&& (editable || gAgent.isGodlike()) 
-								&& !is_flexible);
-
-	mIsTemporary = root_objectp->flagTemporaryOnRez();
-	mCheckTemporary->set( mIsTemporary );
-	mCheckTemporary->setEnabled( roots_selected>0 && editable );
-
-	mIsPhantom = root_objectp->flagPhantom();
-	mCheckPhantom->set( mIsPhantom );
-	mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible );
-
-       
-#if 0 // 1.9.2
-	mCastShadows = root_objectp->flagCastShadows();
-	mCheckCastShadows->set( mCastShadows );
-	mCheckCastShadows->setEnabled( roots_selected==1 && editable );
-#endif
-	
-	//----------------------------------------------------------------------------
-
-	S32 selected_item	= MI_BOX;
-	S32	selected_hole	= MI_HOLE_SAME;
-	BOOL enabled = FALSE;
-	BOOL hole_enabled = FALSE;
-	F32 scale_x=1.f, scale_y=1.f;
-	BOOL isMesh = FALSE;
-	
-	if( !objectp || !objectp->getVolume() || !editable || !single_volume)
-	{
-		// Clear out all geometry fields.
-		mComboBaseType->clear();
-		mSpinHollow->clear();
-		mSpinCutBegin->clear();
-		mSpinCutEnd->clear();
-		mCtrlPathBegin->clear();
-		mCtrlPathEnd->clear();
-		mSpinScaleX->clear();
-		mSpinScaleY->clear();
-		mSpinTwist->clear();
-		mSpinTwistBegin->clear();
-		mComboHoleType->clear();
-		mSpinShearX->clear();
-		mSpinShearY->clear();
-		mSpinTaperX->clear();
-		mSpinTaperY->clear();
-		mSpinRadiusOffset->clear();
-		mSpinRevolutions->clear();
-		mSpinSkew->clear();
-		
-		mSelectedType = MI_NONE;
-	}
-	else
-	{
-		// Only allowed to change these parameters for objects
-		// that you have permissions on AND are not attachments.
-		enabled = root_objectp->permModify();
-		
-		// Volume type
-		const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
-		U8 path = volume_params.getPathParams().getCurveType();
-		U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
-		U8 profile	= profile_and_hole & LL_PCODE_PROFILE_MASK;
-		U8 hole		= profile_and_hole & LL_PCODE_HOLE_MASK;
-		
-		// Scale goes first so we can differentiate between a sphere and a torus,
-		// which have the same profile and path types.
-
-		// Scale
-		scale_x = volume_params.getRatioX();
-		scale_y = volume_params.getRatioY();
-
-		BOOL linear_path = (path == LL_PCODE_PATH_LINE) || (path == LL_PCODE_PATH_FLEXIBLE);
-		if ( linear_path && profile == LL_PCODE_PROFILE_CIRCLE )
-		{
-			selected_item = MI_CYLINDER;
-		}
-		else if ( linear_path && profile == LL_PCODE_PROFILE_SQUARE )
-		{
-			selected_item = MI_BOX;
-		}
-		else if ( linear_path && profile == LL_PCODE_PROFILE_ISOTRI )
-		{
-			selected_item = MI_PRISM;
-		}
-		else if ( linear_path && profile == LL_PCODE_PROFILE_EQUALTRI )
-		{
-			selected_item = MI_PRISM;
-		}
-		else if ( linear_path && profile == LL_PCODE_PROFILE_RIGHTTRI )
-		{
-			selected_item = MI_PRISM;
-		}
-		else if (path == LL_PCODE_PATH_FLEXIBLE) // shouldn't happen
-		{
-			selected_item = MI_CYLINDER; // reasonable default
-		}
-		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y > 0.75f)
-		{
-			selected_item = MI_SPHERE;
-		}
-		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y <= 0.75f)
-		{
-			selected_item = MI_TORUS;
-		}
-		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE_HALF)
-		{
-			selected_item = MI_SPHERE;
-		}
-		else if ( path == LL_PCODE_PATH_CIRCLE2 && profile == LL_PCODE_PROFILE_CIRCLE )
-		{
-			// Spirals aren't supported.  Make it into a sphere.  JC
-			selected_item = MI_SPHERE;
-		}
-		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_EQUALTRI )
-		{
-			selected_item = MI_RING;
-		}
-		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_SQUARE && scale_y <= 0.75f)
-		{
-			selected_item = MI_TUBE;
-		}
-		else
-		{
-			llinfos << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << llendl;
-			selected_item = MI_BOX;
-		}
-
-
-		if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
-		{
-			selected_item = MI_SCULPT;
-			//LLFirstUse::useSculptedPrim();
-		}
-
-		
-		mComboBaseType	->setCurrentByIndex( selected_item );
-		mSelectedType = selected_item;
-		
-		// Grab S path
-		F32 begin_s	= volume_params.getBeginS();
-		F32 end_s	= volume_params.getEndS();
-
-		// Compute cut and advanced cut from S and T
-		F32 begin_t = volume_params.getBeginT();
-		F32 end_t	= volume_params.getEndT();
-
-		// Hollowness
-		F32 hollow = volume_params.getHollow();
-		mSpinHollow->set( 100.f * hollow );
-
-		// All hollow objects allow a shape to be selected.
-		if (hollow > 0.f)
-		{
-			switch (hole)
-			{
-			case LL_PCODE_HOLE_CIRCLE:
-				selected_hole = MI_HOLE_CIRCLE;
-				break;
-			case LL_PCODE_HOLE_SQUARE:
-				selected_hole = MI_HOLE_SQUARE;
-				break;
-			case LL_PCODE_HOLE_TRIANGLE:
-				selected_hole = MI_HOLE_TRIANGLE;
-				break;
-			case LL_PCODE_HOLE_SAME:
-			default:
-				selected_hole = MI_HOLE_SAME;
-				break;
-			}
-			mComboHoleType->setCurrentByIndex( selected_hole );
-			hole_enabled = enabled;
-		}
-		else
-		{
-			mComboHoleType->setCurrentByIndex( MI_HOLE_SAME );
-			hole_enabled = FALSE;
-		}
-
-		// Cut interpretation varies based on base object type
-		F32 cut_begin, cut_end, adv_cut_begin, adv_cut_end;
-
-		if ( selected_item == MI_SPHERE || selected_item == MI_TORUS || 
-			 selected_item == MI_TUBE   || selected_item == MI_RING )
-		{
-			cut_begin		= begin_t;
-			cut_end			= end_t;
-			adv_cut_begin	= begin_s;
-			adv_cut_end		= end_s;
-		}
-		else
-		{
-			cut_begin       = begin_s;
-			cut_end         = end_s;
-			adv_cut_begin   = begin_t;
-			adv_cut_end     = end_t;
-		}
-
-		mSpinCutBegin	->set( cut_begin );
-		mSpinCutEnd		->set( cut_end );
-		mCtrlPathBegin	->set( adv_cut_begin );
-		mCtrlPathEnd	->set( adv_cut_end );
-
-		// Twist
-		F32 twist		= volume_params.getTwist();
-		F32 twist_begin = volume_params.getTwistBegin();
-		// Check the path type for conversion.
-		if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
-		{
-			twist		*= OBJECT_TWIST_LINEAR_MAX;
-			twist_begin	*= OBJECT_TWIST_LINEAR_MAX;
-		}
-		else
-		{
-			twist		*= OBJECT_TWIST_MAX;
-			twist_begin	*= OBJECT_TWIST_MAX;
-		}
-
-		mSpinTwist		->set( twist );
-		mSpinTwistBegin	->set( twist_begin );
-
-		// Shear
-		F32 shear_x = volume_params.getShearX();
-		F32 shear_y = volume_params.getShearY();
-		mSpinShearX->set( shear_x );
-		mSpinShearY->set( shear_y );
-
-		// Taper
-		F32 taper_x	= volume_params.getTaperX();
-		F32 taper_y = volume_params.getTaperY();
-		mSpinTaperX->set( taper_x );
-		mSpinTaperY->set( taper_y );
-
-		// Radius offset.
-		F32 radius_offset = volume_params.getRadiusOffset();
-		// Limit radius offset, based on taper and hole size y.
-		F32 radius_mag = fabs(radius_offset);
-		F32 hole_y_mag = fabs(scale_y);
-		F32 taper_y_mag  = fabs(taper_y);
-		// Check to see if the taper effects us.
-		if ( (radius_offset > 0.f && taper_y < 0.f) ||
-			 (radius_offset < 0.f && taper_y > 0.f) )
-		{
-			// The taper does not help increase the radius offset range.
-			taper_y_mag = 0.f;
-		}
-		F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
-		// Enforce the maximum magnitude.
-		if (radius_mag > max_radius_mag)
-		{
-			// Check radius offset sign.
-			if (radius_offset < 0.f)
-			{
-				radius_offset = -max_radius_mag;
-			}
-			else
-			{
-				radius_offset = max_radius_mag;
-			}
-		}
-		mSpinRadiusOffset->set( radius_offset);
-
-		// Revolutions
-		F32 revolutions = volume_params.getRevolutions();
-		mSpinRevolutions->set( revolutions );
-		
-		// Skew
-		F32 skew	= volume_params.getSkew();
-		// Limit skew, based on revolutions hole size x.
-		F32 skew_mag= fabs(skew);
-		F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
-		// Discontinuity; A revolution of 1 allows skews below 0.5.
-		if ( fabs(revolutions - 1.0f) < 0.001)
-			min_skew_mag = 0.0f;
-
-		// Clip skew.
-		if (skew_mag < min_skew_mag)
-		{
-			// Check skew sign.
-			if (skew < 0.0f)
-			{
-				skew = -min_skew_mag;
-			}
-			else 
-			{
-				skew = min_skew_mag;
-			}
-		}
-		mSpinSkew->set( skew );
-	}
-	
-	// Compute control visibility, label names, and twist range.
-	// Start with defaults.
-	BOOL cut_visible                = TRUE;
-	BOOL hollow_visible             = TRUE;
-	BOOL top_size_x_visible			= TRUE;
-	BOOL top_size_y_visible			= TRUE;
-	BOOL top_shear_x_visible		= TRUE;
-	BOOL top_shear_y_visible		= TRUE;
-	BOOL twist_visible				= TRUE;
-	BOOL advanced_cut_visible		= FALSE;
-	BOOL taper_visible				= FALSE;
-	BOOL skew_visible				= FALSE;
-	BOOL radius_offset_visible		= FALSE;
-	BOOL revolutions_visible		= FALSE;
-	BOOL sculpt_texture_visible     = FALSE;
-	F32	 twist_min					= OBJECT_TWIST_LINEAR_MIN;
-	F32	 twist_max					= OBJECT_TWIST_LINEAR_MAX;
-	F32	 twist_inc					= OBJECT_TWIST_LINEAR_INC;
-
-	BOOL advanced_is_dimple = FALSE;
-	BOOL advanced_is_slice = FALSE;
-	BOOL size_is_hole = FALSE;
-
-	// Tune based on overall volume type
-	switch (selected_item)
-	{
-	case MI_SPHERE:
-		top_size_x_visible		= FALSE;
-		top_size_y_visible		= FALSE;
-		top_shear_x_visible		= FALSE;
-		top_shear_y_visible		= FALSE;
-		//twist_visible			= FALSE;
-		advanced_cut_visible	= TRUE;
-		advanced_is_dimple		= TRUE;
-		twist_min				= OBJECT_TWIST_MIN;
-		twist_max				= OBJECT_TWIST_MAX;
-		twist_inc				= OBJECT_TWIST_INC;
-		break;
-
-	case MI_TORUS:
-	case MI_TUBE:	
-	case MI_RING:
-		//top_size_x_visible		= FALSE;
-		//top_size_y_visible		= FALSE;
-	  	size_is_hole 			= TRUE;
-		skew_visible			= TRUE;
-		advanced_cut_visible	= TRUE;
-		taper_visible			= TRUE;
-		radius_offset_visible	= TRUE;
-		revolutions_visible		= TRUE;
-		twist_min				= OBJECT_TWIST_MIN;
-		twist_max				= OBJECT_TWIST_MAX;
-		twist_inc				= OBJECT_TWIST_INC;
-
-		break;
-
-	case MI_SCULPT:
-		cut_visible             = FALSE;
-		hollow_visible          = FALSE;
-		twist_visible           = FALSE;
-		top_size_x_visible      = FALSE;
-		top_size_y_visible      = FALSE;
-		top_shear_x_visible     = FALSE;
-		top_shear_y_visible     = FALSE;
-		skew_visible            = FALSE;
-		advanced_cut_visible    = FALSE;
-		taper_visible           = FALSE;
-		radius_offset_visible   = FALSE;
-		revolutions_visible     = FALSE;
-		sculpt_texture_visible  = TRUE;
-
-		break;
-		
-	case MI_BOX:
-		advanced_cut_visible	= TRUE;
-		advanced_is_slice		= TRUE;
-		break;
-
-	case MI_CYLINDER:
-		advanced_cut_visible	= TRUE;
-		advanced_is_slice		= TRUE;
-		break;
-
-	case MI_PRISM:
-		advanced_cut_visible	= TRUE;
-		advanced_is_slice		= TRUE;
-		break;
-
-	default:
-		break;
-	}
-
-	// Check if we need to change top size/hole size params.
-	switch (selected_item)
-	{
-	case MI_SPHERE:
-	case MI_TORUS:
-	case MI_TUBE:
-	case MI_RING:
-		mSpinScaleX->set( scale_x );
-		mSpinScaleY->set( scale_y );
-		mSpinScaleX->setMinValue(OBJECT_MIN_HOLE_SIZE);
-		mSpinScaleX->setMaxValue(OBJECT_MAX_HOLE_SIZE_X);
-		mSpinScaleY->setMinValue(OBJECT_MIN_HOLE_SIZE);
-		mSpinScaleY->setMaxValue(OBJECT_MAX_HOLE_SIZE_Y);
-		break;
-	default:
-		if (editable)
-		{
-			mSpinScaleX->set( 1.f - scale_x );
-			mSpinScaleY->set( 1.f - scale_y );
-			mSpinScaleX->setMinValue(-1.f);
-			mSpinScaleX->setMaxValue(1.f);
-			mSpinScaleY->setMinValue(-1.f);
-			mSpinScaleY->setMaxValue(1.f);
-		}
-		break;
-	}
-
-	// Check if we need to limit the hollow based on the hole type.
-	if (  selected_hole == MI_HOLE_SQUARE && 
-		  ( selected_item == MI_CYLINDER || selected_item == MI_TORUS ||
-		    selected_item == MI_PRISM    || selected_item == MI_RING  ||
-			selected_item == MI_SPHERE ) )
-	{
-		mSpinHollow->setMinValue(0.f);
-		mSpinHollow->setMaxValue(70.f);
-	}
-	else 
-	{
-		mSpinHollow->setMinValue(0.f);
-		mSpinHollow->setMaxValue(95.f);
-	}
-
-	// Update field enablement
-	mComboBaseType	->setEnabled( enabled );
-
-	mLabelCut		->setEnabled( enabled );
-	mSpinCutBegin	->setEnabled( enabled );
-	mSpinCutEnd		->setEnabled( enabled );
-
-	mLabelHollow	->setEnabled( enabled );
-	mSpinHollow		->setEnabled( enabled );
-	mLabelHoleType	->setEnabled( hole_enabled );
-	mComboHoleType	->setEnabled( hole_enabled );
-
-	mLabelTwist		->setEnabled( enabled );
-	mSpinTwist		->setEnabled( enabled );
-	mSpinTwistBegin	->setEnabled( enabled );
-
-	mLabelSkew		->setEnabled( enabled );
-	mSpinSkew		->setEnabled( enabled );
-
-	getChildView("scale_hole")->setVisible( FALSE);
-	getChildView("scale_taper")->setVisible( FALSE);
-	if (top_size_x_visible || top_size_y_visible)
-	{
-		if (size_is_hole)
-		{
-			getChildView("scale_hole")->setVisible( TRUE);
-			getChildView("scale_hole")->setEnabled(enabled);
-		}
-		else
-		{
-			getChildView("scale_taper")->setVisible( TRUE);
-			getChildView("scale_taper")->setEnabled(enabled);
-		}
-	}
-	
-	mSpinScaleX		->setEnabled( enabled );
-	mSpinScaleY		->setEnabled( enabled );
-
-	mLabelShear		->setEnabled( enabled );
-	mSpinShearX		->setEnabled( enabled );
-	mSpinShearY		->setEnabled( enabled );
-
-	getChildView("advanced_cut")->setVisible( FALSE);
-	getChildView("advanced_dimple")->setVisible( FALSE);
-	getChildView("advanced_slice")->setVisible( FALSE);
-
-	if (advanced_cut_visible)
-	{
-		if (advanced_is_dimple)
-		{
-			getChildView("advanced_dimple")->setVisible( TRUE);
-			getChildView("advanced_dimple")->setEnabled(enabled);
-		}
-
-		else if (advanced_is_slice)
-		{
-			getChildView("advanced_slice")->setVisible( TRUE);
-			getChildView("advanced_slice")->setEnabled(enabled);
-		}
-		else
-		{
-			getChildView("advanced_cut")->setVisible( TRUE);
-			getChildView("advanced_cut")->setEnabled(enabled);
-		}
-	}
-	
-	mCtrlPathBegin	->setEnabled( enabled );
-	mCtrlPathEnd	->setEnabled( enabled );
-
-	mLabelTaper		->setEnabled( enabled );
-	mSpinTaperX		->setEnabled( enabled );
-	mSpinTaperY		->setEnabled( enabled );
-
-	mLabelRadiusOffset->setEnabled( enabled );
-	mSpinRadiusOffset ->setEnabled( enabled );
-
-	mLabelRevolutions->setEnabled( enabled );
-	mSpinRevolutions ->setEnabled( enabled );
-
-	// Update field visibility
-	mLabelCut		->setVisible( cut_visible );
-	mSpinCutBegin	->setVisible( cut_visible );
-	mSpinCutEnd		->setVisible( cut_visible ); 
-
-	mLabelHollow	->setVisible( hollow_visible );
-	mSpinHollow		->setVisible( hollow_visible );
-	mLabelHoleType	->setVisible( hollow_visible );
-	mComboHoleType	->setVisible( hollow_visible );
-	
-	mLabelTwist		->setVisible( twist_visible );
-	mSpinTwist		->setVisible( twist_visible );
-	mSpinTwistBegin	->setVisible( twist_visible );
-	mSpinTwist		->setMinValue(  twist_min );
-	mSpinTwist		->setMaxValue(  twist_max );
-	mSpinTwist		->setIncrement( twist_inc );
-	mSpinTwistBegin	->setMinValue(  twist_min );
-	mSpinTwistBegin	->setMaxValue(  twist_max );
-	mSpinTwistBegin	->setIncrement( twist_inc );
-
-	mSpinScaleX		->setVisible( top_size_x_visible );
-	mSpinScaleY		->setVisible( top_size_y_visible );
-
-	mLabelSkew		->setVisible( skew_visible );
-	mSpinSkew		->setVisible( skew_visible );
-
-	mLabelShear		->setVisible( top_shear_x_visible || top_shear_y_visible );
-	mSpinShearX		->setVisible( top_shear_x_visible );
-	mSpinShearY		->setVisible( top_shear_y_visible );
-
-	mCtrlPathBegin	->setVisible( advanced_cut_visible );
-	mCtrlPathEnd	->setVisible( advanced_cut_visible );
-
-	mLabelTaper		->setVisible( taper_visible );
-	mSpinTaperX		->setVisible( taper_visible );
-	mSpinTaperY		->setVisible( taper_visible );
-
-	mLabelRadiusOffset->setVisible( radius_offset_visible );
-	mSpinRadiusOffset ->setVisible( radius_offset_visible );
-
-	mLabelRevolutions->setVisible( revolutions_visible );
-	mSpinRevolutions ->setVisible( revolutions_visible );
-
-	mCtrlSculptTexture->setVisible(sculpt_texture_visible);
-	mLabelSculptType->setVisible(sculpt_texture_visible);
-	mCtrlSculptType->setVisible(sculpt_texture_visible);
-
-
-	// sculpt texture
-	if (selected_item == MI_SCULPT)
-	{
-
-
-		LLUUID id;
-		LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
-
-		
-		if (sculpt_params) // if we have a legal sculpt param block for this object:
-		{
-			if (mObject != objectp)  // we've just selected a new object, so save for undo
-			{
-				mSculptTextureRevert = sculpt_params->getSculptTexture();
-				mSculptTypeRevert    = sculpt_params->getSculptType();
-			}
-		
-			U8 sculpt_type = sculpt_params->getSculptType();
-			U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK;
-			BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT;
-			BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR;
-			isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH);
-
-			LLTextureCtrl*  mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
-			if(mTextureCtrl)
-			{
-				mTextureCtrl->setTentative(FALSE);
-				mTextureCtrl->setEnabled(editable && !isMesh);
-				if (editable)
-					mTextureCtrl->setImageAssetID(sculpt_params->getSculptTexture());
-				else
-					mTextureCtrl->setImageAssetID(LLUUID::null);
-			}
-
-			mComboBaseType->setEnabled(!isMesh);
-			
-			if (mCtrlSculptType)
-			{
-				mCtrlSculptType->setCurrentByIndex(sculpt_stitching);
-				mCtrlSculptType->setEnabled(editable && !isMesh);
-			}
-
-			if (mCtrlSculptMirror)
-			{
-				mCtrlSculptMirror->set(sculpt_mirror);
-				mCtrlSculptMirror->setEnabled(editable && !isMesh);
-			}
-
-			if (mCtrlSculptInvert)
-			{
-				mCtrlSculptInvert->set(sculpt_invert);
-				mCtrlSculptInvert->setEnabled(editable);
-			}
-
-			if (mLabelSculptType)
-			{
-				mLabelSculptType->setEnabled(TRUE);
-			}
-			
-		}
-	}
-	else
-	{
-		mSculptTextureRevert = LLUUID::null;		
-	}
-
-	mCtrlSculptMirror->setVisible(sculpt_texture_visible && !isMesh);
-	mCtrlSculptInvert->setVisible(sculpt_texture_visible && !isMesh);
-
-	//----------------------------------------------------------------------------
-
-	mObject = objectp;
-	mRootObject = root_objectp;
-}
-
-// static
-bool LLPanelObject::precommitValidate( const LLSD& data )
-{
-	// TODO: Richard will fill this in later.  
-	return TRUE; // FALSE means that validation failed and new value should not be commited.
-}
-
-void LLPanelObject::sendIsPhysical()
-{
-	BOOL value = mCheckPhysics->get();
-	if( mIsPhysical != value )
-	{
-		LLSelectMgr::getInstance()->selectionUpdatePhysics(value);
-		mIsPhysical = value;
-
-		llinfos << "update physics sent" << llendl;
-	}
-	else
-	{
-		llinfos << "update physics not changed" << llendl;
-	}
-}
-
-void LLPanelObject::sendIsTemporary()
-{
-	BOOL value = mCheckTemporary->get();
-	if( mIsTemporary != value )
-	{
-		LLSelectMgr::getInstance()->selectionUpdateTemporary(value);
-		mIsTemporary = value;
-
-		llinfos << "update temporary sent" << llendl;
-	}
-	else
-	{
-		llinfos << "update temporary not changed" << llendl;
-	}
-}
-
-
-void LLPanelObject::sendIsPhantom()
-{
-	BOOL value = mCheckPhantom->get();
-	if( mIsPhantom != value )
-	{
-		LLSelectMgr::getInstance()->selectionUpdatePhantom(value);
-		mIsPhantom = value;
-
-		llinfos << "update phantom sent" << llendl;
-	}
-	else
-	{
-		llinfos << "update phantom not changed" << llendl;
-	}
-}
-
-void LLPanelObject::sendCastShadows()
-{
-	BOOL value = mCheckCastShadows->get();
-	if( mCastShadows != value )
-	{
-		LLSelectMgr::getInstance()->selectionUpdateCastShadows(value);
-		mCastShadows = value;
-
-		llinfos << "update cast shadows sent" << llendl;
-	}
-	else
-	{
-		llinfos << "update cast shadows not changed" << llendl;
-	}
-}
-
-// static
-void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata )
-{
-	LLPanelObject* self = (LLPanelObject*) userdata;
-
-	if (self->mObject.isNull())
-	{
-		return;
-	}
-
-	if (self->mObject->getPCode() != LL_PCODE_VOLUME)
-	{
-		// Don't allow modification of non-volume objects.
-		return;
-	}
-
-	LLVolume *volume = self->mObject->getVolume();
-	if (!volume)
-	{
-		return;
-	}
-
-	LLVolumeParams volume_params;
-	self->getVolumeParams(volume_params);
-	
-
-	
-	// set sculpting
-	S32 selected_type = self->mComboBaseType->getCurrentIndex();
-
-	if (selected_type == MI_SCULPT)
-	{
-		self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, TRUE, TRUE);
-		LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
-		if (sculpt_params)
-			volume_params.setSculptID(sculpt_params->getSculptTexture(), sculpt_params->getSculptType());
-	}
-	else
-	{
-		LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
-		if (sculpt_params)
-			self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
-	}
-
-	// Update the volume, if necessary.
-	self->mObject->updateVolume(volume_params);
-
-
-	// This was added to make sure thate when changes are made, the UI
-	// adjusts to present valid options.
-	// *FIX: only some changes, ie, hollow or primitive type changes,
-	// require a refresh.
-	self->refresh();
-
-}
-
-void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
-{
-	// Figure out what type of volume to make
-	S32 was_selected_type = mSelectedType;
-	S32 selected_type = mComboBaseType->getCurrentIndex();
-	U8 profile;
-	U8 path;
-	switch ( selected_type )
-	{
-	case MI_CYLINDER:
-		profile = LL_PCODE_PROFILE_CIRCLE;
-		path = LL_PCODE_PATH_LINE;
-		break;
-
-	case MI_BOX:
-		profile = LL_PCODE_PROFILE_SQUARE;
-		path = LL_PCODE_PATH_LINE;
-		break;
-
-	case MI_PRISM:
-		profile = LL_PCODE_PROFILE_EQUALTRI;
-		path = LL_PCODE_PATH_LINE;
-		break;
-
-	case MI_SPHERE:
-		profile = LL_PCODE_PROFILE_CIRCLE_HALF;
-		path = LL_PCODE_PATH_CIRCLE;
-		break;
-
-	case MI_TORUS:
-		profile = LL_PCODE_PROFILE_CIRCLE;
-		path = LL_PCODE_PATH_CIRCLE;
-		break;
-
-	case MI_TUBE:
-		profile = LL_PCODE_PROFILE_SQUARE;
-		path = LL_PCODE_PATH_CIRCLE;
-		break;
-
-	case MI_RING:
-		profile = LL_PCODE_PROFILE_EQUALTRI;
-		path = LL_PCODE_PATH_CIRCLE;
-		break;
-
-	case MI_SCULPT:
-		profile = LL_PCODE_PROFILE_CIRCLE;
-		path = LL_PCODE_PATH_CIRCLE;
-		break;
-		
-	default:
-		llwarns << "Unknown base type " << selected_type 
-			<< " in getVolumeParams()" << llendl;
-		// assume a box
-		selected_type = MI_BOX;
-		profile = LL_PCODE_PROFILE_SQUARE;
-		path = LL_PCODE_PATH_LINE;
-		break;
-	}
-
-
-	if (path == LL_PCODE_PATH_LINE)
-	{
-		LLVOVolume *volobjp = (LLVOVolume *)(LLViewerObject*)(mObject);
-		if (volobjp->isFlexible())
-		{
-			path = LL_PCODE_PATH_FLEXIBLE;
-		}
-	}
-	
-	S32 selected_hole = mComboHoleType->getCurrentIndex();
-	U8 hole;
-	switch (selected_hole)
-	{
-	case MI_HOLE_CIRCLE: 
-		hole = LL_PCODE_HOLE_CIRCLE;
-		break;
-	case MI_HOLE_SQUARE:
-		hole = LL_PCODE_HOLE_SQUARE;
-		break;
-	case MI_HOLE_TRIANGLE:
-		hole = LL_PCODE_HOLE_TRIANGLE;
-		break;
-	case MI_HOLE_SAME:
-	default:
-		hole = LL_PCODE_HOLE_SAME;
-		break;
-	}
-
-	volume_params.setType(profile | hole, path);
-	mSelectedType = selected_type;
-	
-	// Compute cut start/end
-	F32 cut_begin	= mSpinCutBegin->get();
-	F32 cut_end		= mSpinCutEnd->get();
-
-	// Make sure at least OBJECT_CUT_INC of the object survives
-	if (cut_begin > cut_end - OBJECT_MIN_CUT_INC)
-	{
-		cut_begin = cut_end - OBJECT_MIN_CUT_INC;
-		mSpinCutBegin->set(cut_begin);
-	}
-
-	F32 adv_cut_begin	= mCtrlPathBegin->get();
-	F32 adv_cut_end		= mCtrlPathEnd->get();
-
-	// Make sure at least OBJECT_CUT_INC of the object survives
-	if (adv_cut_begin > adv_cut_end - OBJECT_MIN_CUT_INC)
-	{
-		adv_cut_begin = adv_cut_end - OBJECT_MIN_CUT_INC;
-		mCtrlPathBegin->set(adv_cut_begin);
-	}
-
-	F32 begin_s, end_s;
-	F32 begin_t, end_t;
-
-	if (selected_type == MI_SPHERE || selected_type == MI_TORUS || 
-		selected_type == MI_TUBE   || selected_type == MI_RING)
-	{
-		begin_s = adv_cut_begin;
-		end_s	= adv_cut_end;
-
-		begin_t = cut_begin;
-		end_t	= cut_end;
-	}
-	else
-	{
-		begin_s = cut_begin;
-		end_s	= cut_end;
-
-		begin_t = adv_cut_begin;
-		end_t	= adv_cut_end;
-	}
-
-	volume_params.setBeginAndEndS(begin_s, end_s);
-	volume_params.setBeginAndEndT(begin_t, end_t);
-
-	// Hollowness
-	F32 hollow = mSpinHollow->get() / 100.f;
-
-	if (  selected_hole == MI_HOLE_SQUARE && 
-		( selected_type == MI_CYLINDER || selected_type == MI_TORUS ||
-		  selected_type == MI_PRISM    || selected_type == MI_RING  ||
-		  selected_type == MI_SPHERE ) )
-	{
-		if (hollow > 0.7f) hollow = 0.7f;
-	}
-
-	volume_params.setHollow( hollow );
-
-	// Twist Begin,End
-	F32 twist_begin = mSpinTwistBegin->get();
-	F32 twist		= mSpinTwist->get();
-	// Check the path type for twist conversion.
-	if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
-	{
-		twist_begin	/= OBJECT_TWIST_LINEAR_MAX;
-		twist		/= OBJECT_TWIST_LINEAR_MAX;
-	}
-	else
-	{
-		twist_begin	/= OBJECT_TWIST_MAX;
-		twist		/= OBJECT_TWIST_MAX;
-	}
-
-	volume_params.setTwistBegin(twist_begin);
-	volume_params.setTwist(twist);
-
-	// Scale X,Y
-	F32 scale_x = mSpinScaleX->get();
-	F32 scale_y = mSpinScaleY->get();
-	if ( was_selected_type == MI_BOX || was_selected_type == MI_CYLINDER || was_selected_type == MI_PRISM)
-	{
-		scale_x = 1.f - scale_x;
-		scale_y = 1.f - scale_y;
-	}
-	
-	// Skew
-	F32 skew = mSpinSkew->get();
-
-	// Taper X,Y
-	F32 taper_x = mSpinTaperX->get();
-	F32 taper_y = mSpinTaperY->get();
-
-	// Radius offset
-	F32 radius_offset = mSpinRadiusOffset->get();
-
-	// Revolutions
-	F32 revolutions	  = mSpinRevolutions->get();
-
-	if ( selected_type == MI_SPHERE )
-	{
-		// Snap values to valid sphere parameters.
-		scale_x			= 1.0f;
-		scale_y			= 1.0f;
-		skew			= 0.0f;
-		taper_x			= 0.0f;
-		taper_y			= 0.0f;
-		radius_offset	= 0.0f;
-		revolutions		= 1.0f;
-	}
-	else if ( selected_type == MI_TORUS || selected_type == MI_TUBE ||
-			  selected_type == MI_RING )
-	{
-		scale_x = llclamp(
-			scale_x,
-			OBJECT_MIN_HOLE_SIZE,
-			OBJECT_MAX_HOLE_SIZE_X);
-		scale_y = llclamp(
-			scale_y,
-			OBJECT_MIN_HOLE_SIZE,
-			OBJECT_MAX_HOLE_SIZE_Y);
-
-		// Limit radius offset, based on taper and hole size y.
-		F32 radius_mag = fabs(radius_offset);
-		F32 hole_y_mag = fabs(scale_y);
-		F32 taper_y_mag  = fabs(taper_y);
-		// Check to see if the taper effects us.
-		if ( (radius_offset > 0.f && taper_y < 0.f) ||
-			 (radius_offset < 0.f && taper_y > 0.f) )
-		{
-			// The taper does not help increase the radius offset range.
-			taper_y_mag = 0.f;
-		}
-		F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
-		// Enforce the maximum magnitude.
-		if (radius_mag > max_radius_mag)
-		{
-			// Check radius offset sign.
-			if (radius_offset < 0.f)
-			{
-				radius_offset = -max_radius_mag;
-			}
-			else
-			{
-				radius_offset = max_radius_mag;
-			}
-		}
-			
-		// Check the skew value against the revolutions.
-		F32 skew_mag= fabs(skew);
-		F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
-		// Discontinuity; A revolution of 1 allows skews below 0.5.
-		if ( fabs(revolutions - 1.0f) < 0.001)
-			min_skew_mag = 0.0f;
-
-		// Clip skew.
-		if (skew_mag < min_skew_mag)
-		{
-			// Check skew sign.
-			if (skew < 0.0f)
-			{
-				skew = -min_skew_mag;
-			}
-			else 
-			{
-				skew = min_skew_mag;
-			}
-		}
-	}
-
-	volume_params.setRatio( scale_x, scale_y );
-	volume_params.setSkew(skew);
-	volume_params.setTaper( taper_x, taper_y );
-	volume_params.setRadiusOffset(radius_offset);
-	volume_params.setRevolutions(revolutions);
-
-	// Shear X,Y
-	F32 shear_x = mSpinShearX->get();
-	F32 shear_y = mSpinShearY->get();
-	volume_params.setShear( shear_x, shear_y );
-
-	if (selected_type == MI_SCULPT)
-	{
-		volume_params.setSculptID(LLUUID::null, 0);
-		volume_params.setBeginAndEndT   (0, 1);
-		volume_params.setBeginAndEndS   (0, 1);
-		volume_params.setHollow         (0);
-		volume_params.setTwistBegin     (0);
-		volume_params.setTwistEnd       (0);
-		volume_params.setRatio          (1, 0.5);
-		volume_params.setShear          (0, 0);
-		volume_params.setTaper          (0, 0);
-		volume_params.setRevolutions    (1);
-		volume_params.setRadiusOffset   (0);
-		volume_params.setSkew           (0);
-	}
-
-}
-
-// BUG: Make work with multiple objects
-void LLPanelObject::sendRotation(BOOL btn_down)
-{
-	if (mObject.isNull()) return;
-
-	LLVector3 new_rot(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get());
-	new_rot.mV[VX] = llround(new_rot.mV[VX], OBJECT_ROTATION_PRECISION);
-	new_rot.mV[VY] = llround(new_rot.mV[VY], OBJECT_ROTATION_PRECISION);
-	new_rot.mV[VZ] = llround(new_rot.mV[VZ], OBJECT_ROTATION_PRECISION);
-
-	// Note: must compare before conversion to radians
-	LLVector3 delta = new_rot - mCurEulerDegrees;
-
-	if (delta.magVec() >= 0.0005f)
-	{
-		mCurEulerDegrees = new_rot;
-		new_rot *= DEG_TO_RAD;
-
-		LLQuaternion rotation;
-		rotation.setQuat(new_rot.mV[VX], new_rot.mV[VY], new_rot.mV[VZ]);
-
-		if (mRootObject != mObject)
-		{
-			rotation = rotation * ~mRootObject->getRotationRegion();
-		}
-		std::vector<LLVector3>& child_positions = mObject->mUnselectedChildrenPositions ;
-		std::vector<LLQuaternion> child_rotations;
-		if (mObject->isRootEdit())
-		{
-			mObject->saveUnselectedChildrenRotation(child_rotations) ;
-			mObject->saveUnselectedChildrenPosition(child_positions) ;			
-		}
-
-		mObject->setRotation(rotation);
-		LLManip::rebuild(mObject) ;
-
-		// for individually selected roots, we need to counterrotate all the children
-		if (mObject->isRootEdit())
-		{			
-			mObject->resetChildrenRotationAndPosition(child_rotations, child_positions) ;			
-		}
-
-		if(!btn_down)
-		{
-			child_positions.clear() ;
-			LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_ROTATION | UPD_POSITION);
-		}
-	}
-}
-
-
-// BUG: Make work with multiple objects
-void LLPanelObject::sendScale(BOOL btn_down)
-{
-	if (mObject.isNull()) return;
-
-	LLVector3 newscale(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get());
-
-	LLVector3 delta = newscale - mObject->getScale();
-	if (delta.magVec() >= 0.0005f)
-	{
-		// scale changed by more than 1/2 millimeter
-
-		// check to see if we aren't scaling the textures
-		// (in which case the tex coord's need to be recomputed)
-		BOOL dont_stretch_textures = !LLManipScale::getStretchTextures();
-		if (dont_stretch_textures)
-		{
-			LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_SCALE);
-		}
-
-		mObject->setScale(newscale, TRUE);
-
-		if(!btn_down)
-		{
-			LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION);
-		}
-
-		LLSelectMgr::getInstance()->adjustTexturesByScale(TRUE, !dont_stretch_textures);
-//		llinfos << "scale sent" << llendl;
-	}
-	else
-	{
-//		llinfos << "scale not changed" << llendl;
-	}
-}
-
-
-void LLPanelObject::sendPosition(BOOL btn_down)
-{	
-	if (mObject.isNull()) return;
-
-	LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
-	LLViewerRegion* regionp = mObject->getRegion();
-
-	// Clamp the Z height
-	const F32 height = newpos.mV[VZ];
-	const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
-	const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
-
-	if (!mObject->isAttachment())
-	{
-		if ( height < min_height)
-		{
-			newpos.mV[VZ] = min_height;
-			mCtrlPosZ->set( min_height );
-		}
-		else if ( height > max_height )
-		{
-			newpos.mV[VZ] = max_height;
-			mCtrlPosZ->set( max_height );
-		}
-
-		// Grass is always drawn on the ground, so clamp its position to the ground
-		if (mObject->getPCode() == LL_PCODE_LEGACY_GRASS)
-		{
-			mCtrlPosZ->set(LLWorld::getInstance()->resolveLandHeightAgent(newpos) + 1.f);
-		}
-	}
-
-	// Make sure new position is in a valid region, so the object
-	// won't get dumped by the simulator.
-	LLVector3d new_pos_global = regionp->getPosGlobalFromRegion(newpos);
-
-	if ( LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global) )
-	{
-		// send only if the position is changed, that is, the delta vector is not zero
-		LLVector3d old_pos_global = mObject->getPositionGlobal();
-		LLVector3d delta = new_pos_global - old_pos_global;
-		// moved more than 1/2 millimeter
-		if (delta.magVec() >= 0.0005f)
-		{			
-			if (mRootObject != mObject)
-			{
-				newpos = newpos - mRootObject->getPositionRegion();
-				newpos = newpos * ~mRootObject->getRotationRegion();
-				mObject->setPositionParent(newpos);
-			}
-			else
-			{
-				mObject->setPositionEdit(newpos);
-			}			
-			
-			LLManip::rebuild(mObject) ;
-
-			// for individually selected roots, we need to counter-translate all unselected children
-			if (mObject->isRootEdit())
-			{								
-				// only offset by parent's translation
-				mObject->resetChildrenPosition(LLVector3(-delta), TRUE) ;				
-			}
-
-			if(!btn_down)
-			{
-				LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
-			}
-
-			LLSelectMgr::getInstance()->updateSelectionCenter();
-		}
-	}
-	else
-	{
-		// move failed, so we update the UI with the correct values
-		LLVector3 vec = mRootObject->getPositionRegion();
-		mCtrlPosX->set(vec.mV[VX]);
-		mCtrlPosY->set(vec.mV[VY]);
-		mCtrlPosZ->set(vec.mV[VZ]);
-	}
-}
-
-void LLPanelObject::sendSculpt()
-{
-	if (mObject.isNull())
-		return;
-	
-	LLSculptParams sculpt_params;
-
-	if (mCtrlSculptTexture)
-		sculpt_params.setSculptTexture(mCtrlSculptTexture->getImageAssetID());
-
-	U8 sculpt_type = 0;
-	
-	if (mCtrlSculptType)
-		sculpt_type |= mCtrlSculptType->getCurrentIndex();
-
-	bool enabled = sculpt_type != LL_SCULPT_TYPE_MESH;
-
-	if (mCtrlSculptMirror)
-	{
-		mCtrlSculptMirror->setEnabled(enabled ? TRUE : FALSE);
-	}
-	if (mCtrlSculptInvert)
-	{
-		mCtrlSculptInvert->setEnabled(enabled ? TRUE : FALSE);
-	}
-	
-	if ((mCtrlSculptMirror) && (mCtrlSculptMirror->get()))
-		sculpt_type |= LL_SCULPT_FLAG_MIRROR;
-
-	if ((mCtrlSculptInvert) && (mCtrlSculptInvert->get()))
-		sculpt_type |= LL_SCULPT_FLAG_INVERT;
-	
-	sculpt_params.setSculptType(sculpt_type);
-	mObject->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
-}
-
-void LLPanelObject::refresh()
-{
-	getState();
-	if (mObject.notNull() && mObject->isDead())
-	{
-		mObject = NULL;
-	}
-
-	if (mRootObject.notNull() && mRootObject->isDead())
-	{
-		mRootObject = NULL;
-	}
-	
-	bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") && 
-					   gAgent.getRegion() &&
-					   !gAgent.getRegion()->getCapability("GetMesh").empty();
-
-	F32 max_scale = get_default_max_prim_scale(LLPickInfo::isFlora(mObject));
-
-	getChild<LLSpinCtrl>("Scale X")->setMaxValue(max_scale);
-	getChild<LLSpinCtrl>("Scale Y")->setMaxValue(max_scale);
-	getChild<LLSpinCtrl>("Scale Z")->setMaxValue(max_scale);
-
-	BOOL found = mCtrlSculptType->itemExists("Mesh");
-	if (enable_mesh && !found)
-	{
-		mCtrlSculptType->add("Mesh");
-	}
-	else if (!enable_mesh && found)
-	{
-		mCtrlSculptType->remove("Mesh");
-	}
-}
-
-
-void LLPanelObject::draw()
-{
-	const LLColor4	white(	1.0f,	1.0f,	1.0f,	1);
-	const LLColor4	red(	1.0f,	0.25f,	0.f,	1);
-	const LLColor4	green(	0.f,	1.0f,	0.f,	1);
-	const LLColor4	blue(	0.f,	0.5f,	1.0f,	1);
-
-	// Tune the colors of the labels
-	LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
-
-	if (tool == LLToolCompTranslate::getInstance())
-	{
-		mCtrlPosX	->setLabelColor(red);
-		mCtrlPosY	->setLabelColor(green);
-		mCtrlPosZ	->setLabelColor(blue);
-
-		mCtrlScaleX	->setLabelColor(white);
-		mCtrlScaleY	->setLabelColor(white);
-		mCtrlScaleZ	->setLabelColor(white);
-
-		mCtrlRotX	->setLabelColor(white);
-		mCtrlRotY	->setLabelColor(white);
-		mCtrlRotZ	->setLabelColor(white);
-	}
-	else if ( tool == LLToolCompScale::getInstance() )
-	{
-		mCtrlPosX	->setLabelColor(white);
-		mCtrlPosY	->setLabelColor(white);
-		mCtrlPosZ	->setLabelColor(white);
-
-		mCtrlScaleX	->setLabelColor(red);
-		mCtrlScaleY	->setLabelColor(green);
-		mCtrlScaleZ	->setLabelColor(blue);
-
-		mCtrlRotX	->setLabelColor(white);
-		mCtrlRotY	->setLabelColor(white);
-		mCtrlRotZ	->setLabelColor(white);
-	}
-	else if ( tool == LLToolCompRotate::getInstance() )
-	{
-		mCtrlPosX	->setLabelColor(white);
-		mCtrlPosY	->setLabelColor(white);
-		mCtrlPosZ	->setLabelColor(white);
-
-		mCtrlScaleX	->setLabelColor(white);
-		mCtrlScaleY	->setLabelColor(white);
-		mCtrlScaleZ	->setLabelColor(white);
-
-		mCtrlRotX	->setLabelColor(red);
-		mCtrlRotY	->setLabelColor(green);
-		mCtrlRotZ	->setLabelColor(blue);
-	}
-	else
-	{
-		mCtrlPosX	->setLabelColor(white);
-		mCtrlPosY	->setLabelColor(white);
-		mCtrlPosZ	->setLabelColor(white);
-
-		mCtrlScaleX	->setLabelColor(white);
-		mCtrlScaleY	->setLabelColor(white);
-		mCtrlScaleZ	->setLabelColor(white);
-
-		mCtrlRotX	->setLabelColor(white);
-		mCtrlRotY	->setLabelColor(white);
-		mCtrlRotZ	->setLabelColor(white);
-	}
-
-	LLPanel::draw();
-}
-
-// virtual
-void LLPanelObject::clearCtrls()
-{
-	LLPanel::clearCtrls();
-
-	mCheckLock		->set(FALSE);
-	mCheckLock		->setEnabled( FALSE );
-	mCheckPhysics	->set(FALSE);
-	mCheckPhysics	->setEnabled( FALSE );
-	mCheckTemporary	->set(FALSE);
-	mCheckTemporary	->setEnabled( FALSE );
-	mCheckPhantom	->set(FALSE);
-	mCheckPhantom	->setEnabled( FALSE );
-	
-#if 0 // 1.9.2
-	mCheckCastShadows->set(FALSE);
-	mCheckCastShadows->setEnabled( FALSE );
-#endif
-	// Disable text labels
-	mLabelPosition	->setEnabled( FALSE );
-	mLabelSize		->setEnabled( FALSE );
-	mLabelRotation	->setEnabled( FALSE );
-	mLabelCut		->setEnabled( FALSE );
-	mLabelHollow	->setEnabled( FALSE );
-	mLabelHoleType	->setEnabled( FALSE );
-	mLabelTwist		->setEnabled( FALSE );
-	mLabelSkew		->setEnabled( FALSE );
-	mLabelShear		->setEnabled( FALSE );
-	mLabelTaper		->setEnabled( FALSE );
-	mLabelRadiusOffset->setEnabled( FALSE );
-	mLabelRevolutions->setEnabled( FALSE );
-
-	getChildView("select_single")->setVisible( FALSE);
-	getChildView("edit_object")->setVisible( TRUE);	
-	getChildView("edit_object")->setEnabled(FALSE);
-	
-	getChildView("scale_hole")->setEnabled(FALSE);
-	getChildView("scale_taper")->setEnabled(FALSE);
-	getChildView("advanced_cut")->setEnabled(FALSE);
-	getChildView("advanced_dimple")->setEnabled(FALSE);
-	getChildView("advanced_slice")->setVisible( FALSE);
-}
-
-//
-// Static functions
-//
-
-// static
-void LLPanelObject::onCommitLock(LLUICtrl *ctrl, void *data)
-{
-	// Checkbox will have toggled itself
-	LLPanelObject *self = (LLPanelObject *)data;
-
-	if(self->mRootObject.isNull()) return;
-
-	BOOL new_state = self->mCheckLock->get();
-	
-	LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, !new_state, PERM_MOVE | PERM_MODIFY);
-}
-
-// static
-void LLPanelObject::onCommitPosition( LLUICtrl* ctrl, void* userdata )
-{
-	LLPanelObject* self = (LLPanelObject*) userdata;
-	BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
-	self->sendPosition(btn_down);
-}
-
-// static
-void LLPanelObject::onCommitScale( LLUICtrl* ctrl, void* userdata )
-{
-	LLPanelObject* self = (LLPanelObject*) userdata;
-	BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
-	self->sendScale(btn_down);
-}
-
-// static
-void LLPanelObject::onCommitRotation( LLUICtrl* ctrl, void* userdata )
-{
-	LLPanelObject* self = (LLPanelObject*) userdata;
-	BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
-	self->sendRotation(btn_down);
-}
-
-// static
-void LLPanelObject::onCommitPhysics( LLUICtrl* ctrl, void* userdata )
-{
-	LLPanelObject* self = (LLPanelObject*) userdata;
-	self->sendIsPhysical();
-}
-
-// static
-void LLPanelObject::onCommitTemporary( LLUICtrl* ctrl, void* userdata )
-{
-	LLPanelObject* self = (LLPanelObject*) userdata;
-	self->sendIsTemporary();
-}
-
-// static
-void LLPanelObject::onCommitPhantom( LLUICtrl* ctrl, void* userdata )
-{
-	LLPanelObject* self = (LLPanelObject*) userdata;
-	self->sendIsPhantom();
-}
-
-// static
-void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )
-{
-	LLPanelObject* self = (LLPanelObject*) userdata;
-	self->sendCastShadows();
-}
-
-
-void LLPanelObject::onSelectSculpt(const LLSD& data)
-{
-    LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
-
-	if (mTextureCtrl)
-	{
-		mSculptTextureRevert = mTextureCtrl->getImageAssetID();
-	}
-	
-	sendSculpt();
-}
-
-
-void LLPanelObject::onCommitSculpt( const LLSD& data )
-{
-	sendSculpt();
-}
-
-BOOL LLPanelObject::onDropSculpt(LLInventoryItem* item)
-{
-    LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
-
-	if (mTextureCtrl)
-	{
-		LLUUID asset = item->getAssetUUID();
-
-		mTextureCtrl->setImageAssetID(asset);
-		mSculptTextureRevert = asset;
-	}
-
-	return TRUE;
-}
-
-
-void LLPanelObject::onCancelSculpt(const LLSD& data)
-{
-	LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
-	if(!mTextureCtrl)
-		return;
-	
-	mTextureCtrl->setImageAssetID(mSculptTextureRevert);
-	
-	sendSculpt();
-}
-
-// static
-void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)
-{
-	LLPanelObject* self = (LLPanelObject*) userdata;
-
-	self->sendSculpt();
-}
+/** 
+ * @file llpanelobject.cpp
+ * @brief Object editing (position, scale, etc.) in the tools floater
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+// file include
+#include "llpanelobject.h"
+
+// linden library includes
+#include "lleconomy.h"
+#include "llerror.h"
+#include "llfontgl.h"
+#include "llpermissionsflags.h"
+#include "llstring.h"
+#include "llvolume.h"
+#include "m3math.h"
+
+// project includes
+#include "llagent.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llcolorswatch.h"
+#include "llcombobox.h"
+#include "llfocusmgr.h"
+#include "llmanipscale.h"
+#include "llpreviewscript.h"
+#include "llresmgr.h"
+#include "llselectmgr.h"
+#include "llspinctrl.h"
+#include "lltexturectrl.h"
+#include "lltextbox.h"
+#include "lltool.h"
+#include "lltoolcomp.h"
+#include "lltoolmgr.h"
+#include "llui.h"
+#include "llviewerobject.h"
+#include "llviewerregion.h"
+#include "llviewerwindow.h"
+#include "llvovolume.h"
+#include "llworld.h"
+#include "pipeline.h"
+#include "llviewercontrol.h"
+#include "lluictrlfactory.h"
+//#include "llfirstuse.h"
+
+#include "lldrawpool.h"
+
+//
+// Constants
+//
+enum {
+	MI_BOX,
+	MI_CYLINDER,
+	MI_PRISM,
+	MI_SPHERE,
+	MI_TORUS,
+	MI_TUBE,
+	MI_RING,
+	MI_SCULPT,
+	MI_NONE,
+	MI_VOLUME_COUNT
+};
+
+enum {
+	MI_HOLE_SAME,
+	MI_HOLE_CIRCLE,
+	MI_HOLE_SQUARE,
+	MI_HOLE_TRIANGLE,
+	MI_HOLE_COUNT
+};
+
+//static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright");
+
+BOOL	LLPanelObject::postBuild()
+{
+	setMouseOpaque(FALSE);
+	
+	//--------------------------------------------------------
+	// Top
+	//--------------------------------------------------------
+	
+	// Lock checkbox
+	mCheckLock = getChild<LLCheckBoxCtrl>("checkbox locked");
+	childSetCommitCallback("checkbox locked",onCommitLock,this);
+
+	// Physical checkbox
+	mCheckPhysics = getChild<LLCheckBoxCtrl>("Physical Checkbox Ctrl");
+	childSetCommitCallback("Physical Checkbox Ctrl",onCommitPhysics,this);
+
+	// Temporary checkbox
+	mCheckTemporary = getChild<LLCheckBoxCtrl>("Temporary Checkbox Ctrl");
+	childSetCommitCallback("Temporary Checkbox Ctrl",onCommitTemporary,this);
+
+	// Phantom checkbox
+	mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl");
+	childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this);
+       
+
+	// Position
+	mLabelPosition = getChild<LLTextBox>("label position");
+	mCtrlPosX = getChild<LLSpinCtrl>("Pos X");
+	childSetCommitCallback("Pos X",onCommitPosition,this);
+	mCtrlPosY = getChild<LLSpinCtrl>("Pos Y");
+	childSetCommitCallback("Pos Y",onCommitPosition,this);
+	mCtrlPosZ = getChild<LLSpinCtrl>("Pos Z");
+	childSetCommitCallback("Pos Z",onCommitPosition,this);
+
+	// Scale
+	mLabelSize = getChild<LLTextBox>("label size");
+	mCtrlScaleX = getChild<LLSpinCtrl>("Scale X");
+	childSetCommitCallback("Scale X",onCommitScale,this);
+
+	// Scale Y
+	mCtrlScaleY = getChild<LLSpinCtrl>("Scale Y");
+	childSetCommitCallback("Scale Y",onCommitScale,this);
+
+	// Scale Z
+	mCtrlScaleZ = getChild<LLSpinCtrl>("Scale Z");
+	childSetCommitCallback("Scale Z",onCommitScale,this);
+
+	// Rotation
+	mLabelRotation = getChild<LLTextBox>("label rotation");
+	mCtrlRotX = getChild<LLSpinCtrl>("Rot X");
+	childSetCommitCallback("Rot X",onCommitRotation,this);
+	mCtrlRotY = getChild<LLSpinCtrl>("Rot Y");
+	childSetCommitCallback("Rot Y",onCommitRotation,this);
+	mCtrlRotZ = getChild<LLSpinCtrl>("Rot Z");
+	childSetCommitCallback("Rot Z",onCommitRotation,this);
+
+	//--------------------------------------------------------
+		
+	// Base Type
+	mComboBaseType = getChild<LLComboBox>("comboBaseType");
+	childSetCommitCallback("comboBaseType",onCommitParametric,this);
+
+	// Cut
+	mLabelCut = getChild<LLTextBox>("text cut");
+	mSpinCutBegin = getChild<LLSpinCtrl>("cut begin");
+	childSetCommitCallback("cut begin",onCommitParametric,this);
+	mSpinCutBegin->setValidateBeforeCommit( precommitValidate );
+	mSpinCutEnd = getChild<LLSpinCtrl>("cut end");
+	childSetCommitCallback("cut end",onCommitParametric,this);
+	mSpinCutEnd->setValidateBeforeCommit( &precommitValidate );
+
+	// Hollow / Skew
+	mLabelHollow = getChild<LLTextBox>("text hollow");
+	mLabelSkew = getChild<LLTextBox>("text skew");
+	mSpinHollow = getChild<LLSpinCtrl>("Scale 1");
+	childSetCommitCallback("Scale 1",onCommitParametric,this);
+	mSpinHollow->setValidateBeforeCommit( &precommitValidate );
+	mSpinSkew = getChild<LLSpinCtrl>("Skew");
+	childSetCommitCallback("Skew",onCommitParametric,this);
+	mSpinSkew->setValidateBeforeCommit( &precommitValidate );
+	mLabelHoleType = getChild<LLTextBox>("Hollow Shape");
+
+	// Hole Type
+	mComboHoleType = getChild<LLComboBox>("hole");
+	childSetCommitCallback("hole",onCommitParametric,this);
+
+	// Twist
+	mLabelTwist = getChild<LLTextBox>("text twist");
+	mSpinTwistBegin = getChild<LLSpinCtrl>("Twist Begin");
+	childSetCommitCallback("Twist Begin",onCommitParametric,this);
+	mSpinTwistBegin->setValidateBeforeCommit( precommitValidate );
+	mSpinTwist = getChild<LLSpinCtrl>("Twist End");
+	childSetCommitCallback("Twist End",onCommitParametric,this);
+	mSpinTwist->setValidateBeforeCommit( &precommitValidate );
+
+	// Scale
+	mSpinScaleX = getChild<LLSpinCtrl>("Taper Scale X");
+	childSetCommitCallback("Taper Scale X",onCommitParametric,this);
+	mSpinScaleX->setValidateBeforeCommit( &precommitValidate );
+	mSpinScaleY = getChild<LLSpinCtrl>("Taper Scale Y");
+	childSetCommitCallback("Taper Scale Y",onCommitParametric,this);
+	mSpinScaleY->setValidateBeforeCommit( &precommitValidate );
+
+	// Shear
+	mLabelShear = getChild<LLTextBox>("text topshear");
+	mSpinShearX = getChild<LLSpinCtrl>("Shear X");
+	childSetCommitCallback("Shear X",onCommitParametric,this);
+	mSpinShearX->setValidateBeforeCommit( &precommitValidate );
+	mSpinShearY = getChild<LLSpinCtrl>("Shear Y");
+	childSetCommitCallback("Shear Y",onCommitParametric,this);
+	mSpinShearY->setValidateBeforeCommit( &precommitValidate );
+
+	// Path / Profile
+	mCtrlPathBegin = getChild<LLSpinCtrl>("Path Limit Begin");
+	childSetCommitCallback("Path Limit Begin",onCommitParametric,this);
+	mCtrlPathBegin->setValidateBeforeCommit( &precommitValidate );
+	mCtrlPathEnd = getChild<LLSpinCtrl>("Path Limit End");
+	childSetCommitCallback("Path Limit End",onCommitParametric,this);
+	mCtrlPathEnd->setValidateBeforeCommit( &precommitValidate );
+
+	// Taper
+	mLabelTaper = getChild<LLTextBox>("text taper2");
+	mSpinTaperX = getChild<LLSpinCtrl>("Taper X");
+	childSetCommitCallback("Taper X",onCommitParametric,this);
+	mSpinTaperX->setValidateBeforeCommit( precommitValidate );
+	mSpinTaperY = getChild<LLSpinCtrl>("Taper Y");
+	childSetCommitCallback("Taper Y",onCommitParametric,this);
+	mSpinTaperY->setValidateBeforeCommit( precommitValidate );
+	
+	// Radius Offset / Revolutions
+	mLabelRadiusOffset = getChild<LLTextBox>("text radius delta");
+	mLabelRevolutions = getChild<LLTextBox>("text revolutions");
+	mSpinRadiusOffset = getChild<LLSpinCtrl>("Radius Offset");
+	childSetCommitCallback("Radius Offset",onCommitParametric,this);
+	mSpinRadiusOffset->setValidateBeforeCommit( &precommitValidate );
+	mSpinRevolutions = getChild<LLSpinCtrl>("Revolutions");
+	childSetCommitCallback("Revolutions",onCommitParametric,this);
+	mSpinRevolutions->setValidateBeforeCommit( &precommitValidate );
+
+	// Sculpt
+	mCtrlSculptTexture = getChild<LLTextureCtrl>("sculpt texture control");
+	if (mCtrlSculptTexture)
+	{
+		mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE));
+		mCtrlSculptTexture->setCommitCallback( boost::bind(&LLPanelObject::onCommitSculpt, this, _2 ));
+		mCtrlSculptTexture->setOnCancelCallback( boost::bind(&LLPanelObject::onCancelSculpt, this, _2 ));
+		mCtrlSculptTexture->setOnSelectCallback( boost::bind(&LLPanelObject::onSelectSculpt, this, _2 ));
+		mCtrlSculptTexture->setDropCallback( boost::bind(&LLPanelObject::onDropSculpt, this, _2 ));
+		// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
+		mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+		// Allow any texture to be used during non-immediate mode.
+		mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
+		LLAggregatePermissions texture_perms;
+		if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
+		{
+			BOOL can_copy =
+				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
+				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
+			BOOL can_transfer =
+				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
+				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
+			mCtrlSculptTexture->setCanApplyImmediately(can_copy && can_transfer);
+		}
+		else
+		{
+			mCtrlSculptTexture->setCanApplyImmediately(FALSE);
+		}
+	}
+
+	mLabelSculptType = getChild<LLTextBox>("label sculpt type");
+	mCtrlSculptType = getChild<LLComboBox>("sculpt type control");
+	childSetCommitCallback("sculpt type control", onCommitSculptType, this);
+	mCtrlSculptMirror = getChild<LLCheckBoxCtrl>("sculpt mirror control");
+	childSetCommitCallback("sculpt mirror control", onCommitSculptType, this);
+	mCtrlSculptInvert = getChild<LLCheckBoxCtrl>("sculpt invert control");
+	childSetCommitCallback("sculpt invert control", onCommitSculptType, this);
+	
+	// Start with everyone disabled
+	clearCtrls();
+
+	return TRUE;
+}
+
+LLPanelObject::LLPanelObject()
+:	LLPanel(),
+	mIsPhysical(FALSE),
+	mIsTemporary(FALSE),
+	mIsPhantom(FALSE),
+	mCastShadows(TRUE),
+	mSelectedType(MI_BOX),
+	mSculptTextureRevert(LLUUID::null),
+	mSculptTypeRevert(0)
+{
+}
+
+
+LLPanelObject::~LLPanelObject()
+{
+	// Children all cleaned up by default view destructor.
+}
+
+void LLPanelObject::getState( )
+{
+	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
+	LLViewerObject* root_objectp = objectp;
+	if(!objectp)
+	{
+		objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+		// *FIX: shouldn't we just keep the child?
+		if (objectp)
+		{
+			LLViewerObject* parentp = objectp->getRootEdit();
+
+			if (parentp)
+			{
+				root_objectp = parentp;
+			}
+			else
+			{
+				root_objectp = objectp;
+			}
+		}
+	}
+
+	LLVOVolume *volobjp = NULL;
+	if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+	{
+		volobjp = (LLVOVolume *)objectp;
+	}
+
+	if( !objectp )
+	{
+		//forfeit focus
+		if (gFocusMgr.childHasKeyboardFocus(this))
+		{
+			gFocusMgr.setKeyboardFocus(NULL);
+		}
+
+		// Disable all text input fields
+		clearCtrls();
+		return;
+	}
+
+	// can move or rotate only linked group with move permissions, or sub-object with move and modify perms
+	BOOL enable_move	= objectp->permMove() && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
+	BOOL enable_scale	= objectp->permMove() && objectp->permModify();
+	BOOL enable_rotate	= objectp->permMove() && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
+
+	S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+	BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
+						 && (selected_count == 1);
+
+	if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 1)
+	{
+		enable_move = FALSE;
+		enable_scale = FALSE;
+		enable_rotate = FALSE;
+	}
+
+	LLVector3 vec;
+	if (enable_move)
+	{
+		vec = objectp->getPositionEdit();
+		mCtrlPosX->set( vec.mV[VX] );
+		mCtrlPosY->set( vec.mV[VY] );
+		mCtrlPosZ->set( vec.mV[VZ] );
+	}
+	else
+	{
+		mCtrlPosX->clear();
+		mCtrlPosY->clear();
+		mCtrlPosZ->clear();
+	}
+
+
+	mLabelPosition->setEnabled( enable_move );
+	mCtrlPosX->setEnabled(enable_move);
+	mCtrlPosY->setEnabled(enable_move);
+	mCtrlPosZ->setEnabled(enable_move);
+
+	if (enable_scale)
+	{
+		vec = objectp->getScale();
+		mCtrlScaleX->set( vec.mV[VX] );
+		mCtrlScaleY->set( vec.mV[VY] );
+		mCtrlScaleZ->set( vec.mV[VZ] );
+	}
+	else
+	{
+		mCtrlScaleX->clear();
+		mCtrlScaleY->clear();
+		mCtrlScaleZ->clear();
+	}
+
+	mLabelSize->setEnabled( enable_scale );
+	mCtrlScaleX->setEnabled( enable_scale );
+	mCtrlScaleY->setEnabled( enable_scale );
+	mCtrlScaleZ->setEnabled( enable_scale );
+
+	LLQuaternion object_rot = objectp->getRotationEdit();
+	object_rot.getEulerAngles(&(mCurEulerDegrees.mV[VX]), &(mCurEulerDegrees.mV[VY]), &(mCurEulerDegrees.mV[VZ]));
+	mCurEulerDegrees *= RAD_TO_DEG;
+	mCurEulerDegrees.mV[VX] = fmod(llround(mCurEulerDegrees.mV[VX], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
+	mCurEulerDegrees.mV[VY] = fmod(llround(mCurEulerDegrees.mV[VY], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
+	mCurEulerDegrees.mV[VZ] = fmod(llround(mCurEulerDegrees.mV[VZ], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
+
+	if (enable_rotate)
+	{
+		mCtrlRotX->set( mCurEulerDegrees.mV[VX] );
+		mCtrlRotY->set( mCurEulerDegrees.mV[VY] );
+		mCtrlRotZ->set( mCurEulerDegrees.mV[VZ] );
+	}
+	else
+	{
+		mCtrlRotX->clear();
+		mCtrlRotY->clear();
+		mCtrlRotZ->clear();
+	}
+
+	mLabelRotation->setEnabled( enable_rotate );
+	mCtrlRotX->setEnabled( enable_rotate );
+	mCtrlRotY->setEnabled( enable_rotate );
+	mCtrlRotZ->setEnabled( enable_rotate );
+
+	BOOL owners_identical;
+	LLUUID owner_id;
+	std::string owner_name;
+	owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
+
+	// BUG? Check for all objects being editable?
+	S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
+	BOOL editable = root_objectp->permModify();
+
+	// Select Single Message
+	getChildView("select_single")->setVisible( FALSE);
+	getChildView("edit_object")->setVisible( FALSE);
+	if (!editable || single_volume || selected_count <= 1)
+	{
+		getChildView("edit_object")->setVisible( TRUE);
+		getChildView("edit_object")->setEnabled(TRUE);
+	}
+	else
+	{
+		getChildView("select_single")->setVisible( TRUE);
+		getChildView("select_single")->setEnabled(TRUE);
+	}
+	// Lock checkbox - only modifiable if you own the object.
+	BOOL self_owned = (gAgent.getID() == owner_id);
+	mCheckLock->setEnabled( roots_selected > 0 && self_owned );
+
+	// More lock and debit checkbox - get the values
+	BOOL valid;
+	U32 owner_mask_on;
+	U32 owner_mask_off;
+	valid = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER, &owner_mask_on, &owner_mask_off);
+
+	if(valid)
+	{
+		if(owner_mask_on & PERM_MOVE)
+		{
+			// owner can move, so not locked
+			mCheckLock->set(FALSE);
+			mCheckLock->setTentative(FALSE);
+		}
+		else if(owner_mask_off & PERM_MOVE)
+		{
+			// owner can't move, so locked
+			mCheckLock->set(TRUE);
+			mCheckLock->setTentative(FALSE);
+		}
+		else
+		{
+			// some locked, some not locked
+			mCheckLock->set(FALSE);
+			mCheckLock->setTentative(TRUE);
+		}
+	}
+
+	BOOL is_flexible = volobjp && volobjp->isFlexible();
+
+	// Physics checkbox
+	mIsPhysical = root_objectp->usePhysics();
+	mCheckPhysics->set( mIsPhysical );
+	mCheckPhysics->setEnabled( roots_selected>0 
+								&& (editable || gAgent.isGodlike()) 
+								&& !is_flexible);
+
+	mIsTemporary = root_objectp->flagTemporaryOnRez();
+	mCheckTemporary->set( mIsTemporary );
+	mCheckTemporary->setEnabled( roots_selected>0 && editable );
+
+	mIsPhantom = root_objectp->flagPhantom();
+	mCheckPhantom->set( mIsPhantom );
+	mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible );
+
+       
+#if 0 // 1.9.2
+	mCastShadows = root_objectp->flagCastShadows();
+	mCheckCastShadows->set( mCastShadows );
+	mCheckCastShadows->setEnabled( roots_selected==1 && editable );
+#endif
+	
+	//----------------------------------------------------------------------------
+
+	S32 selected_item	= MI_BOX;
+	S32	selected_hole	= MI_HOLE_SAME;
+	BOOL enabled = FALSE;
+	BOOL hole_enabled = FALSE;
+	F32 scale_x=1.f, scale_y=1.f;
+	BOOL isMesh = FALSE;
+	
+	if( !objectp || !objectp->getVolume() || !editable || !single_volume)
+	{
+		// Clear out all geometry fields.
+		mComboBaseType->clear();
+		mSpinHollow->clear();
+		mSpinCutBegin->clear();
+		mSpinCutEnd->clear();
+		mCtrlPathBegin->clear();
+		mCtrlPathEnd->clear();
+		mSpinScaleX->clear();
+		mSpinScaleY->clear();
+		mSpinTwist->clear();
+		mSpinTwistBegin->clear();
+		mComboHoleType->clear();
+		mSpinShearX->clear();
+		mSpinShearY->clear();
+		mSpinTaperX->clear();
+		mSpinTaperY->clear();
+		mSpinRadiusOffset->clear();
+		mSpinRevolutions->clear();
+		mSpinSkew->clear();
+		
+		mSelectedType = MI_NONE;
+	}
+	else
+	{
+		// Only allowed to change these parameters for objects
+		// that you have permissions on AND are not attachments.
+		enabled = root_objectp->permModify();
+		
+		// Volume type
+		const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
+		U8 path = volume_params.getPathParams().getCurveType();
+		U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
+		U8 profile	= profile_and_hole & LL_PCODE_PROFILE_MASK;
+		U8 hole		= profile_and_hole & LL_PCODE_HOLE_MASK;
+		
+		// Scale goes first so we can differentiate between a sphere and a torus,
+		// which have the same profile and path types.
+
+		// Scale
+		scale_x = volume_params.getRatioX();
+		scale_y = volume_params.getRatioY();
+
+		BOOL linear_path = (path == LL_PCODE_PATH_LINE) || (path == LL_PCODE_PATH_FLEXIBLE);
+		if ( linear_path && profile == LL_PCODE_PROFILE_CIRCLE )
+		{
+			selected_item = MI_CYLINDER;
+		}
+		else if ( linear_path && profile == LL_PCODE_PROFILE_SQUARE )
+		{
+			selected_item = MI_BOX;
+		}
+		else if ( linear_path && profile == LL_PCODE_PROFILE_ISOTRI )
+		{
+			selected_item = MI_PRISM;
+		}
+		else if ( linear_path && profile == LL_PCODE_PROFILE_EQUALTRI )
+		{
+			selected_item = MI_PRISM;
+		}
+		else if ( linear_path && profile == LL_PCODE_PROFILE_RIGHTTRI )
+		{
+			selected_item = MI_PRISM;
+		}
+		else if (path == LL_PCODE_PATH_FLEXIBLE) // shouldn't happen
+		{
+			selected_item = MI_CYLINDER; // reasonable default
+		}
+		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y > 0.75f)
+		{
+			selected_item = MI_SPHERE;
+		}
+		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y <= 0.75f)
+		{
+			selected_item = MI_TORUS;
+		}
+		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE_HALF)
+		{
+			selected_item = MI_SPHERE;
+		}
+		else if ( path == LL_PCODE_PATH_CIRCLE2 && profile == LL_PCODE_PROFILE_CIRCLE )
+		{
+			// Spirals aren't supported.  Make it into a sphere.  JC
+			selected_item = MI_SPHERE;
+		}
+		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_EQUALTRI )
+		{
+			selected_item = MI_RING;
+		}
+		else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_SQUARE && scale_y <= 0.75f)
+		{
+			selected_item = MI_TUBE;
+		}
+		else
+		{
+			llinfos << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << llendl;
+			selected_item = MI_BOX;
+		}
+
+
+		if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+		{
+			selected_item = MI_SCULPT;
+			//LLFirstUse::useSculptedPrim();
+		}
+
+		
+		mComboBaseType	->setCurrentByIndex( selected_item );
+		mSelectedType = selected_item;
+		
+		// Grab S path
+		F32 begin_s	= volume_params.getBeginS();
+		F32 end_s	= volume_params.getEndS();
+
+		// Compute cut and advanced cut from S and T
+		F32 begin_t = volume_params.getBeginT();
+		F32 end_t	= volume_params.getEndT();
+
+		// Hollowness
+		F32 hollow = volume_params.getHollow();
+		mSpinHollow->set( 100.f * hollow );
+
+		// All hollow objects allow a shape to be selected.
+		if (hollow > 0.f)
+		{
+			switch (hole)
+			{
+			case LL_PCODE_HOLE_CIRCLE:
+				selected_hole = MI_HOLE_CIRCLE;
+				break;
+			case LL_PCODE_HOLE_SQUARE:
+				selected_hole = MI_HOLE_SQUARE;
+				break;
+			case LL_PCODE_HOLE_TRIANGLE:
+				selected_hole = MI_HOLE_TRIANGLE;
+				break;
+			case LL_PCODE_HOLE_SAME:
+			default:
+				selected_hole = MI_HOLE_SAME;
+				break;
+			}
+			mComboHoleType->setCurrentByIndex( selected_hole );
+			hole_enabled = enabled;
+		}
+		else
+		{
+			mComboHoleType->setCurrentByIndex( MI_HOLE_SAME );
+			hole_enabled = FALSE;
+		}
+
+		// Cut interpretation varies based on base object type
+		F32 cut_begin, cut_end, adv_cut_begin, adv_cut_end;
+
+		if ( selected_item == MI_SPHERE || selected_item == MI_TORUS || 
+			 selected_item == MI_TUBE   || selected_item == MI_RING )
+		{
+			cut_begin		= begin_t;
+			cut_end			= end_t;
+			adv_cut_begin	= begin_s;
+			adv_cut_end		= end_s;
+		}
+		else
+		{
+			cut_begin       = begin_s;
+			cut_end         = end_s;
+			adv_cut_begin   = begin_t;
+			adv_cut_end     = end_t;
+		}
+
+		mSpinCutBegin	->set( cut_begin );
+		mSpinCutEnd		->set( cut_end );
+		mCtrlPathBegin	->set( adv_cut_begin );
+		mCtrlPathEnd	->set( adv_cut_end );
+
+		// Twist
+		F32 twist		= volume_params.getTwist();
+		F32 twist_begin = volume_params.getTwistBegin();
+		// Check the path type for conversion.
+		if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
+		{
+			twist		*= OBJECT_TWIST_LINEAR_MAX;
+			twist_begin	*= OBJECT_TWIST_LINEAR_MAX;
+		}
+		else
+		{
+			twist		*= OBJECT_TWIST_MAX;
+			twist_begin	*= OBJECT_TWIST_MAX;
+		}
+
+		mSpinTwist		->set( twist );
+		mSpinTwistBegin	->set( twist_begin );
+
+		// Shear
+		F32 shear_x = volume_params.getShearX();
+		F32 shear_y = volume_params.getShearY();
+		mSpinShearX->set( shear_x );
+		mSpinShearY->set( shear_y );
+
+		// Taper
+		F32 taper_x	= volume_params.getTaperX();
+		F32 taper_y = volume_params.getTaperY();
+		mSpinTaperX->set( taper_x );
+		mSpinTaperY->set( taper_y );
+
+		// Radius offset.
+		F32 radius_offset = volume_params.getRadiusOffset();
+		// Limit radius offset, based on taper and hole size y.
+		F32 radius_mag = fabs(radius_offset);
+		F32 hole_y_mag = fabs(scale_y);
+		F32 taper_y_mag  = fabs(taper_y);
+		// Check to see if the taper effects us.
+		if ( (radius_offset > 0.f && taper_y < 0.f) ||
+			 (radius_offset < 0.f && taper_y > 0.f) )
+		{
+			// The taper does not help increase the radius offset range.
+			taper_y_mag = 0.f;
+		}
+		F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
+		// Enforce the maximum magnitude.
+		if (radius_mag > max_radius_mag)
+		{
+			// Check radius offset sign.
+			if (radius_offset < 0.f)
+			{
+				radius_offset = -max_radius_mag;
+			}
+			else
+			{
+				radius_offset = max_radius_mag;
+			}
+		}
+		mSpinRadiusOffset->set( radius_offset);
+
+		// Revolutions
+		F32 revolutions = volume_params.getRevolutions();
+		mSpinRevolutions->set( revolutions );
+		
+		// Skew
+		F32 skew	= volume_params.getSkew();
+		// Limit skew, based on revolutions hole size x.
+		F32 skew_mag= fabs(skew);
+		F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
+		// Discontinuity; A revolution of 1 allows skews below 0.5.
+		if ( fabs(revolutions - 1.0f) < 0.001)
+			min_skew_mag = 0.0f;
+
+		// Clip skew.
+		if (skew_mag < min_skew_mag)
+		{
+			// Check skew sign.
+			if (skew < 0.0f)
+			{
+				skew = -min_skew_mag;
+			}
+			else 
+			{
+				skew = min_skew_mag;
+			}
+		}
+		mSpinSkew->set( skew );
+	}
+	
+	// Compute control visibility, label names, and twist range.
+	// Start with defaults.
+	BOOL cut_visible                = TRUE;
+	BOOL hollow_visible             = TRUE;
+	BOOL top_size_x_visible			= TRUE;
+	BOOL top_size_y_visible			= TRUE;
+	BOOL top_shear_x_visible		= TRUE;
+	BOOL top_shear_y_visible		= TRUE;
+	BOOL twist_visible				= TRUE;
+	BOOL advanced_cut_visible		= FALSE;
+	BOOL taper_visible				= FALSE;
+	BOOL skew_visible				= FALSE;
+	BOOL radius_offset_visible		= FALSE;
+	BOOL revolutions_visible		= FALSE;
+	BOOL sculpt_texture_visible     = FALSE;
+	F32	 twist_min					= OBJECT_TWIST_LINEAR_MIN;
+	F32	 twist_max					= OBJECT_TWIST_LINEAR_MAX;
+	F32	 twist_inc					= OBJECT_TWIST_LINEAR_INC;
+
+	BOOL advanced_is_dimple = FALSE;
+	BOOL advanced_is_slice = FALSE;
+	BOOL size_is_hole = FALSE;
+
+	// Tune based on overall volume type
+	switch (selected_item)
+	{
+	case MI_SPHERE:
+		top_size_x_visible		= FALSE;
+		top_size_y_visible		= FALSE;
+		top_shear_x_visible		= FALSE;
+		top_shear_y_visible		= FALSE;
+		//twist_visible			= FALSE;
+		advanced_cut_visible	= TRUE;
+		advanced_is_dimple		= TRUE;
+		twist_min				= OBJECT_TWIST_MIN;
+		twist_max				= OBJECT_TWIST_MAX;
+		twist_inc				= OBJECT_TWIST_INC;
+		break;
+
+	case MI_TORUS:
+	case MI_TUBE:	
+	case MI_RING:
+		//top_size_x_visible		= FALSE;
+		//top_size_y_visible		= FALSE;
+	  	size_is_hole 			= TRUE;
+		skew_visible			= TRUE;
+		advanced_cut_visible	= TRUE;
+		taper_visible			= TRUE;
+		radius_offset_visible	= TRUE;
+		revolutions_visible		= TRUE;
+		twist_min				= OBJECT_TWIST_MIN;
+		twist_max				= OBJECT_TWIST_MAX;
+		twist_inc				= OBJECT_TWIST_INC;
+
+		break;
+
+	case MI_SCULPT:
+		cut_visible             = FALSE;
+		hollow_visible          = FALSE;
+		twist_visible           = FALSE;
+		top_size_x_visible      = FALSE;
+		top_size_y_visible      = FALSE;
+		top_shear_x_visible     = FALSE;
+		top_shear_y_visible     = FALSE;
+		skew_visible            = FALSE;
+		advanced_cut_visible    = FALSE;
+		taper_visible           = FALSE;
+		radius_offset_visible   = FALSE;
+		revolutions_visible     = FALSE;
+		sculpt_texture_visible  = TRUE;
+
+		break;
+		
+	case MI_BOX:
+		advanced_cut_visible	= TRUE;
+		advanced_is_slice		= TRUE;
+		break;
+
+	case MI_CYLINDER:
+		advanced_cut_visible	= TRUE;
+		advanced_is_slice		= TRUE;
+		break;
+
+	case MI_PRISM:
+		advanced_cut_visible	= TRUE;
+		advanced_is_slice		= TRUE;
+		break;
+
+	default:
+		break;
+	}
+
+	// Check if we need to change top size/hole size params.
+	switch (selected_item)
+	{
+	case MI_SPHERE:
+	case MI_TORUS:
+	case MI_TUBE:
+	case MI_RING:
+		mSpinScaleX->set( scale_x );
+		mSpinScaleY->set( scale_y );
+		mSpinScaleX->setMinValue(OBJECT_MIN_HOLE_SIZE);
+		mSpinScaleX->setMaxValue(OBJECT_MAX_HOLE_SIZE_X);
+		mSpinScaleY->setMinValue(OBJECT_MIN_HOLE_SIZE);
+		mSpinScaleY->setMaxValue(OBJECT_MAX_HOLE_SIZE_Y);
+		break;
+	default:
+		if (editable)
+		{
+			mSpinScaleX->set( 1.f - scale_x );
+			mSpinScaleY->set( 1.f - scale_y );
+			mSpinScaleX->setMinValue(-1.f);
+			mSpinScaleX->setMaxValue(1.f);
+			mSpinScaleY->setMinValue(-1.f);
+			mSpinScaleY->setMaxValue(1.f);
+		}
+		break;
+	}
+
+	// Check if we need to limit the hollow based on the hole type.
+	if (  selected_hole == MI_HOLE_SQUARE && 
+		  ( selected_item == MI_CYLINDER || selected_item == MI_TORUS ||
+		    selected_item == MI_PRISM    || selected_item == MI_RING  ||
+			selected_item == MI_SPHERE ) )
+	{
+		mSpinHollow->setMinValue(0.f);
+		mSpinHollow->setMaxValue(70.f);
+	}
+	else 
+	{
+		mSpinHollow->setMinValue(0.f);
+		mSpinHollow->setMaxValue(95.f);
+	}
+
+	// Update field enablement
+	mComboBaseType	->setEnabled( enabled );
+
+	mLabelCut		->setEnabled( enabled );
+	mSpinCutBegin	->setEnabled( enabled );
+	mSpinCutEnd		->setEnabled( enabled );
+
+	mLabelHollow	->setEnabled( enabled );
+	mSpinHollow		->setEnabled( enabled );
+	mLabelHoleType	->setEnabled( hole_enabled );
+	mComboHoleType	->setEnabled( hole_enabled );
+
+	mLabelTwist		->setEnabled( enabled );
+	mSpinTwist		->setEnabled( enabled );
+	mSpinTwistBegin	->setEnabled( enabled );
+
+	mLabelSkew		->setEnabled( enabled );
+	mSpinSkew		->setEnabled( enabled );
+
+	getChildView("scale_hole")->setVisible( FALSE);
+	getChildView("scale_taper")->setVisible( FALSE);
+	if (top_size_x_visible || top_size_y_visible)
+	{
+		if (size_is_hole)
+		{
+			getChildView("scale_hole")->setVisible( TRUE);
+			getChildView("scale_hole")->setEnabled(enabled);
+		}
+		else
+		{
+			getChildView("scale_taper")->setVisible( TRUE);
+			getChildView("scale_taper")->setEnabled(enabled);
+		}
+	}
+	
+	mSpinScaleX		->setEnabled( enabled );
+	mSpinScaleY		->setEnabled( enabled );
+
+	mLabelShear		->setEnabled( enabled );
+	mSpinShearX		->setEnabled( enabled );
+	mSpinShearY		->setEnabled( enabled );
+
+	getChildView("advanced_cut")->setVisible( FALSE);
+	getChildView("advanced_dimple")->setVisible( FALSE);
+	getChildView("advanced_slice")->setVisible( FALSE);
+
+	if (advanced_cut_visible)
+	{
+		if (advanced_is_dimple)
+		{
+			getChildView("advanced_dimple")->setVisible( TRUE);
+			getChildView("advanced_dimple")->setEnabled(enabled);
+		}
+
+		else if (advanced_is_slice)
+		{
+			getChildView("advanced_slice")->setVisible( TRUE);
+			getChildView("advanced_slice")->setEnabled(enabled);
+		}
+		else
+		{
+			getChildView("advanced_cut")->setVisible( TRUE);
+			getChildView("advanced_cut")->setEnabled(enabled);
+		}
+	}
+	
+	mCtrlPathBegin	->setEnabled( enabled );
+	mCtrlPathEnd	->setEnabled( enabled );
+
+	mLabelTaper		->setEnabled( enabled );
+	mSpinTaperX		->setEnabled( enabled );
+	mSpinTaperY		->setEnabled( enabled );
+
+	mLabelRadiusOffset->setEnabled( enabled );
+	mSpinRadiusOffset ->setEnabled( enabled );
+
+	mLabelRevolutions->setEnabled( enabled );
+	mSpinRevolutions ->setEnabled( enabled );
+
+	// Update field visibility
+	mLabelCut		->setVisible( cut_visible );
+	mSpinCutBegin	->setVisible( cut_visible );
+	mSpinCutEnd		->setVisible( cut_visible ); 
+
+	mLabelHollow	->setVisible( hollow_visible );
+	mSpinHollow		->setVisible( hollow_visible );
+	mLabelHoleType	->setVisible( hollow_visible );
+	mComboHoleType	->setVisible( hollow_visible );
+	
+	mLabelTwist		->setVisible( twist_visible );
+	mSpinTwist		->setVisible( twist_visible );
+	mSpinTwistBegin	->setVisible( twist_visible );
+	mSpinTwist		->setMinValue(  twist_min );
+	mSpinTwist		->setMaxValue(  twist_max );
+	mSpinTwist		->setIncrement( twist_inc );
+	mSpinTwistBegin	->setMinValue(  twist_min );
+	mSpinTwistBegin	->setMaxValue(  twist_max );
+	mSpinTwistBegin	->setIncrement( twist_inc );
+
+	mSpinScaleX		->setVisible( top_size_x_visible );
+	mSpinScaleY		->setVisible( top_size_y_visible );
+
+	mLabelSkew		->setVisible( skew_visible );
+	mSpinSkew		->setVisible( skew_visible );
+
+	mLabelShear		->setVisible( top_shear_x_visible || top_shear_y_visible );
+	mSpinShearX		->setVisible( top_shear_x_visible );
+	mSpinShearY		->setVisible( top_shear_y_visible );
+
+	mCtrlPathBegin	->setVisible( advanced_cut_visible );
+	mCtrlPathEnd	->setVisible( advanced_cut_visible );
+
+	mLabelTaper		->setVisible( taper_visible );
+	mSpinTaperX		->setVisible( taper_visible );
+	mSpinTaperY		->setVisible( taper_visible );
+
+	mLabelRadiusOffset->setVisible( radius_offset_visible );
+	mSpinRadiusOffset ->setVisible( radius_offset_visible );
+
+	mLabelRevolutions->setVisible( revolutions_visible );
+	mSpinRevolutions ->setVisible( revolutions_visible );
+
+	mCtrlSculptTexture->setVisible(sculpt_texture_visible);
+	mLabelSculptType->setVisible(sculpt_texture_visible);
+	mCtrlSculptType->setVisible(sculpt_texture_visible);
+
+
+	// sculpt texture
+	if (selected_item == MI_SCULPT)
+	{
+
+
+		LLUUID id;
+		LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+
+		
+		if (sculpt_params) // if we have a legal sculpt param block for this object:
+		{
+			if (mObject != objectp)  // we've just selected a new object, so save for undo
+			{
+				mSculptTextureRevert = sculpt_params->getSculptTexture();
+				mSculptTypeRevert    = sculpt_params->getSculptType();
+			}
+		
+			U8 sculpt_type = sculpt_params->getSculptType();
+			U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK;
+			BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT;
+			BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR;
+			isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH);
+
+			LLTextureCtrl*  mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
+			if(mTextureCtrl)
+			{
+				mTextureCtrl->setTentative(FALSE);
+				mTextureCtrl->setEnabled(editable && !isMesh);
+				if (editable)
+					mTextureCtrl->setImageAssetID(sculpt_params->getSculptTexture());
+				else
+					mTextureCtrl->setImageAssetID(LLUUID::null);
+			}
+
+			mComboBaseType->setEnabled(!isMesh);
+			
+			if (mCtrlSculptType)
+			{
+				mCtrlSculptType->setCurrentByIndex(sculpt_stitching);
+				mCtrlSculptType->setEnabled(editable && !isMesh);
+			}
+
+			if (mCtrlSculptMirror)
+			{
+				mCtrlSculptMirror->set(sculpt_mirror);
+				mCtrlSculptMirror->setEnabled(editable && !isMesh);
+			}
+
+			if (mCtrlSculptInvert)
+			{
+				mCtrlSculptInvert->set(sculpt_invert);
+				mCtrlSculptInvert->setEnabled(editable);
+			}
+
+			if (mLabelSculptType)
+			{
+				mLabelSculptType->setEnabled(TRUE);
+			}
+			
+		}
+	}
+	else
+	{
+		mSculptTextureRevert = LLUUID::null;		
+	}
+
+	mCtrlSculptMirror->setVisible(sculpt_texture_visible && !isMesh);
+	mCtrlSculptInvert->setVisible(sculpt_texture_visible && !isMesh);
+
+	//----------------------------------------------------------------------------
+
+	mObject = objectp;
+	mRootObject = root_objectp;
+}
+
+// static
+bool LLPanelObject::precommitValidate( const LLSD& data )
+{
+	// TODO: Richard will fill this in later.  
+	return TRUE; // FALSE means that validation failed and new value should not be commited.
+}
+
+void LLPanelObject::sendIsPhysical()
+{
+	BOOL value = mCheckPhysics->get();
+	if( mIsPhysical != value )
+	{
+		LLSelectMgr::getInstance()->selectionUpdatePhysics(value);
+		mIsPhysical = value;
+
+		llinfos << "update physics sent" << llendl;
+	}
+	else
+	{
+		llinfos << "update physics not changed" << llendl;
+	}
+}
+
+void LLPanelObject::sendIsTemporary()
+{
+	BOOL value = mCheckTemporary->get();
+	if( mIsTemporary != value )
+	{
+		LLSelectMgr::getInstance()->selectionUpdateTemporary(value);
+		mIsTemporary = value;
+
+		llinfos << "update temporary sent" << llendl;
+	}
+	else
+	{
+		llinfos << "update temporary not changed" << llendl;
+	}
+}
+
+
+void LLPanelObject::sendIsPhantom()
+{
+	BOOL value = mCheckPhantom->get();
+	if( mIsPhantom != value )
+	{
+		LLSelectMgr::getInstance()->selectionUpdatePhantom(value);
+		mIsPhantom = value;
+
+		llinfos << "update phantom sent" << llendl;
+	}
+	else
+	{
+		llinfos << "update phantom not changed" << llendl;
+	}
+}
+
+void LLPanelObject::sendCastShadows()
+{
+	BOOL value = mCheckCastShadows->get();
+	if( mCastShadows != value )
+	{
+		LLSelectMgr::getInstance()->selectionUpdateCastShadows(value);
+		mCastShadows = value;
+
+		llinfos << "update cast shadows sent" << llendl;
+	}
+	else
+	{
+		llinfos << "update cast shadows not changed" << llendl;
+	}
+}
+
+// static
+void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata )
+{
+	LLPanelObject* self = (LLPanelObject*) userdata;
+
+	if (self->mObject.isNull())
+	{
+		return;
+	}
+
+	if (self->mObject->getPCode() != LL_PCODE_VOLUME)
+	{
+		// Don't allow modification of non-volume objects.
+		return;
+	}
+
+	LLVolume *volume = self->mObject->getVolume();
+	if (!volume)
+	{
+		return;
+	}
+
+	LLVolumeParams volume_params;
+	self->getVolumeParams(volume_params);
+	
+
+	
+	// set sculpting
+	S32 selected_type = self->mComboBaseType->getCurrentIndex();
+
+	if (selected_type == MI_SCULPT)
+	{
+		self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, TRUE, TRUE);
+		LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+		if (sculpt_params)
+			volume_params.setSculptID(sculpt_params->getSculptTexture(), sculpt_params->getSculptType());
+	}
+	else
+	{
+		LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+		if (sculpt_params)
+			self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
+	}
+
+	// Update the volume, if necessary.
+	self->mObject->updateVolume(volume_params);
+
+
+	// This was added to make sure thate when changes are made, the UI
+	// adjusts to present valid options.
+	// *FIX: only some changes, ie, hollow or primitive type changes,
+	// require a refresh.
+	self->refresh();
+
+}
+
+void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
+{
+	// Figure out what type of volume to make
+	S32 was_selected_type = mSelectedType;
+	S32 selected_type = mComboBaseType->getCurrentIndex();
+	U8 profile;
+	U8 path;
+	switch ( selected_type )
+	{
+	case MI_CYLINDER:
+		profile = LL_PCODE_PROFILE_CIRCLE;
+		path = LL_PCODE_PATH_LINE;
+		break;
+
+	case MI_BOX:
+		profile = LL_PCODE_PROFILE_SQUARE;
+		path = LL_PCODE_PATH_LINE;
+		break;
+
+	case MI_PRISM:
+		profile = LL_PCODE_PROFILE_EQUALTRI;
+		path = LL_PCODE_PATH_LINE;
+		break;
+
+	case MI_SPHERE:
+		profile = LL_PCODE_PROFILE_CIRCLE_HALF;
+		path = LL_PCODE_PATH_CIRCLE;
+		break;
+
+	case MI_TORUS:
+		profile = LL_PCODE_PROFILE_CIRCLE;
+		path = LL_PCODE_PATH_CIRCLE;
+		break;
+
+	case MI_TUBE:
+		profile = LL_PCODE_PROFILE_SQUARE;
+		path = LL_PCODE_PATH_CIRCLE;
+		break;
+
+	case MI_RING:
+		profile = LL_PCODE_PROFILE_EQUALTRI;
+		path = LL_PCODE_PATH_CIRCLE;
+		break;
+
+	case MI_SCULPT:
+		profile = LL_PCODE_PROFILE_CIRCLE;
+		path = LL_PCODE_PATH_CIRCLE;
+		break;
+		
+	default:
+		llwarns << "Unknown base type " << selected_type 
+			<< " in getVolumeParams()" << llendl;
+		// assume a box
+		selected_type = MI_BOX;
+		profile = LL_PCODE_PROFILE_SQUARE;
+		path = LL_PCODE_PATH_LINE;
+		break;
+	}
+
+
+	if (path == LL_PCODE_PATH_LINE)
+	{
+		LLVOVolume *volobjp = (LLVOVolume *)(LLViewerObject*)(mObject);
+		if (volobjp->isFlexible())
+		{
+			path = LL_PCODE_PATH_FLEXIBLE;
+		}
+	}
+	
+	S32 selected_hole = mComboHoleType->getCurrentIndex();
+	U8 hole;
+	switch (selected_hole)
+	{
+	case MI_HOLE_CIRCLE: 
+		hole = LL_PCODE_HOLE_CIRCLE;
+		break;
+	case MI_HOLE_SQUARE:
+		hole = LL_PCODE_HOLE_SQUARE;
+		break;
+	case MI_HOLE_TRIANGLE:
+		hole = LL_PCODE_HOLE_TRIANGLE;
+		break;
+	case MI_HOLE_SAME:
+	default:
+		hole = LL_PCODE_HOLE_SAME;
+		break;
+	}
+
+	volume_params.setType(profile | hole, path);
+	mSelectedType = selected_type;
+	
+	// Compute cut start/end
+	F32 cut_begin	= mSpinCutBegin->get();
+	F32 cut_end		= mSpinCutEnd->get();
+
+	// Make sure at least OBJECT_CUT_INC of the object survives
+	if (cut_begin > cut_end - OBJECT_MIN_CUT_INC)
+	{
+		cut_begin = cut_end - OBJECT_MIN_CUT_INC;
+		mSpinCutBegin->set(cut_begin);
+	}
+
+	F32 adv_cut_begin	= mCtrlPathBegin->get();
+	F32 adv_cut_end		= mCtrlPathEnd->get();
+
+	// Make sure at least OBJECT_CUT_INC of the object survives
+	if (adv_cut_begin > adv_cut_end - OBJECT_MIN_CUT_INC)
+	{
+		adv_cut_begin = adv_cut_end - OBJECT_MIN_CUT_INC;
+		mCtrlPathBegin->set(adv_cut_begin);
+	}
+
+	F32 begin_s, end_s;
+	F32 begin_t, end_t;
+
+	if (selected_type == MI_SPHERE || selected_type == MI_TORUS || 
+		selected_type == MI_TUBE   || selected_type == MI_RING)
+	{
+		begin_s = adv_cut_begin;
+		end_s	= adv_cut_end;
+
+		begin_t = cut_begin;
+		end_t	= cut_end;
+	}
+	else
+	{
+		begin_s = cut_begin;
+		end_s	= cut_end;
+
+		begin_t = adv_cut_begin;
+		end_t	= adv_cut_end;
+	}
+
+	volume_params.setBeginAndEndS(begin_s, end_s);
+	volume_params.setBeginAndEndT(begin_t, end_t);
+
+	// Hollowness
+	F32 hollow = mSpinHollow->get() / 100.f;
+
+	if (  selected_hole == MI_HOLE_SQUARE && 
+		( selected_type == MI_CYLINDER || selected_type == MI_TORUS ||
+		  selected_type == MI_PRISM    || selected_type == MI_RING  ||
+		  selected_type == MI_SPHERE ) )
+	{
+		if (hollow > 0.7f) hollow = 0.7f;
+	}
+
+	volume_params.setHollow( hollow );
+
+	// Twist Begin,End
+	F32 twist_begin = mSpinTwistBegin->get();
+	F32 twist		= mSpinTwist->get();
+	// Check the path type for twist conversion.
+	if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
+	{
+		twist_begin	/= OBJECT_TWIST_LINEAR_MAX;
+		twist		/= OBJECT_TWIST_LINEAR_MAX;
+	}
+	else
+	{
+		twist_begin	/= OBJECT_TWIST_MAX;
+		twist		/= OBJECT_TWIST_MAX;
+	}
+
+	volume_params.setTwistBegin(twist_begin);
+	volume_params.setTwist(twist);
+
+	// Scale X,Y
+	F32 scale_x = mSpinScaleX->get();
+	F32 scale_y = mSpinScaleY->get();
+	if ( was_selected_type == MI_BOX || was_selected_type == MI_CYLINDER || was_selected_type == MI_PRISM)
+	{
+		scale_x = 1.f - scale_x;
+		scale_y = 1.f - scale_y;
+	}
+	
+	// Skew
+	F32 skew = mSpinSkew->get();
+
+	// Taper X,Y
+	F32 taper_x = mSpinTaperX->get();
+	F32 taper_y = mSpinTaperY->get();
+
+	// Radius offset
+	F32 radius_offset = mSpinRadiusOffset->get();
+
+	// Revolutions
+	F32 revolutions	  = mSpinRevolutions->get();
+
+	if ( selected_type == MI_SPHERE )
+	{
+		// Snap values to valid sphere parameters.
+		scale_x			= 1.0f;
+		scale_y			= 1.0f;
+		skew			= 0.0f;
+		taper_x			= 0.0f;
+		taper_y			= 0.0f;
+		radius_offset	= 0.0f;
+		revolutions		= 1.0f;
+	}
+	else if ( selected_type == MI_TORUS || selected_type == MI_TUBE ||
+			  selected_type == MI_RING )
+	{
+		scale_x = llclamp(
+			scale_x,
+			OBJECT_MIN_HOLE_SIZE,
+			OBJECT_MAX_HOLE_SIZE_X);
+		scale_y = llclamp(
+			scale_y,
+			OBJECT_MIN_HOLE_SIZE,
+			OBJECT_MAX_HOLE_SIZE_Y);
+
+		// Limit radius offset, based on taper and hole size y.
+		F32 radius_mag = fabs(radius_offset);
+		F32 hole_y_mag = fabs(scale_y);
+		F32 taper_y_mag  = fabs(taper_y);
+		// Check to see if the taper effects us.
+		if ( (radius_offset > 0.f && taper_y < 0.f) ||
+			 (radius_offset < 0.f && taper_y > 0.f) )
+		{
+			// The taper does not help increase the radius offset range.
+			taper_y_mag = 0.f;
+		}
+		F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
+		// Enforce the maximum magnitude.
+		if (radius_mag > max_radius_mag)
+		{
+			// Check radius offset sign.
+			if (radius_offset < 0.f)
+			{
+				radius_offset = -max_radius_mag;
+			}
+			else
+			{
+				radius_offset = max_radius_mag;
+			}
+		}
+			
+		// Check the skew value against the revolutions.
+		F32 skew_mag= fabs(skew);
+		F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
+		// Discontinuity; A revolution of 1 allows skews below 0.5.
+		if ( fabs(revolutions - 1.0f) < 0.001)
+			min_skew_mag = 0.0f;
+
+		// Clip skew.
+		if (skew_mag < min_skew_mag)
+		{
+			// Check skew sign.
+			if (skew < 0.0f)
+			{
+				skew = -min_skew_mag;
+			}
+			else 
+			{
+				skew = min_skew_mag;
+			}
+		}
+	}
+
+	volume_params.setRatio( scale_x, scale_y );
+	volume_params.setSkew(skew);
+	volume_params.setTaper( taper_x, taper_y );
+	volume_params.setRadiusOffset(radius_offset);
+	volume_params.setRevolutions(revolutions);
+
+	// Shear X,Y
+	F32 shear_x = mSpinShearX->get();
+	F32 shear_y = mSpinShearY->get();
+	volume_params.setShear( shear_x, shear_y );
+
+	if (selected_type == MI_SCULPT)
+	{
+		volume_params.setSculptID(LLUUID::null, 0);
+		volume_params.setBeginAndEndT   (0, 1);
+		volume_params.setBeginAndEndS   (0, 1);
+		volume_params.setHollow         (0);
+		volume_params.setTwistBegin     (0);
+		volume_params.setTwistEnd       (0);
+		volume_params.setRatio          (1, 0.5);
+		volume_params.setShear          (0, 0);
+		volume_params.setTaper          (0, 0);
+		volume_params.setRevolutions    (1);
+		volume_params.setRadiusOffset   (0);
+		volume_params.setSkew           (0);
+	}
+
+}
+
+// BUG: Make work with multiple objects
+void LLPanelObject::sendRotation(BOOL btn_down)
+{
+	if (mObject.isNull()) return;
+
+	LLVector3 new_rot(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get());
+	new_rot.mV[VX] = llround(new_rot.mV[VX], OBJECT_ROTATION_PRECISION);
+	new_rot.mV[VY] = llround(new_rot.mV[VY], OBJECT_ROTATION_PRECISION);
+	new_rot.mV[VZ] = llround(new_rot.mV[VZ], OBJECT_ROTATION_PRECISION);
+
+	// Note: must compare before conversion to radians
+	LLVector3 delta = new_rot - mCurEulerDegrees;
+
+	if (delta.magVec() >= 0.0005f)
+	{
+		mCurEulerDegrees = new_rot;
+		new_rot *= DEG_TO_RAD;
+
+		LLQuaternion rotation;
+		rotation.setQuat(new_rot.mV[VX], new_rot.mV[VY], new_rot.mV[VZ]);
+
+		if (mRootObject != mObject)
+		{
+			rotation = rotation * ~mRootObject->getRotationRegion();
+		}
+		std::vector<LLVector3>& child_positions = mObject->mUnselectedChildrenPositions ;
+		std::vector<LLQuaternion> child_rotations;
+		if (mObject->isRootEdit())
+		{
+			mObject->saveUnselectedChildrenRotation(child_rotations) ;
+			mObject->saveUnselectedChildrenPosition(child_positions) ;			
+		}
+
+		mObject->setRotation(rotation);
+		LLManip::rebuild(mObject) ;
+
+		// for individually selected roots, we need to counterrotate all the children
+		if (mObject->isRootEdit())
+		{			
+			mObject->resetChildrenRotationAndPosition(child_rotations, child_positions) ;			
+		}
+
+		if(!btn_down)
+		{
+			child_positions.clear() ;
+			LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_ROTATION | UPD_POSITION);
+		}
+	}
+}
+
+
+// BUG: Make work with multiple objects
+void LLPanelObject::sendScale(BOOL btn_down)
+{
+	if (mObject.isNull()) return;
+
+	LLVector3 newscale(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get());
+
+	LLVector3 delta = newscale - mObject->getScale();
+	if (delta.magVec() >= 0.0005f)
+	{
+		// scale changed by more than 1/2 millimeter
+
+		// check to see if we aren't scaling the textures
+		// (in which case the tex coord's need to be recomputed)
+		BOOL dont_stretch_textures = !LLManipScale::getStretchTextures();
+		if (dont_stretch_textures)
+		{
+			LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_SCALE);
+		}
+
+		mObject->setScale(newscale, TRUE);
+
+		if(!btn_down)
+		{
+			LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION);
+		}
+
+		LLSelectMgr::getInstance()->adjustTexturesByScale(TRUE, !dont_stretch_textures);
+//		llinfos << "scale sent" << llendl;
+	}
+	else
+	{
+//		llinfos << "scale not changed" << llendl;
+	}
+}
+
+
+void LLPanelObject::sendPosition(BOOL btn_down)
+{	
+	if (mObject.isNull()) return;
+
+	LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
+	LLViewerRegion* regionp = mObject->getRegion();
+
+	// Clamp the Z height
+	const F32 height = newpos.mV[VZ];
+	const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
+	const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
+
+	if (!mObject->isAttachment())
+	{
+		if ( height < min_height)
+		{
+			newpos.mV[VZ] = min_height;
+			mCtrlPosZ->set( min_height );
+		}
+		else if ( height > max_height )
+		{
+			newpos.mV[VZ] = max_height;
+			mCtrlPosZ->set( max_height );
+		}
+
+		// Grass is always drawn on the ground, so clamp its position to the ground
+		if (mObject->getPCode() == LL_PCODE_LEGACY_GRASS)
+		{
+			mCtrlPosZ->set(LLWorld::getInstance()->resolveLandHeightAgent(newpos) + 1.f);
+		}
+	}
+
+	// Make sure new position is in a valid region, so the object
+	// won't get dumped by the simulator.
+	LLVector3d new_pos_global = regionp->getPosGlobalFromRegion(newpos);
+
+	if ( LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global) )
+	{
+		// send only if the position is changed, that is, the delta vector is not zero
+		LLVector3d old_pos_global = mObject->getPositionGlobal();
+		LLVector3d delta = new_pos_global - old_pos_global;
+		// moved more than 1/2 millimeter
+		if (delta.magVec() >= 0.0005f)
+		{			
+			if (mRootObject != mObject)
+			{
+				newpos = newpos - mRootObject->getPositionRegion();
+				newpos = newpos * ~mRootObject->getRotationRegion();
+				mObject->setPositionParent(newpos);
+			}
+			else
+			{
+				mObject->setPositionEdit(newpos);
+			}			
+			
+			LLManip::rebuild(mObject) ;
+
+			// for individually selected roots, we need to counter-translate all unselected children
+			if (mObject->isRootEdit())
+			{								
+				// only offset by parent's translation
+				mObject->resetChildrenPosition(LLVector3(-delta), TRUE) ;				
+			}
+
+			if(!btn_down)
+			{
+				LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
+			}
+
+			LLSelectMgr::getInstance()->updateSelectionCenter();
+		}
+	}
+	else
+	{
+		// move failed, so we update the UI with the correct values
+		LLVector3 vec = mRootObject->getPositionRegion();
+		mCtrlPosX->set(vec.mV[VX]);
+		mCtrlPosY->set(vec.mV[VY]);
+		mCtrlPosZ->set(vec.mV[VZ]);
+	}
+}
+
+void LLPanelObject::sendSculpt()
+{
+	if (mObject.isNull())
+		return;
+	
+	LLSculptParams sculpt_params;
+
+	if (mCtrlSculptTexture)
+		sculpt_params.setSculptTexture(mCtrlSculptTexture->getImageAssetID());
+
+	U8 sculpt_type = 0;
+	
+	if (mCtrlSculptType)
+		sculpt_type |= mCtrlSculptType->getCurrentIndex();
+
+	bool enabled = sculpt_type != LL_SCULPT_TYPE_MESH;
+
+	if (mCtrlSculptMirror)
+	{
+		mCtrlSculptMirror->setEnabled(enabled ? TRUE : FALSE);
+	}
+	if (mCtrlSculptInvert)
+	{
+		mCtrlSculptInvert->setEnabled(enabled ? TRUE : FALSE);
+	}
+	
+	if ((mCtrlSculptMirror) && (mCtrlSculptMirror->get()))
+		sculpt_type |= LL_SCULPT_FLAG_MIRROR;
+
+	if ((mCtrlSculptInvert) && (mCtrlSculptInvert->get()))
+		sculpt_type |= LL_SCULPT_FLAG_INVERT;
+	
+	sculpt_params.setSculptType(sculpt_type);
+	mObject->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
+}
+
+void LLPanelObject::refresh()
+{
+	getState();
+	if (mObject.notNull() && mObject->isDead())
+	{
+		mObject = NULL;
+	}
+
+	if (mRootObject.notNull() && mRootObject->isDead())
+	{
+		mRootObject = NULL;
+	}
+	
+	bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") && 
+					   gAgent.getRegion() &&
+					   !gAgent.getRegion()->getCapability("GetMesh").empty();
+
+	F32 max_scale = get_default_max_prim_scale(LLPickInfo::isFlora(mObject));
+
+	getChild<LLSpinCtrl>("Scale X")->setMaxValue(max_scale);
+	getChild<LLSpinCtrl>("Scale Y")->setMaxValue(max_scale);
+	getChild<LLSpinCtrl>("Scale Z")->setMaxValue(max_scale);
+
+	BOOL found = mCtrlSculptType->itemExists("Mesh");
+	if (enable_mesh && !found)
+	{
+		mCtrlSculptType->add("Mesh");
+	}
+	else if (!enable_mesh && found)
+	{
+		mCtrlSculptType->remove("Mesh");
+	}
+}
+
+
+void LLPanelObject::draw()
+{
+	const LLColor4	white(	1.0f,	1.0f,	1.0f,	1);
+	const LLColor4	red(	1.0f,	0.25f,	0.f,	1);
+	const LLColor4	green(	0.f,	1.0f,	0.f,	1);
+	const LLColor4	blue(	0.f,	0.5f,	1.0f,	1);
+
+	// Tune the colors of the labels
+	LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
+
+	if (tool == LLToolCompTranslate::getInstance())
+	{
+		mCtrlPosX	->setLabelColor(red);
+		mCtrlPosY	->setLabelColor(green);
+		mCtrlPosZ	->setLabelColor(blue);
+
+		mCtrlScaleX	->setLabelColor(white);
+		mCtrlScaleY	->setLabelColor(white);
+		mCtrlScaleZ	->setLabelColor(white);
+
+		mCtrlRotX	->setLabelColor(white);
+		mCtrlRotY	->setLabelColor(white);
+		mCtrlRotZ	->setLabelColor(white);
+	}
+	else if ( tool == LLToolCompScale::getInstance() )
+	{
+		mCtrlPosX	->setLabelColor(white);
+		mCtrlPosY	->setLabelColor(white);
+		mCtrlPosZ	->setLabelColor(white);
+
+		mCtrlScaleX	->setLabelColor(red);
+		mCtrlScaleY	->setLabelColor(green);
+		mCtrlScaleZ	->setLabelColor(blue);
+
+		mCtrlRotX	->setLabelColor(white);
+		mCtrlRotY	->setLabelColor(white);
+		mCtrlRotZ	->setLabelColor(white);
+	}
+	else if ( tool == LLToolCompRotate::getInstance() )
+	{
+		mCtrlPosX	->setLabelColor(white);
+		mCtrlPosY	->setLabelColor(white);
+		mCtrlPosZ	->setLabelColor(white);
+
+		mCtrlScaleX	->setLabelColor(white);
+		mCtrlScaleY	->setLabelColor(white);
+		mCtrlScaleZ	->setLabelColor(white);
+
+		mCtrlRotX	->setLabelColor(red);
+		mCtrlRotY	->setLabelColor(green);
+		mCtrlRotZ	->setLabelColor(blue);
+	}
+	else
+	{
+		mCtrlPosX	->setLabelColor(white);
+		mCtrlPosY	->setLabelColor(white);
+		mCtrlPosZ	->setLabelColor(white);
+
+		mCtrlScaleX	->setLabelColor(white);
+		mCtrlScaleY	->setLabelColor(white);
+		mCtrlScaleZ	->setLabelColor(white);
+
+		mCtrlRotX	->setLabelColor(white);
+		mCtrlRotY	->setLabelColor(white);
+		mCtrlRotZ	->setLabelColor(white);
+	}
+
+	LLPanel::draw();
+}
+
+// virtual
+void LLPanelObject::clearCtrls()
+{
+	LLPanel::clearCtrls();
+
+	mCheckLock		->set(FALSE);
+	mCheckLock		->setEnabled( FALSE );
+	mCheckPhysics	->set(FALSE);
+	mCheckPhysics	->setEnabled( FALSE );
+	mCheckTemporary	->set(FALSE);
+	mCheckTemporary	->setEnabled( FALSE );
+	mCheckPhantom	->set(FALSE);
+	mCheckPhantom	->setEnabled( FALSE );
+	
+#if 0 // 1.9.2
+	mCheckCastShadows->set(FALSE);
+	mCheckCastShadows->setEnabled( FALSE );
+#endif
+	// Disable text labels
+	mLabelPosition	->setEnabled( FALSE );
+	mLabelSize		->setEnabled( FALSE );
+	mLabelRotation	->setEnabled( FALSE );
+	mLabelCut		->setEnabled( FALSE );
+	mLabelHollow	->setEnabled( FALSE );
+	mLabelHoleType	->setEnabled( FALSE );
+	mLabelTwist		->setEnabled( FALSE );
+	mLabelSkew		->setEnabled( FALSE );
+	mLabelShear		->setEnabled( FALSE );
+	mLabelTaper		->setEnabled( FALSE );
+	mLabelRadiusOffset->setEnabled( FALSE );
+	mLabelRevolutions->setEnabled( FALSE );
+
+	getChildView("select_single")->setVisible( FALSE);
+	getChildView("edit_object")->setVisible( TRUE);	
+	getChildView("edit_object")->setEnabled(FALSE);
+	
+	getChildView("scale_hole")->setEnabled(FALSE);
+	getChildView("scale_taper")->setEnabled(FALSE);
+	getChildView("advanced_cut")->setEnabled(FALSE);
+	getChildView("advanced_dimple")->setEnabled(FALSE);
+	getChildView("advanced_slice")->setVisible( FALSE);
+}
+
+//
+// Static functions
+//
+
+// static
+void LLPanelObject::onCommitLock(LLUICtrl *ctrl, void *data)
+{
+	// Checkbox will have toggled itself
+	LLPanelObject *self = (LLPanelObject *)data;
+
+	if(self->mRootObject.isNull()) return;
+
+	BOOL new_state = self->mCheckLock->get();
+	
+	LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, !new_state, PERM_MOVE | PERM_MODIFY);
+}
+
+// static
+void LLPanelObject::onCommitPosition( LLUICtrl* ctrl, void* userdata )
+{
+	LLPanelObject* self = (LLPanelObject*) userdata;
+	BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
+	self->sendPosition(btn_down);
+}
+
+// static
+void LLPanelObject::onCommitScale( LLUICtrl* ctrl, void* userdata )
+{
+	LLPanelObject* self = (LLPanelObject*) userdata;
+	BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
+	self->sendScale(btn_down);
+}
+
+// static
+void LLPanelObject::onCommitRotation( LLUICtrl* ctrl, void* userdata )
+{
+	LLPanelObject* self = (LLPanelObject*) userdata;
+	BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
+	self->sendRotation(btn_down);
+}
+
+// static
+void LLPanelObject::onCommitPhysics( LLUICtrl* ctrl, void* userdata )
+{
+	LLPanelObject* self = (LLPanelObject*) userdata;
+	self->sendIsPhysical();
+}
+
+// static
+void LLPanelObject::onCommitTemporary( LLUICtrl* ctrl, void* userdata )
+{
+	LLPanelObject* self = (LLPanelObject*) userdata;
+	self->sendIsTemporary();
+}
+
+// static
+void LLPanelObject::onCommitPhantom( LLUICtrl* ctrl, void* userdata )
+{
+	LLPanelObject* self = (LLPanelObject*) userdata;
+	self->sendIsPhantom();
+}
+
+// static
+void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )
+{
+	LLPanelObject* self = (LLPanelObject*) userdata;
+	self->sendCastShadows();
+}
+
+
+void LLPanelObject::onSelectSculpt(const LLSD& data)
+{
+    LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
+
+	if (mTextureCtrl)
+	{
+		mSculptTextureRevert = mTextureCtrl->getImageAssetID();
+	}
+	
+	sendSculpt();
+}
+
+
+void LLPanelObject::onCommitSculpt( const LLSD& data )
+{
+	sendSculpt();
+}
+
+BOOL LLPanelObject::onDropSculpt(LLInventoryItem* item)
+{
+    LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
+
+	if (mTextureCtrl)
+	{
+		LLUUID asset = item->getAssetUUID();
+
+		mTextureCtrl->setImageAssetID(asset);
+		mSculptTextureRevert = asset;
+	}
+
+	return TRUE;
+}
+
+
+void LLPanelObject::onCancelSculpt(const LLSD& data)
+{
+	LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
+	if(!mTextureCtrl)
+		return;
+	
+	mTextureCtrl->setImageAssetID(mSculptTextureRevert);
+	
+	sendSculpt();
+}
+
+// static
+void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)
+{
+	LLPanelObject* self = (LLPanelObject*) userdata;
+
+	self->sendSculpt();
+}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 86b56df556..fdd1199b78 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -5376,10 +5376,10 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
 	{
 		// notification was specified using the new mechanism, so we can just handle it here
 		std::string notificationID;
-		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
-		if (!LLNotifications::getInstance()->templateExists(notificationID))
-		{
-			return false;
+		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
+		if (!LLNotifications::getInstance()->templateExists(notificationID))
+		{
+			return false;
 		}
 
 		std::string llsdRaw;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 929f3ad188..e7878d8adf 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -1,5712 +1,5712 @@
-/** 
- * @file llviewerobject.cpp
- * @brief Base class for viewer objects
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llviewerobject.h"
-
-#include "llaudioengine.h"
-#include "imageids.h"
-#include "indra_constants.h"
-#include "llmath.h"
-#include "llflexibleobject.h"
-#include "llviewercontrol.h"
-#include "lldatapacker.h"
-#include "llfasttimer.h"
-#include "llfloaterreg.h"
-#include "llfontgl.h"
-#include "llframetimer.h"
-#include "llinventory.h"
-#include "llinventorydefines.h"
-#include "llmaterialtable.h"
-#include "llmutelist.h"
-#include "llnamevalue.h"
-#include "llprimitive.h"
-#include "llquantize.h"
-#include "llregionhandle.h"
-#include "llsdserialize.h"
-#include "lltree_common.h"
-#include "llxfermanager.h"
-#include "message.h"
-#include "object_flags.h"
-#include "timing.h"
-
-#include "llaudiosourcevo.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llbbox.h"
-#include "llbox.h"
-#include "llcylinder.h"
-#include "lldrawable.h"
-#include "llface.h"
-#include "llfloaterproperties.h"
-#include "llfloatertools.h"
-#include "llfollowcam.h"
-#include "llhudtext.h"
-#include "llselectmgr.h"
-#include "llrendersphere.h"
-#include "lltooldraganddrop.h"
-#include "llviewercamera.h"
-#include "llviewertexturelist.h"
-#include "llviewerinventory.h"
-#include "llviewerobjectlist.h"
-#include "llviewerparceloverlay.h"
-#include "llviewerpartsource.h"
-#include "llviewerregion.h"
-#include "llviewerstats.h"
-#include "llviewertextureanim.h"
-#include "llviewerwindow.h" // For getSpinAxis
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "llvoclouds.h"
-#include "llvograss.h"
-#include "llvoground.h"
-#include "llvolume.h"
-#include "llvolumemessage.h"
-#include "llvopartgroup.h"
-#include "llvosky.h"
-#include "llvosurfacepatch.h"
-#include "llvotextbubble.h"
-#include "llvotree.h"
-#include "llvovolume.h"
-#include "llvowater.h"
-#include "llworld.h"
-#include "llui.h"
-#include "pipeline.h"
-#include "llviewernetwork.h"
-#include "llvowlsky.h"
-#include "llmanip.h"
-#include "lltrans.h"
-#include "llsdutil.h"
-#include "llmediaentry.h"
-#include "llaccountingquota.h"
-
-//#define DEBUG_UPDATE_TYPE
-
-BOOL		LLViewerObject::sVelocityInterpolate = TRUE;
-BOOL		LLViewerObject::sPingInterpolate = TRUE; 
-
-U32			LLViewerObject::sNumZombieObjects = 0;
-S32			LLViewerObject::sNumObjects = 0;
-BOOL		LLViewerObject::sMapDebug = TRUE;
-LLColor4	LLViewerObject::sEditSelectColor(	1.0f, 1.f, 0.f, 0.3f);	// Edit OK
-LLColor4	LLViewerObject::sNoEditSelectColor(	1.0f, 0.f, 0.f, 0.3f);	// Can't edit
-S32			LLViewerObject::sAxisArrowLength(50);
-BOOL		LLViewerObject::sPulseEnabled(FALSE);
-BOOL		LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
-
-// sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime
-F64			LLViewerObject::sMaxUpdateInterpolationTime = 3.0;		// For motion interpolation: after X seconds with no updates, don't predict object motion
-F64			LLViewerObject::sPhaseOutUpdateInterpolationTime = 2.0;	// For motion interpolation: after Y seconds with no updates, taper off motion prediction
-
-
-static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
-
-// static
-LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-{
-	LLViewerObject *res = NULL;
-	LLFastTimer t1(FTM_CREATE_OBJECT);
-	
-	switch (pcode)
-	{
-	case LL_PCODE_VOLUME:
-	  res = new LLVOVolume(id, pcode, regionp); break;
-	case LL_PCODE_LEGACY_AVATAR:
-	{
-		if (id == gAgentID)
-		{
-			if (!gAgentAvatarp)
-			{
-				gAgentAvatarp = new LLVOAvatarSelf(id, pcode, regionp);
-			}
-			else 
-			{
-				gAgentAvatarp->updateRegion(regionp);
-			}
-			res = gAgentAvatarp;
-		}
-		else
-		{
-			res = new LLVOAvatar(id, pcode, regionp); 
-		}
-		static_cast<LLVOAvatar*>(res)->initInstance();
-		break;
-	}
-	case LL_PCODE_LEGACY_GRASS:
-	  res = new LLVOGrass(id, pcode, regionp); break;
-	case LL_PCODE_LEGACY_PART_SYS:
-// 	  llwarns << "Creating old part sys!" << llendl;
-// 	  res = new LLVOPart(id, pcode, regionp); break;
-	  res = NULL; break;
-	case LL_PCODE_LEGACY_TREE:
-	  res = new LLVOTree(id, pcode, regionp); break;
-	case LL_PCODE_TREE_NEW:
-// 	  llwarns << "Creating new tree!" << llendl;
-// 	  res = new LLVOTree(id, pcode, regionp); break;
-	  res = NULL; break;
-	case LL_PCODE_LEGACY_TEXT_BUBBLE:
-	  res = new LLVOTextBubble(id, pcode, regionp); break;
-	case LL_VO_CLOUDS:
-	  res = new LLVOClouds(id, pcode, regionp); break;
-	case LL_VO_SURFACE_PATCH:
-	  res = new LLVOSurfacePatch(id, pcode, regionp); break;
-	case LL_VO_SKY:
-	  res = new LLVOSky(id, pcode, regionp); break;
-	case LL_VO_VOID_WATER:
-		res = new LLVOVoidWater(id, pcode, regionp); break;
-	case LL_VO_WATER:
-		res = new LLVOWater(id, pcode, regionp); break;
-	case LL_VO_GROUND:
-	  res = new LLVOGround(id, pcode, regionp); break;
-	case LL_VO_PART_GROUP:
-	  res = new LLVOPartGroup(id, pcode, regionp); break;
-	case LL_VO_HUD_PART_GROUP:
-	  res = new LLVOHUDPartGroup(id, pcode, regionp); break;
-	case LL_VO_WL_SKY:
-	  res = new LLVOWLSky(id, pcode, regionp); break;
-	default:
-	  llwarns << "Unknown object pcode " << (S32)pcode << llendl;
-	  res = NULL; break;
-	}
-	return res;
-}
-
-LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global)
-:	LLPrimitive(),
-	mChildList(),
-	mID(id),
-	mLocalID(0),
-	mTotalCRC(0),
-	mTEImages(NULL),
-	mGLName(0),
-	mbCanSelect(TRUE),
-	mFlags(0),
-	mPhysicsShapeType(0),
-	mPhysicsGravity(0),
-	mPhysicsFriction(0),
-	mPhysicsDensity(0),
-	mPhysicsRestitution(0),
-	mDrawable(),
-	mCreateSelected(FALSE),
-	mRenderMedia(FALSE),
-	mBestUpdatePrecision(0),
-	mText(),
-	mLastInterpUpdateSecs(0.f),
-	mLastMessageUpdateSecs(0.f),
-	mLatestRecvPacketID(0),
-	mData(NULL),
-	mAudioSourcep(NULL),
-	mAudioGain(1.f),
-	mAppAngle(0.f),
-	mPixelArea(1024.f),
-	mInventory(NULL),
-	mInventorySerialNum(0),
-	mRegionp( regionp ),
-	mInventoryPending(FALSE),
-	mInventoryDirty(FALSE),
-	mDead(FALSE),
-	mOrphaned(FALSE),
-	mUserSelected(FALSE),
-	mOnActiveList(FALSE),
-	mOnMap(FALSE),
-	mStatic(FALSE),
-	mNumFaces(0),
-	mTimeDilation(1.f),
-	mRotTime(0.f),
-	mJointInfo(NULL),
-	mState(0),
-	mMedia(NULL),
-	mClickAction(0),
-	mObjectCost(0),
-	mLinksetCost(0),
-	mPhysicsCost(0),
-	mLinksetPhysicsCost(0.f),
-	mCostStale(true),
-	mPhysicsShapeUnknown(true),
-	mAttachmentItemID(LLUUID::null),
-	mLastUpdateType(OUT_UNKNOWN),
-	mLastUpdateCached(FALSE)
-{
-	if (!is_global)
-	{
-		llassert(mRegionp);
-	}
-
-	LLPrimitive::init_primitive(pcode);
-
-	// CP: added 12/2/2005 - this was being initialised to 0, not the current frame time
-	mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
-
-	mPositionRegion = LLVector3(0.f, 0.f, 0.f);
-
-	if (!is_global && mRegionp)
-	{
-		mPositionAgent = mRegionp->getOriginAgent();
-	}
-
-	LLViewerObject::sNumObjects++;
-}
-
-LLViewerObject::~LLViewerObject()
-{
-	deleteTEImages();
-
-	if(mInventory)
-	{
-		mInventory->clear();  // will deref and delete entries
-		delete mInventory;
-		mInventory = NULL;
-	}
-
-	if (mJointInfo)
-	{
-		delete mJointInfo;
-		mJointInfo = NULL;
-	}
-
-	if (mPartSourcep)
-	{
-		mPartSourcep->setDead();
-		mPartSourcep = NULL;
-	}
-
-	// Delete memory associated with extra parameters.
-	std::map<U16, ExtraParameter*>::iterator iter;
-	for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
-	{
-		if(iter->second != NULL)
-		{
-			delete iter->second->data;
-			delete iter->second;
-		}
-	}
-	mExtraParameterList.clear();
-
-	for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
-	mNameValuePairs.clear();
-	
-	delete[] mData;
-	mData = NULL;
-
-	delete mMedia;
-	mMedia = NULL;
-
-	sNumObjects--;
-	sNumZombieObjects--;
-	llassert(mChildList.size() == 0);
-
-	clearInventoryListeners();
-}
-
-void LLViewerObject::deleteTEImages()
-{
-	delete[] mTEImages;
-	mTEImages = NULL;
-}
-
-void LLViewerObject::markDead()
-{
-	if (!mDead)
-	{
-		//llinfos << "Marking self " << mLocalID << " as dead." << llendl;
-		
-		// Root object of this hierarchy unlinks itself.
-		if (getParent())
-		{
-			((LLViewerObject *)getParent())->removeChild(this);
-			// go ahead and delete any jointinfo's that we find
-			delete mJointInfo;
-			mJointInfo = NULL;
-		}
-
-		// Mark itself as dead
-		mDead = TRUE;
-		gObjectList.cleanupReferences(this);
-
-		LLViewerObject *childp;
-		while (mChildList.size() > 0)
-		{
-			childp = mChildList.back();
-			if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
-			{
-				//llinfos << "Marking child " << childp->getLocalID() << " as dead." << llendl;
-				childp->setParent(NULL); // LLViewerObject::markDead 1
-				childp->markDead();
-			}
-			else
-			{
-				// make sure avatar is no longer parented, 
-				// so we can properly set it's position
-				childp->setDrawableParent(NULL);
-				((LLVOAvatar*)childp)->getOffObject();
-				childp->setParent(NULL); // LLViewerObject::markDead 2
-			}
-			mChildList.pop_back();
-		}
-
-		if (mDrawable.notNull())
-		{
-			// Drawables are reference counted, mark as dead, then nuke the pointer.
-			mDrawable->markDead();
-			mDrawable = NULL;
-		}
-
-		if (mText)
-		{
-			mText->markDead();
-			mText = NULL;
-		}
-
-		if (mIcon)
-		{
-			mIcon->markDead();
-			mIcon = NULL;
-		}
-
-		if (mPartSourcep)
-		{
-			mPartSourcep->setDead();
-			mPartSourcep = NULL;
-		}
-
-		if (mAudioSourcep)
-		{
-			// Do some cleanup
-			if (gAudiop)
-			{
-				gAudiop->cleanupAudioSource(mAudioSourcep);
-			}
-			mAudioSourcep = NULL;
-		}
-
-		if (flagAnimSource())
-		{
-			if (isAgentAvatarValid())
-			{
-				// stop motions associated with this object
-				gAgentAvatarp->stopMotionFromSource(mID);
-			}
-		}
-
-		if (flagCameraSource())
-		{
-			LLFollowCamMgr::removeFollowCamParams(mID);
-		}
-
-		sNumZombieObjects++;
-	}
-}
-
-void LLViewerObject::dump() const
-{
-	llinfos << "Type: " << pCodeToString(mPrimitiveCode) << llendl;
-	llinfos << "Drawable: " << (LLDrawable *)mDrawable << llendl;
-	llinfos << "Update Age: " << LLFrameTimer::getElapsedSeconds() - mLastMessageUpdateSecs << llendl;
-
-	llinfos << "Parent: " << getParent() << llendl;
-	llinfos << "ID: " << mID << llendl;
-	llinfos << "LocalID: " << mLocalID << llendl;
-	llinfos << "PositionRegion: " << getPositionRegion() << llendl;
-	llinfos << "PositionAgent: " << getPositionAgent() << llendl;
-	llinfos << "PositionGlobal: " << getPositionGlobal() << llendl;
-	llinfos << "Velocity: " << getVelocity() << llendl;
-	if (mDrawable.notNull() && mDrawable->getNumFaces())
-	{
-		LLFacePool *poolp = mDrawable->getFace(0)->getPool();
-		if (poolp)
-		{
-			llinfos << "Pool: " << poolp << llendl;
-			llinfos << "Pool reference count: " << poolp->mReferences.size() << llendl;
-		}
-	}
-	//llinfos << "BoxTree Min: " << mDrawable->getBox()->getMin() << llendl;
-	//llinfos << "BoxTree Max: " << mDrawable->getBox()->getMin() << llendl;
-	/*
-	llinfos << "Velocity: " << getVelocity() << llendl;
-	llinfos << "AnyOwner: " << permAnyOwner() << " YouOwner: " << permYouOwner() << " Edit: " << mPermEdit << llendl;
-	llinfos << "UsePhysics: " << usePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << llendl;
-	llinfos << "AppAngle: " << mAppAngle << llendl;
-	llinfos << "PixelArea: " << mPixelArea << llendl;
-
-	char buffer[1000];
-	char *key;
-	for (key = mNameValuePairs.getFirstKey(); key; key = mNameValuePairs.getNextKey() )
-	{
-		mNameValuePairs[key]->printNameValue(buffer);
-		llinfos << buffer << llendl;
-	}
-	for (child_list_t::iterator iter = mChildList.begin();
-		 iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* child = *iter;
-		llinfos << "  child " << child->getID() << llendl;
-	}
-	*/
-}
-
-void LLViewerObject::printNameValuePairs() const
-{
-	for (name_value_map_t::const_iterator iter = mNameValuePairs.begin();
-		 iter != mNameValuePairs.end(); iter++)
-	{
-		LLNameValue* nv = iter->second;
-		llinfos << nv->printNameValue() << llendl;
-	}
-}
-
-void LLViewerObject::initVOClasses()
-{
-	// Initialized shared class stuff first.
-	LLVOAvatar::initClass();
-	LLVOTree::initClass();
-	llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl;
-	LLVOGrass::initClass();
-	LLVOWater::initClass();
-	LLVOVolume::initClass();
-}
-
-void LLViewerObject::cleanupVOClasses()
-{
-	LLVOGrass::cleanupClass();
-	LLVOWater::cleanupClass();
-	LLVOTree::cleanupClass();
-	LLVOAvatar::cleanupClass();
-	LLVOVolume::cleanupClass();
-}
-
-// Replaces all name value pairs with data from \n delimited list
-// Does not update server
-void LLViewerObject::setNameValueList(const std::string& name_value_list)
-{
-	// Clear out the old
-	for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
-	mNameValuePairs.clear();
-
-	// Bring in the new
-	std::string::size_type length = name_value_list.length();
-	std::string::size_type start = 0;
-	while (start < length)
-	{
-		std::string::size_type end = name_value_list.find_first_of("\n", start);
-		if (end == std::string::npos) end = length;
-		if (end > start)
-		{
-			std::string tok = name_value_list.substr(start, end - start);
-			addNVPair(tok);
-		}
-		start = end+1;
-	}
-}
-
-
-// This method returns true if the object is over land owned by the
-// agent.
-bool LLViewerObject::isReturnable()
-{
-	if (isAttachment())
-	{
-		return false;
-	}
-	std::vector<LLBBox> boxes;
-	boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
-	for (child_list_t::iterator iter = mChildList.begin();
-		 iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* child = *iter;
-		boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
-	}
-
-	return mRegionp
-		&& mRegionp->objectIsReturnable(getPositionRegion(), boxes);
-}
-
-BOOL LLViewerObject::setParent(LLViewerObject* parent)
-{
-	if(mParent != parent)
-	{
-		LLViewerObject* old_parent = (LLViewerObject*)mParent ;		
-		BOOL ret = LLPrimitive::setParent(parent);
-		if(ret && old_parent && parent)
-		{
-			old_parent->removeChild(this) ;
-		}
-		return ret ;
-	}
-
-	return FALSE ;
-}
-
-void LLViewerObject::addChild(LLViewerObject *childp)
-{
-	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
-	{
-		if (*i == childp)
-		{	//already has child
-			return;
-		}
-	}
-	
-	if (!isAvatar())
-	{
-		// propagate selection properties
-		childp->mbCanSelect = mbCanSelect;
-	}
-
-	if(childp->setParent(this))
-	{
-		mChildList.push_back(childp);
-	}
-}
-
-void LLViewerObject::removeChild(LLViewerObject *childp)
-{
-	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
-	{
-		if (*i == childp)
-		{
-			if (!childp->isAvatar() && mDrawable.notNull() && mDrawable->isActive() && childp->mDrawable.notNull() && !isAvatar())
-			{
-				gPipeline.markRebuild(childp->mDrawable, LLDrawable::REBUILD_VOLUME);
-			}
-
-			mChildList.erase(i);
-
-			if(childp->getParent() == this)
-			{
-				childp->setParent(NULL);			
-			}
-			break;
-		}
-	}
-	
-	if (childp->isSelected())
-	{
-		LLSelectMgr::getInstance()->deselectObjectAndFamily(childp);
-		BOOL add_to_end = TRUE;
-		LLSelectMgr::getInstance()->selectObjectAndFamily(childp, add_to_end);
-	}
-}
-
-void LLViewerObject::addThisAndAllChildren(std::vector<LLViewerObject*>& objects)
-{
-	objects.push_back(this);
-	for (child_list_t::iterator iter = mChildList.begin();
-		 iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* child = *iter;
-		if (!child->isAvatar())
-		{
-			child->addThisAndAllChildren(objects);
-		}
-	}
-}
-
-void LLViewerObject::addThisAndNonJointChildren(std::vector<LLViewerObject*>& objects)
-{
-	objects.push_back(this);
-	// don't add any attachments when temporarily selecting avatar
-	if (isAvatar())
-	{
-		return;
-	}
-	for (child_list_t::iterator iter = mChildList.begin();
-		 iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* child = *iter;
-		if ( (!child->isAvatar()) && (!child->isJointChild()))
-		{
-			child->addThisAndNonJointChildren(objects);
-		}
-	}
-}
-
-BOOL LLViewerObject::isChild(LLViewerObject *childp) const
-{
-	for (child_list_t::const_iterator iter = mChildList.begin();
-		 iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* testchild = *iter;
-		if (testchild == childp)
-			return TRUE;
-	}
-	return FALSE;
-}
-
-
-// returns TRUE if at least one avatar is sitting on this object
-BOOL LLViewerObject::isSeat() const
-{
-	for (child_list_t::const_iterator iter = mChildList.begin();
-		 iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* child = *iter;
-		if (child->isAvatar())
-		{
-			return TRUE;
-		}
-	}
-	return FALSE;
-
-}
-
-BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
-{
-	if (mDrawable.isNull())
-	{
-		return FALSE;
-	}
-
-	BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
-	if(!ret)
-	{
-		return FALSE ;
-	}
-	LLDrawable* old_parent = mDrawable->mParent;
-	mDrawable->mParent = parentp; 
-		
-	gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
-	if(	(old_parent != parentp && old_parent)
-		|| (parentp && parentp->isActive()))
-	{
-		// *TODO we should not be relying on setDrawable parent to call markMoved
-		gPipeline.markMoved(mDrawable, FALSE);
-	}
-	else if (!mDrawable->isAvatar())
-	{
-		mDrawable->updateXform(TRUE);
-		/*if (!mDrawable->getSpatialGroup())
-		{
-			mDrawable->movePartition();
-		}*/
-	}
-	
-	return ret;
-}
-
-// Show or hide particles, icon and HUD
-void LLViewerObject::hideExtraDisplayItems( BOOL hidden )
-{
-	if( mPartSourcep.notNull() )
-	{
-		LLViewerPartSourceScript *partSourceScript = mPartSourcep.get();
-		partSourceScript->setSuspended( hidden );
-	}
-
-	if( mText.notNull() )
-	{
-		LLHUDText *hudText = mText.get();
-		hudText->setHidden( hidden );
-	}
-
-	if( mIcon.notNull() )
-	{
-		LLHUDIcon *hudIcon = mIcon.get();
-		hudIcon->setHidden( hidden );
-	}
-}
-
-U32 LLViewerObject::checkMediaURL(const std::string &media_url)
-{
-    U32 retval = (U32)0x0;
-    if (!mMedia && !media_url.empty())
-    {
-        retval |= MEDIA_URL_ADDED;
-        mMedia = new LLViewerObjectMedia;
-        mMedia->mMediaURL = media_url;
-        mMedia->mMediaType = LLViewerObject::MEDIA_SET;
-        mMedia->mPassedWhitelist = FALSE;
-    }
-    else if (mMedia)
-    {
-        if (media_url.empty())
-        {
-            retval |= MEDIA_URL_REMOVED;
-            delete mMedia;
-            mMedia = NULL;
-        }
-        else if (mMedia->mMediaURL != media_url) // <-- This is an optimization.  If they are equal don't bother with below's test.
-        {
-            /*if (! (LLTextureEntry::getAgentIDFromMediaVersionString(media_url) == gAgent.getID() &&
-                   LLTextureEntry::getVersionFromMediaVersionString(media_url) == 
-                        LLTextureEntry::getVersionFromMediaVersionString(mMedia->mMediaURL) + 1))
-			*/
-            {
-                // If the media URL is different and WE were not the one who
-                // changed it, mark dirty.
-                retval |= MEDIA_URL_UPDATED;
-            }
-            mMedia->mMediaURL = media_url;
-            mMedia->mPassedWhitelist = FALSE;
-        }
-    }
-    return retval;
-}
-
-U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
-					 void **user_data,
-					 U32 block_num,
-					 const EObjectUpdateType update_type,
-					 LLDataPacker *dp)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	U32 retval = 0x0;
-	
-	// Coordinates of objects on simulators are region-local.
-	U64 region_handle;
-	mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
-	
-	{
-		LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
-		if(regionp != mRegionp && regionp && mRegionp)//region cross
-		{
-			//this is the redundant position and region update, but it is necessary in case the viewer misses the following 
-			//position and region update messages from sim.
-			//this redundant update should not cause any problems.
-			LLVector3 delta_pos =  mRegionp->getOriginAgent() - regionp->getOriginAgent();
-			setPositionParent(getPosition() + delta_pos); //update to the new region position immediately.
-			setRegion(regionp) ; //change the region.
-		}
-		else
-		{
-			mRegionp = regionp ;
-		}
-	}	
-	
-	if (!mRegionp)
-	{
-		U32 x, y;
-		from_region_handle(region_handle, &x, &y);
-
-		llerrs << "Object has invalid region " << x << ":" << y << "!" << llendl;
-		return retval;
-	}
-
-	U16 time_dilation16;
-	mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
-	F32 time_dilation = ((F32) time_dilation16) / 65535.f;
-	mTimeDilation = time_dilation;
-	mRegionp->setTimeDilation(time_dilation);
-
-	// this will be used to determine if we've really changed position
-	// Use getPosition, not getPositionRegion, since this is what we're comparing directly against.
-	LLVector3 test_pos_parent = getPosition();
-
-	U8  data[60+16]; // This needs to match the largest size below.
-#ifdef LL_BIG_ENDIAN
-	U16 valswizzle[4];
-#endif
-	U16	*val;
-	const F32 size = LLWorld::getInstance()->getRegionWidthInMeters();	
-	const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight();
-	const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight();
-	S32 length;
-	S32	count;
-	S32 this_update_precision = 32;		// in bits
-
-	// Temporaries, because we need to compare w/ previous to set dirty flags...
-	LLVector3 new_pos_parent;
-	LLVector3 new_vel;
-	LLVector3 new_acc;
-	LLVector3 new_angv;
-	LLVector3 old_angv = getAngularVelocity();
-	LLQuaternion new_rot;
-	LLVector3 new_scale = getScale();
-
-	U32	parent_id = 0;
-	U8	material = 0;
-	U8 click_action = 0;
-	U32 crc = 0;
-
-	bool old_special_hover_cursor = specialHoverCursor();
-
-	LLViewerObject *cur_parentp = (LLViewerObject *)getParent();
-
-	if (cur_parentp)
-	{
-		parent_id = cur_parentp->mLocalID;
-	}
-
-	if (!dp)
-	{
-		switch(update_type)
-		{
-		case OUT_FULL:
-			{
-#ifdef DEBUG_UPDATE_TYPE
-				llinfos << "Full:" << getID() << llendl;
-#endif
-				//clear cost and linkset cost
-				mCostStale = true;
-				if (isSelected())
-				{
-					gFloaterTools->dirty();
-				}
-
-				LLUUID audio_uuid;
-				LLUUID owner_id;	// only valid if audio_uuid or particle system is not null
-				F32    gain;
-				U8     sound_flags;
-
-				mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num);
-				mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_ParentID, parent_id, block_num);
-				mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_Sound, audio_uuid, block_num );
-				// HACK: Owner id only valid if non-null sound id or particle system
-				mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num );
-				mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num );
-				mesgsys->getU8Fast(  _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num );
-				mesgsys->getU8Fast(  _PREHASH_ObjectData, _PREHASH_Material, material, block_num );
-				mesgsys->getU8Fast(  _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num); 
-				mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num );
-				length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
-				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num);
-
-				mTotalCRC = crc;
-
-				// Owner ID used for sound muting or particle system muting
-				setAttachedSound(audio_uuid, owner_id, gain, sound_flags);
-
-				U8 old_material = getMaterial();
-				if (old_material != material)
-				{
-					setMaterial(material);
-					if (mDrawable.notNull())
-					{
-						gPipeline.markMoved(mDrawable, FALSE); // undamped
-					}
-				}
-				setClickAction(click_action);
-
-				count = 0;
-				LLVector4 collision_plane;
-				
-				switch(length)
-				{
-				case (60 + 16):
-					// pull out collision normal for avatar
-					htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
-					((LLVOAvatar*)this)->setFootPlane(collision_plane);
-					count += sizeof(LLVector4);
-					// fall through
-				case 60:
-					this_update_precision = 32;
-					// this is a terse update
-					// pos
-					htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-					count += sizeof(LLVector3);
-					// vel
-					htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-					count += sizeof(LLVector3);
-					// acc
-					htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-					count += sizeof(LLVector3);
-					// theta
-					{
-						LLVector3 vec;
-						htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-						new_rot.unpackFromVector3(vec);
-					}
-					count += sizeof(LLVector3);
-					// omega
-					htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-					if (new_angv.isExactlyZero())
-					{
-						// reset rotation time
-						resetRot();
-					}
-					setAngularVelocity(new_angv);
-#if LL_DARWIN
-					if (length == 76)
-					{
-						setAngularVelocity(LLVector3::zero);
-					}
-#endif
-					break;
-				case(32 + 16):
-					// pull out collision normal for avatar
-					htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
-					((LLVOAvatar*)this)->setFootPlane(collision_plane);
-					count += sizeof(LLVector4);
-					// fall through
-				case 32:
-					this_update_precision = 16;
-					test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
-
-					// This is a terse 16 update, so treat data as an array of U16's.
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					count += sizeof(U16)*3;
-					new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
-					new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
-					new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
-
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					count += sizeof(U16)*3;
-					setVelocity(LLVector3(U16_to_F32(val[VX], -size, size),
-													   U16_to_F32(val[VY], -size, size),
-													   U16_to_F32(val[VZ], -size, size)));
-
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					count += sizeof(U16)*3;
-					setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size),
-														   U16_to_F32(val[VY], -size, size),
-														   U16_to_F32(val[VZ], -size, size)));
-
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 4); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					count += sizeof(U16)*4;
-					new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
-					new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
-					new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
-					new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
-
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					new_angv.setVec(U16_to_F32(val[VX], -size, size),
-										U16_to_F32(val[VY], -size, size),
-										U16_to_F32(val[VZ], -size, size));
-					if (new_angv.isExactlyZero())
-					{
-						// reset rotation time
-						resetRot();
-					}
-					setAngularVelocity(new_angv);
-					break;
-
-				case 16:
-					this_update_precision = 8;
-					test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
-					// this is a terse 8 update
-					new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
-					new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
-					new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
-
-					setVelocity(U8_to_F32(data[3], -size, size),
-								U8_to_F32(data[4], -size, size),
-								U8_to_F32(data[5], -size, size) );
-
-					setAcceleration(U8_to_F32(data[6], -size, size),
-									U8_to_F32(data[7], -size, size),
-									U8_to_F32(data[8], -size, size) );
-
-					new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
-					new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
-					new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
-					new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
-
-					new_angv.setVec(U8_to_F32(data[13], -size, size),
-										U8_to_F32(data[14], -size, size),
-										U8_to_F32(data[15], -size, size) );
-					if (new_angv.isExactlyZero())
-					{
-						// reset rotation time
-						resetRot();
-					}
-					setAngularVelocity(new_angv);
-					break;
-				}
-
-				////////////////////////////////////////////////////
-				//
-				// Here we handle data specific to the full message.
-				//
-
-				U32 flags;
-				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
-				// clear all but local flags
-				mFlags &= FLAGS_LOCAL;
-				mFlags |= flags;
-
-				U8 state;
-				mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
-				mState = state;
-
-				// ...new objects that should come in selected need to be added to the selected list
-				mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
-
-				// Set all name value pairs
-				S32 nv_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_NameValue);
-				if (nv_size > 0)
-				{
-					std::string name_value_list;
-					mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_NameValue, name_value_list, block_num);
-					setNameValueList(name_value_list);
-				}
-
-				// Clear out any existing generic data
-				if (mData)
-				{
-					delete [] mData;
-				}
-
-				// Check for appended generic data
-				S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data);
-				if (data_size <= 0)
-				{
-					mData = NULL;
-				}
-				else
-				{
-					// ...has generic data
-					mData = new U8[data_size];
-					mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num);
-				}
-
-				S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text);
-				if (text_size > 1)
-				{
-					// Setup object text
-					if (!mText)
-					{
-						mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
-						mText->setFont(LLFontGL::getFontSansSerif());
-						mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
-						mText->setMaxLines(-1);
-						mText->setSourceObject(this);
-						mText->setOnHUDAttachment(isHUDAttachment());
-					}
-
-					std::string temp_string;
-					mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num );
-					
-					LLColor4U coloru;
-					mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num);
-
-					// alpha was flipped so that it zero encoded better
-					coloru.mV[3] = 255 - coloru.mV[3];
-					mText->setColor(LLColor4(coloru));
-					mText->setString(temp_string);
-					
-					if (mDrawable.notNull())
-					{
-						setChanged(MOVED | SILHOUETTE);
-						gPipeline.markMoved(mDrawable, FALSE); // undamped
-					}
-				}
-				else if (mText.notNull())
-				{
-					mText->markDead();
-					mText = NULL;
-				}
-
-				std::string media_url;
-				mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num);
-                retval |= checkMediaURL(media_url);
-                
-				//
-				// Unpack particle system data
-				//
-				unpackParticleSource(block_num, owner_id);
-
-				// Mark all extra parameters not used
-				std::map<U16, ExtraParameter*>::iterator iter;
-				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
-				{
-					iter->second->in_use = FALSE;
-				}
-
-				// Unpack extra parameters
-				S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams);
-				if (size > 0)
-				{
-					U8 *buffer = new U8[size];
-					mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num);
-					LLDataPackerBinaryBuffer dp(buffer, size);
-
-					U8 num_parameters;
-					dp.unpackU8(num_parameters, "num_params");
-					U8 param_block[MAX_OBJECT_PARAMS_SIZE];
-					for (U8 param=0; param<num_parameters; ++param)
-					{
-						U16 param_type;
-						S32 param_size;
-						dp.unpackU16(param_type, "param_type");
-						dp.unpackBinaryData(param_block, param_size, "param_data");
-						//llinfos << "Param type: " << param_type << ", Size: " << param_size << llendl;
-						LLDataPackerBinaryBuffer dp2(param_block, param_size);
-						unpackParameterEntry(param_type, &dp2);
-					}
-					delete[] buffer;
-				}
-
-				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
-				{
-					if (!iter->second->in_use)
-					{
-						// Send an update message in case it was formerly in use
-						parameterChanged(iter->first, iter->second->data, FALSE, false);
-					}
-				}
-
-				U8 joint_type = 0;
-				mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_JointType, joint_type, block_num);
-				if (joint_type)
-				{
-					// create new joint info 
-					if (!mJointInfo)
-					{
-						mJointInfo = new LLVOJointInfo;
-					}
-					mJointInfo->mJointType = (EHavokJointType) joint_type;
-					mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointPivot, mJointInfo->mPivot, block_num);
-					mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointAxisOrAnchor, mJointInfo->mAxisOrAnchor, block_num);
-				}
-				else if (mJointInfo)
-				{
-					// this joint info is no longer needed
-					delete mJointInfo;
-					mJointInfo = NULL;
-				}
-
-				break;
-			}
-
-		case OUT_TERSE_IMPROVED:
-			{
-#ifdef DEBUG_UPDATE_TYPE
-				llinfos << "TI:" << getID() << llendl;
-#endif
-				length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
-				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num);
-				count = 0;
-				LLVector4 collision_plane;
-				
-				switch(length)
-				{
-				case(60 + 16):
-					// pull out collision normal for avatar
-					htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
-					((LLVOAvatar*)this)->setFootPlane(collision_plane);
-					count += sizeof(LLVector4);
-					// fall through
-				case 60:
-					// this is a terse 32 update
-					// pos
-					this_update_precision = 32;
-					htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-					count += sizeof(LLVector3);
-					// vel
-					htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-					count += sizeof(LLVector3);
-					// acc
-					htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-					count += sizeof(LLVector3);
-					// theta
-					{
-						LLVector3 vec;
-						htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-						new_rot.unpackFromVector3(vec);
-					}
-					count += sizeof(LLVector3);
-					// omega
-					htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
-					if (new_angv.isExactlyZero())
-					{
-						// reset rotation time
-						resetRot();
-					}
-					setAngularVelocity(new_angv);
-#if LL_DARWIN
-					if (length == 76)
-					{
-						setAngularVelocity(LLVector3::zero);
-					}
-#endif
-					break;
-				case(32 + 16):
-					// pull out collision normal for avatar
-					htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
-					((LLVOAvatar*)this)->setFootPlane(collision_plane);
-					count += sizeof(LLVector4);
-					// fall through
-				case 32:
-					// this is a terse 16 update
-					this_update_precision = 16;
-					test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
-
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					count += sizeof(U16)*3;
-					new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
-					new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
-					new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
-
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					count += sizeof(U16)*3;
-					setVelocity(U16_to_F32(val[VX], -size, size),
-								U16_to_F32(val[VY], -size, size),
-								U16_to_F32(val[VZ], -size, size));
-
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					count += sizeof(U16)*3;
-					setAcceleration(U16_to_F32(val[VX], -size, size),
-									U16_to_F32(val[VY], -size, size),
-									U16_to_F32(val[VZ], -size, size));
-
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 8); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					count += sizeof(U16)*4;
-					new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
-					new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
-					new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
-					new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
-
-#ifdef LL_BIG_ENDIAN
-					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
-					val = valswizzle;
-#else
-					val = (U16 *) &data[count];
-#endif
-					setAngularVelocity(	U16_to_F32(val[VX], -size, size),
-										U16_to_F32(val[VY], -size, size),
-										U16_to_F32(val[VZ], -size, size));
-					break;
-
-				case 16:
-					// this is a terse 8 update
-					this_update_precision = 8;
-					test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
-					new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
-					new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
-					new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
-
-					setVelocity(U8_to_F32(data[3], -size, size),
-								U8_to_F32(data[4], -size, size),
-								U8_to_F32(data[5], -size, size) );
-
-					setAcceleration(U8_to_F32(data[6], -size, size),
-									U8_to_F32(data[7], -size, size),
-									U8_to_F32(data[8], -size, size) );
-
-					new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
-					new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
-					new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
-					new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
-
-					setAngularVelocity(	U8_to_F32(data[13], -size, size),
-										U8_to_F32(data[14], -size, size),
-										U8_to_F32(data[15], -size, size) );
-					break;
-				}
-
-				U8 state;
-				mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
-				mState = state;
-				break;
-			}
-
-		default:
-			break;
-
-		}
-	}
-	else
-	{
-		// handle the compressed case
-		LLUUID sound_uuid;
-		LLUUID	owner_id;
-		F32    gain = 0;
-		U8     sound_flags = 0;
-		F32		cutoff = 0;
-
-		U16 val[4];
-
-		U8		state;
-
-		dp->unpackU8(state, "State");
-		mState = state;
-
-		switch(update_type)
-		{
-			case OUT_TERSE_IMPROVED:
-			{
-#ifdef DEBUG_UPDATE_TYPE
-				llinfos << "CompTI:" << getID() << llendl;
-#endif
-				U8		value;
-				dp->unpackU8(value, "agent");
-				if (value)
-				{
-					LLVector4 collision_plane;
-					dp->unpackVector4(collision_plane, "Plane");
-					((LLVOAvatar*)this)->setFootPlane(collision_plane);
-				}
-				test_pos_parent = getPosition();
-				dp->unpackVector3(new_pos_parent, "Pos");
-				dp->unpackU16(val[VX], "VelX");
-				dp->unpackU16(val[VY], "VelY");
-				dp->unpackU16(val[VZ], "VelZ");
-				setVelocity(U16_to_F32(val[VX], -128.f, 128.f),
-							U16_to_F32(val[VY], -128.f, 128.f),
-							U16_to_F32(val[VZ], -128.f, 128.f));
-				dp->unpackU16(val[VX], "AccX");
-				dp->unpackU16(val[VY], "AccY");
-				dp->unpackU16(val[VZ], "AccZ");
-				setAcceleration(U16_to_F32(val[VX], -64.f, 64.f),
-								U16_to_F32(val[VY], -64.f, 64.f),
-								U16_to_F32(val[VZ], -64.f, 64.f));
-
-				dp->unpackU16(val[VX], "ThetaX");
-				dp->unpackU16(val[VY], "ThetaY");
-				dp->unpackU16(val[VZ], "ThetaZ");
-				dp->unpackU16(val[VS], "ThetaS");
-				new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
-				new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
-				new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
-				new_rot.mQ[VS] = U16_to_F32(val[VS], -1.f, 1.f);
-				dp->unpackU16(val[VX], "AccX");
-				dp->unpackU16(val[VY], "AccY");
-				dp->unpackU16(val[VZ], "AccZ");
-				setAngularVelocity(	U16_to_F32(val[VX], -64.f, 64.f),
-									U16_to_F32(val[VY], -64.f, 64.f),
-									U16_to_F32(val[VZ], -64.f, 64.f));
-			}
-			break;
-			case OUT_FULL_COMPRESSED:
-			case OUT_FULL_CACHED:
-			{
-#ifdef DEBUG_UPDATE_TYPE
-				llinfos << "CompFull:" << getID() << llendl;
-#endif
-				mCostStale = true;
-
-				if (isSelected())
-				{
-					gFloaterTools->dirty();
-				}
-	
-				dp->unpackU32(crc, "CRC");
-				mTotalCRC = crc;
-				dp->unpackU8(material, "Material");
-				U8 old_material = getMaterial();
-				if (old_material != material)
-				{
-					setMaterial(material);
-					if (mDrawable.notNull())
-					{
-						gPipeline.markMoved(mDrawable, FALSE); // undamped
-					}
-				}
-				dp->unpackU8(click_action, "ClickAction");
-				setClickAction(click_action);
-				dp->unpackVector3(new_scale, "Scale");
-				dp->unpackVector3(new_pos_parent, "Pos");
-				LLVector3 vec;
-				dp->unpackVector3(vec, "Rot");
-				new_rot.unpackFromVector3(vec);
-				setAcceleration(LLVector3::zero);
-
-				U32 value;
-				dp->unpackU32(value, "SpecialCode");
-				dp->setPassFlags(value);
-				dp->unpackUUID(owner_id, "Owner");
-
-				if (value & 0x80)
-				{
-					dp->unpackVector3(vec, "Omega");
-					setAngularVelocity(vec);
-				}
-
-				if (value & 0x20)
-				{
-					dp->unpackU32(parent_id, "ParentID");
-				}
-				else
-				{
-					parent_id = 0;
-				}
-
-				S32 sp_size;
-				U32 size;
-				if (value & 0x2)
-				{
-					sp_size = 1;
-					delete [] mData;
-					mData = new U8[1];
-					dp->unpackU8(((U8*)mData)[0], "TreeData");
-				}
-				else if (value & 0x1)
-				{
-					dp->unpackU32(size, "ScratchPadSize");
-					delete [] mData;
-					mData = new U8[size];
-					dp->unpackBinaryData((U8 *)mData, sp_size, "PartData");
-				}
-				else
-				{
-					mData = NULL;
-				}
-
-				// Setup object text
-				if (!mText && (value & 0x4))
-				{
-					mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
-					mText->setFont(LLFontGL::getFontSansSerif());
-					mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
-					mText->setMaxLines(-1); // Set to match current agni behavior.
-					mText->setSourceObject(this);
-					mText->setOnHUDAttachment(isHUDAttachment());
-				}
-
-				if (value & 0x4)
-				{
-					std::string temp_string;
-					dp->unpackString(temp_string, "Text");
-					LLColor4U coloru;
-					dp->unpackBinaryDataFixed(coloru.mV, 4, "Color");
-					coloru.mV[3] = 255 - coloru.mV[3];
-					mText->setColor(LLColor4(coloru));
-					mText->setString(temp_string);
-
-					setChanged(TEXTURE);
-				}
-				else if(mText.notNull())
-				{
-					mText->markDead();
-					mText = NULL;
-				}
-
-                std::string media_url;
-				if (value & 0x200)
-				{
-					dp->unpackString(media_url, "MediaURL");
-				}
-                retval |= checkMediaURL(media_url);
-
-				//
-				// Unpack particle system data
-				//
-				if (value & 0x8)
-				{
-					unpackParticleSource(*dp, owner_id);
-				}
-				else
-				{
-					deleteParticleSource();
-				}
-				
-				// Mark all extra parameters not used
-				std::map<U16, ExtraParameter*>::iterator iter;
-				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
-				{
-					iter->second->in_use = FALSE;
-				}
-
-				// Unpack extra params
-				U8 num_parameters;
-				dp->unpackU8(num_parameters, "num_params");
-				U8 param_block[MAX_OBJECT_PARAMS_SIZE];
-				for (U8 param=0; param<num_parameters; ++param)
-				{
-					U16 param_type;
-					S32 param_size;
-					dp->unpackU16(param_type, "param_type");
-					dp->unpackBinaryData(param_block, param_size, "param_data");
-					//llinfos << "Param type: " << param_type << ", Size: " << param_size << llendl;
-					LLDataPackerBinaryBuffer dp2(param_block, param_size);
-					unpackParameterEntry(param_type, &dp2);
-				}
-
-				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
-				{
-					if (!iter->second->in_use)
-					{
-						// Send an update message in case it was formerly in use
-						parameterChanged(iter->first, iter->second->data, FALSE, false);
-					}
-				}
-
-				if (value & 0x10)
-				{
-					dp->unpackUUID(sound_uuid, "SoundUUID");
-					dp->unpackF32(gain, "SoundGain");
-					dp->unpackU8(sound_flags, "SoundFlags");
-					dp->unpackF32(cutoff, "SoundRadius");
-				}
-
-				if (value & 0x100)
-				{
-					std::string name_value_list;
-					dp->unpackString(name_value_list, "NV");
-
-					setNameValueList(name_value_list);
-				}
-
-				mTotalCRC = crc;
-
-				setAttachedSound(sound_uuid, owner_id, gain, sound_flags);
-
-				// only get these flags on updates from sim, not cached ones
-				// Preload these five flags for every object.
-				// Finer shades require the object to be selected, and the selection manager
-				// stores the extended permission info.
-				U32 flags;
-				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
-				// keep local flags and overwrite remote-controlled flags
-				mFlags = (mFlags & FLAGS_LOCAL) | flags;
-
-					// ...new objects that should come in selected need to be added to the selected list
-				mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
-			}
-			break;
-
-		default:
-			break;
-		}
-	}
-
-	//
-	// Fix object parenting.
-	//
-	BOOL b_changed_status = FALSE;
-
-	if (OUT_TERSE_IMPROVED != update_type)
-	{
-		// We only need to update parenting on full updates, terse updates
-		// don't send parenting information.
-		if (!cur_parentp)
-		{
-			if (parent_id == 0)
-			{
-				// No parent now, no parent in message -> do nothing
-			}
-			else
-			{
-				// No parent now, new parent in message -> attach to that parent if possible
-				LLUUID parent_uuid;
-				LLViewerObjectList::getUUIDFromLocal(parent_uuid,
-														parent_id,
-														mesgsys->getSenderIP(),
-														mesgsys->getSenderPort());
-
-				LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid);
-
-				//
-				// Check to see if we have the corresponding viewer object for the parent.
-				//
-				if (sent_parentp && sent_parentp->getParent() == this)
-				{
-					// Try to recover if we attempt to attach a parent to its child
-					llwarns << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << llendl;
-					this->removeChild(sent_parentp);
-					sent_parentp->setDrawableParent(NULL);
-				}
-				
-				if (sent_parentp && (sent_parentp != this) && !sent_parentp->isDead())
-				{
-					//
-					// We have a viewer object for the parent, and it's not dead.
-					// Do the actual reparenting here.
-					//
-
-					// new parent is valid
-					b_changed_status = TRUE;
-					// ...no current parent, so don't try to remove child
-					if (mDrawable.notNull())
-					{
-						if (mDrawable->isDead() || !mDrawable->getVObj())
-						{
-							llwarns << "Drawable is dead or no VObj!" << llendl;
-							sent_parentp->addChild(this);
-						}
-						else
-						{
-							if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 1
-							{
-								// Bad, we got a cycle somehow.
-								// Kill both the parent and the child, and
-								// set cache misses for both of them.
-								llwarns << "Attempting to recover from parenting cycle!" << llendl;
-								llwarns << "Killing " << sent_parentp->getID() << " and " << getID() << llendl;
-								llwarns << "Adding to cache miss list" << llendl;
-								setParent(NULL);
-								sent_parentp->setParent(NULL);
-								getRegion()->addCacheMissFull(getLocalID());
-								getRegion()->addCacheMissFull(sent_parentp->getLocalID());
-								gObjectList.killObject(sent_parentp);
-								gObjectList.killObject(this);
-								return retval;
-							}
-							sent_parentp->addChild(this);
-							// make sure this object gets a non-damped update
-							if (sent_parentp->mDrawable.notNull())
-							{
-								gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
-							}
-						}
-					}
-					else
-					{
-						sent_parentp->addChild(this);
-					}
-					
-					// Show particles, icon and HUD
-					hideExtraDisplayItems( FALSE );
-
-					setChanged(MOVED | SILHOUETTE);
-				}
-				else
-				{
-					//
-					// No corresponding viewer object for the parent, put the various
-					// pieces on the orphan list.
-					//
-					
-					//parent_id
-					U32 ip = mesgsys->getSenderIP();
-					U32 port = mesgsys->getSenderPort();
-					
-					gObjectList.orphanize(this, parent_id, ip, port);
-
-					// Hide particles, icon and HUD
-					hideExtraDisplayItems( TRUE );
-				}
-			}
-		}
-		else
-		{
-			// BUG: this is a bad assumption once border crossing is alowed
-			if (  (parent_id == cur_parentp->mLocalID)
-				&&(update_type == OUT_TERSE_IMPROVED))
-			{
-				// Parent now, same parent in message -> do nothing
-
-				// Debugging for suspected problems with local ids.
-				//LLUUID parent_uuid;
-				//LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, mesgsys->getSenderIP(), mesgsys->getSenderPort() );
-				//if (parent_uuid != cur_parentp->getID() )
-				//{
-				//	llerrs << "Local ID match but UUID mismatch of viewer object" << llendl;
-				//}
-			}
-			else
-			{
-				// Parented now, different parent in message
-				LLViewerObject *sent_parentp;
-				if (parent_id == 0)
-				{
-					//
-					// This object is no longer parented, we sent in a zero parent ID.
-					//
-					sent_parentp = NULL;
-				}
-				else
-				{
-					LLUUID parent_uuid;
-					LLViewerObjectList::getUUIDFromLocal(parent_uuid,
-														parent_id,
-														gMessageSystem->getSenderIP(),
-														gMessageSystem->getSenderPort());
-					sent_parentp = gObjectList.findObject(parent_uuid);
-					
-					if (isAvatar())
-					{
-						// This logic is meant to handle the case where a sitting avatar has reached a new sim
-						// ahead of the object she was sitting on (which is common as objects are transfered through
-						// a slower route than agents)...
-						// In this case, the local id for the object will not be valid, since the viewer has not received
-						// a full update for the object from that sim yet, so we assume that the agent is still sitting
-						// where she was originally. --RN
-						if (!sent_parentp)
-						{
-							sent_parentp = cur_parentp;
-						}
-					}
-					else if (!sent_parentp)
-					{
-						//
-						// Switching parents, but we don't know the new parent.
-						//
-						U32 ip = mesgsys->getSenderIP();
-						U32 port = mesgsys->getSenderPort();
-
-						// We're an orphan, flag things appropriately.
-						gObjectList.orphanize(this, parent_id, ip, port);
-					}
-				}
-
-				// Reattach if possible.
-				if (sent_parentp && sent_parentp != cur_parentp && sent_parentp != this)
-				{
-					// New parent is valid, detach and reattach
-					b_changed_status = TRUE;
-					if (mDrawable.notNull())
-					{
-						if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 2
-						{
-							// Bad, we got a cycle somehow.
-							// Kill both the parent and the child, and
-							// set cache misses for both of them.
-							llwarns << "Attempting to recover from parenting cycle!" << llendl;
-							llwarns << "Killing " << sent_parentp->getID() << " and " << getID() << llendl;
-							llwarns << "Adding to cache miss list" << llendl;
-							setParent(NULL);
-							sent_parentp->setParent(NULL);
-							getRegion()->addCacheMissFull(getLocalID());
-							getRegion()->addCacheMissFull(sent_parentp->getLocalID());
-							gObjectList.killObject(sent_parentp);
-							gObjectList.killObject(this);
-							return retval;
-						}
-						// make sure this object gets a non-damped update
-					}
-					cur_parentp->removeChild(this);
-					sent_parentp->addChild(this);
-					setChanged(MOVED | SILHOUETTE);
-					sent_parentp->setChanged(MOVED | SILHOUETTE);
-					if (sent_parentp->mDrawable.notNull())
-					{
-						gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
-					}
-				}
-				else if (!sent_parentp)
-				{
-					bool remove_parent = true;
-					// No new parent, or the parent that we sent doesn't exist on the viewer.
-					LLViewerObject *parentp = (LLViewerObject *)getParent();
-					if (parentp)
-					{
-						if (parentp->getRegion() != getRegion())
-						{
-							// This is probably an object flying across a region boundary, the
-							// object probably ISN'T being reparented, but just got an object
-							// update out of order (child update before parent).
-							//llinfos << "Don't reparent object handoffs!" << llendl;
-							remove_parent = false;
-						}
-					}
-
-					if (remove_parent)
-					{
-						b_changed_status = TRUE;
-						if (mDrawable.notNull())
-						{
-							// clear parent to removeChild can put the drawable on the damped list
-							setDrawableParent(NULL); // LLViewerObject::processUpdateMessage 3
-						}
-
-						cur_parentp->removeChild(this);
-
-						if (mJointInfo && !parent_id)
-						{
-							// since this object is no longer parent-relative
-							// we make sure we delete any joint info
-							delete mJointInfo;
-							mJointInfo = NULL;
-						}
-
-						setChanged(MOVED | SILHOUETTE);
-
-						if (mDrawable.notNull())
-						{
-							// make sure this object gets a non-damped update
-							gPipeline.markMoved(mDrawable, FALSE); // undamped
-						}
-					}
-				}
-			}
-		}
-	}
-
-	new_rot.normQuat();
-
-	if (sPingInterpolate)
-	{ 
-		LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
-		if (cdp)
-		{
-			F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped);
-			LLVector3 diff = getVelocity() * ping_delay; 
-			new_pos_parent += diff;
-		}
-		else
-		{
-			llwarns << "findCircuit() returned NULL; skipping interpolation" << llendl;
-		}
-	}
-
-	//////////////////////////
-	//
-	// Set the generic change flags...
-	//
-	//
-
-	// WTF?   If we're going to skip this message, why are we 
-	// doing all the parenting, etc above?
-	U32 packet_id = mesgsys->getCurrentRecvPacketID(); 
-	if (packet_id < mLatestRecvPacketID && 
-		mLatestRecvPacketID - packet_id < 65536)
-	{
-		//skip application of this message, it's old
-		return retval;
-	}
-
-	mLatestRecvPacketID = packet_id;
-
-	// Set the change flags for scale
-	if (new_scale != getScale())
-	{
-		setChanged(SCALED | SILHOUETTE);
-		setScale(new_scale);  // Must follow setting permYouOwner()
-	}
-
-	// first, let's see if the new position is actually a change
-
-	//static S32 counter = 0;
-
-	F32 vel_mag_sq = getVelocity().magVecSquared();
-	F32 accel_mag_sq = getAcceleration().magVecSquared();
-
-	if (  ((b_changed_status)||(test_pos_parent != new_pos_parent))
-		||(  (!isSelected())
-		   &&(  (vel_mag_sq != 0.f)
-			  ||(accel_mag_sq != 0.f)
-			  ||(this_update_precision > mBestUpdatePrecision))))
-	{
-		mBestUpdatePrecision = this_update_precision;
-		
-		LLVector3 diff = new_pos_parent - test_pos_parent ;
-		F32 mag_sqr = diff.magVecSquared() ;
-		if(llfinite(mag_sqr)) 
-		{
-			setPositionParent(new_pos_parent);
-		}
-		else
-		{
-			llwarns << "Can not move the object/avatar to an infinite location!" << llendl ;	
-
-			retval |= INVALID_UPDATE ;
-		}
-
-		if (mParent && ((LLViewerObject*)mParent)->isAvatar())
-		{
-			// we have changed the position of an attachment, so we need to clamp it
-			LLVOAvatar *avatar = (LLVOAvatar*)mParent;
-
-			avatar->clampAttachmentPositions();
-		}
-		
-		// If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps
-		if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) )
-		{
-			LLViewerStats::getInstance()->mAgentPositionSnaps.push( diff.length() );
-		}
-	}
-
-	if (new_rot != mLastRot
-		|| new_angv != old_angv)
-	{
-		if (new_rot != mLastRot)
-		{
-			mLastRot = new_rot;
-			setRotation(new_rot);
-		}
-		
-		setChanged(ROTATED | SILHOUETTE);
-		
-		resetRot();
-	}
-
-
-	if ( gShowObjectUpdates )
-	{
-		if (!((mPrimitiveCode == LL_PCODE_LEGACY_AVATAR) && (((LLVOAvatar *) this)->isSelf()))
-			&& mRegionp)
-		{
-			LLViewerObject* object = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, mRegionp);
-			LLVOTextBubble* bubble = (LLVOTextBubble*) object;
-
-			if (update_type == OUT_TERSE_IMPROVED)
-			{
-				bubble->mColor.setVec(0.f, 0.f, 1.f, 1.f);
-			}
-			else
-			{
-				bubble->mColor.setVec(1.f, 0.f, 0.f, 1.f);
-			}
-			object->setPositionGlobal(getPositionGlobal());
-			gPipeline.addObject(object);
-		}
-	}
-
-	if ((0.0f == vel_mag_sq) && 
-		(0.0f == accel_mag_sq) &&
-		(0.0f == getAngularVelocity().magVecSquared()))
-	{
-		mStatic = TRUE; // This object doesn't move!
-	}
-	else
-	{
-		mStatic = FALSE;
-	}
-
-// BUG: This code leads to problems during group rotate and any scale operation.
-// Small discepencies between the simulator and viewer representations cause the 
-// selection center to creep, leading to objects moving around the wrong center.
-// 
-// Removing this, however, means that if someone else drags an object you have
-// selected, your selection center and dialog boxes will be wrong.  It also means
-// that higher precision information on selected objects will be ignored.
-//
-// I believe the group rotation problem is fixed.  JNC 1.21.2002
-//
-	// Additionally, if any child is selected, need to update the dialogs and selection
-	// center.
-	BOOL needs_refresh = mUserSelected;
-	for (child_list_t::iterator iter = mChildList.begin();
-		 iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* child = *iter;
-		needs_refresh = needs_refresh || child->mUserSelected;
-	}
-
-	if (needs_refresh)
-	{
-		LLSelectMgr::getInstance()->updateSelectionCenter();
-		dialog_refresh_all();
-	} 
-
-
-	// Mark update time as approx. now, with the ping delay.
-	// Ping delay is off because it's not set for velocity interpolation, causing
-	// much jumping and hopping around...
-
-//	U32 ping_delay = mesgsys->mCircuitInfo.getPingDelay();
-	mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
-	mLastMessageUpdateSecs = mLastInterpUpdateSecs;
-	if (mDrawable.notNull())
-	{
-		// Don't clear invisibility flag on update if still orphaned!
-		if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned)
-		{
-// 			lldebugs << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << llendl;
-			mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
-		}
-	}
-
-	// Update special hover cursor status
-	bool special_hover_cursor = specialHoverCursor();
-	if (old_special_hover_cursor != special_hover_cursor
-		&& mDrawable.notNull())
-	{
-		mDrawable->updateSpecialHoverCursor(special_hover_cursor);
-	}
-
-	return retval;
-}
-
-BOOL LLViewerObject::isActive() const
-{
-	return TRUE;
-}
-
-
-
-BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
-{
-	static LLFastTimer::DeclareTimer ftm("Viewer Object");
-	LLFastTimer t(ftm);
-
-	if (mDead)
-	{
-		// It's dead.  Don't update it.
-		return TRUE;
-	}
-
-	// CRO - don't velocity interp linked objects!
-	// Leviathan - but DO velocity interp joints
-	if (!mStatic && sVelocityInterpolate && !isSelected())
-	{
-		// calculate dt from last update
-		F32 dt_raw = (F32)(time - mLastInterpUpdateSecs);
-		F32 dt = mTimeDilation * dt_raw;
-
-		if (!mJointInfo)
-		{
-			applyAngularVelocity(dt);
-		}
-
-		LLViewerObject *parentp = (LLViewerObject *) getParent();
-		if (mJointInfo)
-		{
-			if (parentp)
-			{
-				// do parent-relative stuff
-				LLVector3 ang_vel = getAngularVelocity();
-				F32 omega = ang_vel.magVecSquared();
-				F32 angle = 0.0f;
-				LLQuaternion dQ;
-				if (omega > 0.00001f)
-				{
-					omega = sqrt(omega);
-					angle = omega * dt;
-					dQ.setQuat(angle, ang_vel);
-				}
-				LLVector3 pos = getPosition();
-	
-				if (HJT_HINGE == mJointInfo->mJointType)
-				{
-					// hinge = uniform circular motion
-					LLVector3 parent_pivot = getVelocity();
-					LLVector3 parent_axis = getAcceleration();
-	
-					angle = dt * (ang_vel * mJointInfo->mAxisOrAnchor);	// AxisOrAnchor = axis
-					dQ.setQuat(angle, mJointInfo->mAxisOrAnchor);		// AxisOrAnchor = axis
-					LLVector3 pivot_offset = pos - mJointInfo->mPivot;	// pos in pivot-frame
-					pivot_offset = pivot_offset * dQ;					// new rotated pivot-frame pos
-					pos = mJointInfo->mPivot + pivot_offset;			// parent-frame
-					LLViewerObject::setPosition(pos);
-					LLQuaternion Q_PC = getRotation();
-					setRotation(Q_PC * dQ);
-					mLastInterpUpdateSecs = time;
-				}
-				else if (HJT_POINT == mJointInfo->mJointType)
-						// || HJT_LPOINT == mJointInfo->mJointType)
-				{
-					// point-to-point = spin about axis and uniform circular motion
-					// 					of axis about the pivot point
-					//
-					// NOTE: this interpolation scheme is not quite good enough to
-					// reduce the bandwidth -- needs a gravitational correction. 
-					// Similarly for hinges with axes that deviate from vertical.
-	
-					LLQuaternion Q_PC = getRotation();
-					Q_PC = Q_PC * dQ;
-					setRotation(Q_PC);
-
-					LLVector3 pivot_to_child = - mJointInfo->mAxisOrAnchor;	// AxisOrAnchor = anchor
-					pos = mJointInfo->mPivot + pivot_to_child * Q_PC;
-					LLViewerObject::setPosition(pos);
-					mLastInterpUpdateSecs = time;
-				}
-				/* else if (HJT_WHEEL == mJointInfo->mJointInfo)
-				{
-					// wheel = uniform rotation about axis, with linear
-					//		   velocity interpolation (if any)
-					LLVector3 parent_axis = getAcceleration();	// HACK -- accel stores the parent-axis (parent-frame)
-	
-					LLQuaternion Q_PC = getRotation();
-	
-					angle = dt * (parent_axis * ang_vel);
-					dQ.setQuat(angle, parent_axis);
-	
-					Q_PC = Q_PC * dQ;
-					setRotation(Q_PC);
-
-					pos = getPosition() + dt * getVelocity();
-					LLViewerObject::setPosition(pos);
-					mLastInterpUpdateSecs = time;
-				}*/
-			}
-		}
-		else if (isAttachment())
-		{
-			mLastInterpUpdateSecs = time;
-			return TRUE;
-		}
-		else
-		{	// Move object based on it's velocity and rotation
-			interpolateLinearMotion(time, dt);
-		}
-	}
-
-	updateDrawable(FALSE);
-
-	return TRUE;
-}
-
-
-// Move an object due to idle-time viewer side updates by iterpolating motion
-void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)
-{
-	// linear motion
-	// PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
-	// updates represents the average velocity of the last timestep, rather than the final velocity.
-	// the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically
-	// 
-	// *TODO: should also wrap linear accel/velocity in check
-	// to see if object is selected, instead of explicitly
-	// zeroing it out	
-
-	F64 time_since_last_update = time - mLastMessageUpdateSecs;
-	if (time_since_last_update <= 0.0 || dt <= 0.f)
-	{
-		return;
-	}
-
-	LLVector3 accel = getAcceleration();
-	LLVector3 vel 	= getVelocity();
-	
-	if (sMaxUpdateInterpolationTime <= 0.0)
-	{	// Old code path ... unbounded, simple interpolation
-		if (!(accel.isExactlyZero() && vel.isExactlyZero()))
-		{
-			LLVector3 pos   = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;  
-		
-			// region local  
-			setPositionRegion(pos + getPositionRegion());
-			setVelocity(vel + accel*dt);	
-			
-			// for objects that are spinning but not translating, make sure to flag them as having moved
-			setChanged(MOVED | SILHOUETTE);
-		}
-	}
-	else if (!accel.isExactlyZero() || !vel.isExactlyZero())		// object is moving
-	{	// Object is moving, and hasn't been too long since we got an update from the server
-		
-		// Calculate predicted position and velocity
-		LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;	
-		LLVector3 new_v = accel * dt;
-
-		if (time_since_last_update > sPhaseOutUpdateInterpolationTime &&
-			sPhaseOutUpdateInterpolationTime > 0.0)
-		{	// Haven't seen a viewer update in a while, check to see if the ciruit is still active
-			if (mRegionp)
-			{	// The simulator will NOT send updates if the object continues normally on the path
-				// predicted by the velocity and the acceleration (often gravity) sent to the viewer
-				// So check to see if the circuit is blocked, which means the sim is likely in a long lag
-				LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() );
-				if (cdp)
-				{
-					// Find out how many seconds since last packet arrived on the circuit
-					F64 time_since_last_packet = LLMessageSystem::getMessageTimeSeconds() - cdp->getLastPacketInTime();
-
-					if (!cdp->isAlive() ||		// Circuit is dead or blocked
-						 cdp->isBlocked() ||	// or doesn't seem to be getting any packets
-						 (time_since_last_packet > sPhaseOutUpdateInterpolationTime))
-					{
-						// Start to reduce motion interpolation since we haven't seen a server update in a while
-						F64 time_since_last_interpolation = time - mLastInterpUpdateSecs;
-						F64 phase_out = 1.0;
-						if (time_since_last_update > sMaxUpdateInterpolationTime)
-						{	// Past the time limit, so stop the object
-							phase_out = 0.0;
-							//llinfos << "Motion phase out to zero" << llendl;
-
-							// Kill angular motion as well.  Note - not adding this due to paranoia
-							// about stopping rotation for llTargetOmega objects and not having it restart
-							// setAngularVelocity(LLVector3::zero);
-						}
-						else if (mLastInterpUpdateSecs - mLastMessageUpdateSecs > sPhaseOutUpdateInterpolationTime)
-						{	// Last update was already phased out a bit
-							phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / 
-										(sMaxUpdateInterpolationTime - time_since_last_interpolation);
-							//llinfos << "Continuing motion phase out of " << (F32) phase_out << llendl;
-						}
-						else
-						{	// Phase out from full value
-							phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / 
-										(sMaxUpdateInterpolationTime - sPhaseOutUpdateInterpolationTime);
-							//llinfos << "Starting motion phase out of " << (F32) phase_out << llendl;
-						}
-						phase_out = llclamp(phase_out, 0.0, 1.0);
-
-						new_pos = new_pos * ((F32) phase_out);
-						new_v = new_v * ((F32) phase_out);
-					}
-				}
-			}
-		}
-
-		new_pos = new_pos + getPositionRegion();
-		new_v = new_v + vel;
-
-
-		// Clamp interpolated position to minimum underground and maximum region height
-		LLVector3d new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos);
-		F32 min_height;
-		if (isAvatar())
-		{	// Make a better guess about AVs not going underground
-			min_height = LLWorld::getInstance()->resolveLandHeightGlobal(new_pos_global);
-			min_height += (0.5f * getScale().mV[VZ]);
-		}
-		else
-		{	// This will put the object underground, but we can't tell if it will stop 
-			// at ground level or not
-			min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global);
-		}
-
-		new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]);
-		new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]);
-
-		// Check to see if it's going off the region
-		LLVector3 temp(new_pos);
-		if (temp.clamp(0.f, mRegionp->getWidth()))
-		{	// Going off this region, so see if we might end up on another region
-			LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
-			new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos);		// Re-fetch in case it got clipped above
-
-			// Clip the positions to known regions
-			LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global);
-			if (clip_pos_global != new_pos_global)
-			{	// Was clipped, so this means we hit a edge where there is no region to enter
-				
-				//llinfos << "Hit empty region edge, clipped predicted position to " << mRegionp->getPosRegionFromGlobal(clip_pos_global)
-				//	<< " from " << new_pos << llendl;
-				new_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
-				
-				// Stop motion and get server update for bouncing on the edge
-				new_v.clear();
-				setAcceleration(LLVector3::zero);
-			}
-			else
-			{	// Let predicted movement cross into another region
-				//llinfos << "Predicting region crossing to " << new_pos << llendl;
-			}
-		}
-
-		// Set new position and velocity
-		setPositionRegion(new_pos);
-		setVelocity(new_v);	
-		
-		// for objects that are spinning but not translating, make sure to flag them as having moved
-		setChanged(MOVED | SILHOUETTE);
-	}		
-
-	// Update the last time we did anything
-	mLastInterpUpdateSecs = time;
-}
-
-
-
-BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	
-	delete [] mData;
-
-	if (datap)
-	{
-		mData = new U8[data_size];
-		if (!mData)
-		{
-			return FALSE;
-		}
-		memcpy(mData, datap, data_size);		/* Flawfinder: ignore */
-	}
-	return TRUE;
-}
-
-// delete an item in the inventory, but don't tell the server. This is
-// used internally by remove, update, and savescript.
-// This will only delete the first item with an item_id in the list
-void LLViewerObject::deleteInventoryItem(const LLUUID& item_id)
-{
-	if(mInventory)
-	{
-		LLInventoryObject::object_list_t::iterator it = mInventory->begin();
-		LLInventoryObject::object_list_t::iterator end = mInventory->end();
-		for( ; it != end; ++it )
-		{
-			if((*it)->getUUID() == item_id)
-			{
-				// This is safe only because we return immediatly.
-				mInventory->erase(it); // will deref and delete it
-				return;
-			}
-		}
-		doInventoryCallback();
-	}
-}
-
-void LLViewerObject::doUpdateInventory(
-	LLPointer<LLViewerInventoryItem>& item,
-	U8 key,
-	bool is_new)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-
-	LLViewerInventoryItem* old_item = NULL;
-	if(TASK_INVENTORY_ITEM_KEY == key)
-	{
-		old_item = (LLViewerInventoryItem*)getInventoryObject(item->getUUID());
-	}
-	else if(TASK_INVENTORY_ASSET_KEY == key)
-	{
-		old_item = getInventoryItemByAsset(item->getAssetUUID());
-	}
-	LLUUID item_id;
-	LLUUID new_owner;
-	LLUUID new_group;
-	BOOL group_owned = FALSE;
-	if(old_item)
-	{
-		item_id = old_item->getUUID();
-		new_owner = old_item->getPermissions().getOwner();
-		new_group = old_item->getPermissions().getGroup();
-		group_owned = old_item->getPermissions().isGroupOwned();
-		old_item = NULL;
-	}
-	else
-	{
-		item_id = item->getUUID();
-	}
-	if(!is_new && mInventory)
-	{
-		// Attempt to update the local inventory. If we can get the
-		// object perm, we have perfect visibility, so we want the
-		// serial number to match. Otherwise, take our best guess and
-		// make sure that the serial number does not match.
-		deleteInventoryItem(item_id);
-		LLPermissions perm(item->getPermissions());
-		LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this);
-		bool is_atomic = ((S32)LLAssetType::AT_OBJECT == item->getType()) ? false : true;
-		if(obj_perm)
-		{
-			perm.setOwnerAndGroup(LLUUID::null, obj_perm->getOwner(), obj_perm->getGroup(), is_atomic);
-		}
-		else
-		{
-			if(group_owned)
-			{
-				perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
-			}
-			else if(!new_owner.isNull())
-			{
-				// The object used to be in inventory, so we can
-				// assume the owner and group will match what they are
-				// there.
-				perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
-			}
-			// *FIX: can make an even better guess by using the mPermGroup flags
-			else if(permYouOwner())
-			{
-				// best guess.
-				perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic);
-				--mInventorySerialNum;
-			}
-			else
-			{
-				// dummy it up.
-				perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic);
-				--mInventorySerialNum;
-			}
-		}
-		LLViewerInventoryItem* oldItem = item;
-		LLViewerInventoryItem* new_item = new LLViewerInventoryItem(oldItem);
-		new_item->setPermissions(perm);
-		mInventory->push_front(new_item);
-		doInventoryCallback();
-		++mInventorySerialNum;
-	}
-}
-
-// save a script, which involves removing the old one, and rezzing
-// in the new one. This method should be called with the asset id
-// of the new and old script AFTER the bytecode has been saved.
-void LLViewerObject::saveScript(
-	const LLViewerInventoryItem* item,
-	BOOL active,
-	bool is_new)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-
-	/*
-	 * XXXPAM Investigate not making this copy.  Seems unecessary, but I'm unsure about the
-	 * interaction with doUpdateInventory() called below.
-	 */
-	lldebugs << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << llendl;
-	LLPointer<LLViewerInventoryItem> task_item =
-		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
-								  item->getAssetUUID(), item->getType(),
-								  item->getInventoryType(),
-								  item->getName(), item->getDescription(),
-								  item->getSaleInfo(), item->getFlags(),
-								  item->getCreationDate());
-	task_item->setTransactionID(item->getTransactionID());
-
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_RezScript);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
-	msg->nextBlockFast(_PREHASH_UpdateBlock);
-	msg->addU32Fast(_PREHASH_ObjectLocalID, (mLocalID));
-	U8 enabled = active;
-	msg->addBOOLFast(_PREHASH_Enabled, enabled);
-	msg->nextBlockFast(_PREHASH_InventoryBlock);
-	task_item->packMessage(msg);
-	msg->sendReliable(mRegionp->getHost());
-
-	// do the internal logic
-	doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, is_new);
-}
-
-void LLViewerObject::moveInventory(const LLUUID& folder_id,
-								   const LLUUID& item_id)
-{
-	lldebugs << "LLViewerObject::moveInventory " << item_id << llendl;
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_MoveTaskInventory);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->addUUIDFast(_PREHASH_FolderID, folder_id);
-	msg->nextBlockFast(_PREHASH_InventoryData);
-	msg->addU32Fast(_PREHASH_LocalID, mLocalID);
-	msg->addUUIDFast(_PREHASH_ItemID, item_id);
-	msg->sendReliable(mRegionp->getHost());
-
-	LLInventoryObject* inv_obj = getInventoryObject(item_id);
-	if(inv_obj)
-	{
-		LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_obj;
-		if(!item->getPermissions().allowCopyBy(gAgent.getID()))
-		{
-			deleteInventoryItem(item_id);
-			++mInventorySerialNum;
-		}
-	}
-}
-
-void LLViewerObject::dirtyInventory()
-{
-	// If there aren't any LLVOInventoryListeners, we won't be
-	// able to update our mInventory when it comes back from the
-	// simulator, so we should not clear the inventory either.
-	if(mInventory && !mInventoryCallbacks.empty())
-	{
-		mInventory->clear(); // will deref and delete entries
-		delete mInventory;
-		mInventory = NULL;
-		mInventoryDirty = TRUE;
-	}
-}
-
-void LLViewerObject::registerInventoryListener(LLVOInventoryListener* listener, void* user_data)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	
-	LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo;
-	info->mListener = listener;
-	info->mInventoryData = user_data;
-	mInventoryCallbacks.push_front(info);
-}
-
-void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener)
-{
-	if (listener == NULL)
-		return;
-	for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
-		 iter != mInventoryCallbacks.end(); )
-	{
-		callback_list_t::iterator curiter = iter++;
-		LLInventoryCallbackInfo* info = *curiter;
-		if (info->mListener == listener)
-		{
-			delete info;
-			mInventoryCallbacks.erase(curiter);
-			break;
-		}
-	}
-}
-
-void LLViewerObject::clearInventoryListeners()
-{
-	for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer());
-	mInventoryCallbacks.clear();
-}
-
-void LLViewerObject::requestInventory()
-{
-	mInventoryDirty = FALSE;
-	if(mInventory)
-	{
-		//mInventory->clear() // will deref and delete it
-		//delete mInventory;
-		//mInventory = NULL;
-		doInventoryCallback();
-	}
-	// throw away duplicate requests
-	else
-	{
-		fetchInventoryFromServer();
-	}
-}
-
-void LLViewerObject::fetchInventoryFromServer()
-{
-	if (!mInventoryPending)
-	{
-		delete mInventory;
-		mInventory = NULL;
-		mInventoryDirty = FALSE;
-		LLMessageSystem* msg = gMessageSystem;
-		msg->newMessageFast(_PREHASH_RequestTaskInventory);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_InventoryData);
-		msg->addU32Fast(_PREHASH_LocalID, mLocalID);
-		msg->sendReliable(mRegionp->getHost());
-
-		// this will get reset by dirtyInventory or doInventoryCallback
-		mInventoryPending = TRUE;
-	}
-}
-
-struct LLFilenameAndTask
-{
-	LLUUID mTaskID;
-	std::string mFilename;
-#ifdef _DEBUG
-	static S32 sCount;
-	LLFilenameAndTask()
-	{
-		++sCount;
-		lldebugs << "Constructing LLFilenameAndTask: " << sCount << llendl;
-	}
-	~LLFilenameAndTask()
-	{
-		--sCount;
-		lldebugs << "Destroying LLFilenameAndTask: " << sCount << llendl;
-	}
-private:
-	LLFilenameAndTask(const LLFilenameAndTask& rhs);
-	const LLFilenameAndTask& operator=(const LLFilenameAndTask& rhs) const;
-#endif
-};
-
-#ifdef _DEBUG
-S32 LLFilenameAndTask::sCount = 0;
-#endif
-
-// static
-void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	
-	LLUUID task_id;
-	msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);
-	LLViewerObject* object = gObjectList.findObject(task_id);
-	if(!object)
-	{
-		llwarns << "LLViewerObject::processTaskInv object "
-			<< task_id << " does not exist." << llendl;
-		return;
-	}
-
-	msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, object->mInventorySerialNum);
-	LLFilenameAndTask* ft = new LLFilenameAndTask;
-	ft->mTaskID = task_id;
-
-	std::string unclean_filename;
-	msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename);
-	ft->mFilename = LLDir::getScrubbedFileName(unclean_filename);
-	
-	if(ft->mFilename.empty())
-	{
-		lldebugs << "Task has no inventory" << llendl;
-		// mock up some inventory to make a drop target.
-		if(object->mInventory)
-		{
-			object->mInventory->clear(); // will deref and delete it
-		}
-		else
-		{
-			object->mInventory = new LLInventoryObject::object_list_t();
-		}
-		LLPointer<LLInventoryObject> obj;
-		obj = new LLInventoryObject(object->mID, LLUUID::null,
-									LLAssetType::AT_CATEGORY,
-									LLTrans::getString("ViewerObjectContents").c_str());
-		object->mInventory->push_front(obj);
-		object->doInventoryCallback();
-		delete ft;
-		return;
-	}
-	gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename), 
-								ft->mFilename, LL_PATH_CACHE,
-								object->mRegionp->getHost(),
-								TRUE,
-								&LLViewerObject::processTaskInvFile,
-								(void**)ft,
-								LLXferManager::HIGH_PRIORITY);
-}
-
-void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status)
-{
-	LLFilenameAndTask* ft = (LLFilenameAndTask*)user_data;
-	LLViewerObject* object = NULL;
-	if(ft && (0 == error_code) &&
-	   (object = gObjectList.findObject(ft->mTaskID)))
-	{
-		object->loadTaskInvFile(ft->mFilename);
-	}
-	else
-	{
-		// This Occurs When to requests were made, and the first one
-		// has already handled it.
-		lldebugs << "Problem loading task inventory. Return code: "
-				 << error_code << llendl;
-	}
-	delete ft;
-}
-
-void LLViewerObject::loadTaskInvFile(const std::string& filename)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	
-	std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
-	llifstream ifs(filename_and_local_path);
-	if(ifs.good())
-	{
-		char buffer[MAX_STRING];	/* Flawfinder: ignore */
-		// *NOTE: This buffer size is hard coded into scanf() below.
-		char keyword[MAX_STRING];	/* Flawfinder: ignore */
-		if(mInventory)
-		{
-			mInventory->clear(); // will deref and delete it
-		}
-		else
-		{
-			mInventory = new LLInventoryObject::object_list_t;
-		}
-		while(ifs.good())
-		{
-			ifs.getline(buffer, MAX_STRING);
-			sscanf(buffer, " %254s", keyword);	/* Flawfinder: ignore */
-			if(0 == strcmp("inv_item", keyword))
-			{
-				LLPointer<LLInventoryObject> inv = new LLViewerInventoryItem;
-				inv->importLegacyStream(ifs);
-				mInventory->push_front(inv);
-			}
-			else if(0 == strcmp("inv_object", keyword))
-			{
-				LLPointer<LLInventoryObject> inv = new LLInventoryObject;
-				inv->importLegacyStream(ifs);
-				inv->rename(LLTrans::getString("ViewerObjectContents").c_str());
-				mInventory->push_front(inv);
-			}
-			else
-			{
-				llwarns << "Unknown token in inventory file '"
-						<< keyword << "'" << llendl;
-			}
-		}
-		ifs.close();
-		LLFile::remove(filename_and_local_path);
-	}
-	else
-	{
-		llwarns << "unable to load task inventory: " << filename_and_local_path
-				<< llendl;
-	}
-	doInventoryCallback();
-}
-
-void LLViewerObject::doInventoryCallback()
-{
-	for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
-		 iter != mInventoryCallbacks.end(); )
-	{
-		callback_list_t::iterator curiter = iter++;
-		LLInventoryCallbackInfo* info = *curiter;
-		if (info->mListener != NULL)
-		{
-			info->mListener->inventoryChanged(this,
-								 mInventory,
-								 mInventorySerialNum,
-								 info->mInventoryData);
-		}
-		else
-		{
-			llinfos << "LLViewerObject::doInventoryCallback() deleting bad listener entry." << llendl;
-			delete info;
-			mInventoryCallbacks.erase(curiter);
-		}
-	}
-	mInventoryPending = FALSE;
-}
-
-void LLViewerObject::removeInventory(const LLUUID& item_id)
-{
-	// close any associated floater properties
-	LLFloaterReg::hideInstance("properties", item_id);
-
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_RemoveTaskInventory);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_InventoryData);
-	msg->addU32Fast(_PREHASH_LocalID, mLocalID);
-	msg->addUUIDFast(_PREHASH_ItemID, item_id);
-	msg->sendReliable(mRegionp->getHost());
-	deleteInventoryItem(item_id);
-	++mInventorySerialNum;
-}
-
-void LLViewerObject::updateInventory(
-	LLViewerInventoryItem* item,
-	U8 key,
-	bool is_new)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	
-	// This slices the object into what we're concerned about on the
-	// viewer. The simulator will take the permissions and transfer
-	// ownership.
-	LLPointer<LLViewerInventoryItem> task_item =
-		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
-								  item->getAssetUUID(), item->getType(),
-								  item->getInventoryType(),
-								  item->getName(), item->getDescription(),
-								  item->getSaleInfo(),
-								  item->getFlags(),
-								  item->getCreationDate());
-	task_item->setTransactionID(item->getTransactionID());
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_UpdateTaskInventory);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_UpdateData);
-	msg->addU32Fast(_PREHASH_LocalID, mLocalID);
-	msg->addU8Fast(_PREHASH_Key, key);
-	msg->nextBlockFast(_PREHASH_InventoryData);
-	task_item->packMessage(msg);
-	msg->sendReliable(mRegionp->getHost());
-
-	// do the internal logic
-	doUpdateInventory(task_item, key, is_new);
-}
-
-void LLViewerObject::updateInventoryLocal(LLInventoryItem* item, U8 key)
-{
-	LLPointer<LLViewerInventoryItem> task_item =
-		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
-								  item->getAssetUUID(), item->getType(),
-								  item->getInventoryType(),
-								  item->getName(), item->getDescription(),
-								  item->getSaleInfo(), item->getFlags(),
-								  item->getCreationDate());
-
-	// do the internal logic
-	const bool is_new = false;
-	doUpdateInventory(task_item, key, is_new);
-}
-
-LLInventoryObject* LLViewerObject::getInventoryObject(const LLUUID& item_id)
-{
-	LLInventoryObject* rv = NULL;
-	if(mInventory)
-	{
-		LLInventoryObject::object_list_t::iterator it = mInventory->begin();
-		LLInventoryObject::object_list_t::iterator end = mInventory->end();
-		for ( ; it != end; ++it)
-		{
-			if((*it)->getUUID() == item_id)
-			{
-				rv = *it;
-				break;
-			}
-		}		
-	}
-	return rv;
-}
-
-void LLViewerObject::getInventoryContents(LLInventoryObject::object_list_t& objects)
-{
-	if(mInventory)
-	{
-		LLInventoryObject::object_list_t::iterator it = mInventory->begin();
-		LLInventoryObject::object_list_t::iterator end = mInventory->end();
-		for( ; it != end; ++it)
-		{
-			if ((*it)->getType() != LLAssetType::AT_CATEGORY)
-			{
-				objects.push_back(*it);
-			}
-		}
-	}
-}
-
-LLInventoryObject* LLViewerObject::getInventoryRoot()
-{
-	if (!mInventory || !mInventory->size())
-	{
-		return NULL;
-	}
-	return mInventory->back();
-}
-
-LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& asset_id)
-{
-	if (mInventoryDirty)
-		llwarns << "Peforming inventory lookup for object " << mID << " that has dirty inventory!" << llendl;
-
-	LLViewerInventoryItem* rv = NULL;
-	if(mInventory)
-	{
-		LLViewerInventoryItem* item = NULL;
-
-		LLInventoryObject::object_list_t::iterator it = mInventory->begin();
-		LLInventoryObject::object_list_t::iterator end = mInventory->end();
-		for( ; it != end; ++it)
-		{
-			LLInventoryObject* obj = *it;
-			if(obj->getType() != LLAssetType::AT_CATEGORY)
-			{
-				// *FIX: gank-ass down cast!
-				item = (LLViewerInventoryItem*)obj;
-				if(item->getAssetUUID() == asset_id)
-				{
-					rv = item;
-					break;
-				}
-			}
-		}		
-	}
-	return rv;
-}
-
-void LLViewerObject::updateViewerInventoryAsset(
-					const LLViewerInventoryItem* item,
-					const LLUUID& new_asset)
-{
-	LLPointer<LLViewerInventoryItem> task_item =
-		new LLViewerInventoryItem(item);
-	task_item->setAssetUUID(new_asset);
-
-	// do the internal logic
-	doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false);
-}
-
-void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)
-{
-	if (getVolume())
-	{	//volumes calculate pixel area and angle per face
-		return;
-	}
-	
-	LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent();
-	LLVector3 pos_agent = getRenderPosition();
-
-	F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX];
-	F32 dy = viewer_pos_agent.mV[VY] - pos_agent.mV[VY];
-	F32 dz = viewer_pos_agent.mV[VZ] - pos_agent.mV[VZ];
-
-	F32 max_scale = getMaxScale();
-	F32 mid_scale = getMidScale();
-	F32 min_scale = getMinScale();
-
-	// IW: estimate - when close to large objects, computing range based on distance from center is no good
-	// to try to get a min distance from face, subtract min_scale/2 from the range.
-	// This means we'll load too much detail sometimes, but that's better than not enough
-	// I don't think there's a better way to do this without calculating distance per-poly
-	F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2;
-
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
-	if (range < 0.001f || isHUDAttachment())		// range == zero
-	{
-		mAppAngle = 180.f;
-		mPixelArea = (F32)camera->getScreenPixelArea();
-	}
-	else
-	{
-		mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG;
-
-		F32 pixels_per_meter = camera->getPixelMeterRatio() / range;
-
-		mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale);
-		if (mPixelArea > camera->getScreenPixelArea())
-		{
-			mAppAngle = 180.f;
-			mPixelArea = (F32)camera->getScreenPixelArea();
-		}
-	}
-}
-
-BOOL LLViewerObject::updateLOD()
-{
-	return FALSE;
-}
-
-BOOL LLViewerObject::updateGeometry(LLDrawable *drawable)
-{
-	return TRUE;
-}
-
-void LLViewerObject::updateGL()
-{
-
-}
-
-void LLViewerObject::updateFaceSize(S32 idx)
-{
-	
-}
-
-LLDrawable* LLViewerObject::createDrawable(LLPipeline *pipeline)
-{
-	return NULL;
-}
-
-void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped)
-{
-	LLPrimitive::setScale(scale);
-	if (mDrawable.notNull())
-	{
-		//encompass completely sheared objects by taking 
-		//the most extreme point possible (<1,1,0.5>)
-		mDrawable->setRadius(LLVector3(1,1,0.5f).scaleVec(scale).magVec());
-		updateDrawable(damped);
-	}
-
-	if( (LL_PCODE_VOLUME == getPCode()) && !isDead() )
-	{
-		if (permYouOwner() || (scale.magVecSquared() > (7.5f * 7.5f)) )
-		{
-			if (!mOnMap)
-			{
-				llassert_always(LLWorld::getInstance()->getRegionFromHandle(getRegion()->getHandle()));
-
-				gObjectList.addToMap(this);
-				mOnMap = TRUE;
-			}
-		}
-		else
-		{
-			if (mOnMap)
-			{
-				gObjectList.removeFromMap(this);
-				mOnMap = FALSE;
-			}
-		}
-	}
-}
-
-void LLViewerObject::setObjectCost(F32 cost)
-{
-	mObjectCost = cost;
-	mCostStale = false;
-
-	if (isSelected())
-	{
-		gFloaterTools->dirty();
-	}
-}
-
-void LLViewerObject::setLinksetCost(F32 cost)
-{
-	mLinksetCost = cost;
-	mCostStale = false;
-	
-	if (isSelected())
-	{
-		gFloaterTools->dirty();
-	}
-}
-
-void LLViewerObject::setPhysicsCost(F32 cost)
-{
-	mPhysicsCost = cost;
-	mCostStale = false;
-
-	if (isSelected())
-	{
-		gFloaterTools->dirty();
-	}
-}
-
-void LLViewerObject::setLinksetPhysicsCost(F32 cost)
-{
-	mLinksetPhysicsCost = cost;
-	mCostStale = false;
-	
-	if (isSelected())
-	{
-		gFloaterTools->dirty();
-	}
-}
-
-
-F32 LLViewerObject::getObjectCost()
-{
-	if (mCostStale)
-	{
-		gObjectList.updateObjectCost(this);
-	}
-	
-	return mObjectCost;
-}
-
-F32 LLViewerObject::getLinksetCost()
-{
-	if (mCostStale)
-	{
-		gObjectList.updateObjectCost(this);
-	}
-
-	return mLinksetCost;
-}
-
-F32 LLViewerObject::getPhysicsCost()
-{
-	if (mCostStale)
-	{
-		gObjectList.updateObjectCost(this);
-	}
-	
-	return mPhysicsCost;
-}
-
-F32 LLViewerObject::getLinksetPhysicsCost()
-{
-	if (mCostStale)
-	{
-		gObjectList.updateObjectCost(this);
-	}
-
-	return mLinksetPhysicsCost;
-}
-
-F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes)
-{
-	return 0.f;
-}
-
-U32 LLViewerObject::getTriangleCount()
-{
-	return 0;
-}
-
-U32 LLViewerObject::getHighLODTriangleCount()
-{
-	return 0;
-}
-
-void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
-{
-	LLVector4a center;
-	center.load3(getRenderPosition().mV);
-	LLVector4a size;
-	size.load3(getScale().mV);
-	newMin.setSub(center, size);
-	newMax.setAdd(center, size);
-	
-	mDrawable->setPositionGroup(center);
-}
-
-F32 LLViewerObject::getBinRadius()
-{
-	if (mDrawable.notNull())
-	{
-		const LLVector4a* ext = mDrawable->getSpatialExtents();
-		LLVector4a diff;
-		diff.setSub(ext[1], ext[0]);
-		return diff.getLength3().getF32();
-	}
-	
-	return getScale().magVec();
-}
-
-F32 LLViewerObject::getMaxScale() const
-{
-	return llmax(getScale().mV[VX],getScale().mV[VY], getScale().mV[VZ]);
-}
-
-F32 LLViewerObject::getMinScale() const
-{
-	return llmin(getScale().mV[0],getScale().mV[1],getScale().mV[2]);
-}
-
-F32 LLViewerObject::getMidScale() const
-{
-	if (getScale().mV[VX] < getScale().mV[VY])
-	{
-		if (getScale().mV[VY] < getScale().mV[VZ])
-		{
-			return getScale().mV[VY];
-		}
-		else if (getScale().mV[VX] < getScale().mV[VZ])
-		{
-			return getScale().mV[VZ];
-		}
-		else
-		{
-			return getScale().mV[VX];
-		}
-	}
-	else if (getScale().mV[VX] < getScale().mV[VZ])
-	{
-		return getScale().mV[VX];
-	}
-	else if (getScale().mV[VY] < getScale().mV[VZ])
-	{
-		return getScale().mV[VZ];
-	}
-	else
-	{
-		return getScale().mV[VY];
-	}
-}
-
-
-void LLViewerObject::updateTextures()
-{
-}
-
-void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */)
-{
-	if (isDead())
-	{
-		return;
-	}
-
-	S32 i;
-	S32 tex_count = getNumTEs();
-	for (i = 0; i < tex_count; i++)
-	{
- 		getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
-	}
-
-	if (isSculpted() && !isMesh())
-	{
-		LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
-		LLUUID sculpt_id = sculpt_params->getSculptTexture();
-		LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
-	}
-	
-	if (boost_children)
-	{
-		for (child_list_t::iterator iter = mChildList.begin();
-			 iter != mChildList.end(); iter++)
-		{
-			LLViewerObject* child = *iter;
-			child->boostTexturePriority();
-		}
-	}
-}
-
-
-void LLViewerObject::setLineWidthForWindowSize(S32 window_width)
-{
-	if (window_width < 700)
-	{
-		LLUI::setLineWidth(2.0f);
-	}
-	else if (window_width < 1100)
-	{
-		LLUI::setLineWidth(3.0f);
-	}
-	else if (window_width < 2000)
-	{
-		LLUI::setLineWidth(4.0f);
-	}
-	else
-	{
-		// _damn_, what a nice monitor!
-		LLUI::setLineWidth(5.0f);
-	}
-}
-
-void LLViewerObject::increaseArrowLength()
-{
-/* ???
-	if (mAxisArrowLength == 50)
-	{
-		mAxisArrowLength = 100;
-	}
-	else
-	{
-		mAxisArrowLength = 150;
-	}
-*/
-}
-
-
-void LLViewerObject::decreaseArrowLength()
-{
-/* ???
-	if (mAxisArrowLength == 150)
-	{
-		mAxisArrowLength = 100;
-	}
-	else
-	{
-		mAxisArrowLength = 50;
-	}
-*/
-}
-
-// Culled from newsim LLTask::addNVPair
-void LLViewerObject::addNVPair(const std::string& data)
-{
-	// cout << "LLViewerObject::addNVPair() with ---" << data << "---" << endl;
-	LLNameValue *nv = new LLNameValue(data.c_str());
-
-//	char splat[MAX_STRING];
-//	temp->printNameValue(splat);
-//	llinfos << "addNVPair " << splat << llendl;
-
-	name_value_map_t::iterator iter = mNameValuePairs.find(nv->mName);
-	if (iter != mNameValuePairs.end())
-	{
-		LLNameValue* foundnv = iter->second;
-		if (foundnv->mClass != NVC_READ_ONLY)
-		{
-			delete foundnv;
-			mNameValuePairs.erase(iter);
-		}
-		else
-		{
-			delete nv;
-//			llinfos << "Trying to write to Read Only NVPair " << temp->mName << " in addNVPair()" << llendl;
-			return;
-		}
-	}
-	mNameValuePairs[nv->mName] = nv;
-}
-
-BOOL LLViewerObject::removeNVPair(const std::string& name)
-{
-	char* canonical_name = gNVNameTable.addString(name);
-
-	lldebugs << "LLViewerObject::removeNVPair(): " << name << llendl;
-
-	name_value_map_t::iterator iter = mNameValuePairs.find(canonical_name);
-	if (iter != mNameValuePairs.end())
-	{
-		if( mRegionp )
-		{
-			LLNameValue* nv = iter->second;
-/*
-			std::string buffer = nv->printNameValue();
-			gMessageSystem->newMessageFast(_PREHASH_RemoveNameValuePair);
-			gMessageSystem->nextBlockFast(_PREHASH_TaskData);
-			gMessageSystem->addUUIDFast(_PREHASH_ID, mID);
-			
-			gMessageSystem->nextBlockFast(_PREHASH_NameValueData);
-			gMessageSystem->addStringFast(_PREHASH_NVPair, buffer);
-
-			gMessageSystem->sendReliable( mRegionp->getHost() );
-*/
-			// Remove the NV pair from the local list.
-			delete nv;
-			mNameValuePairs.erase(iter);
-			return TRUE;
-		}
-		else
-		{
-			lldebugs << "removeNVPair - No region for object" << llendl;
-		}
-	}
-	return FALSE;
-}
-
-
-LLNameValue *LLViewerObject::getNVPair(const std::string& name) const
-{
-	char		*canonical_name;
-
-	canonical_name = gNVNameTable.addString(name);
-
-	// If you access a map with a name that isn't in it, it will add the name and a null pointer.
-	// So first check if the data is in the map.
-	name_value_map_t::const_iterator iter = mNameValuePairs.find(canonical_name);
-	if (iter != mNameValuePairs.end())
-	{
-		return iter->second;
-	}
-	else
-	{
-		return NULL;
-	}
-}
-
-void LLViewerObject::updatePositionCaches() const
-{
-	if(mRegionp)
-	{
-		if (!isRoot())
-		{
-			mPositionRegion = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
-			mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
-		}
-		else
-		{
-			mPositionRegion = getPosition();
-			mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
-		}
-	}
-}
-
-const LLVector3d LLViewerObject::getPositionGlobal() const
-{	
-	if(mRegionp)
-	{
-		LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
-
-		if (isAttachment())
-		{
-			position_global = gAgent.getPosGlobalFromAgent(getRenderPosition());
-		}		
-		return position_global;
-	}
-	else
-	{
-		LLVector3d position_global(getPosition());
-		return position_global;
-	}	
-}
-
-const LLVector3 &LLViewerObject::getPositionAgent() const
-{
-	if (mRegionp)
-	{
-		if (mDrawable.notNull() && (!mDrawable->isRoot() && getParent()))
-		{
-			// Don't return cached position if you have a parent, recalc (until all dirtying is done correctly.
-			LLVector3 position_region;
-			position_region = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
-			mPositionAgent = mRegionp->getPosAgentFromRegion(position_region);
-		}
-		else
-		{
-			mPositionAgent = mRegionp->getPosAgentFromRegion(getPosition());
-		}
-	}
-	return mPositionAgent;
-}
-
-const LLVector3 &LLViewerObject::getPositionRegion() const
-{
-	if (!isRoot())
-	{
-		LLViewerObject *parent = (LLViewerObject *)getParent();
-		mPositionRegion = parent->getPositionRegion() + (getPosition() * parent->getRotation());
-	}
-	else
-	{
-		mPositionRegion = getPosition();
-	}
-
-	return mPositionRegion;
-}
-
-const LLVector3 LLViewerObject::getPositionEdit() const
-{
-	if (isRootEdit())
-	{
-		return getPosition();
-	}
-	else
-	{
-		LLViewerObject *parent = (LLViewerObject *)getParent();
-		LLVector3 position_edit = parent->getPositionEdit() + getPosition() * parent->getRotationEdit();
-		return position_edit;
-	}
-}
-
-const LLVector3 LLViewerObject::getRenderPosition() const
-{
-	if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED))
-	{
-		LLVOAvatar* avatar = getAvatar();
-		if (avatar)
-		{
-			return avatar->getPositionAgent();
-		}
-	}
-
-	if (mDrawable.isNull() || mDrawable->getGeneration() < 0)
-	{
-		return getPositionAgent();
-	}
-	else
-	{
-		return mDrawable->getPositionAgent();
-	}
-}
-
-const LLVector3 LLViewerObject::getPivotPositionAgent() const
-{
-	return getRenderPosition();
-}
-
-const LLQuaternion LLViewerObject::getRenderRotation() const
-{
-	LLQuaternion ret;
-	if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED))
-	{
-		return ret;
-	}
-	
-	if (mDrawable.isNull() || mDrawable->isStatic())
-	{
-		ret = getRotationEdit();
-	}
-	else
-	{
-		if (!mDrawable->isRoot())
-		{
-			ret = getRotation() * LLQuaternion(mDrawable->getParent()->getWorldMatrix());
-		}
-		else
-		{
-			ret = LLQuaternion(mDrawable->getWorldMatrix());
-		}
-	}
-	
-	return ret;
-}
-
-const LLMatrix4 LLViewerObject::getRenderMatrix() const
-{
-	return mDrawable->getWorldMatrix();
-}
-
-const LLQuaternion LLViewerObject::getRotationRegion() const
-{
-	LLQuaternion global_rotation = getRotation();
-	if (!((LLXform *)this)->isRoot())
-	{
-		global_rotation = global_rotation * getParent()->getRotation();
-	}
-	return global_rotation;
-}
-
-const LLQuaternion LLViewerObject::getRotationEdit() const
-{
-	LLQuaternion global_rotation = getRotation();
-	if (!((LLXform *)this)->isRootEdit())
-	{
-		global_rotation = global_rotation * getParent()->getRotation();
-	}
-	return global_rotation;
-}
-
-void LLViewerObject::setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped )
-{
-	if (isAttachment())
-	{
-		LLVector3 new_pos = mRegionp->getPosRegionFromGlobal(pos_global);
-		if (isRootEdit())
-		{
-			new_pos -= mDrawable->mXform.getParent()->getWorldPosition();
-			LLQuaternion world_rotation = mDrawable->mXform.getParent()->getWorldRotation();
-			new_pos = new_pos * ~world_rotation;
-		}
-		else
-		{
-			LLViewerObject* parentp = (LLViewerObject*)getParent();
-			new_pos -= parentp->getPositionAgent();
-			new_pos = new_pos * ~parentp->getRotationRegion();
-		}
-		LLViewerObject::setPosition(new_pos);
-		
-		if (mParent && ((LLViewerObject*)mParent)->isAvatar())
-		{
-			// we have changed the position of an attachment, so we need to clamp it
-			LLVOAvatar *avatar = (LLVOAvatar*)mParent;
-
-			avatar->clampAttachmentPositions();
-		}
-	}
-	else
-	{
-		if( isRoot() )
-		{
-			setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
-		}
-		else
-		{
-			// the relative position with the parent is not constant
-			LLViewerObject* parent = (LLViewerObject *)getParent();
-			//RN: this assumes we are only calling this function from the edit tools
-			gPipeline.updateMoveNormalAsync(parent->mDrawable);
-
-			LLVector3 pos_local = mRegionp->getPosRegionFromGlobal(pos_global) - parent->getPositionRegion();
-			pos_local = pos_local * ~parent->getRotationRegion();
-			LLViewerObject::setPosition( pos_local );
-		}
-	}
-	//RN: assumes we always want to snap the object when calling this function
-	gPipeline.updateMoveNormalAsync(mDrawable);
-}
-
-void LLViewerObject::setPosition(const LLVector3 &pos, BOOL damped)
-{
-	if (getPosition() != pos)
-	{
-		setChanged(TRANSLATED | SILHOUETTE);
-	}
-		
-	LLXform::setPosition(pos);
-	updateDrawable(damped);
-	if (isRoot())
-	{
-		// position caches need to be up to date on root objects
-		updatePositionCaches();
-	}
-}
-
-void LLViewerObject::setPositionGlobal(const LLVector3d &pos_global, BOOL damped)
-{
-	if (isAttachment())
-	{
-		if (isRootEdit())
-		{
-			LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
-			newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
-
-			LLQuaternion invWorldRotation = mDrawable->mXform.getParent()->getWorldRotation();
-			invWorldRotation.transQuat();
-
-			newPos = newPos * invWorldRotation;
-			LLViewerObject::setPosition(newPos);
-		}
-		else
-		{
-			// assumes parent is root editable (root of attachment)
-			LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
-			newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
-			LLVector3 delta_pos = newPos - getPosition();
-
-			LLQuaternion invRotation = mDrawable->getRotation();
-			invRotation.transQuat();
-			
-			delta_pos = delta_pos * invRotation;
-
-			// *FIX: is this right?  Shouldn't we be calling the
-			// LLViewerObject version of setPosition?
-			LLVector3 old_pos = mDrawable->mXform.getParent()->getPosition();
-			mDrawable->mXform.getParent()->setPosition(old_pos + delta_pos);
-			setChanged(TRANSLATED | SILHOUETTE);
-		}
-		if (mParent && ((LLViewerObject*)mParent)->isAvatar())
-		{
-			// we have changed the position of an attachment, so we need to clamp it
-			LLVOAvatar *avatar = (LLVOAvatar*)mParent;
-
-			avatar->clampAttachmentPositions();
-		}
-	}
-	else
-	{
-		if (isRoot())
-		{
-			setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
-		}
-		else
-		{
-			// the relative position with the parent is constant, but the parent's position needs to be changed
-			LLVector3d position_offset;
-			position_offset.setVec(getPosition()*getParent()->getRotation());
-			LLVector3d new_pos_global = pos_global - position_offset;
-			((LLViewerObject *)getParent())->setPositionGlobal(new_pos_global);
-		}
-	}
-	updateDrawable(damped);
-}
-
-
-void LLViewerObject::setPositionParent(const LLVector3 &pos_parent, BOOL damped)
-{
-	// Set position relative to parent, if no parent, relative to region
-	if (!isRoot())
-	{
-		LLViewerObject::setPosition(pos_parent, damped);
-		//updateDrawable(damped);
-	}
-	else
-	{
-		setPositionRegion(pos_parent, damped);
-	}
-}
-
-void LLViewerObject::setPositionRegion(const LLVector3 &pos_region, BOOL damped)
-{
-	if (!isRootEdit())
-	{
-		LLViewerObject* parent = (LLViewerObject*) getParent();
-		LLViewerObject::setPosition((pos_region-parent->getPositionRegion())*~parent->getRotationRegion());
-	}
-	else
-	{
-		LLViewerObject::setPosition(pos_region);
-		mPositionRegion = pos_region;
-		mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
-	}
-}
-
-void LLViewerObject::setPositionAgent(const LLVector3 &pos_agent, BOOL damped)
-{
-	LLVector3 pos_region = getRegion()->getPosRegionFromAgent(pos_agent);
-	setPositionRegion(pos_region, damped);
-}
-
-// identical to setPositionRegion() except it checks for child-joints 
-// and doesn't also move the joint-parent
-// TODO -- implement similar intelligence for joint-parents toward
-// their joint-children
-void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped)
-{
-	if (!isRootEdit())
-	{
-		// the relative position with the parent is constant, but the parent's position needs to be changed
-		LLVector3 position_offset = getPosition() * getParent()->getRotation();
-
-		((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset);
-		updateDrawable(damped);
-	}
-	else if (isJointChild())
-	{
-		// compute new parent-relative position
-		LLViewerObject *parent = (LLViewerObject *) getParent();
-		LLQuaternion inv_parent_rot = parent->getRotation();
-		inv_parent_rot.transQuat();
-		LLVector3 pos_parent = (pos_edit - parent->getPositionRegion()) * inv_parent_rot;
-		LLViewerObject::setPosition(pos_parent, damped);
-	}
-	else
-	{
-		LLViewerObject::setPosition(pos_edit, damped);
-		mPositionRegion = pos_edit;
-		mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
-	}	
-}
-
-
-LLViewerObject* LLViewerObject::getRootEdit() const
-{
-	const LLViewerObject* root = this;
-	while (root->mParent 
-		   && !(root->mJointInfo
-			   || ((LLViewerObject*)root->mParent)->isAvatar()) )
-	{
-		root = (LLViewerObject*)root->mParent;
-	}
-	return (LLViewerObject*)root;
-}
-
-
-BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
-										  S32 face,
-										  BOOL pick_transparent,
-										  S32* face_hit,
-										  LLVector3* intersection,
-										  LLVector2* tex_coord,
-										  LLVector3* normal,
-										  LLVector3* bi_normal)
-{
-	return false;
-}
-
-BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end)
-{
-	if (mDrawable.isNull() || mDrawable->isDead())
-	{
-		return FALSE;
-	}
-
-	const LLVector4a* ext = mDrawable->getSpatialExtents();
-
-	//VECTORIZE THIS
-	LLVector4a center;
-	center.setAdd(ext[1], ext[0]);
-	center.mul(0.5f);
-	LLVector4a size;
-	size.setSub(ext[1], ext[0]);
-	size.mul(0.5f);
-
-	LLVector4a starta, enda;
-	starta.load3(start.mV);
-	enda.load3(end.mV);
-
-	return LLLineSegmentBoxIntersect(starta, enda, center, size);
-}
-
-U8 LLViewerObject::getMediaType() const
-{
-	if (mMedia)
-	{
-		return mMedia->mMediaType;
-	}
-	else
-	{
-		return LLViewerObject::MEDIA_NONE;
-	}
-}
-
-void LLViewerObject::setMediaType(U8 media_type)
-{
-	if (!mMedia)
-	{
-		// TODO what if we don't have a media pointer?
-	}
-	else if (mMedia->mMediaType != media_type)
-	{
-		mMedia->mMediaType = media_type;
-
-		// TODO: update materials with new image
-	}
-}
-
-std::string LLViewerObject::getMediaURL() const
-{
-	if (mMedia)
-	{
-		return mMedia->mMediaURL;
-	}
-	else
-	{
-		return std::string();
-	}
-}
-
-void LLViewerObject::setMediaURL(const std::string& media_url)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	
-	if (!mMedia)
-	{
-		mMedia = new LLViewerObjectMedia;
-		mMedia->mMediaURL = media_url;
-		mMedia->mPassedWhitelist = FALSE;
-
-		// TODO: update materials with new image
-	}
-	else if (mMedia->mMediaURL != media_url)
-	{
-		mMedia->mMediaURL = media_url;
-		mMedia->mPassedWhitelist = FALSE;
-
-		// TODO: update materials with new image
-	}
-}
-
-BOOL LLViewerObject::getMediaPassedWhitelist() const
-{
-	if (mMedia)
-	{
-		return mMedia->mPassedWhitelist;
-	}
-	else
-	{
-		return FALSE;
-	}
-}
-
-void LLViewerObject::setMediaPassedWhitelist(BOOL passed)
-{
-	if (mMedia)
-	{
-		mMedia->mPassedWhitelist = passed;
-	}
-}
-
-BOOL LLViewerObject::setMaterial(const U8 material)
-{
-	BOOL res = LLPrimitive::setMaterial(material);
-	if (res)
-	{
-		setChanged(TEXTURE);
-	}
-	return res;
-}
-
-void LLViewerObject::setNumTEs(const U8 num_tes)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	
-	U32 i;
-	if (num_tes != getNumTEs())
-	{
-		if (num_tes)
-		{
-			LLPointer<LLViewerTexture> *new_images;
-			new_images = new LLPointer<LLViewerTexture>[num_tes];
-			for (i = 0; i < num_tes; i++)
-			{
-				if (i < getNumTEs())
-				{
-					new_images[i] = mTEImages[i];
-				}
-				else if (getNumTEs())
-				{
-					new_images[i] = mTEImages[getNumTEs()-1];
-				}
-				else
-				{
-					new_images[i] = NULL;
-				}
-			}
-
-			deleteTEImages();
-			
-			mTEImages = new_images;
-		}
-		else
-		{
-			deleteTEImages();
-		}
-		LLPrimitive::setNumTEs(num_tes);
-		setChanged(TEXTURE);
-
-		if (mDrawable.notNull())
-		{
-			gPipeline.markTextured(mDrawable);
-		}
-	}
-}
-
-void LLViewerObject::sendMaterialUpdate() const
-{
-	LLViewerRegion* regionp = getRegion();
-	if(!regionp) return;
-	gMessageSystem->newMessageFast(_PREHASH_ObjectMaterial);
-	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID,	mLocalID );
-	gMessageSystem->addU8Fast(_PREHASH_Material, getMaterial() );
-	gMessageSystem->sendReliable( regionp->getHost() );
-
-}
-
-// formerly send_object_rotation
-void LLViewerObject::sendRotationUpdate() const
-{
-	LLViewerRegion* regionp = getRegion();
-	if(!regionp) return;
-	gMessageSystem->newMessageFast(_PREHASH_ObjectRotation);
-	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID);
-	gMessageSystem->addQuatFast(_PREHASH_Rotation, getRotationEdit());
-	//llinfos << "Sent rotation " << getRotationEdit() << llendl;
-	gMessageSystem->sendReliable( regionp->getHost() );
-}
-
-/* Obsolete, we use MultipleObjectUpdate instead
-//// formerly send_object_position_global
-//void LLViewerObject::sendPositionUpdate() const
-//{
-//	gMessageSystem->newMessageFast(_PREHASH_ObjectPosition);
-//	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-//	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-//	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-//	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-//	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID,	mLocalID );
-//	gMessageSystem->addVector3Fast(_PREHASH_Position, getPositionRegion());
-//	LLViewerRegion* regionp = getRegion();
-//	gMessageSystem->sendReliable(regionp->getHost());
-//}
-*/
-
-//formerly send_object_shape(LLViewerObject *object)
-void LLViewerObject::sendShapeUpdate()
-{
-	gMessageSystem->newMessageFast(_PREHASH_ObjectShape);
-	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
-
-	LLVolumeMessage::packVolumeParams(&getVolume()->getParams(), gMessageSystem);
-
-	LLViewerRegion *regionp = getRegion();
-	gMessageSystem->sendReliable( regionp->getHost() );
-}
-
-
-void LLViewerObject::sendTEUpdate() const
-{
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ObjectImage);
-
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-
-	msg->nextBlockFast(_PREHASH_ObjectData);
-	msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
-	if (mMedia)
-	{
-		msg->addString("MediaURL", mMedia->mMediaURL);
-	}
-	else
-	{
-		msg->addString("MediaURL", NULL);
-	}
-
-	// TODO send media type
-
-	packTEMessage(msg);
-
-	LLViewerRegion *regionp = getRegion();
-	msg->sendReliable( regionp->getHost() );
-}
-
-void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
-{
-	LLPrimitive::setTE(te, texture_entry);
-//  This doesn't work, don't get any textures.
-//	if (mDrawable.notNull() && mDrawable->isVisible())
-//	{
-		const LLUUID& image_id = getTE(te)->getID();
-		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-//	}
-}
-
-void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
-{
-	if (mTEImages[te] != imagep)
-	{
-		mTEImages[te] = imagep;
-		LLPrimitive::setTETexture(te, imagep->getID());
-		setChanged(TEXTURE);
-		if (mDrawable.notNull())
-		{
-			gPipeline.markTextured(mDrawable);
-		}
-	}
-}
-
-
-S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host)
-{
-	S32 retval = 0;
-	if (uuid != getTE(te)->getID() ||
-		uuid == LLUUID::null)
-	{
-		retval = LLPrimitive::setTETexture(te, uuid);
-		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
-		setChanged(TEXTURE);
-		if (mDrawable.notNull())
-		{
-			gPipeline.markTextured(mDrawable);
-		}
-	}
-	return retval;
-}
-
-
-void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image) 
-{
-	if(index < 0 || index >= getNumTEs())
-	{
-		return ;
-	}
-	mTEImages[index] = new_image ;
-}
-
-S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
-{
-	// Invalid host == get from the agent's sim
-	return setTETextureCore(te, uuid, LLHost::invalid);
-}
-
-
-S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)
-{
-	return setTEColor(te, LLColor4(color));
-}
-
-S32 LLViewerObject::setTEColor(const U8 te, const LLColor4& color)
-{
-	S32 retval = 0;
-	const LLTextureEntry *tep = getTE(te);
-	if (!tep)
-	{
-		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
-	}
-	else if (color != tep->getColor())
-	{
-		retval = LLPrimitive::setTEColor(te, color);
-		if (mDrawable.notNull() && retval)
-		{
-			// These should only happen on updates which are not the initial update.
-			dirtyMesh();
-		}
-	}
-	return retval;
-}
-
-S32 LLViewerObject::setTEBumpmap(const U8 te, const U8 bump)
-{
-	S32 retval = 0;
-	const LLTextureEntry *tep = getTE(te);
-	if (!tep)
-	{
-		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
-	}
-	else if (bump != tep->getBumpmap())
-	{
-		retval = LLPrimitive::setTEBumpmap(te, bump);
-		setChanged(TEXTURE);
-		if (mDrawable.notNull() && retval)
-		{
-			gPipeline.markTextured(mDrawable);
-			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
-		}
-	}
-	return retval;
-}
-
-S32 LLViewerObject::setTETexGen(const U8 te, const U8 texgen)
-{
-	S32 retval = 0;
-	const LLTextureEntry *tep = getTE(te);
-	if (!tep)
-	{
-		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
-	}
-	else if (texgen != tep->getTexGen())
-	{
-		retval = LLPrimitive::setTETexGen(te, texgen);
-		setChanged(TEXTURE);
-	}
-	return retval;
-}
-
-S32 LLViewerObject::setTEMediaTexGen(const U8 te, const U8 media)
-{
-	S32 retval = 0;
-	const LLTextureEntry *tep = getTE(te);
-	if (!tep)
-	{
-		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
-	}
-	else if (media != tep->getMediaTexGen())
-	{
-		retval = LLPrimitive::setTEMediaTexGen(te, media);
-		setChanged(TEXTURE);
-	}
-	return retval;
-}
-
-S32 LLViewerObject::setTEShiny(const U8 te, const U8 shiny)
-{
-	S32 retval = 0;
-	const LLTextureEntry *tep = getTE(te);
-	if (!tep)
-	{
-		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
-	}
-	else if (shiny != tep->getShiny())
-	{
-		retval = LLPrimitive::setTEShiny(te, shiny);
-		setChanged(TEXTURE);
-	}
-	return retval;
-}
-
-S32 LLViewerObject::setTEFullbright(const U8 te, const U8 fullbright)
-{
-	S32 retval = 0;
-	const LLTextureEntry *tep = getTE(te);
-	if (!tep)
-	{
-		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
-	}
-	else if (fullbright != tep->getFullbright())
-	{
-		retval = LLPrimitive::setTEFullbright(te, fullbright);
-		setChanged(TEXTURE);
-		if (mDrawable.notNull() && retval)
-		{
-			gPipeline.markTextured(mDrawable);
-		}
-	}
-	return retval;
-}
-
-
-S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags)
-{
-	// this might need work for media type
-	S32 retval = 0;
-	const LLTextureEntry *tep = getTE(te);
-	if (!tep)
-	{
-		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
-	}
-	else if (media_flags != tep->getMediaFlags())
-	{
-		retval = LLPrimitive::setTEMediaFlags(te, media_flags);
-		setChanged(TEXTURE);
-		if (mDrawable.notNull() && retval)
-		{
-			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, TRUE);
-			gPipeline.markTextured(mDrawable);
-			// JC - probably only need this if changes texture coords
-			//gPipeline.markRebuild(mDrawable);
-		}
-	}
-	return retval;
-}
-
-S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)
-{
-	S32 retval = 0;
-	const LLTextureEntry *tep = getTE(te);
-	if (!tep)
-	{
-		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
-	}
-	else if (glow != tep->getGlow())
-	{
-		retval = LLPrimitive::setTEGlow(te, glow);
-		setChanged(TEXTURE);
-		if (mDrawable.notNull() && retval)
-		{
-			gPipeline.markTextured(mDrawable);
-		}
-	}
-	return retval;
-}
-
-
-S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
-{
-	S32 retval = 0;
-	retval = LLPrimitive::setTEScale(te, s, t);
-	setChanged(TEXTURE);
-	if (mDrawable.notNull() && retval)
-	{
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
-	}
-	return retval;
-}
-
-S32 LLViewerObject::setTEScaleS(const U8 te, const F32 s)
-{
-	S32 retval = LLPrimitive::setTEScaleS(te, s);
-	if (mDrawable.notNull() && retval)
-	{
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
-	}
-
-	return retval;
-}
-
-S32 LLViewerObject::setTEScaleT(const U8 te, const F32 t)
-{
-	S32 retval = LLPrimitive::setTEScaleT(te, t);
-	if (mDrawable.notNull() && retval)
-	{
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
-	}
-
-	return retval;
-}
-
-S32 LLViewerObject::setTEOffset(const U8 te, const F32 s, const F32 t)
-{
-	S32 retval = LLPrimitive::setTEOffset(te, s, t);
-	if (mDrawable.notNull() && retval)
-	{
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
-	}
-	return retval;
-}
-
-S32 LLViewerObject::setTEOffsetS(const U8 te, const F32 s)
-{
-	S32 retval = LLPrimitive::setTEOffsetS(te, s);
-	if (mDrawable.notNull() && retval)
-	{
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
-	}
-
-	return retval;
-}
-
-S32 LLViewerObject::setTEOffsetT(const U8 te, const F32 t)
-{
-	S32 retval = LLPrimitive::setTEOffsetT(te, t);
-	if (mDrawable.notNull() && retval)
-	{
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
-	}
-
-	return retval;
-}
-
-S32 LLViewerObject::setTERotation(const U8 te, const F32 r)
-{
-	S32 retval = LLPrimitive::setTERotation(te, r);
-	if (mDrawable.notNull() && retval)
-	{
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
-	}
-	return retval;
-}
-
-
-LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const
-{
-//	llassert(mTEImages);
-
-	if (face < getNumTEs())
-	{
-		LLViewerTexture* image = mTEImages[face];
-		if (image)
-		{
-			return image;
-		}
-		else
-		{
-			return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
-		}
-	}
-
-	llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
-
-	return NULL;
-}
-
-
-void LLViewerObject::fitFaceTexture(const U8 face)
-{
-	llinfos << "fitFaceTexture not implemented" << llendl;
-}
-
-
-LLBBox LLViewerObject::getBoundingBoxAgent() const
-{
-	LLVector3 position_agent;
-	LLQuaternion rot;
-	LLViewerObject* avatar_parent = NULL;
-	LLViewerObject* root_edit = (LLViewerObject*)getRootEdit();
-	if (root_edit)
-	{
-		avatar_parent = (LLViewerObject*)root_edit->getParent();
-	}
-	
-	if (avatar_parent && avatar_parent->isAvatar() &&
-		root_edit && root_edit->mDrawable.notNull() && root_edit->mDrawable->getXform()->getParent())
-	{
-		LLXform* parent_xform = root_edit->mDrawable->getXform()->getParent();
-		position_agent = (getPositionEdit() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
-		rot = getRotationEdit() * parent_xform->getWorldRotation();
-	}
-	else
-	{
-		position_agent = getPositionAgent();
-		rot = getRotationRegion();
-	}
-	
-	return LLBBox( position_agent, rot, getScale() * -0.5f, getScale() * 0.5f );
-}
-
-U32 LLViewerObject::getNumVertices() const
-{
-	U32 num_vertices = 0;
-	if (mDrawable.notNull())
-	{
-		S32 i, num_faces;
-		num_faces = mDrawable->getNumFaces();
-		for (i = 0; i < num_faces; i++)
-		{
-			num_vertices += mDrawable->getFace(i)->getGeomCount();
-		}
-	}
-	return num_vertices;
-}
-
-U32 LLViewerObject::getNumIndices() const
-{
-	U32 num_indices = 0;
-	if (mDrawable.notNull())
-	{
-		S32 i, num_faces;
-		num_faces = mDrawable->getNumFaces();
-		for (i = 0; i < num_faces; i++)
-		{
-			num_indices += mDrawable->getFace(i)->getIndicesCount();
-		}
-	}
-	return num_indices;
-}
-
-// Find the number of instances of this object's inventory that are of the given type
-S32 LLViewerObject::countInventoryContents(LLAssetType::EType type)
-{
-	S32 count = 0;
-	if( mInventory )
-	{
-		LLInventoryObject::object_list_t::const_iterator it = mInventory->begin();
-		LLInventoryObject::object_list_t::const_iterator end = mInventory->end();
-		for(  ; it != end ; ++it )
-		{
-			if( (*it)->getType() == type )
-			{
-				++count;
-			}
-		}
-	}
-	return count;
-}
-
-
-void LLViewerObject::setCanSelect(BOOL canSelect)
-{
-	mbCanSelect = canSelect;
-	for (child_list_t::iterator iter = mChildList.begin();
-		 iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* child = *iter;
-		child->mbCanSelect = canSelect;
-	}
-}
-
-void LLViewerObject::setDebugText(const std::string &utf8text)
-{
-	if (utf8text.empty() && !mText)
-	{
-		return;
-	}
-
-	if (!mText)
-	{
-		mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
-		mText->setFont(LLFontGL::getFontSansSerif());
-		mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
-		mText->setMaxLines(-1);
-		mText->setSourceObject(this);
-		mText->setOnHUDAttachment(isHUDAttachment());
-	}
-	mText->setColor(LLColor4::white);
-	mText->setString(utf8text);
-	mText->setZCompare(FALSE);
-	mText->setDoFade(FALSE);
-	updateText();
-}
-
-void LLViewerObject::setIcon(LLViewerTexture* icon_image)
-{
-	if (!mIcon)
-	{
-		mIcon = (LLHUDIcon *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_ICON);
-		mIcon->setSourceObject(this);
-		mIcon->setImage(icon_image);
-		// *TODO: make this user configurable
-		mIcon->setScale(0.03f);
-	}
-	else
-	{
-		mIcon->restartLifeTimer();
-	}
-}
-
-void LLViewerObject::clearIcon()
-{
-	if (mIcon)
-	{
-		mIcon = NULL;
-	}
-}
-
-LLViewerObject* LLViewerObject::getSubParent() 
-{ 
-	if (isJointChild())
-	{
-		return this;
-	}
-	return (LLViewerObject*) getParent();
-}
-
-const LLViewerObject* LLViewerObject::getSubParent() const
-{
-	if (isJointChild())
-	{
-		return this;
-	}
-	return (const LLViewerObject*) getParent();
-}
-
-BOOL LLViewerObject::isOnMap()
-{
-	return mOnMap;
-}
-
-
-void LLViewerObject::updateText()
-{
-	if (!isDead())
-	{
-		if (mText.notNull())
-		{		
-			LLVector3 up_offset(0,0,0);
-			up_offset.mV[2] = getScale().mV[VZ]*0.6f;
-			
-			if (mDrawable.notNull())
-			{
-				mText->setPositionAgent(getRenderPosition() + up_offset);
-			}
-			else
-			{
-				mText->setPositionAgent(getPositionAgent() + up_offset);
-			}
-		}
-	}
-}
-
-LLVOAvatar* LLViewerObject::asAvatar()
-{
-	return NULL;
-}
-
-BOOL LLViewerObject::isParticleSource() const
-{
-	return !mPartSourcep.isNull() && !mPartSourcep->isDead();
-}
-
-void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id)
-{
-	if (mPartSourcep)
-	{
-		deleteParticleSource();
-	}
-
-	LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::createPSS(this, particle_parameters);
-	mPartSourcep = pss;
-	
-	if (mPartSourcep)
-	{
-		mPartSourcep->setOwnerUUID(owner_id);
-
-		if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
-		{
-			LLViewerTexture* image;
-			if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
-			{
-				image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.tga");
-			}
-			else
-			{
-				image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
-			}
-			mPartSourcep->setImage(image);
-		}
-	}
-	LLViewerPartSim::getInstance()->addPartSource(pss);
-}
-
-void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& owner_id)
-{
-	if (!mPartSourcep.isNull() && mPartSourcep->isDead())
-	{
-		mPartSourcep = NULL;
-	}
-	if (mPartSourcep)
-	{
-		// If we've got one already, just update the existing source (or remove it)
-		if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, block_num))
-		{
-			mPartSourcep->setDead();
-			mPartSourcep = NULL;
-		}
-	}
-	else
-	{
-		LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num);
-		//If the owner is muted, don't create the system
-		if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
-
-		// We need to be able to deal with a particle source that hasn't changed, but still got an update!
-		if (pss)
-		{
-// 			llinfos << "Making particle system with owner " << owner_id << llendl;
-			pss->setOwnerUUID(owner_id);
-			mPartSourcep = pss;
-			LLViewerPartSim::getInstance()->addPartSource(pss);
-		}
-	}
-	if (mPartSourcep)
-	{
-		if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
-		{
-			LLViewerTexture* image;
-			if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
-			{
-				image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
-			}
-			else
-			{
-				image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
-			}
-			mPartSourcep->setImage(image);
-		}
-	}
-}
-
-void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id)
-{
-	if (!mPartSourcep.isNull() && mPartSourcep->isDead())
-	{
-		mPartSourcep = NULL;
-	}
-	if (mPartSourcep)
-	{
-		// If we've got one already, just update the existing source (or remove it)
-		if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp))
-		{
-			mPartSourcep->setDead();
-			mPartSourcep = NULL;
-		}
-	}
-	else
-	{
-		LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp);
-		//If the owner is muted, don't create the system
-		if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
-		// We need to be able to deal with a particle source that hasn't changed, but still got an update!
-		if (pss)
-		{
-// 			llinfos << "Making particle system with owner " << owner_id << llendl;
-			pss->setOwnerUUID(owner_id);
-			mPartSourcep = pss;
-			LLViewerPartSim::getInstance()->addPartSource(pss);
-		}
-	}
-	if (mPartSourcep)
-	{
-		if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
-		{
-			LLViewerTexture* image;
-			if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
-			{
-				image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
-			}
-			else
-			{
-				image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
-			}
-			mPartSourcep->setImage(image);
-		}
-	}
-}
-
-void LLViewerObject::deleteParticleSource()
-{
-	if (mPartSourcep.notNull())
-	{
-		mPartSourcep->setDead();
-		mPartSourcep = NULL;
-	}
-}
-
-// virtual
-void LLViewerObject::updateDrawable(BOOL force_damped)
-{
-	if (mDrawable.notNull() && 
-		!mDrawable->isState(LLDrawable::ON_MOVE_LIST) &&
-		isChanged(MOVED))
-	{
-		BOOL damped_motion = 
-			!isChanged(SHIFTED) &&										// not shifted between regions this frame and...
-			(	force_damped ||										// ...forced into damped motion by application logic or...
-				(	!isSelected() &&									// ...not selected and...
-					(	mDrawable->isRoot() ||								// ... is root or ...
-						(getParent() && !((LLViewerObject*)getParent())->isSelected())// ... parent is not selected and ...
-					) &&	
-					getPCode() == LL_PCODE_VOLUME &&					// ...is a volume object and...
-					getVelocity().isExactlyZero() &&					// ...is not moving physically and...
-					mDrawable->getGeneration() != -1                    // ...was not created this frame.
-				)					
-			);
-		gPipeline.markMoved(mDrawable, damped_motion);
-	}
-	clearChanged(SHIFTED);
-}
-
-// virtual, overridden by LLVOVolume
-F32 LLViewerObject::getVObjRadius() const
-{
-	return mDrawable.notNull() ? mDrawable->getRadius() : 0.f;
-}
-
-void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags)
-{
-	if (!gAudiop)
-	{
-		return;
-	}
-	
-	if (audio_uuid.isNull())
-	{
-		if (!mAudioSourcep)
-		{
-			return;
-		}
-		if (mAudioSourcep->isLoop() && !mAudioSourcep->hasPendingPreloads())
-		{
-			// We don't clear the sound if it's a loop, it'll go away on its own.
-			// At least, this appears to be how the scripts work.
-			// The attached sound ID is set to NULL to avoid it playing back when the
-			// object rezzes in on non-looping sounds.
-			//llinfos << "Clearing attached sound " << mAudioSourcep->getCurrentData()->getID() << llendl;
-			gAudiop->cleanupAudioSource(mAudioSourcep);
-			mAudioSourcep = NULL;
-		}
-		else if (flags & LL_SOUND_FLAG_STOP)
-        {
-			// Just shut off the sound
-			mAudioSourcep->play(LLUUID::null);
-		}
-		return;
-	}
-	if (flags & LL_SOUND_FLAG_LOOP
-		&& mAudioSourcep && mAudioSourcep->isLoop() && mAudioSourcep->getCurrentData()
-		&& mAudioSourcep->getCurrentData()->getID() == audio_uuid)
-	{
-		//llinfos << "Already playing this sound on a loop, ignoring" << llendl;
-		return;
-	}
-
-	// don't clean up before previous sound is done. Solves: SL-33486
-	if ( mAudioSourcep && mAudioSourcep->isDone() ) 
-	{
-		gAudiop->cleanupAudioSource(mAudioSourcep);
-		mAudioSourcep = NULL;
-	}
-
-	if (mAudioSourcep && mAudioSourcep->isMuted() &&
-	    mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid)
-	{
-		//llinfos << "Already having this sound as muted sound, ignoring" << llendl;
-		return;
-	}
-
-	getAudioSource(owner_id);
-
-	if (mAudioSourcep)
-	{
-		BOOL queue = flags & LL_SOUND_FLAG_QUEUE;
-		mAudioGain = gain;
-		mAudioSourcep->setGain(gain);
-		mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP);
-		mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER);
-		mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE);
-		mAudioSourcep->setQueueSounds(queue);
-		if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG
-		{
-			mAudioSourcep->play(LLUUID::null);
-		}
-		
-		// Play this sound if region maturity permits
-		if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) )
-		{
-			//llinfos << "Playing attached sound " << audio_uuid << llendl;
-			mAudioSourcep->play(audio_uuid);
-		}
-	}
-}
-
-LLAudioSource *LLViewerObject::getAudioSource(const LLUUID& owner_id)
-{
-	if (!mAudioSourcep)
-	{
-		// Arbitrary low gain for a sound that's not playing.
-		// This is used for sound preloads, for example.
-		LLAudioSourceVO *asvop = new LLAudioSourceVO(mID, owner_id, 0.01f, this);
-
-		mAudioSourcep = asvop;
-		if(gAudiop) gAudiop->addAudioSource(asvop);
-	}
-
-	return mAudioSourcep;
-}
-
-void LLViewerObject::adjustAudioGain(const F32 gain)
-{
-	if (!gAudiop)
-	{
-		return;
-	}
-	if (mAudioSourcep)
-	{
-		mAudioGain = gain;
-		mAudioSourcep->setGain(mAudioGain);
-	}
-}
-
-//----------------------------------------------------------------------------
-
-bool LLViewerObject::unpackParameterEntry(U16 param_type, LLDataPacker *dp)
-{
-	ExtraParameter* param = getExtraParameterEntryCreate(param_type);
-	if (param)
-	{
-		param->data->unpack(*dp);
-		param->in_use = TRUE;
-		parameterChanged(param_type, param->data, TRUE, false);
-		return true;
-	}
-	else
-	{
-		return false;
-	}
-}
-
-LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 param_type)
-{
-	LLNetworkData* new_block = NULL;
-	switch (param_type)
-	{
-	  case LLNetworkData::PARAMS_FLEXIBLE:
-	  {
-		  new_block = new LLFlexibleObjectData();
-		  break;
-	  }
-	  case LLNetworkData::PARAMS_LIGHT:
-	  {
-		  new_block = new LLLightParams();
-		  break;
-	  }
-	  case LLNetworkData::PARAMS_SCULPT:
-	  {
-		  new_block = new LLSculptParams();
-		  break;
-	  }
-	  case LLNetworkData::PARAMS_LIGHT_IMAGE:
-	  {
-		  new_block = new LLLightImageParams();
-		  break;
-	  }
-	  default:
-	  {
-		  llinfos << "Unknown param type." << llendl;
-		  break;
-	  }
-	};
-
-	if (new_block)
-	{
-		ExtraParameter* new_entry = new ExtraParameter;
-		new_entry->data = new_block;
-		new_entry->in_use = false; // not in use yet
-		mExtraParameterList[param_type] = new_entry;
-		return new_entry;
-	}
-	return NULL;
-}
-
-LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const
-{
-	std::map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
-	if (itor != mExtraParameterList.end())
-	{
-		return itor->second;
-	}
-	return NULL;
-}
-
-LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntryCreate(U16 param_type)
-{
-	ExtraParameter* param = getExtraParameterEntry(param_type);
-	if (!param)
-	{
-		param = createNewParameterEntry(param_type);
-	}
-	return param;
-}
-
-LLNetworkData* LLViewerObject::getParameterEntry(U16 param_type) const
-{
-	ExtraParameter* param = getExtraParameterEntry(param_type);
-	if (param)
-	{
-		return param->data;
-	}
-	else
-	{
-		return NULL;
-	}
-}
-
-BOOL LLViewerObject::getParameterEntryInUse(U16 param_type) const
-{
-	ExtraParameter* param = getExtraParameterEntry(param_type);
-	if (param)
-	{
-		return param->in_use;
-	}
-	else
-	{
-		return FALSE;
-	}
-}
-
-bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin)
-{
-	ExtraParameter* param = getExtraParameterEntryCreate(param_type);
-	if (param)
-	{
-		if (param->in_use && new_value == *(param->data))
-		{
-			return false;
-		}
-		param->in_use = true;
-		param->data->copy(new_value);
-		parameterChanged(param_type, param->data, TRUE, local_origin);
-		return true;
-	}
-	else
-	{
-		return false;
-	}
-}
-
-// Assumed to be called locally
-// If in_use is TRUE, will crate a new extra parameter if none exists.
-// Should always return true.
-bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin)
-{
-	ExtraParameter* param = getExtraParameterEntryCreate(param_type);
-	if (param && param->in_use != in_use)
-	{
-		param->in_use = in_use;
-		parameterChanged(param_type, param->data, in_use, local_origin);
-		return true;
-	}
-	return false;
-}
-
-void LLViewerObject::parameterChanged(U16 param_type, bool local_origin)
-{
-	ExtraParameter* param = getExtraParameterEntry(param_type);
-	if (param)
-	{
-		parameterChanged(param_type, param->data, param->in_use, local_origin);
-	}
-}
-
-void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin)
-{
-	if (local_origin)
-	{
-		LLViewerRegion* regionp = getRegion();
-		if(!regionp) return;
-
-		// Change happened on the viewer. Send the change up
-		U8 tmp[MAX_OBJECT_PARAMS_SIZE];
-		LLDataPackerBinaryBuffer dpb(tmp, MAX_OBJECT_PARAMS_SIZE);
-		if (data->pack(dpb))
-		{
-			U32 datasize = (U32)dpb.getCurrentSize();
-
-			LLMessageSystem* msg = gMessageSystem;
-			msg->newMessageFast(_PREHASH_ObjectExtraParams);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			msg->nextBlockFast(_PREHASH_ObjectData);
-			msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
-
-			msg->addU16Fast(_PREHASH_ParamType, param_type);
-			msg->addBOOLFast(_PREHASH_ParamInUse, in_use);
-
-			msg->addU32Fast(_PREHASH_ParamSize, datasize);
-			msg->addBinaryDataFast(_PREHASH_ParamData, tmp, datasize);
-
-			msg->sendReliable( regionp->getHost() );
-		}
-		else
-		{
-			llwarns << "Failed to send object extra parameters: " << param_type << llendl;
-		}
-	}
-}
-
-void LLViewerObject::setDrawableState(U32 state, BOOL recursive)
-{
-	if (mDrawable)
-	{
-		mDrawable->setState(state);
-	}
-	if (recursive)
-	{
-		for (child_list_t::iterator iter = mChildList.begin();
-			 iter != mChildList.end(); iter++)
-		{
-			LLViewerObject* child = *iter;
-			child->setDrawableState(state, recursive);
-		}
-	}
-}
-
-void LLViewerObject::clearDrawableState(U32 state, BOOL recursive)
-{
-	if (mDrawable)
-	{
-		mDrawable->clearState(state);
-	}
-	if (recursive)
-	{
-		for (child_list_t::iterator iter = mChildList.begin();
-			 iter != mChildList.end(); iter++)
-		{
-			LLViewerObject* child = *iter;
-			child->clearDrawableState(state, recursive);
-		}
-	}
-}
-
-//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-// RN: these functions assume a 2-level hierarchy 
-//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-// Owned by anyone?
-BOOL LLViewerObject::permAnyOwner() const
-{ 
-	if (isRootEdit())
-	{
-		return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0); 
-	}
-	else
-	{
-		return ((LLViewerObject*)getParent())->permAnyOwner();
-	}
-}	
-// Owned by this viewer?
-BOOL LLViewerObject::permYouOwner() const
-{ 
-	if (isRootEdit())
-	{
-#ifdef HACKED_GODLIKE_VIEWER
-		return TRUE;
-#else
-# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
-		if (!LLGridManager::getInstance()->isInProductionGrid()
-            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
-		{
-			return TRUE;
-		}
-# endif
-		return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0); 
-#endif
-	}
-	else
-	{
-		return ((LLViewerObject*)getParent())->permYouOwner();
-	}
-}
-
-// Owned by a group?
-BOOL LLViewerObject::permGroupOwner() const		
-{ 
-	if (isRootEdit())
-	{
-		return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0); 
-	}
-	else
-	{
-		return ((LLViewerObject*)getParent())->permGroupOwner();
-	}
-}
-
-// Can the owner edit
-BOOL LLViewerObject::permOwnerModify() const
-{ 
-	if (isRootEdit())
-	{
-#ifdef HACKED_GODLIKE_VIEWER
-		return TRUE;
-#else
-# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
-		if (!LLGridManager::getInstance()->isInProductionGrid()
-            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
-	{
-			return TRUE;
-	}
-# endif
-		return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0); 
-#endif
-	}
-	else
-	{
-		return ((LLViewerObject*)getParent())->permOwnerModify();
-	}
-}
-
-// Can edit
-BOOL LLViewerObject::permModify() const
-{ 
-	if (isRootEdit())
-	{
-#ifdef HACKED_GODLIKE_VIEWER
-		return TRUE;
-#else
-# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
-		if (!LLGridManager::getInstance()->isInProductionGrid()
-            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
-	{
-			return TRUE;
-	}
-# endif
-		return ((mFlags & FLAGS_OBJECT_MODIFY) != 0); 
-#endif
-	}
-	else
-	{
-		return ((LLViewerObject*)getParent())->permModify();
-	}
-}
-
-// Can copy
-BOOL LLViewerObject::permCopy() const
-{ 
-	if (isRootEdit())
-	{
-#ifdef HACKED_GODLIKE_VIEWER
-		return TRUE;
-#else
-# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
-		if (!LLGridManager::getInstance()->isInProductionGrid()
-            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
-		{
-			return TRUE;
-		}
-# endif
-		return ((mFlags & FLAGS_OBJECT_COPY) != 0); 
-#endif
-	}
-	else
-	{
-		return ((LLViewerObject*)getParent())->permCopy();
-	}
-}
-
-// Can move
-BOOL LLViewerObject::permMove() const
-{
-	if (isRootEdit())
-	{
-#ifdef HACKED_GODLIKE_VIEWER
-		return TRUE;
-#else
-# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
-		if (!LLGridManager::getInstance()->isInProductionGrid()
-            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
-		{
-			return TRUE;
-		}
-# endif
-		return ((mFlags & FLAGS_OBJECT_MOVE) != 0); 
-#endif
-	}
-	else
-	{
-		return ((LLViewerObject*)getParent())->permMove();
-	}
-}
-
-// Can be transferred
-BOOL LLViewerObject::permTransfer() const
-{ 
-	if (isRootEdit())
-	{
-#ifdef HACKED_GODLIKE_VIEWER
-		return TRUE;
-#else
-# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
-		if (!LLGridManager::getInstance()->isInProductionGrid()
-            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
-		{
-			return TRUE;
-		}
-# endif
-		return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0); 
-#endif
-	}
-	else
-	{
-		return ((LLViewerObject*)getParent())->permTransfer();
-	}
-}
-
-// Can only open objects that you own, or that someone has
-// given you modify rights to.  JC
-BOOL LLViewerObject::allowOpen() const
-{
-	return !flagInventoryEmpty() && (permYouOwner() || permModify());
-}
-
-LLViewerObject::LLInventoryCallbackInfo::~LLInventoryCallbackInfo()
-{
-	if (mListener)
-	{
-		mListener->clearVOInventoryListener();
-	}
-}
-
-void LLViewerObject::updateVolume(const LLVolumeParams& volume_params)
-{
-	if (setVolume(volume_params, 1)) // *FIX: magic number, ack!
-	{
-		// Transmit the update to the simulator
-		sendShapeUpdate();
-		markForUpdate(TRUE);
-	}
-}
-
-void LLViewerObject::markForUpdate(BOOL priority)
-{
-	if (mDrawable.notNull())
-	{
-		gPipeline.markTextured(mDrawable);
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, priority);
-	}
-}
-
-bool LLViewerObject::getIncludeInSearch() const
-{
-	return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0);
-}
-
-void LLViewerObject::setIncludeInSearch(bool include_in_search)
-{
-	if (include_in_search)
-	{
-		mFlags |= FLAGS_INCLUDE_IN_SEARCH;
-	}
-	else
-	{
-		mFlags &= ~FLAGS_INCLUDE_IN_SEARCH;
-	}
-}
-
-void LLViewerObject::setRegion(LLViewerRegion *regionp)
-{
-	if (!regionp)
-	{
-		llwarns << "viewer object set region to NULL" << llendl;
-	}
-	
-	mLatestRecvPacketID = 0;
-	mRegionp = regionp;
-
-	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
-	{
-		LLViewerObject* child = *i;
-		child->setRegion(regionp);
-	}
-
-	setChanged(MOVED | SILHOUETTE);
-	updateDrawable(FALSE);
-}
-
-// virtual
-void	LLViewerObject::updateRegion(LLViewerRegion *regionp)
-{
-//	if (regionp)
-//	{
-//		F64 now = LLFrameTimer::getElapsedSeconds();
-//		llinfos << "Updating to region " << regionp->getName()
-//			<< ", ms since last update message: " << (F32)((now - mLastMessageUpdateSecs) * 1000.0)
-//			<< ", ms since last interpolation: " << (F32)((now - mLastInterpUpdateSecs) * 1000.0) 
-//			<< llendl;
-//	}
-}
-
-
-bool LLViewerObject::specialHoverCursor() const
-{
-	return (mFlags & FLAGS_USE_PHYSICS)
-			|| (mFlags & FLAGS_HANDLE_TOUCH)
-			|| (mClickAction != 0);
-}
-
-void LLViewerObject::updateFlags(BOOL physics_changed)
-{
-	LLViewerRegion* regionp = getRegion();
-	if(!regionp) return;
-	gMessageSystem->newMessage("ObjectFlagUpdate");
-	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, getLocalID() );
-	gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, usePhysics() );
-	gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() );
-	gMessageSystem->addBOOL("IsPhantom", flagPhantom() );
-	gMessageSystem->addBOOL("CastsShadows", flagCastShadows() );
-	if (physics_changed)
-	{
-		gMessageSystem->nextBlock("ExtraPhysics");
-		gMessageSystem->addU8("PhysicsShapeType", getPhysicsShapeType() );
-		gMessageSystem->addF32("Density", getPhysicsDensity() );
-		gMessageSystem->addF32("Friction", getPhysicsFriction() );
-		gMessageSystem->addF32("Restitution", getPhysicsRestitution() );
-		gMessageSystem->addF32("GravityMultiplier", getPhysicsGravity() );
-	}
-	gMessageSystem->sendReliable( regionp->getHost() );
-}
-
-BOOL LLViewerObject::setFlags(U32 flags, BOOL state)
-{
-	BOOL setit = FALSE;
-	if (state)
-	{
-		if ((mFlags & flags) != flags)
-		{
-			mFlags |= flags;
-			setit = TRUE;
-		}
-	}
-	else
-	{
-		if ((mFlags & flags) != 0)
-		{
-			mFlags &= ~flags;
-			setit = TRUE;
-		}
-	}
-
-	// BUG: Sometimes viewer physics and simulator physics get
-	// out of sync.  To fix this, always send update to simulator.
-// 	if (setit)
-	{
-		updateFlags();
-	}
-	return setit;
-}
-
-void LLViewerObject::setPhysicsShapeType(U8 type)
-{
-	mPhysicsShapeUnknown = false;
-	mPhysicsShapeType = type;
-	mCostStale = true;
-}
-
-void LLViewerObject::setPhysicsGravity(F32 gravity)
-{
-	mPhysicsGravity = gravity;
-}
-
-void LLViewerObject::setPhysicsFriction(F32 friction)
-{
-	mPhysicsFriction = friction;
-}
-
-void LLViewerObject::setPhysicsDensity(F32 density)
-{
-	mPhysicsDensity = density;
-}
-
-void LLViewerObject::setPhysicsRestitution(F32 restitution)
-{
-	mPhysicsRestitution = restitution;
-}
-
-U8 LLViewerObject::getPhysicsShapeType() const
-{ 
-	if (mPhysicsShapeUnknown)
-	{
-		mPhysicsShapeUnknown = false;
-		gObjectList.updatePhysicsFlags(this);
-	}
-
-	return mPhysicsShapeType; 
-}
-
-void LLViewerObject::applyAngularVelocity(F32 dt)
-{
-	//do target omega here
-	mRotTime += dt;
-	LLVector3 ang_vel = getAngularVelocity();
-	F32 omega = ang_vel.magVecSquared();
-	F32 angle = 0.0f;
-	LLQuaternion dQ;
-	if (omega > 0.00001f)
-	{
-		omega = sqrt(omega);
-		angle = omega * dt;
-
-		ang_vel *= 1.f/omega;
-		
-		dQ.setQuat(angle, ang_vel);
-		
-		setRotation(getRotation()*dQ);
-		setChanged(MOVED | SILHOUETTE);
-	}
-}
-
-void LLViewerObject::resetRot()
-{
-	mRotTime = 0.0f;
-}
-
-U32 LLViewerObject::getPartitionType() const
-{ 
-	return LLViewerRegion::PARTITION_NONE; 
-}
-
-void LLViewerObject::dirtySpatialGroup(BOOL priority) const
-{
-	if (mDrawable)
-	{
-		LLSpatialGroup* group = mDrawable->getSpatialGroup();
-		if (group)
-		{
-			group->dirtyGeom();
-			gPipeline.markRebuild(group, priority);
-		}
-	}
-}
-
-void LLViewerObject::dirtyMesh()
-{
-	if (mDrawable)
-	{
-		LLSpatialGroup* group = mDrawable->getSpatialGroup();
-		if (group)
-		{
-			group->dirtyMesh();
-		}
-	}
-}
-
-F32 LLAlphaObject::getPartSize(S32 idx)
-{
-	return 0.f;
-}
-
-// virtual
-void LLStaticViewerObject::updateDrawable(BOOL force_damped)
-{
-	// Force an immediate rebuild on any update
-	if (mDrawable.notNull())
-	{
-		mDrawable->updateXform(TRUE);
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
-	}
-	clearChanged(SHIFTED);
-}
-
-void LLViewerObject::saveUnselectedChildrenPosition(std::vector<LLVector3>& positions)
-{
-	if(mChildList.empty() || !positions.empty())
-	{
-		return ;
-	}
-
-	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
-			iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* childp = *iter;
-		if (!childp->isSelected() && childp->mDrawable.notNull())
-		{
-			positions.push_back(childp->getPositionEdit());		
-		}
-	}
-
-	return ;
-}
-
-void LLViewerObject::saveUnselectedChildrenRotation(std::vector<LLQuaternion>& rotations)
-{
-	if(mChildList.empty())
-	{
-		return ;
-	}
-
-	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
-			iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* childp = *iter;
-		if (!childp->isSelected() && childp->mDrawable.notNull())
-		{
-			rotations.push_back(childp->getRotationEdit());				
-		}		
-	}
-
-	return ;
-}
-
-//counter-rotation
-void LLViewerObject::resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations, 
-											const std::vector<LLVector3>& positions)
-{
-	if(mChildList.empty())
-	{
-		return ;
-	}
-
-	S32 index = 0 ;
-	LLQuaternion inv_rotation = ~getRotationEdit() ;
-	LLVector3 offset = getPositionEdit() ;
-	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
-			iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* childp = *iter;
-		if (!childp->isSelected() && childp->mDrawable.notNull())
-		{
-			if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
-			{
-				childp->setRotation(rotations[index] * inv_rotation);
-				childp->setPosition((positions[index] - offset) * inv_rotation);
-				LLManip::rebuild(childp);					
-			}
-			else //avatar
-			{
-				LLVector3 reset_pos = (positions[index] - offset) * inv_rotation ;
-				LLQuaternion reset_rot = rotations[index] * inv_rotation ;
-
-				((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);				
-				((LLVOAvatar*)childp)->mDrawable->mXform.setRotation(reset_rot) ;
-				
-				((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos, TRUE);				
-				((LLVOAvatar*)childp)->mDrawable->getVObj()->setRotation(reset_rot, TRUE) ;
-
-				LLManip::rebuild(childp);				
-			}	
-			index++;
-		}				
-	}
-
-	return ;
-}
-
-//counter-translation
-void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplified)
-{
-	if(mChildList.empty())
-	{
-		return ;
-	}
-
-	LLVector3 child_offset;
-	if(simplified) //translation only, rotation matrix does not change
-	{
-		child_offset = offset * ~getRotation();
-	}
-	else //rotation matrix might change too.
-	{
-		if (isAttachment() && mDrawable.notNull())
-		{
-			LLXform* attachment_point_xform = mDrawable->getXform()->getParent();
-			LLQuaternion parent_rotation = getRotation() * attachment_point_xform->getWorldRotation();
-			child_offset = offset * ~parent_rotation;
-		}
-		else
-		{
-			child_offset = offset * ~getRenderRotation();
-		}
-	}
-
-	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
-			iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* childp = *iter;
-		if (!childp->isSelected() && childp->mDrawable.notNull())
-		{
-			if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
-			{
-				childp->setPosition(childp->getPosition() + child_offset);
-				LLManip::rebuild(childp);
-			}
-			else //avatar
-			{
-				LLVector3 reset_pos = ((LLVOAvatar*)childp)->mDrawable->mXform.getPosition() + child_offset ;
-
-				((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);
-				((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos);				
-				
-				LLManip::rebuild(childp);
-			}			
-		}		
-	}
-
-	return ;
-}
-
-const LLUUID &LLViewerObject::getAttachmentItemID() const
-{
-	return mAttachmentItemID;
-}
-
-void LLViewerObject::setAttachmentItemID(const LLUUID &id)
-{
-	mAttachmentItemID = id;
-}
-
-EObjectUpdateType LLViewerObject::getLastUpdateType() const
-{
-	return mLastUpdateType;
-}
-
-void LLViewerObject::setLastUpdateType(EObjectUpdateType last_update_type)
-{
-	mLastUpdateType = last_update_type;
-}
-
-BOOL LLViewerObject::getLastUpdateCached() const
-{
-	return mLastUpdateCached;
-}
-
-void LLViewerObject::setLastUpdateCached(BOOL last_update_cached)
-{
-	mLastUpdateCached = last_update_cached;
-}
-
-const LLUUID &LLViewerObject::extractAttachmentItemID()
-{
-	LLUUID item_id = LLUUID::null;
-	LLNameValue* item_id_nv = getNVPair("AttachItemID");
-	if( item_id_nv )
-	{
-		const char* s = item_id_nv->getString();
-		if( s )
-		{
-			item_id.set(s);
-		}
-	}
-	setAttachmentItemID(item_id);
-	return getAttachmentItemID();
-}
-
-//virtual
-LLVOAvatar* LLViewerObject::getAvatar() const
-{
-	if (isAttachment())
-	{
-		LLViewerObject* vobj = (LLViewerObject*) getParent();
-
-		while (vobj && !vobj->asAvatar())
-		{
-			vobj = (LLViewerObject*) vobj->getParent();
-		}
-
-		return (LLVOAvatar*) vobj;
-	}
-
-	return NULL;
-}
-
-
-class ObjectPhysicsProperties : public LLHTTPNode
-{
-public:
-	virtual void post(
-		ResponsePtr responder,
-		const LLSD& context,
-		const LLSD& input) const
-	{
-		LLSD object_data = input["body"]["ObjectData"];
-		S32 num_entries = object_data.size();
-		
-		for ( S32 i = 0; i < num_entries; i++ )
-		{
-			LLSD& curr_object_data = object_data[i];
-			U32 local_id = curr_object_data["LocalID"].asInteger();
-
-			// Iterate through nodes at end, since it can be on both the regular AND hover list
-			struct f : public LLSelectedNodeFunctor
-			{
-				U32 mID;
-				f(const U32& id) : mID(id) {}
-				virtual bool apply(LLSelectNode* node)
-				{
-					return (node->getObject() && node->getObject()->mLocalID == mID );
-				}
-			} func(local_id);
-
-			LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
-
-			if (node)
-			{
-				// The LLSD message builder doesn't know how to handle U8, so we need to send as S8 and cast
-				U8 type = (U8)curr_object_data["PhysicsShapeType"].asInteger();
-				F32 density = (F32)curr_object_data["Density"].asReal();
-				F32 friction = (F32)curr_object_data["Friction"].asReal();
-				F32 restitution = (F32)curr_object_data["Restitution"].asReal();
-				F32 gravity = (F32)curr_object_data["GravityMultiplier"].asReal();
-
-				node->getObject()->setPhysicsShapeType(type);
-				node->getObject()->setPhysicsGravity(gravity);
-				node->getObject()->setPhysicsFriction(friction);
-				node->getObject()->setPhysicsDensity(density);
-				node->getObject()->setPhysicsRestitution(restitution);
-			}	
-		}
-		
-		dialog_refresh_all();
-	};
-};
-
-LLHTTPRegistration<ObjectPhysicsProperties>
-	gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties");
-
-
-void LLViewerObject::updateQuota( const SelectionQuota& quota )
-{
-	//update quotas
-	mSelectionQuota = quota;
-}
+/** 
+ * @file llviewerobject.cpp
+ * @brief Base class for viewer objects
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerobject.h"
+
+#include "llaudioengine.h"
+#include "imageids.h"
+#include "indra_constants.h"
+#include "llmath.h"
+#include "llflexibleobject.h"
+#include "llviewercontrol.h"
+#include "lldatapacker.h"
+#include "llfasttimer.h"
+#include "llfloaterreg.h"
+#include "llfontgl.h"
+#include "llframetimer.h"
+#include "llinventory.h"
+#include "llinventorydefines.h"
+#include "llmaterialtable.h"
+#include "llmutelist.h"
+#include "llnamevalue.h"
+#include "llprimitive.h"
+#include "llquantize.h"
+#include "llregionhandle.h"
+#include "llsdserialize.h"
+#include "lltree_common.h"
+#include "llxfermanager.h"
+#include "message.h"
+#include "object_flags.h"
+#include "timing.h"
+
+#include "llaudiosourcevo.h"
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llbbox.h"
+#include "llbox.h"
+#include "llcylinder.h"
+#include "lldrawable.h"
+#include "llface.h"
+#include "llfloaterproperties.h"
+#include "llfloatertools.h"
+#include "llfollowcam.h"
+#include "llhudtext.h"
+#include "llselectmgr.h"
+#include "llrendersphere.h"
+#include "lltooldraganddrop.h"
+#include "llviewercamera.h"
+#include "llviewertexturelist.h"
+#include "llviewerinventory.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparceloverlay.h"
+#include "llviewerpartsource.h"
+#include "llviewerregion.h"
+#include "llviewerstats.h"
+#include "llviewertextureanim.h"
+#include "llviewerwindow.h" // For getSpinAxis
+#include "llvoavatar.h"
+#include "llvoavatarself.h"
+#include "llvoclouds.h"
+#include "llvograss.h"
+#include "llvoground.h"
+#include "llvolume.h"
+#include "llvolumemessage.h"
+#include "llvopartgroup.h"
+#include "llvosky.h"
+#include "llvosurfacepatch.h"
+#include "llvotextbubble.h"
+#include "llvotree.h"
+#include "llvovolume.h"
+#include "llvowater.h"
+#include "llworld.h"
+#include "llui.h"
+#include "pipeline.h"
+#include "llviewernetwork.h"
+#include "llvowlsky.h"
+#include "llmanip.h"
+#include "lltrans.h"
+#include "llsdutil.h"
+#include "llmediaentry.h"
+#include "llaccountingquota.h"
+
+//#define DEBUG_UPDATE_TYPE
+
+BOOL		LLViewerObject::sVelocityInterpolate = TRUE;
+BOOL		LLViewerObject::sPingInterpolate = TRUE; 
+
+U32			LLViewerObject::sNumZombieObjects = 0;
+S32			LLViewerObject::sNumObjects = 0;
+BOOL		LLViewerObject::sMapDebug = TRUE;
+LLColor4	LLViewerObject::sEditSelectColor(	1.0f, 1.f, 0.f, 0.3f);	// Edit OK
+LLColor4	LLViewerObject::sNoEditSelectColor(	1.0f, 0.f, 0.f, 0.3f);	// Can't edit
+S32			LLViewerObject::sAxisArrowLength(50);
+BOOL		LLViewerObject::sPulseEnabled(FALSE);
+BOOL		LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
+
+// sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime
+F64			LLViewerObject::sMaxUpdateInterpolationTime = 3.0;		// For motion interpolation: after X seconds with no updates, don't predict object motion
+F64			LLViewerObject::sPhaseOutUpdateInterpolationTime = 2.0;	// For motion interpolation: after Y seconds with no updates, taper off motion prediction
+
+
+static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
+
+// static
+LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
+{
+	LLViewerObject *res = NULL;
+	LLFastTimer t1(FTM_CREATE_OBJECT);
+	
+	switch (pcode)
+	{
+	case LL_PCODE_VOLUME:
+	  res = new LLVOVolume(id, pcode, regionp); break;
+	case LL_PCODE_LEGACY_AVATAR:
+	{
+		if (id == gAgentID)
+		{
+			if (!gAgentAvatarp)
+			{
+				gAgentAvatarp = new LLVOAvatarSelf(id, pcode, regionp);
+			}
+			else 
+			{
+				gAgentAvatarp->updateRegion(regionp);
+			}
+			res = gAgentAvatarp;
+		}
+		else
+		{
+			res = new LLVOAvatar(id, pcode, regionp); 
+		}
+		static_cast<LLVOAvatar*>(res)->initInstance();
+		break;
+	}
+	case LL_PCODE_LEGACY_GRASS:
+	  res = new LLVOGrass(id, pcode, regionp); break;
+	case LL_PCODE_LEGACY_PART_SYS:
+// 	  llwarns << "Creating old part sys!" << llendl;
+// 	  res = new LLVOPart(id, pcode, regionp); break;
+	  res = NULL; break;
+	case LL_PCODE_LEGACY_TREE:
+	  res = new LLVOTree(id, pcode, regionp); break;
+	case LL_PCODE_TREE_NEW:
+// 	  llwarns << "Creating new tree!" << llendl;
+// 	  res = new LLVOTree(id, pcode, regionp); break;
+	  res = NULL; break;
+	case LL_PCODE_LEGACY_TEXT_BUBBLE:
+	  res = new LLVOTextBubble(id, pcode, regionp); break;
+	case LL_VO_CLOUDS:
+	  res = new LLVOClouds(id, pcode, regionp); break;
+	case LL_VO_SURFACE_PATCH:
+	  res = new LLVOSurfacePatch(id, pcode, regionp); break;
+	case LL_VO_SKY:
+	  res = new LLVOSky(id, pcode, regionp); break;
+	case LL_VO_VOID_WATER:
+		res = new LLVOVoidWater(id, pcode, regionp); break;
+	case LL_VO_WATER:
+		res = new LLVOWater(id, pcode, regionp); break;
+	case LL_VO_GROUND:
+	  res = new LLVOGround(id, pcode, regionp); break;
+	case LL_VO_PART_GROUP:
+	  res = new LLVOPartGroup(id, pcode, regionp); break;
+	case LL_VO_HUD_PART_GROUP:
+	  res = new LLVOHUDPartGroup(id, pcode, regionp); break;
+	case LL_VO_WL_SKY:
+	  res = new LLVOWLSky(id, pcode, regionp); break;
+	default:
+	  llwarns << "Unknown object pcode " << (S32)pcode << llendl;
+	  res = NULL; break;
+	}
+	return res;
+}
+
+LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global)
+:	LLPrimitive(),
+	mChildList(),
+	mID(id),
+	mLocalID(0),
+	mTotalCRC(0),
+	mTEImages(NULL),
+	mGLName(0),
+	mbCanSelect(TRUE),
+	mFlags(0),
+	mPhysicsShapeType(0),
+	mPhysicsGravity(0),
+	mPhysicsFriction(0),
+	mPhysicsDensity(0),
+	mPhysicsRestitution(0),
+	mDrawable(),
+	mCreateSelected(FALSE),
+	mRenderMedia(FALSE),
+	mBestUpdatePrecision(0),
+	mText(),
+	mLastInterpUpdateSecs(0.f),
+	mLastMessageUpdateSecs(0.f),
+	mLatestRecvPacketID(0),
+	mData(NULL),
+	mAudioSourcep(NULL),
+	mAudioGain(1.f),
+	mAppAngle(0.f),
+	mPixelArea(1024.f),
+	mInventory(NULL),
+	mInventorySerialNum(0),
+	mRegionp( regionp ),
+	mInventoryPending(FALSE),
+	mInventoryDirty(FALSE),
+	mDead(FALSE),
+	mOrphaned(FALSE),
+	mUserSelected(FALSE),
+	mOnActiveList(FALSE),
+	mOnMap(FALSE),
+	mStatic(FALSE),
+	mNumFaces(0),
+	mTimeDilation(1.f),
+	mRotTime(0.f),
+	mJointInfo(NULL),
+	mState(0),
+	mMedia(NULL),
+	mClickAction(0),
+	mObjectCost(0),
+	mLinksetCost(0),
+	mPhysicsCost(0),
+	mLinksetPhysicsCost(0.f),
+	mCostStale(true),
+	mPhysicsShapeUnknown(true),
+	mAttachmentItemID(LLUUID::null),
+	mLastUpdateType(OUT_UNKNOWN),
+	mLastUpdateCached(FALSE)
+{
+	if (!is_global)
+	{
+		llassert(mRegionp);
+	}
+
+	LLPrimitive::init_primitive(pcode);
+
+	// CP: added 12/2/2005 - this was being initialised to 0, not the current frame time
+	mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
+
+	mPositionRegion = LLVector3(0.f, 0.f, 0.f);
+
+	if (!is_global && mRegionp)
+	{
+		mPositionAgent = mRegionp->getOriginAgent();
+	}
+
+	LLViewerObject::sNumObjects++;
+}
+
+LLViewerObject::~LLViewerObject()
+{
+	deleteTEImages();
+
+	if(mInventory)
+	{
+		mInventory->clear();  // will deref and delete entries
+		delete mInventory;
+		mInventory = NULL;
+	}
+
+	if (mJointInfo)
+	{
+		delete mJointInfo;
+		mJointInfo = NULL;
+	}
+
+	if (mPartSourcep)
+	{
+		mPartSourcep->setDead();
+		mPartSourcep = NULL;
+	}
+
+	// Delete memory associated with extra parameters.
+	std::map<U16, ExtraParameter*>::iterator iter;
+	for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+	{
+		if(iter->second != NULL)
+		{
+			delete iter->second->data;
+			delete iter->second;
+		}
+	}
+	mExtraParameterList.clear();
+
+	for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
+	mNameValuePairs.clear();
+	
+	delete[] mData;
+	mData = NULL;
+
+	delete mMedia;
+	mMedia = NULL;
+
+	sNumObjects--;
+	sNumZombieObjects--;
+	llassert(mChildList.size() == 0);
+
+	clearInventoryListeners();
+}
+
+void LLViewerObject::deleteTEImages()
+{
+	delete[] mTEImages;
+	mTEImages = NULL;
+}
+
+void LLViewerObject::markDead()
+{
+	if (!mDead)
+	{
+		//llinfos << "Marking self " << mLocalID << " as dead." << llendl;
+		
+		// Root object of this hierarchy unlinks itself.
+		if (getParent())
+		{
+			((LLViewerObject *)getParent())->removeChild(this);
+			// go ahead and delete any jointinfo's that we find
+			delete mJointInfo;
+			mJointInfo = NULL;
+		}
+
+		// Mark itself as dead
+		mDead = TRUE;
+		gObjectList.cleanupReferences(this);
+
+		LLViewerObject *childp;
+		while (mChildList.size() > 0)
+		{
+			childp = mChildList.back();
+			if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
+			{
+				//llinfos << "Marking child " << childp->getLocalID() << " as dead." << llendl;
+				childp->setParent(NULL); // LLViewerObject::markDead 1
+				childp->markDead();
+			}
+			else
+			{
+				// make sure avatar is no longer parented, 
+				// so we can properly set it's position
+				childp->setDrawableParent(NULL);
+				((LLVOAvatar*)childp)->getOffObject();
+				childp->setParent(NULL); // LLViewerObject::markDead 2
+			}
+			mChildList.pop_back();
+		}
+
+		if (mDrawable.notNull())
+		{
+			// Drawables are reference counted, mark as dead, then nuke the pointer.
+			mDrawable->markDead();
+			mDrawable = NULL;
+		}
+
+		if (mText)
+		{
+			mText->markDead();
+			mText = NULL;
+		}
+
+		if (mIcon)
+		{
+			mIcon->markDead();
+			mIcon = NULL;
+		}
+
+		if (mPartSourcep)
+		{
+			mPartSourcep->setDead();
+			mPartSourcep = NULL;
+		}
+
+		if (mAudioSourcep)
+		{
+			// Do some cleanup
+			if (gAudiop)
+			{
+				gAudiop->cleanupAudioSource(mAudioSourcep);
+			}
+			mAudioSourcep = NULL;
+		}
+
+		if (flagAnimSource())
+		{
+			if (isAgentAvatarValid())
+			{
+				// stop motions associated with this object
+				gAgentAvatarp->stopMotionFromSource(mID);
+			}
+		}
+
+		if (flagCameraSource())
+		{
+			LLFollowCamMgr::removeFollowCamParams(mID);
+		}
+
+		sNumZombieObjects++;
+	}
+}
+
+void LLViewerObject::dump() const
+{
+	llinfos << "Type: " << pCodeToString(mPrimitiveCode) << llendl;
+	llinfos << "Drawable: " << (LLDrawable *)mDrawable << llendl;
+	llinfos << "Update Age: " << LLFrameTimer::getElapsedSeconds() - mLastMessageUpdateSecs << llendl;
+
+	llinfos << "Parent: " << getParent() << llendl;
+	llinfos << "ID: " << mID << llendl;
+	llinfos << "LocalID: " << mLocalID << llendl;
+	llinfos << "PositionRegion: " << getPositionRegion() << llendl;
+	llinfos << "PositionAgent: " << getPositionAgent() << llendl;
+	llinfos << "PositionGlobal: " << getPositionGlobal() << llendl;
+	llinfos << "Velocity: " << getVelocity() << llendl;
+	if (mDrawable.notNull() && mDrawable->getNumFaces())
+	{
+		LLFacePool *poolp = mDrawable->getFace(0)->getPool();
+		if (poolp)
+		{
+			llinfos << "Pool: " << poolp << llendl;
+			llinfos << "Pool reference count: " << poolp->mReferences.size() << llendl;
+		}
+	}
+	//llinfos << "BoxTree Min: " << mDrawable->getBox()->getMin() << llendl;
+	//llinfos << "BoxTree Max: " << mDrawable->getBox()->getMin() << llendl;
+	/*
+	llinfos << "Velocity: " << getVelocity() << llendl;
+	llinfos << "AnyOwner: " << permAnyOwner() << " YouOwner: " << permYouOwner() << " Edit: " << mPermEdit << llendl;
+	llinfos << "UsePhysics: " << usePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << llendl;
+	llinfos << "AppAngle: " << mAppAngle << llendl;
+	llinfos << "PixelArea: " << mPixelArea << llendl;
+
+	char buffer[1000];
+	char *key;
+	for (key = mNameValuePairs.getFirstKey(); key; key = mNameValuePairs.getNextKey() )
+	{
+		mNameValuePairs[key]->printNameValue(buffer);
+		llinfos << buffer << llendl;
+	}
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* child = *iter;
+		llinfos << "  child " << child->getID() << llendl;
+	}
+	*/
+}
+
+void LLViewerObject::printNameValuePairs() const
+{
+	for (name_value_map_t::const_iterator iter = mNameValuePairs.begin();
+		 iter != mNameValuePairs.end(); iter++)
+	{
+		LLNameValue* nv = iter->second;
+		llinfos << nv->printNameValue() << llendl;
+	}
+}
+
+void LLViewerObject::initVOClasses()
+{
+	// Initialized shared class stuff first.
+	LLVOAvatar::initClass();
+	LLVOTree::initClass();
+	llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl;
+	LLVOGrass::initClass();
+	LLVOWater::initClass();
+	LLVOVolume::initClass();
+}
+
+void LLViewerObject::cleanupVOClasses()
+{
+	LLVOGrass::cleanupClass();
+	LLVOWater::cleanupClass();
+	LLVOTree::cleanupClass();
+	LLVOAvatar::cleanupClass();
+	LLVOVolume::cleanupClass();
+}
+
+// Replaces all name value pairs with data from \n delimited list
+// Does not update server
+void LLViewerObject::setNameValueList(const std::string& name_value_list)
+{
+	// Clear out the old
+	for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
+	mNameValuePairs.clear();
+
+	// Bring in the new
+	std::string::size_type length = name_value_list.length();
+	std::string::size_type start = 0;
+	while (start < length)
+	{
+		std::string::size_type end = name_value_list.find_first_of("\n", start);
+		if (end == std::string::npos) end = length;
+		if (end > start)
+		{
+			std::string tok = name_value_list.substr(start, end - start);
+			addNVPair(tok);
+		}
+		start = end+1;
+	}
+}
+
+
+// This method returns true if the object is over land owned by the
+// agent.
+bool LLViewerObject::isReturnable()
+{
+	if (isAttachment())
+	{
+		return false;
+	}
+	std::vector<LLBBox> boxes;
+	boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* child = *iter;
+		boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+	}
+
+	return mRegionp
+		&& mRegionp->objectIsReturnable(getPositionRegion(), boxes);
+}
+
+BOOL LLViewerObject::setParent(LLViewerObject* parent)
+{
+	if(mParent != parent)
+	{
+		LLViewerObject* old_parent = (LLViewerObject*)mParent ;		
+		BOOL ret = LLPrimitive::setParent(parent);
+		if(ret && old_parent && parent)
+		{
+			old_parent->removeChild(this) ;
+		}
+		return ret ;
+	}
+
+	return FALSE ;
+}
+
+void LLViewerObject::addChild(LLViewerObject *childp)
+{
+	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
+	{
+		if (*i == childp)
+		{	//already has child
+			return;
+		}
+	}
+	
+	if (!isAvatar())
+	{
+		// propagate selection properties
+		childp->mbCanSelect = mbCanSelect;
+	}
+
+	if(childp->setParent(this))
+	{
+		mChildList.push_back(childp);
+	}
+}
+
+void LLViewerObject::removeChild(LLViewerObject *childp)
+{
+	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
+	{
+		if (*i == childp)
+		{
+			if (!childp->isAvatar() && mDrawable.notNull() && mDrawable->isActive() && childp->mDrawable.notNull() && !isAvatar())
+			{
+				gPipeline.markRebuild(childp->mDrawable, LLDrawable::REBUILD_VOLUME);
+			}
+
+			mChildList.erase(i);
+
+			if(childp->getParent() == this)
+			{
+				childp->setParent(NULL);			
+			}
+			break;
+		}
+	}
+	
+	if (childp->isSelected())
+	{
+		LLSelectMgr::getInstance()->deselectObjectAndFamily(childp);
+		BOOL add_to_end = TRUE;
+		LLSelectMgr::getInstance()->selectObjectAndFamily(childp, add_to_end);
+	}
+}
+
+void LLViewerObject::addThisAndAllChildren(std::vector<LLViewerObject*>& objects)
+{
+	objects.push_back(this);
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* child = *iter;
+		if (!child->isAvatar())
+		{
+			child->addThisAndAllChildren(objects);
+		}
+	}
+}
+
+void LLViewerObject::addThisAndNonJointChildren(std::vector<LLViewerObject*>& objects)
+{
+	objects.push_back(this);
+	// don't add any attachments when temporarily selecting avatar
+	if (isAvatar())
+	{
+		return;
+	}
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* child = *iter;
+		if ( (!child->isAvatar()) && (!child->isJointChild()))
+		{
+			child->addThisAndNonJointChildren(objects);
+		}
+	}
+}
+
+BOOL LLViewerObject::isChild(LLViewerObject *childp) const
+{
+	for (child_list_t::const_iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* testchild = *iter;
+		if (testchild == childp)
+			return TRUE;
+	}
+	return FALSE;
+}
+
+
+// returns TRUE if at least one avatar is sitting on this object
+BOOL LLViewerObject::isSeat() const
+{
+	for (child_list_t::const_iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* child = *iter;
+		if (child->isAvatar())
+		{
+			return TRUE;
+		}
+	}
+	return FALSE;
+
+}
+
+BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
+{
+	if (mDrawable.isNull())
+	{
+		return FALSE;
+	}
+
+	BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
+	if(!ret)
+	{
+		return FALSE ;
+	}
+	LLDrawable* old_parent = mDrawable->mParent;
+	mDrawable->mParent = parentp; 
+		
+	gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+	if(	(old_parent != parentp && old_parent)
+		|| (parentp && parentp->isActive()))
+	{
+		// *TODO we should not be relying on setDrawable parent to call markMoved
+		gPipeline.markMoved(mDrawable, FALSE);
+	}
+	else if (!mDrawable->isAvatar())
+	{
+		mDrawable->updateXform(TRUE);
+		/*if (!mDrawable->getSpatialGroup())
+		{
+			mDrawable->movePartition();
+		}*/
+	}
+	
+	return ret;
+}
+
+// Show or hide particles, icon and HUD
+void LLViewerObject::hideExtraDisplayItems( BOOL hidden )
+{
+	if( mPartSourcep.notNull() )
+	{
+		LLViewerPartSourceScript *partSourceScript = mPartSourcep.get();
+		partSourceScript->setSuspended( hidden );
+	}
+
+	if( mText.notNull() )
+	{
+		LLHUDText *hudText = mText.get();
+		hudText->setHidden( hidden );
+	}
+
+	if( mIcon.notNull() )
+	{
+		LLHUDIcon *hudIcon = mIcon.get();
+		hudIcon->setHidden( hidden );
+	}
+}
+
+U32 LLViewerObject::checkMediaURL(const std::string &media_url)
+{
+    U32 retval = (U32)0x0;
+    if (!mMedia && !media_url.empty())
+    {
+        retval |= MEDIA_URL_ADDED;
+        mMedia = new LLViewerObjectMedia;
+        mMedia->mMediaURL = media_url;
+        mMedia->mMediaType = LLViewerObject::MEDIA_SET;
+        mMedia->mPassedWhitelist = FALSE;
+    }
+    else if (mMedia)
+    {
+        if (media_url.empty())
+        {
+            retval |= MEDIA_URL_REMOVED;
+            delete mMedia;
+            mMedia = NULL;
+        }
+        else if (mMedia->mMediaURL != media_url) // <-- This is an optimization.  If they are equal don't bother with below's test.
+        {
+            /*if (! (LLTextureEntry::getAgentIDFromMediaVersionString(media_url) == gAgent.getID() &&
+                   LLTextureEntry::getVersionFromMediaVersionString(media_url) == 
+                        LLTextureEntry::getVersionFromMediaVersionString(mMedia->mMediaURL) + 1))
+			*/
+            {
+                // If the media URL is different and WE were not the one who
+                // changed it, mark dirty.
+                retval |= MEDIA_URL_UPDATED;
+            }
+            mMedia->mMediaURL = media_url;
+            mMedia->mPassedWhitelist = FALSE;
+        }
+    }
+    return retval;
+}
+
+U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
+					 void **user_data,
+					 U32 block_num,
+					 const EObjectUpdateType update_type,
+					 LLDataPacker *dp)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	U32 retval = 0x0;
+	
+	// Coordinates of objects on simulators are region-local.
+	U64 region_handle;
+	mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
+	
+	{
+		LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
+		if(regionp != mRegionp && regionp && mRegionp)//region cross
+		{
+			//this is the redundant position and region update, but it is necessary in case the viewer misses the following 
+			//position and region update messages from sim.
+			//this redundant update should not cause any problems.
+			LLVector3 delta_pos =  mRegionp->getOriginAgent() - regionp->getOriginAgent();
+			setPositionParent(getPosition() + delta_pos); //update to the new region position immediately.
+			setRegion(regionp) ; //change the region.
+		}
+		else
+		{
+			mRegionp = regionp ;
+		}
+	}	
+	
+	if (!mRegionp)
+	{
+		U32 x, y;
+		from_region_handle(region_handle, &x, &y);
+
+		llerrs << "Object has invalid region " << x << ":" << y << "!" << llendl;
+		return retval;
+	}
+
+	U16 time_dilation16;
+	mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
+	F32 time_dilation = ((F32) time_dilation16) / 65535.f;
+	mTimeDilation = time_dilation;
+	mRegionp->setTimeDilation(time_dilation);
+
+	// this will be used to determine if we've really changed position
+	// Use getPosition, not getPositionRegion, since this is what we're comparing directly against.
+	LLVector3 test_pos_parent = getPosition();
+
+	U8  data[60+16]; // This needs to match the largest size below.
+#ifdef LL_BIG_ENDIAN
+	U16 valswizzle[4];
+#endif
+	U16	*val;
+	const F32 size = LLWorld::getInstance()->getRegionWidthInMeters();	
+	const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight();
+	const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight();
+	S32 length;
+	S32	count;
+	S32 this_update_precision = 32;		// in bits
+
+	// Temporaries, because we need to compare w/ previous to set dirty flags...
+	LLVector3 new_pos_parent;
+	LLVector3 new_vel;
+	LLVector3 new_acc;
+	LLVector3 new_angv;
+	LLVector3 old_angv = getAngularVelocity();
+	LLQuaternion new_rot;
+	LLVector3 new_scale = getScale();
+
+	U32	parent_id = 0;
+	U8	material = 0;
+	U8 click_action = 0;
+	U32 crc = 0;
+
+	bool old_special_hover_cursor = specialHoverCursor();
+
+	LLViewerObject *cur_parentp = (LLViewerObject *)getParent();
+
+	if (cur_parentp)
+	{
+		parent_id = cur_parentp->mLocalID;
+	}
+
+	if (!dp)
+	{
+		switch(update_type)
+		{
+		case OUT_FULL:
+			{
+#ifdef DEBUG_UPDATE_TYPE
+				llinfos << "Full:" << getID() << llendl;
+#endif
+				//clear cost and linkset cost
+				mCostStale = true;
+				if (isSelected())
+				{
+					gFloaterTools->dirty();
+				}
+
+				LLUUID audio_uuid;
+				LLUUID owner_id;	// only valid if audio_uuid or particle system is not null
+				F32    gain;
+				U8     sound_flags;
+
+				mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num);
+				mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_ParentID, parent_id, block_num);
+				mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_Sound, audio_uuid, block_num );
+				// HACK: Owner id only valid if non-null sound id or particle system
+				mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num );
+				mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num );
+				mesgsys->getU8Fast(  _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num );
+				mesgsys->getU8Fast(  _PREHASH_ObjectData, _PREHASH_Material, material, block_num );
+				mesgsys->getU8Fast(  _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num); 
+				mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num );
+				length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
+				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num);
+
+				mTotalCRC = crc;
+
+				// Owner ID used for sound muting or particle system muting
+				setAttachedSound(audio_uuid, owner_id, gain, sound_flags);
+
+				U8 old_material = getMaterial();
+				if (old_material != material)
+				{
+					setMaterial(material);
+					if (mDrawable.notNull())
+					{
+						gPipeline.markMoved(mDrawable, FALSE); // undamped
+					}
+				}
+				setClickAction(click_action);
+
+				count = 0;
+				LLVector4 collision_plane;
+				
+				switch(length)
+				{
+				case (60 + 16):
+					// pull out collision normal for avatar
+					htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+					((LLVOAvatar*)this)->setFootPlane(collision_plane);
+					count += sizeof(LLVector4);
+					// fall through
+				case 60:
+					this_update_precision = 32;
+					// this is a terse update
+					// pos
+					htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+					count += sizeof(LLVector3);
+					// vel
+					htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+					count += sizeof(LLVector3);
+					// acc
+					htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+					count += sizeof(LLVector3);
+					// theta
+					{
+						LLVector3 vec;
+						htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+						new_rot.unpackFromVector3(vec);
+					}
+					count += sizeof(LLVector3);
+					// omega
+					htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+					if (new_angv.isExactlyZero())
+					{
+						// reset rotation time
+						resetRot();
+					}
+					setAngularVelocity(new_angv);
+#if LL_DARWIN
+					if (length == 76)
+					{
+						setAngularVelocity(LLVector3::zero);
+					}
+#endif
+					break;
+				case(32 + 16):
+					// pull out collision normal for avatar
+					htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+					((LLVOAvatar*)this)->setFootPlane(collision_plane);
+					count += sizeof(LLVector4);
+					// fall through
+				case 32:
+					this_update_precision = 16;
+					test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
+
+					// This is a terse 16 update, so treat data as an array of U16's.
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					count += sizeof(U16)*3;
+					new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
+					new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
+					new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
+
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					count += sizeof(U16)*3;
+					setVelocity(LLVector3(U16_to_F32(val[VX], -size, size),
+													   U16_to_F32(val[VY], -size, size),
+													   U16_to_F32(val[VZ], -size, size)));
+
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					count += sizeof(U16)*3;
+					setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size),
+														   U16_to_F32(val[VY], -size, size),
+														   U16_to_F32(val[VZ], -size, size)));
+
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 4); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					count += sizeof(U16)*4;
+					new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
+					new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
+					new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
+					new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
+
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					new_angv.setVec(U16_to_F32(val[VX], -size, size),
+										U16_to_F32(val[VY], -size, size),
+										U16_to_F32(val[VZ], -size, size));
+					if (new_angv.isExactlyZero())
+					{
+						// reset rotation time
+						resetRot();
+					}
+					setAngularVelocity(new_angv);
+					break;
+
+				case 16:
+					this_update_precision = 8;
+					test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
+					// this is a terse 8 update
+					new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
+					new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
+					new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
+
+					setVelocity(U8_to_F32(data[3], -size, size),
+								U8_to_F32(data[4], -size, size),
+								U8_to_F32(data[5], -size, size) );
+
+					setAcceleration(U8_to_F32(data[6], -size, size),
+									U8_to_F32(data[7], -size, size),
+									U8_to_F32(data[8], -size, size) );
+
+					new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
+					new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
+					new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
+					new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
+
+					new_angv.setVec(U8_to_F32(data[13], -size, size),
+										U8_to_F32(data[14], -size, size),
+										U8_to_F32(data[15], -size, size) );
+					if (new_angv.isExactlyZero())
+					{
+						// reset rotation time
+						resetRot();
+					}
+					setAngularVelocity(new_angv);
+					break;
+				}
+
+				////////////////////////////////////////////////////
+				//
+				// Here we handle data specific to the full message.
+				//
+
+				U32 flags;
+				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
+				// clear all but local flags
+				mFlags &= FLAGS_LOCAL;
+				mFlags |= flags;
+
+				U8 state;
+				mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
+				mState = state;
+
+				// ...new objects that should come in selected need to be added to the selected list
+				mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
+
+				// Set all name value pairs
+				S32 nv_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_NameValue);
+				if (nv_size > 0)
+				{
+					std::string name_value_list;
+					mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_NameValue, name_value_list, block_num);
+					setNameValueList(name_value_list);
+				}
+
+				// Clear out any existing generic data
+				if (mData)
+				{
+					delete [] mData;
+				}
+
+				// Check for appended generic data
+				S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data);
+				if (data_size <= 0)
+				{
+					mData = NULL;
+				}
+				else
+				{
+					// ...has generic data
+					mData = new U8[data_size];
+					mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num);
+				}
+
+				S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text);
+				if (text_size > 1)
+				{
+					// Setup object text
+					if (!mText)
+					{
+						mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
+						mText->setFont(LLFontGL::getFontSansSerif());
+						mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
+						mText->setMaxLines(-1);
+						mText->setSourceObject(this);
+						mText->setOnHUDAttachment(isHUDAttachment());
+					}
+
+					std::string temp_string;
+					mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num );
+					
+					LLColor4U coloru;
+					mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num);
+
+					// alpha was flipped so that it zero encoded better
+					coloru.mV[3] = 255 - coloru.mV[3];
+					mText->setColor(LLColor4(coloru));
+					mText->setString(temp_string);
+					
+					if (mDrawable.notNull())
+					{
+						setChanged(MOVED | SILHOUETTE);
+						gPipeline.markMoved(mDrawable, FALSE); // undamped
+					}
+				}
+				else if (mText.notNull())
+				{
+					mText->markDead();
+					mText = NULL;
+				}
+
+				std::string media_url;
+				mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num);
+                retval |= checkMediaURL(media_url);
+                
+				//
+				// Unpack particle system data
+				//
+				unpackParticleSource(block_num, owner_id);
+
+				// Mark all extra parameters not used
+				std::map<U16, ExtraParameter*>::iterator iter;
+				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+				{
+					iter->second->in_use = FALSE;
+				}
+
+				// Unpack extra parameters
+				S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams);
+				if (size > 0)
+				{
+					U8 *buffer = new U8[size];
+					mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num);
+					LLDataPackerBinaryBuffer dp(buffer, size);
+
+					U8 num_parameters;
+					dp.unpackU8(num_parameters, "num_params");
+					U8 param_block[MAX_OBJECT_PARAMS_SIZE];
+					for (U8 param=0; param<num_parameters; ++param)
+					{
+						U16 param_type;
+						S32 param_size;
+						dp.unpackU16(param_type, "param_type");
+						dp.unpackBinaryData(param_block, param_size, "param_data");
+						//llinfos << "Param type: " << param_type << ", Size: " << param_size << llendl;
+						LLDataPackerBinaryBuffer dp2(param_block, param_size);
+						unpackParameterEntry(param_type, &dp2);
+					}
+					delete[] buffer;
+				}
+
+				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+				{
+					if (!iter->second->in_use)
+					{
+						// Send an update message in case it was formerly in use
+						parameterChanged(iter->first, iter->second->data, FALSE, false);
+					}
+				}
+
+				U8 joint_type = 0;
+				mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_JointType, joint_type, block_num);
+				if (joint_type)
+				{
+					// create new joint info 
+					if (!mJointInfo)
+					{
+						mJointInfo = new LLVOJointInfo;
+					}
+					mJointInfo->mJointType = (EHavokJointType) joint_type;
+					mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointPivot, mJointInfo->mPivot, block_num);
+					mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointAxisOrAnchor, mJointInfo->mAxisOrAnchor, block_num);
+				}
+				else if (mJointInfo)
+				{
+					// this joint info is no longer needed
+					delete mJointInfo;
+					mJointInfo = NULL;
+				}
+
+				break;
+			}
+
+		case OUT_TERSE_IMPROVED:
+			{
+#ifdef DEBUG_UPDATE_TYPE
+				llinfos << "TI:" << getID() << llendl;
+#endif
+				length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
+				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num);
+				count = 0;
+				LLVector4 collision_plane;
+				
+				switch(length)
+				{
+				case(60 + 16):
+					// pull out collision normal for avatar
+					htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+					((LLVOAvatar*)this)->setFootPlane(collision_plane);
+					count += sizeof(LLVector4);
+					// fall through
+				case 60:
+					// this is a terse 32 update
+					// pos
+					this_update_precision = 32;
+					htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+					count += sizeof(LLVector3);
+					// vel
+					htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+					count += sizeof(LLVector3);
+					// acc
+					htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+					count += sizeof(LLVector3);
+					// theta
+					{
+						LLVector3 vec;
+						htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+						new_rot.unpackFromVector3(vec);
+					}
+					count += sizeof(LLVector3);
+					// omega
+					htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+					if (new_angv.isExactlyZero())
+					{
+						// reset rotation time
+						resetRot();
+					}
+					setAngularVelocity(new_angv);
+#if LL_DARWIN
+					if (length == 76)
+					{
+						setAngularVelocity(LLVector3::zero);
+					}
+#endif
+					break;
+				case(32 + 16):
+					// pull out collision normal for avatar
+					htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+					((LLVOAvatar*)this)->setFootPlane(collision_plane);
+					count += sizeof(LLVector4);
+					// fall through
+				case 32:
+					// this is a terse 16 update
+					this_update_precision = 16;
+					test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
+
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					count += sizeof(U16)*3;
+					new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
+					new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
+					new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
+
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					count += sizeof(U16)*3;
+					setVelocity(U16_to_F32(val[VX], -size, size),
+								U16_to_F32(val[VY], -size, size),
+								U16_to_F32(val[VZ], -size, size));
+
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					count += sizeof(U16)*3;
+					setAcceleration(U16_to_F32(val[VX], -size, size),
+									U16_to_F32(val[VY], -size, size),
+									U16_to_F32(val[VZ], -size, size));
+
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 8); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					count += sizeof(U16)*4;
+					new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
+					new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
+					new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
+					new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
+
+#ifdef LL_BIG_ENDIAN
+					htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6); 
+					val = valswizzle;
+#else
+					val = (U16 *) &data[count];
+#endif
+					setAngularVelocity(	U16_to_F32(val[VX], -size, size),
+										U16_to_F32(val[VY], -size, size),
+										U16_to_F32(val[VZ], -size, size));
+					break;
+
+				case 16:
+					// this is a terse 8 update
+					this_update_precision = 8;
+					test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
+					new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
+					new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
+					new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
+
+					setVelocity(U8_to_F32(data[3], -size, size),
+								U8_to_F32(data[4], -size, size),
+								U8_to_F32(data[5], -size, size) );
+
+					setAcceleration(U8_to_F32(data[6], -size, size),
+									U8_to_F32(data[7], -size, size),
+									U8_to_F32(data[8], -size, size) );
+
+					new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
+					new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
+					new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
+					new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
+
+					setAngularVelocity(	U8_to_F32(data[13], -size, size),
+										U8_to_F32(data[14], -size, size),
+										U8_to_F32(data[15], -size, size) );
+					break;
+				}
+
+				U8 state;
+				mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
+				mState = state;
+				break;
+			}
+
+		default:
+			break;
+
+		}
+	}
+	else
+	{
+		// handle the compressed case
+		LLUUID sound_uuid;
+		LLUUID	owner_id;
+		F32    gain = 0;
+		U8     sound_flags = 0;
+		F32		cutoff = 0;
+
+		U16 val[4];
+
+		U8		state;
+
+		dp->unpackU8(state, "State");
+		mState = state;
+
+		switch(update_type)
+		{
+			case OUT_TERSE_IMPROVED:
+			{
+#ifdef DEBUG_UPDATE_TYPE
+				llinfos << "CompTI:" << getID() << llendl;
+#endif
+				U8		value;
+				dp->unpackU8(value, "agent");
+				if (value)
+				{
+					LLVector4 collision_plane;
+					dp->unpackVector4(collision_plane, "Plane");
+					((LLVOAvatar*)this)->setFootPlane(collision_plane);
+				}
+				test_pos_parent = getPosition();
+				dp->unpackVector3(new_pos_parent, "Pos");
+				dp->unpackU16(val[VX], "VelX");
+				dp->unpackU16(val[VY], "VelY");
+				dp->unpackU16(val[VZ], "VelZ");
+				setVelocity(U16_to_F32(val[VX], -128.f, 128.f),
+							U16_to_F32(val[VY], -128.f, 128.f),
+							U16_to_F32(val[VZ], -128.f, 128.f));
+				dp->unpackU16(val[VX], "AccX");
+				dp->unpackU16(val[VY], "AccY");
+				dp->unpackU16(val[VZ], "AccZ");
+				setAcceleration(U16_to_F32(val[VX], -64.f, 64.f),
+								U16_to_F32(val[VY], -64.f, 64.f),
+								U16_to_F32(val[VZ], -64.f, 64.f));
+
+				dp->unpackU16(val[VX], "ThetaX");
+				dp->unpackU16(val[VY], "ThetaY");
+				dp->unpackU16(val[VZ], "ThetaZ");
+				dp->unpackU16(val[VS], "ThetaS");
+				new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
+				new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
+				new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
+				new_rot.mQ[VS] = U16_to_F32(val[VS], -1.f, 1.f);
+				dp->unpackU16(val[VX], "AccX");
+				dp->unpackU16(val[VY], "AccY");
+				dp->unpackU16(val[VZ], "AccZ");
+				setAngularVelocity(	U16_to_F32(val[VX], -64.f, 64.f),
+									U16_to_F32(val[VY], -64.f, 64.f),
+									U16_to_F32(val[VZ], -64.f, 64.f));
+			}
+			break;
+			case OUT_FULL_COMPRESSED:
+			case OUT_FULL_CACHED:
+			{
+#ifdef DEBUG_UPDATE_TYPE
+				llinfos << "CompFull:" << getID() << llendl;
+#endif
+				mCostStale = true;
+
+				if (isSelected())
+				{
+					gFloaterTools->dirty();
+				}
+	
+				dp->unpackU32(crc, "CRC");
+				mTotalCRC = crc;
+				dp->unpackU8(material, "Material");
+				U8 old_material = getMaterial();
+				if (old_material != material)
+				{
+					setMaterial(material);
+					if (mDrawable.notNull())
+					{
+						gPipeline.markMoved(mDrawable, FALSE); // undamped
+					}
+				}
+				dp->unpackU8(click_action, "ClickAction");
+				setClickAction(click_action);
+				dp->unpackVector3(new_scale, "Scale");
+				dp->unpackVector3(new_pos_parent, "Pos");
+				LLVector3 vec;
+				dp->unpackVector3(vec, "Rot");
+				new_rot.unpackFromVector3(vec);
+				setAcceleration(LLVector3::zero);
+
+				U32 value;
+				dp->unpackU32(value, "SpecialCode");
+				dp->setPassFlags(value);
+				dp->unpackUUID(owner_id, "Owner");
+
+				if (value & 0x80)
+				{
+					dp->unpackVector3(vec, "Omega");
+					setAngularVelocity(vec);
+				}
+
+				if (value & 0x20)
+				{
+					dp->unpackU32(parent_id, "ParentID");
+				}
+				else
+				{
+					parent_id = 0;
+				}
+
+				S32 sp_size;
+				U32 size;
+				if (value & 0x2)
+				{
+					sp_size = 1;
+					delete [] mData;
+					mData = new U8[1];
+					dp->unpackU8(((U8*)mData)[0], "TreeData");
+				}
+				else if (value & 0x1)
+				{
+					dp->unpackU32(size, "ScratchPadSize");
+					delete [] mData;
+					mData = new U8[size];
+					dp->unpackBinaryData((U8 *)mData, sp_size, "PartData");
+				}
+				else
+				{
+					mData = NULL;
+				}
+
+				// Setup object text
+				if (!mText && (value & 0x4))
+				{
+					mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
+					mText->setFont(LLFontGL::getFontSansSerif());
+					mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
+					mText->setMaxLines(-1); // Set to match current agni behavior.
+					mText->setSourceObject(this);
+					mText->setOnHUDAttachment(isHUDAttachment());
+				}
+
+				if (value & 0x4)
+				{
+					std::string temp_string;
+					dp->unpackString(temp_string, "Text");
+					LLColor4U coloru;
+					dp->unpackBinaryDataFixed(coloru.mV, 4, "Color");
+					coloru.mV[3] = 255 - coloru.mV[3];
+					mText->setColor(LLColor4(coloru));
+					mText->setString(temp_string);
+
+					setChanged(TEXTURE);
+				}
+				else if(mText.notNull())
+				{
+					mText->markDead();
+					mText = NULL;
+				}
+
+                std::string media_url;
+				if (value & 0x200)
+				{
+					dp->unpackString(media_url, "MediaURL");
+				}
+                retval |= checkMediaURL(media_url);
+
+				//
+				// Unpack particle system data
+				//
+				if (value & 0x8)
+				{
+					unpackParticleSource(*dp, owner_id);
+				}
+				else
+				{
+					deleteParticleSource();
+				}
+				
+				// Mark all extra parameters not used
+				std::map<U16, ExtraParameter*>::iterator iter;
+				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+				{
+					iter->second->in_use = FALSE;
+				}
+
+				// Unpack extra params
+				U8 num_parameters;
+				dp->unpackU8(num_parameters, "num_params");
+				U8 param_block[MAX_OBJECT_PARAMS_SIZE];
+				for (U8 param=0; param<num_parameters; ++param)
+				{
+					U16 param_type;
+					S32 param_size;
+					dp->unpackU16(param_type, "param_type");
+					dp->unpackBinaryData(param_block, param_size, "param_data");
+					//llinfos << "Param type: " << param_type << ", Size: " << param_size << llendl;
+					LLDataPackerBinaryBuffer dp2(param_block, param_size);
+					unpackParameterEntry(param_type, &dp2);
+				}
+
+				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+				{
+					if (!iter->second->in_use)
+					{
+						// Send an update message in case it was formerly in use
+						parameterChanged(iter->first, iter->second->data, FALSE, false);
+					}
+				}
+
+				if (value & 0x10)
+				{
+					dp->unpackUUID(sound_uuid, "SoundUUID");
+					dp->unpackF32(gain, "SoundGain");
+					dp->unpackU8(sound_flags, "SoundFlags");
+					dp->unpackF32(cutoff, "SoundRadius");
+				}
+
+				if (value & 0x100)
+				{
+					std::string name_value_list;
+					dp->unpackString(name_value_list, "NV");
+
+					setNameValueList(name_value_list);
+				}
+
+				mTotalCRC = crc;
+
+				setAttachedSound(sound_uuid, owner_id, gain, sound_flags);
+
+				// only get these flags on updates from sim, not cached ones
+				// Preload these five flags for every object.
+				// Finer shades require the object to be selected, and the selection manager
+				// stores the extended permission info.
+				U32 flags;
+				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
+				// keep local flags and overwrite remote-controlled flags
+				mFlags = (mFlags & FLAGS_LOCAL) | flags;
+
+					// ...new objects that should come in selected need to be added to the selected list
+				mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	//
+	// Fix object parenting.
+	//
+	BOOL b_changed_status = FALSE;
+
+	if (OUT_TERSE_IMPROVED != update_type)
+	{
+		// We only need to update parenting on full updates, terse updates
+		// don't send parenting information.
+		if (!cur_parentp)
+		{
+			if (parent_id == 0)
+			{
+				// No parent now, no parent in message -> do nothing
+			}
+			else
+			{
+				// No parent now, new parent in message -> attach to that parent if possible
+				LLUUID parent_uuid;
+				LLViewerObjectList::getUUIDFromLocal(parent_uuid,
+														parent_id,
+														mesgsys->getSenderIP(),
+														mesgsys->getSenderPort());
+
+				LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid);
+
+				//
+				// Check to see if we have the corresponding viewer object for the parent.
+				//
+				if (sent_parentp && sent_parentp->getParent() == this)
+				{
+					// Try to recover if we attempt to attach a parent to its child
+					llwarns << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << llendl;
+					this->removeChild(sent_parentp);
+					sent_parentp->setDrawableParent(NULL);
+				}
+				
+				if (sent_parentp && (sent_parentp != this) && !sent_parentp->isDead())
+				{
+					//
+					// We have a viewer object for the parent, and it's not dead.
+					// Do the actual reparenting here.
+					//
+
+					// new parent is valid
+					b_changed_status = TRUE;
+					// ...no current parent, so don't try to remove child
+					if (mDrawable.notNull())
+					{
+						if (mDrawable->isDead() || !mDrawable->getVObj())
+						{
+							llwarns << "Drawable is dead or no VObj!" << llendl;
+							sent_parentp->addChild(this);
+						}
+						else
+						{
+							if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 1
+							{
+								// Bad, we got a cycle somehow.
+								// Kill both the parent and the child, and
+								// set cache misses for both of them.
+								llwarns << "Attempting to recover from parenting cycle!" << llendl;
+								llwarns << "Killing " << sent_parentp->getID() << " and " << getID() << llendl;
+								llwarns << "Adding to cache miss list" << llendl;
+								setParent(NULL);
+								sent_parentp->setParent(NULL);
+								getRegion()->addCacheMissFull(getLocalID());
+								getRegion()->addCacheMissFull(sent_parentp->getLocalID());
+								gObjectList.killObject(sent_parentp);
+								gObjectList.killObject(this);
+								return retval;
+							}
+							sent_parentp->addChild(this);
+							// make sure this object gets a non-damped update
+							if (sent_parentp->mDrawable.notNull())
+							{
+								gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
+							}
+						}
+					}
+					else
+					{
+						sent_parentp->addChild(this);
+					}
+					
+					// Show particles, icon and HUD
+					hideExtraDisplayItems( FALSE );
+
+					setChanged(MOVED | SILHOUETTE);
+				}
+				else
+				{
+					//
+					// No corresponding viewer object for the parent, put the various
+					// pieces on the orphan list.
+					//
+					
+					//parent_id
+					U32 ip = mesgsys->getSenderIP();
+					U32 port = mesgsys->getSenderPort();
+					
+					gObjectList.orphanize(this, parent_id, ip, port);
+
+					// Hide particles, icon and HUD
+					hideExtraDisplayItems( TRUE );
+				}
+			}
+		}
+		else
+		{
+			// BUG: this is a bad assumption once border crossing is alowed
+			if (  (parent_id == cur_parentp->mLocalID)
+				&&(update_type == OUT_TERSE_IMPROVED))
+			{
+				// Parent now, same parent in message -> do nothing
+
+				// Debugging for suspected problems with local ids.
+				//LLUUID parent_uuid;
+				//LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, mesgsys->getSenderIP(), mesgsys->getSenderPort() );
+				//if (parent_uuid != cur_parentp->getID() )
+				//{
+				//	llerrs << "Local ID match but UUID mismatch of viewer object" << llendl;
+				//}
+			}
+			else
+			{
+				// Parented now, different parent in message
+				LLViewerObject *sent_parentp;
+				if (parent_id == 0)
+				{
+					//
+					// This object is no longer parented, we sent in a zero parent ID.
+					//
+					sent_parentp = NULL;
+				}
+				else
+				{
+					LLUUID parent_uuid;
+					LLViewerObjectList::getUUIDFromLocal(parent_uuid,
+														parent_id,
+														gMessageSystem->getSenderIP(),
+														gMessageSystem->getSenderPort());
+					sent_parentp = gObjectList.findObject(parent_uuid);
+					
+					if (isAvatar())
+					{
+						// This logic is meant to handle the case where a sitting avatar has reached a new sim
+						// ahead of the object she was sitting on (which is common as objects are transfered through
+						// a slower route than agents)...
+						// In this case, the local id for the object will not be valid, since the viewer has not received
+						// a full update for the object from that sim yet, so we assume that the agent is still sitting
+						// where she was originally. --RN
+						if (!sent_parentp)
+						{
+							sent_parentp = cur_parentp;
+						}
+					}
+					else if (!sent_parentp)
+					{
+						//
+						// Switching parents, but we don't know the new parent.
+						//
+						U32 ip = mesgsys->getSenderIP();
+						U32 port = mesgsys->getSenderPort();
+
+						// We're an orphan, flag things appropriately.
+						gObjectList.orphanize(this, parent_id, ip, port);
+					}
+				}
+
+				// Reattach if possible.
+				if (sent_parentp && sent_parentp != cur_parentp && sent_parentp != this)
+				{
+					// New parent is valid, detach and reattach
+					b_changed_status = TRUE;
+					if (mDrawable.notNull())
+					{
+						if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 2
+						{
+							// Bad, we got a cycle somehow.
+							// Kill both the parent and the child, and
+							// set cache misses for both of them.
+							llwarns << "Attempting to recover from parenting cycle!" << llendl;
+							llwarns << "Killing " << sent_parentp->getID() << " and " << getID() << llendl;
+							llwarns << "Adding to cache miss list" << llendl;
+							setParent(NULL);
+							sent_parentp->setParent(NULL);
+							getRegion()->addCacheMissFull(getLocalID());
+							getRegion()->addCacheMissFull(sent_parentp->getLocalID());
+							gObjectList.killObject(sent_parentp);
+							gObjectList.killObject(this);
+							return retval;
+						}
+						// make sure this object gets a non-damped update
+					}
+					cur_parentp->removeChild(this);
+					sent_parentp->addChild(this);
+					setChanged(MOVED | SILHOUETTE);
+					sent_parentp->setChanged(MOVED | SILHOUETTE);
+					if (sent_parentp->mDrawable.notNull())
+					{
+						gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
+					}
+				}
+				else if (!sent_parentp)
+				{
+					bool remove_parent = true;
+					// No new parent, or the parent that we sent doesn't exist on the viewer.
+					LLViewerObject *parentp = (LLViewerObject *)getParent();
+					if (parentp)
+					{
+						if (parentp->getRegion() != getRegion())
+						{
+							// This is probably an object flying across a region boundary, the
+							// object probably ISN'T being reparented, but just got an object
+							// update out of order (child update before parent).
+							//llinfos << "Don't reparent object handoffs!" << llendl;
+							remove_parent = false;
+						}
+					}
+
+					if (remove_parent)
+					{
+						b_changed_status = TRUE;
+						if (mDrawable.notNull())
+						{
+							// clear parent to removeChild can put the drawable on the damped list
+							setDrawableParent(NULL); // LLViewerObject::processUpdateMessage 3
+						}
+
+						cur_parentp->removeChild(this);
+
+						if (mJointInfo && !parent_id)
+						{
+							// since this object is no longer parent-relative
+							// we make sure we delete any joint info
+							delete mJointInfo;
+							mJointInfo = NULL;
+						}
+
+						setChanged(MOVED | SILHOUETTE);
+
+						if (mDrawable.notNull())
+						{
+							// make sure this object gets a non-damped update
+							gPipeline.markMoved(mDrawable, FALSE); // undamped
+						}
+					}
+				}
+			}
+		}
+	}
+
+	new_rot.normQuat();
+
+	if (sPingInterpolate)
+	{ 
+		LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
+		if (cdp)
+		{
+			F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped);
+			LLVector3 diff = getVelocity() * ping_delay; 
+			new_pos_parent += diff;
+		}
+		else
+		{
+			llwarns << "findCircuit() returned NULL; skipping interpolation" << llendl;
+		}
+	}
+
+	//////////////////////////
+	//
+	// Set the generic change flags...
+	//
+	//
+
+	// WTF?   If we're going to skip this message, why are we 
+	// doing all the parenting, etc above?
+	U32 packet_id = mesgsys->getCurrentRecvPacketID(); 
+	if (packet_id < mLatestRecvPacketID && 
+		mLatestRecvPacketID - packet_id < 65536)
+	{
+		//skip application of this message, it's old
+		return retval;
+	}
+
+	mLatestRecvPacketID = packet_id;
+
+	// Set the change flags for scale
+	if (new_scale != getScale())
+	{
+		setChanged(SCALED | SILHOUETTE);
+		setScale(new_scale);  // Must follow setting permYouOwner()
+	}
+
+	// first, let's see if the new position is actually a change
+
+	//static S32 counter = 0;
+
+	F32 vel_mag_sq = getVelocity().magVecSquared();
+	F32 accel_mag_sq = getAcceleration().magVecSquared();
+
+	if (  ((b_changed_status)||(test_pos_parent != new_pos_parent))
+		||(  (!isSelected())
+		   &&(  (vel_mag_sq != 0.f)
+			  ||(accel_mag_sq != 0.f)
+			  ||(this_update_precision > mBestUpdatePrecision))))
+	{
+		mBestUpdatePrecision = this_update_precision;
+		
+		LLVector3 diff = new_pos_parent - test_pos_parent ;
+		F32 mag_sqr = diff.magVecSquared() ;
+		if(llfinite(mag_sqr)) 
+		{
+			setPositionParent(new_pos_parent);
+		}
+		else
+		{
+			llwarns << "Can not move the object/avatar to an infinite location!" << llendl ;	
+
+			retval |= INVALID_UPDATE ;
+		}
+
+		if (mParent && ((LLViewerObject*)mParent)->isAvatar())
+		{
+			// we have changed the position of an attachment, so we need to clamp it
+			LLVOAvatar *avatar = (LLVOAvatar*)mParent;
+
+			avatar->clampAttachmentPositions();
+		}
+		
+		// If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps
+		if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) )
+		{
+			LLViewerStats::getInstance()->mAgentPositionSnaps.push( diff.length() );
+		}
+	}
+
+	if (new_rot != mLastRot
+		|| new_angv != old_angv)
+	{
+		if (new_rot != mLastRot)
+		{
+			mLastRot = new_rot;
+			setRotation(new_rot);
+		}
+		
+		setChanged(ROTATED | SILHOUETTE);
+		
+		resetRot();
+	}
+
+
+	if ( gShowObjectUpdates )
+	{
+		if (!((mPrimitiveCode == LL_PCODE_LEGACY_AVATAR) && (((LLVOAvatar *) this)->isSelf()))
+			&& mRegionp)
+		{
+			LLViewerObject* object = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, mRegionp);
+			LLVOTextBubble* bubble = (LLVOTextBubble*) object;
+
+			if (update_type == OUT_TERSE_IMPROVED)
+			{
+				bubble->mColor.setVec(0.f, 0.f, 1.f, 1.f);
+			}
+			else
+			{
+				bubble->mColor.setVec(1.f, 0.f, 0.f, 1.f);
+			}
+			object->setPositionGlobal(getPositionGlobal());
+			gPipeline.addObject(object);
+		}
+	}
+
+	if ((0.0f == vel_mag_sq) && 
+		(0.0f == accel_mag_sq) &&
+		(0.0f == getAngularVelocity().magVecSquared()))
+	{
+		mStatic = TRUE; // This object doesn't move!
+	}
+	else
+	{
+		mStatic = FALSE;
+	}
+
+// BUG: This code leads to problems during group rotate and any scale operation.
+// Small discepencies between the simulator and viewer representations cause the 
+// selection center to creep, leading to objects moving around the wrong center.
+// 
+// Removing this, however, means that if someone else drags an object you have
+// selected, your selection center and dialog boxes will be wrong.  It also means
+// that higher precision information on selected objects will be ignored.
+//
+// I believe the group rotation problem is fixed.  JNC 1.21.2002
+//
+	// Additionally, if any child is selected, need to update the dialogs and selection
+	// center.
+	BOOL needs_refresh = mUserSelected;
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* child = *iter;
+		needs_refresh = needs_refresh || child->mUserSelected;
+	}
+
+	if (needs_refresh)
+	{
+		LLSelectMgr::getInstance()->updateSelectionCenter();
+		dialog_refresh_all();
+	} 
+
+
+	// Mark update time as approx. now, with the ping delay.
+	// Ping delay is off because it's not set for velocity interpolation, causing
+	// much jumping and hopping around...
+
+//	U32 ping_delay = mesgsys->mCircuitInfo.getPingDelay();
+	mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
+	mLastMessageUpdateSecs = mLastInterpUpdateSecs;
+	if (mDrawable.notNull())
+	{
+		// Don't clear invisibility flag on update if still orphaned!
+		if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned)
+		{
+// 			lldebugs << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << llendl;
+			mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
+		}
+	}
+
+	// Update special hover cursor status
+	bool special_hover_cursor = specialHoverCursor();
+	if (old_special_hover_cursor != special_hover_cursor
+		&& mDrawable.notNull())
+	{
+		mDrawable->updateSpecialHoverCursor(special_hover_cursor);
+	}
+
+	return retval;
+}
+
+BOOL LLViewerObject::isActive() const
+{
+	return TRUE;
+}
+
+
+
+BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+{
+	static LLFastTimer::DeclareTimer ftm("Viewer Object");
+	LLFastTimer t(ftm);
+
+	if (mDead)
+	{
+		// It's dead.  Don't update it.
+		return TRUE;
+	}
+
+	// CRO - don't velocity interp linked objects!
+	// Leviathan - but DO velocity interp joints
+	if (!mStatic && sVelocityInterpolate && !isSelected())
+	{
+		// calculate dt from last update
+		F32 dt_raw = (F32)(time - mLastInterpUpdateSecs);
+		F32 dt = mTimeDilation * dt_raw;
+
+		if (!mJointInfo)
+		{
+			applyAngularVelocity(dt);
+		}
+
+		LLViewerObject *parentp = (LLViewerObject *) getParent();
+		if (mJointInfo)
+		{
+			if (parentp)
+			{
+				// do parent-relative stuff
+				LLVector3 ang_vel = getAngularVelocity();
+				F32 omega = ang_vel.magVecSquared();
+				F32 angle = 0.0f;
+				LLQuaternion dQ;
+				if (omega > 0.00001f)
+				{
+					omega = sqrt(omega);
+					angle = omega * dt;
+					dQ.setQuat(angle, ang_vel);
+				}
+				LLVector3 pos = getPosition();
+	
+				if (HJT_HINGE == mJointInfo->mJointType)
+				{
+					// hinge = uniform circular motion
+					LLVector3 parent_pivot = getVelocity();
+					LLVector3 parent_axis = getAcceleration();
+	
+					angle = dt * (ang_vel * mJointInfo->mAxisOrAnchor);	// AxisOrAnchor = axis
+					dQ.setQuat(angle, mJointInfo->mAxisOrAnchor);		// AxisOrAnchor = axis
+					LLVector3 pivot_offset = pos - mJointInfo->mPivot;	// pos in pivot-frame
+					pivot_offset = pivot_offset * dQ;					// new rotated pivot-frame pos
+					pos = mJointInfo->mPivot + pivot_offset;			// parent-frame
+					LLViewerObject::setPosition(pos);
+					LLQuaternion Q_PC = getRotation();
+					setRotation(Q_PC * dQ);
+					mLastInterpUpdateSecs = time;
+				}
+				else if (HJT_POINT == mJointInfo->mJointType)
+						// || HJT_LPOINT == mJointInfo->mJointType)
+				{
+					// point-to-point = spin about axis and uniform circular motion
+					// 					of axis about the pivot point
+					//
+					// NOTE: this interpolation scheme is not quite good enough to
+					// reduce the bandwidth -- needs a gravitational correction. 
+					// Similarly for hinges with axes that deviate from vertical.
+	
+					LLQuaternion Q_PC = getRotation();
+					Q_PC = Q_PC * dQ;
+					setRotation(Q_PC);
+
+					LLVector3 pivot_to_child = - mJointInfo->mAxisOrAnchor;	// AxisOrAnchor = anchor
+					pos = mJointInfo->mPivot + pivot_to_child * Q_PC;
+					LLViewerObject::setPosition(pos);
+					mLastInterpUpdateSecs = time;
+				}
+				/* else if (HJT_WHEEL == mJointInfo->mJointInfo)
+				{
+					// wheel = uniform rotation about axis, with linear
+					//		   velocity interpolation (if any)
+					LLVector3 parent_axis = getAcceleration();	// HACK -- accel stores the parent-axis (parent-frame)
+	
+					LLQuaternion Q_PC = getRotation();
+	
+					angle = dt * (parent_axis * ang_vel);
+					dQ.setQuat(angle, parent_axis);
+	
+					Q_PC = Q_PC * dQ;
+					setRotation(Q_PC);
+
+					pos = getPosition() + dt * getVelocity();
+					LLViewerObject::setPosition(pos);
+					mLastInterpUpdateSecs = time;
+				}*/
+			}
+		}
+		else if (isAttachment())
+		{
+			mLastInterpUpdateSecs = time;
+			return TRUE;
+		}
+		else
+		{	// Move object based on it's velocity and rotation
+			interpolateLinearMotion(time, dt);
+		}
+	}
+
+	updateDrawable(FALSE);
+
+	return TRUE;
+}
+
+
+// Move an object due to idle-time viewer side updates by iterpolating motion
+void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)
+{
+	// linear motion
+	// PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
+	// updates represents the average velocity of the last timestep, rather than the final velocity.
+	// the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically
+	// 
+	// *TODO: should also wrap linear accel/velocity in check
+	// to see if object is selected, instead of explicitly
+	// zeroing it out	
+
+	F64 time_since_last_update = time - mLastMessageUpdateSecs;
+	if (time_since_last_update <= 0.0 || dt <= 0.f)
+	{
+		return;
+	}
+
+	LLVector3 accel = getAcceleration();
+	LLVector3 vel 	= getVelocity();
+	
+	if (sMaxUpdateInterpolationTime <= 0.0)
+	{	// Old code path ... unbounded, simple interpolation
+		if (!(accel.isExactlyZero() && vel.isExactlyZero()))
+		{
+			LLVector3 pos   = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;  
+		
+			// region local  
+			setPositionRegion(pos + getPositionRegion());
+			setVelocity(vel + accel*dt);	
+			
+			// for objects that are spinning but not translating, make sure to flag them as having moved
+			setChanged(MOVED | SILHOUETTE);
+		}
+	}
+	else if (!accel.isExactlyZero() || !vel.isExactlyZero())		// object is moving
+	{	// Object is moving, and hasn't been too long since we got an update from the server
+		
+		// Calculate predicted position and velocity
+		LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;	
+		LLVector3 new_v = accel * dt;
+
+		if (time_since_last_update > sPhaseOutUpdateInterpolationTime &&
+			sPhaseOutUpdateInterpolationTime > 0.0)
+		{	// Haven't seen a viewer update in a while, check to see if the ciruit is still active
+			if (mRegionp)
+			{	// The simulator will NOT send updates if the object continues normally on the path
+				// predicted by the velocity and the acceleration (often gravity) sent to the viewer
+				// So check to see if the circuit is blocked, which means the sim is likely in a long lag
+				LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() );
+				if (cdp)
+				{
+					// Find out how many seconds since last packet arrived on the circuit
+					F64 time_since_last_packet = LLMessageSystem::getMessageTimeSeconds() - cdp->getLastPacketInTime();
+
+					if (!cdp->isAlive() ||		// Circuit is dead or blocked
+						 cdp->isBlocked() ||	// or doesn't seem to be getting any packets
+						 (time_since_last_packet > sPhaseOutUpdateInterpolationTime))
+					{
+						// Start to reduce motion interpolation since we haven't seen a server update in a while
+						F64 time_since_last_interpolation = time - mLastInterpUpdateSecs;
+						F64 phase_out = 1.0;
+						if (time_since_last_update > sMaxUpdateInterpolationTime)
+						{	// Past the time limit, so stop the object
+							phase_out = 0.0;
+							//llinfos << "Motion phase out to zero" << llendl;
+
+							// Kill angular motion as well.  Note - not adding this due to paranoia
+							// about stopping rotation for llTargetOmega objects and not having it restart
+							// setAngularVelocity(LLVector3::zero);
+						}
+						else if (mLastInterpUpdateSecs - mLastMessageUpdateSecs > sPhaseOutUpdateInterpolationTime)
+						{	// Last update was already phased out a bit
+							phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / 
+										(sMaxUpdateInterpolationTime - time_since_last_interpolation);
+							//llinfos << "Continuing motion phase out of " << (F32) phase_out << llendl;
+						}
+						else
+						{	// Phase out from full value
+							phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / 
+										(sMaxUpdateInterpolationTime - sPhaseOutUpdateInterpolationTime);
+							//llinfos << "Starting motion phase out of " << (F32) phase_out << llendl;
+						}
+						phase_out = llclamp(phase_out, 0.0, 1.0);
+
+						new_pos = new_pos * ((F32) phase_out);
+						new_v = new_v * ((F32) phase_out);
+					}
+				}
+			}
+		}
+
+		new_pos = new_pos + getPositionRegion();
+		new_v = new_v + vel;
+
+
+		// Clamp interpolated position to minimum underground and maximum region height
+		LLVector3d new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos);
+		F32 min_height;
+		if (isAvatar())
+		{	// Make a better guess about AVs not going underground
+			min_height = LLWorld::getInstance()->resolveLandHeightGlobal(new_pos_global);
+			min_height += (0.5f * getScale().mV[VZ]);
+		}
+		else
+		{	// This will put the object underground, but we can't tell if it will stop 
+			// at ground level or not
+			min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global);
+		}
+
+		new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]);
+		new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]);
+
+		// Check to see if it's going off the region
+		LLVector3 temp(new_pos);
+		if (temp.clamp(0.f, mRegionp->getWidth()))
+		{	// Going off this region, so see if we might end up on another region
+			LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
+			new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos);		// Re-fetch in case it got clipped above
+
+			// Clip the positions to known regions
+			LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global);
+			if (clip_pos_global != new_pos_global)
+			{	// Was clipped, so this means we hit a edge where there is no region to enter
+				
+				//llinfos << "Hit empty region edge, clipped predicted position to " << mRegionp->getPosRegionFromGlobal(clip_pos_global)
+				//	<< " from " << new_pos << llendl;
+				new_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
+				
+				// Stop motion and get server update for bouncing on the edge
+				new_v.clear();
+				setAcceleration(LLVector3::zero);
+			}
+			else
+			{	// Let predicted movement cross into another region
+				//llinfos << "Predicting region crossing to " << new_pos << llendl;
+			}
+		}
+
+		// Set new position and velocity
+		setPositionRegion(new_pos);
+		setVelocity(new_v);	
+		
+		// for objects that are spinning but not translating, make sure to flag them as having moved
+		setChanged(MOVED | SILHOUETTE);
+	}		
+
+	// Update the last time we did anything
+	mLastInterpUpdateSecs = time;
+}
+
+
+
+BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	
+	delete [] mData;
+
+	if (datap)
+	{
+		mData = new U8[data_size];
+		if (!mData)
+		{
+			return FALSE;
+		}
+		memcpy(mData, datap, data_size);		/* Flawfinder: ignore */
+	}
+	return TRUE;
+}
+
+// delete an item in the inventory, but don't tell the server. This is
+// used internally by remove, update, and savescript.
+// This will only delete the first item with an item_id in the list
+void LLViewerObject::deleteInventoryItem(const LLUUID& item_id)
+{
+	if(mInventory)
+	{
+		LLInventoryObject::object_list_t::iterator it = mInventory->begin();
+		LLInventoryObject::object_list_t::iterator end = mInventory->end();
+		for( ; it != end; ++it )
+		{
+			if((*it)->getUUID() == item_id)
+			{
+				// This is safe only because we return immediatly.
+				mInventory->erase(it); // will deref and delete it
+				return;
+			}
+		}
+		doInventoryCallback();
+	}
+}
+
+void LLViewerObject::doUpdateInventory(
+	LLPointer<LLViewerInventoryItem>& item,
+	U8 key,
+	bool is_new)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+
+	LLViewerInventoryItem* old_item = NULL;
+	if(TASK_INVENTORY_ITEM_KEY == key)
+	{
+		old_item = (LLViewerInventoryItem*)getInventoryObject(item->getUUID());
+	}
+	else if(TASK_INVENTORY_ASSET_KEY == key)
+	{
+		old_item = getInventoryItemByAsset(item->getAssetUUID());
+	}
+	LLUUID item_id;
+	LLUUID new_owner;
+	LLUUID new_group;
+	BOOL group_owned = FALSE;
+	if(old_item)
+	{
+		item_id = old_item->getUUID();
+		new_owner = old_item->getPermissions().getOwner();
+		new_group = old_item->getPermissions().getGroup();
+		group_owned = old_item->getPermissions().isGroupOwned();
+		old_item = NULL;
+	}
+	else
+	{
+		item_id = item->getUUID();
+	}
+	if(!is_new && mInventory)
+	{
+		// Attempt to update the local inventory. If we can get the
+		// object perm, we have perfect visibility, so we want the
+		// serial number to match. Otherwise, take our best guess and
+		// make sure that the serial number does not match.
+		deleteInventoryItem(item_id);
+		LLPermissions perm(item->getPermissions());
+		LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this);
+		bool is_atomic = ((S32)LLAssetType::AT_OBJECT == item->getType()) ? false : true;
+		if(obj_perm)
+		{
+			perm.setOwnerAndGroup(LLUUID::null, obj_perm->getOwner(), obj_perm->getGroup(), is_atomic);
+		}
+		else
+		{
+			if(group_owned)
+			{
+				perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
+			}
+			else if(!new_owner.isNull())
+			{
+				// The object used to be in inventory, so we can
+				// assume the owner and group will match what they are
+				// there.
+				perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
+			}
+			// *FIX: can make an even better guess by using the mPermGroup flags
+			else if(permYouOwner())
+			{
+				// best guess.
+				perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic);
+				--mInventorySerialNum;
+			}
+			else
+			{
+				// dummy it up.
+				perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic);
+				--mInventorySerialNum;
+			}
+		}
+		LLViewerInventoryItem* oldItem = item;
+		LLViewerInventoryItem* new_item = new LLViewerInventoryItem(oldItem);
+		new_item->setPermissions(perm);
+		mInventory->push_front(new_item);
+		doInventoryCallback();
+		++mInventorySerialNum;
+	}
+}
+
+// save a script, which involves removing the old one, and rezzing
+// in the new one. This method should be called with the asset id
+// of the new and old script AFTER the bytecode has been saved.
+void LLViewerObject::saveScript(
+	const LLViewerInventoryItem* item,
+	BOOL active,
+	bool is_new)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+
+	/*
+	 * XXXPAM Investigate not making this copy.  Seems unecessary, but I'm unsure about the
+	 * interaction with doUpdateInventory() called below.
+	 */
+	lldebugs << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << llendl;
+	LLPointer<LLViewerInventoryItem> task_item =
+		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
+								  item->getAssetUUID(), item->getType(),
+								  item->getInventoryType(),
+								  item->getName(), item->getDescription(),
+								  item->getSaleInfo(), item->getFlags(),
+								  item->getCreationDate());
+	task_item->setTransactionID(item->getTransactionID());
+
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_RezScript);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
+	msg->nextBlockFast(_PREHASH_UpdateBlock);
+	msg->addU32Fast(_PREHASH_ObjectLocalID, (mLocalID));
+	U8 enabled = active;
+	msg->addBOOLFast(_PREHASH_Enabled, enabled);
+	msg->nextBlockFast(_PREHASH_InventoryBlock);
+	task_item->packMessage(msg);
+	msg->sendReliable(mRegionp->getHost());
+
+	// do the internal logic
+	doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, is_new);
+}
+
+void LLViewerObject::moveInventory(const LLUUID& folder_id,
+								   const LLUUID& item_id)
+{
+	lldebugs << "LLViewerObject::moveInventory " << item_id << llendl;
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_MoveTaskInventory);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_FolderID, folder_id);
+	msg->nextBlockFast(_PREHASH_InventoryData);
+	msg->addU32Fast(_PREHASH_LocalID, mLocalID);
+	msg->addUUIDFast(_PREHASH_ItemID, item_id);
+	msg->sendReliable(mRegionp->getHost());
+
+	LLInventoryObject* inv_obj = getInventoryObject(item_id);
+	if(inv_obj)
+	{
+		LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_obj;
+		if(!item->getPermissions().allowCopyBy(gAgent.getID()))
+		{
+			deleteInventoryItem(item_id);
+			++mInventorySerialNum;
+		}
+	}
+}
+
+void LLViewerObject::dirtyInventory()
+{
+	// If there aren't any LLVOInventoryListeners, we won't be
+	// able to update our mInventory when it comes back from the
+	// simulator, so we should not clear the inventory either.
+	if(mInventory && !mInventoryCallbacks.empty())
+	{
+		mInventory->clear(); // will deref and delete entries
+		delete mInventory;
+		mInventory = NULL;
+		mInventoryDirty = TRUE;
+	}
+}
+
+void LLViewerObject::registerInventoryListener(LLVOInventoryListener* listener, void* user_data)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	
+	LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo;
+	info->mListener = listener;
+	info->mInventoryData = user_data;
+	mInventoryCallbacks.push_front(info);
+}
+
+void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener)
+{
+	if (listener == NULL)
+		return;
+	for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
+		 iter != mInventoryCallbacks.end(); )
+	{
+		callback_list_t::iterator curiter = iter++;
+		LLInventoryCallbackInfo* info = *curiter;
+		if (info->mListener == listener)
+		{
+			delete info;
+			mInventoryCallbacks.erase(curiter);
+			break;
+		}
+	}
+}
+
+void LLViewerObject::clearInventoryListeners()
+{
+	for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer());
+	mInventoryCallbacks.clear();
+}
+
+void LLViewerObject::requestInventory()
+{
+	mInventoryDirty = FALSE;
+	if(mInventory)
+	{
+		//mInventory->clear() // will deref and delete it
+		//delete mInventory;
+		//mInventory = NULL;
+		doInventoryCallback();
+	}
+	// throw away duplicate requests
+	else
+	{
+		fetchInventoryFromServer();
+	}
+}
+
+void LLViewerObject::fetchInventoryFromServer()
+{
+	if (!mInventoryPending)
+	{
+		delete mInventory;
+		mInventory = NULL;
+		mInventoryDirty = FALSE;
+		LLMessageSystem* msg = gMessageSystem;
+		msg->newMessageFast(_PREHASH_RequestTaskInventory);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->nextBlockFast(_PREHASH_InventoryData);
+		msg->addU32Fast(_PREHASH_LocalID, mLocalID);
+		msg->sendReliable(mRegionp->getHost());
+
+		// this will get reset by dirtyInventory or doInventoryCallback
+		mInventoryPending = TRUE;
+	}
+}
+
+struct LLFilenameAndTask
+{
+	LLUUID mTaskID;
+	std::string mFilename;
+#ifdef _DEBUG
+	static S32 sCount;
+	LLFilenameAndTask()
+	{
+		++sCount;
+		lldebugs << "Constructing LLFilenameAndTask: " << sCount << llendl;
+	}
+	~LLFilenameAndTask()
+	{
+		--sCount;
+		lldebugs << "Destroying LLFilenameAndTask: " << sCount << llendl;
+	}
+private:
+	LLFilenameAndTask(const LLFilenameAndTask& rhs);
+	const LLFilenameAndTask& operator=(const LLFilenameAndTask& rhs) const;
+#endif
+};
+
+#ifdef _DEBUG
+S32 LLFilenameAndTask::sCount = 0;
+#endif
+
+// static
+void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	
+	LLUUID task_id;
+	msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);
+	LLViewerObject* object = gObjectList.findObject(task_id);
+	if(!object)
+	{
+		llwarns << "LLViewerObject::processTaskInv object "
+			<< task_id << " does not exist." << llendl;
+		return;
+	}
+
+	msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, object->mInventorySerialNum);
+	LLFilenameAndTask* ft = new LLFilenameAndTask;
+	ft->mTaskID = task_id;
+
+	std::string unclean_filename;
+	msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename);
+	ft->mFilename = LLDir::getScrubbedFileName(unclean_filename);
+	
+	if(ft->mFilename.empty())
+	{
+		lldebugs << "Task has no inventory" << llendl;
+		// mock up some inventory to make a drop target.
+		if(object->mInventory)
+		{
+			object->mInventory->clear(); // will deref and delete it
+		}
+		else
+		{
+			object->mInventory = new LLInventoryObject::object_list_t();
+		}
+		LLPointer<LLInventoryObject> obj;
+		obj = new LLInventoryObject(object->mID, LLUUID::null,
+									LLAssetType::AT_CATEGORY,
+									LLTrans::getString("ViewerObjectContents").c_str());
+		object->mInventory->push_front(obj);
+		object->doInventoryCallback();
+		delete ft;
+		return;
+	}
+	gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename), 
+								ft->mFilename, LL_PATH_CACHE,
+								object->mRegionp->getHost(),
+								TRUE,
+								&LLViewerObject::processTaskInvFile,
+								(void**)ft,
+								LLXferManager::HIGH_PRIORITY);
+}
+
+void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status)
+{
+	LLFilenameAndTask* ft = (LLFilenameAndTask*)user_data;
+	LLViewerObject* object = NULL;
+	if(ft && (0 == error_code) &&
+	   (object = gObjectList.findObject(ft->mTaskID)))
+	{
+		object->loadTaskInvFile(ft->mFilename);
+	}
+	else
+	{
+		// This Occurs When to requests were made, and the first one
+		// has already handled it.
+		lldebugs << "Problem loading task inventory. Return code: "
+				 << error_code << llendl;
+	}
+	delete ft;
+}
+
+void LLViewerObject::loadTaskInvFile(const std::string& filename)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	
+	std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
+	llifstream ifs(filename_and_local_path);
+	if(ifs.good())
+	{
+		char buffer[MAX_STRING];	/* Flawfinder: ignore */
+		// *NOTE: This buffer size is hard coded into scanf() below.
+		char keyword[MAX_STRING];	/* Flawfinder: ignore */
+		if(mInventory)
+		{
+			mInventory->clear(); // will deref and delete it
+		}
+		else
+		{
+			mInventory = new LLInventoryObject::object_list_t;
+		}
+		while(ifs.good())
+		{
+			ifs.getline(buffer, MAX_STRING);
+			sscanf(buffer, " %254s", keyword);	/* Flawfinder: ignore */
+			if(0 == strcmp("inv_item", keyword))
+			{
+				LLPointer<LLInventoryObject> inv = new LLViewerInventoryItem;
+				inv->importLegacyStream(ifs);
+				mInventory->push_front(inv);
+			}
+			else if(0 == strcmp("inv_object", keyword))
+			{
+				LLPointer<LLInventoryObject> inv = new LLInventoryObject;
+				inv->importLegacyStream(ifs);
+				inv->rename(LLTrans::getString("ViewerObjectContents").c_str());
+				mInventory->push_front(inv);
+			}
+			else
+			{
+				llwarns << "Unknown token in inventory file '"
+						<< keyword << "'" << llendl;
+			}
+		}
+		ifs.close();
+		LLFile::remove(filename_and_local_path);
+	}
+	else
+	{
+		llwarns << "unable to load task inventory: " << filename_and_local_path
+				<< llendl;
+	}
+	doInventoryCallback();
+}
+
+void LLViewerObject::doInventoryCallback()
+{
+	for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
+		 iter != mInventoryCallbacks.end(); )
+	{
+		callback_list_t::iterator curiter = iter++;
+		LLInventoryCallbackInfo* info = *curiter;
+		if (info->mListener != NULL)
+		{
+			info->mListener->inventoryChanged(this,
+								 mInventory,
+								 mInventorySerialNum,
+								 info->mInventoryData);
+		}
+		else
+		{
+			llinfos << "LLViewerObject::doInventoryCallback() deleting bad listener entry." << llendl;
+			delete info;
+			mInventoryCallbacks.erase(curiter);
+		}
+	}
+	mInventoryPending = FALSE;
+}
+
+void LLViewerObject::removeInventory(const LLUUID& item_id)
+{
+	// close any associated floater properties
+	LLFloaterReg::hideInstance("properties", item_id);
+
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_RemoveTaskInventory);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_InventoryData);
+	msg->addU32Fast(_PREHASH_LocalID, mLocalID);
+	msg->addUUIDFast(_PREHASH_ItemID, item_id);
+	msg->sendReliable(mRegionp->getHost());
+	deleteInventoryItem(item_id);
+	++mInventorySerialNum;
+}
+
+void LLViewerObject::updateInventory(
+	LLViewerInventoryItem* item,
+	U8 key,
+	bool is_new)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	
+	// This slices the object into what we're concerned about on the
+	// viewer. The simulator will take the permissions and transfer
+	// ownership.
+	LLPointer<LLViewerInventoryItem> task_item =
+		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
+								  item->getAssetUUID(), item->getType(),
+								  item->getInventoryType(),
+								  item->getName(), item->getDescription(),
+								  item->getSaleInfo(),
+								  item->getFlags(),
+								  item->getCreationDate());
+	task_item->setTransactionID(item->getTransactionID());
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_UpdateTaskInventory);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_UpdateData);
+	msg->addU32Fast(_PREHASH_LocalID, mLocalID);
+	msg->addU8Fast(_PREHASH_Key, key);
+	msg->nextBlockFast(_PREHASH_InventoryData);
+	task_item->packMessage(msg);
+	msg->sendReliable(mRegionp->getHost());
+
+	// do the internal logic
+	doUpdateInventory(task_item, key, is_new);
+}
+
+void LLViewerObject::updateInventoryLocal(LLInventoryItem* item, U8 key)
+{
+	LLPointer<LLViewerInventoryItem> task_item =
+		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
+								  item->getAssetUUID(), item->getType(),
+								  item->getInventoryType(),
+								  item->getName(), item->getDescription(),
+								  item->getSaleInfo(), item->getFlags(),
+								  item->getCreationDate());
+
+	// do the internal logic
+	const bool is_new = false;
+	doUpdateInventory(task_item, key, is_new);
+}
+
+LLInventoryObject* LLViewerObject::getInventoryObject(const LLUUID& item_id)
+{
+	LLInventoryObject* rv = NULL;
+	if(mInventory)
+	{
+		LLInventoryObject::object_list_t::iterator it = mInventory->begin();
+		LLInventoryObject::object_list_t::iterator end = mInventory->end();
+		for ( ; it != end; ++it)
+		{
+			if((*it)->getUUID() == item_id)
+			{
+				rv = *it;
+				break;
+			}
+		}		
+	}
+	return rv;
+}
+
+void LLViewerObject::getInventoryContents(LLInventoryObject::object_list_t& objects)
+{
+	if(mInventory)
+	{
+		LLInventoryObject::object_list_t::iterator it = mInventory->begin();
+		LLInventoryObject::object_list_t::iterator end = mInventory->end();
+		for( ; it != end; ++it)
+		{
+			if ((*it)->getType() != LLAssetType::AT_CATEGORY)
+			{
+				objects.push_back(*it);
+			}
+		}
+	}
+}
+
+LLInventoryObject* LLViewerObject::getInventoryRoot()
+{
+	if (!mInventory || !mInventory->size())
+	{
+		return NULL;
+	}
+	return mInventory->back();
+}
+
+LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& asset_id)
+{
+	if (mInventoryDirty)
+		llwarns << "Peforming inventory lookup for object " << mID << " that has dirty inventory!" << llendl;
+
+	LLViewerInventoryItem* rv = NULL;
+	if(mInventory)
+	{
+		LLViewerInventoryItem* item = NULL;
+
+		LLInventoryObject::object_list_t::iterator it = mInventory->begin();
+		LLInventoryObject::object_list_t::iterator end = mInventory->end();
+		for( ; it != end; ++it)
+		{
+			LLInventoryObject* obj = *it;
+			if(obj->getType() != LLAssetType::AT_CATEGORY)
+			{
+				// *FIX: gank-ass down cast!
+				item = (LLViewerInventoryItem*)obj;
+				if(item->getAssetUUID() == asset_id)
+				{
+					rv = item;
+					break;
+				}
+			}
+		}		
+	}
+	return rv;
+}
+
+void LLViewerObject::updateViewerInventoryAsset(
+					const LLViewerInventoryItem* item,
+					const LLUUID& new_asset)
+{
+	LLPointer<LLViewerInventoryItem> task_item =
+		new LLViewerInventoryItem(item);
+	task_item->setAssetUUID(new_asset);
+
+	// do the internal logic
+	doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false);
+}
+
+void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)
+{
+	if (getVolume())
+	{	//volumes calculate pixel area and angle per face
+		return;
+	}
+	
+	LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent();
+	LLVector3 pos_agent = getRenderPosition();
+
+	F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX];
+	F32 dy = viewer_pos_agent.mV[VY] - pos_agent.mV[VY];
+	F32 dz = viewer_pos_agent.mV[VZ] - pos_agent.mV[VZ];
+
+	F32 max_scale = getMaxScale();
+	F32 mid_scale = getMidScale();
+	F32 min_scale = getMinScale();
+
+	// IW: estimate - when close to large objects, computing range based on distance from center is no good
+	// to try to get a min distance from face, subtract min_scale/2 from the range.
+	// This means we'll load too much detail sometimes, but that's better than not enough
+	// I don't think there's a better way to do this without calculating distance per-poly
+	F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2;
+
+	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	if (range < 0.001f || isHUDAttachment())		// range == zero
+	{
+		mAppAngle = 180.f;
+		mPixelArea = (F32)camera->getScreenPixelArea();
+	}
+	else
+	{
+		mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG;
+
+		F32 pixels_per_meter = camera->getPixelMeterRatio() / range;
+
+		mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale);
+		if (mPixelArea > camera->getScreenPixelArea())
+		{
+			mAppAngle = 180.f;
+			mPixelArea = (F32)camera->getScreenPixelArea();
+		}
+	}
+}
+
+BOOL LLViewerObject::updateLOD()
+{
+	return FALSE;
+}
+
+BOOL LLViewerObject::updateGeometry(LLDrawable *drawable)
+{
+	return TRUE;
+}
+
+void LLViewerObject::updateGL()
+{
+
+}
+
+void LLViewerObject::updateFaceSize(S32 idx)
+{
+	
+}
+
+LLDrawable* LLViewerObject::createDrawable(LLPipeline *pipeline)
+{
+	return NULL;
+}
+
+void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped)
+{
+	LLPrimitive::setScale(scale);
+	if (mDrawable.notNull())
+	{
+		//encompass completely sheared objects by taking 
+		//the most extreme point possible (<1,1,0.5>)
+		mDrawable->setRadius(LLVector3(1,1,0.5f).scaleVec(scale).magVec());
+		updateDrawable(damped);
+	}
+
+	if( (LL_PCODE_VOLUME == getPCode()) && !isDead() )
+	{
+		if (permYouOwner() || (scale.magVecSquared() > (7.5f * 7.5f)) )
+		{
+			if (!mOnMap)
+			{
+				llassert_always(LLWorld::getInstance()->getRegionFromHandle(getRegion()->getHandle()));
+
+				gObjectList.addToMap(this);
+				mOnMap = TRUE;
+			}
+		}
+		else
+		{
+			if (mOnMap)
+			{
+				gObjectList.removeFromMap(this);
+				mOnMap = FALSE;
+			}
+		}
+	}
+}
+
+void LLViewerObject::setObjectCost(F32 cost)
+{
+	mObjectCost = cost;
+	mCostStale = false;
+
+	if (isSelected())
+	{
+		gFloaterTools->dirty();
+	}
+}
+
+void LLViewerObject::setLinksetCost(F32 cost)
+{
+	mLinksetCost = cost;
+	mCostStale = false;
+	
+	if (isSelected())
+	{
+		gFloaterTools->dirty();
+	}
+}
+
+void LLViewerObject::setPhysicsCost(F32 cost)
+{
+	mPhysicsCost = cost;
+	mCostStale = false;
+
+	if (isSelected())
+	{
+		gFloaterTools->dirty();
+	}
+}
+
+void LLViewerObject::setLinksetPhysicsCost(F32 cost)
+{
+	mLinksetPhysicsCost = cost;
+	mCostStale = false;
+	
+	if (isSelected())
+	{
+		gFloaterTools->dirty();
+	}
+}
+
+
+F32 LLViewerObject::getObjectCost()
+{
+	if (mCostStale)
+	{
+		gObjectList.updateObjectCost(this);
+	}
+	
+	return mObjectCost;
+}
+
+F32 LLViewerObject::getLinksetCost()
+{
+	if (mCostStale)
+	{
+		gObjectList.updateObjectCost(this);
+	}
+
+	return mLinksetCost;
+}
+
+F32 LLViewerObject::getPhysicsCost()
+{
+	if (mCostStale)
+	{
+		gObjectList.updateObjectCost(this);
+	}
+	
+	return mPhysicsCost;
+}
+
+F32 LLViewerObject::getLinksetPhysicsCost()
+{
+	if (mCostStale)
+	{
+		gObjectList.updateObjectCost(this);
+	}
+
+	return mLinksetPhysicsCost;
+}
+
+F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes)
+{
+	return 0.f;
+}
+
+U32 LLViewerObject::getTriangleCount()
+{
+	return 0;
+}
+
+U32 LLViewerObject::getHighLODTriangleCount()
+{
+	return 0;
+}
+
+void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
+{
+	LLVector4a center;
+	center.load3(getRenderPosition().mV);
+	LLVector4a size;
+	size.load3(getScale().mV);
+	newMin.setSub(center, size);
+	newMax.setAdd(center, size);
+	
+	mDrawable->setPositionGroup(center);
+}
+
+F32 LLViewerObject::getBinRadius()
+{
+	if (mDrawable.notNull())
+	{
+		const LLVector4a* ext = mDrawable->getSpatialExtents();
+		LLVector4a diff;
+		diff.setSub(ext[1], ext[0]);
+		return diff.getLength3().getF32();
+	}
+	
+	return getScale().magVec();
+}
+
+F32 LLViewerObject::getMaxScale() const
+{
+	return llmax(getScale().mV[VX],getScale().mV[VY], getScale().mV[VZ]);
+}
+
+F32 LLViewerObject::getMinScale() const
+{
+	return llmin(getScale().mV[0],getScale().mV[1],getScale().mV[2]);
+}
+
+F32 LLViewerObject::getMidScale() const
+{
+	if (getScale().mV[VX] < getScale().mV[VY])
+	{
+		if (getScale().mV[VY] < getScale().mV[VZ])
+		{
+			return getScale().mV[VY];
+		}
+		else if (getScale().mV[VX] < getScale().mV[VZ])
+		{
+			return getScale().mV[VZ];
+		}
+		else
+		{
+			return getScale().mV[VX];
+		}
+	}
+	else if (getScale().mV[VX] < getScale().mV[VZ])
+	{
+		return getScale().mV[VX];
+	}
+	else if (getScale().mV[VY] < getScale().mV[VZ])
+	{
+		return getScale().mV[VZ];
+	}
+	else
+	{
+		return getScale().mV[VY];
+	}
+}
+
+
+void LLViewerObject::updateTextures()
+{
+}
+
+void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */)
+{
+	if (isDead())
+	{
+		return;
+	}
+
+	S32 i;
+	S32 tex_count = getNumTEs();
+	for (i = 0; i < tex_count; i++)
+	{
+ 		getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+	}
+
+	if (isSculpted() && !isMesh())
+	{
+		LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+		LLUUID sculpt_id = sculpt_params->getSculptTexture();
+		LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+	}
+	
+	if (boost_children)
+	{
+		for (child_list_t::iterator iter = mChildList.begin();
+			 iter != mChildList.end(); iter++)
+		{
+			LLViewerObject* child = *iter;
+			child->boostTexturePriority();
+		}
+	}
+}
+
+
+void LLViewerObject::setLineWidthForWindowSize(S32 window_width)
+{
+	if (window_width < 700)
+	{
+		LLUI::setLineWidth(2.0f);
+	}
+	else if (window_width < 1100)
+	{
+		LLUI::setLineWidth(3.0f);
+	}
+	else if (window_width < 2000)
+	{
+		LLUI::setLineWidth(4.0f);
+	}
+	else
+	{
+		// _damn_, what a nice monitor!
+		LLUI::setLineWidth(5.0f);
+	}
+}
+
+void LLViewerObject::increaseArrowLength()
+{
+/* ???
+	if (mAxisArrowLength == 50)
+	{
+		mAxisArrowLength = 100;
+	}
+	else
+	{
+		mAxisArrowLength = 150;
+	}
+*/
+}
+
+
+void LLViewerObject::decreaseArrowLength()
+{
+/* ???
+	if (mAxisArrowLength == 150)
+	{
+		mAxisArrowLength = 100;
+	}
+	else
+	{
+		mAxisArrowLength = 50;
+	}
+*/
+}
+
+// Culled from newsim LLTask::addNVPair
+void LLViewerObject::addNVPair(const std::string& data)
+{
+	// cout << "LLViewerObject::addNVPair() with ---" << data << "---" << endl;
+	LLNameValue *nv = new LLNameValue(data.c_str());
+
+//	char splat[MAX_STRING];
+//	temp->printNameValue(splat);
+//	llinfos << "addNVPair " << splat << llendl;
+
+	name_value_map_t::iterator iter = mNameValuePairs.find(nv->mName);
+	if (iter != mNameValuePairs.end())
+	{
+		LLNameValue* foundnv = iter->second;
+		if (foundnv->mClass != NVC_READ_ONLY)
+		{
+			delete foundnv;
+			mNameValuePairs.erase(iter);
+		}
+		else
+		{
+			delete nv;
+//			llinfos << "Trying to write to Read Only NVPair " << temp->mName << " in addNVPair()" << llendl;
+			return;
+		}
+	}
+	mNameValuePairs[nv->mName] = nv;
+}
+
+BOOL LLViewerObject::removeNVPair(const std::string& name)
+{
+	char* canonical_name = gNVNameTable.addString(name);
+
+	lldebugs << "LLViewerObject::removeNVPair(): " << name << llendl;
+
+	name_value_map_t::iterator iter = mNameValuePairs.find(canonical_name);
+	if (iter != mNameValuePairs.end())
+	{
+		if( mRegionp )
+		{
+			LLNameValue* nv = iter->second;
+/*
+			std::string buffer = nv->printNameValue();
+			gMessageSystem->newMessageFast(_PREHASH_RemoveNameValuePair);
+			gMessageSystem->nextBlockFast(_PREHASH_TaskData);
+			gMessageSystem->addUUIDFast(_PREHASH_ID, mID);
+			
+			gMessageSystem->nextBlockFast(_PREHASH_NameValueData);
+			gMessageSystem->addStringFast(_PREHASH_NVPair, buffer);
+
+			gMessageSystem->sendReliable( mRegionp->getHost() );
+*/
+			// Remove the NV pair from the local list.
+			delete nv;
+			mNameValuePairs.erase(iter);
+			return TRUE;
+		}
+		else
+		{
+			lldebugs << "removeNVPair - No region for object" << llendl;
+		}
+	}
+	return FALSE;
+}
+
+
+LLNameValue *LLViewerObject::getNVPair(const std::string& name) const
+{
+	char		*canonical_name;
+
+	canonical_name = gNVNameTable.addString(name);
+
+	// If you access a map with a name that isn't in it, it will add the name and a null pointer.
+	// So first check if the data is in the map.
+	name_value_map_t::const_iterator iter = mNameValuePairs.find(canonical_name);
+	if (iter != mNameValuePairs.end())
+	{
+		return iter->second;
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+void LLViewerObject::updatePositionCaches() const
+{
+	if(mRegionp)
+	{
+		if (!isRoot())
+		{
+			mPositionRegion = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
+			mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+		}
+		else
+		{
+			mPositionRegion = getPosition();
+			mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+		}
+	}
+}
+
+const LLVector3d LLViewerObject::getPositionGlobal() const
+{	
+	if(mRegionp)
+	{
+		LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
+
+		if (isAttachment())
+		{
+			position_global = gAgent.getPosGlobalFromAgent(getRenderPosition());
+		}		
+		return position_global;
+	}
+	else
+	{
+		LLVector3d position_global(getPosition());
+		return position_global;
+	}	
+}
+
+const LLVector3 &LLViewerObject::getPositionAgent() const
+{
+	if (mRegionp)
+	{
+		if (mDrawable.notNull() && (!mDrawable->isRoot() && getParent()))
+		{
+			// Don't return cached position if you have a parent, recalc (until all dirtying is done correctly.
+			LLVector3 position_region;
+			position_region = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
+			mPositionAgent = mRegionp->getPosAgentFromRegion(position_region);
+		}
+		else
+		{
+			mPositionAgent = mRegionp->getPosAgentFromRegion(getPosition());
+		}
+	}
+	return mPositionAgent;
+}
+
+const LLVector3 &LLViewerObject::getPositionRegion() const
+{
+	if (!isRoot())
+	{
+		LLViewerObject *parent = (LLViewerObject *)getParent();
+		mPositionRegion = parent->getPositionRegion() + (getPosition() * parent->getRotation());
+	}
+	else
+	{
+		mPositionRegion = getPosition();
+	}
+
+	return mPositionRegion;
+}
+
+const LLVector3 LLViewerObject::getPositionEdit() const
+{
+	if (isRootEdit())
+	{
+		return getPosition();
+	}
+	else
+	{
+		LLViewerObject *parent = (LLViewerObject *)getParent();
+		LLVector3 position_edit = parent->getPositionEdit() + getPosition() * parent->getRotationEdit();
+		return position_edit;
+	}
+}
+
+const LLVector3 LLViewerObject::getRenderPosition() const
+{
+	if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED))
+	{
+		LLVOAvatar* avatar = getAvatar();
+		if (avatar)
+		{
+			return avatar->getPositionAgent();
+		}
+	}
+
+	if (mDrawable.isNull() || mDrawable->getGeneration() < 0)
+	{
+		return getPositionAgent();
+	}
+	else
+	{
+		return mDrawable->getPositionAgent();
+	}
+}
+
+const LLVector3 LLViewerObject::getPivotPositionAgent() const
+{
+	return getRenderPosition();
+}
+
+const LLQuaternion LLViewerObject::getRenderRotation() const
+{
+	LLQuaternion ret;
+	if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED))
+	{
+		return ret;
+	}
+	
+	if (mDrawable.isNull() || mDrawable->isStatic())
+	{
+		ret = getRotationEdit();
+	}
+	else
+	{
+		if (!mDrawable->isRoot())
+		{
+			ret = getRotation() * LLQuaternion(mDrawable->getParent()->getWorldMatrix());
+		}
+		else
+		{
+			ret = LLQuaternion(mDrawable->getWorldMatrix());
+		}
+	}
+	
+	return ret;
+}
+
+const LLMatrix4 LLViewerObject::getRenderMatrix() const
+{
+	return mDrawable->getWorldMatrix();
+}
+
+const LLQuaternion LLViewerObject::getRotationRegion() const
+{
+	LLQuaternion global_rotation = getRotation();
+	if (!((LLXform *)this)->isRoot())
+	{
+		global_rotation = global_rotation * getParent()->getRotation();
+	}
+	return global_rotation;
+}
+
+const LLQuaternion LLViewerObject::getRotationEdit() const
+{
+	LLQuaternion global_rotation = getRotation();
+	if (!((LLXform *)this)->isRootEdit())
+	{
+		global_rotation = global_rotation * getParent()->getRotation();
+	}
+	return global_rotation;
+}
+
+void LLViewerObject::setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped )
+{
+	if (isAttachment())
+	{
+		LLVector3 new_pos = mRegionp->getPosRegionFromGlobal(pos_global);
+		if (isRootEdit())
+		{
+			new_pos -= mDrawable->mXform.getParent()->getWorldPosition();
+			LLQuaternion world_rotation = mDrawable->mXform.getParent()->getWorldRotation();
+			new_pos = new_pos * ~world_rotation;
+		}
+		else
+		{
+			LLViewerObject* parentp = (LLViewerObject*)getParent();
+			new_pos -= parentp->getPositionAgent();
+			new_pos = new_pos * ~parentp->getRotationRegion();
+		}
+		LLViewerObject::setPosition(new_pos);
+		
+		if (mParent && ((LLViewerObject*)mParent)->isAvatar())
+		{
+			// we have changed the position of an attachment, so we need to clamp it
+			LLVOAvatar *avatar = (LLVOAvatar*)mParent;
+
+			avatar->clampAttachmentPositions();
+		}
+	}
+	else
+	{
+		if( isRoot() )
+		{
+			setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
+		}
+		else
+		{
+			// the relative position with the parent is not constant
+			LLViewerObject* parent = (LLViewerObject *)getParent();
+			//RN: this assumes we are only calling this function from the edit tools
+			gPipeline.updateMoveNormalAsync(parent->mDrawable);
+
+			LLVector3 pos_local = mRegionp->getPosRegionFromGlobal(pos_global) - parent->getPositionRegion();
+			pos_local = pos_local * ~parent->getRotationRegion();
+			LLViewerObject::setPosition( pos_local );
+		}
+	}
+	//RN: assumes we always want to snap the object when calling this function
+	gPipeline.updateMoveNormalAsync(mDrawable);
+}
+
+void LLViewerObject::setPosition(const LLVector3 &pos, BOOL damped)
+{
+	if (getPosition() != pos)
+	{
+		setChanged(TRANSLATED | SILHOUETTE);
+	}
+		
+	LLXform::setPosition(pos);
+	updateDrawable(damped);
+	if (isRoot())
+	{
+		// position caches need to be up to date on root objects
+		updatePositionCaches();
+	}
+}
+
+void LLViewerObject::setPositionGlobal(const LLVector3d &pos_global, BOOL damped)
+{
+	if (isAttachment())
+	{
+		if (isRootEdit())
+		{
+			LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
+			newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
+
+			LLQuaternion invWorldRotation = mDrawable->mXform.getParent()->getWorldRotation();
+			invWorldRotation.transQuat();
+
+			newPos = newPos * invWorldRotation;
+			LLViewerObject::setPosition(newPos);
+		}
+		else
+		{
+			// assumes parent is root editable (root of attachment)
+			LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
+			newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
+			LLVector3 delta_pos = newPos - getPosition();
+
+			LLQuaternion invRotation = mDrawable->getRotation();
+			invRotation.transQuat();
+			
+			delta_pos = delta_pos * invRotation;
+
+			// *FIX: is this right?  Shouldn't we be calling the
+			// LLViewerObject version of setPosition?
+			LLVector3 old_pos = mDrawable->mXform.getParent()->getPosition();
+			mDrawable->mXform.getParent()->setPosition(old_pos + delta_pos);
+			setChanged(TRANSLATED | SILHOUETTE);
+		}
+		if (mParent && ((LLViewerObject*)mParent)->isAvatar())
+		{
+			// we have changed the position of an attachment, so we need to clamp it
+			LLVOAvatar *avatar = (LLVOAvatar*)mParent;
+
+			avatar->clampAttachmentPositions();
+		}
+	}
+	else
+	{
+		if (isRoot())
+		{
+			setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
+		}
+		else
+		{
+			// the relative position with the parent is constant, but the parent's position needs to be changed
+			LLVector3d position_offset;
+			position_offset.setVec(getPosition()*getParent()->getRotation());
+			LLVector3d new_pos_global = pos_global - position_offset;
+			((LLViewerObject *)getParent())->setPositionGlobal(new_pos_global);
+		}
+	}
+	updateDrawable(damped);
+}
+
+
+void LLViewerObject::setPositionParent(const LLVector3 &pos_parent, BOOL damped)
+{
+	// Set position relative to parent, if no parent, relative to region
+	if (!isRoot())
+	{
+		LLViewerObject::setPosition(pos_parent, damped);
+		//updateDrawable(damped);
+	}
+	else
+	{
+		setPositionRegion(pos_parent, damped);
+	}
+}
+
+void LLViewerObject::setPositionRegion(const LLVector3 &pos_region, BOOL damped)
+{
+	if (!isRootEdit())
+	{
+		LLViewerObject* parent = (LLViewerObject*) getParent();
+		LLViewerObject::setPosition((pos_region-parent->getPositionRegion())*~parent->getRotationRegion());
+	}
+	else
+	{
+		LLViewerObject::setPosition(pos_region);
+		mPositionRegion = pos_region;
+		mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+	}
+}
+
+void LLViewerObject::setPositionAgent(const LLVector3 &pos_agent, BOOL damped)
+{
+	LLVector3 pos_region = getRegion()->getPosRegionFromAgent(pos_agent);
+	setPositionRegion(pos_region, damped);
+}
+
+// identical to setPositionRegion() except it checks for child-joints 
+// and doesn't also move the joint-parent
+// TODO -- implement similar intelligence for joint-parents toward
+// their joint-children
+void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped)
+{
+	if (!isRootEdit())
+	{
+		// the relative position with the parent is constant, but the parent's position needs to be changed
+		LLVector3 position_offset = getPosition() * getParent()->getRotation();
+
+		((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset);
+		updateDrawable(damped);
+	}
+	else if (isJointChild())
+	{
+		// compute new parent-relative position
+		LLViewerObject *parent = (LLViewerObject *) getParent();
+		LLQuaternion inv_parent_rot = parent->getRotation();
+		inv_parent_rot.transQuat();
+		LLVector3 pos_parent = (pos_edit - parent->getPositionRegion()) * inv_parent_rot;
+		LLViewerObject::setPosition(pos_parent, damped);
+	}
+	else
+	{
+		LLViewerObject::setPosition(pos_edit, damped);
+		mPositionRegion = pos_edit;
+		mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+	}	
+}
+
+
+LLViewerObject* LLViewerObject::getRootEdit() const
+{
+	const LLViewerObject* root = this;
+	while (root->mParent 
+		   && !(root->mJointInfo
+			   || ((LLViewerObject*)root->mParent)->isAvatar()) )
+	{
+		root = (LLViewerObject*)root->mParent;
+	}
+	return (LLViewerObject*)root;
+}
+
+
+BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+										  S32 face,
+										  BOOL pick_transparent,
+										  S32* face_hit,
+										  LLVector3* intersection,
+										  LLVector2* tex_coord,
+										  LLVector3* normal,
+										  LLVector3* bi_normal)
+{
+	return false;
+}
+
+BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end)
+{
+	if (mDrawable.isNull() || mDrawable->isDead())
+	{
+		return FALSE;
+	}
+
+	const LLVector4a* ext = mDrawable->getSpatialExtents();
+
+	//VECTORIZE THIS
+	LLVector4a center;
+	center.setAdd(ext[1], ext[0]);
+	center.mul(0.5f);
+	LLVector4a size;
+	size.setSub(ext[1], ext[0]);
+	size.mul(0.5f);
+
+	LLVector4a starta, enda;
+	starta.load3(start.mV);
+	enda.load3(end.mV);
+
+	return LLLineSegmentBoxIntersect(starta, enda, center, size);
+}
+
+U8 LLViewerObject::getMediaType() const
+{
+	if (mMedia)
+	{
+		return mMedia->mMediaType;
+	}
+	else
+	{
+		return LLViewerObject::MEDIA_NONE;
+	}
+}
+
+void LLViewerObject::setMediaType(U8 media_type)
+{
+	if (!mMedia)
+	{
+		// TODO what if we don't have a media pointer?
+	}
+	else if (mMedia->mMediaType != media_type)
+	{
+		mMedia->mMediaType = media_type;
+
+		// TODO: update materials with new image
+	}
+}
+
+std::string LLViewerObject::getMediaURL() const
+{
+	if (mMedia)
+	{
+		return mMedia->mMediaURL;
+	}
+	else
+	{
+		return std::string();
+	}
+}
+
+void LLViewerObject::setMediaURL(const std::string& media_url)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	
+	if (!mMedia)
+	{
+		mMedia = new LLViewerObjectMedia;
+		mMedia->mMediaURL = media_url;
+		mMedia->mPassedWhitelist = FALSE;
+
+		// TODO: update materials with new image
+	}
+	else if (mMedia->mMediaURL != media_url)
+	{
+		mMedia->mMediaURL = media_url;
+		mMedia->mPassedWhitelist = FALSE;
+
+		// TODO: update materials with new image
+	}
+}
+
+BOOL LLViewerObject::getMediaPassedWhitelist() const
+{
+	if (mMedia)
+	{
+		return mMedia->mPassedWhitelist;
+	}
+	else
+	{
+		return FALSE;
+	}
+}
+
+void LLViewerObject::setMediaPassedWhitelist(BOOL passed)
+{
+	if (mMedia)
+	{
+		mMedia->mPassedWhitelist = passed;
+	}
+}
+
+BOOL LLViewerObject::setMaterial(const U8 material)
+{
+	BOOL res = LLPrimitive::setMaterial(material);
+	if (res)
+	{
+		setChanged(TEXTURE);
+	}
+	return res;
+}
+
+void LLViewerObject::setNumTEs(const U8 num_tes)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	
+	U32 i;
+	if (num_tes != getNumTEs())
+	{
+		if (num_tes)
+		{
+			LLPointer<LLViewerTexture> *new_images;
+			new_images = new LLPointer<LLViewerTexture>[num_tes];
+			for (i = 0; i < num_tes; i++)
+			{
+				if (i < getNumTEs())
+				{
+					new_images[i] = mTEImages[i];
+				}
+				else if (getNumTEs())
+				{
+					new_images[i] = mTEImages[getNumTEs()-1];
+				}
+				else
+				{
+					new_images[i] = NULL;
+				}
+			}
+
+			deleteTEImages();
+			
+			mTEImages = new_images;
+		}
+		else
+		{
+			deleteTEImages();
+		}
+		LLPrimitive::setNumTEs(num_tes);
+		setChanged(TEXTURE);
+
+		if (mDrawable.notNull())
+		{
+			gPipeline.markTextured(mDrawable);
+		}
+	}
+}
+
+void LLViewerObject::sendMaterialUpdate() const
+{
+	LLViewerRegion* regionp = getRegion();
+	if(!regionp) return;
+	gMessageSystem->newMessageFast(_PREHASH_ObjectMaterial);
+	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID,	mLocalID );
+	gMessageSystem->addU8Fast(_PREHASH_Material, getMaterial() );
+	gMessageSystem->sendReliable( regionp->getHost() );
+
+}
+
+// formerly send_object_rotation
+void LLViewerObject::sendRotationUpdate() const
+{
+	LLViewerRegion* regionp = getRegion();
+	if(!regionp) return;
+	gMessageSystem->newMessageFast(_PREHASH_ObjectRotation);
+	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID);
+	gMessageSystem->addQuatFast(_PREHASH_Rotation, getRotationEdit());
+	//llinfos << "Sent rotation " << getRotationEdit() << llendl;
+	gMessageSystem->sendReliable( regionp->getHost() );
+}
+
+/* Obsolete, we use MultipleObjectUpdate instead
+//// formerly send_object_position_global
+//void LLViewerObject::sendPositionUpdate() const
+//{
+//	gMessageSystem->newMessageFast(_PREHASH_ObjectPosition);
+//	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+//	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+//	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+//	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+//	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID,	mLocalID );
+//	gMessageSystem->addVector3Fast(_PREHASH_Position, getPositionRegion());
+//	LLViewerRegion* regionp = getRegion();
+//	gMessageSystem->sendReliable(regionp->getHost());
+//}
+*/
+
+//formerly send_object_shape(LLViewerObject *object)
+void LLViewerObject::sendShapeUpdate()
+{
+	gMessageSystem->newMessageFast(_PREHASH_ObjectShape);
+	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
+
+	LLVolumeMessage::packVolumeParams(&getVolume()->getParams(), gMessageSystem);
+
+	LLViewerRegion *regionp = getRegion();
+	gMessageSystem->sendReliable( regionp->getHost() );
+}
+
+
+void LLViewerObject::sendTEUpdate() const
+{
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_ObjectImage);
+
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+	msg->nextBlockFast(_PREHASH_ObjectData);
+	msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
+	if (mMedia)
+	{
+		msg->addString("MediaURL", mMedia->mMediaURL);
+	}
+	else
+	{
+		msg->addString("MediaURL", NULL);
+	}
+
+	// TODO send media type
+
+	packTEMessage(msg);
+
+	LLViewerRegion *regionp = getRegion();
+	msg->sendReliable( regionp->getHost() );
+}
+
+void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
+{
+	LLPrimitive::setTE(te, texture_entry);
+//  This doesn't work, don't get any textures.
+//	if (mDrawable.notNull() && mDrawable->isVisible())
+//	{
+		const LLUUID& image_id = getTE(te)->getID();
+		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+//	}
+}
+
+void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
+{
+	if (mTEImages[te] != imagep)
+	{
+		mTEImages[te] = imagep;
+		LLPrimitive::setTETexture(te, imagep->getID());
+		setChanged(TEXTURE);
+		if (mDrawable.notNull())
+		{
+			gPipeline.markTextured(mDrawable);
+		}
+	}
+}
+
+
+S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host)
+{
+	S32 retval = 0;
+	if (uuid != getTE(te)->getID() ||
+		uuid == LLUUID::null)
+	{
+		retval = LLPrimitive::setTETexture(te, uuid);
+		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
+		setChanged(TEXTURE);
+		if (mDrawable.notNull())
+		{
+			gPipeline.markTextured(mDrawable);
+		}
+	}
+	return retval;
+}
+
+
+void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image) 
+{
+	if(index < 0 || index >= getNumTEs())
+	{
+		return ;
+	}
+	mTEImages[index] = new_image ;
+}
+
+S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
+{
+	// Invalid host == get from the agent's sim
+	return setTETextureCore(te, uuid, LLHost::invalid);
+}
+
+
+S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)
+{
+	return setTEColor(te, LLColor4(color));
+}
+
+S32 LLViewerObject::setTEColor(const U8 te, const LLColor4& color)
+{
+	S32 retval = 0;
+	const LLTextureEntry *tep = getTE(te);
+	if (!tep)
+	{
+		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+	}
+	else if (color != tep->getColor())
+	{
+		retval = LLPrimitive::setTEColor(te, color);
+		if (mDrawable.notNull() && retval)
+		{
+			// These should only happen on updates which are not the initial update.
+			dirtyMesh();
+		}
+	}
+	return retval;
+}
+
+S32 LLViewerObject::setTEBumpmap(const U8 te, const U8 bump)
+{
+	S32 retval = 0;
+	const LLTextureEntry *tep = getTE(te);
+	if (!tep)
+	{
+		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+	}
+	else if (bump != tep->getBumpmap())
+	{
+		retval = LLPrimitive::setTEBumpmap(te, bump);
+		setChanged(TEXTURE);
+		if (mDrawable.notNull() && retval)
+		{
+			gPipeline.markTextured(mDrawable);
+			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+		}
+	}
+	return retval;
+}
+
+S32 LLViewerObject::setTETexGen(const U8 te, const U8 texgen)
+{
+	S32 retval = 0;
+	const LLTextureEntry *tep = getTE(te);
+	if (!tep)
+	{
+		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+	}
+	else if (texgen != tep->getTexGen())
+	{
+		retval = LLPrimitive::setTETexGen(te, texgen);
+		setChanged(TEXTURE);
+	}
+	return retval;
+}
+
+S32 LLViewerObject::setTEMediaTexGen(const U8 te, const U8 media)
+{
+	S32 retval = 0;
+	const LLTextureEntry *tep = getTE(te);
+	if (!tep)
+	{
+		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+	}
+	else if (media != tep->getMediaTexGen())
+	{
+		retval = LLPrimitive::setTEMediaTexGen(te, media);
+		setChanged(TEXTURE);
+	}
+	return retval;
+}
+
+S32 LLViewerObject::setTEShiny(const U8 te, const U8 shiny)
+{
+	S32 retval = 0;
+	const LLTextureEntry *tep = getTE(te);
+	if (!tep)
+	{
+		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+	}
+	else if (shiny != tep->getShiny())
+	{
+		retval = LLPrimitive::setTEShiny(te, shiny);
+		setChanged(TEXTURE);
+	}
+	return retval;
+}
+
+S32 LLViewerObject::setTEFullbright(const U8 te, const U8 fullbright)
+{
+	S32 retval = 0;
+	const LLTextureEntry *tep = getTE(te);
+	if (!tep)
+	{
+		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+	}
+	else if (fullbright != tep->getFullbright())
+	{
+		retval = LLPrimitive::setTEFullbright(te, fullbright);
+		setChanged(TEXTURE);
+		if (mDrawable.notNull() && retval)
+		{
+			gPipeline.markTextured(mDrawable);
+		}
+	}
+	return retval;
+}
+
+
+S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags)
+{
+	// this might need work for media type
+	S32 retval = 0;
+	const LLTextureEntry *tep = getTE(te);
+	if (!tep)
+	{
+		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+	}
+	else if (media_flags != tep->getMediaFlags())
+	{
+		retval = LLPrimitive::setTEMediaFlags(te, media_flags);
+		setChanged(TEXTURE);
+		if (mDrawable.notNull() && retval)
+		{
+			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, TRUE);
+			gPipeline.markTextured(mDrawable);
+			// JC - probably only need this if changes texture coords
+			//gPipeline.markRebuild(mDrawable);
+		}
+	}
+	return retval;
+}
+
+S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)
+{
+	S32 retval = 0;
+	const LLTextureEntry *tep = getTE(te);
+	if (!tep)
+	{
+		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+	}
+	else if (glow != tep->getGlow())
+	{
+		retval = LLPrimitive::setTEGlow(te, glow);
+		setChanged(TEXTURE);
+		if (mDrawable.notNull() && retval)
+		{
+			gPipeline.markTextured(mDrawable);
+		}
+	}
+	return retval;
+}
+
+
+S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
+{
+	S32 retval = 0;
+	retval = LLPrimitive::setTEScale(te, s, t);
+	setChanged(TEXTURE);
+	if (mDrawable.notNull() && retval)
+	{
+		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+	}
+	return retval;
+}
+
+S32 LLViewerObject::setTEScaleS(const U8 te, const F32 s)
+{
+	S32 retval = LLPrimitive::setTEScaleS(te, s);
+	if (mDrawable.notNull() && retval)
+	{
+		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+	}
+
+	return retval;
+}
+
+S32 LLViewerObject::setTEScaleT(const U8 te, const F32 t)
+{
+	S32 retval = LLPrimitive::setTEScaleT(te, t);
+	if (mDrawable.notNull() && retval)
+	{
+		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+	}
+
+	return retval;
+}
+
+S32 LLViewerObject::setTEOffset(const U8 te, const F32 s, const F32 t)
+{
+	S32 retval = LLPrimitive::setTEOffset(te, s, t);
+	if (mDrawable.notNull() && retval)
+	{
+		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+	}
+	return retval;
+}
+
+S32 LLViewerObject::setTEOffsetS(const U8 te, const F32 s)
+{
+	S32 retval = LLPrimitive::setTEOffsetS(te, s);
+	if (mDrawable.notNull() && retval)
+	{
+		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+	}
+
+	return retval;
+}
+
+S32 LLViewerObject::setTEOffsetT(const U8 te, const F32 t)
+{
+	S32 retval = LLPrimitive::setTEOffsetT(te, t);
+	if (mDrawable.notNull() && retval)
+	{
+		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+	}
+
+	return retval;
+}
+
+S32 LLViewerObject::setTERotation(const U8 te, const F32 r)
+{
+	S32 retval = LLPrimitive::setTERotation(te, r);
+	if (mDrawable.notNull() && retval)
+	{
+		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+	}
+	return retval;
+}
+
+
+LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const
+{
+//	llassert(mTEImages);
+
+	if (face < getNumTEs())
+	{
+		LLViewerTexture* image = mTEImages[face];
+		if (image)
+		{
+			return image;
+		}
+		else
+		{
+			return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
+		}
+	}
+
+	llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
+
+	return NULL;
+}
+
+
+void LLViewerObject::fitFaceTexture(const U8 face)
+{
+	llinfos << "fitFaceTexture not implemented" << llendl;
+}
+
+
+LLBBox LLViewerObject::getBoundingBoxAgent() const
+{
+	LLVector3 position_agent;
+	LLQuaternion rot;
+	LLViewerObject* avatar_parent = NULL;
+	LLViewerObject* root_edit = (LLViewerObject*)getRootEdit();
+	if (root_edit)
+	{
+		avatar_parent = (LLViewerObject*)root_edit->getParent();
+	}
+	
+	if (avatar_parent && avatar_parent->isAvatar() &&
+		root_edit && root_edit->mDrawable.notNull() && root_edit->mDrawable->getXform()->getParent())
+	{
+		LLXform* parent_xform = root_edit->mDrawable->getXform()->getParent();
+		position_agent = (getPositionEdit() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
+		rot = getRotationEdit() * parent_xform->getWorldRotation();
+	}
+	else
+	{
+		position_agent = getPositionAgent();
+		rot = getRotationRegion();
+	}
+	
+	return LLBBox( position_agent, rot, getScale() * -0.5f, getScale() * 0.5f );
+}
+
+U32 LLViewerObject::getNumVertices() const
+{
+	U32 num_vertices = 0;
+	if (mDrawable.notNull())
+	{
+		S32 i, num_faces;
+		num_faces = mDrawable->getNumFaces();
+		for (i = 0; i < num_faces; i++)
+		{
+			num_vertices += mDrawable->getFace(i)->getGeomCount();
+		}
+	}
+	return num_vertices;
+}
+
+U32 LLViewerObject::getNumIndices() const
+{
+	U32 num_indices = 0;
+	if (mDrawable.notNull())
+	{
+		S32 i, num_faces;
+		num_faces = mDrawable->getNumFaces();
+		for (i = 0; i < num_faces; i++)
+		{
+			num_indices += mDrawable->getFace(i)->getIndicesCount();
+		}
+	}
+	return num_indices;
+}
+
+// Find the number of instances of this object's inventory that are of the given type
+S32 LLViewerObject::countInventoryContents(LLAssetType::EType type)
+{
+	S32 count = 0;
+	if( mInventory )
+	{
+		LLInventoryObject::object_list_t::const_iterator it = mInventory->begin();
+		LLInventoryObject::object_list_t::const_iterator end = mInventory->end();
+		for(  ; it != end ; ++it )
+		{
+			if( (*it)->getType() == type )
+			{
+				++count;
+			}
+		}
+	}
+	return count;
+}
+
+
+void LLViewerObject::setCanSelect(BOOL canSelect)
+{
+	mbCanSelect = canSelect;
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* child = *iter;
+		child->mbCanSelect = canSelect;
+	}
+}
+
+void LLViewerObject::setDebugText(const std::string &utf8text)
+{
+	if (utf8text.empty() && !mText)
+	{
+		return;
+	}
+
+	if (!mText)
+	{
+		mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
+		mText->setFont(LLFontGL::getFontSansSerif());
+		mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
+		mText->setMaxLines(-1);
+		mText->setSourceObject(this);
+		mText->setOnHUDAttachment(isHUDAttachment());
+	}
+	mText->setColor(LLColor4::white);
+	mText->setString(utf8text);
+	mText->setZCompare(FALSE);
+	mText->setDoFade(FALSE);
+	updateText();
+}
+
+void LLViewerObject::setIcon(LLViewerTexture* icon_image)
+{
+	if (!mIcon)
+	{
+		mIcon = (LLHUDIcon *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_ICON);
+		mIcon->setSourceObject(this);
+		mIcon->setImage(icon_image);
+		// *TODO: make this user configurable
+		mIcon->setScale(0.03f);
+	}
+	else
+	{
+		mIcon->restartLifeTimer();
+	}
+}
+
+void LLViewerObject::clearIcon()
+{
+	if (mIcon)
+	{
+		mIcon = NULL;
+	}
+}
+
+LLViewerObject* LLViewerObject::getSubParent() 
+{ 
+	if (isJointChild())
+	{
+		return this;
+	}
+	return (LLViewerObject*) getParent();
+}
+
+const LLViewerObject* LLViewerObject::getSubParent() const
+{
+	if (isJointChild())
+	{
+		return this;
+	}
+	return (const LLViewerObject*) getParent();
+}
+
+BOOL LLViewerObject::isOnMap()
+{
+	return mOnMap;
+}
+
+
+void LLViewerObject::updateText()
+{
+	if (!isDead())
+	{
+		if (mText.notNull())
+		{		
+			LLVector3 up_offset(0,0,0);
+			up_offset.mV[2] = getScale().mV[VZ]*0.6f;
+			
+			if (mDrawable.notNull())
+			{
+				mText->setPositionAgent(getRenderPosition() + up_offset);
+			}
+			else
+			{
+				mText->setPositionAgent(getPositionAgent() + up_offset);
+			}
+		}
+	}
+}
+
+LLVOAvatar* LLViewerObject::asAvatar()
+{
+	return NULL;
+}
+
+BOOL LLViewerObject::isParticleSource() const
+{
+	return !mPartSourcep.isNull() && !mPartSourcep->isDead();
+}
+
+void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id)
+{
+	if (mPartSourcep)
+	{
+		deleteParticleSource();
+	}
+
+	LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::createPSS(this, particle_parameters);
+	mPartSourcep = pss;
+	
+	if (mPartSourcep)
+	{
+		mPartSourcep->setOwnerUUID(owner_id);
+
+		if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
+		{
+			LLViewerTexture* image;
+			if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
+			{
+				image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.tga");
+			}
+			else
+			{
+				image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
+			}
+			mPartSourcep->setImage(image);
+		}
+	}
+	LLViewerPartSim::getInstance()->addPartSource(pss);
+}
+
+void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& owner_id)
+{
+	if (!mPartSourcep.isNull() && mPartSourcep->isDead())
+	{
+		mPartSourcep = NULL;
+	}
+	if (mPartSourcep)
+	{
+		// If we've got one already, just update the existing source (or remove it)
+		if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, block_num))
+		{
+			mPartSourcep->setDead();
+			mPartSourcep = NULL;
+		}
+	}
+	else
+	{
+		LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num);
+		//If the owner is muted, don't create the system
+		if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
+
+		// We need to be able to deal with a particle source that hasn't changed, but still got an update!
+		if (pss)
+		{
+// 			llinfos << "Making particle system with owner " << owner_id << llendl;
+			pss->setOwnerUUID(owner_id);
+			mPartSourcep = pss;
+			LLViewerPartSim::getInstance()->addPartSource(pss);
+		}
+	}
+	if (mPartSourcep)
+	{
+		if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
+		{
+			LLViewerTexture* image;
+			if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
+			{
+				image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
+			}
+			else
+			{
+				image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
+			}
+			mPartSourcep->setImage(image);
+		}
+	}
+}
+
+void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id)
+{
+	if (!mPartSourcep.isNull() && mPartSourcep->isDead())
+	{
+		mPartSourcep = NULL;
+	}
+	if (mPartSourcep)
+	{
+		// If we've got one already, just update the existing source (or remove it)
+		if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp))
+		{
+			mPartSourcep->setDead();
+			mPartSourcep = NULL;
+		}
+	}
+	else
+	{
+		LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp);
+		//If the owner is muted, don't create the system
+		if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
+		// We need to be able to deal with a particle source that hasn't changed, but still got an update!
+		if (pss)
+		{
+// 			llinfos << "Making particle system with owner " << owner_id << llendl;
+			pss->setOwnerUUID(owner_id);
+			mPartSourcep = pss;
+			LLViewerPartSim::getInstance()->addPartSource(pss);
+		}
+	}
+	if (mPartSourcep)
+	{
+		if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
+		{
+			LLViewerTexture* image;
+			if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
+			{
+				image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
+			}
+			else
+			{
+				image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
+			}
+			mPartSourcep->setImage(image);
+		}
+	}
+}
+
+void LLViewerObject::deleteParticleSource()
+{
+	if (mPartSourcep.notNull())
+	{
+		mPartSourcep->setDead();
+		mPartSourcep = NULL;
+	}
+}
+
+// virtual
+void LLViewerObject::updateDrawable(BOOL force_damped)
+{
+	if (mDrawable.notNull() && 
+		!mDrawable->isState(LLDrawable::ON_MOVE_LIST) &&
+		isChanged(MOVED))
+	{
+		BOOL damped_motion = 
+			!isChanged(SHIFTED) &&										// not shifted between regions this frame and...
+			(	force_damped ||										// ...forced into damped motion by application logic or...
+				(	!isSelected() &&									// ...not selected and...
+					(	mDrawable->isRoot() ||								// ... is root or ...
+						(getParent() && !((LLViewerObject*)getParent())->isSelected())// ... parent is not selected and ...
+					) &&	
+					getPCode() == LL_PCODE_VOLUME &&					// ...is a volume object and...
+					getVelocity().isExactlyZero() &&					// ...is not moving physically and...
+					mDrawable->getGeneration() != -1                    // ...was not created this frame.
+				)					
+			);
+		gPipeline.markMoved(mDrawable, damped_motion);
+	}
+	clearChanged(SHIFTED);
+}
+
+// virtual, overridden by LLVOVolume
+F32 LLViewerObject::getVObjRadius() const
+{
+	return mDrawable.notNull() ? mDrawable->getRadius() : 0.f;
+}
+
+void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags)
+{
+	if (!gAudiop)
+	{
+		return;
+	}
+	
+	if (audio_uuid.isNull())
+	{
+		if (!mAudioSourcep)
+		{
+			return;
+		}
+		if (mAudioSourcep->isLoop() && !mAudioSourcep->hasPendingPreloads())
+		{
+			// We don't clear the sound if it's a loop, it'll go away on its own.
+			// At least, this appears to be how the scripts work.
+			// The attached sound ID is set to NULL to avoid it playing back when the
+			// object rezzes in on non-looping sounds.
+			//llinfos << "Clearing attached sound " << mAudioSourcep->getCurrentData()->getID() << llendl;
+			gAudiop->cleanupAudioSource(mAudioSourcep);
+			mAudioSourcep = NULL;
+		}
+		else if (flags & LL_SOUND_FLAG_STOP)
+        {
+			// Just shut off the sound
+			mAudioSourcep->play(LLUUID::null);
+		}
+		return;
+	}
+	if (flags & LL_SOUND_FLAG_LOOP
+		&& mAudioSourcep && mAudioSourcep->isLoop() && mAudioSourcep->getCurrentData()
+		&& mAudioSourcep->getCurrentData()->getID() == audio_uuid)
+	{
+		//llinfos << "Already playing this sound on a loop, ignoring" << llendl;
+		return;
+	}
+
+	// don't clean up before previous sound is done. Solves: SL-33486
+	if ( mAudioSourcep && mAudioSourcep->isDone() ) 
+	{
+		gAudiop->cleanupAudioSource(mAudioSourcep);
+		mAudioSourcep = NULL;
+	}
+
+	if (mAudioSourcep && mAudioSourcep->isMuted() &&
+	    mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid)
+	{
+		//llinfos << "Already having this sound as muted sound, ignoring" << llendl;
+		return;
+	}
+
+	getAudioSource(owner_id);
+
+	if (mAudioSourcep)
+	{
+		BOOL queue = flags & LL_SOUND_FLAG_QUEUE;
+		mAudioGain = gain;
+		mAudioSourcep->setGain(gain);
+		mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP);
+		mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER);
+		mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE);
+		mAudioSourcep->setQueueSounds(queue);
+		if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG
+		{
+			mAudioSourcep->play(LLUUID::null);
+		}
+		
+		// Play this sound if region maturity permits
+		if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) )
+		{
+			//llinfos << "Playing attached sound " << audio_uuid << llendl;
+			mAudioSourcep->play(audio_uuid);
+		}
+	}
+}
+
+LLAudioSource *LLViewerObject::getAudioSource(const LLUUID& owner_id)
+{
+	if (!mAudioSourcep)
+	{
+		// Arbitrary low gain for a sound that's not playing.
+		// This is used for sound preloads, for example.
+		LLAudioSourceVO *asvop = new LLAudioSourceVO(mID, owner_id, 0.01f, this);
+
+		mAudioSourcep = asvop;
+		if(gAudiop) gAudiop->addAudioSource(asvop);
+	}
+
+	return mAudioSourcep;
+}
+
+void LLViewerObject::adjustAudioGain(const F32 gain)
+{
+	if (!gAudiop)
+	{
+		return;
+	}
+	if (mAudioSourcep)
+	{
+		mAudioGain = gain;
+		mAudioSourcep->setGain(mAudioGain);
+	}
+}
+
+//----------------------------------------------------------------------------
+
+bool LLViewerObject::unpackParameterEntry(U16 param_type, LLDataPacker *dp)
+{
+	ExtraParameter* param = getExtraParameterEntryCreate(param_type);
+	if (param)
+	{
+		param->data->unpack(*dp);
+		param->in_use = TRUE;
+		parameterChanged(param_type, param->data, TRUE, false);
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 param_type)
+{
+	LLNetworkData* new_block = NULL;
+	switch (param_type)
+	{
+	  case LLNetworkData::PARAMS_FLEXIBLE:
+	  {
+		  new_block = new LLFlexibleObjectData();
+		  break;
+	  }
+	  case LLNetworkData::PARAMS_LIGHT:
+	  {
+		  new_block = new LLLightParams();
+		  break;
+	  }
+	  case LLNetworkData::PARAMS_SCULPT:
+	  {
+		  new_block = new LLSculptParams();
+		  break;
+	  }
+	  case LLNetworkData::PARAMS_LIGHT_IMAGE:
+	  {
+		  new_block = new LLLightImageParams();
+		  break;
+	  }
+	  default:
+	  {
+		  llinfos << "Unknown param type." << llendl;
+		  break;
+	  }
+	};
+
+	if (new_block)
+	{
+		ExtraParameter* new_entry = new ExtraParameter;
+		new_entry->data = new_block;
+		new_entry->in_use = false; // not in use yet
+		mExtraParameterList[param_type] = new_entry;
+		return new_entry;
+	}
+	return NULL;
+}
+
+LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const
+{
+	std::map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
+	if (itor != mExtraParameterList.end())
+	{
+		return itor->second;
+	}
+	return NULL;
+}
+
+LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntryCreate(U16 param_type)
+{
+	ExtraParameter* param = getExtraParameterEntry(param_type);
+	if (!param)
+	{
+		param = createNewParameterEntry(param_type);
+	}
+	return param;
+}
+
+LLNetworkData* LLViewerObject::getParameterEntry(U16 param_type) const
+{
+	ExtraParameter* param = getExtraParameterEntry(param_type);
+	if (param)
+	{
+		return param->data;
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+BOOL LLViewerObject::getParameterEntryInUse(U16 param_type) const
+{
+	ExtraParameter* param = getExtraParameterEntry(param_type);
+	if (param)
+	{
+		return param->in_use;
+	}
+	else
+	{
+		return FALSE;
+	}
+}
+
+bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin)
+{
+	ExtraParameter* param = getExtraParameterEntryCreate(param_type);
+	if (param)
+	{
+		if (param->in_use && new_value == *(param->data))
+		{
+			return false;
+		}
+		param->in_use = true;
+		param->data->copy(new_value);
+		parameterChanged(param_type, param->data, TRUE, local_origin);
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+// Assumed to be called locally
+// If in_use is TRUE, will crate a new extra parameter if none exists.
+// Should always return true.
+bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin)
+{
+	ExtraParameter* param = getExtraParameterEntryCreate(param_type);
+	if (param && param->in_use != in_use)
+	{
+		param->in_use = in_use;
+		parameterChanged(param_type, param->data, in_use, local_origin);
+		return true;
+	}
+	return false;
+}
+
+void LLViewerObject::parameterChanged(U16 param_type, bool local_origin)
+{
+	ExtraParameter* param = getExtraParameterEntry(param_type);
+	if (param)
+	{
+		parameterChanged(param_type, param->data, param->in_use, local_origin);
+	}
+}
+
+void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin)
+{
+	if (local_origin)
+	{
+		LLViewerRegion* regionp = getRegion();
+		if(!regionp) return;
+
+		// Change happened on the viewer. Send the change up
+		U8 tmp[MAX_OBJECT_PARAMS_SIZE];
+		LLDataPackerBinaryBuffer dpb(tmp, MAX_OBJECT_PARAMS_SIZE);
+		if (data->pack(dpb))
+		{
+			U32 datasize = (U32)dpb.getCurrentSize();
+
+			LLMessageSystem* msg = gMessageSystem;
+			msg->newMessageFast(_PREHASH_ObjectExtraParams);
+			msg->nextBlockFast(_PREHASH_AgentData);
+			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			msg->nextBlockFast(_PREHASH_ObjectData);
+			msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
+
+			msg->addU16Fast(_PREHASH_ParamType, param_type);
+			msg->addBOOLFast(_PREHASH_ParamInUse, in_use);
+
+			msg->addU32Fast(_PREHASH_ParamSize, datasize);
+			msg->addBinaryDataFast(_PREHASH_ParamData, tmp, datasize);
+
+			msg->sendReliable( regionp->getHost() );
+		}
+		else
+		{
+			llwarns << "Failed to send object extra parameters: " << param_type << llendl;
+		}
+	}
+}
+
+void LLViewerObject::setDrawableState(U32 state, BOOL recursive)
+{
+	if (mDrawable)
+	{
+		mDrawable->setState(state);
+	}
+	if (recursive)
+	{
+		for (child_list_t::iterator iter = mChildList.begin();
+			 iter != mChildList.end(); iter++)
+		{
+			LLViewerObject* child = *iter;
+			child->setDrawableState(state, recursive);
+		}
+	}
+}
+
+void LLViewerObject::clearDrawableState(U32 state, BOOL recursive)
+{
+	if (mDrawable)
+	{
+		mDrawable->clearState(state);
+	}
+	if (recursive)
+	{
+		for (child_list_t::iterator iter = mChildList.begin();
+			 iter != mChildList.end(); iter++)
+		{
+			LLViewerObject* child = *iter;
+			child->clearDrawableState(state, recursive);
+		}
+	}
+}
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// RN: these functions assume a 2-level hierarchy 
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+// Owned by anyone?
+BOOL LLViewerObject::permAnyOwner() const
+{ 
+	if (isRootEdit())
+	{
+		return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0); 
+	}
+	else
+	{
+		return ((LLViewerObject*)getParent())->permAnyOwner();
+	}
+}	
+// Owned by this viewer?
+BOOL LLViewerObject::permYouOwner() const
+{ 
+	if (isRootEdit())
+	{
+#ifdef HACKED_GODLIKE_VIEWER
+		return TRUE;
+#else
+# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+		if (!LLGridManager::getInstance()->isInProductionGrid()
+            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
+		{
+			return TRUE;
+		}
+# endif
+		return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0); 
+#endif
+	}
+	else
+	{
+		return ((LLViewerObject*)getParent())->permYouOwner();
+	}
+}
+
+// Owned by a group?
+BOOL LLViewerObject::permGroupOwner() const		
+{ 
+	if (isRootEdit())
+	{
+		return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0); 
+	}
+	else
+	{
+		return ((LLViewerObject*)getParent())->permGroupOwner();
+	}
+}
+
+// Can the owner edit
+BOOL LLViewerObject::permOwnerModify() const
+{ 
+	if (isRootEdit())
+	{
+#ifdef HACKED_GODLIKE_VIEWER
+		return TRUE;
+#else
+# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+		if (!LLGridManager::getInstance()->isInProductionGrid()
+            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
+	{
+			return TRUE;
+	}
+# endif
+		return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0); 
+#endif
+	}
+	else
+	{
+		return ((LLViewerObject*)getParent())->permOwnerModify();
+	}
+}
+
+// Can edit
+BOOL LLViewerObject::permModify() const
+{ 
+	if (isRootEdit())
+	{
+#ifdef HACKED_GODLIKE_VIEWER
+		return TRUE;
+#else
+# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+		if (!LLGridManager::getInstance()->isInProductionGrid()
+            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
+	{
+			return TRUE;
+	}
+# endif
+		return ((mFlags & FLAGS_OBJECT_MODIFY) != 0); 
+#endif
+	}
+	else
+	{
+		return ((LLViewerObject*)getParent())->permModify();
+	}
+}
+
+// Can copy
+BOOL LLViewerObject::permCopy() const
+{ 
+	if (isRootEdit())
+	{
+#ifdef HACKED_GODLIKE_VIEWER
+		return TRUE;
+#else
+# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+		if (!LLGridManager::getInstance()->isInProductionGrid()
+            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
+		{
+			return TRUE;
+		}
+# endif
+		return ((mFlags & FLAGS_OBJECT_COPY) != 0); 
+#endif
+	}
+	else
+	{
+		return ((LLViewerObject*)getParent())->permCopy();
+	}
+}
+
+// Can move
+BOOL LLViewerObject::permMove() const
+{
+	if (isRootEdit())
+	{
+#ifdef HACKED_GODLIKE_VIEWER
+		return TRUE;
+#else
+# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+		if (!LLGridManager::getInstance()->isInProductionGrid()
+            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
+		{
+			return TRUE;
+		}
+# endif
+		return ((mFlags & FLAGS_OBJECT_MOVE) != 0); 
+#endif
+	}
+	else
+	{
+		return ((LLViewerObject*)getParent())->permMove();
+	}
+}
+
+// Can be transferred
+BOOL LLViewerObject::permTransfer() const
+{ 
+	if (isRootEdit())
+	{
+#ifdef HACKED_GODLIKE_VIEWER
+		return TRUE;
+#else
+# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+		if (!LLGridManager::getInstance()->isInProductionGrid()
+            && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
+		{
+			return TRUE;
+		}
+# endif
+		return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0); 
+#endif
+	}
+	else
+	{
+		return ((LLViewerObject*)getParent())->permTransfer();
+	}
+}
+
+// Can only open objects that you own, or that someone has
+// given you modify rights to.  JC
+BOOL LLViewerObject::allowOpen() const
+{
+	return !flagInventoryEmpty() && (permYouOwner() || permModify());
+}
+
+LLViewerObject::LLInventoryCallbackInfo::~LLInventoryCallbackInfo()
+{
+	if (mListener)
+	{
+		mListener->clearVOInventoryListener();
+	}
+}
+
+void LLViewerObject::updateVolume(const LLVolumeParams& volume_params)
+{
+	if (setVolume(volume_params, 1)) // *FIX: magic number, ack!
+	{
+		// Transmit the update to the simulator
+		sendShapeUpdate();
+		markForUpdate(TRUE);
+	}
+}
+
+void LLViewerObject::markForUpdate(BOOL priority)
+{
+	if (mDrawable.notNull())
+	{
+		gPipeline.markTextured(mDrawable);
+		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, priority);
+	}
+}
+
+bool LLViewerObject::getIncludeInSearch() const
+{
+	return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0);
+}
+
+void LLViewerObject::setIncludeInSearch(bool include_in_search)
+{
+	if (include_in_search)
+	{
+		mFlags |= FLAGS_INCLUDE_IN_SEARCH;
+	}
+	else
+	{
+		mFlags &= ~FLAGS_INCLUDE_IN_SEARCH;
+	}
+}
+
+void LLViewerObject::setRegion(LLViewerRegion *regionp)
+{
+	if (!regionp)
+	{
+		llwarns << "viewer object set region to NULL" << llendl;
+	}
+	
+	mLatestRecvPacketID = 0;
+	mRegionp = regionp;
+
+	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
+	{
+		LLViewerObject* child = *i;
+		child->setRegion(regionp);
+	}
+
+	setChanged(MOVED | SILHOUETTE);
+	updateDrawable(FALSE);
+}
+
+// virtual
+void	LLViewerObject::updateRegion(LLViewerRegion *regionp)
+{
+//	if (regionp)
+//	{
+//		F64 now = LLFrameTimer::getElapsedSeconds();
+//		llinfos << "Updating to region " << regionp->getName()
+//			<< ", ms since last update message: " << (F32)((now - mLastMessageUpdateSecs) * 1000.0)
+//			<< ", ms since last interpolation: " << (F32)((now - mLastInterpUpdateSecs) * 1000.0) 
+//			<< llendl;
+//	}
+}
+
+
+bool LLViewerObject::specialHoverCursor() const
+{
+	return (mFlags & FLAGS_USE_PHYSICS)
+			|| (mFlags & FLAGS_HANDLE_TOUCH)
+			|| (mClickAction != 0);
+}
+
+void LLViewerObject::updateFlags(BOOL physics_changed)
+{
+	LLViewerRegion* regionp = getRegion();
+	if(!regionp) return;
+	gMessageSystem->newMessage("ObjectFlagUpdate");
+	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, getLocalID() );
+	gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, usePhysics() );
+	gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() );
+	gMessageSystem->addBOOL("IsPhantom", flagPhantom() );
+	gMessageSystem->addBOOL("CastsShadows", flagCastShadows() );
+	if (physics_changed)
+	{
+		gMessageSystem->nextBlock("ExtraPhysics");
+		gMessageSystem->addU8("PhysicsShapeType", getPhysicsShapeType() );
+		gMessageSystem->addF32("Density", getPhysicsDensity() );
+		gMessageSystem->addF32("Friction", getPhysicsFriction() );
+		gMessageSystem->addF32("Restitution", getPhysicsRestitution() );
+		gMessageSystem->addF32("GravityMultiplier", getPhysicsGravity() );
+	}
+	gMessageSystem->sendReliable( regionp->getHost() );
+}
+
+BOOL LLViewerObject::setFlags(U32 flags, BOOL state)
+{
+	BOOL setit = FALSE;
+	if (state)
+	{
+		if ((mFlags & flags) != flags)
+		{
+			mFlags |= flags;
+			setit = TRUE;
+		}
+	}
+	else
+	{
+		if ((mFlags & flags) != 0)
+		{
+			mFlags &= ~flags;
+			setit = TRUE;
+		}
+	}
+
+	// BUG: Sometimes viewer physics and simulator physics get
+	// out of sync.  To fix this, always send update to simulator.
+// 	if (setit)
+	{
+		updateFlags();
+	}
+	return setit;
+}
+
+void LLViewerObject::setPhysicsShapeType(U8 type)
+{
+	mPhysicsShapeUnknown = false;
+	mPhysicsShapeType = type;
+	mCostStale = true;
+}
+
+void LLViewerObject::setPhysicsGravity(F32 gravity)
+{
+	mPhysicsGravity = gravity;
+}
+
+void LLViewerObject::setPhysicsFriction(F32 friction)
+{
+	mPhysicsFriction = friction;
+}
+
+void LLViewerObject::setPhysicsDensity(F32 density)
+{
+	mPhysicsDensity = density;
+}
+
+void LLViewerObject::setPhysicsRestitution(F32 restitution)
+{
+	mPhysicsRestitution = restitution;
+}
+
+U8 LLViewerObject::getPhysicsShapeType() const
+{ 
+	if (mPhysicsShapeUnknown)
+	{
+		mPhysicsShapeUnknown = false;
+		gObjectList.updatePhysicsFlags(this);
+	}
+
+	return mPhysicsShapeType; 
+}
+
+void LLViewerObject::applyAngularVelocity(F32 dt)
+{
+	//do target omega here
+	mRotTime += dt;
+	LLVector3 ang_vel = getAngularVelocity();
+	F32 omega = ang_vel.magVecSquared();
+	F32 angle = 0.0f;
+	LLQuaternion dQ;
+	if (omega > 0.00001f)
+	{
+		omega = sqrt(omega);
+		angle = omega * dt;
+
+		ang_vel *= 1.f/omega;
+		
+		dQ.setQuat(angle, ang_vel);
+		
+		setRotation(getRotation()*dQ);
+		setChanged(MOVED | SILHOUETTE);
+	}
+}
+
+void LLViewerObject::resetRot()
+{
+	mRotTime = 0.0f;
+}
+
+U32 LLViewerObject::getPartitionType() const
+{ 
+	return LLViewerRegion::PARTITION_NONE; 
+}
+
+void LLViewerObject::dirtySpatialGroup(BOOL priority) const
+{
+	if (mDrawable)
+	{
+		LLSpatialGroup* group = mDrawable->getSpatialGroup();
+		if (group)
+		{
+			group->dirtyGeom();
+			gPipeline.markRebuild(group, priority);
+		}
+	}
+}
+
+void LLViewerObject::dirtyMesh()
+{
+	if (mDrawable)
+	{
+		LLSpatialGroup* group = mDrawable->getSpatialGroup();
+		if (group)
+		{
+			group->dirtyMesh();
+		}
+	}
+}
+
+F32 LLAlphaObject::getPartSize(S32 idx)
+{
+	return 0.f;
+}
+
+// virtual
+void LLStaticViewerObject::updateDrawable(BOOL force_damped)
+{
+	// Force an immediate rebuild on any update
+	if (mDrawable.notNull())
+	{
+		mDrawable->updateXform(TRUE);
+		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+	}
+	clearChanged(SHIFTED);
+}
+
+void LLViewerObject::saveUnselectedChildrenPosition(std::vector<LLVector3>& positions)
+{
+	if(mChildList.empty() || !positions.empty())
+	{
+		return ;
+	}
+
+	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+			iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* childp = *iter;
+		if (!childp->isSelected() && childp->mDrawable.notNull())
+		{
+			positions.push_back(childp->getPositionEdit());		
+		}
+	}
+
+	return ;
+}
+
+void LLViewerObject::saveUnselectedChildrenRotation(std::vector<LLQuaternion>& rotations)
+{
+	if(mChildList.empty())
+	{
+		return ;
+	}
+
+	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+			iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* childp = *iter;
+		if (!childp->isSelected() && childp->mDrawable.notNull())
+		{
+			rotations.push_back(childp->getRotationEdit());				
+		}		
+	}
+
+	return ;
+}
+
+//counter-rotation
+void LLViewerObject::resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations, 
+											const std::vector<LLVector3>& positions)
+{
+	if(mChildList.empty())
+	{
+		return ;
+	}
+
+	S32 index = 0 ;
+	LLQuaternion inv_rotation = ~getRotationEdit() ;
+	LLVector3 offset = getPositionEdit() ;
+	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+			iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* childp = *iter;
+		if (!childp->isSelected() && childp->mDrawable.notNull())
+		{
+			if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
+			{
+				childp->setRotation(rotations[index] * inv_rotation);
+				childp->setPosition((positions[index] - offset) * inv_rotation);
+				LLManip::rebuild(childp);					
+			}
+			else //avatar
+			{
+				LLVector3 reset_pos = (positions[index] - offset) * inv_rotation ;
+				LLQuaternion reset_rot = rotations[index] * inv_rotation ;
+
+				((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);				
+				((LLVOAvatar*)childp)->mDrawable->mXform.setRotation(reset_rot) ;
+				
+				((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos, TRUE);				
+				((LLVOAvatar*)childp)->mDrawable->getVObj()->setRotation(reset_rot, TRUE) ;
+
+				LLManip::rebuild(childp);				
+			}	
+			index++;
+		}				
+	}
+
+	return ;
+}
+
+//counter-translation
+void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplified)
+{
+	if(mChildList.empty())
+	{
+		return ;
+	}
+
+	LLVector3 child_offset;
+	if(simplified) //translation only, rotation matrix does not change
+	{
+		child_offset = offset * ~getRotation();
+	}
+	else //rotation matrix might change too.
+	{
+		if (isAttachment() && mDrawable.notNull())
+		{
+			LLXform* attachment_point_xform = mDrawable->getXform()->getParent();
+			LLQuaternion parent_rotation = getRotation() * attachment_point_xform->getWorldRotation();
+			child_offset = offset * ~parent_rotation;
+		}
+		else
+		{
+			child_offset = offset * ~getRenderRotation();
+		}
+	}
+
+	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+			iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* childp = *iter;
+		if (!childp->isSelected() && childp->mDrawable.notNull())
+		{
+			if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
+			{
+				childp->setPosition(childp->getPosition() + child_offset);
+				LLManip::rebuild(childp);
+			}
+			else //avatar
+			{
+				LLVector3 reset_pos = ((LLVOAvatar*)childp)->mDrawable->mXform.getPosition() + child_offset ;
+
+				((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);
+				((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos);				
+				
+				LLManip::rebuild(childp);
+			}			
+		}		
+	}
+
+	return ;
+}
+
+const LLUUID &LLViewerObject::getAttachmentItemID() const
+{
+	return mAttachmentItemID;
+}
+
+void LLViewerObject::setAttachmentItemID(const LLUUID &id)
+{
+	mAttachmentItemID = id;
+}
+
+EObjectUpdateType LLViewerObject::getLastUpdateType() const
+{
+	return mLastUpdateType;
+}
+
+void LLViewerObject::setLastUpdateType(EObjectUpdateType last_update_type)
+{
+	mLastUpdateType = last_update_type;
+}
+
+BOOL LLViewerObject::getLastUpdateCached() const
+{
+	return mLastUpdateCached;
+}
+
+void LLViewerObject::setLastUpdateCached(BOOL last_update_cached)
+{
+	mLastUpdateCached = last_update_cached;
+}
+
+const LLUUID &LLViewerObject::extractAttachmentItemID()
+{
+	LLUUID item_id = LLUUID::null;
+	LLNameValue* item_id_nv = getNVPair("AttachItemID");
+	if( item_id_nv )
+	{
+		const char* s = item_id_nv->getString();
+		if( s )
+		{
+			item_id.set(s);
+		}
+	}
+	setAttachmentItemID(item_id);
+	return getAttachmentItemID();
+}
+
+//virtual
+LLVOAvatar* LLViewerObject::getAvatar() const
+{
+	if (isAttachment())
+	{
+		LLViewerObject* vobj = (LLViewerObject*) getParent();
+
+		while (vobj && !vobj->asAvatar())
+		{
+			vobj = (LLViewerObject*) vobj->getParent();
+		}
+
+		return (LLVOAvatar*) vobj;
+	}
+
+	return NULL;
+}
+
+
+class ObjectPhysicsProperties : public LLHTTPNode
+{
+public:
+	virtual void post(
+		ResponsePtr responder,
+		const LLSD& context,
+		const LLSD& input) const
+	{
+		LLSD object_data = input["body"]["ObjectData"];
+		S32 num_entries = object_data.size();
+		
+		for ( S32 i = 0; i < num_entries; i++ )
+		{
+			LLSD& curr_object_data = object_data[i];
+			U32 local_id = curr_object_data["LocalID"].asInteger();
+
+			// Iterate through nodes at end, since it can be on both the regular AND hover list
+			struct f : public LLSelectedNodeFunctor
+			{
+				U32 mID;
+				f(const U32& id) : mID(id) {}
+				virtual bool apply(LLSelectNode* node)
+				{
+					return (node->getObject() && node->getObject()->mLocalID == mID );
+				}
+			} func(local_id);
+
+			LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
+
+			if (node)
+			{
+				// The LLSD message builder doesn't know how to handle U8, so we need to send as S8 and cast
+				U8 type = (U8)curr_object_data["PhysicsShapeType"].asInteger();
+				F32 density = (F32)curr_object_data["Density"].asReal();
+				F32 friction = (F32)curr_object_data["Friction"].asReal();
+				F32 restitution = (F32)curr_object_data["Restitution"].asReal();
+				F32 gravity = (F32)curr_object_data["GravityMultiplier"].asReal();
+
+				node->getObject()->setPhysicsShapeType(type);
+				node->getObject()->setPhysicsGravity(gravity);
+				node->getObject()->setPhysicsFriction(friction);
+				node->getObject()->setPhysicsDensity(density);
+				node->getObject()->setPhysicsRestitution(restitution);
+			}	
+		}
+		
+		dialog_refresh_all();
+	};
+};
+
+LLHTTPRegistration<ObjectPhysicsProperties>
+	gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties");
+
+
+void LLViewerObject::updateQuota( const SelectionQuota& quota )
+{
+	//update quotas
+	mSelectionQuota = quota;
+}
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 1335c5c319..a0ad52df6b 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -1,825 +1,825 @@
-/** 
- * @file llviewerobject.h
- * @brief Description of LLViewerObject class, which is the base class for most objects in the viewer.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLVIEWEROBJECT_H
-#define LL_LLVIEWEROBJECT_H
-
-#include <map>
-
-#include "llassetstorage.h"
-#include "lldarrayptr.h"
-#include "llhudicon.h"
-#include "llinventory.h"
-#include "llrefcount.h"
-#include "llmemtype.h"
-#include "llprimitive.h"
-#include "lluuid.h"
-#include "llvoinventorylistener.h"
-#include "object_flags.h"
-#include "llquaternion.h"
-#include "v3dmath.h"
-#include "v3math.h"
-#include "llvertexbuffer.h"
-#include "llaccountingquota.h"
-
-class LLAgent;			// TODO: Get rid of this.
-class LLAudioSource;
-class LLAudioSourceVO;
-class LLBBox;
-class LLDataPacker;
-class LLColor4;
-class LLFrameTimer;
-class LLDrawable;
-class LLHost;
-class LLHUDText;
-class LLWorld;
-class LLNameValue;
-class LLNetMap;
-class LLMessageSystem;
-class LLPartSysData;
-class LLPrimitive;
-class LLPipeline;
-class LLTextureEntry;
-class LLViewerTexture;
-class LLViewerInventoryItem;
-class LLViewerObject;
-class LLViewerPartSourceScript;
-class LLViewerRegion;
-class LLViewerObjectMedia;
-class LLVOInventoryListener;
-class LLVOAvatar;
-
-typedef enum e_object_update_type
-{
-	OUT_FULL,
-	OUT_TERSE_IMPROVED,
-	OUT_FULL_COMPRESSED,
-	OUT_FULL_CACHED,
-	OUT_UNKNOWN,
-} EObjectUpdateType;
-
-
-// callback typedef for inventory
-typedef void (*inventory_callback)(LLViewerObject*,
-								   LLInventoryObject::object_list_t*,
-								   S32 serial_num,
-								   void*);
-
-// a small struct for keeping track of joints
-struct LLVOJointInfo
-{
-	EHavokJointType mJointType;
-	LLVector3 mPivot;			// parent-frame
-	// whether the below an axis or anchor (and thus its frame)
-	// depends on the joint type:
-	//     HINGE   ==>   axis=parent-frame
-	//     P2P     ==>   anchor=child-frame
-	LLVector3 mAxisOrAnchor;	
-};
-
-// for exporting textured materials from SL
-struct LLMaterialExportInfo
-{
-public:
-	LLMaterialExportInfo(S32 mat_index, S32 texture_index, LLColor4 color) : 
-	  mMaterialIndex(mat_index), mTextureIndex(texture_index), mColor(color) {};
-
-	S32			mMaterialIndex;
-	S32			mTextureIndex;
-	LLColor4	mColor;
-};
-
-//============================================================================
-
-class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
-{
-protected:
-	~LLViewerObject(); // use unref()
-
-	// TomY: Provide for a list of extra parameter structures, mapped by structure name
-	struct ExtraParameter
-	{
-		BOOL in_use;
-		LLNetworkData *data;
-	};
-	std::map<U16, ExtraParameter*> mExtraParameterList;
-
-public:
-	typedef std::list<LLPointer<LLViewerObject> > child_list_t;
-	typedef std::list<LLPointer<LLViewerObject> > vobj_list_t;
-
-	typedef const child_list_t const_child_list_t;
-
-	LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global = FALSE);
-	MEM_TYPE_NEW(LLMemType::MTYPE_OBJECT);
-
-	virtual void markDead();				// Mark this object as dead, and clean up its references
-	BOOL isDead() const									{return mDead;}
-	BOOL isOrphaned() const								{ return mOrphaned; }
-	BOOL isParticleSource() const;
-
-	virtual LLVOAvatar* asAvatar();
-
-	static void initVOClasses();
-	static void cleanupVOClasses();
-
-	void			addNVPair(const std::string& data);
-	BOOL			removeNVPair(const std::string& name);
-	LLNameValue*	getNVPair(const std::string& name) const;			// null if no name value pair by that name
-
-	// Object create and update functions
-	virtual BOOL	idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
-
-	// Types of media we can associate
-	enum { MEDIA_NONE = 0, MEDIA_SET = 1 };
-
-	// Return codes for processUpdateMessage
-	enum { 
-        MEDIA_URL_REMOVED = 0x1, 
-        MEDIA_URL_ADDED = 0x2, 
-        MEDIA_URL_UPDATED = 0x4, 
-        MEDIA_FLAGS_CHANGED = 0x8,
-        INVALID_UPDATE = 0x80000000
-    };
-
-	virtual U32		processUpdateMessage(LLMessageSystem *mesgsys,
-										void **user_data,
-										U32 block_num,
-										const EObjectUpdateType update_type,
-										LLDataPacker *dp);
-
-
-	virtual BOOL    isActive() const; // Whether this object needs to do an idleUpdate.
-	BOOL			onActiveList() const				{return mOnActiveList;}
-	void			setOnActiveList(BOOL on_active)		{ mOnActiveList = on_active; }
-
-	virtual BOOL	isAttachment() const { return FALSE; }
-	virtual LLVOAvatar* getAvatar() const;  //get the avatar this object is attached to, or NULL if object is not an attachment
-	virtual BOOL	isHUDAttachment() const { return FALSE; }
-	virtual void 	updateRadius() {};
-	virtual F32 	getVObjRadius() const; // default implemenation is mDrawable->getRadius()
-	
-	BOOL 			isJointChild() const { return mJointInfo ? TRUE : FALSE; } 
-	EHavokJointType	getJointType() const { return mJointInfo ? mJointInfo->mJointType : HJT_INVALID; }
-	// for jointed and other parent-relative hacks
-	LLViewerObject* getSubParent();
-	const LLViewerObject* getSubParent() const;
-	
-	// Object visiblility and GPW functions
-	virtual void setPixelAreaAndAngle(LLAgent &agent); // Override to generate accurate apparent angle and area
-
-	virtual U32 getNumVertices() const;
-	virtual U32 getNumIndices() const;
-	S32 getNumFaces() const { return mNumFaces; }
-
-	// Graphical stuff for objects - maybe broken out into render class later?
-	virtual void updateTextures();
-	virtual void boostTexturePriority(BOOL boost_children = TRUE);	// When you just want to boost priority of this object
-	
-	virtual LLDrawable* createDrawable(LLPipeline *pipeline);
-	virtual BOOL		updateGeometry(LLDrawable *drawable);
-	virtual void		updateGL();
-	virtual void		updateFaceSize(S32 idx);
-	virtual BOOL		updateLOD();
-	virtual BOOL		setDrawableParent(LLDrawable* parentp);
-	F32					getRotTime() { return mRotTime; }
-	void				resetRot();
-	void				applyAngularVelocity(F32 dt);
-
-	void setLineWidthForWindowSize(S32 window_width);
-
-	static void increaseArrowLength();				// makes axis arrows for selections longer
-	static void decreaseArrowLength();				// makes axis arrows for selections shorter
-
-	// Accessor functions
-	LLViewerRegion* getRegion() const				{ return mRegionp; }
-
-	BOOL isSelected() const							{ return mUserSelected; }
-	virtual void setSelected(BOOL sel)				{ mUserSelected = sel; mRotTime = 0.f;}
-
-	const LLUUID &getID() const						{ return mID; }
-	U32 getLocalID() const							{ return mLocalID; }
-	U32 getCRC() const								{ return mTotalCRC; }
-
-	virtual BOOL isFlexible() const					{ return FALSE; }
-	virtual BOOL isSculpted() const 				{ return FALSE; }
-	virtual BOOL isMesh() const						{ return FALSE; }
-	virtual BOOL hasLightTexture() const			{ return FALSE; }
-
-	// This method returns true if the object is over land owned by
-	// the agent, one of its groups, or it encroaches and 
-	// anti-encroachment is enabled
-	bool isReturnable();
-
-	/*
-	// This method will scan through this object, and then query the
-	// selection manager to see if the local agent probably has the
-	// ability to modify the object. Since this calls into the
-	// selection manager, you should avoid calling this method from
-	// there.
-	BOOL isProbablyModifiable() const;
-	*/
-
-	virtual BOOL setParent(LLViewerObject* parent);
-	virtual void addChild(LLViewerObject *childp);
-	virtual void removeChild(LLViewerObject *childp);
-	const_child_list_t& getChildren() const { 	return mChildList; }
-	S32 numChildren() const { return mChildList.size(); }
-	void addThisAndAllChildren(std::vector<LLViewerObject*>& objects);
-	void addThisAndNonJointChildren(std::vector<LLViewerObject*>& objects);
-	BOOL isChild(LLViewerObject *childp) const;
-	BOOL isSeat() const;
-	
-
-	//detect if given line segment (in agent space) intersects with this viewer object.
-	//returns TRUE if intersection detected and returns information about intersection
-	virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
-									  S32 face = -1,                          // which face to check, -1 = ALL_SIDES
-									  BOOL pick_transparent = FALSE,
-									  S32* face_hit = NULL,                   // which face was hit
-									  LLVector3* intersection = NULL,         // return the intersection point
-									  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point
-									  LLVector3* normal = NULL,               // return the surface normal at the intersection point
-									  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point
-		);
-	
-	virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end);
-
-	virtual const LLVector3d getPositionGlobal() const;
-	virtual const LLVector3 &getPositionRegion() const;
-	virtual const LLVector3 getPositionEdit() const;
-	virtual const LLVector3 &getPositionAgent() const;
-	virtual const LLVector3 getRenderPosition() const;
-
-	virtual const LLVector3 getPivotPositionAgent() const; // Usually = to getPositionAgent, unless like flex objects it's not
-
-	LLViewerObject* getRootEdit() const;
-
-	const LLQuaternion getRotationRegion() const;
-	const LLQuaternion getRotationEdit() const;
-	const LLQuaternion getRenderRotation() const;
-	virtual	const LLMatrix4 getRenderMatrix() const;
-
-	void setPosition(const LLVector3 &pos, BOOL damped = FALSE);
-	void setPositionGlobal(const LLVector3d &position, BOOL damped = FALSE);
-	void setPositionRegion(const LLVector3 &position, BOOL damped = FALSE);
-	void setPositionEdit(const LLVector3 &position, BOOL damped = FALSE);
-	void setPositionAgent(const LLVector3 &pos_agent, BOOL damped = FALSE);
-	void setPositionParent(const LLVector3 &pos_parent, BOOL damped = FALSE);
-	void setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped = FALSE );
-
-	virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const		{ return xform->getWorldMatrix(); }
-
-	inline void setRotation(const F32 x, const F32 y, const F32 z, BOOL damped = FALSE);
-	inline void setRotation(const LLQuaternion& quat, BOOL damped = FALSE);
-	void sendRotationUpdate() const;
-
-	/*virtual*/	void	setNumTEs(const U8 num_tes);
-	/*virtual*/	void	setTE(const U8 te, const LLTextureEntry &texture_entry);
-	/*virtual*/ S32		setTETexture(const U8 te, const LLUUID &uuid);
-	S32 setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host);
-	/*virtual*/ S32		setTEColor(const U8 te, const LLColor3 &color);
-	/*virtual*/ S32		setTEColor(const U8 te, const LLColor4 &color);
-	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t);
-	/*virtual*/ S32		setTEScaleS(const U8 te, const F32 s);
-	/*virtual*/ S32		setTEScaleT(const U8 te, const F32 t);
-	/*virtual*/ S32		setTEOffset(const U8 te, const F32 s, const F32 t);
-	/*virtual*/ S32		setTEOffsetS(const U8 te, const F32 s);
-	/*virtual*/ S32		setTEOffsetT(const U8 te, const F32 t);
-	/*virtual*/ S32		setTERotation(const U8 te, const F32 r);
-	/*virtual*/	S32		setTEBumpmap(const U8 te, const U8 bump );
-	/*virtual*/	S32		setTETexGen(const U8 te, const U8 texgen );
-	/*virtual*/	S32		setTEMediaTexGen(const U8 te, const U8 media ); // *FIXME: this confusingly acts upon a superset of setTETexGen's flags without absorbing its semantics
-	/*virtual*/	S32		setTEShiny(const U8 te, const U8 shiny );
-	/*virtual*/	S32		setTEFullbright(const U8 te, const U8 fullbright );
-	/*virtual*/	S32		setTEMediaFlags(const U8 te, const U8 media_flags );
-	/*virtual*/ S32     setTEGlow(const U8 te, const F32 glow);
-	/*virtual*/	BOOL	setMaterial(const U8 material);
-	virtual		void	setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
-	void                changeTEImage(S32 index, LLViewerTexture* new_image)  ;
-	LLViewerTexture		*getTEImage(const U8 te) const;
-	
-	void fitFaceTexture(const U8 face);
-	void sendTEUpdate() const;			// Sends packed representation of all texture entry information
-	
-	virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE);
-
-	virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL);
-	virtual U32 getTriangleCount();
-	virtual U32 getHighLODTriangleCount();
-
-	void setObjectCost(F32 cost);
-	F32 getObjectCost();
-	
-	void setLinksetCost(F32 cost);
-	F32 getLinksetCost();
-	
-	void setPhysicsCost(F32 cost);
-	F32 getPhysicsCost();
-	
-	void setLinksetPhysicsCost(F32 cost);
-	F32 getLinksetPhysicsCost();
-
-	void sendShapeUpdate();
-
-	U8 getState()							{ return mState; }
-
-	F32 getAppAngle() const					{ return mAppAngle; }
-	F32 getPixelArea() const				{ return mPixelArea; }
-	void setPixelArea(F32 area)				{ mPixelArea = area; }
-	F32 getMaxScale() const;
-	F32 getMidScale() const;
-	F32 getMinScale() const;
-
-	// Owner id is this object's owner
-	void setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags);
-	void adjustAudioGain(const F32 gain);
-	void clearAttachedSound()								{ mAudioSourcep = NULL; }
-
-	 // Create if necessary
-	LLAudioSource *getAudioSource(const LLUUID& owner_id);
-	bool isAudioSource() {return mAudioSourcep != NULL;}
-
-	U8 getMediaType() const;
-	void setMediaType(U8 media_type);
-
-	std::string getMediaURL() const;
-	void setMediaURL(const std::string& media_url);
-
-	BOOL getMediaPassedWhitelist() const;
-	void setMediaPassedWhitelist(BOOL passed);
-
-	void sendMaterialUpdate() const;
-
-	void setCanSelect(BOOL canSelect);
-
-	void setDebugText(const std::string &utf8text);
-	void setIcon(LLViewerTexture* icon_image);
-	void clearIcon();
-
-	void markForUpdate(BOOL priority);
-	void updateVolume(const LLVolumeParams& volume_params);
-	virtual	void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
-	virtual F32 getBinRadius();
-	
-	LLBBox				getBoundingBoxAgent() const;
-
-	void updatePositionCaches() const; // Update the global and region position caches from the object (and parent's) xform.
-	void updateText(); // update text label position
-	virtual void updateDrawable(BOOL force_damped); // force updates on static objects
-
-	void setDrawableState(U32 state, BOOL recursive = TRUE);
-	void clearDrawableState(U32 state, BOOL recursive = TRUE);
-
-	// Called when the drawable shifts
-	virtual void onShift(const LLVector4a &shift_vector)	{ }
-		
-	//////////////////////////////////////
-	//
-	// Inventory methods
-	//
-
-	// This function is called when someone is interested in a viewer
-	// object's inventory. The callback is called as soon as the
-	// viewer object has the inventory stored locally.
-	void registerInventoryListener(LLVOInventoryListener* listener, void* user_data);
-	void removeInventoryListener(LLVOInventoryListener* listener);
-	BOOL isInventoryPending() { return mInventoryPending; }
-	void clearInventoryListeners();
-	void requestInventory();
-	void fetchInventoryFromServer();
-	static void processTaskInv(LLMessageSystem* msg, void** user_data);
-	void removeInventory(const LLUUID& item_id);
-
-	// The updateInventory() call potentially calls into the selection
-	// manager, so do no call updateInventory() from the selection
-	// manager until we have better iterators.
-	void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
-	void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
-	LLInventoryObject* getInventoryObject(const LLUUID& item_id);
-	void getInventoryContents(LLInventoryObject::object_list_t& objects);
-	LLInventoryObject* getInventoryRoot();
-	LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
-	S16 getInventorySerial() const { return mInventorySerialNum; }
-
-	// These functions does viewer-side only object inventory modifications
-	void updateViewerInventoryAsset(
-		const LLViewerInventoryItem* item,
-		const LLUUID& new_asset);
-
-	// This function will make sure that we refresh the inventory.
-	void dirtyInventory();
-	BOOL isInventoryDirty() { return mInventoryDirty; }
-
-	// save a script, which involves removing the old one, and rezzing
-	// in the new one. This method should be called with the asset id
-	// of the new and old script AFTER the bytecode has been saved.
-	void saveScript(const LLViewerInventoryItem* item, BOOL active, bool is_new);
-
-	// move an inventory item out of the task and into agent
-	// inventory. This operation is based on messaging. No permissions
-	// checks are made on the viewer - the server will double check.
-	void moveInventory(const LLUUID& agent_folder, const LLUUID& item_id);
-
-	// Find the number of instances of this object's inventory that are of the given type
-	S32 countInventoryContents( LLAssetType::EType type );
-
-	BOOL			permAnyOwner() const;	
-	BOOL			permYouOwner() const;
-	BOOL			permGroupOwner() const;
-	BOOL			permOwnerModify() const;
-	BOOL			permModify() const;	
-	BOOL			permCopy() const;	
-	BOOL			permMove() const;		
-	BOOL			permTransfer() const;
-	inline BOOL		usePhysics() const				{ return ((mFlags & FLAGS_USE_PHYSICS) != 0); }
-	inline BOOL		flagScripted() const			{ return ((mFlags & FLAGS_SCRIPTED) != 0); }
-	inline BOOL		flagHandleTouch() const			{ return ((mFlags & FLAGS_HANDLE_TOUCH) != 0); }
-	inline BOOL		flagTakesMoney() const			{ return ((mFlags & FLAGS_TAKES_MONEY) != 0); }
-	inline BOOL		flagPhantom() const				{ return ((mFlags & FLAGS_PHANTOM) != 0); }
-	inline BOOL		flagInventoryEmpty() const		{ return ((mFlags & FLAGS_INVENTORY_EMPTY) != 0); }
-	inline BOOL		flagCastShadows() const			{ return ((mFlags & FLAGS_CAST_SHADOWS) != 0); }
-	inline BOOL		flagAllowInventoryAdd() const	{ return ((mFlags & FLAGS_ALLOW_INVENTORY_DROP) != 0); }
-	inline BOOL		flagTemporary() const			{ return ((mFlags & FLAGS_TEMPORARY) != 0); }
-	inline BOOL		flagTemporaryOnRez() const		{ return ((mFlags & FLAGS_TEMPORARY_ON_REZ) != 0); }
-	inline BOOL		flagAnimSource() const			{ return ((mFlags & FLAGS_ANIM_SOURCE) != 0); }
-	inline BOOL		flagCameraSource() const		{ return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); }
-	inline BOOL		flagCameraDecoupled() const		{ return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); }
-	inline BOOL		flagObjectMove() const			{ return ((mFlags & FLAGS_OBJECT_MOVE) != 0); }
-
-	U8       getPhysicsShapeType() const;
-	inline F32      getPhysicsGravity() const       { return mPhysicsGravity; }
-	inline F32      getPhysicsFriction() const      { return mPhysicsFriction; }
-	inline F32      getPhysicsDensity() const       { return mPhysicsDensity; }
-	inline F32      getPhysicsRestitution() const   { return mPhysicsRestitution; }
-	
-	bool getIncludeInSearch() const;
-	void setIncludeInSearch(bool include_in_search);
-
-	// Does "open" object menu item apply?
-	BOOL allowOpen() const;
-
-	void setClickAction(U8 action) { mClickAction = action; }
-	U8 getClickAction() const { return mClickAction; }
-	bool specialHoverCursor() const;	// does it have a special hover cursor?
-
-	void			setRegion(LLViewerRegion *regionp);
-	virtual void	updateRegion(LLViewerRegion *regionp);
-
-	void updateFlags(BOOL physics_changed = FALSE);
-	BOOL setFlags(U32 flag, BOOL state);
-	void setPhysicsShapeType(U8 type);
-	void setPhysicsGravity(F32 gravity);
-	void setPhysicsFriction(F32 friction);
-	void setPhysicsDensity(F32 density);
-	void setPhysicsRestitution(F32 restitution);
-	
-	virtual void dump() const;
-	static U32		getNumZombieObjects()			{ return sNumZombieObjects; }
-
-	void printNameValuePairs() const;
-
-	virtual S32 getLOD() const { return 3; } 
-	virtual U32 getPartitionType() const;
-	virtual void dirtySpatialGroup(BOOL priority = FALSE) const;
-	virtual void dirtyMesh();
-
-	virtual LLNetworkData* getParameterEntry(U16 param_type) const;
-	virtual bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin);
-	virtual BOOL getParameterEntryInUse(U16 param_type) const;
-	virtual bool setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin);
-	// Called when a parameter is changed
-	virtual void parameterChanged(U16 param_type, bool local_origin);
-	virtual void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
-	
-	friend class LLViewerObjectList;
-	friend class LLViewerMediaList;
-
-public:
-	//counter-translation
-	void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE) ;
-	//counter-rotation
-	void resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations, 
-											const std::vector<LLVector3>& positions) ;
-	void saveUnselectedChildrenRotation(std::vector<LLQuaternion>& rotations) ;
-	void saveUnselectedChildrenPosition(std::vector<LLVector3>& positions) ;
-	std::vector<LLVector3> mUnselectedChildrenPositions ;
-
-private:
-	ExtraParameter* createNewParameterEntry(U16 param_type);
-	ExtraParameter* getExtraParameterEntry(U16 param_type) const;
-	ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
-	bool unpackParameterEntry(U16 param_type, LLDataPacker *dp);
-
-    // This function checks to see if the given media URL has changed its version
-    // and the update wasn't due to this agent's last action.
-    U32 checkMediaURL(const std::string &media_url);
-	
-	// Motion prediction between updates
-	void interpolateLinearMotion(const F64 & time, const F32 & dt);
-
-public:
-	//
-	// Viewer-side only types - use the LL_PCODE_APP mask.
-	//
-	typedef enum e_vo_types
-	{
-		LL_VO_CLOUDS =				LL_PCODE_APP | 0x20,
-		LL_VO_SURFACE_PATCH =		LL_PCODE_APP | 0x30,
-		LL_VO_WL_SKY =				LL_PCODE_APP | 0x40,
-		LL_VO_SQUARE_TORUS =		LL_PCODE_APP | 0x50,
-		LL_VO_SKY =					LL_PCODE_APP | 0x60,
-		LL_VO_VOID_WATER =			LL_PCODE_APP | 0x70,
-		LL_VO_WATER =				LL_PCODE_APP | 0x80,
-		LL_VO_GROUND =				LL_PCODE_APP | 0x90,
-		LL_VO_PART_GROUP =			LL_PCODE_APP | 0xa0,
-		LL_VO_TRIANGLE_TORUS =		LL_PCODE_APP | 0xb0,
-		LL_VO_HUD_PART_GROUP =		LL_PCODE_APP | 0xc0,
-	} EVOType;
-
-	typedef enum e_physics_shape_types
-	{
-		PHYSICS_SHAPE_PRIM = 0,
-		PHYSICS_SHAPE_NONE,
-		PHYSICS_SHAPE_CONVEX_HULL,
-	} EPhysicsShapeType;
-
-	LLUUID			mID;
-
-	// unique within region, not unique across regions
-	// Local ID = 0 is not used
-	U32				mLocalID;
-
-	// Last total CRC received from sim, used for caching
-	U32				mTotalCRC;
-
-	LLPointer<LLViewerTexture> *mTEImages;
-
-	// Selection, picking and rendering variables
-	U32				mGLName;			// GL "name" used by selection code
-	BOOL			mbCanSelect;		// true if user can select this object by clicking
-
-	// Grabbed from UPDATE_FLAGS
-	U32				mFlags;
-
-	// Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties
-	U8              mPhysicsShapeType;
-	F32             mPhysicsGravity;
-	F32             mPhysicsFriction;
-	F32             mPhysicsDensity;
-	F32             mPhysicsRestitution;
-	
-
-	// Pipeline classes
-	LLPointer<LLDrawable> mDrawable;
-
-	// Band-aid to select object after all creation initialization is done
-	BOOL mCreateSelected;
-
-	// Replace textures with web pages on this object while drawing
-	BOOL mRenderMedia;
-
-	// In bits
-	S32				mBestUpdatePrecision;
-
-	// TODO: Make all this stuff private.  JC
-	LLPointer<LLHUDText> mText;
-	LLPointer<LLHUDIcon> mIcon;
-
-	static			BOOL		sUseSharedDrawables;
-
-protected:
-	// delete an item in the inventory, but don't tell the
-	// server. This is used internally by remove, update, and
-	// savescript.
-	void deleteInventoryItem(const LLUUID& item_id);
-
-	// do the update/caching logic. called by saveScript and
-	// updateInventory.
-	void doUpdateInventory(LLPointer<LLViewerInventoryItem>& item, U8 key, bool is_new);
-
-
-	static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp);
-
-	BOOL setData(const U8 *datap, const U32 data_size);
-
-	// Hide or show HUD, icon and particles
-	void	hideExtraDisplayItems( BOOL hidden );
-
-	//////////////////////////
-	//
-	// inventory functionality
-	//
-
-	static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
-	void loadTaskInvFile(const std::string& filename);
-	void doInventoryCallback();
-	
-	BOOL isOnMap();
-
-	void unpackParticleSource(const S32 block_num, const LLUUID& owner_id);
-	void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id);
-	void deleteParticleSource();
-	void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
-	
-public:
-	void  updateQuota(  const SelectionQuota& quota );
-	const SelectionQuota& getQuota( void ) { return mSelectionQuota; }
-	
-private:
-	void setNameValueList(const std::string& list);		// clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
-	void deleteTEImages(); // correctly deletes list of images
-	
-protected:
-	typedef std::map<char *, LLNameValue *> name_value_map_t;
-	name_value_map_t mNameValuePairs;	// Any name-value pairs stored by script
-
-	child_list_t	mChildList;
-	
-	F64				mLastInterpUpdateSecs;			// Last update for purposes of interpolation
-	F64				mLastMessageUpdateSecs;			// Last update from a message from the simulator
-	TPACKETID		mLatestRecvPacketID;			// Latest time stamp on message from simulator
-
-	// extra data sent from the sim...currently only used for tree species info
-	U8* mData;
-
-	LLPointer<LLViewerPartSourceScript>		mPartSourcep;	// Particle source associated with this object.
-	LLAudioSourceVO* mAudioSourcep;
-	F32				mAudioGain;
-	
-	F32				mAppAngle;	// Apparent visual arc in degrees
-	F32				mPixelArea; // Apparent area in pixels
-
-	// This is the object's inventory from the viewer's perspective.
-	LLInventoryObject::object_list_t* mInventory;
-	class LLInventoryCallbackInfo
-	{
-	public:
-		~LLInventoryCallbackInfo();
-		LLVOInventoryListener* mListener;
-		void* mInventoryData;
-	};
-	typedef std::list<LLInventoryCallbackInfo*> callback_list_t;
-	callback_list_t mInventoryCallbacks;
-	S16 mInventorySerialNum;
-
-	LLViewerRegion	*mRegionp;					// Region that this object belongs to.
-	BOOL			mInventoryPending;
-	BOOL			mInventoryDirty;
-	BOOL			mDead;
-	BOOL			mOrphaned;					// This is an orphaned child
-	BOOL			mUserSelected;				// Cached user select information
-	BOOL			mOnActiveList;
-	BOOL			mOnMap;						// On the map.
-	BOOL			mStatic;					// Object doesn't move.
-	S32				mNumFaces;
-
-	F32				mTimeDilation;				// Time dilation sent with the object.
-	F32				mRotTime;					// Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega)
-	LLQuaternion	mLastRot;					// last rotation received from the simulator
-
-	LLVOJointInfo*  mJointInfo;
-	U8				mState;	// legacy
-	LLViewerObjectMedia* mMedia;	// NULL if no media associated
-	U8 mClickAction;
-	F32 mObjectCost; //resource cost of this object or -1 if unknown
-	F32 mLinksetCost;
-	F32 mPhysicsCost;
-	F32 mLinksetPhysicsCost;
-
-	SelectionQuota mSelectionQuota;
-	
-	bool mCostStale;
-	mutable bool mPhysicsShapeUnknown;
-
-	static			U32			sNumZombieObjects;			// Objects which are dead, but not deleted
-
-	static			BOOL		sMapDebug;					// Map render mode
-	static			LLColor4	sEditSelectColor;
-	static			LLColor4	sNoEditSelectColor;
-	static			F32			sCurrentPulse;
-	static			BOOL		sPulseEnabled;
-
-	static			S32			sAxisArrowLength;
-
-	// These two caches are only correct for non-parented objects right now!
-	mutable LLVector3		mPositionRegion;
-	mutable LLVector3		mPositionAgent;
-
-	static void setPhaseOutUpdateInterpolationTime(F32 value)	{ sPhaseOutUpdateInterpolationTime = (F64) value;	}
-	static void setMaxUpdateInterpolationTime(F32 value)		{ sMaxUpdateInterpolationTime = (F64) value;	}
-
-	static void	setVelocityInterpolate(BOOL value)		{ sVelocityInterpolate = value;	}
-	static void	setPingInterpolate(BOOL value)			{ sPingInterpolate = value;	}
-
-private:	
-	static S32 sNumObjects;
-
-	static F64 sPhaseOutUpdateInterpolationTime;	// For motion interpolation
-	static F64 sMaxUpdateInterpolationTime;			// For motion interpolation
-
-	static BOOL sVelocityInterpolate;
-	static BOOL sPingInterpolate;
-
-	//--------------------------------------------------------------------
-	// For objects that are attachments
-	//--------------------------------------------------------------------
-public:
-	const LLUUID &getAttachmentItemID() const;
-	void setAttachmentItemID(const LLUUID &id);
-	const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object
-	EObjectUpdateType getLastUpdateType() const;
-	void setLastUpdateType(EObjectUpdateType last_update_type);
-	BOOL getLastUpdateCached() const;
-	void setLastUpdateCached(BOOL last_update_cached);
-
-private:
-	LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
-	EObjectUpdateType	mLastUpdateType;
-	BOOL	mLastUpdateCached;
-};
-
-///////////////////
-//
-// Inlines
-//
-//
-
-inline void LLViewerObject::setRotation(const LLQuaternion& quat, BOOL damped)
-{
-	LLPrimitive::setRotation(quat);
-	setChanged(ROTATED | SILHOUETTE);
-	updateDrawable(damped);
-}
-
-inline void LLViewerObject::setRotation(const F32 x, const F32 y, const F32 z, BOOL damped)
-{
-	LLPrimitive::setRotation(x, y, z);
-	setChanged(ROTATED | SILHOUETTE);
-	updateDrawable(damped);
-}
-
-class LLViewerObjectMedia
-{
-public:
-	LLViewerObjectMedia() : mMediaURL(), mPassedWhitelist(FALSE), mMediaType(0) { }
-
-	std::string mMediaURL;	// for web pages on surfaces, one per prim
-	BOOL mPassedWhitelist;	// user has OK'd display
-	U8 mMediaType;			// see LLTextureEntry::WEB_PAGE, etc.
-};
-
-// subclass of viewer object that can be added to particle partitions
-class LLAlphaObject : public LLViewerObject
-{
-public:
-	LLAlphaObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-	: LLViewerObject(id,pcode,regionp) 
-	{ mDepth = 0.f; }
-
-	virtual F32 getPartSize(S32 idx);
-	virtual void getGeometry(S32 idx,
-								LLStrider<LLVector3>& verticesp,
-								LLStrider<LLVector3>& normalsp, 
-								LLStrider<LLVector2>& texcoordsp,
-								LLStrider<LLColor4U>& colorsp, 
-								LLStrider<U16>& indicesp) = 0;
-
-	F32 mDepth;
-};
-
-class LLStaticViewerObject : public LLViewerObject
-{
-public:
-	LLStaticViewerObject(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp, BOOL is_global = FALSE)
-		: LLViewerObject(id,pcode,regionp, is_global)
-	{ }
-
-	virtual void updateDrawable(BOOL force_damped);
-};
-
-
-#endif
+/** 
+ * @file llviewerobject.h
+ * @brief Description of LLViewerObject class, which is the base class for most objects in the viewer.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVIEWEROBJECT_H
+#define LL_LLVIEWEROBJECT_H
+
+#include <map>
+
+#include "llassetstorage.h"
+#include "lldarrayptr.h"
+#include "llhudicon.h"
+#include "llinventory.h"
+#include "llrefcount.h"
+#include "llmemtype.h"
+#include "llprimitive.h"
+#include "lluuid.h"
+#include "llvoinventorylistener.h"
+#include "object_flags.h"
+#include "llquaternion.h"
+#include "v3dmath.h"
+#include "v3math.h"
+#include "llvertexbuffer.h"
+#include "llaccountingquota.h"
+
+class LLAgent;			// TODO: Get rid of this.
+class LLAudioSource;
+class LLAudioSourceVO;
+class LLBBox;
+class LLDataPacker;
+class LLColor4;
+class LLFrameTimer;
+class LLDrawable;
+class LLHost;
+class LLHUDText;
+class LLWorld;
+class LLNameValue;
+class LLNetMap;
+class LLMessageSystem;
+class LLPartSysData;
+class LLPrimitive;
+class LLPipeline;
+class LLTextureEntry;
+class LLViewerTexture;
+class LLViewerInventoryItem;
+class LLViewerObject;
+class LLViewerPartSourceScript;
+class LLViewerRegion;
+class LLViewerObjectMedia;
+class LLVOInventoryListener;
+class LLVOAvatar;
+
+typedef enum e_object_update_type
+{
+	OUT_FULL,
+	OUT_TERSE_IMPROVED,
+	OUT_FULL_COMPRESSED,
+	OUT_FULL_CACHED,
+	OUT_UNKNOWN,
+} EObjectUpdateType;
+
+
+// callback typedef for inventory
+typedef void (*inventory_callback)(LLViewerObject*,
+								   LLInventoryObject::object_list_t*,
+								   S32 serial_num,
+								   void*);
+
+// a small struct for keeping track of joints
+struct LLVOJointInfo
+{
+	EHavokJointType mJointType;
+	LLVector3 mPivot;			// parent-frame
+	// whether the below an axis or anchor (and thus its frame)
+	// depends on the joint type:
+	//     HINGE   ==>   axis=parent-frame
+	//     P2P     ==>   anchor=child-frame
+	LLVector3 mAxisOrAnchor;	
+};
+
+// for exporting textured materials from SL
+struct LLMaterialExportInfo
+{
+public:
+	LLMaterialExportInfo(S32 mat_index, S32 texture_index, LLColor4 color) : 
+	  mMaterialIndex(mat_index), mTextureIndex(texture_index), mColor(color) {};
+
+	S32			mMaterialIndex;
+	S32			mTextureIndex;
+	LLColor4	mColor;
+};
+
+//============================================================================
+
+class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
+{
+protected:
+	~LLViewerObject(); // use unref()
+
+	// TomY: Provide for a list of extra parameter structures, mapped by structure name
+	struct ExtraParameter
+	{
+		BOOL in_use;
+		LLNetworkData *data;
+	};
+	std::map<U16, ExtraParameter*> mExtraParameterList;
+
+public:
+	typedef std::list<LLPointer<LLViewerObject> > child_list_t;
+	typedef std::list<LLPointer<LLViewerObject> > vobj_list_t;
+
+	typedef const child_list_t const_child_list_t;
+
+	LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global = FALSE);
+	MEM_TYPE_NEW(LLMemType::MTYPE_OBJECT);
+
+	virtual void markDead();				// Mark this object as dead, and clean up its references
+	BOOL isDead() const									{return mDead;}
+	BOOL isOrphaned() const								{ return mOrphaned; }
+	BOOL isParticleSource() const;
+
+	virtual LLVOAvatar* asAvatar();
+
+	static void initVOClasses();
+	static void cleanupVOClasses();
+
+	void			addNVPair(const std::string& data);
+	BOOL			removeNVPair(const std::string& name);
+	LLNameValue*	getNVPair(const std::string& name) const;			// null if no name value pair by that name
+
+	// Object create and update functions
+	virtual BOOL	idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+
+	// Types of media we can associate
+	enum { MEDIA_NONE = 0, MEDIA_SET = 1 };
+
+	// Return codes for processUpdateMessage
+	enum { 
+        MEDIA_URL_REMOVED = 0x1, 
+        MEDIA_URL_ADDED = 0x2, 
+        MEDIA_URL_UPDATED = 0x4, 
+        MEDIA_FLAGS_CHANGED = 0x8,
+        INVALID_UPDATE = 0x80000000
+    };
+
+	virtual U32		processUpdateMessage(LLMessageSystem *mesgsys,
+										void **user_data,
+										U32 block_num,
+										const EObjectUpdateType update_type,
+										LLDataPacker *dp);
+
+
+	virtual BOOL    isActive() const; // Whether this object needs to do an idleUpdate.
+	BOOL			onActiveList() const				{return mOnActiveList;}
+	void			setOnActiveList(BOOL on_active)		{ mOnActiveList = on_active; }
+
+	virtual BOOL	isAttachment() const { return FALSE; }
+	virtual LLVOAvatar* getAvatar() const;  //get the avatar this object is attached to, or NULL if object is not an attachment
+	virtual BOOL	isHUDAttachment() const { return FALSE; }
+	virtual void 	updateRadius() {};
+	virtual F32 	getVObjRadius() const; // default implemenation is mDrawable->getRadius()
+	
+	BOOL 			isJointChild() const { return mJointInfo ? TRUE : FALSE; } 
+	EHavokJointType	getJointType() const { return mJointInfo ? mJointInfo->mJointType : HJT_INVALID; }
+	// for jointed and other parent-relative hacks
+	LLViewerObject* getSubParent();
+	const LLViewerObject* getSubParent() const;
+	
+	// Object visiblility and GPW functions
+	virtual void setPixelAreaAndAngle(LLAgent &agent); // Override to generate accurate apparent angle and area
+
+	virtual U32 getNumVertices() const;
+	virtual U32 getNumIndices() const;
+	S32 getNumFaces() const { return mNumFaces; }
+
+	// Graphical stuff for objects - maybe broken out into render class later?
+	virtual void updateTextures();
+	virtual void boostTexturePriority(BOOL boost_children = TRUE);	// When you just want to boost priority of this object
+	
+	virtual LLDrawable* createDrawable(LLPipeline *pipeline);
+	virtual BOOL		updateGeometry(LLDrawable *drawable);
+	virtual void		updateGL();
+	virtual void		updateFaceSize(S32 idx);
+	virtual BOOL		updateLOD();
+	virtual BOOL		setDrawableParent(LLDrawable* parentp);
+	F32					getRotTime() { return mRotTime; }
+	void				resetRot();
+	void				applyAngularVelocity(F32 dt);
+
+	void setLineWidthForWindowSize(S32 window_width);
+
+	static void increaseArrowLength();				// makes axis arrows for selections longer
+	static void decreaseArrowLength();				// makes axis arrows for selections shorter
+
+	// Accessor functions
+	LLViewerRegion* getRegion() const				{ return mRegionp; }
+
+	BOOL isSelected() const							{ return mUserSelected; }
+	virtual void setSelected(BOOL sel)				{ mUserSelected = sel; mRotTime = 0.f;}
+
+	const LLUUID &getID() const						{ return mID; }
+	U32 getLocalID() const							{ return mLocalID; }
+	U32 getCRC() const								{ return mTotalCRC; }
+
+	virtual BOOL isFlexible() const					{ return FALSE; }
+	virtual BOOL isSculpted() const 				{ return FALSE; }
+	virtual BOOL isMesh() const						{ return FALSE; }
+	virtual BOOL hasLightTexture() const			{ return FALSE; }
+
+	// This method returns true if the object is over land owned by
+	// the agent, one of its groups, or it encroaches and 
+	// anti-encroachment is enabled
+	bool isReturnable();
+
+	/*
+	// This method will scan through this object, and then query the
+	// selection manager to see if the local agent probably has the
+	// ability to modify the object. Since this calls into the
+	// selection manager, you should avoid calling this method from
+	// there.
+	BOOL isProbablyModifiable() const;
+	*/
+
+	virtual BOOL setParent(LLViewerObject* parent);
+	virtual void addChild(LLViewerObject *childp);
+	virtual void removeChild(LLViewerObject *childp);
+	const_child_list_t& getChildren() const { 	return mChildList; }
+	S32 numChildren() const { return mChildList.size(); }
+	void addThisAndAllChildren(std::vector<LLViewerObject*>& objects);
+	void addThisAndNonJointChildren(std::vector<LLViewerObject*>& objects);
+	BOOL isChild(LLViewerObject *childp) const;
+	BOOL isSeat() const;
+	
+
+	//detect if given line segment (in agent space) intersects with this viewer object.
+	//returns TRUE if intersection detected and returns information about intersection
+	virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+									  S32 face = -1,                          // which face to check, -1 = ALL_SIDES
+									  BOOL pick_transparent = FALSE,
+									  S32* face_hit = NULL,                   // which face was hit
+									  LLVector3* intersection = NULL,         // return the intersection point
+									  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point
+									  LLVector3* normal = NULL,               // return the surface normal at the intersection point
+									  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point
+		);
+	
+	virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end);
+
+	virtual const LLVector3d getPositionGlobal() const;
+	virtual const LLVector3 &getPositionRegion() const;
+	virtual const LLVector3 getPositionEdit() const;
+	virtual const LLVector3 &getPositionAgent() const;
+	virtual const LLVector3 getRenderPosition() const;
+
+	virtual const LLVector3 getPivotPositionAgent() const; // Usually = to getPositionAgent, unless like flex objects it's not
+
+	LLViewerObject* getRootEdit() const;
+
+	const LLQuaternion getRotationRegion() const;
+	const LLQuaternion getRotationEdit() const;
+	const LLQuaternion getRenderRotation() const;
+	virtual	const LLMatrix4 getRenderMatrix() const;
+
+	void setPosition(const LLVector3 &pos, BOOL damped = FALSE);
+	void setPositionGlobal(const LLVector3d &position, BOOL damped = FALSE);
+	void setPositionRegion(const LLVector3 &position, BOOL damped = FALSE);
+	void setPositionEdit(const LLVector3 &position, BOOL damped = FALSE);
+	void setPositionAgent(const LLVector3 &pos_agent, BOOL damped = FALSE);
+	void setPositionParent(const LLVector3 &pos_parent, BOOL damped = FALSE);
+	void setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped = FALSE );
+
+	virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const		{ return xform->getWorldMatrix(); }
+
+	inline void setRotation(const F32 x, const F32 y, const F32 z, BOOL damped = FALSE);
+	inline void setRotation(const LLQuaternion& quat, BOOL damped = FALSE);
+	void sendRotationUpdate() const;
+
+	/*virtual*/	void	setNumTEs(const U8 num_tes);
+	/*virtual*/	void	setTE(const U8 te, const LLTextureEntry &texture_entry);
+	/*virtual*/ S32		setTETexture(const U8 te, const LLUUID &uuid);
+	S32 setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host);
+	/*virtual*/ S32		setTEColor(const U8 te, const LLColor3 &color);
+	/*virtual*/ S32		setTEColor(const U8 te, const LLColor4 &color);
+	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t);
+	/*virtual*/ S32		setTEScaleS(const U8 te, const F32 s);
+	/*virtual*/ S32		setTEScaleT(const U8 te, const F32 t);
+	/*virtual*/ S32		setTEOffset(const U8 te, const F32 s, const F32 t);
+	/*virtual*/ S32		setTEOffsetS(const U8 te, const F32 s);
+	/*virtual*/ S32		setTEOffsetT(const U8 te, const F32 t);
+	/*virtual*/ S32		setTERotation(const U8 te, const F32 r);
+	/*virtual*/	S32		setTEBumpmap(const U8 te, const U8 bump );
+	/*virtual*/	S32		setTETexGen(const U8 te, const U8 texgen );
+	/*virtual*/	S32		setTEMediaTexGen(const U8 te, const U8 media ); // *FIXME: this confusingly acts upon a superset of setTETexGen's flags without absorbing its semantics
+	/*virtual*/	S32		setTEShiny(const U8 te, const U8 shiny );
+	/*virtual*/	S32		setTEFullbright(const U8 te, const U8 fullbright );
+	/*virtual*/	S32		setTEMediaFlags(const U8 te, const U8 media_flags );
+	/*virtual*/ S32     setTEGlow(const U8 te, const F32 glow);
+	/*virtual*/	BOOL	setMaterial(const U8 material);
+	virtual		void	setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
+	void                changeTEImage(S32 index, LLViewerTexture* new_image)  ;
+	LLViewerTexture		*getTEImage(const U8 te) const;
+	
+	void fitFaceTexture(const U8 face);
+	void sendTEUpdate() const;			// Sends packed representation of all texture entry information
+	
+	virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE);
+
+	virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL);
+	virtual U32 getTriangleCount();
+	virtual U32 getHighLODTriangleCount();
+
+	void setObjectCost(F32 cost);
+	F32 getObjectCost();
+	
+	void setLinksetCost(F32 cost);
+	F32 getLinksetCost();
+	
+	void setPhysicsCost(F32 cost);
+	F32 getPhysicsCost();
+	
+	void setLinksetPhysicsCost(F32 cost);
+	F32 getLinksetPhysicsCost();
+
+	void sendShapeUpdate();
+
+	U8 getState()							{ return mState; }
+
+	F32 getAppAngle() const					{ return mAppAngle; }
+	F32 getPixelArea() const				{ return mPixelArea; }
+	void setPixelArea(F32 area)				{ mPixelArea = area; }
+	F32 getMaxScale() const;
+	F32 getMidScale() const;
+	F32 getMinScale() const;
+
+	// Owner id is this object's owner
+	void setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags);
+	void adjustAudioGain(const F32 gain);
+	void clearAttachedSound()								{ mAudioSourcep = NULL; }
+
+	 // Create if necessary
+	LLAudioSource *getAudioSource(const LLUUID& owner_id);
+	bool isAudioSource() {return mAudioSourcep != NULL;}
+
+	U8 getMediaType() const;
+	void setMediaType(U8 media_type);
+
+	std::string getMediaURL() const;
+	void setMediaURL(const std::string& media_url);
+
+	BOOL getMediaPassedWhitelist() const;
+	void setMediaPassedWhitelist(BOOL passed);
+
+	void sendMaterialUpdate() const;
+
+	void setCanSelect(BOOL canSelect);
+
+	void setDebugText(const std::string &utf8text);
+	void setIcon(LLViewerTexture* icon_image);
+	void clearIcon();
+
+	void markForUpdate(BOOL priority);
+	void updateVolume(const LLVolumeParams& volume_params);
+	virtual	void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
+	virtual F32 getBinRadius();
+	
+	LLBBox				getBoundingBoxAgent() const;
+
+	void updatePositionCaches() const; // Update the global and region position caches from the object (and parent's) xform.
+	void updateText(); // update text label position
+	virtual void updateDrawable(BOOL force_damped); // force updates on static objects
+
+	void setDrawableState(U32 state, BOOL recursive = TRUE);
+	void clearDrawableState(U32 state, BOOL recursive = TRUE);
+
+	// Called when the drawable shifts
+	virtual void onShift(const LLVector4a &shift_vector)	{ }
+		
+	//////////////////////////////////////
+	//
+	// Inventory methods
+	//
+
+	// This function is called when someone is interested in a viewer
+	// object's inventory. The callback is called as soon as the
+	// viewer object has the inventory stored locally.
+	void registerInventoryListener(LLVOInventoryListener* listener, void* user_data);
+	void removeInventoryListener(LLVOInventoryListener* listener);
+	BOOL isInventoryPending() { return mInventoryPending; }
+	void clearInventoryListeners();
+	void requestInventory();
+	void fetchInventoryFromServer();
+	static void processTaskInv(LLMessageSystem* msg, void** user_data);
+	void removeInventory(const LLUUID& item_id);
+
+	// The updateInventory() call potentially calls into the selection
+	// manager, so do no call updateInventory() from the selection
+	// manager until we have better iterators.
+	void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
+	void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
+	LLInventoryObject* getInventoryObject(const LLUUID& item_id);
+	void getInventoryContents(LLInventoryObject::object_list_t& objects);
+	LLInventoryObject* getInventoryRoot();
+	LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
+	S16 getInventorySerial() const { return mInventorySerialNum; }
+
+	// These functions does viewer-side only object inventory modifications
+	void updateViewerInventoryAsset(
+		const LLViewerInventoryItem* item,
+		const LLUUID& new_asset);
+
+	// This function will make sure that we refresh the inventory.
+	void dirtyInventory();
+	BOOL isInventoryDirty() { return mInventoryDirty; }
+
+	// save a script, which involves removing the old one, and rezzing
+	// in the new one. This method should be called with the asset id
+	// of the new and old script AFTER the bytecode has been saved.
+	void saveScript(const LLViewerInventoryItem* item, BOOL active, bool is_new);
+
+	// move an inventory item out of the task and into agent
+	// inventory. This operation is based on messaging. No permissions
+	// checks are made on the viewer - the server will double check.
+	void moveInventory(const LLUUID& agent_folder, const LLUUID& item_id);
+
+	// Find the number of instances of this object's inventory that are of the given type
+	S32 countInventoryContents( LLAssetType::EType type );
+
+	BOOL			permAnyOwner() const;	
+	BOOL			permYouOwner() const;
+	BOOL			permGroupOwner() const;
+	BOOL			permOwnerModify() const;
+	BOOL			permModify() const;	
+	BOOL			permCopy() const;	
+	BOOL			permMove() const;		
+	BOOL			permTransfer() const;
+	inline BOOL		usePhysics() const				{ return ((mFlags & FLAGS_USE_PHYSICS) != 0); }
+	inline BOOL		flagScripted() const			{ return ((mFlags & FLAGS_SCRIPTED) != 0); }
+	inline BOOL		flagHandleTouch() const			{ return ((mFlags & FLAGS_HANDLE_TOUCH) != 0); }
+	inline BOOL		flagTakesMoney() const			{ return ((mFlags & FLAGS_TAKES_MONEY) != 0); }
+	inline BOOL		flagPhantom() const				{ return ((mFlags & FLAGS_PHANTOM) != 0); }
+	inline BOOL		flagInventoryEmpty() const		{ return ((mFlags & FLAGS_INVENTORY_EMPTY) != 0); }
+	inline BOOL		flagCastShadows() const			{ return ((mFlags & FLAGS_CAST_SHADOWS) != 0); }
+	inline BOOL		flagAllowInventoryAdd() const	{ return ((mFlags & FLAGS_ALLOW_INVENTORY_DROP) != 0); }
+	inline BOOL		flagTemporary() const			{ return ((mFlags & FLAGS_TEMPORARY) != 0); }
+	inline BOOL		flagTemporaryOnRez() const		{ return ((mFlags & FLAGS_TEMPORARY_ON_REZ) != 0); }
+	inline BOOL		flagAnimSource() const			{ return ((mFlags & FLAGS_ANIM_SOURCE) != 0); }
+	inline BOOL		flagCameraSource() const		{ return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); }
+	inline BOOL		flagCameraDecoupled() const		{ return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); }
+	inline BOOL		flagObjectMove() const			{ return ((mFlags & FLAGS_OBJECT_MOVE) != 0); }
+
+	U8       getPhysicsShapeType() const;
+	inline F32      getPhysicsGravity() const       { return mPhysicsGravity; }
+	inline F32      getPhysicsFriction() const      { return mPhysicsFriction; }
+	inline F32      getPhysicsDensity() const       { return mPhysicsDensity; }
+	inline F32      getPhysicsRestitution() const   { return mPhysicsRestitution; }
+	
+	bool getIncludeInSearch() const;
+	void setIncludeInSearch(bool include_in_search);
+
+	// Does "open" object menu item apply?
+	BOOL allowOpen() const;
+
+	void setClickAction(U8 action) { mClickAction = action; }
+	U8 getClickAction() const { return mClickAction; }
+	bool specialHoverCursor() const;	// does it have a special hover cursor?
+
+	void			setRegion(LLViewerRegion *regionp);
+	virtual void	updateRegion(LLViewerRegion *regionp);
+
+	void updateFlags(BOOL physics_changed = FALSE);
+	BOOL setFlags(U32 flag, BOOL state);
+	void setPhysicsShapeType(U8 type);
+	void setPhysicsGravity(F32 gravity);
+	void setPhysicsFriction(F32 friction);
+	void setPhysicsDensity(F32 density);
+	void setPhysicsRestitution(F32 restitution);
+	
+	virtual void dump() const;
+	static U32		getNumZombieObjects()			{ return sNumZombieObjects; }
+
+	void printNameValuePairs() const;
+
+	virtual S32 getLOD() const { return 3; } 
+	virtual U32 getPartitionType() const;
+	virtual void dirtySpatialGroup(BOOL priority = FALSE) const;
+	virtual void dirtyMesh();
+
+	virtual LLNetworkData* getParameterEntry(U16 param_type) const;
+	virtual bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin);
+	virtual BOOL getParameterEntryInUse(U16 param_type) const;
+	virtual bool setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin);
+	// Called when a parameter is changed
+	virtual void parameterChanged(U16 param_type, bool local_origin);
+	virtual void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
+	
+	friend class LLViewerObjectList;
+	friend class LLViewerMediaList;
+
+public:
+	//counter-translation
+	void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE) ;
+	//counter-rotation
+	void resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations, 
+											const std::vector<LLVector3>& positions) ;
+	void saveUnselectedChildrenRotation(std::vector<LLQuaternion>& rotations) ;
+	void saveUnselectedChildrenPosition(std::vector<LLVector3>& positions) ;
+	std::vector<LLVector3> mUnselectedChildrenPositions ;
+
+private:
+	ExtraParameter* createNewParameterEntry(U16 param_type);
+	ExtraParameter* getExtraParameterEntry(U16 param_type) const;
+	ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
+	bool unpackParameterEntry(U16 param_type, LLDataPacker *dp);
+
+    // This function checks to see if the given media URL has changed its version
+    // and the update wasn't due to this agent's last action.
+    U32 checkMediaURL(const std::string &media_url);
+	
+	// Motion prediction between updates
+	void interpolateLinearMotion(const F64 & time, const F32 & dt);
+
+public:
+	//
+	// Viewer-side only types - use the LL_PCODE_APP mask.
+	//
+	typedef enum e_vo_types
+	{
+		LL_VO_CLOUDS =				LL_PCODE_APP | 0x20,
+		LL_VO_SURFACE_PATCH =		LL_PCODE_APP | 0x30,
+		LL_VO_WL_SKY =				LL_PCODE_APP | 0x40,
+		LL_VO_SQUARE_TORUS =		LL_PCODE_APP | 0x50,
+		LL_VO_SKY =					LL_PCODE_APP | 0x60,
+		LL_VO_VOID_WATER =			LL_PCODE_APP | 0x70,
+		LL_VO_WATER =				LL_PCODE_APP | 0x80,
+		LL_VO_GROUND =				LL_PCODE_APP | 0x90,
+		LL_VO_PART_GROUP =			LL_PCODE_APP | 0xa0,
+		LL_VO_TRIANGLE_TORUS =		LL_PCODE_APP | 0xb0,
+		LL_VO_HUD_PART_GROUP =		LL_PCODE_APP | 0xc0,
+	} EVOType;
+
+	typedef enum e_physics_shape_types
+	{
+		PHYSICS_SHAPE_PRIM = 0,
+		PHYSICS_SHAPE_NONE,
+		PHYSICS_SHAPE_CONVEX_HULL,
+	} EPhysicsShapeType;
+
+	LLUUID			mID;
+
+	// unique within region, not unique across regions
+	// Local ID = 0 is not used
+	U32				mLocalID;
+
+	// Last total CRC received from sim, used for caching
+	U32				mTotalCRC;
+
+	LLPointer<LLViewerTexture> *mTEImages;
+
+	// Selection, picking and rendering variables
+	U32				mGLName;			// GL "name" used by selection code
+	BOOL			mbCanSelect;		// true if user can select this object by clicking
+
+	// Grabbed from UPDATE_FLAGS
+	U32				mFlags;
+
+	// Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties
+	U8              mPhysicsShapeType;
+	F32             mPhysicsGravity;
+	F32             mPhysicsFriction;
+	F32             mPhysicsDensity;
+	F32             mPhysicsRestitution;
+	
+
+	// Pipeline classes
+	LLPointer<LLDrawable> mDrawable;
+
+	// Band-aid to select object after all creation initialization is done
+	BOOL mCreateSelected;
+
+	// Replace textures with web pages on this object while drawing
+	BOOL mRenderMedia;
+
+	// In bits
+	S32				mBestUpdatePrecision;
+
+	// TODO: Make all this stuff private.  JC
+	LLPointer<LLHUDText> mText;
+	LLPointer<LLHUDIcon> mIcon;
+
+	static			BOOL		sUseSharedDrawables;
+
+protected:
+	// delete an item in the inventory, but don't tell the
+	// server. This is used internally by remove, update, and
+	// savescript.
+	void deleteInventoryItem(const LLUUID& item_id);
+
+	// do the update/caching logic. called by saveScript and
+	// updateInventory.
+	void doUpdateInventory(LLPointer<LLViewerInventoryItem>& item, U8 key, bool is_new);
+
+
+	static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp);
+
+	BOOL setData(const U8 *datap, const U32 data_size);
+
+	// Hide or show HUD, icon and particles
+	void	hideExtraDisplayItems( BOOL hidden );
+
+	//////////////////////////
+	//
+	// inventory functionality
+	//
+
+	static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
+	void loadTaskInvFile(const std::string& filename);
+	void doInventoryCallback();
+	
+	BOOL isOnMap();
+
+	void unpackParticleSource(const S32 block_num, const LLUUID& owner_id);
+	void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id);
+	void deleteParticleSource();
+	void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
+	
+public:
+	void  updateQuota(  const SelectionQuota& quota );
+	const SelectionQuota& getQuota( void ) { return mSelectionQuota; }
+	
+private:
+	void setNameValueList(const std::string& list);		// clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
+	void deleteTEImages(); // correctly deletes list of images
+	
+protected:
+	typedef std::map<char *, LLNameValue *> name_value_map_t;
+	name_value_map_t mNameValuePairs;	// Any name-value pairs stored by script
+
+	child_list_t	mChildList;
+	
+	F64				mLastInterpUpdateSecs;			// Last update for purposes of interpolation
+	F64				mLastMessageUpdateSecs;			// Last update from a message from the simulator
+	TPACKETID		mLatestRecvPacketID;			// Latest time stamp on message from simulator
+
+	// extra data sent from the sim...currently only used for tree species info
+	U8* mData;
+
+	LLPointer<LLViewerPartSourceScript>		mPartSourcep;	// Particle source associated with this object.
+	LLAudioSourceVO* mAudioSourcep;
+	F32				mAudioGain;
+	
+	F32				mAppAngle;	// Apparent visual arc in degrees
+	F32				mPixelArea; // Apparent area in pixels
+
+	// This is the object's inventory from the viewer's perspective.
+	LLInventoryObject::object_list_t* mInventory;
+	class LLInventoryCallbackInfo
+	{
+	public:
+		~LLInventoryCallbackInfo();
+		LLVOInventoryListener* mListener;
+		void* mInventoryData;
+	};
+	typedef std::list<LLInventoryCallbackInfo*> callback_list_t;
+	callback_list_t mInventoryCallbacks;
+	S16 mInventorySerialNum;
+
+	LLViewerRegion	*mRegionp;					// Region that this object belongs to.
+	BOOL			mInventoryPending;
+	BOOL			mInventoryDirty;
+	BOOL			mDead;
+	BOOL			mOrphaned;					// This is an orphaned child
+	BOOL			mUserSelected;				// Cached user select information
+	BOOL			mOnActiveList;
+	BOOL			mOnMap;						// On the map.
+	BOOL			mStatic;					// Object doesn't move.
+	S32				mNumFaces;
+
+	F32				mTimeDilation;				// Time dilation sent with the object.
+	F32				mRotTime;					// Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega)
+	LLQuaternion	mLastRot;					// last rotation received from the simulator
+
+	LLVOJointInfo*  mJointInfo;
+	U8				mState;	// legacy
+	LLViewerObjectMedia* mMedia;	// NULL if no media associated
+	U8 mClickAction;
+	F32 mObjectCost; //resource cost of this object or -1 if unknown
+	F32 mLinksetCost;
+	F32 mPhysicsCost;
+	F32 mLinksetPhysicsCost;
+
+	SelectionQuota mSelectionQuota;
+	
+	bool mCostStale;
+	mutable bool mPhysicsShapeUnknown;
+
+	static			U32			sNumZombieObjects;			// Objects which are dead, but not deleted
+
+	static			BOOL		sMapDebug;					// Map render mode
+	static			LLColor4	sEditSelectColor;
+	static			LLColor4	sNoEditSelectColor;
+	static			F32			sCurrentPulse;
+	static			BOOL		sPulseEnabled;
+
+	static			S32			sAxisArrowLength;
+
+	// These two caches are only correct for non-parented objects right now!
+	mutable LLVector3		mPositionRegion;
+	mutable LLVector3		mPositionAgent;
+
+	static void setPhaseOutUpdateInterpolationTime(F32 value)	{ sPhaseOutUpdateInterpolationTime = (F64) value;	}
+	static void setMaxUpdateInterpolationTime(F32 value)		{ sMaxUpdateInterpolationTime = (F64) value;	}
+
+	static void	setVelocityInterpolate(BOOL value)		{ sVelocityInterpolate = value;	}
+	static void	setPingInterpolate(BOOL value)			{ sPingInterpolate = value;	}
+
+private:	
+	static S32 sNumObjects;
+
+	static F64 sPhaseOutUpdateInterpolationTime;	// For motion interpolation
+	static F64 sMaxUpdateInterpolationTime;			// For motion interpolation
+
+	static BOOL sVelocityInterpolate;
+	static BOOL sPingInterpolate;
+
+	//--------------------------------------------------------------------
+	// For objects that are attachments
+	//--------------------------------------------------------------------
+public:
+	const LLUUID &getAttachmentItemID() const;
+	void setAttachmentItemID(const LLUUID &id);
+	const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object
+	EObjectUpdateType getLastUpdateType() const;
+	void setLastUpdateType(EObjectUpdateType last_update_type);
+	BOOL getLastUpdateCached() const;
+	void setLastUpdateCached(BOOL last_update_cached);
+
+private:
+	LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
+	EObjectUpdateType	mLastUpdateType;
+	BOOL	mLastUpdateCached;
+};
+
+///////////////////
+//
+// Inlines
+//
+//
+
+inline void LLViewerObject::setRotation(const LLQuaternion& quat, BOOL damped)
+{
+	LLPrimitive::setRotation(quat);
+	setChanged(ROTATED | SILHOUETTE);
+	updateDrawable(damped);
+}
+
+inline void LLViewerObject::setRotation(const F32 x, const F32 y, const F32 z, BOOL damped)
+{
+	LLPrimitive::setRotation(x, y, z);
+	setChanged(ROTATED | SILHOUETTE);
+	updateDrawable(damped);
+}
+
+class LLViewerObjectMedia
+{
+public:
+	LLViewerObjectMedia() : mMediaURL(), mPassedWhitelist(FALSE), mMediaType(0) { }
+
+	std::string mMediaURL;	// for web pages on surfaces, one per prim
+	BOOL mPassedWhitelist;	// user has OK'd display
+	U8 mMediaType;			// see LLTextureEntry::WEB_PAGE, etc.
+};
+
+// subclass of viewer object that can be added to particle partitions
+class LLAlphaObject : public LLViewerObject
+{
+public:
+	LLAlphaObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
+	: LLViewerObject(id,pcode,regionp) 
+	{ mDepth = 0.f; }
+
+	virtual F32 getPartSize(S32 idx);
+	virtual void getGeometry(S32 idx,
+								LLStrider<LLVector3>& verticesp,
+								LLStrider<LLVector3>& normalsp, 
+								LLStrider<LLVector2>& texcoordsp,
+								LLStrider<LLColor4U>& colorsp, 
+								LLStrider<U16>& indicesp) = 0;
+
+	F32 mDepth;
+};
+
+class LLStaticViewerObject : public LLViewerObject
+{
+public:
+	LLStaticViewerObject(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp, BOOL is_global = FALSE)
+		: LLViewerObject(id,pcode,regionp, is_global)
+	{ }
+
+	virtual void updateDrawable(BOOL force_damped);
+};
+
+
+#endif
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 5ae4e872f3..8db72da1ee 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -2202,9 +2202,9 @@ bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const
 		= parcelOwner == (forGroup ? gAgent.getGroupID() : gAgent.getID());
 	
 	bool isAuthorized
-			= (authorizeBuyer.isNull()
-				|| (gAgent.getID() == authorizeBuyer)
-				|| (gAgent.hasPowerInGroup(authorizeBuyer,GP_LAND_DEED)
+			= (authorizeBuyer.isNull()
+				|| (gAgent.getID() == authorizeBuyer)
+				|| (gAgent.hasPowerInGroup(authorizeBuyer,GP_LAND_DEED)
 					&& gAgent.hasPowerInGroup(authorizeBuyer,GP_LAND_SET_SALE_INFO)));
 	
 	return isForSale && !isOwner && isAuthorized  && isEmpowered;
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index 45c9b3e91f..faa86d43dd 100644
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -118,8 +118,8 @@
 
 // Library includes from llvfs
 #include "lldir.h"
-
-// Library includes from llmessage project
+
+// Library includes from llmessage project
 #include "llcachename.h"
 
 #endif
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index d9ff931575..cd6653b0c7 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -110,8 +110,8 @@ void LLViewerTextureList::doPreloadImages()
 {
 	LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL;
 	
-	llassert_always(mInitialized) ;
-	llassert_always(mImageList.empty()) ;
+	llassert_always(mInitialized) ;
+	llassert_always(mImageList.empty()) ;
 	llassert_always(mUUIDMap.empty()) ;
 
 	// Set the "missing asset" image
-- 
cgit v1.2.3