summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/CMakeLists.txt1
-rw-r--r--indra/llcommon/llaccountingquota.h78
-rw-r--r--indra/llinventory/llparcel.cpp9
-rw-r--r--indra/llinventory/llparcel.h13
-rw-r--r--indra/llprimitive/llmodel.cpp31
-rw-r--r--indra/llprimitive/llmodel.h1
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llaccountingquotamanager.cpp264
-rw-r--r--indra/newview/llaccountingquotamanager.h60
-rw-r--r--indra/newview/llfloatermodelpreview.cpp25
-rw-r--r--indra/newview/llfloatermodelwizard.cpp25
-rw-r--r--indra/newview/llfloatertools.cpp1
-rw-r--r--indra/newview/llinventorymodel.cpp2
-rw-r--r--indra/newview/llmeshrepository.cpp238
-rw-r--r--indra/newview/llmeshrepository.h10
-rw-r--r--indra/newview/llviewerobject.cpp8
-rw-r--r--indra/newview/llviewerobject.h9
-rw-r--r--indra/newview/llviewerobjectlist.cpp9
-rw-r--r--indra/newview/llviewerobjectlist.h3
-rw-r--r--indra/newview/llviewerregion.cpp6
-rw-r--r--indra/newview/llviewerregion.h1
-rw-r--r--indra/newview/llvoavatar.cpp23
22 files changed, 704 insertions, 115 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 80df91a5c1..9910281b64 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -115,6 +115,7 @@ set(llcommon_HEADER_FILES
indra_constants.h
linden_common.h
linked_lists.h
+ llaccountingquota.h
llallocator.h
llallocator_heap_profile.h
llagentconstants.h
diff --git a/indra/llcommon/llaccountingquota.h b/indra/llcommon/llaccountingquota.h
new file mode 100644
index 0000000000..f52d94f868
--- /dev/null
+++ b/indra/llcommon/llaccountingquota.h
@@ -0,0 +1,78 @@
+/**
+ * @file llaccountingquota.h
+ * @
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, 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$
+ */
+
+#ifndef LL_ACCOUNTINGQUOTA_H
+#define LL_ACCOUNTINGQUOTA_H
+
+struct ParcelQuota
+{
+ ParcelQuota( F32 ownerRenderCost, F32 ownerPhysicsCost, F32 ownerNetworkCost, F32 ownerSimulationCost,
+ F32 groupRenderCost, F32 groupPhysicsCost, F32 groupNetworkCost, F32 groupSimulationCost,
+ F32 otherRenderCost, F32 otherPhysicsCost, F32 otherNetworkCost, F32 otherSimulationCost,
+ F32 totalRenderCost, F32 totalPhysicsCost, F32 totalNetworkCost, F32 totalSimulationCost)
+ : mOwnerRenderCost( ownerRenderCost ), mOwnerPhysicsCost( ownerPhysicsCost )
+ , mOwnerNetworkCost( ownerNetworkCost ), mOwnerSimulationCost( ownerSimulationCost )
+ , mGroupRenderCost( groupRenderCost ), mGroupPhysicsCost( groupPhysicsCost )
+ , mGroupNetworkCost( groupNetworkCost ), mGroupSimulationCost( groupSimulationCost )
+ , mOtherRenderCost( otherRenderCost ), mOtherPhysicsCost( otherPhysicsCost )
+ , mOtherNetworkCost( otherNetworkCost ), mOtherSimulationCost( otherSimulationCost )
+ , mTotalRenderCost( totalRenderCost ), mTotalPhysicsCost( totalPhysicsCost )
+ , mTotalNetworkCost( totalNetworkCost ), mTotalSimulationCost( totalSimulationCost )
+ {
+ }
+ ParcelQuota(){}
+ F32 mOwnerRenderCost, mOwnerPhysicsCost, mOwnerNetworkCost, mOwnerSimulationCost;
+ F32 mGroupRenderCost, mGroupPhysicsCost, mGroupNetworkCost, mGroupSimulationCost;
+ F32 mOtherRenderCost, mOtherPhysicsCost, mOtherNetworkCost, mOtherSimulationCost;
+ F32 mTotalRenderCost, mTotalPhysicsCost, mTotalNetworkCost, mTotalSimulationCost;
+};
+
+struct SelectionQuota
+{
+ SelectionQuota( S32 localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost )
+ : mLocalId( localId)
+ , mRenderCost( renderCost )
+ , mPhysicsCost( physicsCost )
+ , mNetworkCost( networkCost )
+ , mSimulationCost( simulationCost )
+ {
+ }
+ SelectionQuota() {}
+
+ F32 mRenderCost, mPhysicsCost, mNetworkCost, mSimulationCost;
+ S32 mLocalId;
+};
+
+#endif
+
+
+
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index 0a4cd51ea0..e8cd871157 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -1348,3 +1348,12 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s)
// is a distinct option from "None" and "Other"
return LLParcel::C_ANY;
}
+
+void LLParcel::updateQuota( const LLUUID& objectId, const ParcelQuota& quota )
+{
+ if ( mID == objectId )
+ {
+ mQuota = quota;
+ }
+}
+
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index 71b65d99ce..4893337967 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -34,7 +34,7 @@
#include "llpermissions.h"
#include "lltimer.h"
#include "v3math.h"
-
+#include "llaccountingquota.h"
// Grid out of which parcels taken is stepped every 4 meters.
const F32 PARCEL_GRID_STEP_METERS = 4.f;
@@ -586,7 +586,11 @@ public:
LLUUID getPreviousOwnerID() const { return mPreviousOwnerID; }
BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; }
BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; }
-
+
+
+ void updateQuota( const LLUUID& objectId, const ParcelQuota& quota );
+ const ParcelQuota& getQuota( void ) { return mQuota; }
+
protected:
LLUUID mID;
LLUUID mOwnerID;
@@ -657,8 +661,9 @@ protected:
BOOL mRegionPushOverride;
BOOL mRegionDenyAnonymousOverride;
BOOL mRegionDenyAgeUnverifiedOverride;
-
-
+
+ ParcelQuota mQuota;
+
public:
// HACK, make private
S32 mLocalID;
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 57ac7a143f..030a61cd55 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1778,7 +1778,7 @@ void LLModel::updateHullCenters()
if (mHullPoints > 0)
{
mCenterOfHullCenters *= 1.f / mHullPoints;
- llassert(mPhysics.asLLSD().has("HullList"));
+ llassert(mPhysics.hasHullList());
}
}
@@ -2127,6 +2127,11 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
}
}
+bool LLModel::Decomposition::hasHullList() const
+{
+ return !mHull.empty() ;
+}
+
LLSD LLModel::Decomposition::asLLSD() const
{
LLSD ret;
@@ -2208,14 +2213,17 @@ LLSD LLModel::Decomposition::asLLSD() const
//convert to 16-bit normalized across domain
U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535);
- switch (k)
+ if(valid.size() < 3)
{
- case 0: test = test | (U64) val; break;
- case 1: test = test | ((U64) val << 16); break;
- case 2: test = test | ((U64) val << 32); break;
- };
+ switch (k)
+ {
+ case 0: test = test | (U64) val; break;
+ case 1: test = test | ((U64) val << 16); break;
+ case 2: test = test | ((U64) val << 32); break;
+ };
- valid.insert(test);
+ valid.insert(test);
+ }
U8* buff = (U8*) &val;
//write to binary buffer
@@ -2227,8 +2235,8 @@ LLSD LLModel::Decomposition::asLLSD() const
}
}
- //must have at least 4 unique points
- llassert(valid.size() > 3);
+ //must have at least 3 unique points
+ llassert(valid.size() > 2);
}
ret["Position"] = p;
@@ -2290,10 +2298,5 @@ void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs)
{ //take physics shape mesh from rhs
mPhysicsShapeMesh = rhs->mPhysicsShapeMesh;
}
-
- if (!mHull.empty())
- { //verify
- llassert(asLLSD().has("HullList"));
- }
}
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 23f4b5cb42..ebca1f9d9d 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -106,6 +106,7 @@ public:
Decomposition(LLSD& data);
void fromLLSD(LLSD& data);
LLSD asLLSD() const;
+ bool hasHullList() const;
void merge(const Decomposition* rhs);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index cbf22b75e8..769dcf8457 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -77,6 +77,7 @@ include_directories(
set(viewer_SOURCE_FILES
groupchatlistener.cpp
+ llaccountingquotamanager.cpp
llagent.cpp
llagentaccess.cpp
llagentcamera.cpp
@@ -626,6 +627,7 @@ set(viewer_HEADER_FILES
CMakeLists.txt
ViewerInstall.cmake
groupchatlistener.h
+ llaccountingquotamanager.h
llagent.h
llagentaccess.h
llagentcamera.h
diff --git a/indra/newview/llaccountingquotamanager.cpp b/indra/newview/llaccountingquotamanager.cpp
new file mode 100644
index 0000000000..ada74ea44c
--- /dev/null
+++ b/indra/newview/llaccountingquotamanager.cpp
@@ -0,0 +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 );
+}
+//===============================================================================
diff --git a/indra/newview/llaccountingquotamanager.h b/indra/newview/llaccountingquotamanager.h
new file mode 100644
index 0000000000..f605d1e6b2
--- /dev/null
+++ b/indra/newview/llaccountingquotamanager.h
@@ -0,0 +1,60 @@
+/**
+ * @file lllAccountingQuotaManager.h
+ * @
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, 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$
+ */
+
+#ifndef LL_ACCOUNTINGQUOTAMANAGER_H
+#define LL_ACCOUNTINGQUOTAMANAGER_H
+//===============================================================================
+#include "llaccountingquota.h"
+//===============================================================================
+class LLAccountingQuotaManager : public LLSingleton<LLAccountingQuotaManager>
+{
+public:
+ //Ctor
+ LLAccountingQuotaManager();
+ //Store an object that will be eventually fetched
+ void updateObjectCost( const LLUUID& objectID );
+ //Request quotas for object list
+ void fetchQuotas( const std::string& url );
+ //Delete a specific object from the pending list
+ void removePendingObjectQuota( const LLUUID& objectID );
+
+private:
+ //Set of objects that need to update their cost
+ std::set<LLUUID> mUpdateObjectQuota;
+ //During fetchQuota we move object into a the pending set to signify that
+ //a fetch has been instigated.
+ std::set<LLUUID> mPendingObjectQuota;
+ typedef std::set<LLUUID>::iterator IDIt;
+};
+//===============================================================================
+
+#endif
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 9dd5269a6b..2a3bd37129 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -4962,9 +4962,12 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
if (mdl)
{
U16 index_offset = 0;
+ U16 tri[3] ;
mPositions.clear();
mIndices.clear();
+ mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ;
+ mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ;
//queue up vertex positions and indices
for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
@@ -4978,12 +4981,28 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
for (U32 j = 0; j < face.mNumVertices; ++j)
{
mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr()));
+ for(U32 k = 0 ; k < 3 ; k++)
+ {
+ mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ;
+ mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ;
+ }
}
- for (U32 j = 0; j < face.mNumIndices; ++j)
+ updateTriangleAreaThreshold() ;
+
+ for (U32 j = 0; j+2 < face.mNumIndices; j += 3)
{
- mIndices.push_back(face.mIndices[j]+index_offset);
- }
+ tri[0] = face.mIndices[j] + index_offset ;
+ tri[1] = face.mIndices[j + 1] + index_offset ;
+ tri[2] = face.mIndices[j + 2] + index_offset ;
+
+ if(isValidTriangle(tri[0], tri[1], tri[2]))
+ {
+ mIndices.push_back(tri[0]);
+ mIndices.push_back(tri[1]);
+ mIndices.push_back(tri[2]);
+ }
+ }
index_offset += face.mNumVertices;
}
diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp
index faf81dbc5c..e44737f39e 100644
--- a/indra/newview/llfloatermodelwizard.cpp
+++ b/indra/newview/llfloatermodelwizard.cpp
@@ -441,10 +441,13 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM
if (mdl)
{
U16 index_offset = 0;
+ U16 tri[3] ;
mPositions.clear();
mIndices.clear();
-
+ mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ;
+ mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ;
+
//queue up vertex positions and indices
for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
{
@@ -457,11 +460,27 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM
for (U32 j = 0; j < face.mNumVertices; ++j)
{
mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr()));
+ for(U32 k = 0 ; k < 3 ; k++)
+ {
+ mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ;
+ mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ;
+ }
}
- for (U32 j = 0; j < face.mNumIndices; ++j)
+ updateTriangleAreaThreshold() ;
+
+ for (U32 j = 0; j+2 < face.mNumIndices; j += 3)
{
- mIndices.push_back(face.mIndices[j]+index_offset);
+ tri[0] = face.mIndices[j] + index_offset ;
+ tri[1] = face.mIndices[j + 1] + index_offset ;
+ tri[2] = face.mIndices[j + 2] + index_offset ;
+
+ if(isValidTriangle(tri[0], tri[1], tri[2]))
+ {
+ mIndices.push_back(tri[0]);
+ mIndices.push_back(tri[1]);
+ mIndices.push_back(tri[2]);
+ }
}
index_offset += face.mNumVertices;
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 73c1f99fa0..061a42ab57 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -85,6 +85,7 @@
#include "llviewerwindow.h"
#include "llvovolume.h"
#include "lluictrlfactory.h"
+#include "llaccountingquotamanager.h"
// Globals
LLFloaterTools *gFloaterTools = NULL;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b5180854ef..318beafe65 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -632,10 +632,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
}
// We're hiding mesh types
+#if 0
if (item->getType() == LLAssetType::AT_MESH)
{
return mask;
}
+#endif
LLViewerInventoryItem* old_item = getItem(item->getUUID());
LLPointer<LLViewerInventoryItem> new_item;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d9a58d56fe..b79f120eda 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -498,18 +498,29 @@ public:
//assert_main_thread();
llinfos << "completed" << llendl;
mThread->mPendingUploads--;
- dumpLLSDToFile(content,"whole_model_response.xml");
+ dumpLLSDToFile(content,"whole_model_fee_response.xml");
+ if (isGoodStatus(status))
+ {
+ mThread->mWholeModelUploadURL = content["uploader"].asString();
+ }
+ else
+ {
+ llinfos << "upload failed" << llendl;
+ mThread->mWholeModelUploadURL = "";
+ }
- mThread->mWholeModelUploadURL = content["uploader"].asString();
}
};
class LLWholeModelUploadResponder: public LLCurl::Responder
{
LLMeshUploadThread* mThread;
+ LLSD mPostData;
+
public:
- LLWholeModelUploadResponder(LLMeshUploadThread* thread):
- mThread(thread)
+ LLWholeModelUploadResponder(LLMeshUploadThread* thread, LLSD& post_data):
+ mThread(thread),
+ mPostData(post_data)
{
}
virtual void completed(U32 status,
@@ -520,6 +531,10 @@ public:
llinfos << "upload completed" << llendl;
mThread->mPendingUploads--;
dumpLLSDToFile(content,"whole_model_upload_response.xml");
+ // requested "mesh" asset type isn't actually the type
+ // of the resultant object, fix it up here.
+ mPostData["asset_type"] = "object";
+ gMeshRepo.updateInventory(LLMeshRepository::inventory_data(mPostData,content));
}
};
@@ -1386,108 +1401,131 @@ void LLMeshUploadThread::run()
}
}
-#if 1
void dumpLLSDToFile(const LLSD& content, std::string filename)
{
+#if 1
std::ofstream of(filename.c_str());
LLSDSerialize::toPrettyXML(content,of);
-}
#endif
+}
void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
{
- // TODO where do textures go?
-
LLSD result;
LLSD res;
result["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
result["asset_type"] = "mesh";
result["inventory_type"] = "object";
- result["name"] = "your name here";
+ result["name"] = "mesh model";
result["description"] = "your description here";
- // TODO "optional" fields from the spec
-
res["mesh_list"] = LLSD::emptyArray();
-// TODO Textures
- //res["texture_list"] = LLSD::emptyArray();
+ res["texture_list"] = LLSD::emptyArray();
+ res["instance_list"] = LLSD::emptyArray();
S32 mesh_num = 0;
S32 texture_num = 0;
std::set<LLViewerTexture* > textures;
+ std::map<LLViewerTexture*,S32> texture_index;
+ std::map<LLModel*,S32> mesh_index;
+
+ S32 instance_num = 0;
+
for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
{
LLMeshUploadData data;
data.mBaseModel = iter->first;
-
LLModelInstance& instance = *(iter->second.begin());
+ LLModel* model = instance.mModel;
+ if (mesh_index.find(model) == mesh_index.end())
+ {
+ // Have not seen this model before - create a new mesh_list entry for it.
+ std::string model_name = data.mBaseModel->getName();
+ if (!model_name.empty())
+ {
+ result["name"] = model_name;
+ }
+ std::stringstream ostr;
+
+ LLModel::Decomposition& decomp =
+ data.mModel[LLModel::LOD_PHYSICS].notNull() ?
+ data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
+ data.mBaseModel->mPhysics;
+
+ decomp.mBaseHull = mHullMap[data.mBaseModel];
+
+ LLSD mesh_header = LLModel::writeModel(
+ ostr,
+ data.mModel[LLModel::LOD_PHYSICS],
+ data.mModel[LLModel::LOD_HIGH],
+ data.mModel[LLModel::LOD_MEDIUM],
+ data.mModel[LLModel::LOD_LOW],
+ data.mModel[LLModel::LOD_IMPOSTOR],
+ decomp,
+ mUploadSkin,
+ mUploadJoints);
+
+ data.mAssetData = ostr.str();
+ std::string str = ostr.str();
+
+ res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());
+ mesh_index[model] = mesh_num;
+ mesh_num++;
+ }
+
+ LLSD instance_entry;
+
for (S32 i = 0; i < 5; i++)
{
data.mModel[i] = instance.mLOD[i];
}
-
- std::stringstream ostr;
-
- LLModel::Decomposition& decomp =
- data.mModel[LLModel::LOD_PHYSICS].notNull() ?
- data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
- data.mBaseModel->mPhysics;
-
- decomp.mBaseHull = mHullMap[data.mBaseModel];
-
- LLSD mesh_header = LLModel::writeModel(
- ostr,
- data.mModel[LLModel::LOD_PHYSICS],
- data.mModel[LLModel::LOD_HIGH],
- data.mModel[LLModel::LOD_MEDIUM],
- data.mModel[LLModel::LOD_LOW],
- data.mModel[LLModel::LOD_IMPOSTOR],
- decomp,
- mUploadSkin,
- mUploadJoints);
-
- data.mAssetData = ostr.str();
-
- LLSD mesh_entry;
-
+
LLVector3 pos, scale;
LLQuaternion rot;
LLMatrix4 transformation = instance.mTransform;
decomposeMeshMatrix(transformation,pos,rot,scale);
+ instance_entry["position"] = ll_sd_from_vector3(pos);
+ instance_entry["rotation"] = ll_sd_from_quaternion(rot);
+ instance_entry["scale"] = ll_sd_from_vector3(scale);
+
+ instance_entry["material"] = LL_MCODE_WOOD;
+ LLPermissions perm;
+ perm.setOwnerAndGroup(gAgent.getID(), gAgent.getID(), LLUUID::null, false);
+ perm.setCreator(gAgent.getID());
+
+ perm.initMasks(PERM_ITEM_UNRESTRICTED | PERM_MOVE, //base
+ PERM_ITEM_UNRESTRICTED | PERM_MOVE, //owner
+ LLFloaterPerms::getEveryonePerms(),
+ LLFloaterPerms::getGroupPerms(),
+ LLFloaterPerms::getNextOwnerPerms());
+ instance_entry["permissions"] = ll_create_sd_from_permissions(perm);
+ instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
+ instance_entry["mesh"] = mesh_index[model];
-#if 0
- mesh_entry["childpos"] = ll_sd_from_vector3(pos);
- mesh_entry["childrot"] = ll_sd_from_quaternion(rot);
- mesh_entry["scale"] = ll_sd_from_vector3(scale);
-#endif
- mesh_entry["position"] = ll_sd_from_vector3(LLVector3());
- mesh_entry["rotation"] = ll_sd_from_quaternion(rot);
- mesh_entry["scale"] = ll_sd_from_vector3(scale);
-
- // TODO should be binary.
- std::string str = ostr.str();
- mesh_entry["mesh_data"] = LLSD::Binary(str.begin(),str.end());
-
- res["mesh_list"][mesh_num] = mesh_entry;
-
- // TODO how do textures in the list map to textures in the meshes?
if (mUploadTextures)
{
- for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin();
- material_iter != instance.mMaterial.end(); ++material_iter)
- {
+ instance_entry["face_list"] = LLSD::emptyArray();
- if (textures.find(material_iter->mDiffuseMap.get()) == textures.end())
+ for (S32 face_num = 0; face_num < model->getNumVolumeFaces(); face_num++)
+ {
+ LLImportMaterial& material = instance.mMaterial[face_num];
+ LLSD face_entry = LLSD::emptyMap();
+ LLViewerFetchedTexture *texture = material.mDiffuseMap.get();
+
+ if (texture != NULL)
{
- textures.insert(material_iter->mDiffuseMap.get());
+ if (textures.find(texture) == textures.end())
+ {
+ textures.insert(texture);
+ }
std::stringstream ostr;
if (include_textures) // otherwise data is blank.
{
- LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel);
+ LLTextureUploadData data(texture, material.mDiffuseMapLabel);
if (!data.mTexture->isRawImageValid())
{
data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel());
@@ -1497,21 +1535,38 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage());
ostr.write((const char*) upload_file->getData(), upload_file->getDataSize());
}
- LLSD texture_entry;
- texture_entry["texture_data"] = ostr.str();
- res["texture_list"][texture_num] = texture_entry;
- texture_num++;
+
+ if (texture_index.find(texture) == texture_index.end())
+ {
+ texture_index[texture] = texture_num;
+ std::string str = ostr.str();
+ res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
+ texture_num++;
+ }
}
+
+ // Subset of TextureEntry fields.
+ if (texture)
+ {
+ face_entry["image"] = texture_index[texture];
+ }
+ face_entry["scales"] = 1.0;
+ face_entry["scalet"] = 1.0;
+ face_entry["offsets"] = 0.0;
+ face_entry["offsett"] = 0.0;
+ face_entry["imagerot"] = 0.0;
+ face_entry["colors"] = ll_sd_from_color4(material.mDiffuseColor);
+ face_entry["fullbright"] = material.mFullbright;
+ instance_entry["face_list"][face_num] = face_entry;
}
}
- mesh_num++;
+ res["instance_list"][instance_num] = instance_entry;
+ instance_num++;
}
result["asset_resources"] = res;
-#if 1
dumpLLSDToFile(result,"whole_model.xml");
-#endif
dest = result;
}
@@ -1563,9 +1618,9 @@ void LLMeshUploadThread::doWholeModelUpload()
apr_sleep(100);
}
- bool do_include_textures = false; // not needed for initial cost/validation check.
LLSD model_data;
- wholeModelToLLSD(model_data, do_include_textures);
+ wholeModelToLLSD(model_data,false);
+ dumpLLSDToFile(model_data,"whole_model_fee_request.xml");
mPendingUploads++;
LLCurlRequest::headers_t headers;
@@ -1577,12 +1632,24 @@ void LLMeshUploadThread::doWholeModelUpload()
mCurlRequest->process();
} while (mCurlRequest->getQueued() > 0);
- mCurlRequest->post(mWholeModelUploadURL, headers, model_data["asset_resources"], new LLWholeModelUploadResponder(this));
-
- do
+
+ if (mWholeModelUploadURL.empty())
{
- mCurlRequest->process();
- } while (mCurlRequest->getQueued() > 0);
+ llinfos << "unable to upload, fee request failed" << llendl;
+ }
+ else
+ {
+ LLSD full_model_data;
+ wholeModelToLLSD(full_model_data, true);
+ LLSD body = full_model_data["asset_resources"];
+ dumpLLSDToFile(body,"whole_model_body.xml");
+ mCurlRequest->post(mWholeModelUploadURL, headers, body,
+ new LLWholeModelUploadResponder(this, model_data));
+ do
+ {
+ mCurlRequest->process();
+ } while (mCurlRequest->getQueued() > 0);
+ }
delete mCurlRequest;
mCurlRequest = NULL;
@@ -3243,6 +3310,8 @@ bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const
void LLMeshRepository::updateInventory(inventory_data data)
{
LLMutexLock lock(mMeshMutex);
+ dumpLLSDToFile(data.mPostData,"update_inventory_post_data.xml");
+ dumpLLSDToFile(data.mResponse,"update_inventory_response.xml");
mInventoryQ.push(data);
}
@@ -3751,6 +3820,25 @@ void LLPhysicsDecomp::run()
mDone = true;
}
+void LLPhysicsDecomp::Request::updateTriangleAreaThreshold()
+{
+ F32 range = mBBox[1].mV[0] - mBBox[0].mV[0] ;
+ range = llmin(range, mBBox[1].mV[1] - mBBox[0].mV[1]) ;
+ range = llmin(range, mBBox[1].mV[2] - mBBox[0].mV[2]) ;
+
+ mTriangleAreaThreshold = llmin(0.0002f, range * 0.000002f) ;
+}
+
+//check if the triangle area is large enough to qualify for a valid triangle
+bool LLPhysicsDecomp::Request::isValidTriangle(U16 idx1, U16 idx2, U16 idx3)
+{
+ LLVector3 a = mPositions[idx2] - mPositions[idx1] ;
+ LLVector3 b = mPositions[idx3] - mPositions[idx1] ;
+ F32 c = a * b ;
+
+ return ((a*a) * (b*b) - c * c) > mTriangleAreaThreshold ;
+}
+
void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)
{
mStatusMessage = msg;
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index f859e29c07..0a6954bade 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -152,7 +152,7 @@ public:
std::string mStatusMessage;
std::vector<LLModel::PhysicsMesh> mHullMesh;
LLModel::convex_hull_decomposition mHull;
-
+
//status message callback, called from decomposition thread
virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0;
@@ -160,6 +160,14 @@ public:
virtual void completed() = 0;
virtual void setStatusMessage(const std::string& msg);
+
+ protected:
+ //internal use
+ LLVector3 mBBox[2] ;
+ F32 mTriangleAreaThreshold ;
+
+ void updateTriangleAreaThreshold() ;
+ bool isValidTriangle(U16 idx1, U16 idx2, U16 idx3) ;
};
LLCondition* mSignal;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index f5fee662e6..e7878d8adf 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -102,6 +102,7 @@
#include "lltrans.h"
#include "llsdutil.h"
#include "llmediaentry.h"
+#include "llaccountingquota.h"
//#define DEBUG_UPDATE_TYPE
@@ -5702,3 +5703,10 @@ public:
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 21198f7dd1..a0ad52df6b 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -43,6 +43,7 @@
#include "v3dmath.h"
#include "v3math.h"
#include "llvertexbuffer.h"
+#include "llaccountingquota.h"
class LLAgent; // TODO: Get rid of this.
class LLAudioSource;
@@ -643,7 +644,11 @@ protected:
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
@@ -705,6 +710,8 @@ protected:
F32 mPhysicsCost;
F32 mLinksetPhysicsCost;
+ SelectionQuota mSelectionQuota;
+
bool mCostStale;
mutable bool mPhysicsShapeUnknown;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index ab2e07e4df..007b3416f1 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1418,6 +1418,15 @@ void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id)
mPendingObjectCost.erase(object_id);
}
+void LLViewerObjectList::updateQuotaCost( const LLUUID& objectId, const SelectionQuota& quota )
+{
+ LLViewerObject* pVO = findObject( objectId );
+ if ( pVO )
+ {
+ //pVO->updateQuota( quota );
+ }
+}
+
void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object)
{
mStalePhysicsFlags.insert(object->getID());
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 65374bca70..8e211eaf73 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -36,6 +36,7 @@
// project includes
#include "llviewerobject.h"
+#include "llaccountingquota.h"
class LLCamera;
class LLNetMap;
@@ -101,6 +102,8 @@ public:
F32 restitution,
F32 gravity_multiplier);
+ void updateQuotaCost( const LLUUID& objectId, const SelectionQuota& costs );
+
void shiftObjects(const LLVector3 &offset);
bool hasMapObjectInRegion(LLViewerRegion* regionp) ;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index f835351c04..fb608b3a4f 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1508,6 +1508,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("LandResources");
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
+ capabilityNames.append("NewAccountingEnabled");
capabilityNames.append("NewFileAgentInventory");
capabilityNames.append("NewFileAgentInventoryVariablePrice");
capabilityNames.append("ObjectAdd");
@@ -1545,6 +1546,10 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("ViewerMetrics");
capabilityNames.append("ViewerStartAuction");
capabilityNames.append("ViewerStats");
+ //prep# Finalize these!!!!!!!!!
+ capabilityNames.append("AccountingParcel");
+ capabilityNames.append("AccountingSelection");
+
// Please add new capabilities alphabetically to reduce
// merge conflicts.
@@ -1658,3 +1663,4 @@ std::string LLViewerRegion::getDescription() const
{
return stringize(*this);
}
+
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 9c5b85b77f..a6e5c47b86 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -275,6 +275,7 @@ public:
F32 getLandHeightRegion(const LLVector3& region_pos);
void getInfo(LLSD& info);
+
typedef enum
{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index ec2b5a4c98..dc355362ce 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -4968,19 +4968,6 @@ void LLVOAvatar::resetSpecificJointPosition( const std::string& name )
//-----------------------------------------------------------------------------
void LLVOAvatar::resetJointPositionsToDefault( void )
{
- const LLVector3& avPos = getCharacterPosition();
-
- //Reposition the pelvis
- LLJoint* pPelvis = mRoot.findJoint("mPelvis");
- if ( pPelvis )
- {
- pPelvis->setPosition( avPos + pPelvis->getPosition() );
- }
- else
- {
- llwarns<<"Can't get pelvis joint."<<llendl;
- return;
- }
//Subsequent joints are relative to pelvis
for( S32 i = 0; i < (S32)mNumJoints; ++i )
@@ -4991,7 +4978,7 @@ void LLVOAvatar::resetJointPositionsToDefault( void )
pJoint->setId( LLUUID::null );
//restore joints to default positions, however skip over the pelvis
- if ( pJoint && pPelvis != pJoint )
+ if ( pJoint )
{
pJoint->restoreOldXform();
}
@@ -6028,6 +6015,14 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
if ( bindCnt > 0 )
{
LLVOAvatar::resetJointPositionsToDefault();
+ //Need to handle the repositioning of the cam, updating rig data etc during outfit editing
+ //This handles the case where we detach a replacement rig.
+ if ( gAgentCamera.cameraCustomizeAvatar() )
+ {
+ gAgent.unpauseAnimation();
+ //Still want to refocus on head bone
+ gAgentCamera.changeCameraToCustomizeAvatar();
+ }
}
}
}