diff options
| author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2011-05-25 16:09:46 -0400 | 
|---|---|---|
| committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2011-05-25 16:09:46 -0400 | 
| commit | 9d80bee277712427db0670229966f372bb91212a (patch) | |
| tree | 3717d6107b174f84cbdb15bc661c56d4c246f66a | |
| parent | a8470df2c433d2ce0376dde4f1a54b46ba9b01d7 (diff) | |
| parent | d79468057c954a05acdb9dd69d398dd004425ec0 (diff) | |
merge
| -rw-r--r-- | indra/llprimitive/llmodel.cpp | 31 | ||||
| -rw-r--r-- | indra/llprimitive/llmodel.h | 1 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 25 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelwizard.cpp | 25 | ||||
| -rwxr-xr-x | indra/newview/llmeshrepository.cpp | 174 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 10 | 
6 files changed, 171 insertions, 95 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 0cbb46cc71..0d78d656b6 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1775,7 +1775,7 @@ void LLModel::updateHullCenters()  	if (mHullPoints > 0)  	{  		mCenterOfHullCenters *= 1.f / mHullPoints; -		llassert(mPhysics.asLLSD().has("HullList")); +		llassert(mPhysics.hasHullList());  	}  } @@ -2133,6 +2133,11 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)  	}  } +bool LLModel::Decomposition::hasHullList() const +{ +	return !mHull.empty() ; +} +  LLSD LLModel::Decomposition::asLLSD() const  {  	LLSD ret; @@ -2218,14 +2223,17 @@ LLSD LLModel::Decomposition::asLLSD() const  					//convert to 16-bit normalized across domain  					U16 val = (U16) (((src[k]-min.mV[k])/range.mV[k])*65535); -					switch (k) +					if(valid.size() < 3)  					{ -						case 0: test = test | (U64) val; break; -						case 1: test = test | ((U64) val << 16); break; -						case 2: test = test | ((U64) val << 32); break; -					}; +						switch (k) +						{ +							case 0: test = test | (U64) val; break; +							case 1: test = test | ((U64) val << 16); break; +							case 2: test = test | ((U64) val << 32); break; +						}; -					valid.insert(test); +						valid.insert(test); +					}  					U8* buff = (U8*) &val;  					//write to binary buffer @@ -2237,8 +2245,8 @@ LLSD LLModel::Decomposition::asLLSD() const  				}  			} -			//must have at least 4 unique points -			llassert(valid.size() > 3); +			//must have at least 3 unique points +			llassert(valid.size() > 2);  		}  		ret["Positions"] = p; @@ -2304,10 +2312,5 @@ void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs)  	{ //take physics shape mesh from rhs  		mPhysicsShapeMesh = rhs->mPhysicsShapeMesh;  	} - -	if (!mHull.empty()) -	{ //verify -		llassert(asLLSD().has("HullList")); -	}  } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 23f4b5cb42..ebca1f9d9d 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -106,6 +106,7 @@ public:  		Decomposition(LLSD& data);  		void fromLLSD(LLSD& data);  		LLSD asLLSD() const; +		bool hasHullList() const;  		void merge(const Decomposition* rhs); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 9dd5269a6b..2a3bd37129 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -4962,9 +4962,12 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL  	if (mdl)  	{  		U16 index_offset = 0; +		U16 tri[3] ;  		mPositions.clear();  		mIndices.clear(); +		mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ; +		mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ;  		//queue up vertex positions and indices  		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) @@ -4978,12 +4981,28 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL  			for (U32 j = 0; j < face.mNumVertices; ++j)  			{  				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); +				for(U32 k = 0 ; k < 3 ; k++) +				{ +					mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ; +					mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ; +				}  			} -			for (U32 j = 0; j < face.mNumIndices; ++j) +			updateTriangleAreaThreshold() ; + +			for (U32 j = 0; j+2 < face.mNumIndices; j += 3)  			{ -				mIndices.push_back(face.mIndices[j]+index_offset); -			} +				tri[0] = face.mIndices[j] + index_offset ; +				tri[1] = face.mIndices[j + 1] + index_offset ; +				tri[2] = face.mIndices[j + 2] + index_offset ; +				 +				if(isValidTriangle(tri[0], tri[1], tri[2])) +				{ +					mIndices.push_back(tri[0]); +					mIndices.push_back(tri[1]); +					mIndices.push_back(tri[2]); +				} +			}			  			index_offset += face.mNumVertices;  		} diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp index faf81dbc5c..e44737f39e 100644 --- a/indra/newview/llfloatermodelwizard.cpp +++ b/indra/newview/llfloatermodelwizard.cpp @@ -441,10 +441,13 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM  	if (mdl)  	{  		U16 index_offset = 0; +		U16 tri[3] ;  		mPositions.clear();  		mIndices.clear(); - +		mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ; +		mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ; +		  		//queue up vertex positions and indices  		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)  		{ @@ -457,11 +460,27 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM  			for (U32 j = 0; j < face.mNumVertices; ++j)  			{  				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); +				for(U32 k = 0 ; k < 3 ; k++) +				{ +					mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ; +					mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ; +				}  			} -			for (U32 j = 0; j < face.mNumIndices; ++j) +			updateTriangleAreaThreshold() ; + +			for (U32 j = 0; j+2 < face.mNumIndices; j += 3)  			{ -				mIndices.push_back(face.mIndices[j]+index_offset); +				tri[0] = face.mIndices[j] + index_offset ; +				tri[1] = face.mIndices[j + 1] + index_offset ; +				tri[2] = face.mIndices[j + 2] + index_offset ; +				 +				if(isValidTriangle(tri[0], tri[1], tri[2])) +				{ +					mIndices.push_back(tri[0]); +					mIndices.push_back(tri[1]); +					mIndices.push_back(tri[2]); +				}  			}  			index_offset += face.mNumVertices; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index caa5f10575..4b0f002a45 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1437,9 +1437,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  	{  		LLMeshUploadData data;  		data.mBaseModel = iter->first; -		LLModelInstance& instance = *(iter->second.begin()); -		LLModel* model = instance.mModel; -		if (mesh_index.find(model) == mesh_index.end()) +		if (mesh_index.find(data.mBaseModel) == mesh_index.end())  		{  			// Have not seen this model before - create a new mesh_list entry for it.  			std::string model_name = data.mBaseModel->getName(); @@ -1472,97 +1470,106 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  			std::string str = ostr.str();  			res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());  -			mesh_index[model] = mesh_num; +			mesh_index[data.mBaseModel] = mesh_num;  			mesh_num++;  		} + +		// For all instances that use this model +		for (instance_list::iterator instance_iter = iter->second.begin(); +			 instance_iter != iter->second.end(); +			 ++instance_iter) +		{ + +			LLModelInstance& instance = *instance_iter; -		LLSD instance_entry; +			LLSD instance_entry; -		for (S32 i = 0; i < 5; i++) -		{ -			data.mModel[i] = instance.mLOD[i]; -		} +			for (S32 i = 0; i < 5; i++) +			{ +				data.mModel[i] = instance.mLOD[i]; +			} -		LLVector3 pos, scale; -		LLQuaternion rot; -		LLMatrix4 transformation = instance.mTransform; -		decomposeMeshMatrix(transformation,pos,rot,scale); -		instance_entry["position"] = ll_sd_from_vector3(pos); -		instance_entry["rotation"] = ll_sd_from_quaternion(rot); -		instance_entry["scale"] = ll_sd_from_vector3(scale); +			LLVector3 pos, scale; +			LLQuaternion rot; +			LLMatrix4 transformation = instance.mTransform; +			decomposeMeshMatrix(transformation,pos,rot,scale); +			instance_entry["position"] = ll_sd_from_vector3(pos); +			instance_entry["rotation"] = ll_sd_from_quaternion(rot); +			instance_entry["scale"] = ll_sd_from_vector3(scale); -		instance_entry["material"] = LL_MCODE_WOOD; -		LLPermissions perm; -		perm.setOwnerAndGroup(gAgent.getID(), gAgent.getID(), LLUUID::null, false); -		perm.setCreator(gAgent.getID()); +			instance_entry["material"] = LL_MCODE_WOOD; +			LLPermissions perm; +			perm.setOwnerAndGroup(gAgent.getID(), gAgent.getID(), LLUUID::null, false); +			perm.setCreator(gAgent.getID()); -		perm.initMasks(PERM_ITEM_UNRESTRICTED | PERM_MOVE, //base -					   PERM_ITEM_UNRESTRICTED | PERM_MOVE, //owner -					   LLFloaterPerms::getEveryonePerms(), -					   LLFloaterPerms::getGroupPerms(), -					   LLFloaterPerms::getNextOwnerPerms()); -		instance_entry["permissions"] = ll_create_sd_from_permissions(perm); -		instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); -		instance_entry["mesh"] = mesh_index[model]; - -		if (mUploadTextures) -		{ -			instance_entry["face_list"] = LLSD::emptyArray(); - -			for (S32 face_num = 0; face_num < model->getNumVolumeFaces(); face_num++) +			perm.initMasks(PERM_ITEM_UNRESTRICTED | PERM_MOVE, //base +						   PERM_ITEM_UNRESTRICTED | PERM_MOVE, //owner +						   LLFloaterPerms::getEveryonePerms(), +						   LLFloaterPerms::getGroupPerms(), +						   LLFloaterPerms::getNextOwnerPerms()); +			instance_entry["permissions"] = ll_create_sd_from_permissions(perm); +			instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); +			instance_entry["mesh"] = mesh_index[data.mBaseModel]; + +			if (mUploadTextures)  			{ -				LLImportMaterial& material = instance.mMaterial[face_num]; -				LLSD face_entry = LLSD::emptyMap(); -				LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); -				 -				if (texture != NULL) -				{ -					if (textures.find(texture) == textures.end()) -					{ -						textures.insert(texture); -					} +				instance_entry["face_list"] = LLSD::emptyArray(); -					std::stringstream ostr; -					if (include_textures) // otherwise data is blank. +				for (S32 face_num = 0; face_num < data.mBaseModel->getNumVolumeFaces(); face_num++) +				{ +					LLImportMaterial& material = instance.mMaterial[face_num]; +					LLSD face_entry = LLSD::emptyMap(); +					LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); +				 +					if (texture != NULL)  					{ -						LLTextureUploadData data(texture, material.mDiffuseMapLabel); -						if (!data.mTexture->isRawImageValid()) +						if (textures.find(texture) == textures.end())  						{ -							data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); +							textures.insert(texture);  						} + +						std::stringstream ostr; +						if (include_textures) // otherwise data is blank. +						{ +							LLTextureUploadData data(texture, material.mDiffuseMapLabel); +							if (!data.mTexture->isRawImageValid()) +							{ +								data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); +							} -						LLPointer<LLImageJ2C> upload_file = -							LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); -						ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); +							LLPointer<LLImageJ2C> upload_file = +								LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); +							ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); +						} + +						if (texture_index.find(texture) == texture_index.end()) +						{ +							texture_index[texture] = texture_num; +							std::string str = ostr.str(); +							res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end()); +							texture_num++; +						}  					} -					if (texture_index.find(texture) == texture_index.end()) +					// Subset of TextureEntry fields. +					if (texture)  					{ -						texture_index[texture] = texture_num; -						std::string str = ostr.str(); -						res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end()); -						texture_num++; +						face_entry["image"] = texture_index[texture];  					} +					face_entry["scales"] = 1.0; +					face_entry["scalet"] = 1.0; +					face_entry["offsets"] = 0.0; +					face_entry["offsett"] = 0.0; +					face_entry["imagerot"] = 0.0; +					face_entry["colors"] = ll_sd_from_color4(material.mDiffuseColor); +					face_entry["fullbright"] = material.mFullbright; +					instance_entry["face_list"][face_num] = face_entry;  				} +		    } -				// Subset of TextureEntry fields. -				if (texture) -				{ -					face_entry["image"] = texture_index[texture]; -				} -				face_entry["scales"] = 1.0; -				face_entry["scalet"] = 1.0; -				face_entry["offsets"] = 0.0; -				face_entry["offsett"] = 0.0; -				face_entry["imagerot"] = 0.0; -				face_entry["colors"] = ll_sd_from_color4(material.mDiffuseColor); -				face_entry["fullbright"] = material.mFullbright; -				instance_entry["face_list"][face_num] = face_entry; -			} +			res["instance_list"][instance_num] = instance_entry; +			instance_num++;  		} - -		res["instance_list"][instance_num] = instance_entry; -		instance_num++;  	}  	result["asset_resources"] = res; @@ -3820,6 +3827,25 @@ void LLPhysicsDecomp::run()  	mDone = true;  } +void LLPhysicsDecomp::Request::updateTriangleAreaThreshold()  +{ +	F32 range = mBBox[1].mV[0] - mBBox[0].mV[0] ; +	range = llmin(range, mBBox[1].mV[1] - mBBox[0].mV[1]) ; +	range = llmin(range, mBBox[1].mV[2] - mBBox[0].mV[2]) ; + +	mTriangleAreaThreshold = llmin(0.0002f, range * 0.000002f) ; +} + +//check if the triangle area is large enough to qualify for a valid triangle +bool LLPhysicsDecomp::Request::isValidTriangle(U16 idx1, U16 idx2, U16 idx3)  +{ +	LLVector3 a = mPositions[idx2] - mPositions[idx1] ; +	LLVector3 b = mPositions[idx3] - mPositions[idx1] ; +	F32 c = a * b ; + +	return ((a*a) * (b*b) - c * c) > mTriangleAreaThreshold ; +} +  void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)  {  	mStatusMessage = msg; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f859e29c07..0a6954bade 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -152,7 +152,7 @@ public:  		std::string mStatusMessage;  		std::vector<LLModel::PhysicsMesh> mHullMesh;  		LLModel::convex_hull_decomposition mHull; -		 +			  		//status message callback, called from decomposition thread  		virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0; @@ -160,6 +160,14 @@ public:  		virtual void completed() = 0;  		virtual void setStatusMessage(const std::string& msg); + +	protected: +		//internal use +		LLVector3 mBBox[2] ; +		F32 mTriangleAreaThreshold ; + +		void updateTriangleAreaThreshold() ; +		bool isValidTriangle(U16 idx1, U16 idx2, U16 idx3) ;  	};  	LLCondition* mSignal;  | 
