diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llmath/llvolume.cpp | 141 | ||||
| -rw-r--r-- | indra/llprimitive/llmodel.cpp | 355 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 56 | 
3 files changed, 318 insertions, 234 deletions
| diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8c81f27784..7c7c4306da 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2379,11 +2379,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) &&  +		abs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && +		abs(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 +2504,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()) +				{ +					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  				{ -					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; +					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 +2675,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); +				}  			}  		}  	} @@ -5696,8 +5734,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 +5780,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 +5794,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 +5838,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/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index e0cfa07614..7c9dba9597 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(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(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(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(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(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);  } @@ -1477,9 +1429,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 +1440,41 @@ 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]; +					if (face.mNormals) +					{ //normals +						F32* norm = face.mNormals[j].getF32ptr(); + +						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; + +							//write to binary buffer +							normals[norm_idx++] = buff[0]; +							normals[norm_idx++] = buff[1]; +						}  					} +  					F32* src_tc = (F32*) face.mTexCoords[j].mV;  					//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); - -						U8* buff = (U8*) &val; -						//write to binary buffer -						tc[tc_idx++] = buff[0]; -						tc[tc_idx++] = buff[1]; +					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 +1488,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) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 866cc39eec..a4683b4874 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -3719,7 +3719,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)  				{ @@ -3841,6 +3843,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) @@ -3865,8 +3869,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()); @@ -4462,7 +4473,16 @@ 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; +			 +			if (vf.mNormals) +			{ +				mask |= LLVertexBuffer::MAP_NORMAL; +			} +			if (vf.mTexCoords) +			{ +				mask |= LLVertexBuffer::MAP_TEXCOORD0; +			}  			if (skinned)  			{ @@ -4480,8 +4500,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) @@ -4490,8 +4508,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)  			{ @@ -4750,6 +4778,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()) @@ -4798,8 +4828,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)  					{ @@ -4918,7 +4948,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); @@ -4984,7 +5014,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); @@ -5109,7 +5139,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); | 
