Added physics settings to object features panel. Brought in mesh 'prim cost' fetching and now display cost in edit floater if mesh is enabled.

This commit is contained in:
Shyotl
2011-08-01 01:33:07 -05:00
parent 5e9cec2cc5
commit 2aa4aa78e2
22 changed files with 1977 additions and 235 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 )

View File

@@ -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;
}

View File

@@ -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 )
{

View File

@@ -93,6 +93,8 @@ void LLUICtrl::onCommit()
{
mCommitCallback( this, mCallbackUserData );
}
if (mCommitSignal)
(*mCommitSignal)(this, getValue());
}
//virtual

View File

@@ -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

View File

@@ -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 "<<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 containsParcel = content.has("parcel");
bool containsSelection = content.has("selected");
//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
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 "<<llendl;
mUpdateObjectQuota.clear();
mPendingObjectQuota.clear();
}
}
//===============================================================================
void LLAccountingQuotaManager::updateObjectCost( const LLUUID& objectID )
{
mUpdateObjectQuota.insert( objectID );
}
//===============================================================================
void LLAccountingQuotaManager::removePendingObjectQuota( const LLUUID& objectID )
{
mPendingObjectQuota.erase( objectID );
}
//===============================================================================
#endif //MESH_ENABLED

View File

@@ -0,0 +1,55 @@
/**
* @file lllAccountingQuotaManager.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_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 // LLACCOUNTINGQUOTAMANAGER

View File

@@ -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();

View File

@@ -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<LLUICtrl>("FlexNumSections")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("FlexGravity",onCommitFlexible,this);
childSetValidate("FlexGravity",precommitValidate);
getChild<LLUICtrl>("FlexGravity")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("FlexFriction",onCommitFlexible,this);
childSetValidate("FlexFriction",precommitValidate);
getChild<LLUICtrl>("FlexFriction")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("FlexWind",onCommitFlexible,this);
childSetValidate("FlexWind",precommitValidate);
getChild<LLUICtrl>("FlexWind")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("FlexTension",onCommitFlexible,this);
childSetValidate("FlexTension",precommitValidate);
getChild<LLUICtrl>("FlexTension")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("FlexForceX",onCommitFlexible,this);
childSetValidate("FlexForceX",precommitValidate);
getChild<LLUICtrl>("FlexForceX")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("FlexForceY",onCommitFlexible,this);
childSetValidate("FlexForceY",precommitValidate);
getChild<LLUICtrl>("FlexForceY")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("FlexForceZ",onCommitFlexible,this);
childSetValidate("FlexForceZ",precommitValidate);
getChild<LLUICtrl>("FlexForceZ")->setValidateBeforeCommit(precommitValidate);
}
// LIGHT Parameters
@@ -123,20 +128,47 @@ BOOL LLPanelVolume::postBuild()
}
childSetCommitCallback("Light Intensity",onCommitLight,this);
childSetValidate("Light Intensity",precommitValidate);
getChild<LLUICtrl>("Light Intensity")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("Light Radius",onCommitLight,this);
childSetValidate("Light Radius",precommitValidate);
getChild<LLUICtrl>("Light Radius")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("Light Falloff",onCommitLight,this);
childSetValidate("Light Falloff",precommitValidate);
getChild<LLUICtrl>("Light Falloff")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("Light FOV", onCommitLight, this);
childSetValidate("Light FOV", precommitValidate);
getChild<LLUICtrl>("Light FOV")->setValidateBeforeCommit( precommitValidate);
childSetCommitCallback("Light Focus", onCommitLight, this);
childSetValidate("Light Focus", precommitValidate);
getChild<LLUICtrl>("Light Focus")->setValidateBeforeCommit( precommitValidate);
childSetCommitCallback("Light Ambiance", onCommitLight, this);
childSetValidate("Light Ambiance", precommitValidate);
getChild<LLUICtrl>("Light Ambiance")->setValidateBeforeCommit( precommitValidate);
}
#if MESH_ENABLED
// PHYSICS Parameters
{
// Label
mComboPhysicsShapeLabel = getChild<LLTextBox>("label physicsshapetype");
// PhysicsShapeType combobox
mComboPhysicsShapeType = getChild<LLComboBox>("Physics Shape Type Combo Ctrl");
mComboPhysicsShapeType->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsShapeType, this, _1, mComboPhysicsShapeType));
// PhysicsGravity
mSpinPhysicsGravity = getChild<LLSpinCtrl>("Physics Gravity");
mSpinPhysicsGravity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsGravity, this, _1, mSpinPhysicsGravity));
// PhysicsFriction
mSpinPhysicsFriction = getChild<LLSpinCtrl>("Physics Friction");
mSpinPhysicsFriction->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsFriction, this, _1, mSpinPhysicsFriction));
// PhysicsDensity
mSpinPhysicsDensity = getChild<LLSpinCtrl>("Physics Density");
mSpinPhysicsDensity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsDensity, this, _1, mSpinPhysicsDensity));
// PhysicsRestitution
mSpinPhysicsRestitution = getChild<LLSpinCtrl>("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<LLUICtrl>("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<LLColorSwatchCtrl>("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<LLUICtrl>("Light Intensity")->setValue(volobjp->getLightIntensity());
getChild<LLUICtrl>("Light Radius")->setValue(volobjp->getLightRadius());
getChild<LLUICtrl>("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<LLUICtrl>("Light FOV")->setValue(params.mV[0]);
getChild<LLUICtrl>("Light Focus")->setValue(params.mV[1]);
getChild<LLUICtrl>("Light Ambiance")->setValue(params.mV[2]);
mLightSavedColor = volobjp->getLightColor();
}
@@ -273,7 +306,7 @@ void LLPanelVolume::getState( )
getChild<LLSpinCtrl>("Light Radius", true)->clear();
getChild<LLSpinCtrl>("Light Falloff", true)->clear();
childSetEnabled("label color",false);
getChildView("label color")->setEnabled(false);
LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("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<LLUICtrl>("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<LLUICtrl>("FlexNumSections")->setValue((F32)attributes->getSimulateLOD());
getChild<LLUICtrl>("FlexGravity")->setValue(attributes->getGravity());
getChild<LLUICtrl>("FlexTension")->setValue(attributes->getTension());
getChild<LLUICtrl>("FlexFriction")->setValue(attributes->getAirFriction());
getChild<LLUICtrl>("FlexWind")->setValue(attributes->getWindSensitivity());
getChild<LLUICtrl>("FlexForceX")->setValue(attributes->getUserForce().mV[VX]);
getChild<LLUICtrl>("FlexForceY")->setValue(attributes->getUserForce().mV[VY]);
getChild<LLUICtrl>("FlexForceZ")->setValue(attributes->getUserForce().mV[VZ]);
}
else
{
@@ -349,22 +387,73 @@ void LLPanelVolume::getState( )
getChild<LLSpinCtrl>("FlexForceY", true)->clear();
getChild<LLSpinCtrl>("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<LLColorSwatchCtrl>("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<LLUICtrl>("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<LLUICtrl>("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<LLUICtrl>("Light Intensity")->getValue().asReal());
volobjp->setLightRadius((F32)self->getChild<LLUICtrl>("Light Radius")->getValue().asReal());
volobjp->setLightFalloff((F32)self->getChild<LLUICtrl>("Light Falloff")->getValue().asReal());
LLColorSwatchCtrl* LightColorSwatch = self->getChild<LLColorSwatchCtrl>("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<LLUICtrl>("FlexNumSections")->getValue().asInteger());//(S32)self->mSpinSections->get());
new_attributes.setGravity((F32)self->getChild<LLUICtrl>("FlexGravity")->getValue().asReal());
new_attributes.setTension((F32)self->getChild<LLUICtrl>("FlexTension")->getValue().asReal());
new_attributes.setAirFriction((F32)self->getChild<LLUICtrl>("FlexFriction")->getValue().asReal());
new_attributes.setWindSensitivity((F32)self->getChild<LLUICtrl>("FlexWind")->getValue().asReal());
F32 fx = (F32)self->getChild<LLUICtrl>("FlexForceX")->getValue().asReal();
F32 fy = (F32)self->getChild<LLUICtrl>("FlexForceY")->getValue().asReal();
F32 fz = (F32)self->getChild<LLUICtrl>("FlexForceZ")->getValue().asReal();
LLVector3 force(fx,fy,fz);
new_attributes.setUserForce(force);

View File

@@ -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<LLViewerObject> mObject;
LLPointer<LLViewerObject> mRootObject;
#if MESH_ENABLED
LLTextBox* mComboPhysicsShapeLabel;
LLComboBox* mComboPhysicsShapeType;
LLSpinCtrl* mSpinPhysicsGravity;
LLSpinCtrl* mSpinPhysicsFriction;
LLSpinCtrl* mSpinPhysicsDensity;
LLSpinCtrl* mSpinPhysicsRestitution;
#endif //MESH_ENABLED
};
#endif

View File

@@ -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<LLViewerObject*> me_roots;
for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
{
LLSelectNode* node = *iter;
LLViewerObject* object = node->getObject();
if (object)
{
LLViewerObject* root = static_cast<LLViewerObject*>(object->getRoot());
if (root)
{
if (me_roots.find(root) == me_roots.end())
{
me_roots.insert(root);
cost += root->getLinksetCost();
}
}
}
}
return cost;
}
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<LLViewerObject*> me_roots;
for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
{
LLSelectNode* node = *iter;
LLViewerObject* object = node->getObject();
if (object)
{
LLViewerObject* root = static_cast<LLViewerObject*>(object->getRoot());
if (root)
{
if (me_roots.find(root) == me_roots.end())
{
me_roots.insert(root);
cost += root->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()

View File

@@ -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);

View File

@@ -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<ObjectPhysicsProperties>
gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties");
void LLViewerObject::updateQuota( const SelectionQuota& quota )
{
//update quotas
mSelectionQuota = quota;
}
#endif //MESH_ENABLED

View File

@@ -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<LLDrawable> 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

View File

@@ -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<LLUUID>::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<LLUUID>::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)

View File

@@ -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<LLUUID, LLPointer<LLViewerObject> > mUUIDObjectMap;
std::map<LLUUID, LLPointer<LLVOAvatar> > mUUIDAvatarMap;
#if MESH_ENABLED
//set of objects that need to update their cost
std::set<LLUUID> mStaleObjectCost;
std::set<LLUUID> mPendingObjectCost;
//set of objects that need to update their physics flags
std::set<LLUUID> mStalePhysicsFlags;
std::set<LLUUID> mPendingPhysicsFlags;
#endif //MESH_ENABLED
std::vector<LLDebugBeacon> mDebugBeacons;
S32 mCurLazyUpdateIndex;

View File

@@ -301,9 +301,7 @@
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom="-163" left="118" drop_shadow_visible="true" follows="left|top"
font="SansSerifSmall" h_pad="0" halign="right" height="16"
mouse_opaque="true" name="prim_count" v_pad="0" width="143">
primitives: [COUNT]
</text>
mouse_opaque="true" name="prim_count" v_pad="0" width="143"/>
<!-- Sub-tabs -->
@@ -1011,6 +1009,9 @@
<panel border="true" bottom="-383" follows="left|top|right|bottom" height="367"
label="Features" left="1" mouse_opaque="false" name="Features" width="270">
<string name="None">None</string>
<string name="Prim">Prim</string>
<string name="Convex Hull">Convex Hull</string>
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom="-20" drop_shadow_visible="true" follows="left|top"
font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
@@ -1029,35 +1030,35 @@
tool_tip="Allows object to flex about the Z axis. (Client-side only)"
width="121" />
<spinner bottom_delta="-20" decimal_digits="5" follows="left|top" height="16"
increment="1" initial_val="2" label="Softness" label_width="65" left="10"
increment="1" initial_val="2" label="Softness" label_width="55" left="10"
max_val="3" min_val="0" mouse_opaque="true" name="FlexNumSections"
width="128" />
width="118" />
<spinner bottom_delta="-20" decimal_digits="5" follows="left|top" height="16"
increment="0.5" initial_val="0.3" label="Gravity" label_width="65"
increment="0.5" initial_val="0.3" label="Gravity" label_width="55"
left="10" max_val="10" min_val="-10" mouse_opaque="true" name="FlexGravity"
width="128" />
width="118" />
<spinner bottom_delta="-20" decimal_digits="5" follows="left|top" height="16"
increment="0.5" initial_val="2" label="Drag" label_width="65" left="10"
increment="0.5" initial_val="2" label="Drag" label_width="55" left="10"
max_val="10" min_val="0" mouse_opaque="true" name="FlexFriction"
width="128" />
width="118" />
<spinner bottom_delta="-20" decimal_digits="5" follows="left|top" height="16"
increment="0.5" initial_val="0" label="Wind" label_width="65" left="10"
max_val="10" min_val="0" mouse_opaque="true" name="FlexWind" width="128" />
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" />
<spinner bottom_delta="-20" decimal_digits="5" follows="left|top" height="16"
increment="0.5" initial_val="1" label="Tension" label_width="65" left="10"
max_val="10" min_val="0" mouse_opaque="true" name="FlexTension" width="128" />
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" />
<spinner bottom_delta="-20" decimal_digits="5" follows="left|top" height="16"
increment="0.01" initial_val="0" label="Force X" label_width="65" left="10"
increment="0.01" initial_val="0" label="Force X" label_width="55" left="10"
max_val="10" min_val="-10" mouse_opaque="true" name="FlexForceX"
width="128" />
width="118" />
<spinner bottom_delta="-20" decimal_digits="5" follows="left|top" height="16"
increment="0.01" initial_val="0" label="Force Y" label_width="65" left="10"
increment="0.01" initial_val="0" label="Force Y" label_width="55" left="10"
max_val="10" min_val="-10" mouse_opaque="true" name="FlexForceY"
width="128" />
width="118" />
<spinner bottom_delta="-20" decimal_digits="5" follows="left|top" height="16"
increment="0.01" initial_val="0" label="Force Z" label_width="65" left="10"
increment="0.01" initial_val="0" label="Force Z" label_width="55" left="10"
max_val="10" min_val="-10" mouse_opaque="true" name="FlexForceZ"
width="128" />
width="118" />
<check_box bottom_delta="-30" follows="left|top" font="SansSerifSmall" height="16"
initial_value="false" label="Light" left="10" mouse_opaque="true"
name="Light Checkbox Ctrl" tool_tip="Causes object to emit light"
@@ -1123,12 +1124,102 @@
max_val="2" min_val="0" mouse_opaque="true"
name="Light Falloff"
width="108" />
<spinner bottom_delta="0" decimal_digits="3" follows="left|top" height="16"
<spinner bottom_delta="0"
decimal_digits="3"
follows="left|top"
height="16"
left_delta="114"
increment="0.05" initial_val="1" label="Ambiance" label_width="55"
max_val="1" min_val="0" mouse_opaque="true"
name="Light Ambiance"
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" />
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
name="label physicsshapetype"
left_delta="13"
bottom="-41"
width="121">
Physics Shape Type:
</text>
<combo_box
height="19"
bottom_delta="-26"
layout="topleft"
follows="left|top"
name="Physics Shape Type Combo Ctrl"
tool_tip="Choose the physics shape type"
width="108"/>
<spinner
follows="left|top"
height="19"
increment="1"
initial_value="1"
label="Gravity"
label_width="55"
layout="topleft"
min_val="-1"
max_val="28"
name="Physics Gravity"
top_pad="10"
width="118" />
<spinner
follows="left|top"
height="19"
increment="0.1"
initial_value="0"
label="Friction"
label_width="55"
layout="topleft"
left_delta="0"
max_val="255"
min_val="0"
name="Physics Friction"
top_pad="4"
bottom_delta="-20"
width="118" />
<spinner
follows="left|top"
height="19"
increment="0.1"
initial_value="0"
label="Density"
label_width="55"
label_wrap="true"
layout="topleft"
left_delta="0"
max_val="22587"
min_val="1"
name="Physics Density"
top_pad="4"
bottom_delta="-20"
width="118" />
<spinner
follows="left|top"
height="19"
increment="0.01"
initial_value="0"
label="Restitution"
label_width="55"
layout="topleft"
left_delta="0"
max_val="1"
min_val="0"
name="Physics Restitution"
top_pad="8"
bottom_delta="-20"
width="118" />
</panel>
<!-- Texture sub-tab -->
@@ -1469,4 +1560,10 @@
<string name="grid_attachment_text">
Attachment
</string>
<string name="status_selectprimequiv">
, Cost: [SEL_WEIGHT]
</string>
<string name="status_selectcount">
Primitives: [COUNT][PE_STRING]
</string>
</floater>