summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/llaccountingcost.h (renamed from indra/llcommon/llaccountingquota.h)24
-rw-r--r--indra/llinventory/llparcel.cpp9
-rw-r--r--indra/llinventory/llparcel.h5
-rw-r--r--indra/llmath/llmath.h7
-rw-r--r--indra/llmath/llvolume.cpp177
-rw-r--r--indra/llmath/llvolume.h6
-rw-r--r--indra/llprimitive/llmodel.cpp85
-rw-r--r--indra/llprimitive/llmodel.h22
-rw-r--r--indra/llwindow/llwindowmacosx.cpp1
-rw-r--r--indra/llwindow/llwindowsdl.cpp3
-rw-r--r--indra/llwindow/llwindowwin32.cpp1
-rw-r--r--indra/newview/CMakeLists.txt6
-rw-r--r--indra/newview/app_settings/settings.xml97
-rwxr-xr-x[-rw-r--r--]indra/newview/featuretable.txt2
-rw-r--r--indra/newview/llaccountingcostmanager.cpp181
-rw-r--r--indra/newview/llaccountingcostmanager.h (renamed from indra/newview/llaccountingquotamanager.h)42
-rw-r--r--indra/newview/llaccountingquotamanager.cpp278
-rw-r--r--indra/newview/llchathistory.cpp2
-rw-r--r--indra/newview/lldrawpoolavatar.cpp41
-rw-r--r--indra/newview/llfloatermodelpreview.cpp1286
-rw-r--r--indra/newview/llfloatermodelpreview.h39
-rw-r--r--indra/newview/llfloaterobjectweights.cpp266
-rw-r--r--indra/newview/llfloaterobjectweights.h93
-rw-r--r--indra/newview/llfloaterregioninfo.cpp52
-rw-r--r--indra/newview/llfloaterregioninfo.h4
-rw-r--r--indra/newview/llfloatertools.cpp155
-rw-r--r--indra/newview/llfloatertools.h5
-rw-r--r--indra/newview/llmeshrepository.cpp150
-rw-r--r--indra/newview/llmeshrepository.h4
-rw-r--r--indra/newview/llpanelobject.cpp13
-rw-r--r--indra/newview/llpanelvolume.cpp2
-rw-r--r--indra/newview/llselectmgr.cpp67
-rw-r--r--indra/newview/llspatialpartition.cpp116
-rw-r--r--indra/newview/llviewercontrol.cpp10
-rw-r--r--indra/newview/llviewerfloaterreg.cpp4
-rwxr-xr-xindra/newview/llviewerobject.cpp21
-rw-r--r--indra/newview/llviewerobject.h12
-rw-r--r--indra/newview/llviewerobjectlist.cpp13
-rw-r--r--indra/newview/llviewerobjectlist.h3
-rw-r--r--indra/newview/llviewerparceloverlay.cpp59
-rw-r--r--indra/newview/llviewerparceloverlay.h1
-rw-r--r--indra/newview/llviewerregion.cpp13
-rw-r--r--indra/newview/llviewerregion.h1
-rw-r--r--indra/newview/llvoavatar.cpp54
-rw-r--r--indra/newview/llvoavatar.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llvovolume.cpp279
-rw-r--r--indra/newview/llvovolume.h18
-rw-r--r--indra/newview/pipeline.h1
-rw-r--r--indra/newview/skins/default/colors.xml6
-rw-r--r--indra/newview/skins/default/textures/green_checkmark.pngbin0 -> 414 bytes
-rw-r--r--indra/newview/skins/default/textures/red_x.pngbin0 -> 624 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml8
-rw-r--r--indra/newview/skins/default/xui/en/floater_build_options.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_model_preview.xml2002
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_wizard.xml89
-rw-r--r--indra/newview/skins/default/xui/en/floater_object_weights.xml342
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml22
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_general.xml12
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml10
62 files changed, 4160 insertions, 2083 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 60d4cfe6d3..6f39aba976 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -117,7 +117,7 @@ set(llcommon_HEADER_FILES
indra_constants.h
linden_common.h
linked_lists.h
- llaccountingquota.h
+ llaccountingcost.h
llallocator.h
llallocator_heap_profile.h
llagentconstants.h
diff --git a/indra/llcommon/llaccountingquota.h b/indra/llcommon/llaccountingcost.h
index 140333de07..0ef3b50c6d 100644
--- a/indra/llcommon/llaccountingquota.h
+++ b/indra/llcommon/llaccountingcost.h
@@ -1,5 +1,5 @@
/**
- * @file llaccountingquota.h
+ * @file llaccountingcost.h
* @
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
@@ -58,22 +58,28 @@ struct ParcelQuota
F32 mParcelCapacity;
};
-struct SelectionQuota
+//SelectionQuota atm does not require a id
+struct SelectionCost
{
- SelectionQuota( LLUUID localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost )
- : mLocalId( localId)
- , mRenderCost( renderCost )
- , mPhysicsCost( physicsCost )
+ SelectionCost( /*LLTransactionID transactionId, */ F32 physicsCost, F32 networkCost, F32 simulationCost )
+ //: mTransactionId( transactionId)
+ : mPhysicsCost( physicsCost )
, mNetworkCost( networkCost )
, mSimulationCost( simulationCost )
{
}
- SelectionQuota() {}
+ SelectionCost()
+ : mPhysicsCost( 0.0f )
+ , mNetworkCost( 0.0f )
+ , mSimulationCost( 0.0f )
+ {}
- F32 mRenderCost, mPhysicsCost, mNetworkCost, mSimulationCost;
- LLUUID mLocalId;
+ F32 mPhysicsCost, mNetworkCost, mSimulationCost;
+ //LLTransactionID mTransactionId;
};
+typedef enum { Roots = 0 , Prims } eSelectionType;
+
#endif
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index c95f922301..433076c7a9 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -1373,12 +1373,3 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s)
// is a distinct option from "None" and "Other"
return LLParcel::C_ANY;
}
-
-void LLParcel::updateQuota( const LLUUID& objectId, const ParcelQuota& quota )
-{
- if ( mID == objectId )
- {
- mQuota = quota;
- }
-}
-
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index ff35caab4c..e36d0b20d2 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -34,7 +34,6 @@
#include "llpermissions.h"
#include "lltimer.h"
#include "v3math.h"
-#include "llaccountingquota.h"
// Grid out of which parcels taken is stepped every 4 meters.
const F32 PARCEL_GRID_STEP_METERS = 4.f;
@@ -603,9 +602,6 @@ public:
BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; }
- void updateQuota( const LLUUID& objectId, const ParcelQuota& quota );
- const ParcelQuota& getQuota( void ) { return mQuota; }
-
protected:
LLUUID mID;
LLUUID mOwnerID;
@@ -681,7 +677,6 @@ protected:
BOOL mAllowGroupAVSounds;
BOOL mAllowAnyAVSounds;
- ParcelQuota mQuota;
public:
// HACK, make private
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index eea7c977fb..9297bcbac2 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -510,6 +510,13 @@ inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k)
VEC_TYPE Q1 = data[data.size()/4];
VEC_TYPE Q3 = data[data.size()-data.size()/4-1];
+ if ((F32)(Q3-Q1) < 1.f)
+ {
+ // not enough variation to detect outliers
+ return;
+ }
+
+
VEC_TYPE min = (VEC_TYPE) ((F32) Q1-k * (F32) (Q3-Q1));
VEC_TYPE max = (VEC_TYPE) ((F32) Q3+k * (F32) (Q3-Q1));
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 2893e746e9..1a95f9cd46 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2078,7 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mFaceMask = 0x0;
mDetail = detail;
mSculptLevel = -2;
- mIsTetrahedron = FALSE;
+ mIsMeshAssetLoaded = FALSE;
mLODScaleBias.setVec(1,1,1);
mHullPoints = NULL;
mHullIndices = NULL;
@@ -2100,7 +2100,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
generate();
- if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE)
+ if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE || mParams.getSculptType() == LL_SCULPT_TYPE_MESH)
{
createVolumeFaces();
}
@@ -2408,7 +2408,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
LLSD mdl;
if (!unzip_llsd(mdl, is, size))
{
- llwarns << "not a valid mesh asset!" << llendl;
+ LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD, will probably fetch from sim again." << llendl;
return false;
}
@@ -2706,173 +2706,21 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
return true;
}
-void tetrahedron_set_normal(LLVolumeFace::VertexData* cv)
-{
- LLVector4a v0;
- v0.setSub(cv[1].getPosition(), cv[0].getNormal());
- LLVector4a v1;
- v1.setSub(cv[2].getNormal(), cv[0].getPosition());
-
- cv[0].getNormal().setCross3(v0,v1);
- cv[0].getNormal().normalize3fast();
- cv[1].setNormal(cv[0].getNormal());
- cv[2].setNormal(cv[1].getNormal());
-}
-BOOL LLVolume::isTetrahedron()
+BOOL LLVolume::isMeshAssetLoaded()
{
- return mIsTetrahedron;
+ return mIsMeshAssetLoaded;
}
-void LLVolume::makeTetrahedron()
+void LLVolume::setMeshAssetLoaded(BOOL loaded)
{
- mVolumeFaces.clear();
-
- LLVolumeFace face;
-
- F32 x = 0.25f;
- LLVector4a p[] =
- { //unit tetrahedron corners
- LLVector4a(x,x,x),
- LLVector4a(-x,-x,x),
- LLVector4a(-x,x,-x),
- LLVector4a(x,-x,-x)
- };
-
- face.mExtents[0].splat(-x);
- face.mExtents[1].splat(x);
-
- LLVolumeFace::VertexData cv[3];
-
- //set texture coordinates
- cv[0].mTexCoord = LLVector2(0,0);
- cv[1].mTexCoord = LLVector2(1,0);
- cv[2].mTexCoord = LLVector2(0.5f, 0.5f*F_SQRT3);
-
-
- //side 1
- cv[0].setPosition(p[1]);
- cv[1].setPosition(p[0]);
- cv[2].setPosition(p[2]);
-
- tetrahedron_set_normal(cv);
-
- face.resizeVertices(12);
- face.resizeIndices(12);
-
- LLVector4a* v = (LLVector4a*) face.mPositions;
- LLVector4a* n = (LLVector4a*) face.mNormals;
- LLVector2* tc = (LLVector2*) face.mTexCoords;
-
- v[0] = cv[0].getPosition();
- v[1] = cv[1].getPosition();
- v[2] = cv[2].getPosition();
- v += 3;
-
- n[0] = cv[0].getNormal();
- n[1] = cv[1].getNormal();
- n[2] = cv[2].getNormal();
- n += 3;
-
- if(tc)
- {
- tc[0] = cv[0].mTexCoord;
- tc[1] = cv[1].mTexCoord;
- tc[2] = cv[2].mTexCoord;
- tc += 3;
- }
-
- //side 2
- cv[0].setPosition(p[3]);
- cv[1].setPosition(p[0]);
- cv[2].setPosition(p[1]);
-
- tetrahedron_set_normal(cv);
-
- v[0] = cv[0].getPosition();
- v[1] = cv[1].getPosition();
- v[2] = cv[2].getPosition();
- v += 3;
-
- n[0] = cv[0].getNormal();
- n[1] = cv[1].getNormal();
- n[2] = cv[2].getNormal();
- n += 3;
-
- if(tc)
- {
- tc[0] = cv[0].mTexCoord;
- tc[1] = cv[1].mTexCoord;
- tc[2] = cv[2].mTexCoord;
- tc += 3;
- }
-
- //side 3
- cv[0].setPosition(p[3]);
- cv[1].setPosition(p[1]);
- cv[2].setPosition(p[2]);
-
- tetrahedron_set_normal(cv);
-
- v[0] = cv[0].getPosition();
- v[1] = cv[1].getPosition();
- v[2] = cv[2].getPosition();
- v += 3;
-
- n[0] = cv[0].getNormal();
- n[1] = cv[1].getNormal();
- n[2] = cv[2].getNormal();
- n += 3;
-
- if(tc)
- {
- tc[0] = cv[0].mTexCoord;
- tc[1] = cv[1].mTexCoord;
- tc[2] = cv[2].mTexCoord;
- tc += 3;
- }
-
- //side 4
- cv[0].setPosition(p[2]);
- cv[1].setPosition(p[0]);
- cv[2].setPosition(p[3]);
-
- tetrahedron_set_normal(cv);
-
- v[0] = cv[0].getPosition();
- v[1] = cv[1].getPosition();
- v[2] = cv[2].getPosition();
- v += 3;
-
- n[0] = cv[0].getNormal();
- n[1] = cv[1].getNormal();
- n[2] = cv[2].getNormal();
- n += 3;
-
- if(tc)
- {
- tc[0] = cv[0].mTexCoord;
- tc[1] = cv[1].mTexCoord;
- tc[2] = cv[2].mTexCoord;
- tc += 3;
- }
-
- //set index buffer
- for (U16 i = 0; i < 12; i++)
- {
- face.mIndices[i] = i;
- }
-
- mVolumeFaces.push_back(face);
- mSculptLevel = 0;
- mIsTetrahedron = TRUE;
+ mIsMeshAssetLoaded = loaded;
}
void LLVolume::copyVolumeFaces(const LLVolume* volume)
{
mVolumeFaces = volume->mVolumeFaces;
mSculptLevel = 0;
- mIsTetrahedron = FALSE;
}
void LLVolume::cacheOptimize()
@@ -2886,14 +2734,7 @@ void LLVolume::cacheOptimize()
S32 LLVolume::getNumFaces() const
{
- U8 sculpt_type = (mParams.getSculptType() & LL_SCULPT_TYPE_MASK);
-
- if (sculpt_type == LL_SCULPT_TYPE_MESH)
- {
- return LL_SCULPT_MESH_MAX_FACES;
- }
-
- return (S32)mProfilep->mFaces.size();
+ return mIsMeshAssetLoaded ? getNumVolumeFaces() : (S32)mProfilep->mFaces.size();
}
@@ -7269,7 +7110,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
resizeVertices(num_vertices);
resizeIndices(num_indices);
- if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
+ if (!volume->isMeshAssetLoaded())
{
mEdge.resize(num_indices);
}
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index f67f8f644d..f0e59a3c00 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -1058,14 +1058,14 @@ protected:
public:
virtual bool unpackVolumeFaces(std::istream& is, S32 size);
- virtual void makeTetrahedron();
- virtual BOOL isTetrahedron();
+ virtual void setMeshAssetLoaded(BOOL loaded);
+ virtual BOOL isMeshAssetLoaded();
protected:
BOOL mUnique;
F32 mDetail;
S32 mSculptLevel;
- BOOL mIsTetrahedron;
+ BOOL mIsMeshAssetLoaded;
LLVolumeParams mParams;
LLPath *mPathp;
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 434fb7650b..6e4bb7ec97 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1679,6 +1679,19 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
{
+ //1. If a vertex has been weighted then we'll find it via pos and return it's weight list
+ weight_map::iterator iterPos = mSkinWeights.begin();
+ weight_map::iterator iterEnd = mSkinWeights.end();
+
+ for ( ; iterPos!=iterEnd; ++iterPos )
+ {
+ if ( jointPositionalLookup( iterPos->first, pos ) )
+ {
+ return iterPos->second;
+ }
+ }
+
+ //2. Otherwise we'll use the older implementation
weight_map::iterator iter = mSkinWeights.find(pos);
if (iter != mSkinWeights.end())
@@ -1692,13 +1705,13 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
}
else
{ //no exact match found, get closest point
- const F32 epsilon = 2.f/65536;
+ const F32 epsilon = 1e-5f;
weight_map::iterator iter_up = mSkinWeights.lower_bound(pos);
weight_map::iterator iter_down = ++iter_up;
weight_map::iterator best = iter_up;
- F32 min_dist = (iter->first - pos).magVecSquared();
+ F32 min_dist = (iter->first - pos).magVec();
bool done = false;
while (!done)
@@ -1709,7 +1722,7 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
if (iter_up != mSkinWeights.end() && ++iter_up != mSkinWeights.end())
{
done = false;
- F32 dist = (iter_up->first - pos).magVecSquared();
+ F32 dist = (iter_up->first - pos).magVec();
if (dist < epsilon)
{
@@ -1727,7 +1740,7 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
{
done = false;
- F32 dist = (iter_down->first - pos).magVecSquared();
+ F32 dist = (iter_down->first - pos).magVec();
if (dist < epsilon)
{
@@ -1890,14 +1903,71 @@ bool LLModel::loadModel(std::istream& is)
}
-void LLModel::matchMaterialOrder(LLModel* ref)
+bool LLModel::isMaterialListSubset( LLModel* ref )
{
- llassert(ref->mMaterialList.size() == mMaterialList.size());
+ int refCnt = ref->mMaterialList.size();
+ int modelCnt = mMaterialList.size();
+
+ for (U32 src = 0; src < modelCnt; ++src)
+ {
+ bool foundRef = false;
+
+ for (U32 dst = 0; dst < refCnt; ++dst)
+ {
+ //llinfos<<mMaterialList[src]<<" "<<ref->mMaterialList[dst]<<llendl;
+ foundRef = mMaterialList[src] == ref->mMaterialList[dst];
+
+ if ( foundRef )
+ {
+ break;
+ }
+ }
+ if (!foundRef)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+bool LLModel::needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt )
+{
+ bool changed = false;
+ if ( refFaceCnt< modelFaceCnt )
+ {
+ refFaceCnt += modelFaceCnt - refFaceCnt;
+ changed = true;
+ }
+ else
+ if ( modelFaceCnt < refFaceCnt )
+ {
+ modelFaceCnt += refFaceCnt - modelFaceCnt;
+ changed = true;
+ }
+
+ return changed;
+}
+
+bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt )
+{
+ //Is this a subset?
+ //LODs cannot currently add new materials, e.g.
+ //1. ref = a,b,c lod1 = d,e => This is not permitted
+ //2. ref = a,b,c lod1 = c => This would be permitted
+
+ bool isASubset = isMaterialListSubset( ref );
+ if ( !isASubset )
+ {
+ llinfos<<"Material of model is not a subset of reference."<<llendl;
+ return false;
+ }
+
std::map<std::string, U32> index_map;
//build a map of material slot names to face indexes
bool reorder = false;
+
std::set<std::string> base_mat;
std::set<std::string> cur_mat;
@@ -1939,6 +2009,7 @@ void LLModel::matchMaterialOrder(LLModel* ref)
//override material list with reference model ordering
mMaterialList = ref->mMaterialList;
+ return true;
}
@@ -2329,8 +2400,6 @@ LLSD LLModel::Decomposition::asLLSD() const
for (U32 k = 0; k < 3; k++)
{
- llassert(v[k] <= 0.51f && v[k] >= -0.51f);
-
//convert to 16-bit normalized across domain
U16 val = (U16) (((v[k]-min.mV[k])/range.mV[k])*65535);
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 3f58eba07d..1cf528fd9f 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -148,6 +148,7 @@ public:
static LLModel* loadModelFromDomMesh(domMesh* mesh);
static std::string getElementLabel(daeElement* element);
std::string getName() const;
+ std::string getMetric() const {return mMetric;}
EModelStatus getStatus() const {return mStatus;}
static std::string getStatusString(U32 status) ;
@@ -175,8 +176,10 @@ public:
//reorder face list based on mMaterialList in this and reference so
//order matches that of reference (material ordering touchup)
- void matchMaterialOrder(LLModel* reference);
-
+ bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
+ bool isMaterialListSubset( LLModel* ref );
+ bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
+
std::vector<std::string> mMaterialList;
//data used for skin weights
@@ -217,6 +220,19 @@ public:
}
};
+
+ //Are the doubles the same w/in epsilon specified tolerance
+ bool areEqual( double a, double b )
+ {
+ const float epsilon = 1e-5f;
+ return (fabs((a - b)) < epsilon) ? true : false ;
+ }
+ //Make sure that we return false for any values that are within the tolerance for equivalence
+ bool jointPositionalLookup( const LLVector3& a, const LLVector3& b )
+ {
+ return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? true : false;
+ }
+
//copy of position array for this model -- mPosition[idx].mV[X,Y,Z]
std::vector<LLVector3> mPosition;
@@ -234,6 +250,8 @@ public:
std::string mRequestedLabel; // name requested in UI, if any.
std::string mLabel; // name computed from dae.
+ std::string mMetric; // user-supplied metric data for upload
+
LLVector3 mNormalizedScale;
LLVector3 mNormalizedTranslation;
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index cb2abc5bc0..4dd11541b9 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1266,6 +1266,7 @@ BOOL LLWindowMacOSX::setSize(const LLCoordScreen size)
void LLWindowMacOSX::swapBuffers()
{
+ glFinish();
aglSwapBuffers(mContext);
}
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index b65287715c..e41aa9820f 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -984,7 +984,10 @@ BOOL LLWindowSDL::setSize(const LLCoordScreen size)
void LLWindowSDL::swapBuffers()
{
if (mWindow)
+ {
+ glFinish();
SDL_GL_SwapBuffers();
+ }
}
U32 LLWindowSDL::getFSAASamples()
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 1239e2d40b..121c7880df 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -2896,6 +2896,7 @@ BOOL LLWindowWin32::resetDisplayResolution()
void LLWindowWin32::swapBuffers()
{
+ glFinish();
SwapBuffers(mhDC);
}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 11b19ca4fe..fe80a47ca4 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -77,7 +77,7 @@ include_directories(
set(viewer_SOURCE_FILES
groupchatlistener.cpp
- llaccountingquotamanager.cpp
+ llaccountingcostmanager.cpp
llagent.cpp
llagentaccess.cpp
llagentcamera.cpp
@@ -213,6 +213,7 @@ set(viewer_SOURCE_FILES
llfloatermodelwizard.cpp
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
+ llfloaterobjectweights.cpp
llfloateropenobject.cpp
llfloaterpay.cpp
llfloaterperms.cpp
@@ -639,7 +640,7 @@ set(viewer_HEADER_FILES
CMakeLists.txt
ViewerInstall.cmake
groupchatlistener.h
- llaccountingquotamanager.h
+ llaccountingcostmanager.h
llagent.h
llagentaccess.h
llagentcamera.h
@@ -776,6 +777,7 @@ set(viewer_HEADER_FILES
llfloatermodelwizard.h
llfloaternamedesc.h
llfloaternotificationsconsole.h
+ llfloaterobjectweights.h
llfloateropenobject.h
llfloaterpay.h
llfloaterperms.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f4535f12f8..8804c40aff 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5501,7 +5501,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>64.0</real>
+ <real>128.0</real>
</map>
<key>MaxWearableWaitTime</key>
<map>
@@ -7416,7 +7416,89 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>RenderAvatarLODFactor</key>
+ <key>RenderAvatarComplexityLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Max visual complexity of avatars in a scene</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>-1</integer>
+ </map>
+ <key>RenderComplexityColorMin</key>
+ <map>
+ <key>Comment</key>
+ <string>Max visual complexity of avatars in a scene</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ <real>0.5</real>
+ </array>
+ </map>
+ <key>RenderComplexityColorMid</key>
+ <map>
+ <key>Comment</key>
+ <string>Max visual complexity of avatars in a scene</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.0</real>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>0.5</real>
+ </array>
+ </map>
+ <key>RenderComplexityColorMax</key>
+ <map>
+ <key>Comment</key>
+ <string>Max visual complexity of avatars in a scene</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>0.5</real>
+ </array>
+ </map>
+ <key>RenderComplexityThreshold</key>
+ <map>
+ <key>Comment</key>
+ <string>Only color objects higher than render threshold</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>-1</integer>
+ </map>
+ <key>RenderComplexityStaticMax</key>
+ <map>
+ <key>Comment</key>
+ <string>Sets a static max value for scaling of RenderComplexity
+ display (-1 for dynamic scaling)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>-1</integer>
+ </map>
+ <key>RenderAvatarLODFactor</key>
<map>
<key>Comment</key>
<string>Controls level of detail of avatars (multiplier for current screen area when calculated level of detail)</string>
@@ -9580,17 +9662,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowAdvancedBuilderOptions</key>
- <map>
- <key>Comment</key>
- <string>Shows physics and display weight</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ShowAdvancedGraphicsSettings</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 1f9dc6e4e5..e12c2f7853 100644..100755
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -88,7 +88,7 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderUseImpostors 1 1
-RenderVolumeLODFactor 1 0.5
+RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
new file mode 100644
index 0000000000..8767955fcb
--- /dev/null
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -0,0 +1,181 @@
+/**
+ * @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"
+#include "llaccountingcostmanager.h"
+#include "llagent.h"
+#include "llcurl.h"
+#include "llhttpclient.h"
+//===============================================================================
+LLAccountingCostManager::LLAccountingCostManager()
+{
+}
+//===============================================================================
+class LLAccountingCostResponder : public LLCurl::Responder
+{
+public:
+ LLAccountingCostResponder( const LLSD& objectIDs, const LLHandle<LLAccountingCostObserver>& observer_handle )
+ : mObjectIDs( objectIDs ),
+ mObserverHandle( observer_handle )
+ {
+ LLAccountingCostObserver* observer = mObserverHandle.get();
+ if (observer)
+ {
+ mTransactionID = observer->getTransactionID();
+ }
+ }
+
+ void clearPendingRequests ( void )
+ {
+ for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
+ {
+ LLAccountingCostManager::getInstance()->removePendingObject( iter->asUUID() );
+ }
+ }
+
+ void error( U32 statusNum, const std::string& reason )
+ {
+ llwarns << "Transport error "<<reason<<llendl;
+ clearPendingRequests();
+
+ LLAccountingCostObserver* observer = mObserverHandle.get();
+ if (observer && observer->getTransactionID() == mTransactionID)
+ {
+ observer->setErrorStatus(statusNum, reason);
+ }
+ }
+
+ void result( const LLSD& content )
+ {
+ //Check for error
+ if ( !content.isMap() || content.has("error") )
+ {
+ llwarns << "Error on fetched data"<< llendl;
+ }
+ else if (content.has("selected"))
+ {
+ F32 physicsCost = 0.0f;
+ F32 networkCost = 0.0f;
+ F32 simulationCost = 0.0f;
+
+ physicsCost = content["selected"]["physics"].asReal();
+ networkCost = content["selected"]["streaming"].asReal();
+ simulationCost = content["selected"]["simulation"].asReal();
+
+ SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost );
+
+ LLAccountingCostObserver* observer = mObserverHandle.get();
+ if (observer && observer->getTransactionID() == mTransactionID)
+ {
+ observer->onWeightsUpdate(selectionCost);
+ }
+ }
+
+ clearPendingRequests();
+ }
+
+private:
+ //List of posted objects
+ LLSD mObjectIDs;
+
+ // Current request ID
+ LLUUID mTransactionID;
+
+ // Cost update observer handle
+ LLHandle<LLAccountingCostObserver> mObserverHandle;
+};
+//===============================================================================
+void LLAccountingCostManager::fetchCosts( eSelectionType selectionType,
+ const std::string& url,
+ const LLHandle<LLAccountingCostObserver>& observer_handle )
+{
+ // Invoking system must have already determined capability availability
+ if ( !url.empty() )
+ {
+ LLSD objectList;
+ U32 objectIndex = 0;
+
+ IDIt IDIter = mObjectList.begin();
+ IDIt IDIterEnd = mObjectList.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;
+ }
+ }
+
+ mObjectList.clear();
+
+ //Post results
+ if ( objectList.size() > 0 )
+ {
+ std::string keystr;
+ if ( selectionType == Roots )
+ {
+ keystr="selected_roots";
+ }
+ else
+ if ( selectionType == Prims )
+ {
+ keystr="selected_prims";
+ }
+ else
+ {
+ llinfos<<"Invalid selection type "<<llendl;
+ mObjectList.clear();
+ mPendingObjectQuota.clear();
+ return;
+ }
+
+ LLSD dataToPost = LLSD::emptyMap();
+ dataToPost[keystr.c_str()] = objectList;
+
+ LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList, observer_handle ));
+ }
+ }
+ else
+ {
+ //url was empty - warn & continue
+ llwarns<<"Supplied url is empty "<<llendl;
+ mObjectList.clear();
+ mPendingObjectQuota.clear();
+ }
+}
+//===============================================================================
+void LLAccountingCostManager::addObject( const LLUUID& objectID )
+{
+ mObjectList.insert( objectID );
+}
+//===============================================================================
+void LLAccountingCostManager::removePendingObject( const LLUUID& objectID )
+{
+ mPendingObjectQuota.erase( objectID );
+}
+//===============================================================================
diff --git a/indra/newview/llaccountingquotamanager.h b/indra/newview/llaccountingcostmanager.h
index 9251ef9351..0bca1f54ef 100644
--- a/indra/newview/llaccountingquotamanager.h
+++ b/indra/newview/llaccountingcostmanager.h
@@ -27,29 +27,49 @@
#ifndef LL_ACCOUNTINGQUOTAMANAGER_H
#define LL_ACCOUNTINGQUOTAMANAGER_H
//===============================================================================
-#include "llaccountingquota.h"
+#include "llhandle.h"
+
+#include "llaccountingcost.h"
+//===============================================================================
+// An interface class for panels which display the parcel accounting information.
+class LLAccountingCostObserver
+{
+public:
+ LLAccountingCostObserver() { mObserverHandle.bind(this); }
+ virtual ~LLAccountingCostObserver() {}
+ virtual void onWeightsUpdate(const SelectionCost& selection_cost) = 0;
+ virtual void setErrorStatus(U32 status, const std::string& reason) = 0;
+ const LLHandle<LLAccountingCostObserver>& getObserverHandle() const { return mObserverHandle; }
+ const LLUUID& getTransactionID() { return mTransactionID; }
+
+protected:
+ virtual void generateTransactionID() = 0;
+
+ LLRootHandle<LLAccountingCostObserver> mObserverHandle;
+ LLUUID mTransactionID;
+};
//===============================================================================
-class LLAccountingQuotaManager : public LLSingleton<LLAccountingQuotaManager>
+class LLAccountingCostManager : public LLSingleton<LLAccountingCostManager>
{
public:
//Ctor
- LLAccountingQuotaManager();
+ LLAccountingCostManager();
//Store an object that will be eventually fetched
- void updateObjectCost( const LLUUID& objectID );
+ void addObject( const LLUUID& objectID );
//Request quotas for object list
- void fetchQuotas( const std::string& url );
+ void fetchCosts( eSelectionType selectionType, const std::string& url,
+ const LLHandle<LLAccountingCostObserver>& observer_handle );
//Delete a specific object from the pending list
- void removePendingObjectQuota( const LLUUID& objectID );
+ void removePendingObject( 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
+ //Set of objects that will be used to generate a cost
+ std::set<LLUUID> mObjectList;
+ //During fetchCosts 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
-
+#endif // LLACCOUNTINGCOSTMANAGER
diff --git a/indra/newview/llaccountingquotamanager.cpp b/indra/newview/llaccountingquotamanager.cpp
deleted file mode 100644
index a4f5de5632..0000000000
--- a/indra/newview/llaccountingquotamanager.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/**
- * @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"
-#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 );
-}
-//===============================================================================
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index c0c9ea1451..913d2f34b0 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -255,7 +255,7 @@ public:
mSourceType = chat.mSourceType;
//*TODO overly defensive thing, source type should be maintained out there
- if((chat.mFromID.isNull() && chat.mFromName.empty()) || chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull())
+ if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()))
{
mSourceType = CHAT_SOURCE_SYSTEM;
}
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 28e464b60d..37ee81aeb5 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1299,30 +1299,38 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
return;
}
- LLVertexBuffer* buffer = face->getVertexBuffer();
+ LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
+ LLDrawable* drawable = face->getDrawable();
U32 data_mask = face->getRiggedVertexBufferDataMask();
- if (!buffer ||
+ if (buffer.isNull() ||
buffer->getTypeMask() != data_mask ||
- buffer->getRequestedVerts() != vol_face.mNumVertices)
+ buffer->getRequestedVerts() != vol_face.mNumVertices ||
+ buffer->getRequestedIndices() != vol_face.mNumIndices ||
+ (drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
{
face->setGeomIndex(0);
face->setIndicesIndex(0);
- face->setSize(vol_face.mNumVertices, vol_face.mNumIndices, true);
-
-
- if (sShaderLevel > 0)
- {
- buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
+
+ if (buffer.isNull() || buffer->getTypeMask() != data_mask)
+ { //make a new buffer
+ if (sShaderLevel > 0)
+ {
+ buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
+ }
+ else
+ {
+ buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+ }
+ buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
}
else
- {
- buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+ { //resize existing buffer
+ buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
}
- buffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), true);
-
+ face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
face->setVertexBuffer(buffer);
U16 offset = 0;
@@ -1423,6 +1431,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
}
}
}
+
+ if (drawable && (face->getTEOffset() == drawable->getNumFaces()-1))
+ {
+ drawable->clearState(LLDrawable::REBUILD_ALL);
+ }
}
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
@@ -1453,7 +1466,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
LLVolume* volume = vobj->getVolume();
S32 te = face->getTEOffset();
- if (!volume || volume->getNumVolumeFaces() <= te)
+ if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded())
{
continue;
}
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 2510f43aa7..5869cf6fee 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -96,6 +96,7 @@
#include "llsliderctrl.h"
#include "llspinctrl.h"
#include "lltoggleablemenu.h"
+#include "lltrans.h"
#include "llvfile.h"
#include "llvfs.h"
#include "llcallbacklist.h"
@@ -106,7 +107,7 @@
#include <boost/algorithm/string.hpp>
-const S32 SLM_SUPPORTED_VERSION = 2;
+const S32 SLM_SUPPORTED_VERSION = 3;
//static
S32 LLFloaterModelPreview::sUploadAmount = 10;
@@ -119,6 +120,19 @@ const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16;
const S32 PREVIEW_TEXTURE_HEIGHT = 300;
+// "Retain%" decomp parameter has values from 0.0 to 1.0 by 0.01
+// But according to the UI spec for upload model floater, this parameter
+// should be represented by Retain spinner with values from 1 to 100 by 1.
+// To achieve this, RETAIN_COEFFICIENT is used while creating spinner
+// and when value is requested from spinner.
+const double RETAIN_COEFFICIENT = 100;
+
+// "Cosine%" decomp parameter has values from 0.9 to 1 by 0.001
+// But according to the UI spec for upload model floater, this parameter
+// should be represented by Smooth combobox with only 10 values.
+// So this const is used as a size of Smooth combobox list.
+const S32 SMOOTH_VALUES_NUMBER = 10;
+
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
@@ -184,6 +198,13 @@ std::string lod_label_name[NUM_LOD+1] =
"I went off the end of the lod_label_name array. Me so smart."
};
+std::string colladaVersion[VERSIONTYPE_COUNT+1] =
+{
+ "1.4.0",
+ "1.4.1",
+ "Unsupported"
+};
+
#define LL_DEGENERACY_TOLERANCE 1e-7f
@@ -387,21 +408,23 @@ BOOL LLFloaterModelPreview::postBuild()
return FALSE;
}
- childSetAction("lod_browse", onBrowseLOD, this);
-
childSetCommitCallback("cancel_btn", onCancel, this);
childSetCommitCallback("crease_angle", onGenerateNormalsCommit, this);
- childSetCommitCallback("generate_normals", onGenerateNormalsCommit, this);
+ getChild<LLCheckBoxCtrl>("gen_normals")->setCommitCallback(boost::bind(&LLFloaterModelPreview::toggleGenarateNormals, this));
childSetCommitCallback("lod_generate", onAutoFillCommit, this);
- childSetCommitCallback("lod_mode", onLODParamCommit, this);
- childSetCommitCallback("lod_error_threshold", onLODParamCommit, this);
- childSetCommitCallback("lod_triangle_limit", onLODParamCommitTriangleLimit, this);
- childSetCommitCallback("build_operator", onLODParamCommit, this);
- childSetCommitCallback("queue_mode", onLODParamCommit, this);
- childSetCommitCallback("border_mode", onLODParamCommit, this);
- childSetCommitCallback("share_tolerance", onLODParamCommit, this);
+ for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)
+ {
+ LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]);
+ lod_source_combo->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLoDSourceCommit, this, lod));
+ lod_source_combo->setCurrentByIndex(mLODMode[lod]);
+
+ getChild<LLButton>("lod_browse_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onBrowseLOD, this, lod));
+ getChild<LLComboBox>("lod_mode_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, false));
+ getChild<LLSpinCtrl>("lod_error_threshold_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, false));
+ getChild<LLSpinCtrl>("lod_triangle_limit_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, true));
+ }
childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
@@ -422,26 +445,14 @@ BOOL LLFloaterModelPreview::postBuild()
childSetCommitCallback("import_scale", onImportScaleCommit, this);
childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this);
- childSetCommitCallback("lod_file_or_limit", refresh, this);
- childSetCommitCallback("physics_load_radio", onPhysicsLoadRadioCommit, this);
- //childSetCommitCallback("physics_optimize", refresh, this);
- //childSetCommitCallback("physics_use_hull", refresh, this);
+ getChild<LLCheckBoxCtrl>("show_edges")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
+ getChild<LLCheckBoxCtrl>("show_physics")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
+ getChild<LLCheckBoxCtrl>("show_textures")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
+ getChild<LLCheckBoxCtrl>("show_skin_weight")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
+ getChild<LLCheckBoxCtrl>("show_joint_positions")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
childDisable("upload_skin");
childDisable("upload_joints");
-
- childDisable("ok_btn");
-
- mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn");
-
- mCommitCallbackRegistrar.add("ModelImport.ViewOption.Action", boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _2));
- mEnableCallbackRegistrar.add("ModelImport.ViewOption.Check", boost::bind(&LLFloaterModelPreview::isViewOptionChecked, this, _2));
- mEnableCallbackRegistrar.add("ModelImport.ViewOption.Enabled", boost::bind(&LLFloaterModelPreview::isViewOptionEnabled, this, _2));
-
-
-
- mViewOptionMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_model_import_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mViewOptionMenuButton->setMenu(mViewOptionMenu, LLMenuButton::MP_BOTTOM_LEFT);
initDecompControls();
@@ -535,11 +546,11 @@ void LLFloaterModelPreview::initModelPreview()
mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
}
-void LLFloaterModelPreview::onViewOptionChecked(const LLSD& userdata)
+void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
{
if (mModelPreview)
{
- mModelPreview->mViewOption[userdata.asString()] = !mModelPreview->mViewOption[userdata.asString()];
+ mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
mModelPreview->refresh();
}
@@ -557,12 +568,12 @@ bool LLFloaterModelPreview::isViewOptionChecked(const LLSD& userdata)
bool LLFloaterModelPreview::isViewOptionEnabled(const LLSD& userdata)
{
- return !mViewOptionDisabled[userdata.asString()];
+ return childIsEnabled(userdata.asString());
}
void LLFloaterModelPreview::setViewOptionEnabled(const std::string& option, bool enabled)
{
- mViewOptionDisabled[option] = !enabled;
+ childSetEnabled(option, enabled);
}
void LLFloaterModelPreview::enableViewOption(const std::string& option)
@@ -640,29 +651,6 @@ void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata )
}
//static
-void LLFloaterModelPreview::onPhysicsLoadRadioCommit( LLUICtrl*, void *userdata)
-{
- LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
- if (fmp)
- {
- if (fmp->childGetValue("physics_use_lod").asBoolean())
- {
- onPhysicsUseLOD(NULL,NULL);
- }
- if (fmp->childGetValue("physics_load_from_file").asBoolean())
- {
-
- }
- LLModelPreview *model_preview = fmp->mModelPreview;
- if (model_preview)
- {
- model_preview->refresh();
- model_preview->updateStatusMessages();
- }
- }
-}
-
-//static
void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata)
{
LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
@@ -716,6 +704,12 @@ void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userda
fp->mModelPreview->generateNormals();
}
+void LLFloaterModelPreview::toggleGenarateNormals()
+{
+ bool enabled = childGetValue("gen_normals").asBoolean();
+ childSetEnabled("crease_angle", enabled);
+}
+
//static
void LLFloaterModelPreview::onExplodeCommit(LLUICtrl* ctrl, void* userdata)
{
@@ -732,19 +726,9 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)
fp->mModelPreview->genLODs();
}
-//static
-void LLFloaterModelPreview::onLODParamCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
-
- fp->mModelPreview->onLODParamCommit(false);
-}
-
-//static
-void LLFloaterModelPreview::onLODParamCommitTriangleLimit(LLUICtrl* ctrl, void* userdata)
+void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
{
- LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
- fp->mModelPreview->onLODParamCommit(true);
+ mModelPreview->onLODParamCommit(lod, enforce_tri_limit);
}
@@ -768,6 +752,7 @@ void LLFloaterModelPreview::draw()
if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_PARSING )
{
childSetTextArg("status", "[STATUS]", getString("status_parse_error"));
+ toggleCalculateButton(false);
}
else
{
@@ -775,8 +760,6 @@ void LLFloaterModelPreview::draw()
}
}
- childSetEnabled("ok_btn", mHasUploadPerm && !mUploadModelUrl.empty());
-
childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost));
childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size()));
@@ -931,20 +914,32 @@ void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data)
{
LLCDParam* param = (LLCDParam*) data;
std::string name(param->mName);
- sInstance->mDecompParams[name] = ctrl->getValue();
+
+ LLSD value = ctrl->getValue();
+
+ if("Retain%" == name)
+ {
+ value = ctrl->getValue().asReal() / RETAIN_COEFFICIENT;
+ }
+
+ sInstance->mDecompParams[name] = value;
if (name == "Simplify Method")
{
- if (ctrl->getValue().asInteger() == 0)
- {
- sInstance->childSetVisible("Retain%", true);
- sInstance->childSetVisible("Detail Scale", false);
- }
- else
+ bool show_retain = false;
+ bool show_detail = true;
+
+ if (ctrl->getValue().asInteger() == 0)
{
- sInstance->childSetVisible("Retain%", false);
- sInstance->childSetVisible("Detail Scale", true);
+ show_retain = true;
+ show_detail = false;
}
+
+ sInstance->childSetVisible("Retain%", show_retain);
+ sInstance->childSetVisible("Retain%_label", show_retain);
+
+ sInstance->childSetVisible("Detail Scale", show_detail);
+ sInstance->childSetVisible("Detail Scale label", show_detail);
}
}
}
@@ -1000,14 +995,38 @@ void LLFloaterModelPreview::onPhysicsBrowse(LLUICtrl* ctrl, void* userdata)
//static
void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
{
+ S32 num_modes = 4;
S32 which_mode = 3;
+ static S32 previous_mode = which_mode;
+
LLCtrlSelectionInterface* iface = sInstance->childGetSelectionInterface("physics_lod_combo");
if (iface)
{
which_mode = iface->getFirstSelectedIndex();
}
- sInstance->mModelPreview->setPhysicsFromLOD(which_mode);
+ S32 file_mode = iface->getItemCount() - 1;
+ bool file_browse = which_mode == file_mode;
+ bool lod_to_file = file_browse && (previous_mode != file_mode);
+ bool file_to_lod = !file_browse && (previous_mode == file_mode);
+
+ if (!lod_to_file)
+ {
+ which_mode = num_modes - which_mode;
+ sInstance->mModelPreview->setPhysicsFromLOD(which_mode);
+ }
+
+ if (lod_to_file || file_to_lod)
+ {
+ LLModelPreview *model_preview = sInstance->mModelPreview;
+ if (model_preview)
+ {
+ model_preview->refresh();
+ model_preview->updateStatusMessages();
+ }
+ }
+
+ previous_mode = which_mode;
}
//static
@@ -1032,6 +1051,11 @@ void LLFloaterModelPreview::onPhysicsStageCancel(LLUICtrl* ctrl, void*data)
}
sInstance->mCurRequest.clear();
+
+ if (sInstance->mModelPreview)
+ {
+ sInstance->mModelPreview->updateStatusMessages();
+ }
}
}
@@ -1094,8 +1118,9 @@ void LLFloaterModelPreview::initDecompControls()
mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat);
//llinfos << "Type: float, Default: " << param[i].mDefault.mFloat << llendl;
- LLSliderCtrl* slider = getChild<LLSliderCtrl>(name);
- if (slider)
+
+ LLUICtrl* ctrl = getChild<LLUICtrl>(name);
+ if (LLSliderCtrl* slider = dynamic_cast<LLSliderCtrl*>(ctrl))
{
slider->setMinValue(param[i].mDetails.mRange.mLow.mFloat);
slider->setMaxValue(param[i].mDetails.mRange.mHigh.mFloat);
@@ -1103,14 +1128,49 @@ void LLFloaterModelPreview::initDecompControls()
slider->setValue(param[i].mDefault.mFloat);
slider->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
}
+ else if (LLSpinCtrl* spinner = dynamic_cast<LLSpinCtrl*>(ctrl))
+ {
+ bool is_retain_ctrl = "Retain%" == name;
+ double coefficient = is_retain_ctrl ? RETAIN_COEFFICIENT : 1.f;
+
+ spinner->setMinValue(param[i].mDetails.mRange.mLow.mFloat * coefficient);
+ spinner->setMaxValue(param[i].mDetails.mRange.mHigh.mFloat * coefficient);
+ spinner->setIncrement(param[i].mDetails.mRange.mDelta.mFloat * coefficient);
+ spinner->setValue(param[i].mDefault.mFloat * coefficient);
+ spinner->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
+ }
+ else if (LLComboBox* combo_box = dynamic_cast<LLComboBox*>(ctrl))
+ {
+ float min = param[i].mDetails.mRange.mLow.mFloat;
+ float max = param[i].mDetails.mRange.mHigh.mFloat;
+ float delta = param[i].mDetails.mRange.mDelta.mFloat;
+
+ if ("Cosine%" == name)
+ {
+ createSmoothComboBox(combo_box, min, max);
+ }
+ else
+ {
+ for(float value = min; value <= max; value += delta)
+ {
+ std::string label = llformat("%.1f", value);
+ combo_box->add(label, value, ADD_BOTTOM, true);
+ }
+ combo_box->setValue(param[i].mDefault.mFloat);
+
+ }
+
+ combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
+ }
}
else if (param[i].mType == LLCDParam::LLCD_INTEGER)
{
mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
//llinfos << "Type: integer, Default: " << param[i].mDefault.mIntOrEnumValue << llendl;
- LLSliderCtrl* slider = getChild<LLSliderCtrl>(name);
- if (slider)
+
+ LLUICtrl* ctrl = getChild<LLUICtrl>(name);
+ if (LLSliderCtrl* slider = dynamic_cast<LLSliderCtrl*>(ctrl))
{
slider->setMinValue(param[i].mDetails.mRange.mLow.mIntOrEnumValue);
slider->setMaxValue(param[i].mDetails.mRange.mHigh.mIntOrEnumValue);
@@ -1118,6 +1178,16 @@ void LLFloaterModelPreview::initDecompControls()
slider->setValue(param[i].mDefault.mIntOrEnumValue);
slider->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
}
+ else if (LLComboBox* combo_box = dynamic_cast<LLComboBox*>(ctrl))
+ {
+ for(int k = param[i].mDetails.mRange.mLow.mIntOrEnumValue; k<=param[i].mDetails.mRange.mHigh.mIntOrEnumValue; k+=param[i].mDetails.mRange.mDelta.mIntOrEnumValue)
+ {
+ std::string name = llformat("%.1d", k);
+ combo_box->add(name, k, ADD_BOTTOM, true);
+ }
+ combo_box->setValue(param[i].mDefault.mIntOrEnumValue);
+ combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
+ }
}
else if (param[i].mType == LLCDParam::LLCD_BOOLEAN)
{
@@ -1145,7 +1215,11 @@ void LLFloaterModelPreview::initDecompControls()
//llinfos << param[i].mDetails.mEnumValues.mEnumsArray[k].mValue
// << " - " << param[i].mDetails.mEnumValues.mEnumsArray[k].mName << llendl;
- combo_box->add(param[i].mDetails.mEnumValues.mEnumsArray[k].mName,
+ std::string name(param[i].mDetails.mEnumValues.mEnumsArray[k].mName);
+ std::string localized_name;
+ bool is_localized = LLTrans::findString(localized_name, name);
+
+ combo_box->add(is_localized ? localized_name : name,
LLSD::Integer(param[i].mDetails.mEnumValues.mEnumsArray[k].mValue));
}
combo_box->setValue(param[i].mDefault.mIntOrEnumValue);
@@ -1161,6 +1235,22 @@ void LLFloaterModelPreview::initDecompControls()
childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this);
}
+void LLFloaterModelPreview::createSmoothComboBox(LLComboBox* combo_box, float min, float max)
+{
+ float delta = (max - min) / SMOOTH_VALUES_NUMBER;
+ int ilabel = 0;
+
+ combo_box->add("0 (none)", ADD_BOTTOM, true);
+
+ for(float value = min + delta; value < max; value += delta)
+ {
+ std::string label = (++ilabel == SMOOTH_VALUES_NUMBER) ? "10 (max)" : llformat("%.1d", ilabel);
+ combo_box->add(label, value, ADD_BOTTOM, true);
+ }
+
+
+}
+
//-----------------------------------------------------------------------------
// onMouseCaptureLost()
//-----------------------------------------------------------------------------
@@ -1385,9 +1475,26 @@ bool LLModelLoader::doLoadModel()
if (!dom)
{
+ llinfos<<" Error with dae - traditionally indicates a corrupt file."<<llendl;
+ setLoadState( ERROR_PARSING );
return false;
}
-
+ //Dom version
+ daeString domVersion = dae.getDomVersion();
+ std::string sldom(domVersion);
+ llinfos<<"Collada Importer Version: "<<sldom<<llendl;
+ //Dae version
+ domVersionType docVersion = dom->getVersion();
+ //0=1.4
+ //1=1.4.1
+ //2=Currently unsupported, however may work
+ if (docVersion > 1 )
+ {
+ docVersion = VERSIONTYPE_COUNT;
+ }
+ llinfos<<"Dae version "<<colladaVersion[docVersion]<<llendl;
+
+
daeDatabase* db = dae.getDatabase();
daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH);
@@ -1536,8 +1643,7 @@ bool LLModelLoader::doLoadModel()
LLMatrix4 trans = normalized_transformation;
trans *= skin_info.mBindShapeMatrix;
- skin_info.mBindShapeMatrix = trans;
-
+ skin_info.mBindShapeMatrix = trans;
}
@@ -1610,7 +1716,7 @@ bool LLModelLoader::doLoadModel()
{
//Build a joint for the resolver to work with
char str[64]={0};
- sprintf(str,"./%s",(*jointIt).second.c_str() );
+ sprintf(str,"./%s",(*jointIt).first.c_str() );
//llwarns<<"Joint "<< str <<llendl;
//Setup the resolver
@@ -1621,15 +1727,22 @@ bool LLModelLoader::doLoadModel()
if ( pJoint )
{
//Pull out the translate id and store it in the jointTranslations map
- daeSIDResolver jointResolver( pJoint, "./translate" );
- domTranslate* pTranslate = daeSafeCast<domTranslate>( jointResolver.getElement() );
+ daeSIDResolver jointResolverA( pJoint, "./translate" );
+ domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() );
+ daeSIDResolver jointResolverB( pJoint, "./location" );
+ domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() );
LLMatrix4 workingTransform;
//Translation via SID
- if ( pTranslate )
+ if ( pTranslateA )
+ {
+ extractTranslation( pTranslateA, workingTransform );
+ }
+ else
+ if ( pTranslateB )
{
- extractTranslation( pTranslate, workingTransform );
+ extractTranslation( pTranslateB, workingTransform );
}
else
{
@@ -1641,9 +1754,15 @@ bool LLModelLoader::doLoadModel()
missingSkeletonOrScene = true;
}
else
+ if ( pTranslateElement )
{
extractTranslationViaElement( pTranslateElement, workingTransform );
}
+ else
+ {
+ extractTranslationViaSID( pJoint, workingTransform );
+ }
+
}
//Store the joint transform w/respect to it's name.
@@ -1740,7 +1859,7 @@ bool LLModelLoader::doLoadModel()
}
}
- model->mSkinInfo.mInvBindMatrix.push_back(mat);
+ model->mSkinInfo.mInvBindMatrix.push_back(mat);
}
}
}
@@ -1748,7 +1867,7 @@ bool LLModelLoader::doLoadModel()
}
//Now that we've parsed the joint array, let's determine if we have a full rig
- //(which means we have all the joints that are required for an avatar versus
+ //(which means we have all the joint sthat are required for an avatar versus
//a skinned asset attached to a node in a file that contains an entire skeleton,
//but does not use the skeleton).
buildJointToNodeMappingFromScene( root );
@@ -2040,6 +2159,14 @@ bool LLModelLoader::loadFromSLM(const std::string& filename)
return false;
}
+ // Set name.
+ std::string name = data["name"];
+ if (!name.empty())
+ {
+ model[LLModel::LOD_HIGH][0]->mLabel = name;
+ }
+
+
//load instance list
model_instance_list instance_list;
@@ -2152,15 +2279,37 @@ void LLModelLoader::processJointToNodeMapping( domNode* pNode )
mJointsFromNode.push_front( pNode->getName() );
}
//2. Handle the kiddo's
- daeTArray< daeSmartRef<daeElement> > childOfChild = pNode->getChildren();
- S32 childOfChildCount = childOfChild.getCount();
- for (S32 i = 0; i < childOfChildCount; ++i)
+ processChildJoints( pNode );
+ }
+ else
+ {
+ //Determine if the're any children wrt to this failed node.
+ //This occurs when an armature is exported and ends up being what essentially amounts to
+ //as the root for the visual_scene
+ if ( pNode )
{
- domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] );
- if ( pChildNode )
- {
- processJointToNodeMapping( pChildNode );
- }
+ processChildJoints( pNode );
+ }
+ else
+ {
+ llinfos<<"Node is NULL"<<llendl;
+ }
+
+ }
+}
+//-----------------------------------------------------------------------------
+// processChildJoint()
+//-----------------------------------------------------------------------------
+void LLModelLoader::processChildJoints( domNode* pParentNode )
+{
+ daeTArray< daeSmartRef<daeElement> > childOfChild = pParentNode->getChildren();
+ S32 childOfChildCount = childOfChild.getCount();
+ for (S32 i = 0; i < childOfChildCount; ++i)
+ {
+ domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] );
+ if ( pChildNode )
+ {
+ processJointToNodeMapping( pChildNode );
}
}
}
@@ -2185,15 +2334,11 @@ void LLModelPreview::critiqueRigForUploadApplicability( const std::vector<std::s
setRigValidForJointPositionUpload( true );
}
- if ( isRigLegacyOK )
- {
+ if ( isRigLegacyOK)
+ {
setLegacyRigValid( true );
}
- if ( getRigWithSceneParity() && isJointPositionUploadOK )
- {
- setResetJointFlag( true );
- }
}
//-----------------------------------------------------------------------------
// critiqueJointToNodeMappingFromScene()
@@ -2233,12 +2378,7 @@ void LLModelPreview::critiqueJointToNodeMappingFromScene( void )
//2. Partial rig but w/o parity between the scene and joint array
if ( result )
{
- setResetJointFlag( true );
setRigWithSceneParity( true );
- }
- else
- {
- setResetJointFlag( false );
}
}
//-----------------------------------------------------------------------------
@@ -2355,8 +2495,20 @@ void LLModelLoader::loadTextures()
//-----------------------------------------------------------------------------
bool LLModelLoader::isNodeAJoint( domNode* pNode )
{
- if ( !pNode || pNode->getName() == NULL)
+ if ( !pNode )
+ {
+ llinfos<<"Created node is NULL"<<llendl;
+ return false;
+ }
+
+ if ( pNode->getName() == NULL )
{
+ llinfos<<"Parsed node has no name "<<llendl;
+ //Attempt to write the node id, if possible (aids in debugging the visual scene)
+ if ( pNode->getId() )
+ {
+ llinfos<<"Parsed node ID: "<<pNode->getId()<<llendl;
+ }
return false;
}
@@ -2466,10 +2618,43 @@ void LLModelLoader::extractTranslation( domTranslate* pTranslate, LLMatrix4& tra
//-----------------------------------------------------------------------------
void LLModelLoader::extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform )
{
- domTranslate* pTranslateChild = dynamic_cast<domTranslate*>( pTranslateElement );
- domFloat3 translateChild = pTranslateChild->getValue();
- LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] );
- transform.setTranslation( singleJointTranslation );
+ if ( pTranslateElement )
+ {
+ domTranslate* pTranslateChild = dynamic_cast<domTranslate*>( pTranslateElement );
+ domFloat3 translateChild = pTranslateChild->getValue();
+ LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] );
+ transform.setTranslation( singleJointTranslation );
+ }
+}
+//-----------------------------------------------------------------------------
+// extractTranslationViaSID()
+//-----------------------------------------------------------------------------
+void LLModelLoader::extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform )
+{
+ if ( pElement )
+ {
+ daeSIDResolver resolver( pElement, "./transform" );
+ domMatrix* pMatrix = daeSafeCast<domMatrix>( resolver.getElement() );
+ //We are only extracting out the translational component atm
+ LLMatrix4 workingTransform;
+ if ( pMatrix )
+ {
+ domFloat4x4 domArray = pMatrix->getValue();
+ for ( int i = 0; i < 4; i++ )
+ {
+ for( int j = 0; j < 4; j++ )
+ {
+ workingTransform.mMatrix[i][j] = domArray[i + j*4];
+ }
+ }
+ LLVector3 trans = workingTransform.getTranslation();
+ transform.setTranslation( trans );
+ }
+ }
+ else
+ {
+ llwarns<<"Element is nonexistent - empty/unsupported node."<<llendl;
+ }
}
//-----------------------------------------------------------------------------
// processJointNode()
@@ -2489,13 +2674,20 @@ void LLModelLoader::processJointNode( domNode* pNode, JointTransformMap& jointTr
LLMatrix4 workingTransform;
//Pull out the translate id and store it in the jointTranslations map
- daeSIDResolver jointResolver( pNode, "./translate" );
- domTranslate* pTranslate = daeSafeCast<domTranslate>( jointResolver.getElement() );
+ daeSIDResolver jointResolverA( pNode, "./translate" );
+ domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() );
+ daeSIDResolver jointResolverB( pNode, "./location" );
+ domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() );
//Translation via SID was successful
- if ( pTranslate )
+ if ( pTranslateA )
+ {
+ extractTranslation( pTranslateA, workingTransform );
+ }
+ else
+ if ( pTranslateB )
{
- extractTranslation( pTranslate, workingTransform );
+ extractTranslation( pTranslateB, workingTransform );
}
else
{
@@ -2637,6 +2829,12 @@ void LLModelLoader::processElement( daeElement* element, bool& badElement )
{
LLMatrix4 transformation = mTransform;
+ if (mTransform.determinant() < 0)
+ { //negative scales are not supported
+ llinfos << "Negative scale detected, unsupported transform. domInstance_geometry: " << LLModel::getElementLabel(instance_geo) << llendl;
+ badElement = true;
+ }
+
std::map<std::string, LLImportMaterial> materials = getMaterials(model, instance_geo);
// adjust the transformation to compensate for mesh normalization
@@ -2681,7 +2879,8 @@ void LLModelLoader::processElement( daeElement* element, bool& badElement )
//process children
daeTArray< daeSmartRef<daeElement> > children = element->getChildren();
- for (S32 i = 0; i < children.getCount(); i++)
+ int childCount = children.getCount();
+ for (S32 i = 0; i < childCount; i++)
{
processElement(children[i],badElement);
}
@@ -2981,14 +3180,6 @@ U32 LLModelPreview::calcResourceCost()
rebuildUploadData();
- if (mFMP && mModelLoader)
- {
- if ( getLoadState() < LLModelLoader::ERROR_PARSING)
- {
- mFMP->childEnable("ok_btn");
- }
- }
-
//Upload skin is selected BUT check to see if the joints coming in from the asset were malformed.
if ( mFMP && mFMP->childGetValue("upload_skin").asBoolean() )
{
@@ -2996,13 +3187,7 @@ U32 LLModelPreview::calcResourceCost()
if ( uploadingJointPositions && !isRigValidForJointPositionUpload() )
{
mFMP->childDisable("ok_btn");
- }
- else
- if ( !isLegacyRigValid() )
- {
- mFMP->childDisable("ok_btn");
- }
- //ok_btn should not have been changed unless something was wrong with joint list
+ }
}
std::set<LLModel*> accounted;
@@ -3089,6 +3274,7 @@ U32 LLModelPreview::calcResourceCost()
void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)
{
+ assert_main_thread();
childSetTextArg("import_dimensions", "[X]", llformat("%.3f", x));
childSetTextArg("import_dimensions", "[Y]", llformat("%.3f", y));
childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z));
@@ -3106,14 +3292,10 @@ void LLModelPreview::rebuildUploadData()
std::string requested_name = mFMP->getChild<LLUICtrl>("description_form")->getValue().asString();
+ std::string metric = mFMP->getChild<LLUICtrl>("model_category_combo")->getValue().asString();
LLSpinCtrl* scale_spinner = mFMP->getChild<LLSpinCtrl>("import_scale");
- if (!scale_spinner)
- {
- llerrs << "floater_model_preview.xml MUST contain import_scale spinner." << llendl;
- }
-
F32 scale = scale_spinner->getValue().asReal();
LLMatrix4 scale_mat;
@@ -3121,11 +3303,6 @@ void LLModelPreview::rebuildUploadData()
F32 max_scale = 0.f;
- if ( mBaseScene.size() > 0)
- {
- mFMP->childEnable("ok_btn");
- }
-
//reorder materials to match mBaseModel
for (U32 i = 0; i < LLModel::NUM_LODS; i++)
{
@@ -3133,8 +3310,14 @@ void LLModelPreview::rebuildUploadData()
{
for (U32 j = 0; j < mBaseModel.size(); ++j)
{
- mModel[i][j]->matchMaterialOrder(mBaseModel[j]);
- llassert(mModel[i][j]->mMaterialList == mBaseModel[j]->mMaterialList);
+
+ int refFaceCnt = 0;
+ int modelFaceCnt = 0;
+
+ if ( !mModel[i][j]->matchMaterialOrder(mBaseModel[j], refFaceCnt, modelFaceCnt ) )
+ {
+ mFMP->childDisable( "calculate_btn" );
+ }
}
}
}
@@ -3167,6 +3350,7 @@ void LLModelPreview::rebuildUploadData()
if (base_model)
{
base_model->mRequestedLabel = requested_name;
+ base_model->mMetric = metric;
}
S32 idx = 0;
@@ -3197,7 +3381,14 @@ void LLModelPreview::rebuildUploadData()
}
}
- F32 max_import_scale = DEFAULT_MAX_PRIM_SCALE/max_scale;
+ F32 max_import_scale = (DEFAULT_MAX_PRIM_SCALE-0.1f)/max_scale;
+
+ F32 max_axis = llmax(mPreviewScale.mV[0], mPreviewScale.mV[1]);
+ max_axis = llmax(max_axis, mPreviewScale.mV[2]);
+ max_axis *= 2.f;
+
+ //clamp scale so that total imported model bounding box is smaller than 240m on a side
+ max_import_scale = llmin(max_import_scale, 240.f/max_axis);
scale_spinner->setMaxValue(max_import_scale);
@@ -3238,6 +3429,10 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw
LLSD data;
data["version"] = SLM_SUPPORTED_VERSION;
+ if (!mBaseModel.empty())
+ {
+ data["name"] = mBaseModel[0]->getName();
+ }
S32 mesh_id = 0;
@@ -3298,6 +3493,13 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
LLMutexLock lock(this);
+ if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::NUM_LODS - 1)
+ {
+ llwarns << "Invalid level of detail: " << lod << llendl;
+ assert(lod >= LLModel::LOD_IMPOSTOR && lod < LLModel::NUM_LODS);
+ return;
+ }
+
// This triggers if you bring up the file picker and then hit CANCEL.
// Just use the previous model (if any) and ignore that you brought up
// the file picker.
@@ -3343,11 +3545,12 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
if ( getLoadState() >= LLModelLoader::ERROR_PARSING )
{
mFMP->childDisable("ok_btn");
+ mFMP->childDisable( "calculate_btn" );
}
if (lod == mPreviewLOD)
{
- mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]);
+ mFMP->childSetText("lod_file_" + lod_name[lod], mLODFile[lod]);
}
else if (lod == LLModel::LOD_PHYSICS)
{
@@ -3376,6 +3579,12 @@ void LLModelPreview::setPhysicsFromLOD(S32 lod)
void LLModelPreview::clearIncompatible(S32 lod)
{
+ //Don't discard models if specified model is the physic rep
+ if ( lod == LLModel::LOD_PHYSICS )
+ {
+ return;
+ }
+
for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
{ //clear out any entries that aren't compatible with this model
if (i != lod)
@@ -3616,6 +3825,14 @@ void LLModelPreview::generateNormals()
void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_limit)
{
+ // Allow LoD from -1 to LLModel::LOD_PHYSICS
+ if (which_lod < -1 || which_lod > LLModel::NUM_LODS - 1)
+ {
+ llwarns << "Invalid level of detail: " << which_lod << llendl;
+ assert(which_lod >= -1 && which_lod < LLModel::NUM_LODS);
+ return;
+ }
+
if (mBaseModel.empty())
{
return;
@@ -3645,111 +3862,41 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
U32 lod_mode = 0;
- LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode");
- if (iface)
- {
- lod_mode = iface->getFirstSelectedIndex();
- }
- mRequestedLoDMode[mPreviewLOD] = lod_mode;
-
- F32 lod_error_threshold = mFMP->childGetValue("lod_error_threshold").asReal();
+ F32 lod_error_threshold = 0;
- if (lod_mode == 0)
+ // The LoD should be in range from Lowest to High
+ if (which_lod > -1 && which_lod < NUM_LOD)
{
- lod_mode = GLOD_TRIANGLE_BUDGET;
- if (which_lod != -1)
+ LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode_" + lod_name[which_lod]);
+ if (iface)
{
- limit = mFMP->childGetValue("lod_triangle_limit").asInteger();
+ lod_mode = iface->getFirstSelectedIndex();
}
- }
- else
- {
- lod_mode = GLOD_ERROR_THRESHOLD;
- }
- U32 build_operator = 0;
-
- iface = mFMP->childGetSelectionInterface("build_operator");
- if (iface)
- {
- build_operator = iface->getFirstSelectedIndex();
- }
- mRequestedBuildOperator[mPreviewLOD] = build_operator;
-
- if (build_operator == 0)
- {
- build_operator = GLOD_OPERATOR_EDGE_COLLAPSE;
- }
- else
- {
- build_operator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE;
- }
-
- U32 queue_mode=0;
- iface = mFMP->childGetSelectionInterface("queue_mode");
- if (iface)
- {
- queue_mode = iface->getFirstSelectedIndex();
+ lod_error_threshold = mFMP->childGetValue("lod_error_threshold_" + lod_name[which_lod]).asReal();
}
- mRequestedQueueMode[mPreviewLOD] = queue_mode;
- if (queue_mode == 0)
- {
- queue_mode = GLOD_QUEUE_GREEDY;
- }
- else if (queue_mode == 1)
- {
- queue_mode = GLOD_QUEUE_LAZY;
- }
- else
+ if (which_lod != -1)
{
- queue_mode = GLOD_QUEUE_INDEPENDENT;
+ mRequestedLoDMode[which_lod] = lod_mode;
}
- U32 border_mode = 0;
-
- iface = mFMP->childGetSelectionInterface("border_mode");
- if (iface)
+ if (lod_mode == 0)
{
- border_mode = iface->getFirstSelectedIndex();
- }
- mRequestedBorderMode[mPreviewLOD] = border_mode;
+ lod_mode = GLOD_TRIANGLE_BUDGET;
- if (border_mode == 0)
- {
- border_mode = GLOD_BORDER_UNLOCK;
+ // The LoD should be in range from Lowest to High
+ if (which_lod > -1 && which_lod < NUM_LOD)
+ {
+ limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asInteger();
+ }
}
else
{
- border_mode = GLOD_BORDER_LOCK;
+ lod_mode = GLOD_ERROR_THRESHOLD;
}
bool object_dirty = false;
- if (border_mode != mBuildBorderMode)
- {
- mBuildBorderMode = border_mode;
- object_dirty = true;
- }
-
- if (queue_mode != mBuildQueueMode)
- {
- mBuildQueueMode = queue_mode;
- object_dirty = true;
- }
-
- if (build_operator != mBuildOperator)
- {
- mBuildOperator = build_operator;
- object_dirty = true;
- }
-
- F32 share_tolerance = mFMP->childGetValue("share_tolerance").asReal();
- if (share_tolerance != mBuildShareTolerance)
- {
- mBuildShareTolerance = share_tolerance;
- object_dirty = true;
- }
- mRequestedShareTolerance[mPreviewLOD] = share_tolerance;
if (mGroup == 0)
{
@@ -3799,18 +3946,6 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
stop_gloderror();
}
- glodObjectParameteri(mObject[mdl], GLOD_BUILD_OPERATOR, build_operator);
- stop_gloderror();
-
- glodObjectParameteri(mObject[mdl], GLOD_BUILD_QUEUE_MODE, queue_mode);
- stop_gloderror();
-
- glodObjectParameteri(mObject[mdl], GLOD_BUILD_BORDER_MODE, border_mode);
- stop_gloderror();
-
- glodObjectParameterf(mObject[mdl], GLOD_BUILD_SHARE_TOLERANCE, share_tolerance);
- stop_gloderror();
-
glodBuildObject(mObject[mdl]);
stop_gloderror();
}
@@ -4185,6 +4320,8 @@ void LLModelPreview::updateStatusMessages()
icon = mFMP->getChild<LLIconCtrl>("lod_status_message_icon");
icon->setImage(img);
}
+
+ updateLodControls(lod);
}
@@ -4213,11 +4350,11 @@ void LLModelPreview::updateStatusMessages()
if ( uploadingJointPositions && !isRigValidForJointPositionUpload() )
{
skinAndRigOk = false;
- }
+ }
else
if ( !isLegacyRigValid() )
{
- skinAndRigOk = false;
+ mFMP->childDisable("calculate_btn");
}
}
@@ -4229,11 +4366,7 @@ void LLModelPreview::updateStatusMessages()
}
}
- if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate)
- {
- mFMP->childEnable("ok_btn");
- }
- else
+ if (!upload_ok || errorStateFromLoader || !skinAndRigOk || has_degenerate)
{
mFMP->childDisable("ok_btn");
}
@@ -4300,12 +4433,14 @@ void LLModelPreview::updateStatusMessages()
{
fmp->enableViewOption("show_physics");
mViewOption["show_physics"] = true;
+ fmp->childSetValue("show_physics", true);
}
}
else
{
fmp->disableViewOption("show_physics");
mViewOption["show_physics"] = false;
+ fmp->childSetValue("show_physics", false);
}
@@ -4313,7 +4448,7 @@ void LLModelPreview::updateStatusMessages()
//fmp->childSetEnabled("physics_optimize", !use_hull);
- bool enable = phys_tris > 0 || phys_hulls > 0;
+ bool enable = (phys_tris > 0 || phys_hulls > 0) && fmp->mCurRequest.empty();
//enable = enable && !use_hull && fmp->childGetValue("physics_optimize").asBoolean();
//enable/disable "analysis" UI
@@ -4325,7 +4460,7 @@ void LLModelPreview::updateStatusMessages()
child = panel->findNextSibling(child);
}
- enable = phys_hulls > 0;
+ enable = phys_hulls > 0 && fmp->mCurRequest.empty();
//enable/disable "simplification" UI
panel = fmp->getChild<LLPanel>("physics simplification");
child = panel->getFirstChild();
@@ -4352,151 +4487,155 @@ void LLModelPreview::updateStatusMessages()
fmp->childEnable("Decompose");
}
}
+ else
+ {
+ fmp->childEnable("simplify_cancel");
+ fmp->childEnable("decompose_cancel");
+ }
+ }
+
+ if (mFMP->childGetValue("physics_lod_combo").asString() == "From file")
+ {
+ mFMP->childEnable("physics_file");
+ mFMP->childEnable("physics_browse");
+ }
+ else
+ {
+ mFMP->childDisable("physics_file");
+ mFMP->childDisable("physics_browse");
+ }
+
+ LLSpinCtrl* crease = mFMP->getChild<LLSpinCtrl>("crease_angle");
+
+ if (mRequestedCreaseAngle[mPreviewLOD] == -1.f)
+ {
+ mFMP->childSetColor("crease_label", LLColor4::grey);
+ crease->forceSetValue(75.f);
+ }
+ else
+ {
+ mFMP->childSetColor("crease_label", LLColor4::white);
+ crease->forceSetValue(mRequestedCreaseAngle[mPreviewLOD]);
+ }
+
+ mModelUpdatedSignal(true);
+
+}
+
+void LLModelPreview::updateLodControls(S32 lod)
+{
+ if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::LOD_HIGH)
+ {
+ llwarns << "Invalid level of detail: " << lod << llendl;
+ assert(lod >= LLModel::LOD_IMPOSTOR && lod <= LLModel::LOD_HIGH);
+ return;
}
const char* lod_controls[] =
{
- "lod_mode",
- "lod_triangle_limit",
- "lod_error_tolerance",
- "build_operator_text",
- "queue_mode_text",
- "border_mode_text",
- "share_tolerance_text",
- "build_operator",
- "queue_mode",
- "border_mode",
- "share_tolerance"
+ "lod_mode_",
+ "lod_triangle_limit_",
+ "lod_error_threshold_"
};
const U32 num_lod_controls = sizeof(lod_controls)/sizeof(char*);
const char* file_controls[] =
{
- "lod_browse",
- "lod_file"
+ "lod_browse_",
+ "lod_file_",
};
const U32 num_file_controls = sizeof(file_controls)/sizeof(char*);
- if (fmp)
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (!fmp) return;
+
+ LLComboBox* lod_combo = mFMP->findChild<LLComboBox>("lod_source_" + lod_name[lod]);
+ if (!lod_combo) return;
+
+ S32 lod_mode = lod_combo->getCurrentIndex();
+ if (lod_mode == 0) // LoD from file
{
- //enable/disable controls based on radio groups
- if (mFMP->childGetValue("lod_from_file").asBoolean())
- {
- fmp->mLODMode[mPreviewLOD] = 0;
- for (U32 i = 0; i < num_file_controls; ++i)
- {
- mFMP->childEnable(file_controls[i]);
- }
+ fmp->mLODMode[lod] = 0;
+ for (U32 i = 0; i < num_file_controls; ++i)
+ {
+ mFMP->childShow(file_controls[i] + lod_name[lod]);
+ }
- for (U32 i = 0; i < num_lod_controls; ++i)
- {
- mFMP->childDisable(lod_controls[i]);
- }
+ for (U32 i = 0; i < num_lod_controls; ++i)
+ {
+ mFMP->childHide(lod_controls[i] + lod_name[lod]);
}
- else if (mFMP->childGetValue("lod_none").asBoolean())
+ }
+ else if (lod_mode == 2) // use LoD above
+ {
+ fmp->mLODMode[lod] = 2;
+ for (U32 i = 0; i < num_file_controls; ++i)
{
- fmp->mLODMode[mPreviewLOD] = 2;
- for (U32 i = 0; i < num_file_controls; ++i)
- {
- mFMP->childDisable(file_controls[i]);
- }
+ mFMP->childHide(file_controls[i] + lod_name[lod]);
+ }
- for (U32 i = 0; i < num_lod_controls; ++i)
- {
- mFMP->childDisable(lod_controls[i]);
- }
+ for (U32 i = 0; i < num_lod_controls; ++i)
+ {
+ mFMP->childHide(lod_controls[i] + lod_name[lod]);
+ }
- if (!mModel[mPreviewLOD].empty())
- {
- mModel[mPreviewLOD].clear();
- mScene[mPreviewLOD].clear();
- mVertexBuffer[mPreviewLOD].clear();
+ if (lod < LLModel::LOD_HIGH)
+ {
+ mModel[lod] = mModel[lod + 1];
+ mScene[lod] = mScene[lod + 1];
+ mVertexBuffer[lod].clear();
- //this can cause phasing issues with the UI, so reenter this function and return
- updateStatusMessages();
- return;
+ // Also update lower LoD
+ if (lod > LLModel::LOD_IMPOSTOR)
+ {
+ updateLodControls(lod - 1);
}
}
- else
- { // auto generate, also the default case for wizard which has no radio selection
- fmp->mLODMode[mPreviewLOD] = 1;
+ }
+ else // auto generate, the default case for all LoDs except High
+ {
+ fmp->mLODMode[lod] = 1;
- //don't actually regenerate lod when refreshing UI
- mLODFrozen = true;
+ //don't actually regenerate lod when refreshing UI
+ mLODFrozen = true;
- for (U32 i = 0; i < num_file_controls; ++i)
- {
- mFMP->childDisable(file_controls[i]);
- }
+ for (U32 i = 0; i < num_file_controls; ++i)
+ {
+ mFMP->childHide(file_controls[i] + lod_name[lod]);
+ }
- for (U32 i = 0; i < num_lod_controls; ++i)
- {
- mFMP->childEnable(lod_controls[i]);
- }
+ for (U32 i = 0; i < num_lod_controls; ++i)
+ {
+ mFMP->childShow(lod_controls[i] + lod_name[lod]);
+ }
- //if (threshold)
- {
- LLSpinCtrl* threshold = mFMP->getChild<LLSpinCtrl>("lod_error_threshold");
- LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit");
- limit->setMaxValue(mMaxTriangleLimit);
- limit->forceSetValue(mRequestedTriangleCount[mPreviewLOD]);
+ LLSpinCtrl* threshold = mFMP->getChild<LLSpinCtrl>("lod_error_threshold_" + lod_name[lod]);
+ LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit_" + lod_name[lod]);
- threshold->forceSetValue(mRequestedErrorThreshold[mPreviewLOD]);
+ limit->setMaxValue(mMaxTriangleLimit);
+ limit->forceSetValue(mRequestedTriangleCount[lod]);
- mFMP->getChild<LLComboBox>("lod_mode")->selectNthItem(mRequestedLoDMode[mPreviewLOD]);
- mFMP->getChild<LLComboBox>("build_operator")->selectNthItem(mRequestedBuildOperator[mPreviewLOD]);
- mFMP->getChild<LLComboBox>("queue_mode")->selectNthItem(mRequestedQueueMode[mPreviewLOD]);
- mFMP->getChild<LLComboBox>("border_mode")->selectNthItem(mRequestedBorderMode[mPreviewLOD]);
- mFMP->getChild<LLSpinCtrl>("share_tolerance")->setValue(mRequestedShareTolerance[mPreviewLOD]);
+ threshold->forceSetValue(mRequestedErrorThreshold[lod]);
- if (mRequestedLoDMode[mPreviewLOD] == 0)
- {
- limit->setVisible(true);
- threshold->setVisible(false);
+ mFMP->getChild<LLComboBox>("lod_mode_" + lod_name[lod])->selectNthItem(mRequestedLoDMode[lod]);
- limit->setMaxValue(mMaxTriangleLimit);
- limit->setIncrement(mMaxTriangleLimit/32);
- }
- else
- {
- limit->setVisible(false);
- threshold->setVisible(true);
- }
- }
+ if (mRequestedLoDMode[lod] == 0)
+ {
+ limit->setVisible(true);
+ threshold->setVisible(false);
- mLODFrozen = false;
+ limit->setMaxValue(mMaxTriangleLimit);
+ limit->setIncrement(mMaxTriangleLimit/32);
+ }
+ else
+ {
+ limit->setVisible(false);
+ threshold->setVisible(true);
}
- }
-
- if (mFMP->childGetValue("physics_load_from_file").asBoolean())
- {
- mFMP->childDisable("physics_lod_combo");
- mFMP->childEnable("physics_file");
- mFMP->childEnable("physics_browse");
- }
- else
- {
- mFMP->childEnable("physics_lod_combo");
- mFMP->childDisable("physics_file");
- mFMP->childDisable("physics_browse");
- }
- LLSpinCtrl* crease = mFMP->getChild<LLSpinCtrl>("crease_angle");
-
- if (mRequestedCreaseAngle[mPreviewLOD] == -1.f)
- {
- mFMP->childSetColor("crease_label", LLColor4::grey);
- crease->forceSetValue(75.f);
- }
- else
- {
- mFMP->childSetColor("crease_label", LLColor4::white);
- crease->forceSetValue(mRequestedCreaseAngle[mPreviewLOD]);
+ mLODFrozen = false;
}
-
- mModelUpdatedSignal(true);
-
}
void LLModelPreview::setPreviewTarget(F32 distance)
@@ -4703,6 +4842,42 @@ void LLModelPreview::createPreviewAvatar( void )
}
}
+void LLModelPreview::addEmptyFace( LLModel* pTarget )
+{
+ U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
+
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);
+
+ buff->allocateBuffer(1, 3, true);
+ memset( buff->getMappedData(), 0, buff->getSize() );
+ memset( buff->getIndicesPointer(), 0, buff->getIndicesSize() );
+
+ buff->validateRange( 0, buff->getNumVerts()-1, buff->getNumIndices(), 0 );
+
+ LLStrider<LLVector3> pos;
+ LLStrider<LLVector3> norm;
+ LLStrider<LLVector2> tc;
+ LLStrider<U16> index;
+
+ buff->getVertexStrider(pos);
+
+ if ( type_mask & LLVertexBuffer::MAP_NORMAL )
+ {
+ buff->getNormalStrider(norm);
+ }
+ if ( type_mask & LLVertexBuffer::MAP_TEXCOORD0 )
+ {
+ buff->getTexCoord0Strider(tc);
+ }
+
+ buff->getIndexStrider(index);
+
+ //resize face array
+ int faceCnt = pTarget->getNumVolumeFaces();
+ pTarget->setNumVolumeFaces( faceCnt+1 );
+ pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() );
+
+}
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
@@ -4784,12 +4959,12 @@ BOOL LLModelPreview::render()
if (has_skin_weights)
{ //model has skin weights, enable view options for skin weights and joint positions
- if (fmp)
+ if (fmp && isLegacyRigValid() )
{
fmp->enableViewOption("show_skin_weight");
fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
+ mFMP->childEnable("upload_skin");
}
- mFMP->childEnable("upload_skin");
}
else
{
@@ -4814,8 +4989,12 @@ BOOL LLModelPreview::render()
mFMP->childSetValue("upload_joints", false);
upload_joints = false;
}
-
- mFMP->childSetEnabled("upload_joints", upload_skin);
+
+ //Only enable joint offsets if it passed the earlier critiquing
+ if ( isRigValidForJointPositionUpload() )
+ {
+ mFMP->childSetEnabled("upload_joints", upload_skin);
+ }
F32 explode = mFMP->childGetValue("physics_explode").asReal();
@@ -4869,6 +5048,8 @@ BOOL LLModelPreview::render()
target_pos); // point of interest
+ z_near = llclamp(z_far * 0.001f, 0.001f, 0.1f);
+
LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, width, height, FALSE, z_near, z_far);
stop_glerror();
@@ -4908,8 +5089,13 @@ BOOL LLModelPreview::render()
{
for (U32 j = 0; j < mBaseModel.size(); ++j)
{
- mModel[i][j]->matchMaterialOrder(mBaseModel[j]);
- llassert(mModel[i][j]->mMaterialList == mBaseModel[j]->mMaterialList);
+ int refFaceCnt = 0;
+ int modelFaceCnt = 0;
+
+ if ( !mModel[i][j]->matchMaterialOrder(mBaseModel[j], refFaceCnt, modelFaceCnt ) )
+ {
+ mFMP->childDisable( "calculate_btn" );
+ }
}
}
}
@@ -4945,18 +5131,20 @@ BOOL LLModelPreview::render()
if (textures)
{
- const std::string& binding = instance.mModel->mMaterialList[i];
- const LLImportMaterial& material = instance.mMaterial[binding];
-
- llassert(binding == model->mMaterialList[i]);
-
- glColor4fv(material.mDiffuseColor.mV);
- if (material.mDiffuseMap.notNull())
+ int materialCnt = instance.mModel->mMaterialList.size();
+ if ( i < materialCnt )
{
- if (material.mDiffuseMap->getDiscardLevel() > -1)
+ const std::string& binding = instance.mModel->mMaterialList[i];
+ const LLImportMaterial& material = instance.mMaterial[binding];
+
+ glColor4fv(material.mDiffuseColor.mV);
+ if (material.mDiffuseMap.notNull())
{
- gGL.getTexUnit(0)->bind(material.mDiffuseMap, true);
- mTextureSet.insert(material.mDiffuseMap.get());
+ if (material.mDiffuseMap->getDiscardLevel() > -1)
+ {
+ gGL.getTexUnit(0)->bind(material.mDiffuseMap, true);
+ mTextureSet.insert(material.mDiffuseMap.get());
+ }
}
}
}
@@ -4984,184 +5172,197 @@ BOOL LLModelPreview::render()
if (physics)
{
glClear(GL_DEPTH_BUFFER_BIT);
- LLGLEnable blend(GL_BLEND);
- gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_ZERO);
-
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+
+ for (U32 i = 0; i < 2; i++)
{
- LLModelInstance& instance = *iter;
+ if (i == 0)
+ { //depth only pass
+ gGL.setColorMask(false, false);
+ }
+ else
+ {
+ gGL.setColorMask(true, true);
+ }
- LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
+ //enable alpha blending on second pass but not first pass
+ LLGLState blend(GL_BLEND, i);
+
+ gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
- if (!model)
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
- continue;
- }
+ LLModelInstance& instance = *iter;
- gGL.pushMatrix();
- LLMatrix4 mat = instance.mTransform;
+ LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
- glMultMatrixf((GLfloat*) mat.mMatrix);
+ if (!model)
+ {
+ continue;
+ }
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
- bool render_mesh = true;
+ glMultMatrixf((GLfloat*) mat.mMatrix);
- LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
- if (decomp)
- {
- LLMutexLock(decomp->mMutex);
- LLModel::Decomposition& physics = model->mPhysics;
+ bool render_mesh = true;
- if (!physics.mHull.empty())
+ LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+ if (decomp)
{
- render_mesh = false;
+ LLMutexLock(decomp->mMutex);
- if (physics.mMesh.empty())
- { //build vertex buffer for physics mesh
- gMeshRepo.buildPhysicsMesh(physics);
- }
+ LLModel::Decomposition& physics = model->mPhysics;
+
+ if (!physics.mHull.empty())
+ {
+ render_mesh = false;
+
+ if (physics.mMesh.empty())
+ { //build vertex buffer for physics mesh
+ gMeshRepo.buildPhysicsMesh(physics);
+ }
- if (!physics.mMesh.empty())
- { //render hull instead of mesh
- for (U32 i = 0; i < physics.mMesh.size(); ++i)
- {
- if (explode > 0.f)
+ if (!physics.mMesh.empty())
+ { //render hull instead of mesh
+ for (U32 i = 0; i < physics.mMesh.size(); ++i)
{
- gGL.pushMatrix();
+ if (explode > 0.f)
+ {
+ gGL.pushMatrix();
- LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
- offset *= explode;
+ LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
+ offset *= explode;
- gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
- }
+ gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
+ }
- static std::vector<LLColor4U> hull_colors;
+ static std::vector<LLColor4U> hull_colors;
- if (i+1 >= hull_colors.size())
- {
- hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255));
- }
+ if (i+1 >= hull_colors.size())
+ {
+ hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
+ }
glColor4ubv(hull_colors[i].mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
- if (explode > 0.f)
- {
- gGL.popMatrix();
+ if (explode > 0.f)
+ {
+ gGL.popMatrix();
+ }
}
}
}
}
- }
- if (render_mesh)
- {
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
- {
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
- for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
+ if (render_mesh)
{
- LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
-
- buffer->setBuffer(type_mask & buffer->getTypeMask());
+ if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
+ for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- glColor4f(0.4f, 0.4f, 0.0f, 0.4f);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ glColor4f(0.4f, 0.4f, 0.0f, 0.4f);
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+ buffer->setBuffer(type_mask & buffer->getTypeMask());
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
- glColor3f(1.f, 1.f, 0.f);
+ glColor3f(1.f, 1.f, 0.f);
- glLineWidth(2.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+ glLineWidth(2.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glLineWidth(1.f);
+ }
}
- }
- gGL.popMatrix();
- }
-
- glLineWidth(3.f);
- glPointSize(8.f);
- gPipeline.enableLightsFullbright(LLColor4::white);
- //show degenerate triangles
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
- LLGLDisable cull(GL_CULL_FACE);
- glColor4f(1.f,0.f,0.f,1.f);
- const LLVector4a scale(0.5f);
-
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
- {
- LLModelInstance& instance = *iter;
+ gGL.popMatrix();
+ }
- LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
+ glLineWidth(3.f);
+ glPointSize(8.f);
+ gPipeline.enableLightsFullbright(LLColor4::white);
+ //show degenerate triangles
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ LLGLDisable cull(GL_CULL_FACE);
+ glColor4f(1.f,0.f,0.f,1.f);
+ const LLVector4a scale(0.5f);
- if (!model)
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
- continue;
- }
+ LLModelInstance& instance = *iter;
- gGL.pushMatrix();
- LLMatrix4 mat = instance.mTransform;
+ LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
- glMultMatrixf((GLfloat*) mat.mMatrix);
+ if (!model)
+ {
+ continue;
+ }
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
- LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
- if (decomp)
- {
- LLMutexLock(decomp->mMutex);
+ glMultMatrixf((GLfloat*) mat.mMatrix);
- LLModel::Decomposition& physics = model->mPhysics;
- if (physics.mHull.empty())
+ LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+ if (decomp)
{
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ LLMutexLock(decomp->mMutex);
+
+ LLModel::Decomposition& physics = model->mPhysics;
+
+ if (physics.mHull.empty())
{
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
+ if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
- for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
- {
- LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
+ for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
- buffer->setBuffer(type_mask & buffer->getTypeMask());
+ buffer->setBuffer(type_mask & buffer->getTypeMask());
- LLStrider<LLVector3> pos_strider;
- buffer->getVertexStrider(pos_strider, 0);
- LLVector4a* pos = (LLVector4a*) pos_strider.get();
+ LLStrider<LLVector3> pos_strider;
+ buffer->getVertexStrider(pos_strider, 0);
+ LLVector4a* pos = (LLVector4a*) pos_strider.get();
- LLStrider<U16> idx;
- buffer->getIndexStrider(idx, 0);
-
- for (U32 i = 0; i < buffer->getNumIndices(); i += 3)
- {
- LLVector4a v1; v1.setMul(pos[*idx++], scale);
- LLVector4a v2; v2.setMul(pos[*idx++], scale);
- LLVector4a v3; v3.setMul(pos[*idx++], scale);
+ LLStrider<U16> idx;
+ buffer->getIndexStrider(idx, 0);
- if (ll_is_degenerate(v1,v2,v3))
+ for (U32 i = 0; i < buffer->getNumIndices(); i += 3)
{
- buffer->draw(LLRender::LINE_LOOP, 3, i);
- buffer->draw(LLRender::POINTS, 3, i);
+ LLVector4a v1; v1.setMul(pos[*idx++], scale);
+ LLVector4a v2; v2.setMul(pos[*idx++], scale);
+ LLVector4a v3; v3.setMul(pos[*idx++], scale);
+
+ if (ll_is_degenerate(v1,v2,v3))
+ {
+ buffer->draw(LLRender::LINE_LOOP, 3, i);
+ buffer->draw(LLRender::POINTS, 3, i);
+ }
}
}
}
}
- }
- gGL.popMatrix();
+ gGL.popMatrix();
+ }
+ glLineWidth(1.f);
+ glPointSize(1.f);
+ gPipeline.enableLightsPreview();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
- glLineWidth(1.f);
- glPointSize(1.f);
- gPipeline.enableLightsPreview();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
else
@@ -5328,8 +5529,7 @@ void LLModelPreview::setPreviewLOD(S32 lod)
LLComboBox* combo_box = mFMP->getChild<LLComboBox>("preview_lod_combo");
combo_box->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
- mFMP->childSetTextArg("lod_table_footer", "[DETAIL]", mFMP->getString(lod_name[mPreviewLOD]));
- mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]);
+ mFMP->childSetText("lod_file_" + lod_name[mPreviewLOD], mLODFile[mPreviewLOD]);
// the wizard has three lod drop downs
LLComboBox* combo_box2 = mFMP->getChild<LLComboBox>("preview_lod_combo2");
@@ -5350,25 +5550,16 @@ void LLModelPreview::setPreviewLOD(S32 lod)
mFMP->childSetColor(lod_triangles_name[i], color);
mFMP->childSetColor(lod_vertices_name[i], color);
}
-
- LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
- if (fmp)
- {
- LLRadioGroup* radio = fmp->getChild<LLRadioGroup>("lod_file_or_limit");
- radio->selectNthItem(fmp->mLODMode[mPreviewLOD]);
- }
}
refresh();
updateStatusMessages();
}
-//static
-void LLFloaterModelPreview::onBrowseLOD(void* data)
+void LLFloaterModelPreview::onBrowseLOD(S32 lod)
{
assert_main_thread();
- LLFloaterModelPreview* mp = (LLFloaterModelPreview*) data;
- mp->loadModel(mp->mModelPreview->mPreviewLOD);
+ loadModel(lod);
}
//static
@@ -5380,6 +5571,7 @@ void LLFloaterModelPreview::onReset(void* user_data)
LLModelPreview* mp = fmp->mModelPreview;
std::string filename = mp->mLODFile[3];
+ fmp->resetDisplayOptions();
//reset model preview
fmp->initModelPreview();
@@ -5394,6 +5586,8 @@ void LLFloaterModelPreview::onUpload(void* user_data)
LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data;
+ mp->mUploadBtn->setEnabled(false);
+
mp->mModelPreview->rebuildUploadData();
bool upload_skinweights = mp->childGetValue("upload_skin").asBoolean();
@@ -5407,8 +5601,7 @@ void LLFloaterModelPreview::onUpload(void* user_data)
}
-//static
-void LLFloaterModelPreview::refresh(LLUICtrl* ctrl, void* user_data)
+void LLFloaterModelPreview::refresh()
{
sInstance->toggleCalculateButton(true);
sInstance->mModelPreview->mDirty = true;
@@ -5429,12 +5622,11 @@ void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture
}
}
-void LLModelPreview::onLODParamCommit(bool enforce_tri_limit)
+void LLModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
{
if (!mLODFrozen)
{
- genLODs(mPreviewLOD, 3, enforce_tri_limit);
- updateStatusMessages();
+ genLODs(lod, 3, enforce_tri_limit);
refresh();
}
}
@@ -5475,11 +5667,6 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
{
mCalculateBtn->setVisible( false );
}
- else
- if ( !mModelPreview->isLegacyRigValid() )
- {
- mCalculateBtn->setVisible( false );
- }
}
mUploadBtn->setVisible(!visible);
@@ -5488,10 +5675,10 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
if (visible)
{
std::string tbd = getString("tbd");
- childSetTextArg("weights", "[EQ]", tbd);
- childSetTextArg("weights", "[ST]", tbd);
- childSetTextArg("weights", "[SIM]", tbd);
- childSetTextArg("weights", "[PH]", tbd);
+ childSetTextArg("prim_weight", "[EQ]", tbd);
+ childSetTextArg("download_weight", "[ST]", tbd);
+ childSetTextArg("server_weight", "[SIM]", tbd);
+ childSetTextArg("physics_weight", "[PH]", tbd);
childSetTextArg("upload_fee", "[FEE]", tbd);
childSetTextArg("price_breakdown", "[STREAMING]", tbd);
childSetTextArg("price_breakdown", "[PHYSICS]", tbd);
@@ -5501,6 +5688,23 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
}
}
+void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)
+{
+ mModelPreview->updateLodControls(lod);
+ refresh();
+}
+
+void LLFloaterModelPreview::resetDisplayOptions()
+{
+ std::map<std::string,bool>::iterator option_it = mModelPreview->mViewOption.begin();
+
+ for(;option_it != mModelPreview->mViewOption.end(); ++option_it)
+ {
+ LLUICtrl* ctrl = getChild<LLUICtrl>(option_it->first);
+ ctrl->setValue(false);
+ }
+}
+
void LLFloaterModelPreview::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url)
{
mModelPhysicsFee = result;
@@ -5514,17 +5718,16 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
const LLSD& result = mModelPhysicsFee;
mUploadModelUrl = result["url"].asString();
- childSetTextArg("weights", "[EQ]", llformat("%0.3f", result["resource_cost"].asReal()));
- childSetTextArg("weights", "[ST]", llformat("%0.3f", result["model_streaming_cost"].asReal()));
- childSetTextArg("weights", "[SIM]", llformat("%0.3f", result["simulation_cost"].asReal()));
- childSetTextArg("weights", "[PH]", llformat("%0.3f", result["physics_cost"].asReal()));
+ childSetTextArg("prim_weight", "[EQ]", llformat("%0.3f", result["resource_cost"].asReal()));
+ childSetTextArg("download_weight", "[ST]", llformat("%0.3f", result["model_streaming_cost"].asReal()));
+ childSetTextArg("server_weight", "[SIM]", llformat("%0.3f", result["simulation_cost"].asReal()));
+ childSetTextArg("physics_weight", "[PH]", llformat("%0.3f", result["physics_cost"].asReal()));
childSetTextArg("upload_fee", "[FEE]", llformat("%d", result["upload_price"].asInteger()));
childSetTextArg("price_breakdown", "[STREAMING]", llformat("%d", result["upload_price_breakdown"]["mesh_streaming"].asInteger()));
childSetTextArg("price_breakdown", "[PHYSICS]", llformat("%d", result["upload_price_breakdown"]["mesh_physics"].asInteger()));
childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger()));
childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger()));
childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger()));
- childSetVisible("weights", true);
childSetVisible("upload_fee", true);
childSetVisible("price_breakdown", true);
mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty());
@@ -5532,20 +5735,23 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason)
{
- toggleCalculateButton(true);
llwarns << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << llendl;
+ doOnIdleOneTime(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, true));
}
/*virtual*/
void LLFloaterModelPreview::onModelUploadSuccess()
{
+ assert_main_thread();
closeFloater(false);
}
/*virtual*/
void LLFloaterModelPreview::onModelUploadFailure()
{
+ assert_main_thread();
toggleCalculateButton(true);
+ mUploadBtn->setEnabled(true);
}
S32 LLFloaterModelPreview::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2)
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 3a5f7602fe..47de99ce25 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -120,12 +120,13 @@ public:
void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
-
+ void extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform );
+
void setLoadState(U32 state);
void buildJointToNodeMappingFromScene( daeElement* pRoot );
void processJointToNodeMapping( domNode* pNode );
-
+ void processChildJoints( domNode* pParentNode );
//map of avatar joints as named in COLLADA assets to internal joint names
std::map<std::string, std::string> mJointMap;
@@ -176,18 +177,18 @@ public:
void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
- static void onBrowseLOD(void* data);
+ void onBrowseLOD(S32 lod);
static void onReset(void* data);
static void onUpload(void* data);
- static void refresh(LLUICtrl* ctrl, void* data);
+ void refresh();
void loadModel(S32 lod);
void loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false);
- void onViewOptionChecked(const LLSD& userdata);
+ void onViewOptionChecked(LLUICtrl* ctrl);
bool isViewOptionChecked(const LLSD& userdata);
bool isViewOptionEnabled(const LLSD& userdata);
void setViewOptionEnabled(const std::string& option, bool enabled);
@@ -217,17 +218,17 @@ protected:
static void onPelvisOffsetCommit(LLUICtrl*, void*);
static void onUploadJointsCommit(LLUICtrl*,void*);
static void onUploadSkinCommit(LLUICtrl*,void*);
-
- static void onPhysicsLoadRadioCommit(LLUICtrl*,void *data);
static void onPreviewLODCommit(LLUICtrl*,void*);
static void onGenerateNormalsCommit(LLUICtrl*,void*);
+ void toggleGenarateNormals();
+
static void onAutoFillCommit(LLUICtrl*,void*);
- static void onLODParamCommit(LLUICtrl*,void*);
- static void onLODParamCommitTriangleLimit(LLUICtrl*,void*);
+ void onLODParamCommit(S32 lod, bool enforce_tri_limit);
+
static void onExplodeCommit(LLUICtrl*, void*);
static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
@@ -266,11 +267,9 @@ protected:
//store which lod mode each LOD is using
// 0 - load from file
// 1 - auto generate
- // 2 - None
+ // 2 - use LoD above
S32 mLODMode[4];
- LLMenuButton* mViewOptionMenuButton;
- LLToggleableMenu* mViewOptionMenu;
LLMutex* mStatusLock;
LLSD mModelPhysicsFee;
@@ -279,9 +278,16 @@ private:
void onClickCalculateBtn();
void toggleCalculateButton();
+ void onLoDSourceCommit(S32 lod);
+
// Toggles between "Calculate weights & fee" and "Upload" buttons.
void toggleCalculateButton(bool visible);
+ // resets display options of model preview to their defaults.
+ void resetDisplayOptions();
+
+ void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
+
LLButton* mUploadBtn;
LLButton* mCalculateBtn;
};
@@ -334,9 +340,11 @@ public:
void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions);
void clearIncompatible(S32 lod);
void updateStatusMessages();
+ void updateLodControls(S32 lod);
void clearGLODGroup();
- void onLODParamCommit(bool enforce_tri_limit);
-
+ void onLODParamCommit(S32 lod, bool enforce_tri_limit);
+ void addEmptyFace( LLModel* pTarget );
+
const bool getModelPivot( void ) const { return mHasPivot; }
void setHasPivot( bool val ) { mHasPivot = val; }
void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; }
@@ -365,9 +373,6 @@ public:
void setLoadState( U32 state ) { mLoadState = state; }
U32 getLoadState() { return mLoadState; }
- //setRestJointFlag: If an asset comes through that changes the joints, we want the reset to persist
- void setResetJointFlag( bool state ) { if ( !mResetJoints ) mResetJoints = state; }
- const bool getResetJointFlag( void ) const { return mResetJoints; }
void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; }
const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; }
diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp
new file mode 100644
index 0000000000..0862cd2897
--- /dev/null
+++ b/indra/newview/llfloaterobjectweights.cpp
@@ -0,0 +1,266 @@
+/**
+ * @file llfloaterobjectweights.cpp
+ * @brief Object weights advanced view floater
+ *
+ * $LicenseInfo:firstyear=2011&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"
+
+#include "llfloaterobjectweights.h"
+
+#include "llparcel.h"
+
+#include "llfloaterreg.h"
+#include "lltextbox.h"
+
+#include "llagent.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+// virtual
+bool LLCrossParcelFunctor::apply(LLViewerObject* obj)
+{
+ // Add the root object box.
+ mBoundingBox.addBBoxAgent(LLBBox(obj->getPositionRegion(), obj->getRotationRegion(), obj->getScale() * -0.5f, obj->getScale() * 0.5f).getAxisAligned());
+
+ // Extend the bounding box across all the children.
+ LLViewerObject::const_child_list_t children = obj->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin();
+ iter != children.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ mBoundingBox.addBBoxAgent(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+ }
+
+ bool result = false;
+
+ LLViewerRegion* region = obj->getRegion();
+ if (region)
+ {
+ std::vector<LLBBox> boxes;
+ boxes.push_back(mBoundingBox);
+ result = region->objectsCrossParcel(boxes);
+ }
+
+ return result;
+}
+
+LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key)
+: LLFloater(key),
+ mSelectedObjects(NULL),
+ mSelectedPrims(NULL),
+ mSelectedDownloadWeight(NULL),
+ mSelectedPhysicsWeight(NULL),
+ mSelectedServerWeight(NULL),
+ mSelectedDisplayWeight(NULL),
+ mSelectedOnLand(NULL),
+ mRezzedOnLand(NULL),
+ mRemainingCapacity(NULL),
+ mTotalCapacity(NULL)
+{
+}
+
+LLFloaterObjectWeights::~LLFloaterObjectWeights()
+{
+}
+
+// virtual
+BOOL LLFloaterObjectWeights::postBuild()
+{
+ mSelectedObjects = getChild<LLTextBox>("objects");
+ mSelectedPrims = getChild<LLTextBox>("prims");
+
+ mSelectedDownloadWeight = getChild<LLTextBox>("download");
+ mSelectedPhysicsWeight = getChild<LLTextBox>("physics");
+ mSelectedServerWeight = getChild<LLTextBox>("server");
+ mSelectedDisplayWeight = getChild<LLTextBox>("display");
+
+ mSelectedOnLand = getChild<LLTextBox>("selected");
+ mRezzedOnLand = getChild<LLTextBox>("rezzed_on_land");
+ mRemainingCapacity = getChild<LLTextBox>("remaining_capacity");
+ mTotalCapacity = getChild<LLTextBox>("total_capacity");
+
+ return TRUE;
+}
+
+// virtual
+void LLFloaterObjectWeights::onOpen(const LLSD& key)
+{
+ refresh();
+ updateLandImpacts(LLViewerParcelMgr::getInstance()->getFloatingParcelSelection()->getParcel());
+}
+
+// virtual
+void LLFloaterObjectWeights::onWeightsUpdate(const SelectionCost& selection_cost)
+{
+ mSelectedDownloadWeight->setText(llformat("%.1f", selection_cost.mNetworkCost));
+ mSelectedPhysicsWeight->setText(llformat("%.1f", selection_cost.mPhysicsCost));
+ mSelectedServerWeight->setText(llformat("%.1f", selection_cost.mSimulationCost));
+
+ S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost();
+ mSelectedDisplayWeight->setText(llformat("%d", render_cost));
+
+ toggleWeightsLoadingIndicators(false);
+}
+
+//virtual
+void LLFloaterObjectWeights::setErrorStatus(U32 status, const std::string& reason)
+{
+ const std::string text = getString("nothing_selected");
+
+ mSelectedDownloadWeight->setText(text);
+ mSelectedPhysicsWeight->setText(text);
+ mSelectedServerWeight->setText(text);
+ mSelectedDisplayWeight->setText(text);
+
+ toggleWeightsLoadingIndicators(false);
+}
+
+void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel)
+{
+ if (!parcel || LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ updateIfNothingSelected();
+ }
+ else
+ {
+ S32 rezzed_prims = parcel->getSimWidePrimCount();
+ S32 total_capacity = parcel->getSimWideMaxPrimCapacity();
+
+ mRezzedOnLand->setText(llformat("%d", rezzed_prims));
+ mRemainingCapacity->setText(llformat("%d", total_capacity - rezzed_prims));
+ mTotalCapacity->setText(llformat("%d", total_capacity));
+
+ toggleLandImpactsLoadingIndicators(false);
+ }
+}
+
+void LLFloaterObjectWeights::refresh()
+{
+ LLSelectMgr* sel_mgr = LLSelectMgr::getInstance();
+
+ if (sel_mgr->getSelection()->isEmpty())
+ {
+ updateIfNothingSelected();
+ }
+ else
+ {
+ S32 prim_count = sel_mgr->getSelection()->getObjectCount();
+ S32 link_count = sel_mgr->getSelection()->getRootObjectCount();
+ F32 prim_equiv = sel_mgr->getSelection()->getSelectedLinksetCost();
+
+ mSelectedObjects->setText(llformat("%d", link_count));
+ mSelectedPrims->setText(llformat("%d", prim_count));
+ mSelectedOnLand->setText(llformat("%.1d", (S32)prim_equiv));
+
+ LLCrossParcelFunctor func;
+ if (sel_mgr->getSelection()->applyToRootObjects(&func, true))
+ {
+ // Some of the selected objects cross parcel bounds.
+ // We don't display object weights and land impacts in this case.
+ const std::string text = getString("nothing_selected");
+
+ mRezzedOnLand->setText(text);
+ mRemainingCapacity->setText(text);
+ mTotalCapacity->setText(text);
+
+ toggleLandImpactsLoadingIndicators(false);
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region && region->capabilitiesReceived())
+ {
+ for (LLObjectSelection::valid_root_iterator iter = sel_mgr->getSelection()->valid_root_begin();
+ iter != sel_mgr->getSelection()->valid_root_end(); ++iter)
+ {
+ LLAccountingCostManager::getInstance()->addObject((*iter)->getObject()->getID());
+ }
+
+ std::string url = region->getCapability("ResourceCostSelected");
+ if (!url.empty())
+ {
+ // Update the transaction id before the new fetch request
+ generateTransactionID();
+
+ LLAccountingCostManager::getInstance()->fetchCosts(Roots, url, getObserverHandle());
+ toggleWeightsLoadingIndicators(true);
+ }
+ }
+ else
+ {
+ llwarns << "Failed to get region capabilities" << llendl;
+ }
+ }
+}
+
+// virtual
+void LLFloaterObjectWeights::generateTransactionID()
+{
+ mTransactionID.generate();
+}
+
+void LLFloaterObjectWeights::toggleWeightsLoadingIndicators(bool visible)
+{
+ childSetVisible("download_loading_indicator", visible);
+ childSetVisible("physics_loading_indicator", visible);
+ childSetVisible("server_loading_indicator", visible);
+ childSetVisible("display_loading_indicator", visible);
+
+ mSelectedDownloadWeight->setVisible(!visible);
+ mSelectedPhysicsWeight->setVisible(!visible);
+ mSelectedServerWeight->setVisible(!visible);
+ mSelectedDisplayWeight->setVisible(!visible);
+}
+
+void LLFloaterObjectWeights::toggleLandImpactsLoadingIndicators(bool visible)
+{
+ childSetVisible("selected_loading_indicator", visible);
+ childSetVisible("rezzed_on_land_loading_indicator", visible);
+ childSetVisible("remaining_capacity_loading_indicator", visible);
+ childSetVisible("total_capacity_loading_indicator", visible);
+
+ mSelectedOnLand->setVisible(!visible);
+ mRezzedOnLand->setVisible(!visible);
+ mRemainingCapacity->setVisible(!visible);
+ mTotalCapacity->setVisible(!visible);
+}
+
+void LLFloaterObjectWeights::updateIfNothingSelected()
+{
+ const std::string text = getString("nothing_selected");
+
+ mSelectedObjects->setText(text);
+ mSelectedPrims->setText(text);
+
+ mSelectedDownloadWeight->setText(text);
+ mSelectedPhysicsWeight->setText(text);
+ mSelectedServerWeight->setText(text);
+ mSelectedDisplayWeight->setText(text);
+
+ mSelectedOnLand->setText(text);
+ mRezzedOnLand->setText(text);
+ mRemainingCapacity->setText(text);
+ mTotalCapacity->setText(text);
+
+ toggleWeightsLoadingIndicators(false);
+ toggleLandImpactsLoadingIndicators(false);
+}
diff --git a/indra/newview/llfloaterobjectweights.h b/indra/newview/llfloaterobjectweights.h
new file mode 100644
index 0000000000..9a244573be
--- /dev/null
+++ b/indra/newview/llfloaterobjectweights.h
@@ -0,0 +1,93 @@
+/**
+ * @file llfloaterobjectweights.h
+ * @brief Object weights advanced view floater
+ *
+ * $LicenseInfo:firstyear=2011&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_LLFLOATEROBJECTWEIGHTS_H
+#define LL_LLFLOATEROBJECTWEIGHTS_H
+
+#include "llfloater.h"
+
+#include "llaccountingcostmanager.h"
+#include "llselectmgr.h"
+
+class LLParcel;
+class LLTextBox;
+
+/**
+ * struct LLCrossParcelFunctor
+ *
+ * A functor that checks whether a bounding box for all
+ * selected objects crosses a region or parcel bounds.
+ */
+struct LLCrossParcelFunctor : public LLSelectedObjectFunctor
+{
+ /*virtual*/ bool apply(LLViewerObject* obj);
+
+private:
+ LLBBox mBoundingBox;
+};
+
+
+class LLFloaterObjectWeights : public LLFloater, LLAccountingCostObserver
+{
+public:
+ LOG_CLASS(LLFloaterObjectWeights);
+
+ LLFloaterObjectWeights(const LLSD& key);
+ ~LLFloaterObjectWeights();
+
+ /*virtual*/ BOOL postBuild();
+
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ /*virtual*/ void onWeightsUpdate(const SelectionCost& selection_cost);
+ /*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
+
+ void updateLandImpacts(const LLParcel* parcel);
+ void refresh();
+
+private:
+ /*virtual*/ void generateTransactionID();
+
+ void toggleWeightsLoadingIndicators(bool visible);
+ void toggleLandImpactsLoadingIndicators(bool visible);
+
+ void updateIfNothingSelected();
+
+ LLTextBox *mSelectedObjects;
+ LLTextBox *mSelectedPrims;
+
+ LLTextBox *mSelectedDownloadWeight;
+ LLTextBox *mSelectedPhysicsWeight;
+ LLTextBox *mSelectedServerWeight;
+ LLTextBox *mSelectedDisplayWeight;
+
+ LLTextBox *mSelectedOnLand;
+ LLTextBox *mRezzedOnLand;
+ LLTextBox *mRemainingCapacity;
+ LLTextBox *mTotalCapacity;
+};
+
+#endif //LL_LLFLOATEROBJECTWEIGHTS_H
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 9a99417e93..676059779c 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -172,30 +172,9 @@ bool estate_dispatch_initialized = false;
LLUUID LLFloaterRegionInfo::sRequestInvoice;
-void LLFloaterRegionInfo::onConsoleReplyReceived(const std::string& output)
-{
- llwarns << "here is what they're giving us: " << output << llendl;
-
- if (output.find("FALSE") != std::string::npos)
- {
- getChild<LLUICtrl>("mesh_rez_enabled_check")->setValue(FALSE);
- }
- else
- {
- getChild<LLUICtrl>("mesh_rez_enabled_check")->setValue(TRUE);
- }
-}
-
-
LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed)
: LLFloater(seed)
-{
- mConsoleReplySignalConnection = LLFloaterRegionDebugConsole::setConsoleReplyCallback(
- boost::bind(
- &LLFloaterRegionInfo::onConsoleReplyReceived,
- this,
- _1));
-}
+{}
BOOL LLFloaterRegionInfo::postBuild()
{
@@ -246,9 +225,7 @@ BOOL LLFloaterRegionInfo::postBuild()
}
LLFloaterRegionInfo::~LLFloaterRegionInfo()
-{
- mConsoleReplySignalConnection.disconnect();
-}
+{}
void LLFloaterRegionInfo::onOpen(const LLSD& key)
{
@@ -638,9 +615,6 @@ bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region)
getChildView("im_btn")->setEnabled(allow_modify);
getChildView("manage_telehub_btn")->setEnabled(allow_modify);
- const bool enable_mesh = gMeshRepo.meshRezEnabled();
- getChildView("mesh_rez_enabled_check")->setVisible(enable_mesh);
- getChildView("mesh_rez_enabled_check")->setEnabled(getChildView("mesh_rez_enabled_check")->getEnabled() && enable_mesh);
// Data gets filled in by processRegionInfo
return LLPanelRegionInfo::refreshFromRegion(region);
@@ -659,7 +633,6 @@ BOOL LLPanelRegionGeneralInfo::postBuild()
initCtrl("access_combo");
initCtrl("restrict_pushobject");
initCtrl("block_parcel_search_check");
- initCtrl("mesh_rez_enabled_check");
childSetAction("kick_btn", boost::bind(&LLPanelRegionGeneralInfo::onClickKick, this));
childSetAction("kick_all_btn", onClickKickAll, this);
@@ -875,27 +848,6 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate()
sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings);
}
- std::string sim_console_url = gAgent.getRegion()->getCapability("SimConsoleAsync");
-
- if (!sim_console_url.empty())
- {
- std::string update_str = "set mesh_rez_enabled ";
- if (getChild<LLUICtrl>("mesh_rez_enabled_check")->getValue().asBoolean())
- {
- update_str += "true";
- }
- else
- {
- update_str += "false";
- }
-
- LLHTTPClient::post(
- sim_console_url,
- LLSD(update_str),
- new ConsoleUpdateResponder);
- }
-
-
// if we changed access levels, tell user about it
LLViewerRegion* region = gAgent.getRegion();
if (region && (getChild<LLUICtrl>("access_combo")->getValue().asInteger() != region->getSimAccess()) )
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index c1fef57ac9..c402de66e8 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -100,10 +100,6 @@ private:
LLFloaterRegionInfo(const LLSD& seed);
~LLFloaterRegionInfo();
-
- void onConsoleReplyReceived(const std::string& output);
-
- boost::signals2::connection mConsoleReplySignalConnection;;
protected:
void onTabSelected(const LLSD& param);
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 84fb8bd9e7..1008b4a6e4 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -41,6 +41,7 @@
#include "llfloaterbuildoptions.h"
#include "llfloatermediasettings.h"
#include "llfloateropenobject.h"
+#include "llfloaterobjectweights.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmediaentry.h"
@@ -54,6 +55,7 @@
#include "llpanelobject.h"
#include "llpanelvolume.h"
#include "llpanelpermissions.h"
+#include "llparcel.h"
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -84,7 +86,6 @@
#include "llviewerwindow.h"
#include "llvovolume.h"
#include "lluictrlfactory.h"
-#include "llaccountingquotamanager.h"
#include "llmeshrepository.h"
// Globals
@@ -118,6 +119,24 @@ void commit_radio_group_edit(LLUICtrl* ctrl);
void commit_radio_group_land(LLUICtrl* ctrl);
void commit_slider_zoom(LLUICtrl *ctrl);
+/**
+ * Class LLLandImpactsObserver
+ *
+ * An observer class to monitor parcel selection and update
+ * the land impacts data from a parcel containing the selected object.
+ */
+class LLLandImpactsObserver : public LLParcelObserver
+{
+public:
+ virtual void changed()
+ {
+ LLFloaterTools* tools_floater = LLFloaterReg::getTypedInstance<LLFloaterTools>("build");
+ if(tools_floater)
+ {
+ tools_floater->updateLandImpacts();
+ }
+ }
+};
//static
void* LLFloaterTools::createPanelPermissions(void* data)
@@ -345,6 +364,9 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCostTextBorder(NULL),
mTabLand(NULL),
+
+ mLandImpactsObserver(NULL),
+
mDirty(TRUE),
mNeedMediaTitle(TRUE)
{
@@ -376,12 +398,17 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
+ mLandImpactsObserver = new LLLandImpactsObserver();
+ LLViewerParcelMgr::getInstance()->addObserver(mLandImpactsObserver);
}
LLFloaterTools::~LLFloaterTools()
{
// children automatically deleted
gFloaterTools = NULL;
+
+ LLViewerParcelMgr::getInstance()->removeObserver(mLandImpactsObserver);
+ delete mLandImpactsObserver;
}
void LLFloaterTools::setStatusText(const std::string& text)
@@ -436,7 +463,8 @@ void LLFloaterTools::refresh()
if (sShowObjectCost)
{
std::string prim_cost_string;
- LLResMgr::getInstance()->getIntegerString(prim_cost_string, calcRenderCost());
+ S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost();
+ LLResMgr::getInstance()->getIntegerString(prim_cost_string, render_cost);
getChild<LLUICtrl>("RenderingCost")->setTextArg("[COUNT]", prim_cost_string);
}
@@ -449,49 +477,44 @@ void LLFloaterTools::refresh()
else
#endif
{
- F32 link_phys_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetPhysicsCost();
F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost();
- S32 prim_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
S32 link_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
- LLStringUtil::format_map_t selection_args;
- selection_args["OBJ_COUNT"] = llformat("%.1d", link_count);
- selection_args["PRIM_COUNT"] = llformat("%.1d", prim_count);
-
- std::ostringstream selection_info;
-
- bool show_adv_weight = gSavedSettings.getBOOL("ShowAdvancedBuilderOptions");
- bool show_mesh_cost = gMeshRepo.meshRezEnabled();
-
- if (show_mesh_cost)
+ LLCrossParcelFunctor func;
+ if (LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true))
{
- 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);
+ // Selection crosses parcel bounds.
+ // We don't display remaining land capacity in this case.
+ const LLStringExplicit empty_str("");
+ childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", empty_str);
}
else
{
- selection_args["PE_STRING"] = "";
+ LLViewerObject* selected_object = mObjectSelection->getFirstObject();
+ if (selected_object)
+ {
+ // Select a parcel at the currently selected object's position.
+ LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
+ }
+ else
+ {
+ llwarns << "Failed to get selected object" << llendl;
+ }
}
- selection_info << getString("status_selectcount", selection_args);
+ LLStringUtil::format_map_t selection_args;
+ selection_args["OBJ_COUNT"] = llformat("%.1d", link_count);
+ selection_args["LAND_IMPACT"] = llformat("%.1d", (S32)link_cost);
- if (show_adv_weight)
- {
- selection_info << ",";
+ std::ostringstream selection_info;
+
+ selection_info << getString("status_selectcount", selection_args);
- childSetTextArg("selection_weight", "[PHYS_WEIGHT]", llformat("%.1f", link_phys_cost));
- childSetTextArg("selection_weight", "[DISP_WEIGHT]", llformat("%.1d", calcRenderCost()));
- }
- else
- {
- selection_info<<".";
- }
getChild<LLTextBox>("selection_count")->setText(selection_info.str());
bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
childSetVisible("selection_count", have_selection);
- childSetVisible("selection_weight", have_selection && show_adv_weight);
+ childSetVisible("remaining_capacity", have_selection);
childSetVisible("selection_empty", !have_selection);
}
@@ -504,6 +527,13 @@ void LLFloaterTools::refresh()
refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
+
+ // Refresh the advanced weights floater
+ LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::getTypedInstance<LLFloaterObjectWeights>("object_weights");
+ if(object_weights_floater && object_weights_floater->getVisible())
+ {
+ object_weights_floater->refresh();
+ }
}
void LLFloaterTools::draw()
@@ -762,7 +792,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
getChildView("selection_count")->setVisible(!land_visible && have_selection);
- getChildView("selection_weight")->setVisible(!land_visible && have_selection && gSavedSettings.getBOOL("ShowAdvancedBuilderOptions"));
+ getChildView("remaining_capacity")->setVisible(!land_visible && have_selection);
getChildView("selection_empty")->setVisible(!land_visible && !have_selection);
mTab->setVisible(!land_visible);
@@ -826,6 +856,9 @@ void LLFloaterTools::onClose(bool app_quitting)
//gMenuBarView->setItemVisible("BuildTools", FALSE);
LLFloaterReg::hideInstance("media_settings");
+
+ // hide the advanced object weights floater
+ LLFloaterReg::hideInstance("object_weights");
}
void click_popup_info(void*)
@@ -1012,35 +1045,6 @@ void LLFloaterTools::onClickGridOptions()
//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
}
-S32 LLFloaterTools::calcRenderCost()
-{
- S32 cost = 0;
- std::set<LLUUID> textures;
-
- for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin();
- selection_iter != LLSelectMgr::getInstance()->getSelection()->end();
- ++selection_iter)
- {
- LLSelectNode *select_node = *selection_iter;
- if (select_node)
- {
- LLViewerObject *vobj = select_node->getObject();
- if (vobj->getVolume())
- {
- LLVOVolume* volume = (LLVOVolume*) vobj;
-
- cost += volume->getRenderCost(textures);
- cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST;
- textures.clear();
- }
- }
- }
-
-
- return cost;
-}
-
-
// static
void LLFloaterTools::setEditTool(void* tool_pointer)
{
@@ -1116,6 +1120,37 @@ bool LLFloaterTools::selectedMediaEditable()
return selected_Media_editable;
}
+void LLFloaterTools::updateLandImpacts()
+{
+ LLParcel *parcel = mParcelSelection->getParcel();
+ if (!parcel)
+ {
+ return;
+ }
+
+ S32 rezzed_prims = parcel->getSimWidePrimCount();
+ S32 total_capacity = parcel->getSimWideMaxPrimCapacity();
+
+ std::string remaining_capacity_str = "";
+
+ bool show_mesh_cost = gMeshRepo.meshRezEnabled();
+ if (show_mesh_cost)
+ {
+ LLStringUtil::format_map_t remaining_capacity_args;
+ remaining_capacity_args["LAND_CAPACITY"] = llformat("%d", total_capacity - rezzed_prims);
+ remaining_capacity_str = getString("status_remaining_capacity", remaining_capacity_args);
+ }
+
+ childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", remaining_capacity_str);
+
+ // Update land impacts info in the weights floater
+ LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::getTypedInstance<LLFloaterObjectWeights>("object_weights");
+ if(object_weights_floater)
+ {
+ object_weights_floater->updateLandImpacts(parcel);
+ }
+}
+
void LLFloaterTools::getMediaState()
{
LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 69636190fc..63ed9dc82b 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -47,6 +47,7 @@ class LLMediaCtrl;
class LLTool;
class LLParcelSelection;
class LLObjectSelection;
+class LLLandImpactsObserver;
typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle;
@@ -103,6 +104,7 @@ public:
void updateMediaTitle();
void navigateToTitleMedia( const std::string url );
bool selectedMediaEditable();
+ void updateLandImpacts();
private:
void refresh();
@@ -113,7 +115,6 @@ private:
static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
void onClickGridOptions();
- S32 calcRenderCost();
public:
LLButton *mBtnFocus;
@@ -181,6 +182,8 @@ public:
LLTabContainer* mTabLand;
+ LLLandImpactsObserver* mLandImpactsObserver;
+
LLParcelSelectionHandle mParcelSelection;
LLObjectSelectionHandle mObjectSelection;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index fc594841e3..e12f140747 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -411,7 +411,6 @@ public:
cc = llsd_from_file("fake_upload_error.xml");
}
- //assert_main_thread();
mThread->mPendingUploads--;
dump_llsd_to_file(cc,make_dump_name("whole_model_upload_response_",dump_num));
@@ -1321,6 +1320,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
std::map<LLModel*,S32> mesh_index;
std::string model_name;
+ std::string model_metric;
S32 instance_num = 0;
@@ -1342,6 +1342,11 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
model_name = data.mBaseModel->getName();
}
+ if (model_metric.empty())
+ {
+ model_metric = data.mBaseModel->getMetric();
+ }
+
std::stringstream ostr;
LLModel::Decomposition& decomp =
@@ -1455,6 +1460,8 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
if (model_name.empty()) model_name = "mesh model";
result["name"] = model_name;
+ if (model_metric.empty()) model_metric = "MUT_Unspecified";
+ res["metric"] = model_metric;
result["asset_resources"] = res;
dump_llsd_to_file(result,make_dump_name("whole_model_",dump_num));
@@ -1463,51 +1470,57 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
void LLMeshUploadThread::generateHulls()
{
+ bool has_valid_requests = false ;
+
for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
- {
- LLMeshUploadData data;
- data.mBaseModel = iter->first;
+ {
+ LLMeshUploadData data;
+ data.mBaseModel = iter->first;
- LLModelInstance& instance = *(iter->second.begin());
+ LLModelInstance& instance = *(iter->second.begin());
- for (S32 i = 0; i < 5; i++)
- {
- data.mModel[i] = instance.mLOD[i];
- }
+ for (S32 i = 0; i < 5; i++)
+ {
+ data.mModel[i] = instance.mLOD[i];
+ }
- //queue up models for hull generation
- LLModel* physics = NULL;
+ //queue up models for hull generation
+ LLModel* physics = NULL;
- if (data.mModel[LLModel::LOD_PHYSICS].notNull())
- {
- physics = data.mModel[LLModel::LOD_PHYSICS];
- }
- else if (data.mModel[LLModel::LOD_LOW].notNull())
- {
- physics = data.mModel[LLModel::LOD_LOW];
- }
- else if (data.mModel[LLModel::LOD_MEDIUM].notNull())
- {
- physics = data.mModel[LLModel::LOD_MEDIUM];
- }
- else
- {
- physics = data.mModel[LLModel::LOD_HIGH];
- }
+ if (data.mModel[LLModel::LOD_PHYSICS].notNull())
+ {
+ physics = data.mModel[LLModel::LOD_PHYSICS];
+ }
+ else if (data.mModel[LLModel::LOD_LOW].notNull())
+ {
+ physics = data.mModel[LLModel::LOD_LOW];
+ }
+ else if (data.mModel[LLModel::LOD_MEDIUM].notNull())
+ {
+ physics = data.mModel[LLModel::LOD_MEDIUM];
+ }
+ else
+ {
+ physics = data.mModel[LLModel::LOD_HIGH];
+ }
- llassert(physics != NULL);
+ llassert(physics != NULL);
- DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this);
- if(request->isValid())
- {
- gMeshRepo.mDecompThread->submitRequest(request);
- }
+ DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this);
+ if(request->isValid())
+ {
+ gMeshRepo.mDecompThread->submitRequest(request);
+ has_valid_requests = true ;
}
-
+ }
+
+ if(has_valid_requests)
+ {
while (!mPhysicsComplete)
{
apr_sleep(100);
}
+ }
}
void LLMeshUploadThread::doWholeModelUpload()
@@ -1688,6 +1701,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
{
LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
volume->copyVolumeFaces(data.mModel[i]);
+ volume->setMeshAssetLoaded(TRUE);
}
}
@@ -2141,11 +2155,6 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
if (volume)
{
- if (volume->getNumVolumeFaces() == 0 && !volume->isTetrahedron())
- {
- volume->makeTetrahedron();
- }
-
LLVolumeParams params = volume->getParams();
LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params);
@@ -2156,7 +2165,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
if (last_lod >= 0)
{
LLVolume* lod = group->refLOD(last_lod);
- if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
+ if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
{
group->derefLOD(lod);
return last_lod;
@@ -2168,7 +2177,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
for (S32 i = detail-1; i >= 0; --i)
{
LLVolume* lod = group->refLOD(i);
- if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
+ if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
{
group->derefLOD(lod);
return i;
@@ -2181,7 +2190,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
for (S32 i = detail+1; i < 4; ++i)
{
LLVolume* lod = group->refLOD(i);
- if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
+ if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
{
group->derefLOD(lod);
return i;
@@ -2432,7 +2441,6 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
if (volume->getNumVolumeFaces() <= 0)
{
llwarns << "Mesh loading returned empty volume." << llendl;
- volume->makeTetrahedron();
}
{ //update system volume
@@ -2440,6 +2448,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
if (sys_volume)
{
sys_volume->copyVolumeFaces(volume);
+ sys_volume->setMeshAssetLoaded(TRUE);
LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);
}
else
@@ -2496,7 +2505,7 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
return mThread->getActualMeshLOD(mesh_params, lod);
}
-const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj)
+const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj)
{
if (mesh_id.notNull())
{
@@ -2752,7 +2761,7 @@ void LLMeshRepository::uploadError(LLSD& args)
}
//static
-F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod)
+F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
{
F32 max_distance = 512.f;
@@ -2841,6 +2850,11 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32
triangles_low*low_area +
triangles_lowest*lowest_area;
+ if (unscaled_value)
+ {
+ *unscaled_value = weighted_avg;
+ }
+
return weighted_avg/gSavedSettings.getU32("MeshTriangleBudget")*15000.f;
}
@@ -3135,32 +3149,33 @@ void LLPhysicsDecomp::doDecompositionSingleHull()
llwarns << "Could not execute decomposition stage when attempting to create single hull." << llendl;
make_box(mCurRequest);
}
+ else
+ {
+ mMutex->lock();
+ mCurRequest->mHull.clear();
+ mCurRequest->mHull.resize(1);
+ mCurRequest->mHullMesh.clear();
+ mMutex->unlock();
- mMutex->lock();
- mCurRequest->mHull.clear();
- mCurRequest->mHull.resize(1);
- mCurRequest->mHullMesh.clear();
- mMutex->unlock();
-
- std::vector<LLVector3> p;
- LLCDHull hull;
+ std::vector<LLVector3> p;
+ LLCDHull hull;
- // if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code
- decomp->getSingleHull(&hull);
+ // if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code
+ decomp->getSingleHull(&hull);
- const F32* v = hull.mVertexBase;
+ const F32* v = hull.mVertexBase;
- for (S32 j = 0; j < hull.mNumVertices; ++j)
- {
- LLVector3 vert(v[0], v[1], v[2]);
- p.push_back(vert);
- v = (F32*) (((U8*) v) + hull.mVertexStrideBytes);
- }
+ for (S32 j = 0; j < hull.mNumVertices; ++j)
+ {
+ LLVector3 vert(v[0], v[1], v[2]);
+ p.push_back(vert);
+ v = (F32*) (((U8*) v) + hull.mVertexStrideBytes);
+ }
- mMutex->lock();
- mCurRequest->mHull[0] = p;
- mMutex->unlock();
-
+ mMutex->lock();
+ mCurRequest->mHull[0] = p;
+ mMutex->unlock();
+ }
#else
setMeshData(mesh, false);
@@ -3498,8 +3513,7 @@ void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp)
bool LLMeshRepository::meshUploadEnabled()
{
LLViewerRegion *region = gAgent.getRegion();
- if(gSavedSettings.getBOOL("MeshEnabled") &&
- LLViewerParcelMgr::getInstance()->allowAgentBuild() &&
+ if(gSavedSettings.getBOOL("MeshEnabled") &&
region)
{
return region->meshUploadEnabled();
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 35a7314cd5..31b84ea0d9 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -445,7 +445,7 @@ public:
static U32 sCacheBytesWritten;
static U32 sPeakKbps;
- static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1);
+ static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
LLMeshRepository();
@@ -464,7 +464,7 @@ public:
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
static S32 getActualMeshLOD(LLSD& header, S32 lod);
- const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj);
+ const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj);
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
void fetchPhysicsShape(const LLUUID& mesh_id);
bool hasPhysicsShape(const LLUUID& mesh_id);
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index c222bbb191..1f77e7a602 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -1112,7 +1112,16 @@ void LLPanelObject::getState( )
if (mCtrlSculptType)
{
- mCtrlSculptType->setCurrentByIndex(sculpt_stitching);
+ if (sculpt_stitching == LL_SCULPT_TYPE_NONE)
+ {
+ // since 'None' is no longer an option in the combo box
+ // use 'Plane' as an equivalent sculpt type
+ mCtrlSculptType->setSelectedByValue(LLSD(LL_SCULPT_TYPE_PLANE), true);
+ }
+ else
+ {
+ mCtrlSculptType->setSelectedByValue(LLSD(sculpt_stitching), true);
+ }
mCtrlSculptType->setEnabled(editable && !isMesh);
}
@@ -1749,7 +1758,7 @@ void LLPanelObject::sendSculpt()
U8 sculpt_type = 0;
if (mCtrlSculptType)
- sculpt_type |= mCtrlSculptType->getCurrentIndex();
+ sculpt_type |= mCtrlSculptType->getValue().asInteger();
bool enabled = sculpt_type != LL_SCULPT_TYPE_MESH;
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index bb87601d20..12eea7844d 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -351,7 +351,7 @@ void LLPanelVolume::getState( )
getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(is_flexible);
if (is_flexible || (volobjp && volobjp->canBeFlexible()))
{
- getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp);
+ getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh());
}
else
{
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 26b2b0f5c3..733902ad30 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6520,32 +6520,75 @@ U32 LLObjectSelection::getSelectedObjectTriangleCount()
return count;
}
-/*S32 LLObjectSelection::getSelectedObjectRenderCost()
+S32 LLObjectSelection::getSelectedObjectRenderCost()
{
S32 cost = 0;
LLVOVolume::texture_cost_t textures;
+ typedef std::set<LLUUID> uuid_list_t;
+ uuid_list_t computed_objects;
+
+ typedef std::list<LLPointer<LLViewerObject> > child_list_t;
+ typedef const child_list_t const_child_list_t;
+
+ // add render cost of complete linksets first, to get accurate texture counts
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)
+ if (object && object->isRootEdit())
{
- // add the cost of each individual texture in the linkset
- cost += iter->second;
+ cost += object->getRenderCost(textures);
+ computed_objects.insert(object->getID());
+
+ const_child_list_t children = object->getChildren();
+ for (const_child_list_t::const_iterator child_iter = children.begin();
+ child_iter != children.end();
+ ++child_iter)
+ {
+ LLViewerObject* child_obj = *child_iter;
+ LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
+ if (child)
+ {
+ cost += child->getRenderCost(textures);
+ computed_objects.insert(child->getID());
+ }
+ }
+
+ 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();
}
- textures.clear();
}
+
+ // add any partial linkset objects, texture cost may be slightly misleading
+ for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLVOVolume* object = (LLVOVolume*)node->getObject();
+
+ if (object && computed_objects.find(object->getID()) == computed_objects.end() )
+ {
+ cost += object->getRenderCost(textures);
+ computed_objects.insert(object->getID());
+ }
+ 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;
+ }
- return cost;
-}*/
+ textures.clear();
+ }
+ return cost;
+}
//-----------------------------------------------------------------------------
// getTECount()
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index fd17781a2e..6c2b71dd0a 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2763,6 +2763,115 @@ void renderUpdateType(LLDrawable* drawablep)
}
}
+void renderComplexityDisplay(LLDrawable* drawablep)
+{
+ LLViewerObject* vobj = drawablep->getVObj();
+ if (!vobj)
+ {
+ return;
+ }
+
+ LLVOVolume *voVol = dynamic_cast<LLVOVolume*>(vobj);
+
+ if (!voVol)
+ {
+ return;
+ }
+
+ if (!voVol->isRoot())
+ {
+ return;
+ }
+
+ LLVOVolume::texture_cost_t textures;
+ F32 cost = (F32) voVol->getRenderCost(textures);
+
+ // add any child volumes
+ LLViewerObject::const_child_list_t children = voVol->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter)
+ {
+ const LLViewerObject *child = *iter;
+ const LLVOVolume *child_volume = dynamic_cast<const LLVOVolume*>(child);
+ if (child_volume)
+ {
+ cost += child_volume->getRenderCost(textures);
+ }
+ }
+
+ // add texture cost
+ 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;
+ }
+
+ F32 cost_max = (F32) LLVOVolume::getRenderComplexityMax();
+
+
+
+ // allow user to set a static color scale
+ if (gSavedSettings.getS32("RenderComplexityStaticMax") > 0)
+ {
+ cost_max = gSavedSettings.getS32("RenderComplexityStaticMax");
+ }
+
+ F32 cost_ratio = cost / cost_max;
+
+ // cap cost ratio at 1.0f in case cost_max is at a low threshold
+ cost_ratio = cost_ratio > 1.0f ? 1.0f : cost_ratio;
+
+ LLGLEnable blend(GL_BLEND);
+
+ LLColor4 color;
+ const LLColor4 color_min = gSavedSettings.getColor4("RenderComplexityColorMin");
+ const LLColor4 color_mid = gSavedSettings.getColor4("RenderComplexityColorMid");
+ const LLColor4 color_max = gSavedSettings.getColor4("RenderComplexityColorMax");
+
+ if (cost_ratio < 0.5f)
+ {
+ color = color_min * (1 - cost_ratio * 2) + color_mid * (cost_ratio * 2);
+ }
+ else
+ {
+ color = color_mid * (1 - (cost_ratio - 0.5) * 2) + color_max * ((cost_ratio - 0.5) * 2);
+ }
+
+ LLSD color_val = color.getValue();
+
+ // don't highlight objects below the threshold
+ if (cost > gSavedSettings.getS32("RenderComplexityThreshold"))
+ {
+ glColor4f(color[0],color[1],color[2],0.5f);
+
+
+ S32 num_faces = drawablep->getNumFaces();
+ if (num_faces)
+ {
+ for (S32 i = 0; i < num_faces; ++i)
+ {
+ pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX);
+ }
+ }
+ LLViewerObject::const_child_list_t children = voVol->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter)
+ {
+ const LLViewerObject *child = *iter;
+ if (child)
+ {
+ num_faces = child->getNumFaces();
+ if (num_faces)
+ {
+ for (S32 i = 0; i < num_faces; ++i)
+ {
+ pushVerts(child->mDrawable->getFace(i), LLVertexBuffer::MAP_VERTEX);
+ }
+ }
+ }
+ }
+ }
+
+ voVol->setDebugText(llformat("%4.0f", cost));
+}
void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
{
@@ -3867,6 +3976,10 @@ public:
{
renderUpdateType(drawable);
}
+ if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY))
+ {
+ renderComplexityDisplay(drawable);
+ }
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get());
@@ -4115,7 +4228,8 @@ void LLSpatialPartition::renderDebug()
LLPipeline::RENDER_DEBUG_AVATAR_VOLUME |
LLPipeline::RENDER_DEBUG_AGENT_TARGET |
//LLPipeline::RENDER_DEBUG_BUILD_QUEUE |
- LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
+ LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY))
{
return;
}
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index b87ca1eaec..0f0b7d7e78 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -142,7 +142,6 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
LLPipeline::RENDER_TYPE_WATER,
LLPipeline::RENDER_TYPE_PASS_GRASS,
LLPipeline::RENDER_TYPE_HUD,
- LLPipeline::RENDER_TYPE_PARTICLES,
LLPipeline::RENDER_TYPE_CLOUDS,
LLPipeline::RENDER_TYPE_HUD_PARTICLES,
LLPipeline::END_RENDER_TYPES);
@@ -158,7 +157,6 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
LLPipeline::RENDER_TYPE_WATER,
LLPipeline::RENDER_TYPE_PASS_GRASS,
LLPipeline::RENDER_TYPE_HUD,
- LLPipeline::RENDER_TYPE_PARTICLES,
LLPipeline::RENDER_TYPE_CLOUDS,
LLPipeline::RENDER_TYPE_HUD_PARTICLES,
LLPipeline::END_RENDER_TYPES);
@@ -168,6 +166,11 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
return true;
}
+bool handleRenderAvatarComplexityLimitChanged(const LLSD& newvalue)
+{
+ return true;
+}
+
bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
{
LLWorld::getInstance()->updateWaterObjects();
@@ -404,7 +407,7 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue)
gPipeline.releaseGLBuffers();
gPipeline.createGLBuffers();
gPipeline.resetVertexBuffers();
- if (LLPipeline::sRenderDeferred && LLRenderTarget::sUseFBO)
+ if (LLPipeline::sRenderDeferred == (BOOL)LLRenderTarget::sUseFBO)
{
LLViewerShaderMgr::instance()->setShaders();
}
@@ -611,6 +614,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderAvatarMaxVisible")->getSignal()->connect(boost::bind(&handleAvatarMaxVisibleChanged, _2));
+ gSavedSettings.getControl("RenderAvatarComplexityLimit")->getSignal()->connect(boost::bind(&handleRenderAvatarComplexityLimitChanged, _2));
gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 4af5fdd9f3..8e2240981b 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -80,6 +80,7 @@
#include "llfloatermodelwizard.h"
#include "llfloaternamedesc.h"
#include "llfloaternotificationsconsole.h"
+#include "llfloaterobjectweights.h"
#include "llfloateropenobject.h"
#include "llfloaterpay.h"
#include "llfloaterperms.h"
@@ -228,6 +229,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
LLFloaterReg::add("notification_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNotificationWellWindow>);
+ LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterObjectWeights>);
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
LLFloaterPayUtil::registerFloater();
@@ -287,7 +289,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);
LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>);
- LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWebContent>);
+ LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWebContent>);
LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>);
LLFloaterWindowSizeUtil::registerFloater();
LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index db7bb002c1..d81e67bfe2 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -100,7 +100,6 @@
#include "lltrans.h"
#include "llsdutil.h"
#include "llmediaentry.h"
-#include "llaccountingquota.h"
//#define DEBUG_UPDATE_TYPE
@@ -630,6 +629,20 @@ void LLViewerObject::constructAndAddReturnable( std::vector<PotentialReturnableO
}
}
+bool LLViewerObject::crossesParcelBounds()
+{
+ std::vector<LLBBox> boxes;
+ boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+ }
+
+ return mRegionp && mRegionp->objectsCrossParcel(boxes);
+}
+
BOOL LLViewerObject::setParent(LLViewerObject* parent)
{
if(mParent != parent)
@@ -5787,9 +5800,3 @@ public:
LLHTTPRegistration<ObjectPhysicsProperties>
gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties");
-
-void LLViewerObject::updateQuota( const SelectionQuota& quota )
-{
- //update quotas
- mSelectionQuota = quota;
-}
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 1828a64917..53e951e483 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -43,7 +43,7 @@
#include "v3dmath.h"
#include "v3math.h"
#include "llvertexbuffer.h"
-#include "llaccountingquota.h"
+#include "llbbox.h"
#include "llbbox.h"
class LLAgent; // TODO: Get rid of this.
@@ -243,6 +243,10 @@ public:
void buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion );
void constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion );
+ // This method returns true if the object crosses
+ // any parcel bounds in the region.
+ bool crossesParcelBounds();
+
/*
// This method will scan through this object, and then query the
// selection manager to see if the local agent probably has the
@@ -655,9 +659,7 @@ protected:
void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
public:
- void updateQuota( const SelectionQuota& quota );
- const SelectionQuota& getQuota( void ) { return mSelectionQuota; }
-
+
private:
void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
void deleteTEImages(); // correctly deletes list of images
@@ -719,8 +721,6 @@ protected:
F32 mPhysicsCost;
F32 mLinksetPhysicsCost;
- SelectionQuota mSelectionQuota;
-
bool mCostStale;
mutable bool mPhysicsShapeUnknown;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 153a91e7d8..6912faa9ec 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -58,6 +58,7 @@
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerstatsrecorder.h"
+#include "llvovolume.h"
#include "llvoavatarself.h"
#include "lltoolmgr.h"
#include "lltoolpie.h"
@@ -993,6 +994,9 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
mNumSizeCulled = 0;
mNumVisCulled = 0;
+ // update max computed render cost
+ LLVOVolume::updateRenderComplexity();
+
// compute all sorts of time-based stats
// don't factor frames that were paused into the stats
if (! mWasPaused)
@@ -1443,15 +1447,6 @@ void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id)
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());
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 9d1b5cb56f..c5f2a2c1ee 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -36,7 +36,6 @@
// project includes
#include "llviewerobject.h"
-#include "llaccountingquota.h"
class LLCamera;
class LLNetMap;
@@ -102,8 +101,6 @@ public:
F32 restitution,
F32 gravity_multiplier);
- void updateQuota( const LLUUID& objectId, const SelectionQuota& costs );
-
void shiftObjects(const LLVector3 &offset);
void repartitionObjects();
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index eff16b6a6e..e619b89f9b 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -201,6 +201,65 @@ bool LLViewerParcelOverlay::encroachesOnUnowned(const std::vector<LLBBox>& boxes
return false;
}
+bool LLViewerParcelOverlay::encroachesOnNearbyParcel(const std::vector<LLBBox>& boxes) const
+{
+ // boxes are expected to already be axis aligned
+ for (U32 i = 0; i < boxes.size(); ++i)
+ {
+ LLVector3 min = boxes[i].getMinAgent();
+ LLVector3 max = boxes[i].getMaxAgent();
+
+ // If an object crosses region borders it crosses a parcel
+ if ( min.mV[VX] < 0
+ || min.mV[VY] < 0
+ || max.mV[VX] > REGION_WIDTH_METERS
+ || max.mV[VY] > REGION_WIDTH_METERS)
+ {
+ return true;
+ }
+
+ S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+ S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+ S32 bottom = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+ S32 top = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+
+ const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
+
+ for (S32 row = bottom; row <= top; row++)
+ {
+ for (S32 col = left; col <= right; col++)
+ {
+ // This is not the rightmost column
+ if (col < GRIDS_PER_EDGE-1)
+ {
+ U8 east_overlay = mOwnership[row*GRIDS_PER_EDGE+col+1];
+ // If the column to the east of the current one marks
+ // the other parcel's west edge and the box extends
+ // to the west it crosses the parcel border.
+ if ((east_overlay & PARCEL_WEST_LINE) && col < right)
+ {
+ return true;
+ }
+ }
+
+ // This is not the topmost column
+ if (row < GRIDS_PER_EDGE-1)
+ {
+ U8 north_overlay = mOwnership[(row+1)*GRIDS_PER_EDGE+col];
+ // If the row to the north of the current one marks
+ // the other parcel's south edge and the box extends
+ // to the south it crosses the parcel border.
+ if ((north_overlay & PARCEL_SOUTH_LINE) && row < top)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 3c6794e7d0..7445d5bf1d 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -61,6 +61,7 @@ public:
// bounding boxes which isn't perfect, but is close
bool encroachesOwned(const std::vector<LLBBox>& boxes) const;
bool encroachesOnUnowned(const std::vector<LLBBox>& boxes) const;
+ bool encroachesOnNearbyParcel(const std::vector<LLBBox>& boxes) const;
BOOL isSoundLocal(const LLVector3& pos) const;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 17f908d73f..ed943964f9 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1487,11 +1487,8 @@ void LLViewerRegion::unpackRegionHandshake()
msg->sendReliable(host);
}
-
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
{
- capabilityNames.append("AccountingParcel");
- capabilityNames.append("AccountingSelection");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
capabilityNames.append("ChatSessionRequest");
@@ -1531,6 +1528,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("ProvisionVoiceAccountRequest");
capabilityNames.append("RemoteParcelRequest");
capabilityNames.append("RequestTextureDownload");
+ capabilityNames.append("ResourceCostSelected");
capabilityNames.append("SearchStatRequest");
capabilityNames.append("SearchStatTracking");
capabilityNames.append("SendPostcard");
@@ -1556,10 +1554,6 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("ViewerMetrics");
capabilityNames.append("ViewerStartAuction");
capabilityNames.append("ViewerStats");
- //prep# Finalize these!!!!!!!!!
- //capabilityNames.append("AccountingVO");
- capabilityNames.append("AccountingParcel");
- capabilityNames.append("AccountingRegion");
// Please add new capabilities alphabetically to reduce
// merge conflicts.
@@ -1790,6 +1784,11 @@ bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes
return result;
}
+bool LLViewerRegion::objectsCrossParcel(const std::vector<LLBBox>& boxes) const
+{
+ return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes);
+}
+
void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
{
mImpl->mLandp->getNeighboringRegions( uniqueRegions );
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index ef1a6d285c..c483c6ef52 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -322,6 +322,7 @@ public:
bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;
bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const;
+ bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const;
void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 7c6a815def..e457cc3e70 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2803,7 +2803,10 @@ void LLVOAvatar::idleUpdateLoadingEffect()
LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK |
LLPartData::LL_PART_TARGET_POS_MASK );
- setParticleSource(particle_parameters, getID());
+ if (!isTooComplex()) // do not generate particles for overly-complex avatars
+ {
+ setParticleSource(particle_parameters, getID());
+ }
}
}
}
@@ -6389,6 +6392,11 @@ BOOL LLVOAvatar::getIsCloud()
{
return TRUE;
}
+
+ if (isTooComplex())
+ {
+ return TRUE;
+ }
return FALSE;
}
@@ -6483,6 +6491,16 @@ BOOL LLVOAvatar::isFullyLoaded() const
return mFullyLoaded;
}
+bool LLVOAvatar::isTooComplex() const
+{
+ if (gSavedSettings.getS32("RenderAvatarComplexityLimit") > 0 && mVisualComplexity >= gSavedSettings.getS32("RenderAvatarComplexityLimit"))
+ {
+ return true;
+ }
+
+ return false;
+}
+
//-----------------------------------------------------------------------------
// findMotion()
@@ -8315,7 +8333,7 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d
void LLVOAvatar::idleUpdateRenderCost()
{
- static const U32 ARC_BODY_PART_COST = 20;
+ static const U32 ARC_BODY_PART_COST = 200;
static const U32 ARC_LIMIT = 2048;
static std::set<LLUUID> all_textures;
@@ -8326,7 +8344,7 @@ void LLVOAvatar::idleUpdateRenderCost()
}
U32 cost = 0;
- std::set<LLUUID> textures;
+ LLVOVolume::texture_cost_t textures;
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
@@ -8341,6 +8359,7 @@ void LLVOAvatar::idleUpdateRenderCost()
}
}
+
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -8353,6 +8372,7 @@ void LLVOAvatar::idleUpdateRenderCost()
const LLViewerObject* attached_object = (*attachment_iter);
if (attached_object && !attached_object->isHUDAttachment())
{
+ textures.clear();
const LLDrawable* drawable = attached_object->mDrawable;
if (drawable)
{
@@ -8360,6 +8380,25 @@ void LLVOAvatar::idleUpdateRenderCost()
if (volume)
{
cost += volume->getRenderCost(textures);
+
+ const_child_list_t children = volume->getChildren();
+ for (const_child_list_t::const_iterator child_iter = children.begin();
+ child_iter != children.end();
+ ++child_iter)
+ {
+ LLViewerObject* child_obj = *child_iter;
+ LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
+ if (child)
+ {
+ cost += child->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;
+ }
}
}
}
@@ -8367,15 +8406,17 @@ void LLVOAvatar::idleUpdateRenderCost()
}
+
+
// Diagnostic output to identify all avatar-related textures.
// Does not affect rendering cost calculation.
// Could be wrapped in a debug option if output becomes problematic.
if (isSelf())
{
// print any attachment textures we didn't already know about.
- for (std::set<LLUUID>::iterator it = textures.begin(); it != textures.end(); ++it)
+ for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
{
- LLUUID image_id = *it;
+ LLUUID image_id = it->first;
if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
continue;
if (all_textures.find(image_id) == all_textures.end())
@@ -8407,9 +8448,8 @@ void LLVOAvatar::idleUpdateRenderCost()
}
}
- cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST;
-
setDebugText(llformat("%d", cost));
+ mVisualComplexity = cost;
F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f);
F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f);
mText->setColor(LLColor4(red,green,0,1));
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 03c0498a2a..e53b8e3f4b 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -273,6 +273,7 @@ public:
//--------------------------------------------------------------------
public:
BOOL isFullyLoaded() const;
+ bool isTooComplex() const;
bool visualParamWeightsAreDefault();
protected:
virtual BOOL getIsCloud();
@@ -285,6 +286,7 @@ private:
BOOL mPreviousFullyLoaded;
BOOL mFullyLoadedInitialized;
S32 mFullyLoadedFrameCounter;
+ S32 mVisualComplexity;
LLFrameTimer mFullyLoadedTimer;
LLFrameTimer mRuthTimer;
protected:
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 528c7acbc8..380d63c77b 100644..100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -90,6 +90,8 @@ F32 LLVOVolume::sLODFactor = 1.f;
F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
F32 LLVOVolume::sDistanceFactor = 1.0f;
S32 LLVOVolume::sNumLODChanges = 0;
+S32 LLVOVolume::mRenderComplexity_last = 0;
+S32 LLVOVolume::mRenderComplexity_current = 0;
LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL;
LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL;
@@ -367,6 +369,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
//
// Unpack texture entry data
//
+
S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
if (result & teDirtyBits)
{
@@ -969,18 +972,14 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
S32 lod = mLOD;
BOOL is404 = FALSE;
-
+
if (isSculpted())
{
// if it's a mesh
if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
{ //meshes might not have all LODs, get the force detail to best existing LOD
-
LLUUID mesh_id = volume_params.getSculptID();
- //profile and path params don't matter for meshes
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
-
lod = gMeshRepo.getActualMeshLOD(volume_params, lod);
if (lod == -1)
{
@@ -1036,14 +1035,13 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
updateSculptTexture();
-
if (isSculpted())
{
updateSculptTexture();
// if it's a mesh
if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
{
- if (getVolume()->getNumVolumeFaces() == 0 || getVolume()->isTetrahedron())
+ if (!getVolume()->isMeshAssetLoaded())
{
//load request not yet issued, request pipeline load this mesh
LLUUID asset_id = volume_params.getSculptID();
@@ -1662,11 +1660,16 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
compiled = TRUE;
sNumLODChanges += new_num_faces ;
+ if((S32)getNumTEs() != getVolume()->getNumFaces())
+ {
+ setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces.
+ }
+
drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles()
{
LLFastTimer t(FTM_GEN_TRIANGLES);
- if (new_num_faces != old_num_faces)
+ if (new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs())
{
regenFaces();
}
@@ -2971,24 +2974,38 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
// total cost is returned value + 5 * size of the resulting set.
// Cannot include cost of textures, as they may be re-used in linked
// children, and cost should only be increased for unique textures -Nyx
-U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const
+U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
{
- // base cost of each prim should be 10 points
- static const U32 ARC_PRIM_COST = 10;
+ // Get access to params we'll need at various points.
+ // Skip if this is object doesn't have a volume (e.g. is an avatar).
+ BOOL has_volume = (getVolume() != NULL);
+ LLVolumeParams volume_params;
+ LLPathParams path_params;
+ LLProfileParams profile_params;
+
+ U32 num_triangles = 0;
+
// per-prim costs
- static const U32 ARC_INVISI_COST = 1;
- static const U32 ARC_SHINY_COST = 1;
- static const U32 ARC_GLOW_COST = 1;
- static const U32 ARC_FLEXI_COST = 8;
- static const U32 ARC_PARTICLE_COST = 16;
- static const U32 ARC_BUMP_COST = 4;
+ static const U32 ARC_PARTICLE_COST = 1; // determined experimentally
+ static const U32 ARC_PARTICLE_MAX = 2048; // default values
+ static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested
+ static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims
+ static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face
+
- // per-face costs
- static const U32 ARC_PLANAR_COST = 1;
- static const U32 ARC_ANIM_TEX_COST = 4;
- static const U32 ARC_ALPHA_COST = 4;
+ // per-prim multipliers
+ static const F32 ARC_GLOW_MULT = 1.5f; // tested based on performance
+ static const F32 ARC_BUMP_MULT = 1.25f; // tested based on performance
+ static const F32 ARC_FLEXI_MULT = 5; // tested based on performance
+ static const F32 ARC_SHINY_MULT = 1.6f; // tested based on performance
+ static const F32 ARC_INVISI_COST = 1.2f; // tested based on performance
+ static const F32 ARC_WEIGHTED_MESH = 1.2f; // tested based on performance
- U32 shame = ARC_PRIM_COST;
+ static const F32 ARC_PLANAR_COST = 1.0f; // tested based on performance to have negligible impact
+ static const F32 ARC_ANIM_TEX_COST = 4.f; // tested based on performance
+ static const F32 ARC_ALPHA_COST = 4.f; // 4x max - based on performance
+
+ F32 shame = 0;
U32 invisi = 0;
U32 shiny = 0;
@@ -2997,9 +3014,72 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const
U32 flexi = 0;
U32 animtex = 0;
U32 particles = 0;
- U32 scale = 0;
U32 bump = 0;
U32 planar = 0;
+ U32 weighted_mesh = 0;
+ U32 produces_light = 0;
+ U32 media_faces = 0;
+
+ const LLDrawable* drawablep = mDrawable;
+ U32 num_faces = drawablep->getNumFaces();
+
+ if (has_volume)
+ {
+ volume_params = getVolume()->getParams();
+ path_params = volume_params.getPathParams();
+ profile_params = volume_params.getProfileParams();
+
+ F32 weighted_triangles = -1.0;
+ getStreamingCost(NULL, NULL, &weighted_triangles);
+
+ if (weighted_triangles > 0.0)
+ {
+ num_triangles = (U32)(weighted_triangles);
+ }
+ }
+
+ if (num_triangles == 0)
+ {
+ num_triangles = 4;
+ }
+
+ if (isSculpted())
+ {
+ if (isMesh())
+ {
+ // base cost is dependent on mesh complexity
+ // note that 3 is the highest LOD as of the time of this coding.
+ S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(),3);
+ if ( size > 0)
+ {
+ if (gMeshRepo.getSkinInfo(volume_params.getSculptID(), this))
+ {
+ // weighted attachment - 1 point for every 3 bytes
+ weighted_mesh = 1;
+ }
+
+ }
+ else
+ {
+ // something went wrong - user should know their content isn't render-free
+ return 0;
+ }
+ }
+ else
+ {
+ const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLUUID sculpt_id = sculpt_params->getSculptTexture();
+ if (textures.find(sculpt_id) == textures.end())
+ {
+ LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(sculpt_id);
+ if (texture)
+ {
+ S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (texture->getFullHeight() / 128.f + texture->getFullWidth() / 128.f));
+ textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost));
+ }
+ }
+ }
+ }
if (isFlexible())
{
@@ -3010,19 +3090,12 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const
particles = 1;
}
- const LLVector3& sc = getScale();
- scale += (U32) sc.mV[0] + (U32) sc.mV[1] + (U32) sc.mV[2];
-
- const LLDrawable* drawablep = mDrawable;
-
- if (isSculpted())
+ if (getIsLight())
{
- const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- LLUUID sculpt_id = sculpt_params->getSculptTexture();
- textures.insert(sculpt_id);
+ produces_light = 1;
}
- for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
+ for (S32 i = 0; i < num_faces; ++i)
{
const LLFace* face = drawablep->getFace(i);
const LLTextureEntry* te = face->getTextureEntry();
@@ -3030,77 +3103,137 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const
if (img)
{
- textures.insert(img->getID());
+ if (textures.find(img->getID()) == textures.end())
+ {
+ S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
+ textures.insert(texture_cost_t::value_type(img->getID(), texture_cost));
+ }
}
if (face->getPoolType() == LLDrawPool::POOL_ALPHA)
{
- alpha++;
+ alpha = 1;
}
else if (img && img->getPrimaryFormat() == GL_ALPHA)
{
invisi = 1;
}
+ if (face->hasMedia())
+ {
+ media_faces++;
+ }
if (te)
{
if (te->getBumpmap())
{
+ // bump is a multiplier, don't add per-face
bump = 1;
}
if (te->getShiny())
{
+ // shiny is a multiplier, don't add per-face
shiny = 1;
}
if (te->getGlow() > 0.f)
{
+ // glow is a multiplier, don't add per-face
glow = 1;
}
if (face->mTextureMatrix != NULL)
{
- animtex++;
+ animtex = 1;
}
if (te->getTexGen())
{
- planar++;
+ planar = 1;
}
}
}
+ // shame currently has the "base" cost of 1 point per 15 triangles, min 2.
+ shame = num_triangles * 5.f;
+ shame = shame < 2.f ? 2.f : shame;
- shame += invisi * ARC_INVISI_COST;
- shame += shiny * ARC_SHINY_COST;
- shame += glow * ARC_GLOW_COST;
- shame += alpha * ARC_ALPHA_COST;
- shame += flexi * ARC_FLEXI_COST;
- shame += animtex * ARC_ANIM_TEX_COST;
- shame += particles * ARC_PARTICLE_COST;
- shame += bump * ARC_BUMP_COST;
- shame += planar * ARC_PLANAR_COST;
- shame += scale;
+ // multiply by per-face modifiers
+ if (planar)
+ {
+ shame *= planar * ARC_PLANAR_COST;
+ }
- LLViewerObject::const_child_list_t& child_list = getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end();
- ++iter)
+ if (animtex)
{
- const LLViewerObject* child_objectp = *iter;
- const LLDrawable* child_drawablep = child_objectp->mDrawable;
- if (child_drawablep)
- {
- const LLVOVolume* child_volumep = child_drawablep->getVOVolume();
- if (child_volumep)
- {
- shame += child_volumep->getRenderCost(textures);
- }
- }
+ shame *= animtex * ARC_ANIM_TEX_COST;
}
- return shame;
+ if (alpha)
+ {
+ shame *= alpha * ARC_ALPHA_COST;
+ }
+
+ if(invisi)
+ {
+ shame *= invisi * ARC_INVISI_COST;
+ }
+
+ if (glow)
+ {
+ shame *= glow * ARC_GLOW_MULT;
+ }
+
+ if (bump)
+ {
+ shame *= bump * ARC_BUMP_MULT;
+ }
+ if (shiny)
+ {
+ shame *= shiny * ARC_SHINY_MULT;
+ }
+
+
+ // multiply shame by multipliers
+ if (weighted_mesh)
+ {
+ shame *= weighted_mesh * ARC_WEIGHTED_MESH;
+ }
+
+ if (flexi)
+ {
+ shame *= flexi * ARC_FLEXI_MULT;
+ }
+
+
+ // add additional costs
+ if (particles)
+ {
+ const LLPartSysData *part_sys_data = &(mPartSourcep->mPartSysData);
+ const LLPartData *part_data = &(part_sys_data->mPartData);
+ U32 num_particles = (U32)(part_sys_data->mBurstPartCount * llceil( part_data->mMaxAge / part_sys_data->mBurstRate));
+ num_particles = num_particles > ARC_PARTICLE_MAX ? ARC_PARTICLE_MAX : num_particles;
+ F32 part_size = (llmax(part_data->mStartScale[0], part_data->mEndScale[0]) + llmax(part_data->mStartScale[1], part_data->mEndScale[1])) / 2.f;
+ shame += num_particles * part_size * ARC_PARTICLE_COST;
+ }
+
+ if (produces_light)
+ {
+ shame += ARC_LIGHT_COST;
+ }
+
+ if (media_faces)
+ {
+ shame += media_faces * ARC_MEDIA_FACE_COST;
+ }
+
+ if (shame > mRenderComplexity_current)
+ {
+ mRenderComplexity_current = (S32)shame;
+ }
+
+ return (U32)shame;
}
-F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
+F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_value) const
{
F32 radius = getScale().length()*0.5f;
@@ -3108,7 +3241,7 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
{
LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
- return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD);
+ return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD, unscaled_value);
}
else
{
@@ -3122,11 +3255,18 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
header["medium_lod"]["size"] = counts[2] * 10;
header["high_lod"]["size"] = counts[3] * 10;
- return LLMeshRepository::getStreamingCost(header, radius);
+ return LLMeshRepository::getStreamingCost(header, radius, NULL, NULL, -1, unscaled_value);
}
}
-U32 LLVOVolume::getTriangleCount()
+//static
+void LLVOVolume::updateRenderComplexity()
+{
+ mRenderComplexity_last = mRenderComplexity_current;
+ mRenderComplexity_current = 0;
+}
+
+U32 LLVOVolume::getTriangleCount() const
{
U32 count = 0;
LLVolume* volume = getVolume();
@@ -3153,7 +3293,7 @@ U32 LLVOVolume::getHighLODTriangleCount()
else if (isMesh())
{
LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
- if (ref->isTetrahedron() || ref->getNumVolumeFaces() == 0)
+ if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0)
{
gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH);
}
@@ -3439,7 +3579,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
bool special_cursor = specialHoverCursor();
for (S32 i = start_face; i < end_face; ++i)
{
- if (!special_cursor && !pick_transparent && getTE(i)->getColor().mV[3] == 0.f)
+ if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f)
{ //don't attempt to pick completely transparent faces unless
//pick_transparent is true
continue;
@@ -3995,7 +4135,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLVOVolume* vobj = drawablep->getVOVolume();
- if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled()))
+ if (vobj->isMesh() &&
+ (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
{
continue;
}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 13565cb27c..b6347526ee 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -129,9 +129,11 @@ public:
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
/*virtual*/ const LLMatrix4 getRenderMatrix() const;
- U32 getRenderCost(std::set<LLUUID> &textures) const;
- /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL);
- /*virtual*/ U32 getTriangleCount();
+ typedef std::map<LLUUID, S32> texture_cost_t;
+ U32 getRenderCost(texture_cost_t &textures) const;
+ /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL, F32* unscaled_value = NULL) const;
+
+ /*virtual*/ U32 getTriangleCount() const;
/*virtual*/ U32 getHighLODTriangleCount();
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
@@ -320,11 +322,19 @@ protected:
LLFace* addFace(S32 face_index);
void updateTEData();
+ // stats tracking for render complexity
+ static S32 mRenderComplexity_last;
+ static S32 mRenderComplexity_current;
+
void requestMediaDataUpdate(bool isNew);
void cleanUpMediaImpls();
void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
void removeMediaImpl(S32 texture_index) ;
public:
+
+ static S32 getRenderComplexityMax() {return mRenderComplexity_last;}
+ static void updateRenderComplexity();
+
LLViewerTextureAnim *mTextureAnimp;
U8 mTexAnimMode;
private:
@@ -359,8 +369,6 @@ public:
static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
- static const U32 ARC_TEXTURE_COST = 5;
-
protected:
static S32 sNumLODChanges;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 3f0640221e..27ee2745b5 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -461,6 +461,7 @@ public:
RENDER_DEBUG_PHYSICS_SHAPES = 0x1000000,
RENDER_DEBUG_NORMALS = 0x2000000,
RENDER_DEBUG_LOD_INFO = 0x4000000,
+ RENDER_DEBUG_RENDER_COMPLEXITY = 0x8000000
};
public:
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index d19e56e9a0..b5cc949ebf 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -90,6 +90,9 @@
name="LtYellow"
value="1 1 .79 1" />
<color
+ name="DrYellow"
+ value="1 0.86 0 1" />
+ <color
name="LtOrange"
value="1 .85 .73 1" />
<color
@@ -517,6 +520,9 @@
name="MenuPopupBgColor"
reference="DkGray2" />
<color
+ name="ModelUploaderLabels"
+ value="1 0.6 0 1" />
+ <color
name="MultiSliderDisabledThumbColor"
reference="Black" />
<color
diff --git a/indra/newview/skins/default/textures/green_checkmark.png b/indra/newview/skins/default/textures/green_checkmark.png
new file mode 100644
index 0000000000..d2a5b348dc
--- /dev/null
+++ b/indra/newview/skins/default/textures/green_checkmark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/red_x.png b/indra/newview/skins/default/textures/red_x.png
new file mode 100644
index 0000000000..a61202f09b
--- /dev/null
+++ b/indra/newview/skins/default/textures/red_x.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 4d83ec2902..9fc2479bb1 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -283,9 +283,9 @@ with the same filename but different name
<texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" />
- <texture name="ModelImport_Status_Good" file_name="lag_status_good.tga" preload="false"/>
+ <texture name="ModelImport_Status_Good" file_name="green_checkmark.png" preload="false"/>
<texture name="ModelImport_Status_Warning" file_name="lag_status_warning.tga" preload="false"/>
- <texture name="ModelImport_Status_Error" file_name="lag_status_critical.tga" preload="false"/>
+ <texture name="ModelImport_Status_Error" file_name="red_x.png" preload="false"/>
<texture name="MouseLook_View_Off" file_name="bottomtray/MouseLook_view_off.png" preload="false" />
<texture name="MouseLook_View_On" file_name="bottomtray/MouseLook_view_on.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 07cb4c12f5..e5dcc9bcb5 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -834,7 +834,7 @@
name="Simulator primitive usage:"
top_pad="4"
width="364">
- Primitive usage:
+ Region capacity:
</text>
<text
type="string"
@@ -858,7 +858,7 @@
name="Primitives parcel supports:"
top="44"
width="152">
- Prims parcel supports:
+ Parcel land capacity:
</text>
<text
type="string"
@@ -882,7 +882,7 @@
name="Primitives on parcel:"
top="64"
width="152">
- Prims on parcel:
+ Parcel land impact:
</text>
<text
type="string"
@@ -2179,4 +2179,4 @@ Only large parcels can be listed in search.
</panel>
</panel>
</tab_container>
-</floater> \ No newline at end of file
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml
index afb7917043..c247a12e7a 100644
--- a/indra/newview/skins/default/xui/en/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/en/floater_build_options.xml
@@ -37,7 +37,7 @@
layout="topleft"
left="10"
tool_tip="Grid opacity"
- name="grid_mode_label"
+ name="grid_opacity_label"
top_pad="30"
width="123">
Mode
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index 1d4a1d4827..2eea286c8b 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater can_close="true" can_drag_on_left="false" can_minimize="false"
- can_resize="true" height="550" min_height="550" min_width="620"
- name="Model Preview" title="Upload Model" width="620"
+ can_resize="false" height="480" min_height="480" min_width="940"
+ name="Model Preview" title="Upload Model" width="940"
help_topic="upload_model" >
- <string name="status_idle">Idle</string>
- <string name="status_parse_error">Dae parsing issue - see log for details.</string>
+ <string name="status_idle"></string>
+ <string name="status_parse_error">Error: Dae parsing issue - see log for details.</string>
<string name="status_reading_file">Loading...</string>
<string name="status_generating_meshes">Generating Meshes...</string>
<string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string>
@@ -21,615 +21,1409 @@
<string name="mesh_status_mesh_mismatch">Levels of detail have a different number of mesh instances.</string>
<string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string>
<string name="mesh_status_missing_lod">Missing required level of detail.</string>
+ <string name="mesh_status_invalid_material_list">LOD materials are not a subset of reference model.</string>
<string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
<string name="decomposing">Analyzing...</string>
<string name="simplifying">Simplifying...</string>
<string name="tbd">TBD</string>
-
-
- <text left="15" bottom="25" follows="top|left" height="15" name="name_label">
- Name:
- </text>
- <line_editor bottom_delta="20" follows="top|left|right" height="19" max_length_bytes="64"
- name="description_form" prevalidate_callback="ascii" width="290" />
-
- <text bottom_delta="20" left="15" follows="left|top" height="15" name="lod_label">
- Preview:
- </text>
- <combo_box bottom_delta="20" follows="left|top" height="18"
- name="preview_lod_combo" width="240" tool_tip="LOD to view in preview render">
- <combo_item name="high">
- Level of Detail: High
- </combo_item>
- <combo_item name="medium">
- Level of Detail: Medium
- </combo_item>
- <combo_item name="low">
- Level of Detail: Low
- </combo_item>
- <combo_item name="lowest">
- Level of Detail: Lowest
- </combo_item>
- </combo_box>
-
- <menu_button follows="top|left"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left_pad="5"
- name="options_gear_btn"
- width="31"
- height="25"/>
- <!-- Placeholder panel for 3D preview render -->
- <panel
- name="preview_panel"
- left="15"
- bevel_style="none"
- border_style="line"
- border="true"
- width="290"
- height="290"
- follows="all"/>
-
- <text
- font="SansSerif"
- bottom_delta="15"
- left_delta="0"
- name="warning_title"
- text_color="Yellow"
- visible="false">
- WARNING:
- </text>
- <text
- text_color="White"
- height="40"
- width="290"
- top_delta="15"
- left_delta="0"
- name="warning_message"
- parse_urls="true"
- wrap="true"
- visible="false">
- You will not be able to complete the final upload of this model to the Second Life servers. [[VURL] Find out how] to get enabled for mesh model uploads.</text>
-
- <text
- height="65"
- top_delta="45"
- left_delta="0"
- name="weights_text"
- width="80"
- word_wrap="true"
- >
-Download:
-Physics:
-Server:
-
-Prim equivs:
- </text>
-
- <text
- height="65"
- top_delta="0"
- left_delta="80"
- name="weights"
- width="70"
- word_wrap="true"
- >
-[ST]
-[PH]
-[SIM]
-
-[EQ]
- </text>
-
-<!--
- <text
- height="65"
- top_delta="0"
- left_delta="70"
- name="price_breakdown_text"
- width="80"
- word_wrap="true"
- >
-Streaming:
-Physics:
-Instances:
-Textures:
-Model:
- </text>
-
- <text
- height="65"
- top_delta="0"
- left_delta="80"
- name="price_breakdown"
- width="65"
- word_wrap="true"
- >
-L$ [STREAMING]
-L$ [PHYSICS]
-L$ [INSTANCES]
-L$ [TEXTURES]
-L$ [MODEL]
- </text>
- -->
- <tab_container
- follows="right|top|bottom"
- top="15"
- left="310"
- height="470"
- width="300"
- name="import_tab"
- border="true"
- tab_position="top">
-
- <!-- LOD PANEL -->
+<panel
+ follows="top|left"
+ height="455"
+ layout="topleft"
+ left="3"
+ name="left_panel"
+ top_pad="10"
+ width="630">
<panel
- border="true"
- label="Level of Detail"
- name="lod_panel"
- help_topic="upload_model_lod">
-
- <text left="10" width="240" bottom="20" height="15" follows="left|top" name="lod_table_header">
- Select Level of Detail:
- </text>
-
- <text valign="center" halign="center" bg_visible="true" bottom_delta="16" left="75" width="65" height="18" follows="left|top" value="Triangles"/>
- <text valign="center" halign="center" bg_visible="true" left_pad="0" width="65" height="18" follows="left|top" value="Vertices"/>
- <text valign="center" halign="center" left_pad="0" width="65" bg_visible="true" height="18" follows="left|top" value="Status"/>
-
- <text valign="center" halign="center" bg_visible="true" name="high_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="High"/>
- <text valign="center" halign="center" bg_visible="true" name="high_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="high_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="high_status" left_pad="0" width="65" height="18" follows="left|top" value=""/>
- <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_high" left_delta="20" top_delta="0" />
-
- <text valign="center" halign="center" bg_visible="true" name="medium_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Medium"/>
- <text valign="center" halign="center" bg_visible="true" name="medium_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="medium_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="medium_status" left_pad="0" width="65" height="18" follows="left|top" value=""/>
- <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_medium" left_delta="20" top_delta="0" />
-
- <text valign="center" halign="center" bg_visible="true" name="low_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Low"/>
- <text valign="center" halign="center" bg_visible="true" name="low_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="low_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="low_status" left_pad="0" width="65" height="18" follows="left|top" value=""/>
- <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_low" left_delta="20" top_delta="0" />
-
- <text valign="center" halign="center" bg_visible="true" name="lowest_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Lowest"/>
- <text valign="center" halign="center" bg_visible="true" name="lowest_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="lowest_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="lowest_status" left_pad="0" width="65" height="18" follows="left|top" value=""/>
- <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_lowest" left_delta="20" top_delta="0" />
-
- <text left="10" width="240" height="15" top_pad="15" follows="left|top" name="lod_table_footer">
- Level of Detail: [DETAIL]
- </text>
-
- <icon height="16" width="16" left="20" follows="left|top" name="lod_status_message_icon"/>
- <text left_pad="5" width="200" height="28" follows="left|top" top_pad="-15" wrap="true" name="lod_status_message_text"/>
-
- <text top_pad="-3" left="10" height="15" follows="left|top">
- Mesh
- </text>
-
- <radio_group follows="top|left" height="210" left="30" name="lod_file_or_limit" width="240" value="lod_from_file">
- <radio_item bottom="195" label="Load from file" name="lod_from_file"/>
- <radio_item bottom="150" label="Auto generate" name="lod_auto_generate"/>
- <radio_item bottom="0" label="None" name="lod_none"/>
- </radio_group>
-
- <line_editor follows="left|top" bottom_delta="-170" width="140" left="45" value="" name="lod_file" height="20"/>
- <button bottom_delta="3" name="lod_browse" label="Browse..." left_pad="5" follows="left|top" width="70" height="25"/>
-
- <combo_box follows="top|left" name="lod_mode" top_pad="22" width="100" left="45" height="20">
- <combo_item name="triangle_limit">
- Triangle Limit
- </combo_item>
- <combo_item name="error_threshold">
- Error Threshold
- </combo_item>
- </combo_box>
- <spinner follows="top|left" name="lod_triangle_limit" increment="10" left_pad="5" height="20" width="100" decimal_digits="0" enabled="true"/>
- <spinner left_delta="0" bottom_delta="0" increment="0.01" follows="top|left" name="lod_error_threshold" min_val="0" max_val="100" height="20" width="100" decimal_digits="3" visible="false" enabled="true"/>
-
- <text follows="top|left" name="build_operator_text" left="45" top_pad="10" width="100" height="15">
- Build Operator:
- </text>
- <text follows="top|left" name="queue_mode_text" left_pad="5" width="100" height="15">
- Queue Mode:
- </text>
- <combo_box follows="top|left" name="build_operator" top_pad="5" left="45" width="100" height="20">
- <combo_item name="edge_collapse">
- Edge Collapse
- </combo_item>
- <combo_item name="half_edge_collapse">
- Half Edge Collapse
- </combo_item>
- </combo_box>
-
- <combo_box follows="top|left" name="queue_mode" left_pad="5" width="100" height="20">
- <combo_item name="greedy">
- Greedy
- </combo_item>
- <combo_item name="lazy">
- Lazy
- </combo_item>
- <combo_item name="independent">
- Independent
- </combo_item>
- </combo_box>
-
- <text top_pad="10" name="border_mode_text" left="45" follows="left|top" width="100" height="15">
- Border Mode:
- </text>
-
- <text left_pad="5" name="share_tolderance_text" follows="left|top" width="100" height="15">
- Share Tolerance:
- </text>
-
- <combo_box follows="left|top" left="45" height="20" name="border_mode" width="100">
- <combo_item name="border_unlock">
- Unlock
- </combo_item>
- <combo_item name="border_lock">
- Lock
- </combo_item>
- </combo_box>
- <spinner follows="left|top" name="share_tolerance" left_pad="5" width="100" decimal_digits="5" initial_value="0.00001" height="20"/>
-
- <text left="10" top_pad="35" follows="top|left" width="240" height="15">
- Generate Normals
- </text>
- <text left="35" top_pad="5" follows="top|left" width="100" height="15" name="crease_label">
- Crease Angle:
- </text>
- <spinner follows="top|left" left_pad="5" min_val="0" max_val="180" value="75" width="60" height="20" name="crease_angle"/>
- </panel>
-
- <!-- PANEL -->
- <panel
- border="true"
- label="Physics"
- name="physics_panel"
- help_topic="upload_model_physics">
-
- <!-- PHYSICS GEOMETRY-->
- <panel
- follows="top|left"
- name="physics geometry"
- left="0"
- top="0"
- width="300"
- height="65"
- visible="true"
- border="true"
- bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
-
- <radio_group follows="top|left" top="10" width="240" height="40" name="physics_load_radio" value="physics_load_from_file">
- <radio_item bottom="0" name="physics_load_from_file" label="File:"/>
- <radio_item bottom="23" name="physics_use_lod" label="Use Level of Detail:"/>
- </radio_group>
-
- <combo_box left="180" top="10" follows="left|top" height="18"
- name="physics_lod_combo" width="110" tool_tip="LOD to use for physics shape">
- <combo_item name="physics_lowest">
- Lowest
- </combo_item>
- <combo_item name="physics_low">
- Low
- </combo_item>
- <combo_item name="physics_medium">
- Medium
- </combo_item>
- <combo_item name="physics_high">
- High
- </combo_item>
- </combo_box>
-
- <line_editor follows="left|top" top_pad="5" width="140" left="60" value="" name="physics_file" height="20"/>
- <button left_pad="10" name="physics_browse" label="Browse..." follows="left|top" width="70" height="20"/>
-
- <!--
- <check_box name="physics_optimize" follows="left|top" width="130" left="10" top_pad="5" height="20" label="Optimize"/>
- <check_box name="physics_use_hull" follows="left|top" width="130" left_pad="5" height="20" label="Use Convex Hull"/>
- -->
- </panel>
-
-
- <!-- PHYSICS ANALYSIS-->
- <panel
- follows="top|left"
- name="physics analysis"
- top_pad="0"
- left="0"
- width="300"
- height="130"
- visible="true"
- border="true"
- bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
-
- <text follows="left|top" bottom="40" height="30" left="10" font="SansSerifBig">
- Step 1: Analysis
+ follows="all"
+ height="50"
+ layout="top|left"
+ left="3"
+ name="model_name_representation_panel"
+ width="525">
+ <text
+ follows="top|left"
+ layout="topleft"
+ height="15"
+ left="15"
+ name="name_label"
+ text_color="White"
+ top="0"
+ width="290">
+ Model name:
</text>
-
- <text top_pad="5" width="50" follows="top|left" height="15">
- Method:
+ <line_editor
+ follows="top|left"
+ layout="topleft"
+ height="19"
+ max_length_bytes="64"
+ name="description_form"
+ prevalidate_callback="ascii"
+ top_pad="5"
+ width="290" />
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left_pad="15"
+ name="model_category_label"
+ text_color="White"
+ top="0"
+ width="200">
+ This model represents...
</text>
- <combo_box name="Method" follows="top|left" left_pad="5" bottom_delta="2" height="20" width="80"/>
- <text left="160" bottom_delta="-2" width="50" follows="top|left" height="15">
- Quality:
- </text>
- <combo_box name="Decompose Quality" bottom_delta="2" follows="top|left" left_pad="5" height="20" width="80"/>
-
- <slider name="Smooth" left="10" width="280" follows="top|left" top_pad="10" height="20" label="Smooth:"/>
-
- <check_box name="Close Holes (Slow)" follows="top|left" top_pad="10" height="15" label="Close Holes (slow)"/>
-
- <button left="200" bottom_delta="0" width="90" follows="top|left" label="Analyze" name="Decompose" height="20"/>
- <button left="200" bottom_delta="0" width="90" follows="top|left" label="Cancel" name="decompose_cancel" visble="false" height="20"/>
- </panel>
-
-
- <!-- PHYSICS SIMPLIFICATION -->
- <panel
- follows="top|left"
- name="physics simplification"
- left="0"
- top_pad="0"
- width="300"
- height="150"
- visible="true"
- border="true"
- bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
-
- <text follows="left|top" bottom="40" height="30" left="10" font="SansSerifBig">
- Step 2: Simplification
- </text>
-
- <text left="10" top_pad="5" height="15" width="140" follows="top|left">
- Method:
- </text>
-
- <combo_box left_pad="5" height="20" width="120" follows="top|left" name="Simplify Method"/>
-
- <slider left="10" name="Combine Quality" label="Passes:" label_width="120" width="270" follows="top|left" top_pad="10" height="20"/>
- <slider name="Detail Scale" label="Detail Scale:" label_width="120" width="270" follows="top|left" top_pad="10" height="20"/>
- <slider name="Retain%" label="Retain:" label_width="120" width="270" follows="top|left" bottom_delta="0" left_delta="0" visible="false" height="20"/>
- <button left="190" width="90" follows="top|left" label="Simplify" name="Simplify" height="20"/>
- <button left="190" bottom_delta="0" width="90" follows="top|left" label="Cancel" name="simplify_cancel" height="20"/>
-
- </panel>
-
- <!-- INFO PANEL -->
- <panel
- left="0"
- top_pad="0"
- width="300"
- height="100"
- follows="left|top"
- name="physics info"
- visible="true"
- border="true"
- bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
-
- <slider name="physics_explode" follows="top|left" top="10" left="10" label="Preview Spread:" min_val="0.0" max_val="3.0" height="20" width="280"/>
-
- <text follows="top|left" name="physics_triangles" top_pad="10" height="15" left="10">
- Triangles: [TRIANGLES]
- </text>
- <text follows="top|left" name="physics_points" top_pad="5" height="15">
- Vertices: [POINTS]
- </text>
- <text follows="top|left" name="physics_hulls" top_pad="5" height="15">
- Hulls: [HULLS]
- </text>
-
-
- </panel>
+ <combo_box
+ follows="left|top"
+ height="23"
+ left_pad="10"
+ name="model_category_combo"
+ top_pad="10"
+ width="200">
+ <combo_box.drop_down_button
+ label_color="White"/>
+ <combo_item name="Choose one" label="Choose One..." value="MUT_Unspecified"/>
+ <combo_item name="Avatar shape" label="Avatar shape" value="MUT_AvatarShape"/>
+ <combo_item name="Avatar attachment" label="Avatar attachment" value="MUT_AvatarAttachment"/>
+ <combo_item name="Moving object (vehicle, animal)" label="Moving object (vehicle, animal)" value="MUT_MovingObject"/>
+ <combo_item name="Building Component" label="Building Component" value="MUT_BuildingComponent"/>
+ <combo_item name="Large, non moving etc" label="Large, non moving etc" value="MUT_LargeStationary"/>
+ <combo_item name="Smaller, non-moving etc" label="Smaller, non-moving etc" value="MUT_SmallStationary"/>
+ <combo_item name="Not really any of these" label="Not really any of these" value="MUT_Other"/>
+ </combo_box>
</panel>
-
- <!-- MODIFIERS PANEL -->
+ <tab_container
+ follows="top|left"
+ top_pad="15"
+ left="0"
+ height="300"
+ width="625"
+ name="import_tab"
+ tab_position="top">
+ <!-- LOD PANEL -->
+ <panel
+ help_topic="upload_model_lod"
+ label="Level of Detail"
+ layout="topleft"
+ name="lod_panel"
+ title="Level of Detail">
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="275"
+ layout="topleft"
+ left="3"
+ name="lod_tab_border"
+ top_pad="0"
+ width="619" />
+ <text
+ follows="left|top"
+ height="18"
+ initial_value="Source"
+ layout="topleft"
+ left="75"
+ name="source"
+ text_color="ModelUploaderLabels"
+ top="15"
+ valign="center"
+ value="Source"
+ width="335" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="Triangles"
+ layout="topleft"
+ left_pad="0"
+ name="triangles"
+ text_color="ModelUploaderLabels"
+ top_delta="0"
+ valign="center"
+ value="Triangles"
+ width="65" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="Vertices"
+ layout="topleft"
+ left_pad="0"
+ name="vertices"
+ text_color="ModelUploaderLabels"
+ valign="center"
+ value="Vertices"
+ width="65" />
+ <text
+ follows="left|top"
+ height="18"
+ initial_value="High"
+ layout="topleft"
+ left="10"
+ name="high_label"
+ text_color="ModelUploaderLabels"
+ top_pad="10"
+ valign="center"
+ value="High"
+ width="65" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ name="lod_source_high"
+ top_delta="-3"
+ width="135">
+ <item
+ id="Load from file"
+ value="Load from file" />
+ <item
+ id="Generate"
+ value="Generate" />
+ </combo_box>
+ <line_editor
+ follows="left|top"
+ height="20"
+ initial_value=""
+ layout="topleft"
+ left_pad="5"
+ name="lod_file_high"
+ top_delta="0"
+ value=""
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Browse..."
+ layout="topleft"
+ left_pad="5"
+ name="lod_browse_high"
+ top_delta="0"
+ width="70" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left="215"
+ name="lod_mode_high"
+ top_delta="0"
+ visible="false"
+ width="135">
+ <item
+ id="Triangle Limit"
+ value="Triangle Limit" />
+ <item
+ id="Error Threshold"
+ value="Error Threshold" />
+ </combo_box>
+ <spinner
+ decimal_digits="0"
+ follows="top|left"
+ height="20"
+ increment="10"
+ layout="topleft"
+ left_pad="5"
+ name="lod_triangle_limit_high"
+ visible="false"
+ width="55" />
+ <spinner
+ follows="top|left"
+ height="20"
+ increment="0.01"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="lod_error_threshold_high"
+ top_delta="0"
+ visible="false"
+ width="55" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="0"
+ layout="topleft"
+ left_pad="0"
+ name="high_triangles"
+ valign="center"
+ value="0"
+ width="65" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="0"
+ layout="topleft"
+ left_pad="0"
+ name="high_vertices"
+ valign="center"
+ value="0"
+ width="65" />
+ <text
+ follows="left|top"
+ halign="center"
+ height="18"
+ initial_value=""
+ layout="topleft"
+ left_pad="0"
+ name="high_status"
+ valign="center"
+ value=""
+ width="65" />
+ <icon
+ height="16"
+ image_name="red_x.png"
+ layout="topleft"
+ left_delta="20"
+ mouse_opaque="true"
+ name="status_icon_high"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="18"
+ initial_value="Medium"
+ layout="topleft"
+ left="10"
+ name="medium_label"
+ text_color="ModelUploaderLabels"
+ top_pad="15"
+ valign="center"
+ value="Medium"
+ width="65" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ name="lod_source_medium"
+ top_delta="-3"
+ width="135">
+ <item
+ id="Load from file"
+ value="Load from file" />
+ <item
+ id="Generate"
+ value="Generate" />
+ <item
+ id="Use LoD above"
+ value="Use LoD above" />
+ </combo_box>
+ <line_editor
+ follows="left|top"
+ height="20"
+ initial_value=""
+ layout="topleft"
+ left_pad="5"
+ name="lod_file_medium"
+ top_delta="0"
+ value=""
+ visible="false"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Browse..."
+ layout="topleft"
+ left_pad="5"
+ name="lod_browse_medium"
+ top_delta="0"
+ visible="false"
+ width="70" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left="215"
+ name="lod_mode_medium"
+ top_delta="0"
+ width="135">
+ <item
+ id="Triangle Limit"
+ value="Triangle Limit" />
+ <item
+ id="Error Threshold"
+ value="Error Threshold" />
+ </combo_box>
+ <spinner
+ decimal_digits="0"
+ follows="top|left"
+ height="20"
+ increment="10"
+ layout="topleft"
+ left_pad="5"
+ name="lod_triangle_limit_medium"
+ width="55" />
+ <spinner
+ follows="top|left"
+ height="20"
+ increment="0.01"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="lod_error_threshold_medium"
+ top_delta="0"
+ visible="false"
+ width="55" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="0"
+ layout="topleft"
+ left_pad="0"
+ name="medium_triangles"
+ valign="center"
+ value="0"
+ width="65" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="0"
+ layout="topleft"
+ left_pad="0"
+ name="medium_vertices"
+ valign="center"
+ value="0"
+ width="65" />
+ <text
+ follows="left|top"
+ halign="center"
+ height="18"
+ initial_value=""
+ layout="topleft"
+ left_pad="0"
+ name="medium_status"
+ valign="center"
+ value=""
+ width="65" />
+ <icon
+ height="16"
+ image_name="red_x.png"
+ layout="topleft"
+ left_delta="20"
+ mouse_opaque="true"
+ name="status_icon_medium"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="18"
+ initial_value="Low"
+ layout="topleft"
+ left="10"
+ name="low_label"
+ text_color="ModelUploaderLabels"
+ top_pad="15"
+ valign="center"
+ value="Low"
+ width="65" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ name="lod_source_low"
+ top_delta="-3"
+ width="135">
+ <item
+ id="Load from file"
+ value="Load from file" />
+ <item
+ id="Generate"
+ value="Generate" />
+ <item
+ id="Use LoD above"
+ value="Use LoD above" />
+ </combo_box>
+ <line_editor
+ follows="left|top"
+ height="20"
+ initial_value=""
+ layout="topleft"
+ left_pad="5"
+ name="lod_file_low"
+ top_delta="0"
+ value=""
+ visible="false"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Browse..."
+ layout="topleft"
+ left_pad="5"
+ name="lod_browse_low"
+ top_delta="0"
+ visible="false"
+ width="70" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left="215"
+ name="lod_mode_low"
+ top_delta="0"
+ width="135">
+ <item
+ id="Triangle Limit"
+ value="Triangle Limit" />
+ <item
+ id="Error Threshold"
+ value="Error Threshold" />
+ </combo_box>
+ <spinner
+ decimal_digits="0"
+ follows="top|left"
+ height="20"
+ increment="10"
+ layout="topleft"
+ left_pad="5"
+ name="lod_triangle_limit_low"
+ width="55" />
+ <spinner
+ follows="top|left"
+ height="20"
+ increment="0.01"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="lod_error_threshold_low"
+ top_delta="0"
+ visible="false"
+ width="55" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="0"
+ layout="topleft"
+ left_pad="0"
+ name="low_triangles"
+ valign="center"
+ value="0"
+ width="65" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="0"
+ layout="topleft"
+ left_pad="0"
+ name="low_vertices"
+ valign="center"
+ value="0"
+ width="65" />
+ <text
+ follows="left|top"
+ halign="center"
+ height="18"
+ initial_value=""
+ layout="topleft"
+ left_pad="0"
+ name="low_status"
+ valign="center"
+ value=""
+ width="65" />
+ <icon
+ height="16"
+ image_name="red_x.png"
+ layout="topleft"
+ left_delta="20"
+ mouse_opaque="true"
+ name="status_icon_low"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="18"
+ initial_value="Lowest"
+ layout="topleft"
+ left="10"
+ name="lowest_label"
+ text_color="ModelUploaderLabels"
+ top_pad="15"
+ valign="center"
+ value="Lowest"
+ width="65" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ name="lod_source_lowest"
+ top_delta="-3"
+ width="135">
+ <item
+ id="Load from file"
+ value="Load from file" />
+ <item
+ id="Generate"
+ value="Generate" />
+ <item
+ id="Use LoD above"
+ value="Use LoD above" />
+ </combo_box>
+ <line_editor
+ follows="left|top"
+ height="20"
+ initial_value=""
+ layout="topleft"
+ left_pad="5"
+ name="lod_file_lowest"
+ top_delta="0"
+ value=""
+ visible="false"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Browse..."
+ layout="topleft"
+ left_pad="5"
+ name="lod_browse_lowest"
+ top_delta="0"
+ visible="false"
+ width="70" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left="215"
+ name="lod_mode_lowest"
+ top_delta="0"
+ width="135">
+ <item
+ id="Triangle Limit"
+ value="Triangle Limit" />
+ <item
+ id="Error Threshold"
+ value="Error Threshold" />
+ </combo_box>
+ <spinner
+ decimal_digits="0"
+ follows="top|left"
+ height="20"
+ increment="10"
+ layout="topleft"
+ left_pad="5"
+ name="lod_triangle_limit_lowest"
+ width="55" />
+ <spinner
+ follows="top|left"
+ height="20"
+ increment="0.01"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="lod_error_threshold_lowest"
+ top_delta="0"
+ visible="false"
+ width="55" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="0"
+ layout="topleft"
+ left_pad="0"
+ name="lowest_triangles"
+ valign="center"
+ value="0"
+ width="65" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="18"
+ initial_value="0"
+ layout="topleft"
+ left_pad="0"
+ name="lowest_vertices"
+ valign="center"
+ value="0"
+ width="65" />
+ <text
+ follows="left|top"
+ halign="center"
+ height="18"
+ initial_value=""
+ layout="topleft"
+ left_pad="0"
+ name="lowest_status"
+ valign="center"
+ value=""
+ width="65" />
+ <icon
+ height="16"
+ image_name="red_x.png"
+ layout="topleft"
+ left_delta="20"
+ mouse_opaque="true"
+ name="status_icon_lowest"
+ top_delta="0"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left="10"
+ name="lod_status_message_icon"
+ top_pad="20"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="lod_status_message_text"
+ top_delta="0"
+ width="584"
+ word_wrap="true"
+ wrap="true" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="10"
+ name="lod_tab_border"
+ top_pad="20"
+ width="605" />
+ <check_box
+ follows="top|left"
+ height="15"
+ label="Generate Normals"
+ layout="topleft"
+ left="10"
+ name="gen_normals"
+ top_pad="20" />
+ <text
+ enabled="false"
+ follows="top|left"
+ height="15"
+ initial_value="Crease Angle:"
+ layout="topleft"
+ left="200"
+ name="crease_label"
+ top_delta="0"
+ value="Crease Angle:"
+ width="100" />
+ <spinner
+ enabled="false"
+ follows="top|left"
+ height="20"
+ initial_value="75"
+ layout="topleft"
+ left_pad="5"
+ max_val="180"
+ name="crease_angle"
+ value="75"
+ width="60" />
+ </panel>
+ <!-- PHYSYCS PANEL -->
+ <panel
+ help_topic="upload_model_physics"
+ label="Physics"
+ name="physics_panel">
+
+ <!-- ==== STEP 1: Level of Detail ==== -->
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="275"
+ layout="topleft"
+ left="3"
+ name="physics_tab_border"
+ top_pad="0"
+ width="619"/>
+ <panel
+ bg_alpha_color="0 0 0 0"
+ bg_opaque_color="0 0 0 0.3"
+ follows="top|left"
+ height="21"
+ left="18"
+ name="physics geometry"
+ top="15"
+ visible="true"
+ width="589">
+ <text
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="0"
+ name="first_step_name"
+ text_color="White"
+ top_pad="0"
+ width="210">
+ Step 1: Level of Detail
+ </text>
+ <combo_box
+ follows="left|top"
+ height="18"
+ left_pad="10"
+ name="physics_lod_combo"
+ width="130"
+ tool_tip="LOD to use for physics shape">
+ <combo_item name="choose_one"> Choose one... </combo_item>
+ <combo_item name="physics_high"> High </combo_item>
+ <combo_item name="physics_medium"> Medium </combo_item>
+ <combo_item name="physics_low"> Low </combo_item>
+ <combo_item name="physics_lowest"> Lowest </combo_item>
+ <combo_item name="load_from_file"> From file </combo_item>
+ </combo_box>
+ <line_editor
+ follows="left|top"
+ left_pad="10"
+ value=""
+ name="physics_file"
+ height="20"
+ width="154"/>
+ <button
+ follows="left|top"
+ height="20"
+ left_pad="4"
+ name="physics_browse"
+ label="Browse..."
+ width="70"/>
+ <!-- <check_box name="physics_optimize" follows="left|top" width="130" left="10" top_pad="5" height="20" label="Optimize"/>
+ <check_box name="physics_use_hull" follows="left|top" width="130" left_pad="5" height="20" label="Use Convex Hull"/> -->
+ </panel>
+
+ <!-- ==== STEP 2: Analyse ==== -->
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="18"
+ name="physics_tab_border"
+ top_pad="15"
+ width="589"/>
+ <panel
+ bg_alpha_color="0 0 0 0"
+ bg_opaque_color="0 0 0 0.3"
+ height="65"
+ follows="top|left"
+ left="18"
+ name="physics analysis"
+ top_pad="15"
+ visible="true"
+ width="589">
+ <text
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="0"
+ name="method_label"
+ text_color="White"
+ top_pad="0">
+ Step 2: Analyse
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ name="analysis_method_label"
+ top_pad="10"
+ width="100">
+ Method:
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ name="quality_label"
+ layout="topleft"
+ left_pad="15"
+ width="100">
+ Quality:
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ name="smooth_method_label"
+ layout="topleft"
+ left_pad="15"
+ width="100">
+ Smooth:
+ </text>
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ left="0"
+ name="Method"
+ top_pad="0"
+ height="20"
+ width="100"/>
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ left_pad="15"
+ name="Decompose Quality"
+ height="20"
+ width="100"/>
+ <combo_box
+ height="20"
+ follows="top|left"
+ layout="topleft"
+ left_pad="15"
+ name="Cosine%"
+ width="100"/>
+ <check_box
+ follows="top|left"
+ label="Close Holes"
+ layout="topleft"
+ left_pad="10"
+ name="Close Holes (Slow)"
+ height="15"/>
+ <button
+ bottom="1"
+ follows="top|right"
+ height="20"
+ label="Analyze"
+ layout="bottomleft"
+ name="Decompose"
+ right="-1"
+ width="90"/>
+ <button
+ follows="top|left"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left_delta="0"
+ name="decompose_cancel"
+ visible="false"
+ width="90"/>
+ </panel>
+
+ <!-- ==== STEP 3: Simplify ==== -->
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="18"
+ name="physics_tab_border"
+ top_pad="15"
+ width="589"/>
+ <panel
+ bg_alpha_color="0 0 0 0"
+ bg_opaque_color="0 0 0 0.3"
+ follows="top|left"
+ height="66"
+ left="18"
+ name="physics simplification"
+ top_pad="15"
+ width="589">
+ <text
+ text_color="White"
+ follows="left|top"
+ height="20"
+ left="0"
+ name="second_step_label"
+ top_pad="0"
+ font="SansSerif">
+ Step 3: Simplify
+ </text>
+ <text
+ name="simp_method_header"
+ top_pad="10"
+ height="15"
+ width="100"
+ follows="top|left">
+ Method:
+ </text>
+ <text
+ follows="top|left"
+ left_pad="40"
+ name="pass_method_header"
+ height="15"
+ width="41">
+ Passes:
+ </text>
+ <text
+ follows="top|left"
+ left_pad="40"
+ name="Detail Scale label"
+ height="15"
+ width="80">
+ Detail scale:
+ </text>
+ <text
+ follows="top|left"
+ left_delta="0"
+ name="Retain%_label"
+ height="15"
+ width="80"
+ visible="false">
+ Retain:
+ </text>
+ <combo_box
+ follows="top|left"
+ height="20"
+ left="0"
+ name="Simplify Method"
+ top_pad="0"
+ width="100"/>
+ <combo_box
+ height="20"
+ follows="top|left"
+ left_pad="40"
+ name="Combine Quality"
+ width="41"
+ value="1">
+ </combo_box>
+ <spinner
+ follows="top|left"
+ name="Detail Scale"
+ height="20"
+ left_pad="40"
+ width="60"/>
+ <spinner
+ name="Retain%"
+ decimal_digits="0"
+ width="60"
+ follows="top|left"
+ height="20"
+ left_delta="0"
+ visible="false"/>
+ <button
+ follows="top|left"
+ height="20"
+ label="Simplify"
+ left_pad="40"
+ name="Simplify"
+ width="90"/>
+ <button
+ follows="top|left"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left_delta="0"
+ name="simplify_cancel"
+ width="90"/>
+ </panel>
+
+ <!-- ==== Results ==== -->
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="18"
+ name="physics_tab_border"
+ top_pad="15"
+ width="589"/>
+ <panel
+ bg_alpha_color="0 0 0 0"
+ bg_opaque_color="0 0 0 0.3"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="18"
+ name="physics info"
+ top_pad="15"
+ width="589">
+ <text
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="0"
+ text_color="White"
+ top_pad="0"
+ name="results_text"
+ width="50">
+ Results:
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left_pad="0"
+ text_color="White"
+ top_delta="0"
+ name="physics_triangles"
+ width="90">
+ Triangles: [TRIANGLES],
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left_pad="0"
+ name="physics_points"
+ top_delta="0"
+ text_color="White"
+ width="85">
+ Vertices: [POINTS],
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left_pad="0"
+ name="physics_hulls"
+ top_delta="0"
+ text_color="White">
+ Hulls: [HULLS]
+ </text>
+ </panel>
+ </panel>
+ <!-- MODIFIERS PANEL -->
+ <panel
+ label="Upload options"
+ name="modifiers_panel"
+ help_topic="upload_model_modifiers">
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="275"
+ layout="topleft"
+ left="3"
+ name="border"
+ top_pad="0"
+ width="619"/>
+ <text
+ follows="top|left"
+ height="16"
+ left="20"
+ name="scale_label"
+ text_color="White"
+ top="15"
+ width="140">
+ Scale (1=no scaling):
+ </text>
+ <spinner
+ height="20"
+ follows="top|left"
+ left_pad="10"
+ max_val="64.0"
+ min_val="0.01"
+ name="import_scale"
+ top_delta="-4"
+ value="1.0"
+ width="80"/>
+ <text
+ follows="top|left"
+ height="15"
+ left_pad="20"
+ name="dimensions_label"
+ text_color="White"
+ width="90">
+ Dimensions:
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ left_pad="0"
+ name="import_dimensions"
+ text_color="White"
+ width="140">
+ [X] X [Y] X [Z]
+ </text>
+ <check_box
+ height="15"
+ follows="top|left"
+ name="upload_textures"
+ label="Include textures"
+ label_text.text_color="White"
+ left="20"
+ top_pad="20"/>
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ name="border"
+ top_pad="20"
+ width="579"/>
+ <text
+ follows="top|left"
+ height="15"
+ left="20"
+ name="include_label"
+ text_color="White"
+ top_pad="20"
+ width="150">
+ For avatar models only:
+ </text>
+ <check_box
+ follows="top|left"
+ height="15"
+ label="Include skin weight"
+ label_text.text_color="White"
+ name="upload_skin"
+ top_pad="15"/>
+ <check_box
+ follows="top|left"
+ height="15"
+ label="Include joint positions"
+ label_text.text_color="White"
+ name="upload_joints"
+ top_pad="15"/>
+ <text
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="220"
+ name="pelvis_offset_label"
+ text_color="White"
+ top="134"
+ width="200">
+ Z offset (raise or lower avatar):
+ </text>
+ <spinner
+ follows="top|left"
+ height="20"
+ min_val="-3.00"
+ max_val="3.0"
+ name="pelvis_offset"
+ top_pad="10"
+ value="0.0"
+ width="80"/>
+ </panel>
+ </tab_container>
<panel
- border="true"
- label="Modifiers"
- name="modifiers_panel"
- help_topic="upload_model_modifiers">
-
- <text left="10" width="90" bottom="30" follows="top|left" height="15">
- Scale:
- </text>
- <text left_pad="5" width="140" follows="top|left" height="15">
- Dimensions:
- </text>
-
- <spinner left="10" height="20" follows="top|left" width="80" top_pad="5" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/>
-
- <text left_pad="20" height="15" name="import_dimensions" follows="top|left">
- [X] x [Y] x [Z] m
- </text>
-
- <text left="10" top_pad="20" follows="top|left" height="15">
- Include:
- </text>
-
- <check_box top_pad="5" name="upload_textures" height="15" follows="top|left" label="Textures"/>
- <check_box top_pad="5" name="upload_skin" height="15" follows="top|left" label="Skin weight"/>
- <check_box top_pad="5" left="20" name="upload_joints" height="15" follows="top|left" label="Joint positions"/>
-
- <text left="10" top_pad="4" width="90" bottom="30" follows="top|left" height="15">
- Pelvis Z Offset:
- </text>
-
- <spinner left="10" top_pad="4" height="20" follows="top|left" width="80" value="0.0" min_val="-3.00" max_val="3.0" name="pelvis_offset"/>
-
- </panel>
- </tab_container>
-
- <text
- height="16"
- left_delta="5"
- bottom_delta="30"
- name="upload_fee"
- width="300"
- follows="bottom|right"
- word_wrap="true"
- >
- Upload fee: L$ [FEE]
- </text>
-
- <button bottom="540" left="10" follows="bottom|left" height="20" label="Set to defaults"
- width="100" name="reset_btn" tool_tip="Set to defaults"/>
- <button left="310" follows="bottom|right" height="20" label="Calculate weights &amp; fee"
- width="150" name="calculate_btn" tool_tip="Calculate weights &amp; fee" top_delta="0"/>
- <button bottom="540" left="310" follows="bottom|right" height="20" label="Upload"
- width="80" name="ok_btn" tool_tip="Upload to simulator" visible="false"/>
- <button right="-10" follows="right|bottom" height="20" width="80" label="Cancel" name="cancel_btn" top_delta="0"/>
-
- <!--
- <button bottom_delta="0" left="10" width="120" name="auto fill" label="Generate LOD" tool_tip="Automatically generate levels of detail"/>
- <button bottom_delta="0" left="140" width="120" name="smooth normals" label="Generate Normals" tool_tip="Regenerate normals based on mesh shape"/>
- <button bottom_delta="0" left="260" width="120" name="consolidate" label="Consolidate" tool_tip="Combine similar submeshes (reduces number of submeshes)"/>
- <button bottom_delta="30" left="260" width="120" name="scrub materials" label="Scrub Materials" tool_tip="Remove all material information (clear textures, set all colors to white)."/>
-
- <spinner bottom_delta="0" left="140" width="120" height="16" initial_value="75" label_width="60" name="edge threshold" decimal_digits="0" min_val="0" max_val="180" increment="5" label="Hard Angle" tool_tip="Maximum angle that will be smoothed between triangles when using Generate Normals"/>
-
- <text bottom_delta="30" follows="top|left" height="15" left="10" name="high_lod_label">
- High LOD:
- </text>
- <combo_box bottom_delta="0" left="97" follows="left|top" height="18"
- name="high detail combo" width="100" tool_tip="Specify mesh for this level of detail">
- <combo_item name="high none" value="none">
- None
- </combo_item>
- <combo_item name="high choose file" value="file">
- Choose File...
- </combo_item>
- <combo_item name="high triangle limit" value="limit">
- Triangle Limit
- </combo_item>
- </combo_box>
- <spinner bottom_delta="-5" left="200" width="120" name="high limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/>
- <text bottom_delta="25" follows="top|left" height="15" left="10" name="high info" width="300">
- [TRIANGLES] Triangles, [VERTICES] Vertices, [SUBMESHES] Submeshes.
- [MESSAGE]
- </text>
-
- <text bottom_delta="35" follows="top|left" height="15" left="10" name="medium_lod_label">
- Medium LOD:
- </text>
- <combo_box bottom_delta="0" left="97" follows="left|top" height="18"
- name="medium detail combo" width="100" tool_tip="Specify mesh for this level of detail">
- <combo_item name="medium none" value="none">
- None
- </combo_item>
- <combo_item name="medium choose file" value="file">
- Choose File...
- </combo_item>
- <combo_item name="medium triangle limit" value="limit">
- Triangle Limit
- </combo_item>
- </combo_box>
- <spinner bottom_delta="-5" left="200" width="120" name="medium limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/>
- <text bottom_delta="25" follows="top|left" height="15" left="10" name="medium info" width="300">
- [TRIANGLES] Triangles, [VERTICES] Vertices, [SUBMESHES] Submeshes.
- [MESSAGE]
- </text>
-
- <text bottom_delta="35" follows="top|left" height="15" left="10" name="low_lod_label">
- Low LOD:
- </text>
- <combo_box bottom_delta="0" left="97" follows="left|top" height="18"
- name="low detail combo" width="100" tool_tip="Specify mesh for this level of detail">
- <combo_item name="low none" value="none">
- None
- </combo_item>
- <combo_item name="low choose file" value="file">
- Choose File...
- </combo_item>
- <combo_item name="low triangle limit" value="limit">
- Triangle Limit
- </combo_item>
- </combo_box>
- <spinner bottom_delta="-5" left="200" width="120" name="low limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/>
- <text bottom_delta="25" follows="top|left" height="15" left="10" name="low info" width="300">
- [TRIANGLES] Triangles, [VERTICES] Vertices, [SUBMESHES] Submeshes
- [MESSAGE]
- </text>
-
- <text bottom_delta="35" follows="top|left" height="15" left="10" name="lowest_lod_label">
- Lowest LOD:
- </text>
- <combo_box bottom_delta="0" left="97" follows="left|top" height="18"
- name="lowest detail combo" width="100" tool_tip="Specify mesh for this level of detail">
- <combo_item name="lowest none" value="none">
- None
- </combo_item>
- <combo_item name="lowest choose file" value="file">
- Choose File...
- </combo_item>
- <combo_item name="lowest triangle limit" value="limit">
- Triangle Limit
- </combo_item>
- </combo_box>
- <spinner bottom_delta="-5" left="200" width="120" name="lowest limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/>
- <text bottom_delta="25" follows="top|left" height="15" left="10" name="lowest info" width="300">
- [TRIANGLES] Triangles, [VERTICES] Vertices, [SUBMESHES] Submeshes
- [MESSAGE]
- </text>
-
- <text bottom_delta="35" follows="top|left" height="15" left="10" name="physics_lod_label">
- Physical Shape:
- </text>
- <combo_box bottom_delta="0" left="97" follows="left|top" height="18"
- name="physics detail combo" width="100">
- <combo_item name="physics none" value="none">
- None
- </combo_item>
- <combo_item name="physics choose file" value="file">
- Choose File...
- </combo_item>
- <combo_item name="physics triangle limit" value="limit">
- Triangle Limit...
- </combo_item>
- </combo_box>
- <spinner bottom_delta="-5" left="200" width="90" name="physics limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/>
- <button bottom_delta="0" left="290" width="30" follows="left|top" height="20" label=">>"
- name="decompose_btn" tool_tip="Create convex decomposition."/>
- <text bottom_delta="25" follows="top|left" height="15" left="10" name="physics info" width="300">
- [TRIANGLES] Triangles, [HULLS] Hulls, [POINTS] Points
- </text>
-
- <text bottom_delta="25" follows="top|left" height="15" left="10" name="include label" width="300">
- Include:
- </text>
-
- <check_box bottom_delta="20" follow="bottom|left" height="20" label="Textures"
- left="15" width="125" name="upload_textures" tool_tip="Upload associated textures "/>
-
- <check_box bottom_delta="20" follow="bottom|left" height="20" label="Skin Weights"
- left="15" width="125" name="upload_skin" tool_tip="Upload vertex skin weighting information."/>
-
- <check_box bottom_delta="20" follow="bottom|left" height="20" label="Joint Positions"
- left="15" width="125" name="upload_joints" tool_tip="Upload joint position information (will override avatar joint positions when mesh is worn)."/>
-
-
- <button bottom_delta="25" follows="bottom|left" height="20" label="Upload"
- left="15" name="ok_btn" width="125" tool_tip="Upload to simulator"/>
-
- <text bottom_delta="20" left="15" width="280" follows="top|left" height="15" name="description_label" text_color="1 0.82 0.46 1">
- (No charge for upload during First Look)
- </text>
- <text bottom_delta="20" left="15" width="280" follows="top|left" height="15" name="upload_message">
- [MESSAGE]
- </text>
+ follows="top|left"
+ height="80"
+ layout="top|left"
+ left="0"
+ name="weights_and_warning_panel"
+ top_pad="3"
+ width="625">
+ <button
+ follows="top|left"
+ label="Calculate weights &amp; fee"
+ label_color="White"
+ layout="topleft"
+ left="3"
+ name="calculate_btn"
+ top="3"
+ height="20"
+ width="150"
+ tool_tip="Calculate weights &amp;fee"/>
+ <button
+ follows="top|left"
+ label="Cancel"
+ label_color="White"
+ layout="topleft"
+ left_pad="6"
+ name="cancel_btn"
+ top="3"
+ height="20"
+ width="80"/>
+ <button
+ follows="top|left"
+ label="Upload"
+ layout="topleft"
+ label_color="White"
+ left="35"
+ name="ok_btn"
+ top="3"
+ height="20"
+ visible="false"
+ width="80"
+ tool_tip="Upload to simulator"/>
+ <button
+ follows="top|right"
+ label="Clear settings &amp; reset form"
+ label_color="White"
+ layout="topleft"
+ name="reset_btn"
+ right="-2"
+ top="3"
+ height="20"
+ width="155"/>
+ <!-- ========== WEIGHTS ==========-->
+ <text
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="5"
+ name="upload_fee"
+ top_pad="10"
+ width="130"
+ word_wrap="true">
+ Upload fee: L$ [FEE]
+ </text>
+ <text
+ height="15"
+ layout="topleft"
+ left_pad="0"
+ name="prim_weight"
+ top_delta="0"
+ width="120"
+ word_wrap="true">
+ Land impact: [EQ]
+ </text>
+ <text
+ height="15"
+ layout="topleft"
+ left_pad="0"
+ name="download_weight"
+ top_delta="0"
+ width="100"
+ word_wrap="true">
+ Download: [ST]
+ </text>
+ <text
+ height="15"
+ top_delta="0"
+ layout="topleft"
+ left_pad="0"
+ name="physics_weight"
+ width="90"
+ word_wrap="true">
+ Physics: [PH]
+ </text>
+ <text
+ height="15"
+ top_delta="0"
+ layout="topleft"
+ left_pad="0"
+ name="server_weight"
+ width="83"
+ word_wrap="true">
+ Server: [SIM]
+ </text>
+ <!-- ========== NOTE MESSAGE ========== -->
+ <text
+ font="SansSerif"
+ layout="topleft"
+ left="6"
+ name="warning_title"
+ top_pad="10"
+ text_color="DrYellow"
+ visible="false"
+ width="40">
+ NOTE:
+ </text>
+ <text
+ text_color="White"
+ height="20"
+ layout="topleft"
+ left_pad="1"
+ name="warning_message"
+ parse_urls="true"
+ top_delta="2"
+ wrap="true"
+ width="462"
+ visible="false">
+ You dont have rights to upload mesh models. [[VURL] Find out how] to get certified.
+ </text>
+ <text text_color="Yellow" layout="topleft" top_delta="20" left="6" name="status">[STATUS]</text>
- <spinner bottom_delta="20" label="Scale" left="15" width="120" name="debug scale" decimal_digits="3" increment="0.1" min_val="0" max_val="64" initial_value="1" tool_tip="Multiplier for incoming object scale. If incoming dimensions are very small or very large, modify this value to get dimensions into an acceptable range."/>
- <text bottom_delta="30" left="15" width="280" follows="top|left" height="15" name="dimensions">
- Model Dimensions: [X]m x [Y]m x [Z]m
- </text>
- -->
+ </panel>
+</panel>
+
+<text
+ follows="left|top"
+ layout="topleft"
+ left="640"
+ name="lod_label"
+ text_color="White"
+ top="13"
+ height="15"
+ width="290">
+ Preview:
+ </text>
+<panel
+ border="true"
+ bevel_style="none"
+ follows="top|left"
+ name="preview_panel"
+ top_pad="4"
+ width="290"
+ height="290"/>
+
+<panel
+ follows="all"
+ height="130"
+ layout="topleft"
+ name="right_panel"
+ top_pad="5"
+ width="290">
+ <combo_box
+ top_pad="3"
+ follows="left|top"
+ height="18"
+ layout="topleft"
+ name="preview_lod_combo"
+ width="150"
+ tool_tip="LOD to view in preview render">
+ <combo_item name="high"> High </combo_item>
+ <combo_item name="medium"> Medium </combo_item>
+ <combo_item name="low"> Low </combo_item>
+ <combo_item name="lowest"> Lowest </combo_item>
+ </combo_box>
+ <text
+ follows="top|left"
+ layout="topleft"
+ text_color="White"
+ top="5"
+ left_pad="20"
+ name="label_display"
+ width="50">
+ Display...
+ </text>
+ <check_box
+ follows="top|left"
+ label="Edges"
+ label_text.text_color="White"
+ layout="topleft"
+ left_delta="0"
+ name="show_edges"
+ top_pad="8">
+ </check_box>
+ <check_box
+ follows="top|left"
+ label="Physics"
+ label_text.text_color="White"
+ layout="topleft"
+ name="show_physics"
+ top_pad="8">
+ </check_box>
+ <check_box
+ follows="top|left"
+ label="Textures"
+ label_text.text_color="White"
+ layout="topleft"
+ name="show_textures"
+ top_pad="8">
+ </check_box>
+ <check_box
+ follows="top|left"
+ label="Skin weights"
+ label_text.text_color="White"
+ layout="topleft"
+ name="show_skin_weight"
+ top_pad="8">
+ </check_box>
+ <check_box
+ follows="top|left"
+ label="Joints"
+ label_text.text_color="White"
+ layout="topleft"
+ name="show_joint_positions"
+ top_pad="8">
+ </check_box>
+ <text
+ follows="top|left"
+ layout="topleft"
+ left="2"
+ name="physics_explode_label"
+ top="85"
+ width="150">
+ Preview Spread:
+ </text>
+ <slider
+ name="physics_explode"
+ follows="top|left"
+ top="100"
+ left="0"
+ min_val="0.0"
+ max_val="3.0"
+ height="20"
+ width="150"/>
+</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml
index 3d16ccbc45..b5a5ff5342 100644
--- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml
@@ -108,7 +108,7 @@
height="22"
top_pad="15"
width="505"
- name="choose_file_header_panel"
+ name="header_panel"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true"
@@ -117,7 +117,7 @@
width="200"
left="10"
top="3"
- name="choose_file_header_text"
+ name="header_text"
text_color="White"
height="10"
font="SansSerifBig"
@@ -130,7 +130,7 @@
left="15"
height="310"
width="505"
- name="choose_file_content_panel"
+ name="content"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
@@ -163,7 +163,7 @@
height="10"
layout="topleft"
left_delta="0"
- name="choose_model_file_label"
+ name="Cache location"
width="320">
Choose model file to upload
</text>
@@ -199,7 +199,7 @@
height="10"
layout="topleft"
left="10"
- name="support_collada_text"
+ name="Cache location"
width="320">
Second Life supports COLLADA (.dae) files
</text>
@@ -221,7 +221,6 @@
width="130"
height="14"
left_delta="0"
- name="dimensions_label"
text_color="White"
word_wrap="true">
Dimensions (meters):
@@ -288,7 +287,7 @@
<panel
height="22"
top_pad="15"
- name="optimize_header_panel"
+ name="header_panel"
width="505"
bg_opaque_color="DkGray2"
background_visible="true"
@@ -297,7 +296,7 @@
<text
width="200"
left="10"
- name="optimize_header_text"
+ name="header_text"
top="3"
text_color="White"
height="10"
@@ -312,7 +311,7 @@
height="20"
font="SansSerifSmall"
layout="topleft"
- name="optimize_hint"
+ name="description"
word_wrap="true"
left_delta="5">
We have optimized the model for performance. Adjust it further if you wish.
@@ -323,12 +322,11 @@
left="15"
height="270"
width="505"
- name="optimize_content_panel"
+ name="content"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
<text
- name="generating_lod_label"
top="20"
width="300"
height="12"
@@ -403,12 +401,12 @@
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
- <text name="optimize_performance_text" top="69" left="10" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Performance</text>
- <text name="optimize_faster_rendering_text" top="85" left="10" width="120" word_wrap="true" font="SansSerifSmall" height="40">Faster rendering
+ <text top="69" left="10" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Performance</text>
+ <text top="85" left="10" width="120" word_wrap="true" font="SansSerifSmall" height="40">Faster rendering
Less detail
Lower prim weight</text>
- <text name="optimize_accuracy_text" top="69" left="184" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Accuracy</text>
- <text name="optimize_slower_rendering_text" top="85" left="184" width="120" word_wrap="true" font="SansSerifSmall" height="40">Slower rendering
+ <text top="69" left="184" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Accuracy</text>
+ <text top="85" left="184" width="120" word_wrap="true" font="SansSerifSmall" height="40">Slower rendering
More detail
Higher prim weight</text>
@@ -426,24 +424,21 @@ Higher prim weight</text>
top="130"
width="290" />
<text
- font="SansSerifSmall"
- name="accuracy_slider_mark1"
+ font="SansSerifSmall"
top_pad="0"
width="5"
left_delta="6"
height="4">'
</text>
<text
- font="SansSerifSmall"
- name="accuracy_slider_mark2"
+ font="SansSerifSmall"
top_delta="0"
width="5"
left_delta="137"
height="4">'
</text>
<text
- font="SansSerifSmall"
- name="accuracy_slider_mark3"
+ font="SansSerifSmall"
top_delta="0"
width="5"
left_delta="137"
@@ -459,7 +454,7 @@ Higher prim weight</text>
top_pad="15"
width="150">
</button>
- <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="geometry_preview_label">
+ <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label">
Geometry preview
</text>
<panel
@@ -476,16 +471,16 @@ Higher prim weight</text>
</panel>
<combo_box left_delta="75" top_pad="10" follows="left|top" list_position="below" height="22"
name="preview_lod_combo" width="110" tool_tip="LOD to view in preview render">
- <combo_item name="preview_lod_high">
+ <combo_item name="high">
High detail
</combo_item>
- <combo_item name="preview_lod_medium">
+ <combo_item name="medium">
Medium detail
</combo_item>
- <combo_item name="preview_lod_low">
+ <combo_item name="low">
Low detail
</combo_item>
- <combo_item name="preview_lod_lowest">
+ <combo_item name="lowest">
Lowest detail
</combo_item>
</combo_box>
@@ -502,7 +497,7 @@ Higher prim weight</text>
<panel
height="22"
top_pad="15"
- name="physics_header_panel"
+ name="header_panel"
width="505"
bg_opaque_color="DkGray2"
background_visible="true"
@@ -511,7 +506,7 @@ Higher prim weight</text>
<text
width="200"
left="10"
- name="physics_header_text"
+ name="header_text"
top="3"
height="10"
font="SansSerifBig"
@@ -526,7 +521,7 @@ Higher prim weight</text>
height="50"
font="SansSerifSmall"
layout="topleft"
- name="physics_hint"
+ name="description"
word_wrap="true"
left_delta="5">
We will create a shape for the outer hull of the model. Adjust the shape's detail level as needed for the intended purpose of your model.
@@ -536,16 +531,16 @@ Higher prim weight</text>
left="15"
height="270"
width="505"
- name="physics_content_panel"
+ name="content"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
- <text name="physics_performance_text" top="10" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Performance</text>
- <text name="physics_faster_rendering_text" top="26" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Faster rendering
+ <text top="10" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Performance</text>
+ <text top="26" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Faster rendering
Less detail
Lower prim weight</text>
- <text name="physics_accuracy_text" top="174" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Accuracy</text>
- <text name="physics_slower_dendering_text" top="190" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Slower rendering
+ <text top="174" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Accuracy</text>
+ <text top="190" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Slower rendering
More detail
Higher prim weight</text>
@@ -563,15 +558,15 @@ Higher prim weight</text>
show_text="false"
top="25"
width="22" />
- <text name="physics_example_1" top="10" width="120" word_wrap="true" left_pad="10" height="50">Examples:
+ <text top="10" width="120" word_wrap="true" left_pad="10" height="50">Examples:
Moving objects
Flying objects
Vehicles</text>
- <text name="physics_example_2" top="95" width="120" word_wrap="true" left_delta="0" height="50">Examples:
+ <text top="95" width="120" word_wrap="true" left_delta="0" height="50">Examples:
Small static objects
Less detailed objects
Simple furniture</text>
- <text name="physics_example_3" top="180" width="120" word_wrap="true" left_delta="0" height="50">Examples:
+ <text top="180" width="120" word_wrap="true" left_delta="0" height="50">Examples:
Static objects
Detailed objects
Buildings</text>
@@ -597,7 +592,7 @@ Buildings</text>
visible="false"
width="150">
</button>
- <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="physics_preview_label">
+ <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label">
Physics preview
</text>
<panel
@@ -614,16 +609,16 @@ Buildings</text>
</panel>
<combo_box left_delta="75" top_pad="10" follows="left|top" list_position="below" height="22"
name="preview_lod_combo2" width="110" tool_tip="LOD to view in preview render">
- <combo_item name="preview_lod2_high">
+ <combo_item name="high">
High detail
</combo_item>
- <combo_item name="preview_lod2_medium">
+ <combo_item name="medium">
Medium detail
</combo_item>
- <combo_item name="preview_lod2_low">
+ <combo_item name="low">
Low detail
</combo_item>
- <combo_item name="preview_lod2_lowest">
+ <combo_item name="lowest">
Lowest detail
</combo_item>
</combo_box>
@@ -640,7 +635,7 @@ Buildings</text>
<panel
height="22"
top_pad="15"
- name="review_header_panel"
+ name="header_panel"
width="505"
bg_opaque_color="DkGray2"
background_visible="true"
@@ -649,7 +644,7 @@ Buildings</text>
<text
width="200"
left="10"
- name="review_header_text"
+ name="header_text"
text_color="White"
top="3"
height="10"
@@ -663,7 +658,7 @@ Buildings</text>
left="15"
height="310"
width="505"
- name="review_content_panel"
+ name="content"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
@@ -711,7 +706,7 @@ Buildings</text>
<panel
height="22"
top_pad="15"
- name="upload_header_panel"
+ name="header_panel"
width="505"
bg_opaque_color="DkGray2"
background_visible="true"
@@ -720,7 +715,7 @@ Buildings</text>
<text
width="200"
left="10"
- name="upload_header_text"
+ name="header_text"
top="3"
text_color="White"
height="10"
diff --git a/indra/newview/skins/default/xui/en/floater_object_weights.xml b/indra/newview/skins/default/xui/en/floater_object_weights.xml
new file mode 100644
index 0000000000..eb283a1043
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_object_weights.xml
@@ -0,0 +1,342 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_close="true"
+ can_tear_off="false"
+ height="315"
+ help_topic="object_weights"
+ layout="topleft"
+ name="object_weights"
+ save_rect="true"
+ single_instance="true"
+ title="ADVANCED"
+ width="200">
+ <floater.string
+ name="nothing_selected"
+ value="--"/>
+
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="selected_text"
+ text_color="EmphasisColor"
+ top="10"
+ value="SELECTED"
+ width="180" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="objects"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="objects_label"
+ top_delta="0"
+ value="Objects"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="prims"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="prims_label"
+ top_delta="0"
+ value="Prims"
+ width="130" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="10"
+ name="selected_text_border"
+ top_pad="5"
+ width="180"/>
+
+
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="weights_of_selected_text"
+ text_color="EmphasisColor"
+ top_pad="10"
+ value="WEIGHTS OF SELECTED"
+ width="180" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="download"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="download_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="download_label"
+ top_delta="0"
+ value="Download"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="physics"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="physics_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="physics_label"
+ top_delta="0"
+ value="Physics"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="server"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="server_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="server_label"
+ top_delta="0"
+ value="Server"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="display"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="display_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="display_label"
+ top_delta="0"
+ value="Display"
+ width="130" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="10"
+ name="weights_text_border"
+ top_pad="5"
+ width="180"/>
+
+
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="land_impacts_text"
+ text_color="EmphasisColor"
+ top_pad="10"
+ value="LAND IMPACTS"
+ width="180" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="selected"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="selected_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="selected_label"
+ top_delta="0"
+ value="Selected"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="rezzed_on_land"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="rezzed_on_land_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="rezzed_on_land_label"
+ top_delta="0"
+ value="Rezzed on land"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="remaining_capacity"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="remaining_capacity_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="remaining_capacity_label"
+ top_delta="0"
+ value="Remaining capacity"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="total_capacity"
+ top_pad="3"
+ value="--"
+ width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="total_capacity_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="total_capacity_label"
+ top_delta="0"
+ value="Total capacity"
+ width="130" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="10"
+ name="land_impacts_text_border"
+ top_pad="5"
+ width="180"/>
+
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="help_SLURL"
+ top_pad="10"
+ value="[secondlife:///app/help/object_weights What is all this?...]"
+ width="180" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 8901583799..9b02f7d273 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -48,11 +48,11 @@
</floater.string>
<floater.string
name="status_selectcount">
- [OBJ_COUNT] objects ( [PRIM_COUNT] prims[PE_STRING] ) selected
+ [OBJ_COUNT] objects selected, land impact [LAND_IMPACT]
</floater.string>
<floater.string
- name="status_selectprimequiv">
- , [SEL_WEIGHT] prim equivs
+ name="status_remaining_capacity">
+ Remaining capacity [LAND_CAPACITY].
</floater.string>
<button
follows="left|top"
@@ -738,11 +738,11 @@
font="SansSerifSmall"
layout="topleft"
left="10"
- name="selection_weight"
+ name="remaining_capacity"
top_pad="0"
visible="false"
width="280">
- Physics weight [PHYS_WEIGHT], Render Cost [DISP_WEIGHT].
+ [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights More info]
</text>
<!-- <text -->
<!-- text_color="LtGray_50" -->
@@ -2000,25 +2000,21 @@ even though the user gets a free copy.
visible="false"
width="150">
<combo_box.item
- label="(none)"
- name="None"
- value="None" />
- <combo_box.item
label="Sphere"
name="Sphere"
- value="Sphere" />
+ value="1" />
<combo_box.item
label="Torus"
name="Torus"
- value="Torus" />
+ value="2" />
<combo_box.item
label="Plane"
name="Plane"
- value="Plane" />
+ value="3" />
<combo_box.item
label="Cylinder"
name="Cylinder"
- value="Cylinder" />
+ value="4" />
</combo_box>
</panel>
<panel
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 36ebe73753..16f48f3a4e 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1277,7 +1277,7 @@
parameter="stats" />
</menu_item_check>
<menu_item_check
- label="Show Avatar Rendering Cost"
+ label="Show Draw Weight for Avatars"
name="Avatar Rendering Cost">
<menu_item_check.on_check
function="Advanced.CheckInfoDisplay"
@@ -2435,6 +2435,16 @@
function="Advanced.ToggleInfoDisplay"
parameter="raycast" />
</menu_item_check>
+ <menu_item_check
+ label="Render Complexity"
+ name="rendercomplexity">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="rendercomplexity" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="rendercomplexity" />
+ </menu_item_check>
<menu_item_check
label="Sculpt"
name="Sculpt">
diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml
index 3f9195d092..44c84e69a1 100644
--- a/indra/newview/skins/default/xui/en/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_general.xml
@@ -133,17 +133,7 @@
tool_tip="Let people see this region and its parcels in search results"
top="190"
width="80" />
- <check_box
- visible="FALSE"
- height="20"
- label="Allow Mesh Objects"
- layout="topleft"
- left="10"
- name="mesh_rez_enabled_check"
- tool_tip="Let people rez mesh objects on this region"
- top="210"
- width="80" />
- <spinner
+ <spinner
decimal_digits="0"
follows="left|top"
height="20"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c0154ae9b3..5d2db8cc4c 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3650,5 +3650,15 @@ Try enclosing path to the editor with double quotes.
<string name="BeaconSound">Viewing sound beacons (yellow)</string>
<string name="BeaconMedia">Viewing media beacons (white)</string>
<string name="ParticleHiding">Hiding Particles</string>
+
+ <!-- Mesh UI terms -->
+ <string name="Retain%">Retain%</string>
+ <string name="Detail">Detail</string>
+ <string name="Better Detail">Better Detail</string>
+ <string name="Surface">Surface</string>
+ <string name="Solid">Solid</string>
+ <string name="Wrap">Wrap</string>
+ <string name="Preview">Preview</string>
+ <string name="Normal">Normal</string>
</strings>