diff options
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 ¶ms, 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 ¶ms, 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*) ¶m[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*) ¶m[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*) ¶m[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*) ¶m[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*) ¶m[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 ¶ms_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 ¶ms_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.pngBinary files differ new file mode 100644 index 0000000000..d2a5b348dc --- /dev/null +++ b/indra/newview/skins/default/textures/green_checkmark.png diff --git a/indra/newview/skins/default/textures/red_x.png b/indra/newview/skins/default/textures/red_x.pngBinary files differ new file mode 100644 index 0000000000..a61202f09b --- /dev/null +++ b/indra/newview/skins/default/textures/red_x.png 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 & fee" -	     width="150" name="calculate_btn" tool_tip="Calculate weights & 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 & fee" +         label_color="White" +         layout="topleft" +         left="3" +         name="calculate_btn" +         top="3" +         height="20" +         width="150" +         tool_tip="Calculate weights &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 & 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> | 
