diff options
33 files changed, 1059 insertions, 658 deletions
diff --git a/autobuild.xml b/autobuild.xml index d1a7107319..084fe2f2f4 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -246,9 +246,9 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>d05be8fc196e9ce7b6636b931cf13dff</string> +              <string>be7321370b69b6d66938b82a9230a067</string>                <key>url</key> -              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-colladadom/rev/226716/arch/Linux/installer/colladadom-2.2-linux-20110415.tar.bz2</string> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-colladadom/rev/233450/arch/Linux/installer/colladadom-2.2-linux-20110621.tar.bz2</string>              </map>              <key>name</key>              <string>linux</string> diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8c81f27784..bddb8d8c66 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -32,6 +32,7 @@  #if !LL_WINDOWS  #include <stdint.h>  #endif +#include <cmath>  #include "llerror.h"  #include "llmemtype.h" @@ -2379,11 +2380,16 @@ bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)co  bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const  {  	bool retval = false; -	if (rhs.mData[POSITION].equals3(mData[POSITION]) && rhs.mTexCoord == mTexCoord) + +	const F32 epsilon = 0.00001f; + +	if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) &&  +		fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && +		fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon)  	{  		if (angle_cutoff > 1.f)  		{ -			retval = (mData[NORMAL].equals3(rhs.mData[NORMAL])); +			retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon));  		}  		else  		{ @@ -2499,38 +2505,52 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			}  			{ -				U16* n = (U16*) &(norm[0]); -				for (U32 j = 0; j < num_verts; ++j) +				if (!norm.empty())  				{ -					norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); -					norm_out->div(65535.f); -					norm_out->mul(2.f); -					norm_out->sub(1.f); -					norm_out++; -					n += 3; +					U16* n = (U16*) &(norm[0]); +					for (U32 j = 0; j < num_verts; ++j) +					{ +						norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); +						norm_out->div(65535.f); +						norm_out->mul(2.f); +						norm_out->sub(1.f); +						norm_out++; +						n += 3; +					} +				} +				else +				{ +					memset(norm_out, 0, sizeof(LLVector4a)*num_verts);  				}  			}  			{ -				U16* t = (U16*) &(tc[0]); -				for (U32 j = 0; j < num_verts; j+=2) +				if (!tc.empty())  				{ -					if (j < num_verts-1) -					{ -						tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); -					} -					else +					U16* t = (U16*) &(tc[0]); +					for (U32 j = 0; j < num_verts; j+=2)  					{ -						tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); -					} +						if (j < num_verts-1) +						{ +							tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); +						} +						else +						{ +							tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); +						} -					t += 4; +						t += 4; -					tc_out->div(65535.f); -					tc_out->mul(tc_range); -					tc_out->add(min_tc4); +						tc_out->div(65535.f); +						tc_out->mul(tc_range); +						tc_out->add(min_tc4); -					tc_out++; +						tc_out++; +					} +				} +				else +				{ +					memset(tc_out, 0, sizeof(LLVector2)*num_verts);  				}  			} @@ -2656,6 +2676,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  					min.setMin(min, face.mPositions[i]);  					max.setMax(max, face.mPositions[i]);  				} + +				if (face.mTexCoords) +				{ +					LLVector2& min_tc = face.mTexCoordExtents[0]; +					LLVector2& max_tc = face.mTexCoordExtents[1]; + +					min_tc = face.mTexCoords[0]; +					max_tc = face.mTexCoords[0]; + +					for (U32 j = 1; j < face.mNumVertices; ++j) +					{ +						update_min_max(min_tc, max_tc, face.mTexCoords[j]); +					} +				} +				else +				{ +					face.mTexCoordExtents[0].set(0,0); +					face.mTexCoordExtents[1].set(1,1); +				}  			}  		}  	} @@ -2735,11 +2774,13 @@ void LLVolume::makeTetrahedron()  	n[2] = cv[2].getNormal();  	n += 3; -	tc[0] = cv[0].mTexCoord; -	tc[1] = cv[1].mTexCoord; -	tc[2] = cv[2].mTexCoord; -	tc += 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]); @@ -2758,11 +2799,14 @@ void LLVolume::makeTetrahedron()  	n[2] = cv[2].getNormal();  	n += 3; -	tc[0] = cv[0].mTexCoord; -	tc[1] = cv[1].mTexCoord; -	tc[2] = cv[2].mTexCoord; -	tc += 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]); @@ -2780,10 +2824,13 @@ void LLVolume::makeTetrahedron()  	n[2] = cv[2].getNormal();  	n += 3; -	tc[0] = cv[0].mTexCoord; -	tc[1] = cv[1].mTexCoord; -	tc[2] = cv[2].mTexCoord; -	tc += 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]); @@ -2802,10 +2849,13 @@ void LLVolume::makeTetrahedron()  	n[2] = cv[2].getNormal();  	n += 3; -	tc[0] = cv[0].mTexCoord; -	tc[1] = cv[1].mTexCoord; -	tc[2] = cv[2].mTexCoord; -	tc += 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++) @@ -5574,7 +5624,16 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  		LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size);  		LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); -		LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); + +		if(src.mTexCoords) +		{ +			LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); +		} +		else +		{ +			ll_aligned_free_16(mTexCoords) ; +			mTexCoords = NULL ; +		}  		if (src.mBinormals) @@ -5696,8 +5755,23 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)  void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv)  {  	cv.setPosition(mPositions[index]); -	cv.setNormal(mNormals[index]); -	cv.mTexCoord = mTexCoords[index]; +	if (mNormals) +	{ +		cv.setNormal(mNormals[index]); +	} +	else +	{ +		cv.getNormal().clear(); +	} + +	if (mTexCoords) +	{ +		cv.mTexCoord = mTexCoords[index]; +	} +	else +	{ +		cv.mTexCoord.clear(); +	}  }  bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const @@ -5727,7 +5801,10 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  	LLVolumeFace new_face;  	//map of points to vector of vertices at that point -	VertexMapData::PointMap point_map; +	std::map<U64, std::vector<VertexMapData> > point_map; + +	LLVector4a range; +	range.setSub(mExtents[1],mExtents[0]);  	//remove redundant vertices  	for (U32 i = 0; i < mNumIndices; ++i) @@ -5738,7 +5815,19 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  		getVertexData(index, cv);  		BOOL found = FALSE; -		VertexMapData::PointMap::iterator point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr())); + +		LLVector4a pos; +		pos.setSub(mPositions[index], mExtents[0]); +		pos.div(range); + +		U64 pos64 = 0; + +		pos64 = (U16) (pos[0]*65535); +		pos64 = pos64 | (((U64) (pos[1]*65535)) << 16); +		pos64 = pos64 | (((U64) (pos[2]*65535)) << 32); + +		std::map<U64, std::vector<VertexMapData> >::iterator point_iter = point_map.find(pos64); +		  		if (point_iter != point_map.end())  		{ //duplicate point might exist  			for (U32 j = 0; j < point_iter->second.size(); ++j) @@ -5770,11 +5859,26 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  			}  			else  			{ -				point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d); +				point_map[pos64].push_back(d);  			}  		}  	} +	llassert(new_face.mNumIndices == mNumIndices); +	llassert(new_face.mNumVertices <= mNumVertices); + +	if (angle_cutoff > 1.f && !mNormals) +	{ +		ll_aligned_free_16(new_face.mNormals); +		new_face.mNormals = NULL; +	} + +	if (!mTexCoords) +	{ +		ll_aligned_free_16(new_face.mTexCoords); +		new_face.mTexCoords = NULL; +	} +  	swapData(new_face);  } diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 7c8b7e3584..44330cf8ff 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -244,7 +244,7 @@ public:  	U32 report(CURLcode);  	void getTransferInfo(LLCurl::TransferInfo* info); -	void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, bool post = false); +	void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, S32 time_out = 0, bool post = false);  	const char* getErrorBuffer(); @@ -525,7 +525,7 @@ size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data  void LLCurl::Easy::prepRequest(const std::string& url,  							   const std::vector<std::string>& headers, -							   ResponderPtr responder, bool post) +							   ResponderPtr responder, S32 time_out, bool post)  {  	resetState(); @@ -558,7 +558,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,  	//don't verify host name so urls with scrubbed host names will work (improves DNS performance)  	setopt(CURLOPT_SSL_VERIFYHOST, 0); -	setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT); +	setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));  	setoptString(CURLOPT_URL, url); @@ -855,14 +855,14 @@ bool LLCurlRequest::getByteRange(const std::string& url,  bool LLCurlRequest::post(const std::string& url,  						 const headers_t& headers,  						 const LLSD& data, -						 LLCurl::ResponderPtr responder) +						 LLCurl::ResponderPtr responder, S32 time_out)  {  	LLCurl::Easy* easy = allocEasy();  	if (!easy)  	{  		return false;  	} -	easy->prepRequest(url, headers, responder); +	easy->prepRequest(url, headers, responder, time_out);  	LLSDSerialize::toXML(data, easy->getInput());  	S32 bytes = easy->getInput().str().length(); @@ -882,14 +882,14 @@ bool LLCurlRequest::post(const std::string& url,  bool LLCurlRequest::post(const std::string& url,  						 const headers_t& headers,  						 const std::string& data, -						 LLCurl::ResponderPtr responder) +						 LLCurl::ResponderPtr responder, S32 time_out)  {  	LLCurl::Easy* easy = allocEasy();  	if (!easy)  	{  		return false;  	} -	easy->prepRequest(url, headers, responder); +	easy->prepRequest(url, headers, responder, time_out);  	easy->getInput().write(data.data(), data.size());  	S32 bytes = easy->getInput().str().length(); diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 4ce3fa1078..5833a27b84 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -201,8 +201,8 @@ public:  	void get(const std::string& url, LLCurl::ResponderPtr responder);  	bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder); -	bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder); -	bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder); +	bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder, S32 time_out = 0); +	bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder, S32 time_out = 0);  	S32  process();  	S32  getQueued(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 0463d5364b..da78b30b34 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -27,6 +27,7 @@  #include "linden_common.h"  #include "llmodel.h" +#include "llmemory.h"  #include "llconvexdecomposition.h"  #include "llsdserialize.h"  #include "llvector4a.h" @@ -71,88 +72,10 @@ LLModel::~LLModel()  	}  } -void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Array& inputs, U32 min_idx, U32 max_idx) -{ -	for (U32 j = 0; j < inputs.getCount(); ++j) -	{ -		if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[j]->getSemantic()) == 0) -		{ //found vertex array -			const domURIFragmentType& uri = inputs[j]->getSource(); -			daeElementRef elem = uri.getElement(); -			domVertices* vertices = (domVertices*) elem.cast(); - -			domInputLocal_Array& v_inp = vertices->getInput_array(); -			if (inputs[j]->getOffset() != 0) -			{ -				llerrs << "Vertex array offset MUST be zero." << llendl; -			} - -			for (U32 k = 0; k < v_inp.getCount(); ++k) -			{ -				if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0) -				{ -					const domURIFragmentType& uri = v_inp[k]->getSource(); -					 -					daeElementRef elem = uri.getElement(); -					domSource* src = (domSource*) elem.cast(); - -					if (src->getTechnique_common()->getAccessor()->getStride() != 3) -					{ -						llerrs << "Vertex array stride MUST be three." << llendl; -					} - -					domListOfFloats& v = src->getFloat_array()->getValue(); - -					LLVector4a min; -					min.set(v[min_idx], v[min_idx+1], v[min_idx+2]); -					LLVector4a max = min; - -					for (U32 j = min_idx; j <= max_idx; ++j) -					{ //copy vertex array -						face.mPositions[j-min_idx].set(v[j*3+0], v[j*3+1], v[j*3+2]); -						update_min_max(min, max, face.mPositions[j-min_idx]); -					} - -					face.mExtents[0] = min; -					face.mExtents[1] = max; -				} -			} -		} - -		if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0) -		{ -			//found normal array for this triangle list -			const domURIFragmentType& uri = inputs[j]->getSource(); -			daeElementRef elem = uri.getElement(); -			domSource* src = (domSource*) elem.cast(); -			domListOfFloats& n = src->getFloat_array()->getValue(); -			 -			for (U32 j = min_idx; j <= max_idx; ++j) -			{ -				LLVector4a* norm = (LLVector4a*) face.mNormals + (j-min_idx); -				norm->set(n[j*3+0], n[j*3+1], n[j*3+2]); -				norm->normalize3(); -			} -		} -		else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0) -		{ //found texCoords -			const domURIFragmentType& uri = inputs[j]->getSource(); -			daeElementRef elem = uri.getElement(); -			domSource* src = (domSource*) elem.cast(); -			domListOfFloats& u = src->getFloat_array()->getValue(); -			 -			for (U32 j = min_idx; j <= max_idx; ++j) -			{ -				face.mTexCoords[j-min_idx].setVec(u[j*2+0], u[j*2+1]); -			} -		} -	} -}  bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,  					 domSource* &pos_source, domSource* &tc_source, domSource* &norm_source)  { -	  	idx_stride = 0;  	for (U32 j = 0; j < inputs.getCount(); ++j) @@ -271,14 +194,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  			cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0],  								tc[idx[i+tc_offset]*2+1]);  		} - +		  		if (norm_source)  		{  			cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0],  								n[idx[i+norm_offset]*3+1],  								n[idx[i+norm_offset]*3+2]));  		} -  		BOOL found = FALSE; @@ -329,10 +251,22 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  		{  			face_list.push_back(face);  			face_list.rbegin()->fillFromLegacyData(verts, indices); +			LLVolumeFace& new_face = *face_list.rbegin(); +			if (!norm_source) +			{ +				ll_aligned_free_16(new_face.mNormals); +				new_face.mNormals = NULL; +			} + +			if (!tc_source) +			{ +				ll_aligned_free_16(new_face.mTexCoords); +				new_face.mTexCoords = NULL; +			} +  			face = LLVolumeFace();  			point_map.clear();  		} -  	}  	if (!verts.empty()) @@ -348,6 +282,18 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  		face_list.push_back(face);  		face_list.rbegin()->fillFromLegacyData(verts, indices); +		LLVolumeFace& new_face = *face_list.rbegin(); +		if (!norm_source) +		{ +			ll_aligned_free_16(new_face.mNormals); +			new_face.mNormals = NULL; +		} + +		if (!tc_source) +		{ +			ll_aligned_free_16(new_face.mTexCoords); +			new_face.mTexCoords = NULL; +		}  	}  	return LLModel::NO_ERRORS ; @@ -433,14 +379,14 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  				cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0],  									tc[idx[cur_idx+tc_offset]*2+1]);  			} - +			  			if (norm_source)  			{  				cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0],  									n[idx[cur_idx+norm_offset]*3+1],  									n[idx[cur_idx+norm_offset]*3+2]);  			} - +			  			cur_idx += idx_stride;  			BOOL found = FALSE; @@ -524,6 +470,19 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  			{  				face_list.push_back(face);  				face_list.rbegin()->fillFromLegacyData(verts, indices); +				LLVolumeFace& new_face = *face_list.rbegin(); +				if (!norm_source) +				{ +					ll_aligned_free_16(new_face.mNormals); +					new_face.mNormals = NULL; +				} + +				if (!tc_source) +				{ +					ll_aligned_free_16(new_face.mTexCoords); +					new_face.mTexCoords = NULL; +				} +  				face = LLVolumeFace();  				verts.clear();  				indices.clear(); @@ -540,10 +499,23 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  		{  			material = std::string(poly->getMaterial());  		} -		 +	  		materials.push_back(material);  		face_list.push_back(face);  		face_list.rbegin()->fillFromLegacyData(verts, indices); + +		LLVolumeFace& new_face = *face_list.rbegin(); +		if (!norm_source) +		{ +			ll_aligned_free_16(new_face.mNormals); +			new_face.mNormals = NULL; +		} + +		if (!tc_source) +		{ +			ll_aligned_free_16(new_face.mTexCoords); +			new_face.mTexCoords = NULL; +		}  	}  	return LLModel::NO_ERRORS ; @@ -557,7 +529,6 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  	const domInputLocalOffset_Array& inputs = poly->getInput_array(); -  	S32 v_offset = -1;  	S32 n_offset = -1;  	S32 t_offset = -1; @@ -662,15 +633,14 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  								n->get(n_idx+1),  								n->get(n_idx+2));  			} - +			  			if (t)  			{  				U32 t_idx = idx[j*stride+t_offset]*2;  				vert.mTexCoord.setVec(t->get(t_idx),  								t->get(t_idx+1));								  			} -		 -			 +						  			verts.push_back(vert);  		}  	} @@ -733,6 +703,19 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  		materials.push_back(material);  		face_list.push_back(face);  		face_list.rbegin()->fillFromLegacyData(new_verts, indices); + +		LLVolumeFace& new_face = *face_list.rbegin(); +		if (!n) +		{ +			ll_aligned_free_16(new_face.mNormals); +			new_face.mNormals = NULL; +		} + +		if (!t) +		{ +			ll_aligned_free_16(new_face.mTexCoords); +			new_face.mTexCoords = NULL; +		}  	}  	return LLModel::NO_ERRORS ; @@ -817,9 +800,9 @@ BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh)  		if (getNumVolumeFaces() > 0)  		{ -			optimizeVolumeFaces();  			normalizeVolumeFaces(); - +			optimizeVolumeFaces(); +			  			if (getNumVolumeFaces() > 0)  			{  				return TRUE; @@ -853,81 +836,10 @@ void LLModel::offsetMesh( const LLVector3& pivotPoint )  void LLModel::optimizeVolumeFaces()  { -#if 0 //VECTORIZE ? -	for (std::vector<LLVolumeFace>::iterator iter = mVolumeFaces.begin(); iter != mVolumeFaces.end(); ) -	{ -		std::vector<LLVolumeFace>::iterator cur_iter = iter++; -		LLVolumeFace& face = *cur_iter; - -		for (S32 i = 0; i < (S32) face.mNumIndices; i += 3) -		{ //remove zero area triangles -			U16 i0 = face.mIndices[i+0]; -			U16 i1 = face.mIndices[i+1]; -			U16 i2 = face.mIndices[i+2]; - -			if (i0 == i1 ||  -				i1 == i2 ||  -				i0 == i2) -			{ //duplicate index in triangle, remove triangle -				face.mIndices.erase(face.mIndices.begin()+i, face.mIndices.begin()+i+3); -				i -= 3; -			} -			else -			{  -				LLVolumeFace::VertexData& v0 = face.mVertices[i0]; -				LLVolumeFace::VertexData& v1 = face.mVertices[i1]; -				LLVolumeFace::VertexData& v2 = face.mVertices[i2]; - -				if (v0.mPosition == v1.mPosition || -					v1.mPosition == v2.mPosition || -					v2.mPosition == v0.mPosition) -				{ //zero area triangle, delete -					face.mIndices.erase(face.mIndices.begin()+i, face.mIndices.begin()+i+3); -					i-=3; -				} -			} -		} - -		//remove unreference vertices -		std::vector<bool> ref; -		ref.resize(face.mNumVertices); - -		for (U32 i = 0; i < ref.size(); ++i) -		{ -			ref[i] = false; -		} - -		for (U32 i = 0; i < face.mNumIndices; ++i) -		{  -			ref[face.mIndices[i]] = true; -		} - -		U32 unref_count = 0; -		for (U32 i = 0; i < ref.size(); ++i) -		{ -			if (!ref[i]) -			{ -				//vertex is unreferenced -				face.mVertices.erase(face.mVertices.begin()+(i-unref_count)); -				U16 idx = (U16) (i-unref_count); - -				for (U32 j = 0; j < face.mNumIndices; ++j) -				{ //decrement every index array value greater than idx -					if (face.mIndices[j] > idx) -					{ -						--face.mIndices[j]; -					} -				} -				++unref_count; -			} -		} - -		if (face.mVertices.empty() || face.mIndices.empty()) -		{ //face is empty, remove it -			iter = mVolumeFaces.erase(cur_iter); -		} +	for (U32 i = 0; i < getNumVolumeFaces(); ++i) +	{ +		mVolumeFaces[i].optimize();  	} -#endif  }  // Shrink the model to fit @@ -962,6 +874,25 @@ void LLModel::normalizeVolumeFaces()  			update_min_max(min, max, face.mExtents[0]);  			update_min_max(min, max, face.mExtents[1]); + +			if (face.mTexCoords) +			{ +				LLVector2& min_tc = face.mTexCoordExtents[0]; +				LLVector2& max_tc = face.mTexCoordExtents[1]; + +				min_tc = face.mTexCoords[0]; +				max_tc = face.mTexCoords[0]; + +				for (U32 j = 1; j < face.mNumVertices; ++j) +				{ +					update_min_max(min_tc, max_tc, face.mTexCoords[j]); +				} +			} +			else +			{ +				face.mTexCoordExtents[0].set(0,0); +				face.mTexCoordExtents[1].set(1,1); +			}  		}  		// Now that we have the extents of the model @@ -1029,8 +960,11 @@ void LLModel::normalizeVolumeFaces()  			{  			 	pos[j].add(trans);  				pos[j].mul(scale); -				norm[j].mul(inv_scale); -				norm[j].normalize3(); +				if (norm && !norm[j].equals3(LLVector4a::getZero())) +				{ +					norm[j].mul(inv_scale); +					norm[j].normalize3(); +				}  			}  		} @@ -1073,8 +1007,26 @@ void LLModel::setVolumeFaceData(  	face.resizeIndices(num_indices);  	LLVector4a::memcpyNonAliased16((F32*) face.mPositions, (F32*) pos.get(), num_verts*4*sizeof(F32)); -	LLVector4a::memcpyNonAliased16((F32*) face.mNormals, (F32*) norm.get(), num_verts*4*sizeof(F32)); -	LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32)); +	if (norm.get()) +	{ +		LLVector4a::memcpyNonAliased16((F32*) face.mNormals, (F32*) norm.get(), num_verts*4*sizeof(F32)); +	} +	else +	{ +		ll_aligned_free_16(face.mNormals); +		face.mNormals = NULL; +	} + +	if (tc.get()) +	{ +		LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32)); +	} +	else +	{ +		ll_aligned_free_16(face.mTexCoords); +		face.mTexCoords = NULL; +	} +  	U32 size = (num_indices*2+0xF)&~0xF;  	LLVector4a::memcpyNonAliased16((F32*) face.mIndices, (F32*) ind.get(), size);  } @@ -1462,13 +1414,19 @@ LLSD LLModel::writeModel(  				U32 tc_idx = 0;  				LLVector2* ftc = (LLVector2*) face.mTexCoords; -				LLVector2 min_tc = ftc[0]; -				LLVector2 max_tc = min_tc; -	 -				//get texture coordinate domain -				for (U32 j = 0; j < face.mNumVertices; ++j) +				LLVector2 min_tc; +				LLVector2 max_tc; + +				if (ftc)  				{ -					update_min_max(min_tc, max_tc, ftc[j]); +					min_tc = ftc[0]; +					max_tc = min_tc; +					 +					//get texture coordinate domain +					for (U32 j = 0; j < face.mNumVertices; ++j) +					{ +						update_min_max(min_tc, max_tc, ftc[j]); +					}  				}  				LLVector2 tc_range = max_tc - min_tc; @@ -1477,9 +1435,8 @@ LLSD LLModel::writeModel(  				{ //for each vert  					F32* pos = face.mPositions[j].getF32ptr(); -					F32* norm = face.mNormals[j].getF32ptr(); - -					//position + normal +										 +					//position  					for (U32 k = 0; k < 3; ++k)  					{ //for each component  						//convert to 16-bit normalized across domain @@ -1489,29 +1446,40 @@ LLSD LLModel::writeModel(  						//write to binary buffer  						verts[vert_idx++] = buff[0];  						verts[vert_idx++] = buff[1]; -						 -						//convert to 16-bit normalized -						val = (U16) ((norm[k]+1.f)*0.5f*65535); - -						//write to binary buffer -						normals[norm_idx++] = buff[0]; -						normals[norm_idx++] = buff[1];  					} -					F32* src_tc = (F32*) face.mTexCoords[j].mV; +					if (face.mNormals) +					{ //normals +						F32* norm = face.mNormals[j].getF32ptr(); -					//texcoord -					for (U32 k = 0; k < 2; ++k) -					{ //for each component -						//convert to 16-bit normalized -						U16 val = (U16) ((src_tc[k]-min_tc.mV[k])/tc_range.mV[k]*65535); +						for (U32 k = 0; k < 3; ++k) +						{ //for each component +							//convert to 16-bit normalized +							U16 val = (U16) ((norm[k]+1.f)*0.5f*65535); +							U8* buff = (U8*) &val; -						U8* buff = (U8*) &val; -						//write to binary buffer -						tc[tc_idx++] = buff[0]; -						tc[tc_idx++] = buff[1]; +							//write to binary buffer +							normals[norm_idx++] = buff[0]; +							normals[norm_idx++] = buff[1]; +						}  					} +					F32* src_tc = (F32*) face.mTexCoords[j].mV; + +					//texcoord +					if (face.mTexCoords) +					{ +						for (U32 k = 0; k < 2; ++k) +						{ //for each component +							//convert to 16-bit normalized +							U16 val = (U16) ((src_tc[k]-min_tc.mV[k])/tc_range.mV[k]*65535); + +							U8* buff = (U8*) &val; +							//write to binary buffer +							tc[tc_idx++] = buff[0]; +							tc[tc_idx++] = buff[1]; +						} +					}  				}  				U32 idx_idx = 0; @@ -1525,12 +1493,20 @@ LLSD LLModel::writeModel(  				//write out face data  				mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue();  				mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); -				mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); -				mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue(); -  				mdl[model_names[idx]][i]["Position"] = verts; -				mdl[model_names[idx]][i]["Normal"] = normals; -				mdl[model_names[idx]][i]["TexCoord0"] = tc; +				 +				if (face.mNormals) +				{ +					mdl[model_names[idx]][i]["Normal"] = normals; +				} + +				if (face.mTexCoords) +				{ +					mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); +					mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue(); +					mdl[model_names[idx]][i]["TexCoord0"] = tc; +				} +  				mdl[model_names[idx]][i]["TriangleList"] = indices;  				if (skinning) @@ -1808,6 +1784,7 @@ bool LLModel::loadModel(std::istream& is)  	if (header[nm[lod]]["offset"].asInteger() == -1 ||   		header[nm[lod]]["size"].asInteger() == 0 )  	{ //cannot load requested LOD +		llwarns << "LoD data is invalid!" << llendl;  		return false;  	} @@ -1821,7 +1798,7 @@ bool LLModel::loadModel(std::istream& is)  		is.seekg(cur_pos);  	} -	if (lod == LLModel::LOD_PHYSICS) +	if (lod == LLModel::LOD_HIGH || lod == LLModel::LOD_PHYSICS)  	{  		std::ios::pos_type cur_pos = is.tellg();  		loadDecomposition(header, is); @@ -1868,6 +1845,10 @@ bool LLModel::loadModel(std::istream& is)  		}  		return true;  	} +	else +	{ +		llwarns << "unpackVolumeFaces failed!" << llendl; +	}  	return false; @@ -2034,7 +2015,7 @@ LLModel::Decomposition::Decomposition(LLSD& data)  void LLModel::Decomposition::fromLLSD(LLSD& decomp)  { -	if (decomp.has("HullList")) +	if (decomp.has("HullList") && decomp.has("Positions"))  	{  		// updated for const-correctness. gcc is picky about this type of thing - Nyx  		const LLSD::Binary& hulls = decomp["HullList"].asBinary(); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4a0b964e61..d5a7159ee3 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -240,7 +240,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)  {  	U32 count = pos.size(); -	llassert(norm.size() >= pos.size()); +	llassert_always(norm.size() >= pos.size()); +	llassert_always(count > 0) ;  	unbind(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 594285b92b..b520650978 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5587,7 +5587,7 @@      <key>Type</key>      <string>Boolean</string>      <key>Value</key> -    <real>0</real> +    <real>1</real>    </map>    <key>MeshUploadLogXML</key>    <map> @@ -5611,6 +5611,17 @@      <key>Value</key>      <real>0</real>    </map> +  <key>MeshUploadTimeOut</key> +  <map> +    <key>Comment</key> +    <string>Maximum time in seconds for llcurl to execute a mesh uoloading request</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>S32</string> +    <key>Value</key> +    <real>600</real> +  </map>    <key>MigrateCacheDirectory</key>      <map>        <key>Comment</key> @@ -9134,28 +9145,51 @@        <key>Value</key>        <real>1.0</real>      </map> -  <key>MeshStreamingCostScaler</key> +  <key>MeshTriangleBudget</key>    <map>      <key>Comment</key> -    <string>DEBUG</string> +    <string>Target visible triangle budget to use when estimating streaming cost.</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> -    <string>F32</string> +    <string>U32</string>      <key>Value</key> -    <real>2.0</real> +    <real>250000</real>    </map> -  <key>MeshThreadCount</key> +  <key>MeshMetaDataDiscount</key>    <map>      <key>Comment</key> -    <string>Number of threads to use for loading meshes.</string> +    <string>Number of bytes to deduct for metadata when determining streaming cost.</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key>      <string>U32</string>      <key>Value</key> -    <integer>8</integer> +    <real>384</real>    </map> +  <key>MeshMinimumByteSize</key> +  <map> +    <key>Comment</key> +    <string>Minimum number of bytes per LoD block when determining streaming cost.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <real>16</real> +  </map> +  <key>MeshBytesPerTriangle</key> +  <map> +    <key>Comment</key> +    <string>Approximation of bytes per triangle to use for determining mesh streaming cost.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <real>16</real> +  </map> +    <key>MeshMaxConcurrentRequests</key>    <map>      <key>Comment</key> @@ -9387,6 +9421,17 @@        <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/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index c30d3b9aa3..f195c985c0 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -393,8 +393,6 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi  	LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation  	LLVector3 object_extents = object->getScale();	 -	const LLVector4a* oe4 = object->mDrawable->getSpatialExtents(); -	object_extents.set( oe4[1][0], oe4[1][1], oe4[1][2] );  	// make sure they object extents are non-zero  	object_extents.clamp(0.001f, F32_MAX); diff --git a/indra/newview/llfloaterbuildoptions.cpp b/indra/newview/llfloaterbuildoptions.cpp index 4b6fe4a115..86c1bf0534 100644 --- a/indra/newview/llfloaterbuildoptions.cpp +++ b/indra/newview/llfloaterbuildoptions.cpp @@ -34,15 +34,81 @@  #include "llfloaterbuildoptions.h"  #include "lluictrlfactory.h" +#include "llcombobox.h" +#include "llselectmgr.h" +  //  // Methods  // + +void commit_grid_mode(LLUICtrl *); +  LLFloaterBuildOptions::LLFloaterBuildOptions(const LLSD& key) -  : LLFloater(key) +  : LLFloater(key), +    mComboGridMode(NULL)  { +	mCommitCallbackRegistrar.add("GridOptions.gridMode", boost::bind(&commit_grid_mode,_1));  }  LLFloaterBuildOptions::~LLFloaterBuildOptions() +{} + +BOOL LLFloaterBuildOptions::postBuild() +{ +	mComboGridMode = getChild<LLComboBox>("combobox grid mode"); + +	return TRUE; +} + +void LLFloaterBuildOptions::setGridMode(EGridMode mode) +{ +	mComboGridMode->setCurrentByIndex((S32)mode); +} + +void LLFloaterBuildOptions::updateGridMode()  { +	if (mComboGridMode) +	{ +		S32 index = mComboGridMode->getCurrentIndex(); +		mComboGridMode->removeall(); + +		switch (mObjectSelection->getSelectType()) +		{ +		case SELECT_TYPE_HUD: +		  mComboGridMode->add(getString("grid_screen_text")); +		  mComboGridMode->add(getString("grid_local_text")); +		  break; +		case SELECT_TYPE_WORLD: +		  mComboGridMode->add(getString("grid_world_text")); +		  mComboGridMode->add(getString("grid_local_text")); +		  mComboGridMode->add(getString("grid_reference_text")); +		  break; +		case SELECT_TYPE_ATTACHMENT: +		  mComboGridMode->add(getString("grid_attachment_text")); +		  mComboGridMode->add(getString("grid_local_text")); +		  mComboGridMode->add(getString("grid_reference_text")); +		  break; +		} + +		mComboGridMode->setCurrentByIndex(index); +	} +} + +// virtual +void LLFloaterBuildOptions::onOpen(const LLSD& key) +{ +	mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();  } +// virtual +void LLFloaterBuildOptions::onClose(bool app_quitting) +{ +	mObjectSelection = NULL; +} + +void commit_grid_mode(LLUICtrl *ctrl) +{ +	LLComboBox* combo = (LLComboBox*)ctrl; + +	LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex()); +} diff --git a/indra/newview/llfloaterbuildoptions.h b/indra/newview/llfloaterbuildoptions.h index 164944d7bc..7f3811bf1c 100644 --- a/indra/newview/llfloaterbuildoptions.h +++ b/indra/newview/llfloaterbuildoptions.h @@ -33,15 +33,34 @@  #define LL_LLFLOATERBUILDOPTIONS_H  #include "llfloater.h" +#include "llselectmgr.h" +class LLComboBox; +class LLObjectSelection; + +typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle;  class LLFloaterBuildOptions  	:	public LLFloater  { -	friend class LLFloaterReg; +public: + +	virtual BOOL postBuild(); + +	/*virtual*/ void onOpen(const LLSD& key); +	/*virtual*/	void onClose(bool app_quitting); + +	void setGridMode(EGridMode mode); +	void updateGridMode(); +  private: + +	friend class LLFloaterReg; +  	LLFloaterBuildOptions(const LLSD& key);  	~LLFloaterBuildOptions(); -}; +	LLComboBox*	mComboGridMode; +	LLObjectSelectionHandle	mObjectSelection; +};  #endif diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ab6753b4be..67841620ea 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1968,10 +1968,6 @@ bool LLModelLoader::loadFromSLM(const std::string& filename)  					mPreview->critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames );					  				}  			} -			else -			{ -				llassert(model[lod].empty()); -			}  		}  	}	 @@ -1980,6 +1976,12 @@ bool LLModelLoader::loadFromSLM(const std::string& filename)  		return false;  	} +	if (model[LLModel::LOD_PHYSICS].empty()) +	{ //no explicit physics block, copy HIGH_LOD into physics array to recover convex decomp +		model[LLModel::LOD_PHYSICS] = model[LLModel::LOD_HIGH]; +	} + +  	//load instance list  	model_instance_list instance_list; @@ -3107,18 +3109,20 @@ void LLModelPreview::rebuildUploadData()  				}  			} -			for (U32 i = 0; i < LLModel::NUM_LODS; i++) -			{ //fill LOD slots based on reference model index -				if (!mModel[i].empty()) -				{ -					instance.mLOD[i] = mModel[i][idx]; -				} -				else -				{ -					instance.mLOD[i] = NULL; +			if(idx < mBaseModel.size()) +			{ +				for (U32 i = 0; i < LLModel::NUM_LODS; i++) +				{ //fill LOD slots based on reference model index +					if (mModel[i].size() > idx) +					{ +						instance.mLOD[i] = mModel[i][idx]; +					} +					else +					{ +						instance.mLOD[i] = NULL; +					}  				}  			} -  			instance.mTransform = mat;  			mUploadData.push_back(instance);  		} @@ -3734,7 +3738,9 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  			U32 tri_count = 0;  			for (U32 i = 0; i < mVertexBuffer[5][mdl].size(); ++i)  			{ -				mVertexBuffer[5][mdl][i]->setBuffer(type_mask); +				LLVertexBuffer* buff = mVertexBuffer[5][mdl][i]; +				buff->setBuffer(type_mask & buff->getTypeMask()); +				  				U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices();  				if (num_indices > 2)  				{ @@ -3856,6 +3862,8 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  			for (GLint i = 0; i < patch_count; ++i)  			{ +				type_mask = mVertexBuffer[5][base][i]->getTypeMask(); +  				LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);  				if (sizes[i*2+1] > 0 && sizes[i*2] > 0) @@ -3880,8 +3888,15 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  				LLStrider<U16> index;  				buff->getVertexStrider(pos); -				buff->getNormalStrider(norm); -				buff->getTexCoord0Strider(tc); +				if (type_mask & LLVertexBuffer::MAP_NORMAL) +				{ +					buff->getNormalStrider(norm); +				} +				if (type_mask & LLVertexBuffer::MAP_TEXCOORD0) +				{ +					buff->getTexCoord0Strider(tc); +				} +  				buff->getIndexStrider(index);  				target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices()); @@ -4087,18 +4102,20 @@ void LLModelPreview::updateStatusMessages()  			}  			else if (!verts[lod].empty())  			{ +				S32 sum_verts_higher_lod = 0; +				S32 sum_verts_this_lod = 0;  				for (U32 i = 0; i < verts[lod].size(); ++i)  				{ -					S32 max_verts = i < verts[lod+1].size() ? verts[lod+1][i] : 0; +					sum_verts_higher_lod += ((i < verts[lod+1].size()) ? verts[lod+1][i] : 0); +					sum_verts_this_lod += verts[lod][i]; +				} -					if (max_verts > 0) -					{ -						if (verts[lod][i] > max_verts) -						{ //too many vertices in this lod -							message = "mesh_status_too_many_vertices"; -							upload_status[lod] = 2; -						} -					} +				if ((sum_verts_higher_lod > 0) && +					(sum_verts_this_lod > sum_verts_higher_lod)) +				{ +					//too many vertices in this lod +					message = "mesh_status_too_many_vertices"; +					upload_status[lod] = 2;  				}  			}  		} @@ -4485,7 +4502,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  			bool skinned = include_skin_weights && !mdl->mSkinWeights.empty(); -			U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; +			U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0 ;  			if (skinned)  			{ @@ -4503,8 +4520,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  			LLStrider<LLVector4> weights_strider;  			vb->getVertexStrider(vertex_strider); -			vb->getNormalStrider(normal_strider); -			vb->getTexCoord0Strider(tc_strider);  			vb->getIndexStrider(index_strider);  			if (skinned) @@ -4513,8 +4528,18 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  			}  			LLVector4a::memcpyNonAliased16((F32*) vertex_strider.get(), (F32*) vf.mPositions, num_vertices*4*sizeof(F32)); -			LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); -			LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); +			 +			if (vf.mTexCoords) +			{ +				vb->getTexCoord0Strider(tc_strider); +				LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); +			} +			 +			if (vf.mNormals) +			{ +				vb->getNormalStrider(normal_strider); +				LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); +			}  			if (skinned)  			{ @@ -4773,6 +4798,8 @@ BOOL LLModelPreview::render()  	const F32 BRIGHTNESS = 0.9f;  	gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); +	const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; +  	LLGLEnable normalize(GL_NORMALIZE);  	if (!mBaseModel.empty() && mVertexBuffer[5].empty()) @@ -4821,8 +4848,8 @@ BOOL LLModelPreview::render()  				for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i)  				{  					LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; - -					buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); +				 +					buffer->setBuffer(type_mask & buffer->getTypeMask());  					if (textures)  					{ @@ -4941,7 +4968,7 @@ BOOL LLModelPreview::render()  						{  							LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; -							buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); +							buffer->setBuffer(type_mask & buffer->getTypeMask());  							buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);  							gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -5007,7 +5034,7 @@ BOOL LLModelPreview::render()  							{  								LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; -								buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); +								buffer->setBuffer(type_mask & buffer->getTypeMask());  								LLStrider<LLVector3> pos_strider;   								buffer->getVertexStrider(pos_strider, 0); @@ -5132,7 +5159,7 @@ BOOL LLModelPreview::render()  								position[j] = v;  							} -							buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); +							buffer->setBuffer(type_mask & buffer->getTypeMask());  							glColor4fv(instance.mMaterial[i].mDiffuseColor.mV);  							gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  							buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 33b7777d2e..dc71ade621 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -36,7 +36,6 @@  #include "llagentcamera.h"  #include "llbutton.h"  #include "llcheckboxctrl.h" -#include "llcombobox.h"  #include "lldraghandle.h"  #include "llerror.h"  #include "llfloaterbuildoptions.h" @@ -101,6 +100,7 @@ const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =  	std::string("Content"),	// PANEL_CONTENTS,  }; +  // Local prototypes  void commit_select_component(void *data);  void click_show_more(void*); @@ -116,7 +116,6 @@ void commit_radio_group_focus(LLUICtrl* ctrl);  void commit_radio_group_move(LLUICtrl* ctrl);  void commit_radio_group_edit(LLUICtrl* ctrl);  void commit_radio_group_land(LLUICtrl* ctrl); -void commit_grid_mode(LLUICtrl *);  void commit_slider_zoom(LLUICtrl *ctrl); @@ -234,7 +233,6 @@ BOOL	LLFloaterTools::postBuild()  	getChild<LLUICtrl>("checkbox uniform")->setValue((BOOL)gSavedSettings.getBOOL("ScaleUniform"));  	mCheckStretchTexture	= getChild<LLCheckBoxCtrl>("checkbox stretch textures");  	getChild<LLUICtrl>("checkbox stretch textures")->setValue((BOOL)gSavedSettings.getBOOL("ScaleStretchTextures")); -	mComboGridMode			= getChild<LLComboBox>("combobox grid mode");  	mCheckStretchUniformLabel = getChild<LLTextBox>("checkbox uniform label");  	// @@ -269,6 +267,8 @@ BOOL	LLFloaterTools::postBuild()  	// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here  	getChild<LLUICtrl>("slider force")->setValue(log10(gSavedSettings.getF32("LandBrushForce"))); +	mCostTextBorder = getChild<LLViewBorder>("cost_text_border"); +  	mTab = getChild<LLTabContainer>("Object Info Tabs");  	if(mTab)  	{ @@ -311,7 +311,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)  	mCheckSnapToGrid(NULL),  	mBtnGridOptions(NULL),  	mTitleMedia(NULL), -	mComboGridMode(NULL),  	mCheckStretchUniform(NULL),  	mCheckStretchTexture(NULL),  	mCheckStretchUniformLabel(NULL), @@ -344,6 +343,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)  	mPanelFace(NULL),  	mPanelLandInfo(NULL), +	mCostTextBorder(NULL),  	mTabLand(NULL),  	mDirty(TRUE),  	mNeedMediaTitle(TRUE) @@ -367,7 +367,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)  	mCommitCallbackRegistrar.add("BuildTool.selectComponent",	boost::bind(&commit_select_component, this));  	mCommitCallbackRegistrar.add("BuildTool.gridOptions",		boost::bind(&LLFloaterTools::onClickGridOptions,this));  	mCommitCallbackRegistrar.add("BuildTool.applyToSelection",	boost::bind(&click_apply_to_selection, this)); -	mCommitCallbackRegistrar.add("BuildTool.gridMode",			boost::bind(&commit_grid_mode,_1));  	mCommitCallbackRegistrar.add("BuildTool.commitRadioLand",	boost::bind(&commit_radio_group_land,_1));  	mCommitCallbackRegistrar.add("BuildTool.LandBrushForce",	boost::bind(&commit_slider_dozer_force,_1));  	mCommitCallbackRegistrar.add("BuildTool.AddMedia",			boost::bind(&LLFloaterTools::onClickBtnAddMedia,this)); @@ -428,10 +427,10 @@ void LLFloaterTools::refresh()  	{		  		std::string obj_count_string;  		LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); -		getChild<LLUICtrl>("obj_count")->setTextArg("[COUNT]", obj_count_string);	 +		getChild<LLUICtrl>("selection_count")->setTextArg("[OBJ_COUNT]", obj_count_string);  		std::string prim_count_string;  		LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); -		getChild<LLUICtrl>("prim_count")->setTextArg("[COUNT]", prim_count_string); +		getChild<LLUICtrl>("selection_count")->setTextArg("[PRIM_COUNT]", prim_count_string);  		// calculate selection rendering cost  		if (sShowObjectCost) @@ -449,55 +448,50 @@ void LLFloaterTools::refresh()  	}  	else  	{ -		// Get the number of objects selected -		std::string root_object_count_string; -		std::string object_count_string; - -		LLResMgr::getInstance()->getIntegerString( -			root_object_count_string, -			LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); -		LLResMgr::getInstance()->getIntegerString( -			object_count_string, -			LLSelectMgr::getInstance()->getSelection()->getObjectCount()); - -		F32 obj_cost = -			LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost(); -		F32 link_cost = -			LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost(); -		F32 obj_physics_cost = -			LLSelectMgr::getInstance()->getSelection()->getSelectedPhysicsCost(); -		F32 link_physics_cost = -			LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetPhysicsCost(); - -		// Update the text for the counts -		childSetTextArg( -			"linked_set_count", -			"[COUNT]", -			root_object_count_string); -		childSetTextArg("object_count", "[COUNT]", object_count_string); - -		// Update the text for the resource costs -		childSetTextArg("linked_set_cost","[COST]",llformat("%.1f", link_cost)); -		childSetTextArg("object_cost", "[COST]", llformat("%.1f", obj_cost)); -		childSetTextArg("linked_set_cost","[PHYSICS]",llformat("%.1f", link_physics_cost)); -		childSetTextArg("object_cost", "[PHYSICS]", llformat("%.1f", obj_physics_cost)); - -		// Display rendering cost if needed -		if (sShowObjectCost) +		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)  		{ -			std::string prim_cost_string; -			LLResMgr::getInstance()->getIntegerString(prim_cost_string, calcRenderCost()); -			getChild<LLUICtrl>("RenderingCost")->setTextArg("[COUNT]", prim_cost_string); +			LLStringUtil::format_map_t prim_equiv_args; +			prim_equiv_args["SEL_WEIGHT"] = llformat("%.1d", (S32)link_cost); +			selection_args["PE_STRING"] = getString("status_selectprimequiv", prim_equiv_args); +		} +		else +		{ +			selection_args["PE_STRING"] = "";  		} +		selection_info << getString("status_selectcount", selection_args); -		// disable the object and prim counts if nothing selected -		bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty(); -		childSetEnabled("linked_set_count", have_selection); -		childSetEnabled("object_count", have_selection); -		childSetEnabled("linked_set_cost", have_selection); -		childSetEnabled("object_cost", have_selection); -		getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost); +		if (show_adv_weight) +		{ +			selection_info << ","; + +			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("selection_empty", !have_selection);  	} @@ -662,33 +656,6 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)  		mRadioGroupEdit->setValue("radio select face");  	} -	if (mComboGridMode)  -	{ -		mComboGridMode->setVisible( edit_visible ); -		S32 index = mComboGridMode->getCurrentIndex(); -		mComboGridMode->removeall(); - -		switch (mObjectSelection->getSelectType()) -		{ -		case SELECT_TYPE_HUD: -		  mComboGridMode->add(getString("grid_screen_text")); -		  mComboGridMode->add(getString("grid_local_text")); -		  //mComboGridMode->add(getString("grid_reference_text")); -		  break; -		case SELECT_TYPE_WORLD: -		  mComboGridMode->add(getString("grid_world_text")); -		  mComboGridMode->add(getString("grid_local_text")); -		  mComboGridMode->add(getString("grid_reference_text")); -		  break; -		case SELECT_TYPE_ATTACHMENT: -		  mComboGridMode->add(getString("grid_attachment_text")); -		  mComboGridMode->add(getString("grid_local_text")); -		  mComboGridMode->add(getString("grid_reference_text")); -		  break; -		} - -		mComboGridMode->setCurrentByIndex(index); -	}  	// Snap to grid disabled for grab tool - very confusing  	if (mCheckSnapToGrid) mCheckSnapToGrid->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ );  	if (mBtnGridOptions) mBtnGridOptions->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ ); @@ -737,6 +704,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)  	// Land buttons  	BOOL land_visible = (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance() ); +	mCostTextBorder->setVisible(!land_visible); +  	if (mBtnLand)	mBtnLand	->setToggleState( land_visible );  	mRadioGroupLand->setVisible( land_visible ); @@ -789,15 +758,11 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)  		getChildView("Strength:")->setVisible( land_visible);  	} -	bool show_mesh_cost = gMeshRepo.meshRezEnabled(); +	bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); -	getChildView("obj_count")->setVisible( !land_visible && !show_mesh_cost); -	getChildView("prim_count")->setVisible( !land_visible && !show_mesh_cost); -	getChildView("linked_set_count")->setVisible( !land_visible && show_mesh_cost); -	getChildView("linked_set_cost")->setVisible( !land_visible && show_mesh_cost); -	getChildView("object_count")->setVisible( !land_visible && show_mesh_cost); -	getChildView("object_cost")->setVisible( !land_visible && show_mesh_cost); -	getChildView("RenderingCost")->setVisible( !land_visible && sShowObjectCost); +	getChildView("selection_count")->setVisible(!land_visible && have_selection); +	getChildView("selection_weight")->setVisible(!land_visible && have_selection && gSavedSettings.getBOOL("ShowAdvancedBuilderOptions")); +	getChildView("selection_empty")->setVisible(!land_visible && !have_selection);  	mTab->setVisible(!land_visible);  	mPanelLandInfo->setVisible(land_visible); @@ -1030,13 +995,6 @@ void commit_select_component(void *data)  	}  } -void commit_grid_mode(LLUICtrl *ctrl)    -{    -	LLComboBox* combo = (LLComboBox*)ctrl;    -     -	LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex()); -}  -  // static   void LLFloaterTools::setObjectType( LLPCode pcode )  { diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index fd81a75397..69636190fc 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -32,7 +32,6 @@  #include "llparcelselection.h"  class LLButton; -class LLComboBox;  class LLCheckBoxCtrl;  class LLPanelPermissions;  class LLPanelObject; @@ -140,7 +139,6 @@ public:  	LLCheckBoxCtrl*	mCheckSnapToGrid;  	LLButton*		mBtnGridOptions; -	LLComboBox*		mComboGridMode;  	LLCheckBoxCtrl*	mCheckStretchUniform;  	LLCheckBoxCtrl*	mCheckStretchTexture; @@ -179,6 +177,8 @@ public:  	LLPanelFace				*mPanelFace;  	LLPanelLandInfo			*mPanelLandInfo; +	LLViewBorder*			mCostTextBorder; +  	LLTabContainer*			mTabLand;  	LLParcelSelectionHandle	mParcelSelection; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 6e0722bcf9..be11c53efa 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -78,6 +78,14 @@ LLMeshRepository gMeshRepo;  const U32 MAX_MESH_REQUESTS_PER_SECOND = 100; +// Maximum mesh version to support.  Three least significant digits are reserved for the minor version,  +// with major version changes indicating a format change that is not backwards compatible and should not +// be parsed by viewers that don't specifically support that version. For example, if the integer "1" is  +// present, the version is 0.001. A viewer that can parse version 0.001 can also parse versions up to 0.999,  +// but not 1.0 (integer 1000). +// See wiki at https://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format +const S32 MAX_MESH_VERSION = 999; +  U32 LLMeshRepository::sBytesReceived = 0;  U32 LLMeshRepository::sHTTPRequestCount = 0;  U32 LLMeshRepository::sHTTPRetryCount = 0; @@ -843,12 +851,13 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)  	if (header_size > 0)  	{ +		S32 version = mMeshHeader[mesh_id]["version"].asInteger();  		S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger();  		S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger();  		mHeaderMutex->unlock(); -		if (offset >= 0 && size > 0) +		if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)  		{  			//check VFS for mesh skin info  			LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); @@ -915,12 +924,13 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)  	if (header_size > 0)  	{ +		S32 version = mMeshHeader[mesh_id]["version"].asInteger();  		S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger();  		S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger();  		mHeaderMutex->unlock(); -		if (offset >= 0 && size > 0) +		if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)  		{  			//check VFS for mesh skin info  			LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); @@ -987,12 +997,13 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)  	if (header_size > 0)  	{ +		S32 version = mMeshHeader[mesh_id]["version"].asInteger();  		S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger();  		S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger();  		mHeaderMutex->unlock(); -		if (offset >= 0 && size > 0) +		if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)  		{  			//check VFS for mesh physics shape info  			LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); @@ -1103,10 +1114,12 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)  	if (header_size > 0)  	{ +		S32 version = mMeshHeader[mesh_id]["version"].asInteger();  		S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger();  		S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger();  		mHeaderMutex->unlock(); -		if (offset >= 0 && size > 0) +				 +		if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)  		{  			//check VFS for mesh asset @@ -1383,6 +1396,8 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,  	mWholeModelFeeCapability = gAgent.getRegion()->getCapability("NewFileAgentInventory");  	mOrigin += gAgent.getAtAxis() * scale.magVec(); + +	mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut") ;  }  LLMeshUploadThread::~LLMeshUploadThread() @@ -1573,6 +1588,11 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  			for (S32 face_num = 0; face_num < data.mBaseModel->getNumVolumeFaces(); face_num++)  			{ +				if(face_num >= instance.mMaterial.size()) +				{ +					break ; +				} +  				LLImportMaterial& material = instance.mMaterial[face_num];  				LLSD face_entry = LLSD::emptyMap();  				LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); @@ -1686,7 +1706,7 @@ void LLMeshUploadThread::doWholeModelUpload()  	mPendingUploads++;  	LLCurlRequest::headers_t headers;  	mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, -					   new LLWholeModelFeeResponder(this,model_data)); +					   new LLWholeModelFeeResponder(this,model_data), mMeshUploadTimeOut);  	do  	{ @@ -1705,7 +1725,7 @@ void LLMeshUploadThread::doWholeModelUpload()  		LLSD body = full_model_data["asset_resources"];  		dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num));  		mCurlRequest->post(mWholeModelUploadURL, headers, body, -						   new LLWholeModelUploadResponder(this, model_data)); +						   new LLWholeModelUploadResponder(this, model_data), mMeshUploadTimeOut);  		do  		{  			mCurlRequest->process(); @@ -1799,7 +1819,9 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)  {  	lod = llclamp(lod, 0, 3); -	if (header.has("404")) +	S32 version = header["version"]; + +	if (header.has("404") || version > MAX_MESH_VERSION)  	{  		return -1;  	} @@ -2135,54 +2157,59 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,  		LLUUID mesh_id = mMeshParams.getSculptID();  		LLSD header = gMeshRepo.mThread->mMeshHeader[mesh_id]; -		std::stringstream str; +		S32 version = header["version"].asInteger(); + +		if (version <= MAX_MESH_VERSION) +		{ +			std::stringstream str; -		S32 lod_bytes = 0; +			S32 lod_bytes = 0; -		for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i) -		{ //figure out how many bytes we'll need to reserve in the file -			std::string lod_name = header_lod[i]; -			lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger()); -		} +			for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i) +			{ //figure out how many bytes we'll need to reserve in the file +				std::string lod_name = header_lod[i]; +				lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger()); +			} -		//just in case skin info or decomposition is at the end of the file (which it shouldn't be) -		lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger()); -		lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger()); +			//just in case skin info or decomposition is at the end of the file (which it shouldn't be) +			lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger()); +			lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger()); -		S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; -		S32 bytes = lod_bytes + header_bytes;  +			S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; +			S32 bytes = lod_bytes + header_bytes;  -		//it's possible for the remote asset to have more data than is needed for the local cache -		//only allocate as much space in the VFS as is needed for the local cache -		data_size = llmin(data_size, bytes); +			//it's possible for the remote asset to have more data than is needed for the local cache +			//only allocate as much space in the VFS as is needed for the local cache +			data_size = llmin(data_size, bytes); -		LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH, LLVFile::WRITE); -		if (file.getMaxSize() >= bytes || file.setMaxSize(bytes)) -		{ -			LLMeshRepository::sCacheBytesWritten += data_size; +			LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH, LLVFile::WRITE); +			if (file.getMaxSize() >= bytes || file.setMaxSize(bytes)) +			{ +				LLMeshRepository::sCacheBytesWritten += data_size; -			file.write((const U8*) data, data_size); +				file.write((const U8*) data, data_size); -			//zero out the rest of the file  -			U8 block[4096]; -			memset(block, 0, 4096); +				//zero out the rest of the file  +				U8 block[4096]; +				memset(block, 0, 4096); -			while (bytes-file.tell() > 4096) -			{ -				file.write(block, 4096); -			} +				while (bytes-file.tell() > 4096) +				{ +					file.write(block, 4096); +				} -			S32 remaining = bytes-file.tell(); +				S32 remaining = bytes-file.tell(); -			if (remaining < 0 || remaining > 4096) -			{ -				llerrs << "Bad padding of mesh asset cache entry." << llendl; -			} +				if (remaining < 0 || remaining > 4096) +				{ +					llerrs << "Bad padding of mesh asset cache entry." << llendl; +				} -			if (remaining > 0) -			{ -				file.write(block, remaining); +				if (remaining > 0) +				{ +					file.write(block, remaining); +				}  			}  		}  	} @@ -2874,7 +2901,7 @@ void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data)  		LLCurlRequest::headers_t headers;  		mPendingUploads++; -		mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLMeshUploadResponder(data, this)); +		mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLMeshUploadResponder(data, this), mMeshUploadTimeOut);  	}  } @@ -2906,7 +2933,7 @@ void LLMeshUploadThread::doUploadTexture(LLTextureUploadData& data)  		LLCurlRequest::headers_t headers;  		mPendingUploads++; -		mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLTextureUploadResponder(data, this)); +		mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLTextureUploadResponder(data, this), mMeshUploadTimeOut);  	}  } @@ -3158,55 +3185,66 @@ void LLMeshRepository::uploadError(LLSD& args)  //static  F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod)  { -	F32 dlowest = llmin(radius/0.03f, 256.f); -	F32 dlow = llmin(radius/0.06f, 256.f); -	F32 dmid = llmin(radius/0.24f, 256.f); -	 -	F32 bytes_lowest = header["lowest_lod"]["size"].asReal()/1024.f; -	F32 bytes_low = header["low_lod"]["size"].asReal()/1024.f; -	F32 bytes_mid = header["medium_lod"]["size"].asReal()/1024.f; -	F32 bytes_high = header["high_lod"]["size"].asReal()/1024.f; +	F32 max_distance = 512.f; -	if (bytes) -	{ -		*bytes = 0; -		*bytes += header["lowest_lod"]["size"].asInteger(); -		*bytes += header["low_lod"]["size"].asInteger(); -		*bytes += header["medium_lod"]["size"].asInteger(); -		*bytes += header["high_lod"]["size"].asInteger(); -	} +	F32 dlowest = llmin(radius/0.03f, max_distance); +	F32 dlow = llmin(radius/0.06f, max_distance); +	F32 dmid = llmin(radius/0.24f, max_distance); +	 +	F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount");  //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead +	F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free" +	F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle"); -	if (bytes_visible) -	{ -		lod = LLMeshRepository::getActualMeshLOD(header, lod); -		if (lod >= 0 && lod <= 3) -		{ -			*bytes_visible = header[header_lod[lod]]["size"].asInteger(); -		} -	} +	S32 bytes_lowest = header["lowest_lod"]["size"].asInteger(); +	S32 bytes_low = header["low_lod"]["size"].asInteger(); +	S32 bytes_mid = header["medium_lod"]["size"].asInteger(); +	S32 bytes_high = header["high_lod"]["size"].asInteger(); -	if (bytes_high == 0.f) +	if (bytes_high == 0)  	{  		return 0.f;  	} -	if (bytes_mid == 0.f) +	if (bytes_mid == 0)  	{  		bytes_mid = bytes_high;  	} -	if (bytes_low == 0.f) +	if (bytes_low == 0)  	{  		bytes_low = bytes_mid;  	} -	if (bytes_lowest == 0.f) +	if (bytes_lowest == 0)  	{  		bytes_lowest = bytes_low;  	} -	F32 max_area = 65536.f; +	F32 triangles_lowest = llmax((F32) bytes_lowest-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; +	F32 triangles_low = llmax((F32) bytes_low-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; +	F32 triangles_mid = llmax((F32) bytes_mid-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; +	F32 triangles_high = llmax((F32) bytes_high-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; + +	if (bytes) +	{ +		*bytes = 0; +		*bytes += header["lowest_lod"]["size"].asInteger(); +		*bytes += header["low_lod"]["size"].asInteger(); +		*bytes += header["medium_lod"]["size"].asInteger(); +		*bytes += header["high_lod"]["size"].asInteger(); +	} + +	if (bytes_visible) +	{ +		lod = LLMeshRepository::getActualMeshLOD(header, lod); +		if (lod >= 0 && lod <= 3) +		{ +			*bytes_visible = header[header_lod[lod]]["size"].asInteger(); +		} +	} + +	F32 max_area = 102932.f; //area of circle that encompasses region  	F32 min_area = 1.f;  	F32 high_area = llmin(F_PI*dmid*dmid, max_area); @@ -3229,12 +3267,12 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32  	low_area /= total_area;  	lowest_area /= total_area; -	F32 weighted_avg = bytes_high*high_area + -					   bytes_mid*mid_area + -					   bytes_low*low_area + -					  bytes_lowest*lowest_area; +	F32 weighted_avg = triangles_high*high_area + +					   triangles_mid*mid_area + +					   triangles_low*low_area + +					  triangles_lowest*lowest_area; -	return weighted_avg * gSavedSettings.getF32("MeshStreamingCostScaler"); +	return weighted_avg/gSavedSettings.getU32("MeshTriangleBudget")*15000.f;  } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f237c3a60e..f56734a7de 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -356,6 +356,9 @@ public:  class LLMeshUploadThread : public LLThread   { +private: +	S32 mMeshUploadTimeOut ; //maximum time in seconds to execute an uploading request. +  public:  	class DecompRequest : public LLPhysicsDecomp::Request  	{ diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp index 8e8fc9dd25..09e799e4f7 100644 --- a/indra/newview/llsceneview.cpp +++ b/indra/newview/llsceneview.cpp @@ -83,6 +83,9 @@ void LLSceneView::draw()  	S32 total_visible_triangles[] = {0, 0};  	S32 total_triangles[] = {0, 0}; +	S32 total_visible_bytes[] = {0, 0}; +	S32 total_bytes[] = {0, 0}; +  	//streaming cost  	std::vector<F32> streaming_cost[2];  	F32 total_streaming[] = { 0.f, 0.f }; @@ -122,13 +125,19 @@ void LLSceneView::draw()  				visible_triangles[idx].push_back(visible);  				triangles[idx].push_back(high_triangles); -				F32 streaming = object->getStreamingCost(); +				S32 bytes = 0; +				S32 visible_bytes = 0; + +				F32 streaming = object->getStreamingCost(&bytes, &visible_bytes);  				total_streaming[idx] += streaming;  				streaming_cost[idx].push_back(streaming);  				F32 physics = object->getPhysicsCost();  				total_physics[idx] += physics;  				physics_cost[idx].push_back(physics); + +				total_bytes[idx] += bytes; +				total_visible_bytes[idx] += visible_bytes;  			}  		}  	} @@ -279,8 +288,8 @@ void LLSceneView::draw()  				total_visible += tri_count;	  			} -			std::string label = llformat("%s Object Triangle Counts (Ktris) -- [%.2f, %.2f] Mean: %.2f  Median: %.2f  Visible: %.2f/%.2f", -											category[idx], tri_domain[0]/1024.f, tri_domain[1]/1024.f, (total/count)/1024.f, triangles[idx][count/2]/1024.f, total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f); +			std::string label = llformat("%s Object Triangle Counts (Ktris) -- Visible: %.2f/%.2f (%.2f KB Visible)", +				category[idx], total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, total_visible_bytes[idx]/1024.f);  			LLFontGL::getFontMonospace()->renderUTF8(label,  											0 , tri_rect.mLeft, tri_rect.mTop+margin, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index bccabe21a8..66df7dae3e 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -334,6 +334,17 @@ void LLSurface::setOriginGlobal(const LLVector3d &origin_global)  	}  } +void LLSurface::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ) +{ +	S32 i; +	for (i = 0; i < 8; i++) +	{ +		if ( mNeighbors[i] != NULL ) +		{ +			uniqueRegions.push_back( mNeighbors[i]->getRegion() ); +		} +	}	 +}  void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)  { diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 673ee83fe3..a4ef4fe2de 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -140,6 +140,9 @@ public:  	friend class LLSurfacePatch;  	friend std::ostream& operator<<(std::ostream &s, const LLSurface &S); +	 +	void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); +	  public:  	// Number of grid points on one side of a region, including +1 buffer for  	// north and east edge. diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index a1c2c926af..f3b22eab40 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -129,12 +129,12 @@  // *NOTE: Please add files in alphabetical order to keep merges easy. -// handle secondlife:///app/floater/{NAME} URLs +// handle secondlife:///app/openfloater/{NAME} URLs  class LLFloaterOpenHandler : public LLCommandHandler  {  public:  	// requires trusted browser to trigger -	LLFloaterOpenHandler() : LLCommandHandler("floater", UNTRUSTED_THROTTLE) { } +	LLFloaterOpenHandler() : LLCommandHandler("openfloater", UNTRUSTED_THROTTLE) { }  	bool handle(const LLSD& params, const LLSD& query_map,  				LLMediaCtrl* web) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 41d8b57f36..4bf5454905 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -60,6 +60,7 @@  #include "llfloatersnapshot.h"  #include "llfloatertools.h"  #include "llfloaterworldmap.h" +#include "llfloaterbuildoptions.h"  #include "llavataractions.h"  #include "lllandmarkactions.h"  #include "llgroupmgr.h" @@ -7159,9 +7160,11 @@ class LLToolsUseSelectionForGrid : public view_listener_t  		} func;  		LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);  		LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT); -		if (gFloaterTools) + +		LLFloaterBuildOptions* build_options_floater = LLFloaterReg::getTypedInstance<LLFloaterBuildOptions>("build_options"); +		if (build_options_floater && build_options_floater->getVisible())  		{ -			gFloaterTools->mComboGridMode->setCurrentByIndex((S32)GRID_MODE_REF_OBJECT); +			build_options_floater->setGridMode(GRID_MODE_REF_OBJECT);  		}  		return true;  	} diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index f6b01e92cb..729f69ec3f 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -936,7 +936,6 @@ protected:  //one global instance to bind them  LLOpenTaskOffer* gNewInventoryObserver=NULL; -  class LLNewInventoryHintObserver : public LLInventoryAddedObserver  {  protected: @@ -946,6 +945,8 @@ protected:  	}  }; +LLNewInventoryHintObserver* gNewInventoryHintObserver=NULL; +  void start_new_inventory_observer()  {  	if (!gNewInventoryObserver) //task offer observer  @@ -962,7 +963,12 @@ void start_new_inventory_observer()  		gInventory.addObserver(gInventoryMoveObserver);  	} -	gInventory.addObserver(new LLNewInventoryHintObserver()); +	if (!gNewInventoryHintObserver) +	{ +		// Observer is deleted by gInventory +		gNewInventoryHintObserver = new LLNewInventoryHintObserver(); +		gInventory.addObserver(gNewInventoryHintObserver); +	}  }  class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index be9ff872c0..c3a7d345f5 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -519,7 +519,6 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list)  	}  } -  // This method returns true if the object is over land owned by the  // agent.  bool LLViewerObject::isReturnable() @@ -528,17 +527,106 @@ bool LLViewerObject::isReturnable()  	{  		return false;  	} +		  	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()); +		boxes.push_back( LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); +	} + +	bool result = (mRegionp && mRegionp->objectIsReturnable(getPositionRegion(), boxes)) ? 1 : 0; +	 +	if ( !result ) +	{		 +		//Get list of neighboring regions relative to this vo's region +		std::vector<LLViewerRegion*> uniqueRegions; +		mRegionp->getNeighboringRegions( uniqueRegions ); +	 +		//Build aabb's - for root and all children +		std::vector<PotentialReturnableObject> returnables; +		typedef std::vector<LLViewerRegion*>::iterator RegionIt; +		RegionIt regionStart = uniqueRegions.begin(); +		RegionIt regionEnd   = uniqueRegions.end(); +		 +		for (; regionStart != regionEnd; ++regionStart ) +		{ +			LLViewerRegion* pTargetRegion = *regionStart; +			//Add the root vo as there may be no children and we still want +			//to test for any edge overlap +			buildReturnablesForChildrenVO( returnables, this, pTargetRegion ); +			//Add it's children +			for (child_list_t::iterator iter = mChildList.begin();  iter != mChildList.end(); iter++) +			{ +				LLViewerObject* pChild = *iter;		 +				buildReturnablesForChildrenVO( returnables, pChild, pTargetRegion ); +			} +		}	 +	 +		//TBD#Eventually create a region -> box list map  +		typedef std::vector<PotentialReturnableObject>::iterator ReturnablesIt; +		ReturnablesIt retCurrentIt = returnables.begin(); +		ReturnablesIt retEndIt = returnables.end(); +	 +		for ( ; retCurrentIt !=retEndIt; ++retCurrentIt ) +		{ +			boxes.clear(); +			LLViewerRegion* pRegion = (*retCurrentIt).pRegion; +			boxes.push_back( (*retCurrentIt).box );	 +			bool retResult = (pRegion && pRegion->childrenObjectReturnable( boxes )) ? 1 : 0; +			if ( retResult ) +			{  +				result = true; +				break; +			} +		} +	} +	return result; +} + +void LLViewerObject::buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ) +{ +	if ( !pChild ) +	{ +		llerrs<<"child viewerobject is NULL "<<llendl; +	} +	 +	constructAndAddReturnable( returnables, pChild, pTargetRegion ); +	 +	//We want to handle any children VO's as well +	for (child_list_t::iterator iter = pChild->mChildList.begin();  iter != pChild->mChildList.end(); iter++) +	{ +		LLViewerObject* pChildofChild = *iter; +		buildReturnablesForChildrenVO( returnables, pChildofChild, pTargetRegion );  	} +} -	return mRegionp -		&& mRegionp->objectIsReturnable(getPositionRegion(), boxes); +void LLViewerObject::constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ) +{ +	 +	LLVector3 targetRegionPos; +	targetRegionPos.setVec( pChild->getPositionGlobal() );	 +	 +	LLBBox childBBox = LLBBox( targetRegionPos, pChild->getRotationRegion(), pChild->getScale() * -0.5f,  +							    pChild->getScale() * 0.5f).getAxisAligned(); +	 +	LLVector3 edgeA = targetRegionPos + childBBox.getMinLocal(); +	LLVector3 edgeB = targetRegionPos + childBBox.getMaxLocal(); +	 +	LLVector3d edgeAd, edgeBd; +	edgeAd.setVec(edgeA); +	edgeBd.setVec(edgeB); +	 +	//Only add the box when either of the extents are in a neighboring region +	if ( pTargetRegion->pointInRegionGlobal( edgeAd ) || pTargetRegion->pointInRegionGlobal( edgeBd ) ) +	{ +		PotentialReturnableObject returnableObj; +		returnableObj.box		= childBBox; +		returnableObj.pRegion	= pTargetRegion; +		returnables.push_back( returnableObj ); +	}  }  BOOL LLViewerObject::setParent(LLViewerObject* parent) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index a0ad52df6b..f75a3d996d 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -44,11 +44,11 @@  #include "v3math.h"  #include "llvertexbuffer.h"  #include "llaccountingquota.h" +#include "llbbox.h"  class LLAgent;			// TODO: Get rid of this.  class LLAudioSource;  class LLAudioSourceVO; -class LLBBox;  class LLDataPacker;  class LLColor4;  class LLFrameTimer; @@ -112,6 +112,12 @@ public:  	LLColor4	mColor;  }; +struct PotentialReturnableObject +{ +	LLBBox			box; +	LLViewerRegion* pRegion; +}; +  //============================================================================  class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate @@ -234,6 +240,9 @@ public:  	// anti-encroachment is enabled  	bool isReturnable(); +	void buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); +	void constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); +  	/*  	// This method will scan through this object, and then query the  	// selection manager to see if the local agent probably has the diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 26765bdd01..eff16b6a6e 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -173,6 +173,33 @@ bool LLViewerParcelOverlay::encroachesOwned(const std::vector<LLBBox>& boxes) co  	}  	return false;  } +bool LLViewerParcelOverlay::encroachesOnUnowned(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(); +		 +		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 top    = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); +		S32 bottom = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); +		 +		for (S32 row = top; row <= bottom; row++) +		{ +			for (S32 column = left; column <= right; column++) +			{ +				U8 type = ownership(row, column); +				if ((PARCEL_SELF != type)) +				{ +					return true; +				} +			} +		} +	} +	return false; +}  BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const  { diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index c80baedda6..3c6794e7d0 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -60,6 +60,7 @@ public:  	// might be in another parcel. for now, we simply test axis aligned   	// 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			isSoundLocal(const LLVector3& pos) const; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 002e0567e4..85b4b60bf7 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1699,6 +1699,18 @@ bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<  				&& mParcelOverlay->encroachesOwned(boxes)) );  } +bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const +{ +	bool result = false; +	result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0; +	return result; +} + +void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ) +{ +	mImpl->mLandp->getNeighboringRegions( uniqueRegions ); +} +  void LLViewerRegion::showReleaseNotes()  {  	std::string url = this->getCapability("ServerReleaseNotes"); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 3811b989e7..68662c99bd 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -318,6 +318,10 @@ public:  	LLSpatialPartition* getSpatialPartition(U32 type);  	bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const; +	bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const; + +	void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); +	  public:  	struct CompareDistance  	{ diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b1441cc281..b2fd802ae7 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -528,8 +528,8 @@ public:  				addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost));  				ypos += y_inc; -				addText(xpos, ypos, llformat("    %.1f KTris, %.1f/%.1f KB, %d objects", -										count/1024.f, visible_bytes/1024.f, total_bytes/1024.f, object_count)); +				addText(xpos, ypos, llformat("    %.3f KTris, %.1f/%.1f KB, %d objects", +										count/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count));  				ypos += y_inc;  			} @@ -3142,6 +3142,12 @@ void LLViewerWindow::updateLayout()  		//gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible());  	} +	LLFloaterBuildOptions* build_options_floater = LLFloaterReg::getTypedInstance<LLFloaterBuildOptions>("build_options"); +	if (build_options_floater && build_options_floater->getVisible()) +	{ +		build_options_floater->updateGridMode(); +	} +  	// Always update console  	if(gConsole)  	{ diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 8eda6346b0..27f3a26f83 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1123,7 +1123,10 @@ void LLVOAvatar::initClass()  	// Process XML data  	// avatar_skeleton.xml -	llassert(!sAvatarSkeletonInfo); +	if (sAvatarSkeletonInfo) +	{ //this can happen if a login attempt failed +		delete sAvatarSkeletonInfo; +	}  	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;  	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))  	{ 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 56230e912c..c247a12e7a 100644 --- a/indra/newview/skins/default/xui/en/floater_build_options.xml +++ b/indra/newview/skins/default/xui/en/floater_build_options.xml @@ -2,27 +2,84 @@  <floater   legacy_header_height="18"   follows="right" - height="170" + height="198"   layout="topleft"   name="build options floater"   help_topic="build_options_floater"   save_rect="true"   title="GRID OPTIONS"   width="264"> + 	<floater.string +     name="grid_screen_text"> +        Screen +    </floater.string> +    <floater.string +     name="grid_local_text"> +        Local +    </floater.string> +    <floater.string +     name="grid_world_text"> +        World +    </floater.string> +    <floater.string +     name="grid_reference_text"> +        Reference +    </floater.string> +    <floater.string +     name="grid_attachment_text"> +        Attachment +    </floater.string> +    <text +     type="string" +     length="1" +     follows="left|top" +     height="16" +     layout="topleft" +     left="10" +     tool_tip="Grid opacity" +     name="grid_opacity_label" +     top_pad="30" +     width="123"> +        Mode +    </text> +    <combo_box +     height="23" +     layout="topleft" +     left_pad="9" +     follows="left|top" +     name="combobox grid mode" +     tool_tip="Choose the type of grid ruler for positioning the object" +     top_delta="-3" +     width="108"> +      <combo_box.item +       label="World grid" +       name="World" +       value="World" /> +      <combo_box.item +       label="Local grid" +       name="Local" +       value="Local" /> +      <combo_box.item +       label="Reference grid" +       name="Reference" +       value="Reference" /> +       <combo_box.commit_callback +      function="GridOptions.gridMode"/> +    </combo_box>      <spinner       control_name="GridResolution"       follows="left|top"       height="23"       initial_value="1" -     label="Grid Units (meters)" -     label_width="160" +     label="Units (meters)" +     label_width="130"       layout="topleft"       left="10"       max_val="5"       min_val="0.01"       name="GridResolution" -     top="25" -     width="230" /> +     top_pad="4" +     width="200" />      <spinner       control_name="GridDrawSize"       decimal_digits="1" @@ -30,15 +87,15 @@       height="23"       increment="0.5"       initial_value="5" -     label="Grid Extents (meters)" -     label_width="160" +     label="Extents (meters)" +     label_width="130"       layout="topleft"       left_delta="0"       max_val="50"       min_val="1"       name="GridDrawSize"       top_pad="0" -     width="230" /> +     width="200" />      <check_box       control_name="GridSubUnit"       height="16" 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 f58595b3c5..07958b762e 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1,7 +1,8 @@  <?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"> +     name="Model Preview" title="Upload Model" width="620" +      help_topic="upload_model" >    <string name="status_idle">Idle</string>    <string name="status_parse_error">Dae parsing issue - see log for details.</string> 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 8603682e3a..c3f7b70ca7 100644 --- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml +++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml @@ -281,7 +281,7 @@  			 height="40"  			 left="10"  			 word_wrap="true"> -Advanced users familiar with 3d content creation tools may prefer to use the [secondlife:///app/floater/upload_model Advanced Mesh Import Window] . +Advanced users familiar with 3d content creation tools may prefer to use the [secondlife:///app/openfloater/upload_model Advanced Mesh Import Window] .  			</text>  		</panel>  	</panel> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 8b8f70b940..2169b5ccc3 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -47,24 +47,12 @@          Click and drag to select land      </floater.string>      <floater.string -     name="grid_screen_text"> -        Screen +     name="status_selectcount"> +        [OBJ_COUNT] objects ( [PRIM_COUNT] prims[PE_STRING] ) selected      </floater.string>      <floater.string -     name="grid_local_text"> -        Local -    </floater.string> -    <floater.string -     name="grid_world_text"> -        World -    </floater.string> -    <floater.string -     name="grid_reference_text"> -        Reference -    </floater.string> -    <floater.string -     name="grid_attachment_text"> -        Attachment +     name="status_selectprimequiv"> +        , [SEL_WEIGHT] prim equivs      </floater.string>      <button       follows="left|top" @@ -221,7 +209,7 @@  	<radio_group       follows="left|top"  	 left="5" -	 top="59" +	 top="55"  	 height="70"       layout="topleft"  	 name="edit_radio_group"> @@ -255,18 +243,18 @@       label="Edit linked"       layout="topleft"       name="checkbox edit linked parts" -     top_pad="-10"> +     top_pad="-18">  		  <check_box.commit_callback  			function="BuildTool.selectComponent"/>  	</check_box>     <button       follows="left|top" -     height="23" +     height="20"       label="Link" -     top_pad="2" +     top="108"       layout="topleft" -     left="5" +     left="143"       name="link_btn"       width="50">  	  <button.commit_callback @@ -274,7 +262,7 @@      </button>      <button       follows="left|top" -     height="23" +     height="20"       label="Unlink"       layout="topleft"       left_pad="2" @@ -283,18 +271,6 @@  	  <button.commit_callback  	     function="BuildTool.UnlinkObjects"/>      </button> -    <text -	   text_color="LtGray_50" -	   follows="top|left" -	   halign="left" -	   left_pad="3" -	   name="RenderingCost" -	   tool_tip="Shows the rendering cost calculated for this object" -	   top_delta="11" -	   type="string" -	   width="100"> -	   รพ: [COUNT] -	   </text>      <check_box       control_name="ScaleUniform"       height="19" @@ -302,7 +278,7 @@       layout="topleft"       left="143"       name="checkbox uniform" -     top="50" +     top="48"       width="20" />      <text       height="19" @@ -324,53 +300,29 @@       layout="topleft"       left="143"       name="checkbox stretch textures" -     top_pad="-6" +     top_pad="-4"       follows="left|top"       width="134" />     <check_box       control_name="SnapEnabled"       height="18"       initial_value="true" -     label="Snap to grid" +     label="Snap"       layout="topleft"       top_pad="0"       name="checkbox snap to grid"       width="134" /> -    <combo_box -     height="23" -     layout="topleft" -     follows="left|top" -     name="combobox grid mode" -     tool_tip="Choose the type of grid ruler for positioning the object" -     top_pad="0" -     width="108"> -        <combo_box.item -         label="World grid" -         name="World" -         value="World" /> -        <combo_box.item -         label="Local grid" -         name="Local" -         value="Local" /> -        <combo_box.item -         label="Reference grid" -         name="Reference" -         value="Reference" /> -		 <combo_box.commit_callback -	     function="BuildTool.gridMode"/> -    </combo_box>      <button       left_pad="0" -     image_selected="ForwardArrow_Press" -     image_unselected="ForwardArrow_Off" +     label="Options..."       layout="topleft"       follows="top|left"       name="Options..."       tool_tip="See more grid options" -     top_pad="-22" -     right="-10" -     width="18" -     height="23" > +     top="83" +     right="-35" +     width="65" +     height="21" >  	 <button.commit_callback  	     function="BuildTool.gridOptions"/>  	</button> @@ -385,7 +337,7 @@       left="10"       name="ToolCube"       tool_tip="Cube" -     top="51" +     top="58"       width="20" />      <button       follows="left|top" @@ -447,10 +399,10 @@       image_selected="Object_Hemi_Cylinder_Selected"       image_unselected="Object_Hemi_Cylinder"       layout="topleft" -     left_delta="29" +     left="10"       name="ToolHemiCylinder"       tool_tip="Hemicylinder" -     top_delta="0" +     top="84"       width="20" />      <button       follows="left|top" @@ -515,7 +467,7 @@       left="10"       name="ToolTorus"       tool_tip="Torus" -     top="77" +     top="109"       width="20" />      <button       follows="left|top" @@ -575,9 +527,9 @@       height="19"       label="Keep Tool selected"       layout="topleft" -     left="4" +     left="155"       name="checkbox sticky" -     top="101" +     top="55"       width="128" />      <check_box       control_name="CreateToolCopySelection" @@ -596,7 +548,7 @@       layout="topleft"       left_delta="18"       name="checkbox copy centers" -     top="132" +     top="85"       width="134" />      <check_box       control_name="CreateToolCopyRotates" @@ -749,89 +701,49 @@  	  <button.commit_callback  	     function="BuildTool.applyToSelection"/>      </button> +    <text +	 text_color="LtGray_50" +	  type="string" +	  length="1" +	  height="16" +	  follows="left|top" +	  font="SansSerifSmall" +	  layout="topleft" +	  left="10" +	  name="selection_empty" +	  top_pad="0" +	  width="100"> +		Nothing selected. +	</text>  	<text  	 text_color="LtGray_50"  	  type="string"  	  length="1" -	  height="10" +	  height="16"  	  follows="left|top" -	  halign="right" +	  font="SansSerifSmall"  	  layout="topleft" -	  right="-10" -	  name="obj_count" -	  top_pad="5" -	  width="143"> -		Objects: [COUNT] +	  left="10" +	  name="selection_count" +	  top_delta="0" +	  visible="false" +	  width="280">  	</text>  	<text -    text_color="LtGray_50" -     type="string" -     length="1" -	height="10"  -     follows="left|top" -     halign="right" -     layout="topleft" -     right="-10" -     name="prim_count" -     width="143"> -		Prims: [COUNT] +	 text_color="LtGray_50" +	  type="string" +	  length="1" +	  height="16" +	  follows="left|top" +	  font="SansSerifSmall" +	  layout="topleft" +	  left="10" +	  name="selection_weight" +	  top_pad="0" +	  visible="false" +	  width="280"> +	  Physics weight [PHYS_WEIGHT], Render Cost [DISP_WEIGHT].  	</text> -    <text -    text_color="LtGray_50" -     type="string" -     length="1" -     height="10" -     follows="left|top" -     halign="right" -     layout="topleft" -     right="-120" -     name="linked_set_count" -     top="144" -     width="80"> -        Linked Sets: [COUNT] -    </text> -    <text -    text_color="LtGray_50" -     type="string" -     length="1" -     height="10" -     follows="left|top" -     halign="right" -     layout="topleft" -     top_delta="0" -     right="-8" -     name="linked_set_cost" -     tool_tip="Cost of currently selected linked sets as [prims],[physics complexity]"  -     width="80"> -        Cost: [COST] / [PHYSICS] -    </text> -    <text -    text_color="LtGray_50" -     type="string" -     length="1" -     follows="left|top" -     halign="right" -     layout="topleft" -     top_pad="5" -     right="-120" -     name="object_count" -     width="80"> -        Objects: [COUNT] -    </text> -    <text -    text_color="LtGray_50" -     type="string" -     length="1" -     follows="left|top" -     halign="right" -     layout="topleft" -	 top_delta="0" -     right="-8" -     name="object_cost" -     tool_tip="Cost of currently selected objects as [prims] / [physics complexity]" -     width="80"> -        Cost: [COST] / [PHYSICS] -    </text>      <!-- <text -->      <!-- text_color="LtGray_50" -->      <!--  type="string" --> @@ -858,6 +770,15 @@      <!--  width="143"> -->      <!--     Prims: [COUNT] -->      <!-- </text> --> +    <view_border +    bevel_style="none" +    follows="top|left" +    height="0" +    layout="topleft" +    left="6" +    name="cost_text_border" +    top="135" +    width="282"/>      <tab_container       follows="left|top"       height="410"  | 
