From 2aa4aa78e2a2e0d10dfd95a5dcb49171f1b02b18 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 1 Aug 2011 01:33:07 -0500 Subject: [PATCH] Added physics settings to object features panel. Brought in mesh 'prim cost' fetching and now display cost in edit floater if mesh is enabled. --- indra/llcommon/CMakeLists.txt | 1 + indra/llcommon/llaccountingquota.h | 80 ++++ indra/llinventory/llparcel.cpp | 10 + indra/llinventory/llparcel.h | 13 +- indra/llui/llmultisliderctrl.cpp | 26 +- indra/llui/llsliderctrl.cpp | 26 +- indra/llui/llspinctrl.cpp | 76 ++-- indra/llui/lluictrl.cpp | 2 + indra/newview/CMakeLists.txt | 2 + indra/newview/llaccountingquotamanager.cpp | 281 +++++++++++++ indra/newview/llaccountingquotamanager.h | 55 +++ indra/newview/llfloatertools.cpp | 25 +- indra/newview/llpanelvolume.cpp | 391 +++++++++++++----- indra/newview/llpanelvolume.h | 27 +- indra/newview/llselectmgr.cpp | 288 +++++++++++++ indra/newview/llselectmgr.h | 17 + indra/newview/llviewerobject.cpp | 250 ++++++++++- indra/newview/llviewerobject.h | 72 +++- indra/newview/llviewerobjectlist.cpp | 386 +++++++++++++++++ indra/newview/llviewerobjectlist.h | 30 ++ .../skins/default/xui/en-us/floater_tools.xml | 145 +++++-- scripts/messages/message_template.msg | 9 + 22 files changed, 1977 insertions(+), 235 deletions(-) create mode 100644 indra/llcommon/llaccountingquota.h create mode 100644 indra/newview/llaccountingquotamanager.cpp create mode 100644 indra/newview/llaccountingquotamanager.h diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index d6e2c7c45..3132a03e1 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -96,6 +96,7 @@ set(llcommon_HEADER_FILES indra_constants.h linden_common.h linked_lists.h + llaccountingquota.h llagentconstants.h llavatarname.h llapp.h diff --git a/indra/llcommon/llaccountingquota.h b/indra/llcommon/llaccountingquota.h new file mode 100644 index 000000000..140333de0 --- /dev/null +++ b/indra/llcommon/llaccountingquota.h @@ -0,0 +1,80 @@ +/** + * @file llaccountingquota.h + * @ + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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_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 tempRenderCost, F32 tempPhysicsCost, F32 tempNetworkCost, F32 tempSimulationCost, + F32 selectedRenderCost, F32 selectedPhysicsCost, F32 selectedNetworkCost, F32 selectedSimulationCost, + F32 parcelCapacity ) + : mOwnerRenderCost( ownerRenderCost ), mOwnerPhysicsCost( ownerPhysicsCost ) + , mOwnerNetworkCost( ownerNetworkCost ), mOwnerSimulationCost( ownerSimulationCost ) + , mGroupRenderCost( groupRenderCost ), mGroupPhysicsCost( groupPhysicsCost ) + , mGroupNetworkCost( groupNetworkCost ), mGroupSimulationCost( groupSimulationCost ) + , mOtherRenderCost( otherRenderCost ), mOtherPhysicsCost( otherPhysicsCost ) + , mOtherNetworkCost( otherNetworkCost ), mOtherSimulationCost( otherSimulationCost ) + , mTempRenderCost( tempRenderCost ), mTempPhysicsCost( tempPhysicsCost ) + , mTempNetworkCost( tempNetworkCost ), mTempSimulationCost( tempSimulationCost ) + , mSelectedRenderCost( tempRenderCost ), mSelectedPhysicsCost( tempPhysicsCost ) + , mSelectedNetworkCost( tempNetworkCost ), mSelectedSimulationCost( selectedSimulationCost ) + , mParcelCapacity( parcelCapacity ) + { + } + + ParcelQuota(){} + F32 mOwnerRenderCost, mOwnerPhysicsCost, mOwnerNetworkCost, mOwnerSimulationCost; + F32 mGroupRenderCost, mGroupPhysicsCost, mGroupNetworkCost, mGroupSimulationCost; + F32 mOtherRenderCost, mOtherPhysicsCost, mOtherNetworkCost, mOtherSimulationCost; + F32 mTempRenderCost, mTempPhysicsCost, mTempNetworkCost, mTempSimulationCost; + F32 mSelectedRenderCost, mSelectedPhysicsCost, mSelectedNetworkCost, mSelectedSimulationCost; + F32 mParcelCapacity; +}; + +struct SelectionQuota +{ + SelectionQuota( LLUUID 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; + LLUUID mLocalId; +}; + +#endif + + + diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index c167ef194..432cb3e61 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -1354,3 +1354,13 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s) // is a distinct option from "None" and "Other" return LLParcel::C_ANY; } + +#if MESH_ENABLED +void LLParcel::updateQuota( const LLUUID& objectId, const ParcelQuota& quota ) +{ + if ( mID == objectId ) + { + mQuota = quota; + } +} +#endif //MESH_ENABLED diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 2d74495b6..7d92d4b37 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -38,8 +38,11 @@ #include "lluuid.h" #include "llparcelflags.h" #include "llpermissions.h" -#include "v3math.h" #include "lltimer.h" +#include "v3math.h" +#if MESH_ENABLED +#include "llaccountingquota.h" +#endif //MESH_ENABLED // Grid out of which parcels taken is stepped every 4 meters. const F32 PARCEL_GRID_STEP_METERS = 4.f; @@ -599,6 +602,10 @@ public: BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; } BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; } +#if MESH_ENABLED + void updateQuota( const LLUUID& objectId, const ParcelQuota& quota ); + const ParcelQuota& getQuota( void ) { return mQuota; } +#endif //MESH_ENABLED protected: LLUUID mID; LLUUID mOwnerID; @@ -671,7 +678,9 @@ protected: BOOL mRegionPushOverride; BOOL mRegionDenyAnonymousOverride; BOOL mRegionDenyAgeUnverifiedOverride; - +#if MESH_ENABLED + ParcelQuota mQuota; +#endif //MESH_ENABLED public: // HACK, make private diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index f9ec6d5ee..acf928f01 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -307,17 +307,10 @@ void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata ) val = (F32) atof( text.c_str() ); if( self->mMultiSlider->getMinValue() <= val && val <= self->mMultiSlider->getMaxValue() ) { - if( self->mValidateCallback ) + self->setCurSliderValue( val ); + if( (!self->mValidateCallback || self->mValidateCallback( self, self->mCallbackUserData )) && + (!self->mValidateSignal || (*(self->mValidateSignal))(self, val))) { - self->setCurSliderValue( val ); // set the value temporarily so that the callback can retrieve it. - if( self->mValidateCallback( self, self->mCallbackUserData ) ) - { - success = TRUE; - } - } - else - { - self->setCurSliderValue( val ); success = TRUE; } } @@ -348,18 +341,11 @@ void LLMultiSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata ) F32 saved_val = self->mCurValue; F32 new_val = self->mMultiSlider->getCurSliderValue(); - if( self->mValidateCallback ) + self->mCurValue = new_val; // set the value temporarily so that the callback can retrieve it. + if( (!self->mValidateCallback || self->mValidateCallback( self, self->mCallbackUserData )) && + (!self->mValidateSignal || (*(self->mValidateSignal))(self, new_val ))) { - self->mCurValue = new_val; // set the value temporarily so that the callback can retrieve it. - if( self->mValidateCallback( self, self->mCallbackUserData ) ) - { success = TRUE; - } - } - else - { - self->mCurValue = new_val; - success = TRUE; } if( success ) diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 51d43fbb7..590d3cf2e 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -238,17 +238,10 @@ void LLSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata ) val = (F32) atof( text.c_str() ); if( self->mSlider->getMinValue() <= val && val <= self->mSlider->getMaxValue() ) { - if( self->mValidateCallback ) + self->setValue( val ); + if( (!self->mValidateCallback || self->mValidateCallback( self, self->mCallbackUserData )) && + (!self->mValidateSignal || (*(self->mValidateSignal))( self, val ))) { - self->setValue( val ); // set the value temporarily so that the callback can retrieve it. - if( self->mValidateCallback( self, self->mCallbackUserData ) ) - { - success = TRUE; - } - } - else - { - self->setValue( val ); success = TRUE; } } @@ -279,17 +272,10 @@ void LLSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata ) F32 saved_val = self->mValue; F32 new_val = self->mSlider->getValueF32(); - if( self->mValidateCallback ) + self->mValue = new_val; // set the value temporarily so that the callback can retrieve it. + if( (!self->mValidateCallback || self->mValidateCallback( self, self->mCallbackUserData )) && + (!self->mValidateSignal || (*(self->mValidateSignal))( self, new_val ))) { - self->mValue = new_val; // set the value temporarily so that the callback can retrieve it. - if( self->mValidateCallback( self, self->mCallbackUserData ) ) - { - success = TRUE; - } - } - else - { - self->mValue = new_val; success = TRUE; } diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 717604670..f833dac6c 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -168,21 +168,15 @@ void LLSpinCtrl::onUpBtn( void *userdata ) val = clamp_precision(val, self->mPrecision); val = llmin( val, self->mMaxValue ); - if( self->mValidateCallback ) + F32 saved_val = (F32)self->getValue().asReal(); + self->setValue(val); + if( (self->mValidateCallback && !self->mValidateCallback( self, self->mCallbackUserData ) ) || + (self->mValidateSignal && !(*(self->mValidateSignal))( self, val ) )) { - F32 saved_val = (F32)self->getValue().asReal(); - self->setValue(val); - if( !self->mValidateCallback( self, self->mCallbackUserData ) ) - { - self->setValue( saved_val ); - self->reportInvalidData(); - self->updateEditor(); - return; - } - } - else - { - self->setValue(val); + self->setValue( saved_val ); + self->reportInvalidData(); + self->updateEditor(); + return; } self->updateEditor(); @@ -201,21 +195,19 @@ void LLSpinCtrl::onDownBtn( void *userdata ) val = clamp_precision(val, self->mPrecision); val = llmax( val, self->mMinValue ); - if( self->mValidateCallback ) + + if (val < self->mMinValue) val = self->mMinValue; + if (val > self->mMaxValue) val = self->mMaxValue; + + F32 saved_val = (F32)self->getValue().asReal(); + self->setValue(val); + if( (self->mValidateCallback && !self->mValidateCallback( self, self->mCallbackUserData ) ) || + (self->mValidateSignal && !(*(self->mValidateSignal))( self, val ) )) { - F32 saved_val = (F32)self->getValue().asReal(); - self->setValue(val); - if( !self->mValidateCallback( self, self->mCallbackUserData ) ) - { - self->setValue( saved_val ); - self->reportInvalidData(); - self->updateEditor(); - return; - } - } - else - { - self->setValue(val); + self->setValue( saved_val ); + self->reportInvalidData(); + self->updateEditor(); + return; } self->updateEditor(); @@ -303,32 +295,20 @@ void LLSpinCtrl::onEditorCommit( LLUICtrl* caller, void *userdata ) if (val < self->mMinValue) val = self->mMinValue; if (val > self->mMaxValue) val = self->mMaxValue; - if( self->mValidateCallback ) + F32 saved_val = self->mValue; + self->mValue = val; + + if( (!self->mValidateCallback || self->mValidateCallback( self, self->mCallbackUserData )) && + (!self->mValidateSignal || (*(self->mValidateSignal))(self, val))) { - F32 saved_val = self->mValue; - self->mValue = val; - if( self->mValidateCallback( self, self->mCallbackUserData ) ) - { - success = TRUE; - self->onCommit(); - } - else - { - self->mValue = saved_val; - } + success = TRUE; + self->onCommit(); } else { - self->mValue = val; - self->onCommit(); - success = TRUE; + self->mValue = saved_val; } } - else - { - // We want to update the editor in case it fails while blanking -- MC - success = TRUE; - } if( success ) { diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 4038f0a3e..49767a547 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -93,6 +93,8 @@ void LLUICtrl::onCommit() { mCommitCallback( this, mCallbackUserData ); } + if (mCommitSignal) + (*mCommitSignal)(this, getValue()); } //virtual diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 342c19552..b095c90d4 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -100,6 +100,7 @@ set(viewer_SOURCE_FILES jcfloaterareasearch.cpp chatbar_as_cmdline.cpp qtoolalign.cpp + llaccountingquotamanager.cpp llagent.cpp llagentaccess.cpp llagentcamera.cpp @@ -579,6 +580,7 @@ set(viewer_HEADER_FILES lgghunspell_wrapper.h chatbar_as_cmdline.h qtoolalign.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 000000000..44d5b7e71 --- /dev/null +++ b/indra/newview/llaccountingquotamanager.cpp @@ -0,0 +1,281 @@ +/** + * @file LLAccountingQuotaManager.cpp + * @ Handles the setting and accessing for costs associated with mesh + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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" +#if MESH_ENABLED +#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 "<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 + LLUUID parcelId; + //S32 parcelOwner = 0; + if ( content["parcel"][i].has("parcel_id") ) + { + parcelId = content["parcel"][i]["parcel_id"].asUUID(); + } + + //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 tempRenderCost = 0; + F32 tempPhysicsCost = 0; + F32 tempNetworkCost = 0; + F32 tempSimulationCost = 0; + + F32 selectedRenderCost = 0; + F32 selectedPhysicsCost = 0; + F32 selectedNetworkCost = 0; + F32 selectedSimulationCost = 0; + + F32 parcelCapacity = 0; + + if ( content["parcel"][i].has("capacity") ) + { + parcelCapacity = content["parcel"][i].has("capacity"); + } + + if ( content["parcel"][i].has("owner") ) + { + ownerRenderCost = content["parcel"][i]["owner"]["rendering"].asReal(); + ownerPhysicsCost = content["parcel"][i]["owner"]["physics"].asReal(); + ownerNetworkCost = content["parcel"][i]["owner"]["streaming"].asReal(); + ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal(); + } + + if ( content["parcel"][i].has("group") ) + { + groupRenderCost = content["parcel"][i]["group"]["rendering"].asReal(); + groupPhysicsCost = content["parcel"][i]["group"]["physics"].asReal(); + groupNetworkCost = content["parcel"][i]["group"]["streaming"].asReal(); + groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal(); + + } + if ( content["parcel"][i].has("other") ) + { + otherRenderCost = content["parcel"][i]["other"]["rendering"].asReal(); + otherPhysicsCost = content["parcel"][i]["other"]["physics"].asReal(); + otherNetworkCost = content["parcel"][i]["other"]["streaming"].asReal(); + otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal(); + } + + if ( content["parcel"][i].has("temp") ) + { + tempRenderCost = content["parcel"][i]["total"]["rendering"].asReal(); + tempPhysicsCost = content["parcel"][i]["total"]["physics"].asReal(); + tempNetworkCost = content["parcel"][i]["total"]["streaming"].asReal(); + tempSimulationCost = content["parcel"][i]["total"]["simulation"].asReal(); + } + + if ( content["parcel"][i].has("selected") ) + { + selectedRenderCost = content["parcel"][i]["total"]["rendering"].asReal(); + selectedPhysicsCost = content["parcel"][i]["total"]["physics"].asReal(); + selectedNetworkCost = content["parcel"][i]["total"]["streaming"].asReal(); + selectedSimulationCost = content["parcel"][i]["total"]["simulation"].asReal(); + } + + ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost, + groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost, + otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost, + tempRenderCost, tempPhysicsCost, tempNetworkCost, tempSimulationCost, + selectedRenderCost, selectedPhysicsCost, selectedNetworkCost, selectedSimulationCost, + parcelCapacity ); + //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; + + LLUUID objectId; + + objectId = content["selected"][i]["local_id"].asUUID(); + renderCost = content["selected"][i]["rendering"].asReal(); + physicsCost = content["selected"][i]["physics"].asReal(); + networkCost = content["selected"][i]["streaming"].asReal(); + simulationCost = content["selected"][i]["simulation"].asReal(); + + SelectionQuota selectionQuota( objectId, renderCost, physicsCost, networkCost, simulationCost ); + + //Update the objects + gObjectList.updateQuota( objectId, 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 "< +{ +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 mUpdateObjectQuota; + //During fetchQuota we move object into a the pending set to signify that + //a fetch has been instigated. + std::set mPendingObjectQuota; + typedef std::set::iterator IDIt; +}; +//=============================================================================== + +#endif // LLACCOUNTINGQUOTAMANAGER + diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index d0e41a96a..ac283ff57 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -81,9 +81,14 @@ #include "llviewercontrol.h" #include "llviewerjoystick.h" #include "lluictrlfactory.h" +#if MESH_ENABLED +#include "llaccountingquotamanager.h" +#include "llmeshrepository.h" +#endif #include "qtoolalign.h" //Thank Qarl! + // Globals LLFloaterTools *gFloaterTools = NULL; @@ -511,9 +516,23 @@ void LLFloaterTools::refresh() childSetTextArg("link_num_obj_count", "[DESC]", desc_string); childSetTextArg("link_num_obj_count", "[NUM]", value_string); - std::string prim_count_string; - LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); - childSetTextArg("prim_count", "[COUNT]", prim_count_string); + LLStringUtil::format_map_t selection_args; + selection_args["COUNT"] = llformat("%.1d", (S32)prim_count); +#if MESH_ENABLED + if(gMeshRepo.meshRezEnabled()) + { + F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost(); + LLStringUtil::format_map_t prim_equiv_args; + prim_equiv_args["SEL_WEIGHT"] = llformat("%.1d", (S32)link_cost); + selection_args["PE_STRING"] = getString("status_selectprimequiv", prim_equiv_args); + } + else +#endif //MESH_ENABLED + { + selection_args["PE_STRING"] = ""; + } + std::string prim_count_string = getString("status_selectcount",selection_args); + childSetText("prim_count", prim_count_string); // Refresh child tabs mPanelPermissions->refresh(); diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 2d4dc3246..19322dfb4 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -78,6 +78,11 @@ #include "lldrawpool.h" #include "lluictrlfactory.h" #include "lltexturectrl.h" +#if MESH_ENABLED +// For mesh physics +#include "llviewercontrol.h" +#include "llmeshrepository.h" +#endif //MESH_ENABLED // "Features" Tab @@ -87,21 +92,21 @@ BOOL LLPanelVolume::postBuild() { childSetCommitCallback("Flexible1D Checkbox Ctrl",onCommitIsFlexible,this); childSetCommitCallback("FlexNumSections",onCommitFlexible,this); - childSetValidate("FlexNumSections",precommitValidate); + getChild("FlexNumSections")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexGravity",onCommitFlexible,this); - childSetValidate("FlexGravity",precommitValidate); + getChild("FlexGravity")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexFriction",onCommitFlexible,this); - childSetValidate("FlexFriction",precommitValidate); + getChild("FlexFriction")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexWind",onCommitFlexible,this); - childSetValidate("FlexWind",precommitValidate); + getChild("FlexWind")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexTension",onCommitFlexible,this); - childSetValidate("FlexTension",precommitValidate); + getChild("FlexTension")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexForceX",onCommitFlexible,this); - childSetValidate("FlexForceX",precommitValidate); + getChild("FlexForceX")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexForceY",onCommitFlexible,this); - childSetValidate("FlexForceY",precommitValidate); + getChild("FlexForceY")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexForceZ",onCommitFlexible,this); - childSetValidate("FlexForceZ",precommitValidate); + getChild("FlexForceZ")->setValidateBeforeCommit(precommitValidate); } // LIGHT Parameters @@ -123,20 +128,47 @@ BOOL LLPanelVolume::postBuild() } childSetCommitCallback("Light Intensity",onCommitLight,this); - childSetValidate("Light Intensity",precommitValidate); + getChild("Light Intensity")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("Light Radius",onCommitLight,this); - childSetValidate("Light Radius",precommitValidate); + getChild("Light Radius")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("Light Falloff",onCommitLight,this); - childSetValidate("Light Falloff",precommitValidate); + getChild("Light Falloff")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("Light FOV", onCommitLight, this); - childSetValidate("Light FOV", precommitValidate); + getChild("Light FOV")->setValidateBeforeCommit( precommitValidate); childSetCommitCallback("Light Focus", onCommitLight, this); - childSetValidate("Light Focus", precommitValidate); + getChild("Light Focus")->setValidateBeforeCommit( precommitValidate); childSetCommitCallback("Light Ambiance", onCommitLight, this); - childSetValidate("Light Ambiance", precommitValidate); + getChild("Light Ambiance")->setValidateBeforeCommit( precommitValidate); } + +#if MESH_ENABLED + // PHYSICS Parameters + { + // Label + mComboPhysicsShapeLabel = getChild("label physicsshapetype"); + + // PhysicsShapeType combobox + mComboPhysicsShapeType = getChild("Physics Shape Type Combo Ctrl"); + mComboPhysicsShapeType->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsShapeType, this, _1, mComboPhysicsShapeType)); + // PhysicsGravity + mSpinPhysicsGravity = getChild("Physics Gravity"); + mSpinPhysicsGravity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsGravity, this, _1, mSpinPhysicsGravity)); + + // PhysicsFriction + mSpinPhysicsFriction = getChild("Physics Friction"); + mSpinPhysicsFriction->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsFriction, this, _1, mSpinPhysicsFriction)); + + // PhysicsDensity + mSpinPhysicsDensity = getChild("Physics Density"); + mSpinPhysicsDensity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsDensity, this, _1, mSpinPhysicsDensity)); + + // PhysicsRestitution + mSpinPhysicsRestitution = getChild("Physics Restitution"); + mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution)); + } +#endif //MESH_ENABLED // Start with everyone disabled clearCtrls(); @@ -212,25 +244,25 @@ void LLPanelVolume::getState( ) // Select Single Message if (single_volume) { - childSetVisible("edit_object",true); - childSetEnabled("edit_object",true); - childSetVisible("select_single",false); + getChildView("edit_object")->setVisible(true); + getChildView("edit_object")->setEnabled(true); + getChildView("select_single")->setVisible(false); } else { - childSetVisible("edit_object",false); - childSetVisible("select_single",true); - childSetEnabled("select_single",true); + getChildView("edit_object")->setVisible(false); + getChildView("select_single")->setVisible(true); + getChildView("select_single")->setEnabled(true); } // Light properties BOOL is_light = volobjp && volobjp->getIsLight(); - childSetValue("Light Checkbox Ctrl",is_light); - childSetEnabled("Light Checkbox Ctrl",editable && single_volume && volobjp); + getChild("Light Checkbox Ctrl")->setValue(is_light); + getChildView("Light Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp); if (is_light && editable && single_volume) { - childSetEnabled("label color",true); + getChildView("label color")->setEnabled(true); //mLabelColor ->setEnabled( TRUE ); LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) @@ -248,22 +280,23 @@ void LLPanelVolume::getState( ) LightTextureCtrl->setValid(TRUE); LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID()); } - childSetEnabled("Light Intensity",true); - childSetEnabled("Light Radius",true); - childSetEnabled("Light Falloff",true); - childSetEnabled("Light FOV",true); - childSetEnabled("Light Focus",true); - childSetEnabled("Light Ambiance",true); + getChildView("Light Intensity")->setEnabled(true); + getChildView("Light Radius")->setEnabled(true); + getChildView("Light Falloff")->setEnabled(true); + + getChildView("Light FOV")->setEnabled(true); + getChildView("Light Focus")->setEnabled(true); + getChildView("Light Ambiance")->setEnabled(true); - childSetValue("Light Intensity",volobjp->getLightIntensity()); - childSetValue("Light Radius",volobjp->getLightRadius()); - childSetValue("Light Falloff",volobjp->getLightFalloff()); + getChild("Light Intensity")->setValue(volobjp->getLightIntensity()); + getChild("Light Radius")->setValue(volobjp->getLightRadius()); + getChild("Light Falloff")->setValue(volobjp->getLightFalloff()); LLVector3 params = volobjp->getSpotLightParams(); - childSetValue("Light FOV",params.mV[0]); - childSetValue("Light Focus",params.mV[1]); - childSetValue("Light Ambiance",params.mV[2]); + getChild("Light FOV")->setValue(params.mV[0]); + getChild("Light Focus")->setValue(params.mV[1]); + getChild("Light Ambiance")->setValue(params.mV[2]); mLightSavedColor = volobjp->getLightColor(); } @@ -273,7 +306,7 @@ void LLPanelVolume::getState( ) getChild("Light Radius", true)->clear(); getChild("Light Falloff", true)->clear(); - childSetEnabled("label color",false); + getChildView("label color")->setEnabled(false); LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { @@ -287,56 +320,61 @@ void LLPanelVolume::getState( ) LightTextureCtrl->setEnabled(FALSE); LightTextureCtrl->setValid(FALSE); } - childSetEnabled("Light Intensity",false); - childSetEnabled("Light Radius",false); - childSetEnabled("Light Falloff",false); - childSetEnabled("Light FOV",false); - childSetEnabled("Light Focus",false); - childSetEnabled("Light Ambiance",false); + getChildView("Light Intensity")->setEnabled(false); + getChildView("Light Radius")->setEnabled(false); + getChildView("Light Falloff")->setEnabled(false); + + getChildView("Light FOV")->setEnabled(false); + getChildView("Light Focus")->setEnabled(false); + getChildView("Light Ambiance")->setEnabled(false); } // Flexible properties BOOL is_flexible = volobjp && volobjp->isFlexible(); - childSetValue("Flexible1D Checkbox Ctrl",is_flexible); + getChild("Flexible1D Checkbox Ctrl")->setValue(is_flexible); if (is_flexible || (volobjp && volobjp->canBeFlexible())) { - childSetEnabled("Flexible1D Checkbox Ctrl", editable && single_volume && volobjp); + getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp +#if MESH_ENABLED + && !volobjp->isMesh() +#endif //MESH_ENABLED + ); } else { - childSetEnabled("Flexible1D Checkbox Ctrl", false); + getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); } if (is_flexible && editable && single_volume) { - childSetVisible("FlexNumSections",true); - childSetVisible("FlexGravity",true); - childSetVisible("FlexTension",true); - childSetVisible("FlexFriction",true); - childSetVisible("FlexWind",true); - childSetVisible("FlexForceX",true); - childSetVisible("FlexForceY",true); - childSetVisible("FlexForceZ",true); + getChildView("FlexNumSections")->setVisible(true); + getChildView("FlexGravity")->setVisible(true); + getChildView("FlexTension")->setVisible(true); + getChildView("FlexFriction")->setVisible(true); + getChildView("FlexWind")->setVisible(true); + getChildView("FlexForceX")->setVisible(true); + getChildView("FlexForceY")->setVisible(true); + getChildView("FlexForceZ")->setVisible(true); - childSetEnabled("FlexNumSections",true); - childSetEnabled("FlexGravity",true); - childSetEnabled("FlexTension",true); - childSetEnabled("FlexFriction",true); - childSetEnabled("FlexWind",true); - childSetEnabled("FlexForceX",true); - childSetEnabled("FlexForceY",true); - childSetEnabled("FlexForceZ",true); + getChildView("FlexNumSections")->setEnabled(true); + getChildView("FlexGravity")->setEnabled(true); + getChildView("FlexTension")->setEnabled(true); + getChildView("FlexFriction")->setEnabled(true); + getChildView("FlexWind")->setEnabled(true); + getChildView("FlexForceX")->setEnabled(true); + getChildView("FlexForceY")->setEnabled(true); + getChildView("FlexForceZ")->setEnabled(true); LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); - childSetValue("FlexNumSections",(F32)attributes->getSimulateLOD()); - childSetValue("FlexGravity",attributes->getGravity()); - childSetValue("FlexTension",attributes->getTension()); - childSetValue("FlexFriction",attributes->getAirFriction()); - childSetValue("FlexWind",attributes->getWindSensitivity()); - childSetValue("FlexForceX",attributes->getUserForce().mV[VX]); - childSetValue("FlexForceY",attributes->getUserForce().mV[VY]); - childSetValue("FlexForceZ",attributes->getUserForce().mV[VZ]); + getChild("FlexNumSections")->setValue((F32)attributes->getSimulateLOD()); + getChild("FlexGravity")->setValue(attributes->getGravity()); + getChild("FlexTension")->setValue(attributes->getTension()); + getChild("FlexFriction")->setValue(attributes->getAirFriction()); + getChild("FlexWind")->setValue(attributes->getWindSensitivity()); + getChild("FlexForceX")->setValue(attributes->getUserForce().mV[VX]); + getChild("FlexForceY")->setValue(attributes->getUserForce().mV[VY]); + getChild("FlexForceZ")->setValue(attributes->getUserForce().mV[VZ]); } else { @@ -349,22 +387,73 @@ void LLPanelVolume::getState( ) getChild("FlexForceY", true)->clear(); getChild("FlexForceZ", true)->clear(); - childSetEnabled("FlexNumSections",false); - childSetEnabled("FlexGravity",false); - childSetEnabled("FlexTension",false); - childSetEnabled("FlexFriction",false); - childSetEnabled("FlexWind",false); - childSetEnabled("FlexForceX",false); - childSetEnabled("FlexForceY",false); - childSetEnabled("FlexForceZ",false); + getChildView("FlexNumSections")->setEnabled(false); + getChildView("FlexGravity")->setEnabled(false); + getChildView("FlexTension")->setEnabled(false); + getChildView("FlexFriction")->setEnabled(false); + getChildView("FlexWind")->setEnabled(false); + getChildView("FlexForceX")->setEnabled(false); + getChildView("FlexForceY")->setEnabled(false); + getChildView("FlexForceZ")->setEnabled(false); } +#if MESH_ENABLED + // Physics properties + + mComboPhysicsShapeLabel->setEnabled(editable); + mSpinPhysicsGravity->set(objectp->getPhysicsGravity()); + mSpinPhysicsGravity->setEnabled(editable); + + mSpinPhysicsFriction->set(objectp->getPhysicsFriction()); + mSpinPhysicsFriction->setEnabled(editable); + + mSpinPhysicsDensity->set(objectp->getPhysicsDensity()); + mSpinPhysicsDensity->setEnabled(editable); + + mSpinPhysicsRestitution->set(objectp->getPhysicsRestitution()); + mSpinPhysicsRestitution->setEnabled(editable); + + // update the physics shape combo to include allowed physics shapes + mComboPhysicsShapeType->removeall(); + mComboPhysicsShapeType->add(getString("None"), LLSD(1)); + + BOOL isMesh = FALSE; + LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + if (sculpt_params) + { + U8 sculpt_type = sculpt_params->getSculptType(); + U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; + isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH); + } + + if(isMesh && objectp) + { + const LLVolumeParams &volume_params = objectp->getVolume()->getParams(); + LLUUID mesh_id = volume_params.getSculptID(); + if(gMeshRepo.hasPhysicsShape(mesh_id)) + { + // if a mesh contains an uploaded or decomposed physics mesh, + // allow 'Prim' + mComboPhysicsShapeType->add(getString("Prim"), LLSD(0)); + } + } + else + { + // simple prims always allow physics shape prim + mComboPhysicsShapeType->add(getString("Prim"), LLSD(0)); + } + + mComboPhysicsShapeType->add(getString("Convex Hull"), LLSD(2)); + mComboPhysicsShapeType->setValue(LLSD(objectp->getPhysicsShapeType())); + mComboPhysicsShapeType->setEnabled(editable); +#endif //MESH_ENABLED + mObject = objectp; mRootObject = root_objectp; } // static -BOOL LLPanelVolume::precommitValidate( LLUICtrl* ctrl, void* userdata ) +BOOL LLPanelVolume::precommitValidate(LLUICtrl* ctrl,void* userdata) { // TODO: Richard will fill this in later. return TRUE; // FALSE means that validation failed and new value should not be commited. @@ -386,11 +475,32 @@ void LLPanelVolume::refresh() BOOL visible = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE; - childSetVisible("label texture", visible); - childSetVisible("Light FOV", visible); - childSetVisible("Light Focus", visible); - childSetVisible("Light Ambiance", visible); - childSetVisible("light texture control", visible); + getChildView("label texture")->setVisible( visible); + getChildView("Light FOV")->setVisible( visible); + getChildView("Light Focus")->setVisible( visible); + getChildView("Light Ambiance")->setVisible( visible); + getChildView("light texture control")->setVisible( visible); + +#if MESH_ENABLED + bool enable_mesh = false; + + LLSD sim_features; + LLViewerRegion *region = gAgent.getRegion(); + if(region) + { + LLSD sim_features; + region->getSimulatorFeatures(sim_features); + enable_mesh = sim_features.has("PhysicsShapeTypes"); + } + getChildView("label physicsshapetype")->setVisible(enable_mesh); + getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh); + getChildView("Physics Gravity")->setVisible(enable_mesh); + getChildView("Physics Friction")->setVisible(enable_mesh); + getChildView("Physics Density")->setVisible(enable_mesh); + getChildView("Physics Restitution")->setVisible(enable_mesh); + + /* TODO: add/remove individual physics shape types as per the PhysicsShapeTypes simulator features */ +#endif //MESH_ENABLED } @@ -404,12 +514,12 @@ void LLPanelVolume::clearCtrls() { LLPanel::clearCtrls(); - childSetEnabled("select_single",false); - childSetVisible("select_single",true); - childSetEnabled("edit_object",false); - childSetVisible("edit_object",false); - childSetEnabled("Light Checkbox Ctrl",false); - childSetEnabled("label color",false); + getChildView("select_single")->setEnabled(false); + getChildView("select_single")->setVisible(true); + getChildView("edit_object")->setEnabled(false); + getChildView("edit_object")->setVisible(false); + getChildView("Light Checkbox Ctrl")->setEnabled(false); + getChildView("label color")->setEnabled(false); LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { @@ -424,19 +534,26 @@ void LLPanelVolume::clearCtrls() LightTextureCtrl->setValid( FALSE ); } - childSetEnabled("Light Intensity",false); - childSetEnabled("Light Radius",false); - childSetEnabled("Light Falloff",false); + getChildView("Light Intensity")->setEnabled(false); + getChildView("Light Radius")->setEnabled(false); + getChildView("Light Falloff")->setEnabled(false); - childSetEnabled("Flexible1D Checkbox Ctrl",false); - childSetEnabled("FlexNumSections",false); - childSetEnabled("FlexGravity",false); - childSetEnabled("FlexTension",false); - childSetEnabled("FlexFriction",false); - childSetEnabled("FlexWind",false); - childSetEnabled("FlexForceX",false); - childSetEnabled("FlexForceY",false); - childSetEnabled("FlexForceZ",false); + getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); + getChildView("FlexNumSections")->setEnabled(false); + getChildView("FlexGravity")->setEnabled(false); + getChildView("FlexTension")->setEnabled(false); + getChildView("FlexFriction")->setEnabled(false); + getChildView("FlexWind")->setEnabled(false); + getChildView("FlexForceX")->setEnabled(false); + getChildView("FlexForceY")->setEnabled(false); + getChildView("FlexForceZ")->setEnabled(false); + +#if MESH_ENABLED + mSpinPhysicsGravity->setEnabled(FALSE); + mSpinPhysicsFriction->setEnabled(FALSE); + mSpinPhysicsDensity->setEnabled(FALSE); + mSpinPhysicsRestitution->setEnabled(FALSE); +#endif //MESH_ENABLED } // @@ -452,7 +569,7 @@ void LLPanelVolume::sendIsLight() } LLVOVolume *volobjp = (LLVOVolume *)objectp; - BOOL value = childGetValue("Light Checkbox Ctrl"); + BOOL value = getChild("Light Checkbox Ctrl")->getValue(); volobjp->setIsLight(value); llinfos << "update light sent" << llendl; } @@ -466,7 +583,7 @@ void LLPanelVolume::sendIsFlexible() } LLVOVolume *volobjp = (LLVOVolume *)objectp; - BOOL is_flexible = childGetValue("Flexible1D Checkbox Ctrl"); + BOOL is_flexible = getChild("Flexible1D Checkbox Ctrl")->getValue(); //BOOL is_flexible = mCheckFlexible1D->get(); if (is_flexible) @@ -489,6 +606,50 @@ void LLPanelVolume::sendIsFlexible() llinfos << "update flexible sent" << llendl; } +#if MESH_ENABLED +void LLPanelVolume::sendPhysicsShapeType(LLUICtrl* ctrl, void* userdata) +{ + U8 type = ctrl->getValue().asInteger(); + LLSelectMgr::getInstance()->selectionSetPhysicsType(type); + + refreshCost(); +} + +void LLPanelVolume::sendPhysicsGravity(LLUICtrl* ctrl, void* userdata) +{ + F32 val = ctrl->getValue().asReal(); + LLSelectMgr::getInstance()->selectionSetGravity(val); +} + +void LLPanelVolume::sendPhysicsFriction(LLUICtrl* ctrl, void* userdata) +{ + F32 val = ctrl->getValue().asReal(); + LLSelectMgr::getInstance()->selectionSetFriction(val); +} + +void LLPanelVolume::sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata) +{ + F32 val = ctrl->getValue().asReal(); + LLSelectMgr::getInstance()->selectionSetRestitution(val); +} + +void LLPanelVolume::sendPhysicsDensity(LLUICtrl* ctrl, void* userdata) +{ + F32 val = ctrl->getValue().asReal(); + LLSelectMgr::getInstance()->selectionSetDensity(val); +} + +void LLPanelVolume::refreshCost() +{ + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + + if (obj) + { + obj->getObjectCost(); + } +} +#endif //MESH_ENABLED + void LLPanelVolume::onLightCancelColor(LLUICtrl* ctrl, void* userdata) { LLPanelVolume* self = (LLPanelVolume*) userdata; @@ -531,6 +692,7 @@ void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) } } + void LLPanelVolume::onLightSelectTexture(LLUICtrl* ctrl, void* userdata) { LLPanelVolume* self = (LLPanelVolume*) userdata; @@ -550,6 +712,7 @@ void LLPanelVolume::onLightSelectTexture(LLUICtrl* ctrl, void* userdata) } } + // static void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) { @@ -562,9 +725,9 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) LLVOVolume *volobjp = (LLVOVolume *)objectp; - volobjp->setLightIntensity((F32)self->childGetValue("Light Intensity").asReal()); - volobjp->setLightRadius((F32)self->childGetValue("Light Radius").asReal()); - volobjp->setLightFalloff((F32)self->childGetValue("Light Falloff").asReal()); + volobjp->setLightIntensity((F32)self->getChild("Light Intensity")->getValue().asReal()); + volobjp->setLightRadius((F32)self->getChild("Light Radius")->getValue().asReal()); + volobjp->setLightFalloff((F32)self->getChild("Light Falloff")->getValue().asReal()); LLColorSwatchCtrl* LightColorSwatch = self->getChild("colorswatch"); if(LightColorSwatch) @@ -632,14 +795,14 @@ void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata ) new_attributes = *attributes; - new_attributes.setSimulateLOD(self->childGetValue("FlexNumSections").asInteger());//(S32)self->mSpinSections->get()); - new_attributes.setGravity((F32)self->childGetValue("FlexGravity").asReal()); - new_attributes.setTension((F32)self->childGetValue("FlexTension").asReal()); - new_attributes.setAirFriction((F32)self->childGetValue("FlexFriction").asReal()); - new_attributes.setWindSensitivity((F32)self->childGetValue("FlexWind").asReal()); - F32 fx = (F32)self->childGetValue("FlexForceX").asReal(); - F32 fy = (F32)self->childGetValue("FlexForceY").asReal(); - F32 fz = (F32)self->childGetValue("FlexForceZ").asReal(); + new_attributes.setSimulateLOD(self->getChild("FlexNumSections")->getValue().asInteger());//(S32)self->mSpinSections->get()); + new_attributes.setGravity((F32)self->getChild("FlexGravity")->getValue().asReal()); + new_attributes.setTension((F32)self->getChild("FlexTension")->getValue().asReal()); + new_attributes.setAirFriction((F32)self->getChild("FlexFriction")->getValue().asReal()); + new_attributes.setWindSensitivity((F32)self->getChild("FlexWind")->getValue().asReal()); + F32 fx = (F32)self->getChild("FlexForceX")->getValue().asReal(); + F32 fy = (F32)self->getChild("FlexForceY")->getValue().asReal(); + F32 fz = (F32)self->getChild("FlexForceZ")->getValue().asReal(); LLVector3 force(fx,fy,fz); new_attributes.setUserForce(force); diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index bd9803b90..9cb744db6 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -70,16 +70,31 @@ public: static void onCommitLight( LLUICtrl* ctrl, void* userdata); static void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata); static void onCommitFlexible( LLUICtrl* ctrl, void* userdata); +#if MESH_ENABLED + static void onCommitPhysicsParam( LLUICtrl* ctrl, void* userdata); +#endif //MESH_ENABLED static void onLightCancelColor(LLUICtrl* ctrl, void* userdata); static void onLightSelectColor(LLUICtrl* ctrl, void* userdata); static void onLightCancelTexture(LLUICtrl* ctrl, void* userdata); static void onLightSelectTexture(LLUICtrl* ctrl, void* userdata); -protected: - void getState(); + protected: + void getState(); +#if MESH_ENABLED + void refreshCost(); +#endif //MESH_ENABLED + +protected: +#if MESH_ENABLED + void sendPhysicsShapeType(LLUICtrl* ctrl, void* userdata); + void sendPhysicsGravity(LLUICtrl* ctrl, void* userdata); + void sendPhysicsFriction(LLUICtrl* ctrl, void* userdata); + void sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata); + void sendPhysicsDensity(LLUICtrl* ctrl, void* userdata); +#endif //MESH_ENABLED /* LLTextBox* mLabelSelectSingleMessage; // Light @@ -104,6 +119,14 @@ protected: LLUUID mLightSavedTexture; LLPointer mObject; LLPointer mRootObject; +#if MESH_ENABLED + LLTextBox* mComboPhysicsShapeLabel; + LLComboBox* mComboPhysicsShapeType; + LLSpinCtrl* mSpinPhysicsGravity; + LLSpinCtrl* mSpinPhysicsFriction; + LLSpinCtrl* mSpinPhysicsDensity; + LLSpinCtrl* mSpinPhysicsRestitution; +#endif //MESH_ENABLED }; #endif diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 6248f1edf..dadd29dbd 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1992,6 +1992,103 @@ BOOL LLSelectMgr::selectionGetGlow(F32 *glow) return identical; } +#if MESH_ENABLED +void LLSelectMgr::selectionSetPhysicsType(U8 type) +{ + struct f : public LLSelectedObjectFunctor + { + U8 mType; + f(const U8& t) : mType(t) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsShapeType(mType); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(type); + getSelection()->applyToObjects(&sendfunc); +} + +void LLSelectMgr::selectionSetFriction(F32 friction) +{ + struct f : public LLSelectedObjectFunctor + { + F32 mFriction; + f(const F32& friction) : mFriction(friction) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsFriction(mFriction); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(friction); + getSelection()->applyToObjects(&sendfunc); +} + +void LLSelectMgr::selectionSetGravity(F32 gravity ) +{ + struct f : public LLSelectedObjectFunctor + { + F32 mGravity; + f(const F32& gravity) : mGravity(gravity) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsGravity(mGravity); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(gravity); + getSelection()->applyToObjects(&sendfunc); +} + +void LLSelectMgr::selectionSetDensity(F32 density ) +{ + struct f : public LLSelectedObjectFunctor + { + F32 mDensity; + f(const F32& density ) : mDensity(density) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsDensity(mDensity); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(density); + getSelection()->applyToObjects(&sendfunc); +} + +void LLSelectMgr::selectionSetRestitution(F32 restitution) +{ + struct f : public LLSelectedObjectFunctor + { + F32 mRestitution; + f(const F32& restitution ) : mRestitution(restitution) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsRestitution(mRestitution); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(restitution); + getSelection()->applyToObjects(&sendfunc); +} +#endif //MESH_ENABLED + //----------------------------------------------------------------------------- // selectionSetMaterial() //----------------------------------------------------------------------------- @@ -3832,6 +3929,27 @@ void LLSelectMgr::sendDelink() return; } +#if MESH_ENABLED + struct f : public LLSelectedObjectFunctor + { //on delink, any modifyable object should + f() {} + + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + if (object->getPhysicsShapeType() == LLViewerObject::PHYSICS_SHAPE_NONE) + { + object->setPhysicsShapeType(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); + object->updateFlags(); + } + } + return true; + } + } sendfunc; + getSelection()->applyToObjects(&sendfunc); +#endif //MESH_ENABLED + // Delink needs to send individuals so you can unlink a single object from // a linked set. sendListToRegions( @@ -6277,6 +6395,176 @@ S32 LLObjectSelection::getObjectCount() return count; } +#if MESH_ENABLED +F32 LLObjectSelection::getSelectedObjectCost() +{ + cleanupNodes(); + F32 cost = 0.f; + + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + cost += object->getObjectCost(); + } + } + + return cost; +} + +F32 LLObjectSelection::getSelectedLinksetCost() +{ + cleanupNodes(); + F32 cost = 0.f; + + std::set me_roots; + + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + LLViewerObject* root = static_cast(object->getRoot()); + if (root) + { + if (me_roots.find(root) == me_roots.end()) + { + me_roots.insert(root); + cost += root->getLinksetCost(); + } + } + } + } + + return cost; +} + +F32 LLObjectSelection::getSelectedPhysicsCost() +{ + cleanupNodes(); + F32 cost = 0.f; + + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + cost += object->getPhysicsCost(); + } + } + + return cost; +} + +F32 LLObjectSelection::getSelectedLinksetPhysicsCost() +{ + cleanupNodes(); + F32 cost = 0.f; + + std::set me_roots; + + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + LLViewerObject* root = static_cast(object->getRoot()); + if (root) + { + if (me_roots.find(root) == me_roots.end()) + { + me_roots.insert(root); + cost += root->getLinksetPhysicsCost(); + } + } + } + } + + return cost; +} + +F32 LLObjectSelection::getSelectedObjectStreamingCost(S32* total_bytes, S32* visible_bytes) +{ + F32 cost = 0.f; + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + S32 bytes = 0; + S32 visible = 0; + cost += object->getStreamingCost(&bytes, &visible); + + if (total_bytes) + { + *total_bytes += bytes; + } + + if (visible_bytes) + { + *visible_bytes += visible; + } + } + } + + return cost; +} + +U32 LLObjectSelection::getSelectedObjectTriangleCount() +{ + U32 count = 0; + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + count += object->getTriangleCount(); + } + } + + return count; +} + +/*S32 LLObjectSelection::getSelectedObjectRenderCost() +{ + S32 cost = 0; + LLVOVolume::texture_cost_t textures; + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLVOVolume* object = (LLVOVolume*)node->getObject(); + + if (object) + { + cost += object->getRenderCost(textures); + } + + for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) + { + // add the cost of each individual texture in the linkset + cost += iter->second; + } + textures.clear(); + } + + + return cost; +}*/ +#endif //MESH_ENABLED + //----------------------------------------------------------------------------- // getTECount() diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 2dee99fda..2ea1f46b7 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -284,6 +284,16 @@ public: // count members S32 getObjectCount(); +#if MESH_ENABLED + F32 getSelectedObjectCost(); + F32 getSelectedLinksetCost(); + F32 getSelectedPhysicsCost(); + F32 getSelectedLinksetPhysicsCost(); + S32 getSelectedObjectRenderCost(); + + F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL); + U32 getSelectedObjectTriangleCount(); +#endif //MESH_ENABLED S32 getTECount(); S32 getRootObjectCount(); @@ -505,6 +515,13 @@ public: bool selectionGetIncludeInSearch(bool* include_in_search_out); // true if all selected objects have same BOOL selectionGetGlow(F32 *glow); +#if MESH_ENABLED + void selectionSetPhysicsType(U8 type); + void selectionSetGravity(F32 gravity); + void selectionSetFriction(F32 friction); + void selectionSetDensity(F32 density); + void selectionSetRestitution(F32 restitution); +#endif //MESH_ENABLED void selectionSetMaterial(U8 material); void selectionSetImage(const LLUUID& imageid); // could be item or asset id void selectionSetColor(const LLColor4 &color); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 3d091dc24..57e8b5d18 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -66,6 +66,7 @@ #include "lldrawable.h" #include "llface.h" #include "llfloaterproperties.h" +#include "llfloatertools.h" #include "llfollowcam.h" #include "llselectmgr.h" #include "llrendersphere.h" @@ -178,6 +179,13 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mGLName(0), mbCanSelect(TRUE), mFlags(0), +#if MESH_ENABLED + mPhysicsShapeType(0), + mPhysicsGravity(0), + mPhysicsFriction(0), + mPhysicsDensity(0), + mPhysicsRestitution(0), +#endif //MESH_ENABLED mDrawable(), mCreateSelected(FALSE), mRenderMedia(FALSE), @@ -210,6 +218,14 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mState(0), mMedia(NULL), mClickAction(0), +#if MESH_ENABLED + mObjectCost(0), + mLinksetCost(0), + mPhysicsCost(0), + mLinksetPhysicsCost(0.f), + mCostStale(true), + mPhysicsShapeUnknown(true), +#endif //MESH_ENABLED mAttachmentItemID(LLUUID::null), mLastUpdateType(OUT_UNKNOWN), mLastUpdateCached(FALSE) @@ -791,6 +807,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #ifdef DEBUG_UPDATE_TYPE llinfos << "Full:" << getID() << llendl; #endif +#if MESH_ENABLED + //clear cost and linkset cost + mCostStale = true; + if (isSelected()) + { + gFloaterTools->dirty(); + } +#endif //MESH_ENABLED LLUUID audio_uuid; LLUUID owner_id; // only valid if audio_uuid or particle system is not null F32 gain; @@ -1389,6 +1413,15 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #ifdef DEBUG_UPDATE_TYPE llinfos << "CompFull:" << getID() << llendl; #endif + +#if MESH_ENABLED + mCostStale = true; + + if (isSelected()) + { + gFloaterTools->dirty(); + } +#endif //MESH_ENABLED dp->unpackU32(crc, "CRC"); mTotalCRC = crc; dp->unpackU8(material, "Material"); @@ -2912,6 +2945,108 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped) } } +#if MESH_ENABLED +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; +} +#endif //MESH_ENABLED + void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { if(mDrawable.isNull()) @@ -5060,7 +5195,7 @@ bool LLViewerObject::specialHoverCursor() const || (mClickAction != 0); } -void LLViewerObject::updateFlags() +void LLViewerObject::updateFlags(BOOL physics_changed) { LLViewerRegion* regionp = getRegion(); if(!regionp) return; @@ -5073,6 +5208,17 @@ void LLViewerObject::updateFlags() gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() ); gMessageSystem->addBOOL("IsPhantom", flagPhantom() ); gMessageSystem->addBOOL("CastsShadows", flagCastShadows() ); +#if MESH_ENABLED + 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() ); + } +#endif //MESH_ENABLED gMessageSystem->sendReliable( regionp->getHost() ); } @@ -5105,6 +5251,46 @@ BOOL LLViewerObject::setFlags(U32 flags, BOOL state) return setit; } +#if MESH_ENABLED +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; +} +#endif //MESH_ENABLED + void LLViewerObject::applyAngularVelocity(F32 dt) { //do target omega here @@ -5386,3 +5572,65 @@ LLVOAvatar* LLViewerObject::getAvatar() const return NULL; } + +#if MESH_ENABLED +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 + gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties"); + + +void LLViewerObject::updateQuota( const SelectionQuota& quota ) +{ + //update quotas + mSelectionQuota = quota; +} +#endif //MESH_ENABLED diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 3eefe1113..fadecd742 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -49,6 +49,9 @@ #include "v3dmath.h" #include "v3math.h" #include "llvertexbuffer.h" +#if MESH_ENABLED +#include "llaccountingquota.h" +#endif //MESH_ENABLED class LLAgent; // TODO: Get rid of this. class LLAudioSource; @@ -327,6 +330,23 @@ public: virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE); +#if MESH_ENABLED + 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(); +#endif //MESH_ENABLED void sendShapeUpdate(); // U8 getState() { return mState; } @@ -460,6 +480,14 @@ public: inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); } inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); } +#if MESH_ENABLED + 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; } +#endif //MESH_ENABLED + bool getIncludeInSearch() const; void setIncludeInSearch(bool include_in_search); @@ -473,8 +501,15 @@ public: void setRegion(LLViewerRegion *regionp); virtual void updateRegion(LLViewerRegion *regionp) {} - void updateFlags(); + void updateFlags(BOOL physics_changed = FALSE); BOOL setFlags(U32 flag, BOOL state); +#if MESH_ENABLED + void setPhysicsShapeType(U8 type); + void setPhysicsGravity(F32 gravity); + void setPhysicsFriction(F32 friction); + void setPhysicsDensity(F32 density); + void setPhysicsRestitution(F32 restitution); +#endif //MESH_ENABLED virtual void dump() const; static U32 getNumZombieObjects() { return sNumZombieObjects; } @@ -532,6 +567,15 @@ public: LL_VO_HUD_PART_GROUP = LL_PCODE_APP | 0xc0, } EVOType; +#if MESH_ENABLED + typedef enum e_physics_shape_types + { + PHYSICS_SHAPE_PRIM = 0, + PHYSICS_SHAPE_NONE, + PHYSICS_SHAPE_CONVEX_HULL, + } EPhysicsShapeType; +#endif //MESH_ENABLED + LLUUID mID; // unique within region, not unique across regions @@ -550,6 +594,15 @@ public: // Grabbed from UPDATE_FLAGS U32 mFlags; +#if MESH_ENABLED + // Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties + U8 mPhysicsShapeType; + F32 mPhysicsGravity; + F32 mPhysicsFriction; + F32 mPhysicsDensity; + F32 mPhysicsRestitution; +#endif //MESH_ENABLED + // Pipeline classes LLPointer mDrawable; @@ -604,6 +657,12 @@ protected: void deleteParticleSource(); void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); +#if MESH_ENABLED +public: + void updateQuota( const SelectionQuota& quota ); + const SelectionQuota& getQuota( void ) { return mSelectionQuota; } +#endif //MESH_ENABLED + 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 @@ -659,6 +718,17 @@ protected: U8 mState; // legacy LLViewerObjectMedia* mMedia; // NULL if no media associated U8 mClickAction; +#if MESH_ENABLED + F32 mObjectCost; //resource cost of this object or -1 if unknown + F32 mLinksetCost; + F32 mPhysicsCost; + F32 mLinksetPhysicsCost; + + SelectionQuota mSelectionQuota; + + bool mCostStale; + mutable bool mPhysicsShapeUnknown; +#endif //MESH_ENABLED static U32 sNumZombieObjects; // Objects which are dead, but not deleted diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 9be2aacc3..94f532306 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -671,6 +671,192 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) LLVOAvatar::cullAvatarsByPixelArea(); } +#if MESH_ENABLED + +class LLObjectCostResponder : public LLCurl::Responder +{ +public: + LLObjectCostResponder(const LLSD& object_ids) + : mObjectIDs(object_ids) + { + } + + // Clear's the global object list's pending + // request list for all objects requested + void clear_object_list_pending_requests() + { + // TODO*: No more hard coding + for ( + LLSD::array_iterator iter = mObjectIDs.beginArray(); + iter != mObjectIDs.endArray(); + ++iter) + { + gObjectList.onObjectCostFetchFailure(iter->asUUID()); + } + } + + void error(U32 statusNum, const std::string& reason) + { + llwarns + << "Transport error requesting object cost " + << "HTTP status: " << statusNum << ", reason: " + << reason << "." << llendl; + + // TODO*: Error message to user + // For now just clear the request from the pending list + clear_object_list_pending_requests(); + } + + void result(const LLSD& content) + { + if ( !content.isMap() || content.has("error") ) + { + // Improper response or the request had an error, + // show an error to the user? + llwarns + << "Application level error when fetching object " + << "cost. Message: " << content["error"]["message"].asString() + << ", identifier: " << content["error"]["identifier"].asString() + << llendl; + + // TODO*: Adaptively adjust request size if the + // service says we've requested too many and retry + + // TODO*: Error message if not retrying + clear_object_list_pending_requests(); + return; + } + + // Success, grab the resource cost and linked set costs + // for an object if one was returned + for ( + LLSD::array_iterator iter = mObjectIDs.beginArray(); + iter != mObjectIDs.endArray(); + ++iter) + { + LLUUID object_id = iter->asUUID(); + + // Check to see if the request contains data for the object + if ( content.has(iter->asString()) ) + { + F32 link_cost = + content[iter->asString()]["linked_set_resource_cost"].asReal(); + F32 object_cost = + content[iter->asString()]["resource_cost"].asReal(); + + F32 physics_cost = content[iter->asString()]["physics_cost"].asReal(); + F32 link_physics_cost = content[iter->asString()]["linked_set_physics_cost"].asReal(); + + gObjectList.updateObjectCost(object_id, object_cost, link_cost, physics_cost, link_physics_cost); + } + else + { + // TODO*: Give user feedback about the missing data? + gObjectList.onObjectCostFetchFailure(object_id); + } + } + } + +private: + LLSD mObjectIDs; +}; + + +class LLPhysicsFlagsResponder : public LLCurl::Responder +{ +public: + LLPhysicsFlagsResponder(const LLSD& object_ids) + : mObjectIDs(object_ids) + { + } + + // Clear's the global object list's pending + // request list for all objects requested + void clear_object_list_pending_requests() + { + // TODO*: No more hard coding + for ( + LLSD::array_iterator iter = mObjectIDs.beginArray(); + iter != mObjectIDs.endArray(); + ++iter) + { + gObjectList.onPhysicsFlagsFetchFailure(iter->asUUID()); + } + } + + void error(U32 statusNum, const std::string& reason) + { + llwarns + << "Transport error requesting object physics flags " + << "HTTP status: " << statusNum << ", reason: " + << reason << "." << llendl; + + // TODO*: Error message to user + // For now just clear the request from the pending list + clear_object_list_pending_requests(); + } + + void result(const LLSD& content) + { + if ( !content.isMap() || content.has("error") ) + { + // Improper response or the request had an error, + // show an error to the user? + llwarns + << "Application level error when fetching object " + << "physics flags. Message: " << content["error"]["message"].asString() + << ", identifier: " << content["error"]["identifier"].asString() + << llendl; + + // TODO*: Adaptively adjust request size if the + // service says we've requested too many and retry + + // TODO*: Error message if not retrying + clear_object_list_pending_requests(); + return; + } + + // Success, grab the resource cost and linked set costs + // for an object if one was returned + for ( + LLSD::array_iterator iter = mObjectIDs.beginArray(); + iter != mObjectIDs.endArray(); + ++iter) + { + LLUUID object_id = iter->asUUID(); + + // Check to see if the request contains data for the object + if ( content.has(iter->asString()) ) + { + const LLSD& data = content[iter->asString()]; + + S32 shape_type = data["PhysicsShapeType"].asInteger(); + + gObjectList.updatePhysicsShapeType(object_id, shape_type); + + if (data.has("Density")) + { + F32 density = data["Density"].asReal(); + F32 friction = data["Friction"].asReal(); + F32 restitution = data["Restitution"].asReal(); + F32 gravity_multiplier = data["GravityMultiplier"].asReal(); + + gObjectList.updatePhysicsProperties(object_id, + density, friction, restitution, gravity_multiplier); + } + } + else + { + // TODO*: Give user feedback about the missing data? + gObjectList.onPhysicsFlagsFetchFailure(object_id); + } + } + } + +private: + LLSD mObjectIDs; +}; +#endif //MESH_ENABLED void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) { @@ -763,6 +949,10 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) } } +#if MESH_ENABLED + fetchObjectCosts(); + fetchPhysicsFlags(); +#endif //MESH_ENABLED mNumSizeCulled = 0; mNumVisCulled = 0; @@ -828,6 +1018,124 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) mNumVisCulledStat.addValue(mNumVisCulled); } +#if MESH_ENABLED +void LLViewerObjectList::fetchObjectCosts() +{ + // issue http request for stale object physics costs + if (!mStaleObjectCost.empty()) + { + LLViewerRegion* regionp = gAgent.getRegion(); + + if (regionp) + { + std::string url = regionp->getCapability("GetObjectCost"); + + if (!url.empty()) + { + LLSD id_list; + U32 object_index = 0; + + U32 count = 0; + + for ( + std::set::iterator iter = mStaleObjectCost.begin(); + iter != mStaleObjectCost.end(); + ) + { + // Check to see if a request for this object + // has already been made. + if ( mPendingObjectCost.find(*iter) == + mPendingObjectCost.end() ) + { + mPendingObjectCost.insert(*iter); + id_list[object_index++] = *iter; + } + + mStaleObjectCost.erase(iter++); + + if (count++ >= 450) + { + break; + } + } + + if ( id_list.size() > 0 ) + { + LLSD post_data = LLSD::emptyMap(); + + post_data["object_ids"] = id_list; + LLHTTPClient::post( + url, + post_data, + new LLObjectCostResponder(id_list)); + } + } + else + { + mStaleObjectCost.clear(); + mPendingObjectCost.clear(); + } + } + } +} + +void LLViewerObjectList::fetchPhysicsFlags() +{ + // issue http request for stale object physics flags + if (!mStalePhysicsFlags.empty()) + { + LLViewerRegion* regionp = gAgent.getRegion(); + + if (regionp) + { + std::string url = regionp->getCapability("GetObjectPhysicsData"); + + if (!url.empty()) + { + LLSD id_list; + U32 object_index = 0; + + for ( + std::set::iterator iter = mStalePhysicsFlags.begin(); + iter != mStalePhysicsFlags.end(); + ++iter) + { + // Check to see if a request for this object + // has already been made. + if ( mPendingPhysicsFlags.find(*iter) == + mPendingPhysicsFlags.end() ) + { + mPendingPhysicsFlags.insert(*iter); + id_list[object_index++] = *iter; + } + } + + // id_list should now contain all + // requests in mStalePhysicsFlags before, so clear + // it now + mStalePhysicsFlags.clear(); + + if ( id_list.size() > 0 ) + { + LLSD post_data = LLSD::emptyMap(); + + post_data["object_ids"] = id_list; + LLHTTPClient::post( + url, + post_data, + new LLPhysicsFlagsResponder(id_list)); + } + } + else + { + mStalePhysicsFlags.clear(); + mPendingPhysicsFlags.clear(); + } + } + } +} +#endif //MESH_ENABLED + void LLViewerObjectList::clearDebugText() { for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) @@ -1084,6 +1392,84 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) } } +#if MESH_ENABLED +void LLViewerObjectList::updateObjectCost(LLViewerObject* object) +{ + if (!object->isRoot()) + { //always fetch cost for the parent when fetching cost for children + mStaleObjectCost.insert(((LLViewerObject*)object->getParent())->getID()); + } + mStaleObjectCost.insert(object->getID()); +} + +void LLViewerObjectList::updateObjectCost(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost) +{ + mPendingObjectCost.erase(object_id); + + LLViewerObject* object = findObject(object_id); + if (object) + { + object->setObjectCost(object_cost); + object->setLinksetCost(link_cost); + object->setPhysicsCost(physics_cost); + object->setLinksetPhysicsCost(link_physics_cost); + } +} + +void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id) +{ + //llwarns << "Failed to fetch object cost for object: " << object_id << llendl; + mPendingObjectCost.erase(object_id); +} + +void LLViewerObjectList::updateQuota( 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()); +} + +void LLViewerObjectList::updatePhysicsShapeType(const LLUUID& object_id, S32 type) +{ + mPendingPhysicsFlags.erase(object_id); + LLViewerObject* object = findObject(object_id); + if (object) + { + object->setPhysicsShapeType(type); + } +} + +void LLViewerObjectList::updatePhysicsProperties(const LLUUID& object_id, + F32 density, + F32 friction, + F32 restitution, + F32 gravity_multiplier) +{ + mPendingPhysicsFlags.erase(object_id); + + LLViewerObject* object = findObject(object_id); + if (object) + { + object->setPhysicsDensity(density); + object->setPhysicsFriction(friction); + object->setPhysicsGravity(gravity_multiplier); + object->setPhysicsRestitution(restitution); + } +} + +void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id) +{ + //llwarns << "Failed to fetch physics flags for object: " << object_id << llendl; + mPendingPhysicsFlags.erase(object_id); +} +#endif //MESH_ENABLED void LLViewerObjectList::shiftObjects(const LLVector3 &offset) diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 90d100044..c47ace52e 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -44,6 +44,7 @@ #include "llviewerobject.h" #include "llvoavatar.h" +class LLCamera; class LLNetMap; class LLDebugBeacon; @@ -94,6 +95,25 @@ public: void updateApparentAngles(LLAgent &agent); void update(LLAgent &agent, LLWorld &world); +#if MESH_ENABLED + void fetchObjectCosts(); + void fetchPhysicsFlags(); + + void updateObjectCost(LLViewerObject* object); + void updateObjectCost(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost); + void onObjectCostFetchFailure(const LLUUID& object_id); + + void updatePhysicsFlags(const LLViewerObject* object); + void onPhysicsFlagsFetchFailure(const LLUUID& object_id); + void updatePhysicsShapeType(const LLUUID& object_id, S32 type); + void updatePhysicsProperties(const LLUUID& object_id, + F32 density, + F32 friction, + F32 restitution, + F32 gravity_multiplier); + + void updateQuota( const LLUUID& objectId, const SelectionQuota& costs ); +#endif //MESH_ENABLED void shiftObjects(const LLVector3 &offset); void repartitionObjects(); @@ -212,6 +232,16 @@ protected: std::map > mUUIDObjectMap; std::map > mUUIDAvatarMap; +#if MESH_ENABLED + //set of objects that need to update their cost + std::set mStaleObjectCost; + std::set mPendingObjectCost; + + //set of objects that need to update their physics flags + std::set mStalePhysicsFlags; + std::set mPendingPhysicsFlags; +#endif //MESH_ENABLED + std::vector mDebugBeacons; S32 mCurLazyUpdateIndex; diff --git a/indra/newview/skins/default/xui/en-us/floater_tools.xml b/indra/newview/skins/default/xui/en-us/floater_tools.xml index 295ac58c7..b303cb50b 100644 --- a/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -301,9 +301,7 @@ - primitives: [COUNT] - + mouse_opaque="true" name="prim_count" v_pad="0" width="143"/> @@ -1011,6 +1009,9 @@ + None + Prim + Convex Hull + width="118" /> + width="118" /> + width="118" /> + increment="0.5" initial_val="0" label="Wind" label_width="55" left="10" + max_val="10" min_val="0" mouse_opaque="true" name="FlexWind" width="118" /> + increment="0.5" initial_val="1" label="Tension" label_width="55" left="10" + max_val="10" min_val="0" mouse_opaque="true" name="FlexTension" width="118" /> + width="118" /> + width="118" /> + width="118" /> - + ncrement="0.05" + initial_val="1" + label="Ambiance" + label_width="55" + max_val="1" + min_val="0" + mouse_opaque="true" + name="Light Ambiance" + width="118" /> + + Physics Shape Type: + + + + + + + + + @@ -1469,4 +1560,10 @@ Attachment + + , Cost: [SEL_WEIGHT] + + + Primitives: [COUNT][PE_STRING] + diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index d56bda3f6..d3acb611e 100644 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -2061,6 +2061,15 @@ version 2.0 { IsPhantom BOOL } { CastsShadows BOOL } } + { + ExtraPhysics Variable + { PhysicsShapeType U8 } + { Density F32 } + { Friction F32 } + { Restitution F32 } + { GravityMultiplier F32 } + + } }