From 9cb31845bafe9188d9f90dc1330355c73fb96851 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 4 May 2011 20:45:14 -0500
Subject: SH-1497 Update mesh asset parser to use new format restrictions.

---
 indra/llmath/llvolume.cpp          |   7 +--
 indra/llprimitive/llmodel.cpp      | 122 +++++++++++--------------------------
 indra/newview/llmeshrepository.cpp |  12 ++--
 3 files changed, 43 insertions(+), 98 deletions(-)

(limited to 'indra')

diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 70e1e1f312..c44c95272e 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2239,13 +2239,12 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 					
 			}
 
-			LLVector3 minp;
-			LLVector3 maxp;
+			LLVector3 minp(-0.5f, -0.5f, -0.5f);
+			LLVector3 maxp(0.5f, 0.5f, 0.5f);
 			LLVector2 min_tc; 
 			LLVector2 max_tc; 
 		
-			minp.setValue(mdl[i]["PositionDomain"]["Min"]);
-			maxp.setValue(mdl[i]["PositionDomain"]["Max"]);
+			
 			LLVector4a min_pos, max_pos;
 			min_pos.load3(minp.mV);
 			max_pos.load3(maxp.mV);
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 794cdb83d5..66b5150ed4 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -50,7 +50,7 @@ std::string model_names[] =
 	"low_lod",
 	"medium_lod",
 	"high_lod",
-	"physics_shape"
+	"physics_mesh"
 };
 
 const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
@@ -1403,25 +1403,15 @@ LLSD LLModel::writeModel(
 	if (!decomp.mBaseHull.empty() ||
 		!decomp.mHull.empty())		
 	{
-		mdl["decomposition"] = decomp.asLLSD();
+		mdl["physics_convex"] = decomp.asLLSD();
 	}
 
 	for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx)
 	{
 		if (model[idx] && model[idx]->getNumVolumeFaces() > 0)
 		{
-			LLVector3 min_pos = LLVector3(model[idx]->getVolumeFace(0).mPositions[0].getF32ptr());
-			LLVector3 max_pos = min_pos;
-
-			//find position domain
-			for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i)
-			{ //for each face
-				const LLVolumeFace& face = model[idx]->getVolumeFace(i);
-				for (U32 j = 0; j < face.mNumVertices; ++j)
-				{
-					update_min_max(min_pos, max_pos, face.mPositions[j].getF32ptr());
-				}
-			}
+			LLVector3 min_pos(-0.5f, -0.5f, -0.5f);
+			LLVector3 max_pos(0.5f, 0.5f, 0.5f);
 
 			LLVector3 pos_range = max_pos - min_pos;
 
@@ -1462,6 +1452,7 @@ LLSD LLModel::writeModel(
 					//position + normal
 					for (U32 k = 0; k < 3; ++k)
 					{ //for each component
+						llassert(pos[k] <= 0.5001f && pos[k] >= -0.5001f);
 
 						//convert to 16-bit normalized across domain
 						U16 val = (U16) (((pos[k]-min_pos.mV[k])/pos_range.mV[k])*65535);
@@ -1504,9 +1495,6 @@ 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();
 
@@ -1608,15 +1596,15 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
 
 	std::string decomposition;
 
-	if (mdl.has("decomposition"))
+	if (mdl.has("physics_convex"))
 	{ //write out convex decomposition
-		decomposition = zip_llsd(mdl["decomposition"]);
+		decomposition = zip_llsd(mdl["physics_convex"]);
 
 		U32 size = decomposition.size();
 		if (size > 0)
 		{
-			header["decomposition"]["offset"] = (LLSD::Integer) cur_offset;
-			header["decomposition"]["size"] = (LLSD::Integer) size;
+			header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset;
+			header["physics_convex"]["size"] = (LLSD::Integer) size;
 			cur_offset += size;
 			bytes += size;
 		}
@@ -1637,11 +1625,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
 			cur_offset += size;
 			bytes += size;
 		}
-		else
-		{
-			header[model_names[i]]["offset"] = -1;
-			header[model_names[i]]["size"] = 0;
-		}
 	}
 
 	if (!nowrite)
@@ -1655,7 +1638,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
 
 		if (!decomposition.empty())
 		{ //write decomposition block
-			ostr.write((const char*) decomposition.data(), header["decomposition"]["size"].asInteger());
+			ostr.write((const char*) decomposition.data(), header["physics_convex"]["size"].asInteger());
 		}
 
 		for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++)
@@ -1794,7 +1777,7 @@ bool LLModel::loadModel(std::istream& is)
 		"low_lod",
 		"medium_lod",
 		"high_lod",
-		"physics_shape",
+		"physics_mesh",
 	};
 
 	const S32 MODEL_LODS = 5;
@@ -1893,8 +1876,8 @@ bool LLModel::loadSkinInfo(LLSD& header, std::istream &is)
 
 bool LLModel::loadDecomposition(LLSD& header, std::istream& is)
 {
-	S32 offset = header["decomposition"]["offset"].asInteger();
-	S32 size = header["decomposition"]["size"].asInteger();
+	S32 offset = header["physics_convex"]["offset"].asInteger();
+	S32 size = header["physics_convex"]["size"].asInteger();
 
 	if (offset >= 0 && size > 0)
 	{
@@ -2040,15 +2023,10 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
 
 		mHull.resize(hulls.size());
 
-		LLVector3 min;
-		LLVector3 max;
-		LLVector3 range;
-
-		min.setValue(decomp["Min"]);
-		max.setValue(decomp["Max"]);
-		range = max-min;
+		LLVector3 min(-0.5f,-0.5f,-0.5f);
+		LLVector3 max(0.5f,0.5f,0.5f);
+		LLVector3 range = max-min;
 
-		
 		for (U32 i = 0; i < hulls.size(); ++i)
 		{
 			U16 count = (hulls[i] == 0) ? 256 : hulls[i];
@@ -2064,6 +2042,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
 				//point must be unique
 				//llassert(valid.find(test) == valid.end());
 				valid.insert(test);
+
 				mHull[i].push_back(LLVector3(
 					(F32) p[0]/65535.f*range.mV[0]+min.mV[0],
 					(F32) p[1]/65535.f*range.mV[1]+min.mV[1],
@@ -2078,28 +2057,15 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
 		}
 	}
 
-	if (decomp.has("Hull"))
+	if (decomp.has("BoundingVerts"))
 	{
-		const LLSD::Binary& position = decomp["Hull"].asBinary();
+		const LLSD::Binary& position = decomp["BundingVerts"].asBinary();
 
 		U16* p = (U16*) &position[0];
 
-		LLVector3 min;
-		LLVector3 max;
-		LLVector3 range;
-
-		if (decomp.has("Min"))
-		{
-			min.setValue(decomp["Min"]);
-			max.setValue(decomp["Max"]);
-		}
-		else
-		{
-			min.set(-0.5f, -0.5f, -0.5f);
-			max.set(0.5f, 0.5f, 0.5f);
-		}
-
-		range = max-min;
+		LLVector3 min(-0.5f,-0.5f,-0.5f);
+		LLVector3 max(0.5f,0.5f,0.5f);
+		LLVector3 range = max-min;
 
 		U16 count = position.size()/6;
 		
@@ -2130,26 +2096,11 @@ LLSD LLModel::Decomposition::asLLSD() const
 	}
 
 	//write decomposition block
-	// ["decomposition"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points
-	// ["decomposition"]["PositionDomain"]["Min"/"Max"]
-	// ["decomposition"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
-	// ["decomposition"]["Hull"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
-	
+	// ["physics_convex"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points
+	// ["physics_convex"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
+	// ["physics_convex"]["BoundingVerts"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
 	
-	//get minimum and maximum
-	LLVector3 min;
 	
-	if (mHull.empty())
-	{  
-		min = mBaseHull[0];
-	}
-	else
-	{
-		min = mHull[0][0];
-	}
-
-	LLVector3 max = min;
-
 	LLSD::Binary hulls(mHull.size());
 
 	U32 total = 0;
@@ -2159,21 +2110,8 @@ LLSD LLModel::Decomposition::asLLSD() const
 		U32 size = mHull[i].size();
 		total += size;
 		hulls[i] = (U8) (size);
-
-		for (U32 j = 0; j < mHull[i].size(); ++j)
-		{
-			update_min_max(min, max, mHull[i][j]);
-		}
-	}
-
-	for (U32 i = 0; i < mBaseHull.size(); ++i)
-	{
-		update_min_max(min, max, mBaseHull[i]);	
 	}
 
-	ret["Min"] = min.getValue();
-	ret["Max"] = max.getValue();
-
 	if (!hulls.empty())
 	{
 		ret["HullList"] = hulls;
@@ -2183,6 +2121,8 @@ LLSD LLModel::Decomposition::asLLSD() const
 	{
 		LLSD::Binary p(total*3*2);
 
+		LLVector3 min(-0.5f, -0.5f, -0.5f);
+		LLVector3 max(0.5f, 0.5f, 0.5f);
 		LLVector3 range = max-min;
 
 		U32 vert_idx = 0;
@@ -2198,6 +2138,8 @@ LLSD LLModel::Decomposition::asLLSD() const
 				U64 test = 0;
 				for (U32 k = 0; k < 3; k++)
 				{
+					llassert(mHull[i][j].mV[k] <= 0.50001f && mHull[i][j].mV[k] >= -0.50001f);
+
 					//convert to 16-bit normalized across domain
 					U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535);
 
@@ -2231,6 +2173,8 @@ LLSD LLModel::Decomposition::asLLSD() const
 	{
 		LLSD::Binary p(mBaseHull.size()*3*2);
 
+		LLVector3 min(-0.5f, -0.5f, -0.5f);
+		LLVector3 max(0.5f, 0.5f, 0.5f);
 		LLVector3 range = max-min;
 
 		U32 vert_idx = 0;
@@ -2238,6 +2182,8 @@ LLSD LLModel::Decomposition::asLLSD() const
 		{
 			for (U32 k = 0; k < 3; k++)
 			{
+				llassert(mBaseHull[j].mV[k] <= 0.50001f && mBaseHull[j].mV[k] >= -0.50001f);
+
 				//convert to 16-bit normalized across domain
 				U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535);
 
@@ -2253,7 +2199,7 @@ LLSD LLModel::Decomposition::asLLSD() const
 			}
 		}
 		
-		ret["Hull"] = p;
+		ret["BoundingVerts"] = p;
 	}
 
 	return ret;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index dd2ffdf7f1..013fc43f99 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -772,8 +772,8 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 
 	if (header_size > 0)
 	{
-		S32 offset = header_size + mMeshHeader[mesh_id]["decomposition"]["offset"].asInteger();
-		S32 size = mMeshHeader[mesh_id]["decomposition"]["size"].asInteger();
+		S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger();
+		S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger();
 
 		mHeaderMutex->unlock();
 
@@ -844,8 +844,8 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 
 	if (header_size > 0)
 	{
-		S32 offset = header_size + mMeshHeader[mesh_id]["physics_shape"]["offset"].asInteger();
-		S32 size = mMeshHeader[mesh_id]["physics_shape"]["size"].asInteger();
+		S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger();
+		S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger();
 
 		mHeaderMutex->unlock();
 
@@ -1927,7 +1927,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
 		
 		//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["decomposition"]["offset"].asInteger() + header["decomposition"]["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; 
@@ -2543,7 +2543,7 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
 bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
 {
 	LLSD mesh = mThread->getMeshHeader(mesh_id);
-	return mesh.has("physics_shape") && mesh["physics_shape"].has("size") && (mesh["physics_shape"]["size"].asInteger() > 0);
+	return mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0);
 }
 
 LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
-- 
cgit v1.2.3


From 3c516973f3a508d2bf0060d8dc70fa0d7809340f Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 5 May 2011 17:12:41 -0500
Subject: SH-1497 "Positions" not "Position" for convex decomp.

---
 indra/llprimitive/llmodel.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 66b5150ed4..ebd2fc7a29 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -2017,7 +2017,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
 	{
 		// updated for const-correctness. gcc is picky about this type of thing - Nyx
 		const LLSD::Binary& hulls = decomp["HullList"].asBinary();
-		const LLSD::Binary& position = decomp["Position"].asBinary();
+		const LLSD::Binary& position = decomp["Positions"].asBinary();
 
 		U16* p = (U16*) &position[0];
 
@@ -2166,7 +2166,7 @@ LLSD LLModel::Decomposition::asLLSD() const
 			llassert(valid.size() > 3);
 		}
 
-		ret["Position"] = p;
+		ret["Positions"] = p;
 	}
 
 	if (!mBaseHull.empty())
-- 
cgit v1.2.3


From ca0a568264ca1f9990b2450cc55f3cc011d59e63 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 5 May 2011 18:33:03 -0500
Subject: SH-1497 Don't upload physics mesh if decomposition exists.

---
 indra/llprimitive/llmodel.cpp | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index ebd2fc7a29..e9e212c5c6 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1404,6 +1404,10 @@ LLSD LLModel::writeModel(
 		!decomp.mHull.empty())		
 	{
 		mdl["physics_convex"] = decomp.asLLSD();
+		if (!decomp.mHull.empty())
+		{ //convex decomposition exists, physics mesh will not be used
+			model[LLModel::LOD_PHYSICS] = NULL;
+		}
 	}
 
 	for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx)
@@ -2138,10 +2142,12 @@ LLSD LLModel::Decomposition::asLLSD() const
 				U64 test = 0;
 				for (U32 k = 0; k < 3; k++)
 				{
-					llassert(mHull[i][j].mV[k] <= 0.50001f && mHull[i][j].mV[k] >= -0.50001f);
+					F32* src = (F32*) (mHull[i][j].mV);
+
+					llassert(src[k] <= 0.501f && src[k] >= -0.501f);
 
 					//convert to 16-bit normalized across domain
-					U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535);
+					U16 val = (U16) (((src[k]-min.mV[k])/range.mV[k])*65535);
 
 					switch (k)
 					{
-- 
cgit v1.2.3


From 3acc3d39f0309a8e812838e22a8ff3eafe8da195 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 11 May 2011 19:13:18 -0500
Subject: Put back "PositionDomain" and "Min"/"Max" on convex decomposition.

---
 indra/llprimitive/llmodel.cpp | 82 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 72 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index e9e212c5c6..24d9a3a1e2 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1414,8 +1414,18 @@ LLSD LLModel::writeModel(
 	{
 		if (model[idx] && model[idx]->getNumVolumeFaces() > 0)
 		{
-			LLVector3 min_pos(-0.5f, -0.5f, -0.5f);
-			LLVector3 max_pos(0.5f, 0.5f, 0.5f);
+			LLVector3 min_pos = LLVector3(model[idx]->getVolumeFace(0).mPositions[0].getF32ptr());
+			LLVector3 max_pos = min_pos;
+
+			//find position domain
+			for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i)
+			{ //for each face
+				const LLVolumeFace& face = model[idx]->getVolumeFace(i);
+				for (U32 j = 0; j < face.mNumVertices; ++j)
+				{
+					update_min_max(min_pos, max_pos, face.mPositions[j].getF32ptr());
+				}
+			}
 
 			LLVector3 pos_range = max_pos - min_pos;
 
@@ -1456,8 +1466,6 @@ LLSD LLModel::writeModel(
 					//position + normal
 					for (U32 k = 0; k < 3; ++k)
 					{ //for each component
-						llassert(pos[k] <= 0.5001f && pos[k] >= -0.5001f);
-
 						//convert to 16-bit normalized across domain
 						U16 val = (U16) (((pos[k]-min_pos.mV[k])/pos_range.mV[k])*65535);
 
@@ -1499,6 +1507,8 @@ 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();
 
@@ -2027,9 +2037,22 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
 
 		mHull.resize(hulls.size());
 
-		LLVector3 min(-0.5f,-0.5f,-0.5f);
-		LLVector3 max(0.5f,0.5f,0.5f);
-		LLVector3 range = max-min;
+		LLVector3 min;
+		LLVector3 max;
+		LLVector3 range;
+
+		if (decomp.has("Min"))
+		{
+			min.setValue(decomp["Min"]);
+			max.setValue(decomp["Max"]);
+		}
+		else
+		{
+			min.set(-0.5f, -0.5f, -0.5f);
+			max.set(0.5f, 0.5f, 0.5f);
+		}
+
+		range = max-min;
 
 		for (U32 i = 0; i < hulls.size(); ++i)
 		{
@@ -2067,9 +2090,22 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
 
 		U16* p = (U16*) &position[0];
 
-		LLVector3 min(-0.5f,-0.5f,-0.5f);
-		LLVector3 max(0.5f,0.5f,0.5f);
-		LLVector3 range = max-min;
+		LLVector3 min;
+		LLVector3 max;
+		LLVector3 range;
+
+		if (decomp.has("Min"))
+		{
+			min.setValue(decomp["Min"]);
+			max.setValue(decomp["Max"]);
+		}
+		else
+		{
+			min.set(-0.5f, -0.5f, -0.5f);
+			max.set(0.5f, 0.5f, 0.5f);
+		}
+
+		range = max-min;
 
 		U16 count = position.size()/6;
 		
@@ -2104,7 +2140,20 @@ LLSD LLModel::Decomposition::asLLSD() const
 	// ["physics_convex"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
 	// ["physics_convex"]["BoundingVerts"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
 	
+	//get minimum and maximum
+	LLVector3 min;
 	
+	if (mHull.empty())
+	{  
+		min = mBaseHull[0];
+	}
+	else
+	{
+		min = mHull[0][0];
+	}
+
+	LLVector3 max = min;
+
 	LLSD::Binary hulls(mHull.size());
 
 	U32 total = 0;
@@ -2114,8 +2163,21 @@ LLSD LLModel::Decomposition::asLLSD() const
 		U32 size = mHull[i].size();
 		total += size;
 		hulls[i] = (U8) (size);
+
+		for (U32 j = 0; j < mHull[i].size(); ++j)
+		{
+			update_min_max(min, max, mHull[i][j]);
+		}
 	}
 
+	for (U32 i = 0; i < mBaseHull.size(); ++i)
+	{
+		update_min_max(min, max, mBaseHull[i]);	
+	}
+
+	ret["Min"] = min.getValue();
+	ret["Max"] = max.getValue();
+
 	if (!hulls.empty())
 	{
 		ret["HullList"] = hulls;
-- 
cgit v1.2.3


From d79468057c954a05acdb9dd69d398dd004425ec0 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Wed, 25 May 2011 16:08:21 -0400
Subject: SH-1492 WIP

---
 indra/newview/llmeshrepository.cpp | 155 +++++++++++++++++++------------------
 1 file changed, 81 insertions(+), 74 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index b79f120eda..79541e49d3 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;
-- 
cgit v1.2.3


From 081ba71f9632153efa86df07b33c28471b31e2cb Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Wed, 25 May 2011 18:36:01 -0400
Subject: SH-1492 WIP

---
 indra/newview/llmeshrepository.cpp | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 79541e49d3..d4be311be8 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -62,6 +62,8 @@
 #include "llinventorymodel.h"
 #include "llfoldertype.h"
 
+#include "boost/lexical_cast.hpp"
+
 #ifndef LL_WINDOWS
 #include "netdb.h"
 #endif
@@ -85,6 +87,12 @@ U32 LLMeshRepository::sPeakKbps = 0;
 
 const U32 MAX_TEXTURE_UPLOAD_RETRIES = 5;
 
+static S32 dump_num = 0;
+std::string make_dump_name(std::string prefix, S32 num)
+{
+	return prefix + boost::lexical_cast<std::string>(num) + std::string(".xml");
+	
+}
 void dumpLLSDToFile(const LLSD& content, std::string filename);
 
 std::string header_lod[] = 
@@ -498,7 +506,7 @@ public:
 		//assert_main_thread();
 		llinfos << "completed" << llendl;
 		mThread->mPendingUploads--;
-		dumpLLSDToFile(content,"whole_model_fee_response.xml");
+		dumpLLSDToFile(content,make_dump_name("whole_model_fee_response_",dump_num));
 		if (isGoodStatus(status))
 		{
 			mThread->mWholeModelUploadURL = content["uploader"].asString(); 
@@ -530,7 +538,7 @@ public:
 		//assert_main_thread();
 		llinfos << "upload completed" << llendl;
 		mThread->mPendingUploads--;
-		dumpLLSDToFile(content,"whole_model_upload_response.xml");
+		dumpLLSDToFile(content,make_dump_name("whole_model_upload_response_",dump_num));
 		// requested "mesh" asset type isn't actually the type
 		// of the resultant object, fix it up here.
 		mPostData["asset_type"] = "object";
@@ -1437,6 +1445,12 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 	{
 		LLMeshUploadData data;
 		data.mBaseModel = iter->first;
+		LLModelInstance& first_instance = *(iter->second.begin());
+		for (S32 i = 0; i < 5; i++)
+		{
+			data.mModel[i] = first_instance.mLOD[i];
+		}
+
 		if (mesh_index.find(data.mBaseModel) == mesh_index.end())
 		{
 			// Have not seen this model before - create a new mesh_list entry for it.
@@ -1573,13 +1587,15 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 	}
 
 	result["asset_resources"] = res;
-	dumpLLSDToFile(result,"whole_model.xml");
+	dumpLLSDToFile(result,make_dump_name("whole_model_",dump_num));
 
 	dest = result;
 }
 
 void LLMeshUploadThread::doWholeModelUpload()
 {
+	dump_num++;
+	
 	mCurlRequest = new LLCurlRequest();	
 
 	// Queue up models for hull generation (viewer-side)
@@ -1627,7 +1643,7 @@ void LLMeshUploadThread::doWholeModelUpload()
 
 	LLSD model_data;
 	wholeModelToLLSD(model_data,false);
-	dumpLLSDToFile(model_data,"whole_model_fee_request.xml");
+	dumpLLSDToFile(model_data,make_dump_name("whole_model_fee_request_",dump_num));
 
 	mPendingUploads++;
 	LLCurlRequest::headers_t headers;
@@ -1649,7 +1665,7 @@ void LLMeshUploadThread::doWholeModelUpload()
 		LLSD full_model_data;
 		wholeModelToLLSD(full_model_data, true);
 		LLSD body = full_model_data["asset_resources"];
-		dumpLLSDToFile(body,"whole_model_body.xml");
+		dumpLLSDToFile(body,make_dump_name("whole_model_body_",dump_num));
 		mCurlRequest->post(mWholeModelUploadURL, headers, body,
 						   new LLWholeModelUploadResponder(this, model_data));
 		do
@@ -3317,8 +3333,8 @@ bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const
 void LLMeshRepository::updateInventory(inventory_data data)
 {
 	LLMutexLock lock(mMeshMutex);
-	dumpLLSDToFile(data.mPostData,"update_inventory_post_data.xml");
-	dumpLLSDToFile(data.mResponse,"update_inventory_response.xml");
+	dumpLLSDToFile(data.mPostData,make_dump_name("update_inventory_post_data_",dump_num));
+	dumpLLSDToFile(data.mResponse,make_dump_name("update_inventory_response_",dump_num));
 	mInventoryQ.push(data);
 }
 
-- 
cgit v1.2.3


From 8b552a25c4fb1e9babdd52c5a5acee3540f353ac Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Thu, 26 May 2011 13:56:12 -0400
Subject: SH-1492 WIP - include face info even if textures not being uploaded

---
 indra/newview/llmeshrepository.cpp | 88 ++++++++++++++++++--------------------
 1 file changed, 42 insertions(+), 46 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d4be311be8..7c75599a15 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1525,60 +1525,56 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 			instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
 			instance_entry["mesh"] = mesh_index[data.mBaseModel];
 
-			if (mUploadTextures)
+			instance_entry["face_list"] = LLSD::emptyArray();
+
+			for (S32 face_num = 0; face_num < data.mBaseModel->getNumVolumeFaces(); face_num++)
 			{
-				instance_entry["face_list"] = LLSD::emptyArray();
+				LLImportMaterial& material = instance.mMaterial[face_num];
+				LLSD face_entry = LLSD::emptyMap();
+				LLViewerFetchedTexture *texture = material.mDiffuseMap.get();
+				
+				if ((texture != NULL) &&
+					(textures.find(texture) == textures.end()))
+				{
+					textures.insert(texture);
+				}
 
-				for (S32 face_num = 0; face_num < data.mBaseModel->getNumVolumeFaces(); face_num++)
+				std::stringstream texture_str;
+				if (texture != NULL && include_textures && mUploadTextures)
 				{
-					LLImportMaterial& material = instance.mMaterial[face_num];
-					LLSD face_entry = LLSD::emptyMap();
-					LLViewerFetchedTexture *texture = material.mDiffuseMap.get();
-				
-					if (texture != NULL)
+					// Get binary rep of texture, if needed.
+					LLTextureUploadData data(texture, material.mDiffuseMapLabel);
+					if (!data.mTexture->isRawImageValid())
 					{
-						if (textures.find(texture) == textures.end())
-						{
-							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());
-							}
+						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());
+					texture_str.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())
+				{
+					texture_index[texture] = texture_num;
+					std::string str = texture_str.str();
+					res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
+					texture_num++;
+				}
 
-					// 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;
+				// 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;
-- 
cgit v1.2.3


From 01c5e12853b60d6f9ddc4f32b1450548beb09736 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Thu, 26 May 2011 18:22:14 -0400
Subject: SH-1492 WIP

---
 indra/newview/llmeshrepository.cpp | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 7c75599a15..5074caccb6 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1554,7 +1554,9 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 					texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
 				}
 
-				if (texture_index.find(texture) == texture_index.end())
+				if (texture != NULL &&
+					mUploadTextures &&
+					texture_index.find(texture) == texture_index.end())
 				{
 					texture_index[texture] = texture_num;
 					std::string str = texture_str.str();
@@ -1563,15 +1565,15 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 				}
 
 				// Subset of TextureEntry fields.
-				if (texture)
+				if (texture != NULL && mUploadTextures)
 				{
 					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["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;
-- 
cgit v1.2.3


From 31e850d04885bed2ac779c66bb6b7923a0a51d96 Mon Sep 17 00:00:00 2001
From: Roxie Linden <roxie@lindenlab.com>
Date: Fri, 27 May 2011 11:50:39 -0700
Subject: transplant fix for SH-1467 viewer now uses simulatorfeatures to check
 whether to show UI elements for mesh or not

---
 indra/llmessage/message_prehash.cpp   |  1 +
 indra/llmessage/message_prehash.h     |  1 +
 indra/newview/llfloaterregioninfo.cpp |  5 ++-
 indra/newview/llfloatertools.cpp      |  7 ++---
 indra/newview/llmanipscale.cpp        |  5 ++-
 indra/newview/llmeshrepository.cpp    | 31 +++++++++++++++++++
 indra/newview/llmeshrepository.h      |  4 +++
 indra/newview/llpanelobject.cpp       |  5 ++-
 indra/newview/llpanelvolume.cpp       | 14 +++++++--
 indra/newview/llviewermenufile.cpp    |  4 +--
 indra/newview/llviewerregion.cpp      | 57 +++++++++++++++++++++++++++++++++++
 indra/newview/llviewerregion.h        |  4 +++
 indra/newview/llviewerwindow.cpp      |  2 +-
 13 files changed, 120 insertions(+), 20 deletions(-)

(limited to 'indra')

diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 5d03615e53..6133f50637 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -742,6 +742,7 @@ char const* const _PREHASH_MoneyData = LLMessageStringTable::getInstance()->getS
 char const* const _PREHASH_ObjectDeselect = LLMessageStringTable::getInstance()->getString("ObjectDeselect");
 char const* const _PREHASH_NewAssetID = LLMessageStringTable::getInstance()->getString("NewAssetID");
 char const* const _PREHASH_ObjectAdd = LLMessageStringTable::getInstance()->getString("ObjectAdd");
+char const* const _PREHASH_SimulatorFeatures = LLMessageStringTable::getInstance()->getString("SimulatorFeatures");
 char const* const _PREHASH_RayEndIsIntersection = LLMessageStringTable::getInstance()->getString("RayEndIsIntersection");
 char const* const _PREHASH_CompleteAuction = LLMessageStringTable::getInstance()->getString("CompleteAuction");
 char const* const _PREHASH_CircuitCode = LLMessageStringTable::getInstance()->getString("CircuitCode");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 8dc86601e6..f94ee1ed22 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -742,6 +742,7 @@ extern char const* const _PREHASH_MoneyData;
 extern char const* const _PREHASH_ObjectDeselect;
 extern char const* const _PREHASH_NewAssetID;
 extern char const* const _PREHASH_ObjectAdd;
+extern char const* const _PREHASH_SimulatorFeatures;
 extern char const* const _PREHASH_RayEndIsIntersection;
 extern char const* const _PREHASH_CompleteAuction;
 extern char const* const _PREHASH_CircuitCode;
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index fc6976755f..6b3e3088d5 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -82,6 +82,7 @@
 #include "llvlcomposition.h"
 #include "lltrans.h"
 #include "llagentui.h"
+#include "llmeshrepository.h"
 
 const S32 TERRAIN_TEXTURE_COUNT = 4;
 const S32 CORNER_COUNT = 4;
@@ -590,9 +591,7 @@ bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region)
 	getChildView("im_btn")->setEnabled(allow_modify);
 	getChildView("manage_telehub_btn")->setEnabled(allow_modify);
 
-	const bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") && 
-		gAgent.getRegion() &&
-		!gAgent.getRegion()->getCapability("GetMesh").empty();
+	const bool enable_mesh = gMeshRepo.meshRezEnabled();
 	getChildView("mesh_rez_enabled_check")->setVisible(enable_mesh);
 	getChildView("mesh_rez_enabled_check")->setEnabled(getChildView("mesh_rez_enabled_check")->getEnabled() && enable_mesh);
 	// Data gets filled in by processRegionInfo
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 061a42ab57..0f11d05175 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -86,6 +86,7 @@
 #include "llvovolume.h"
 #include "lluictrlfactory.h"
 #include "llaccountingquotamanager.h"
+#include "llmeshrepository.h"
 
 // Globals
 LLFloaterTools *gFloaterTools = NULL;
@@ -423,7 +424,7 @@ void LLFloaterTools::refresh()
 	// Refresh object and prim count labels
 	LLLocale locale(LLLocale::USER_LOCALE);
 
-	if ((gAgent.getRegion() && gAgent.getRegion()->getCapability("GetMesh").empty()) || !gSavedSettings.getBOOL("MeshEnabled"))
+	if (gMeshRepo.meshRezEnabled())
 	{		
 		std::string obj_count_string;
 		LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount());
@@ -788,9 +789,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 		getChildView("Strength:")->setVisible( land_visible);
 	}
 
-	bool show_mesh_cost = gAgent.getRegion() && 
-		                  !gAgent.getRegion()->getCapability("GetMesh").empty() && 
-						  gSavedSettings.getBOOL("MeshEnabled");
+	bool show_mesh_cost = gMeshRepo.meshRezEnabled();
 
 	getChildView("obj_count")->setVisible( !land_visible && !show_mesh_cost);
 	getChildView("prim_count")->setVisible( !land_visible && !show_mesh_cost);
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 738d82e732..4eb94dfb8e 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -58,6 +58,7 @@
 #include "llworld.h"
 #include "v2math.h"
 #include "llvoavatar.h"
+#include "llmeshrepository.h"
 
 
 const F32 MAX_MANIP_SELECT_DISTANCE_SQUARED = 11.f * 11.f;
@@ -90,9 +91,7 @@ F32 get_default_max_prim_scale(bool is_flora)
 {
 	// a bit of a hack, but if it's foilage, we don't want to use the
 	// new larger scale which would result in giant trees and grass
-	if (gSavedSettings.getBOOL("MeshEnabled") && 
-		gAgent.getRegion() && 
-		!gAgent.getRegion()->getCapability("GetMesh").empty() &&
+	if (gMeshRepo.meshRezEnabled() &&
 		!is_flora)
 	{
 		return DEFAULT_MAX_PRIM_SCALE;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 4464d299ed..4e75219c3e 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -61,6 +61,7 @@
 #include "pipeline.h"
 #include "llinventorymodel.h"
 #include "llfoldertype.h"
+#include "llviewerparcelmgr.h"
 
 #include "boost/lexical_cast.hpp"
 
@@ -3957,3 +3958,33 @@ void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp)
 		}
 	}
 }
+
+bool LLMeshRepository::meshUploadEnabled()
+{
+	LLViewerRegion *region = gAgent.getRegion();
+	if(gSavedSettings.getBOOL("MeshEnabled") && 
+	   LLViewerParcelMgr::getInstance()->allowAgentBuild() &&
+	   region)
+	{
+		LLSD sim_features;
+		region->getSimulatorFeatures(sim_features);
+		return (sim_features.has("MeshUploadEnabled") &&
+				sim_features["MeshUploadEnabled"].asBoolean());
+	}
+	return false;
+}
+
+bool LLMeshRepository::meshRezEnabled()
+{
+	LLViewerRegion *region = gAgent.getRegion();
+	if(gSavedSettings.getBOOL("MeshEnabled") && 
+	   region)
+	{
+		LLSD sim_features;
+		region->getSimulatorFeatures(sim_features);
+		return (sim_features.has("MeshRezEnabled") &&
+				sim_features["MeshRezEnabled"].asBoolean());
+	}
+	return false;
+}
+
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 0a6954bade..44cf7dadf6 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -482,6 +482,10 @@ public:
 	
 	void buildHull(const LLVolumeParams& params, S32 detail);
 	void buildPhysicsMesh(LLModel::Decomposition& decomp);
+	
+	bool meshUploadEnabled();
+	bool meshRezEnabled();
+	
 
 	LLSD& getMeshHeader(const LLUUID& mesh_id);
 
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 34a92cd0ac..61241e3ce5 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -64,6 +64,7 @@
 #include "pipeline.h"
 #include "llviewercontrol.h"
 #include "lluictrlfactory.h"
+#include "llmeshrepository.h"
 //#include "llfirstuse.h"
 
 #include "lldrawpool.h"
@@ -1740,9 +1741,7 @@ void LLPanelObject::refresh()
 		mRootObject = NULL;
 	}
 	
-	bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") && 
-					   gAgent.getRegion() &&
-					   !gAgent.getRegion()->getCapability("GetMesh").empty();
+	bool enable_mesh = gMeshRepo.meshRezEnabled();
 
 	F32 max_scale = get_default_max_prim_scale(LLPickInfo::isFlora(mObject));
 
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index ebddaa90bc..bb87601d20 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -530,16 +530,24 @@ void LLPanelVolume::refresh()
 	getChildView("Light Ambiance")->setVisible( visible);
 	getChildView("light texture control")->setVisible( visible);
 
-	bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") && 
-					   gAgent.getRegion() &&
-					   !gAgent.getRegion()->getCapability("GetMesh").empty();
+	bool enable_mesh = false;
 
+	LLSD sim_features;
+	LLViewerRegion *region = gAgent.getRegion();
+	if(region)
+	{
+		LLSD sim_features;
+		region->getSimulatorFeatures(sim_features);		 
+		enable_mesh = sim_features.has("PhysicsShapeTypes");
+	}
 	getChildView("label physicsshapetype")->setVisible(enable_mesh);
 	getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh);
 	getChildView("Physics Gravity")->setVisible(enable_mesh);
 	getChildView("Physics Friction")->setVisible(enable_mesh);
 	getChildView("Physics Density")->setVisible(enable_mesh);
 	getChildView("Physics Restitution")->setVisible(enable_mesh);
+	
+    /* TODO: add/remove individual physics shape types as per the PhysicsShapeTypes simulator features */
 }
 
 
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 37640ad0d4..b2080a5b82 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -107,9 +107,7 @@ class LLMeshUploadVisible : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		return gSavedSettings.getBOOL("MeshEnabled") && 
-			   LLViewerParcelMgr::getInstance()->allowAgentBuild() && 
-			   !gAgent.getRegion()->getCapability("ObjectAdd").empty();
+		return gMeshRepo.meshUploadEnabled();
 	}
 };
 
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index fb608b3a4f..41437329c1 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -69,6 +69,7 @@
 #include "llspatialpartition.h"
 #include "stringize.h"
 #include "llviewercontrol.h"
+#include "llsdserialize.h"
 
 #ifdef LL_WINDOWS
 	#pragma warning(disable:4355)
@@ -1140,6 +1141,20 @@ void LLViewerRegion::getInfo(LLSD& info)
 	info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
 }
 
+void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features)
+{
+	sim_features = mSimulatorFeatures;
+}
+
+void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
+{
+	std::stringstream str;
+	
+	LLSDSerialize::toPrettyXML(sim_features, str);
+	llinfos << str.str() << llendl;
+	mSimulatorFeatures = sim_features;
+}
+
 LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)
 {
 	U32 local_id = objectp->getLocalID();
@@ -1559,6 +1574,42 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	LLHTTPClient::post(url, capabilityNames, mImpl->mHttpResponderPtr);
 }
 
+class SimulatorFeaturesReceived : public LLHTTPClient::Responder
+{
+	LOG_CLASS(SimulatorFeaturesReceived);
+public:
+    SimulatorFeaturesReceived(LLViewerRegion* region)
+	: mRegion(region)
+    { }
+	
+	
+    void error(U32 statusNum, const std::string& reason)
+    {
+		LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL;
+    }
+	
+    void result(const LLSD& content)
+    {
+		if(!mRegion) //region is removed or responder is not created.
+		{
+			return ;
+		}
+		
+		mRegion->setSimulatorFeatures(content);
+	}
+	
+    static boost::intrusive_ptr<SimulatorFeaturesReceived> build(
+																 LLViewerRegion* region)
+    {
+		return boost::intrusive_ptr<SimulatorFeaturesReceived>(
+															   new SimulatorFeaturesReceived(region));
+    }
+	
+private:
+	LLViewerRegion* mRegion;
+};
+
+
 void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
 {
 	if(name == "EventQueueGet")
@@ -1571,6 +1622,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
 	{
 		LLHTTPSender::setSender(mImpl->mHost, new LLCapHTTPSender(url));
 	}
+	else if (name == "SimulatorFeatures")
+	{
+		// kick off a request for simulator features
+		LLHTTPClient::get(url, new SimulatorFeaturesReceived(this));
+	}
 	else
 	{
 		mImpl->mCapabilities[name] = url;
@@ -1664,3 +1720,4 @@ std::string LLViewerRegion::getDescription() const
     return stringize(*this);
 }
 
+
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index a6e5c47b86..d936277231 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -276,6 +276,8 @@ public:
 
 	void getInfo(LLSD& info);
 	
+	void getSimulatorFeatures(LLSD& info);	
+	void setSimulatorFeatures(const LLSD& info);
 
 	typedef enum
 	{
@@ -401,6 +403,8 @@ private:
 	bool	mCapabilitiesReceived;
 
 	BOOL mReleaseNotesRequested;
+	
+	LLSD mSimulatorFeatures;
 };
 
 inline BOOL LLViewerRegion::getAllowDamage() const
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 6fe79c2e85..4ecf156646 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -601,7 +601,7 @@ public:
 			
 			ypos += y_inc;
 
-			if (gSavedSettings.getBOOL("MeshEnabled"))
+			if (gMeshRepo.meshRezEnabled())
 			{
 				addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f)));
 				
-- 
cgit v1.2.3


From b0a04b08f7b3cf4040b9708125a548e646b990f7 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 3 Jun 2011 00:13:50 -0500
Subject: SH-1744 Add havok's degenerate triangle check to importer.  Highlight
 degenerate triangles in physics mesh and block upload when degenerate
 triangles are present.

---
 indra/newview/llfloatermodelpreview.cpp | 160 +++++++++++++++++++++++++++++++-
 indra/newview/llmeshrepository.cpp      |   6 +-
 2 files changed, 161 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 2a3bd37129..b715f326a0 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -178,6 +178,80 @@ std::string lod_label_name[NUM_LOD+1] =
 	"I went off the end of the lod_label_name array.  Me so smart."
 };
 
+
+#define LL_DEGENERACY_TOLERANCE  1e-7f
+
+inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b)
+{
+    volatile F32 p0 = a[0] * b[0];
+    volatile F32 p1 = a[1] * b[1];
+    volatile F32 p2 = a[2] * b[2];
+    return p0 + p1 + p2;
+}
+
+bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE)
+{
+        // small area check
+        {
+                LLVector4a edge1; edge1.setSub( a, b );
+                LLVector4a edge2; edge2.setSub( a, c );
+                //////////////////////////////////////////////////////////////////////////
+                /// Linden Modified
+                //////////////////////////////////////////////////////////////////////////
+
+                // If no one edge is more than 10x longer than any other edge, we weaken
+                // the tolerance by a factor of 1e-4f.
+
+                LLVector4a edge3; edge3.setSub( c, b );
+				const F32 len1sq = edge1.dot3(edge1).getF32();
+                const F32 len2sq = edge2.dot3(edge2).getF32();
+                const F32 len3sq = edge3.dot3(edge3).getF32();
+                bool abOK = (len1sq <= 100.f * len2sq) && (len1sq <= 100.f * len3sq);
+                bool acOK = (len2sq <= 100.f * len1sq) && (len1sq <= 100.f * len3sq);
+                bool cbOK = (len3sq <= 100.f * len1sq) && (len1sq <= 100.f * len2sq);
+                if ( abOK && acOK && cbOK )
+                {
+                        tolerance *= 1e-4f;
+                }
+
+                //////////////////////////////////////////////////////////////////////////
+                /// End Modified
+                //////////////////////////////////////////////////////////////////////////
+
+                LLVector4a cross; cross.setCross3( edge1, edge2 );
+
+                LLVector4a edge1b; edge1b.setSub( b, a );
+                LLVector4a edge2b; edge2b.setSub( b, c );
+                LLVector4a crossb; crossb.setCross3( edge1b, edge2b );
+
+                if ( ( cross.dot3(cross).getF32() < tolerance ) || ( crossb.dot3(crossb).getF32() < tolerance ))
+                {
+                        return true;
+                }
+        }
+
+        // point triangle distance check
+        {
+                LLVector4a Q; Q.setSub(a, b);
+                LLVector4a R; R.setSub(c, b);
+
+                const F32 QQ = dot3fpu(Q, Q);
+                const F32 RR = dot3fpu(R, R);
+                const F32 QR = dot3fpu(R, Q);
+
+                volatile F32 QQRR = QQ * RR;
+                volatile F32 QRQR = QR * QR;
+                F32 Det = (QQRR - QRQR);
+
+                if( Det == 0.0f )
+                {
+                        return true;
+                }
+        }
+
+        return false;
+}
+
 bool validate_face(const LLVolumeFace& face)
 {
 	for (U32 i = 0; i < face.mNumIndices; ++i)
@@ -189,6 +263,31 @@ bool validate_face(const LLVolumeFace& face)
 		}
 	}
 
+	if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0)
+	{
+		llwarns << "Face has invalid number of indices." << llendl;
+		return false;
+	}
+
+	/*const LLVector4a scale(0.5f);
+
+	for (U32 i = 0; i < face.mNumIndices; i+=3)
+	{
+		U16 idx1 = face.mIndices[i];
+		U16 idx2 = face.mIndices[i+1];
+		U16 idx3 = face.mIndices[i+2];
+
+		LLVector4a v1; v1.setMul(face.mPositions[idx1], scale);
+		LLVector4a v2; v2.setMul(face.mPositions[idx2], scale);
+		LLVector4a v3; v3.setMul(face.mPositions[idx3], scale);
+
+		if (ll_is_degenerate(v1,v2,v3))
+		{
+			llwarns << "Degenerate face found!" << llendl;
+			return false;
+		}
+	}*/
+
 	return true;
 }
 
@@ -3752,7 +3851,35 @@ void LLModelPreview::updateStatusMessages()
 		mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
 	}
 
+	bool has_degenerate = false;
 
+	{//check for degenerate triangles in physics mesh
+		U32 lod = LLModel::LOD_PHYSICS;
+		const LLVector4a scale(0.5f);
+		for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i)
+		{ //for each model in the lod
+			if (mModel[lod][i]->mPhysics.mHull.empty())
+			{ //no decomp exists
+				S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
+				for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j)
+				{ //for each submesh (face), add triangles and vertices to current total
+					const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
+					for (S32 k = 0; k < face.mNumIndices && !has_degenerate; )
+					{
+						LLVector4a v1; v1.setMul(face.mPositions[face.mIndices[k++]], scale);
+						LLVector4a v2; v2.setMul(face.mPositions[face.mIndices[k++]], scale);
+						LLVector4a v3; v3.setMul(face.mPositions[face.mIndices[k++]], scale);
+
+						if (ll_is_degenerate(v1,v2,v3))
+						{
+							has_degenerate = true;
+						}
+					}
+				}
+			}
+		}
+	}
+	
 	mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
 
 	std::string mesh_status_na = mFMP->getString("mesh_status_na");
@@ -3853,7 +3980,10 @@ void LLModelPreview::updateStatusMessages()
 
 		for (U32 j = 0; upload_ok && j < mdl->mPhysics.mHull.size(); ++j)
 		{
-			upload_ok = upload_ok && mdl->mPhysics.mHull[i].size() <= 256;
+			if (mdl->mPhysics.mHull[j].size() > 256)
+			{
+				upload_ok = false;
+			}
 		}
 	}
 
@@ -3876,7 +4006,7 @@ void LLModelPreview::updateStatusMessages()
 		}
 	}
 	
-	if ( upload_ok && !errorStateFromLoader && skinAndRigOk )
+	if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate)
 	{
 		mFMP->childEnable("ok_btn");
 	}
@@ -4666,6 +4796,32 @@ BOOL LLModelPreview::render()
 							glLineWidth(3.f);
 							glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 							buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+
+							{ //show degenerate triangles
+								LLStrider<LLVector3> pos_strider; 
+								buffer->getVertexStrider(pos_strider, 0);
+								LLVector4a* pos = (LLVector4a*) pos_strider.get();
+							
+								LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+								LLGLDisable cull(GL_CULL_FACE);
+								LLStrider<U16> idx;
+								buffer->getIndexStrider(idx, 0);
+
+								glColor4f(1.f,0.f,0.f,1.f);
+								const LLVector4a scale(0.5f);
+								for (U32 i = 0; i < buffer->getNumIndices(); i += 3)
+								{
+									LLVector4a v1; v1.setMul(pos[*idx++], scale);
+									LLVector4a v2; v2.setMul(pos[*idx++], scale);
+									LLVector4a v3; v3.setMul(pos[*idx++], scale);
+
+									if (ll_is_degenerate(v1,v2,v3))
+									{
+										buffer->draw(LLRender::TRIANGLES, 3, i);
+									}
+								}
+							}
+
 							glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 							glLineWidth(1.f);
 						}
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 4464d299ed..4a8c644dbc 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1399,14 +1399,14 @@ BOOL LLMeshUploadThread::isDiscarded()
 
 void LLMeshUploadThread::run()
 {
-	if (gSavedSettings.getBOOL("MeshUseWholeModelUpload"))
+	//if (gSavedSettings.getBOOL("MeshUseWholeModelUpload"))
 	{
 		doWholeModelUpload();
 	}
-	else
+	/*else
 	{
 		doIterativeUpload();
-	}
+	}*/
 }
 
 void dumpLLSDToFile(const LLSD& content, std::string filename)
-- 
cgit v1.2.3


From 325c2b216907b84b02b425103b011a556222b474 Mon Sep 17 00:00:00 2001
From: Don Kjer <don@lindenlab.com>
Date: Mon, 6 Jun 2011 21:27:29 +0000
Subject: Removed the old mesh asset upload pipeline.  Fixed a problem with
 spamming MissingString MacLocale warnings.   Reviewed by Dave

---
 indra/llui/llresmgr.cpp                 |   2 +-
 indra/newview/llfloatermodelpreview.cpp |   2 +-
 indra/newview/llmeshrepository.cpp      | 265 +-------------------------------
 indra/newview/llmeshrepository.h        |   5 -
 indra/newview/llviewermenufile.cpp      |  73 +--------
 indra/newview/llviewermenufile.h        |  17 --
 indra/newview/llviewerregion.cpp        |   4 +-
 7 files changed, 6 insertions(+), 362 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp
index 39385786bc..820e7cb26a 100644
--- a/indra/llui/llresmgr.cpp
+++ b/indra/llui/llresmgr.cpp
@@ -337,7 +337,7 @@ LLLocale::LLLocale(const std::string& locale_string)
 	char* new_locale_string = setlocale( LC_ALL, locale_string.c_str());
 	if ( new_locale_string == NULL)
 	{
-		llwarns << "Failed to set locale " << locale_string << llendl;
+		LL_WARNS_ONCE("LLLocale") << "Failed to set locale " << locale_string << LL_ENDL;
 		setlocale(LC_ALL, SYSTEM_LOCALE.c_str());
 	}
 	//else
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index f21d60dd03..675edd7643 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1399,7 +1399,7 @@ bool LLModelLoader::doLoadModel()
 			if(model->getStatus() != LLModel::NO_ERRORS)
 			{
 				setLoadState(ERROR_PARSING + model->getStatus()) ;
-				return true ; //abort
+				return false; //abort
 			}
 
 			if (model.notNull() && validate_model(model))
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d8024b362e..a4dcd3cd52 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -507,6 +507,7 @@ public:
 		llinfos << "completed" << llendl;
 		mThread->mPendingUploads--;
 		dumpLLSDToFile(content,make_dump_name("whole_model_fee_response_",dump_num));
+		llinfos << "LLWholeModelFeeResponder content: " << content << llendl;
 		if (isGoodStatus(status))
 		{
 			mThread->mWholeModelUploadURL = content["uploader"].asString(); 
@@ -1302,8 +1303,6 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
 	mOrigin = gAgent.getPositionAgent();
 	mHost = gAgent.getRegionHost();
 	
-	mUploadObjectAssetCapability = gAgent.getRegion()->getCapability("UploadObjectAsset");
-	mNewInventoryCapability = gAgent.getRegion()->getCapability("NewFileAgentInventoryVariablePrice");
 	mWholeModelFeeCapability = gAgent.getRegion()->getCapability("NewFileAgentInventory");
 
 	mOrigin += gAgent.getAtAxis() * scale.magVec();
@@ -1393,14 +1392,7 @@ BOOL LLMeshUploadThread::isDiscarded()
 
 void LLMeshUploadThread::run()
 {
-	//if (gSavedSettings.getBOOL("MeshUseWholeModelUpload"))
-	{
-		doWholeModelUpload();
-	}
-	/*else
-	{
-		doIterativeUpload();
-	}*/
+	doWholeModelUpload();
 }
 
 void dumpLLSDToFile(const LLSD& content, std::string filename)
@@ -1670,163 +1662,6 @@ void LLMeshUploadThread::doWholeModelUpload()
 	mFinished = true;
 }
 
-void LLMeshUploadThread::doIterativeUpload()
-{
-	if(isDiscarded())
-	{
-		mFinished = true;
-		return ;
-	}
-	
-	mCurlRequest = new LLCurlRequest();	
-
-	std::set<LLViewerTexture* > textures;
-
-	//populate upload queue with relevant models
-	for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
-	{
-		LLMeshUploadData data;
-		data.mBaseModel = iter->first;
-
-		LLModelInstance& instance = *(iter->second.begin());
-
-		for (S32 i = 0; i < 5; i++)
-		{
-			data.mModel[i] = instance.mLOD[i];
-		}
-
-		uploadModel(data);
-
-		if (mUploadTextures)
-		{
-			for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin();
-				material_iter != instance.mMaterial.end(); ++material_iter)
-			{
-
-				if (textures.find(material_iter->mDiffuseMap.get()) == textures.end())
-				{
-					textures.insert(material_iter->mDiffuseMap.get());
-					
-					LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel);
-					uploadTexture(data);
-				}
-			}
-		}
-
-		//queue up models for hull generation
-		LLModel* physics = data.mModel[LLModel::LOD_PHYSICS];
-		if (physics == NULL)
-		{ //no physics model available, use high lod
-			physics = data.mModel[LLModel::LOD_HIGH];
-		}
-		
-		DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this);
-		gMeshRepo.mDecompThread->submitRequest(request);
-	}
-
-	while (!mPhysicsComplete)
-	{
-		apr_sleep(100);
-	}
-
-	//upload textures
-	bool done = false;
-	do
-	{
-		if (!mTextureQ.empty())
-		{
-			sendCostRequest(mTextureQ.front());
-			mTextureQ.pop();
-		}
-
-		if (!mConfirmedTextureQ.empty())
-		{
-			doUploadTexture(mConfirmedTextureQ.front());
-			mConfirmedTextureQ.pop();
-		}
-
-		mCurlRequest->process();
-
-		done = mTextureQ.empty() && mConfirmedTextureQ.empty();
-	}
-	while (!done || mCurlRequest->getQueued() > 0);
-
-	LLSD object_asset;
-	object_asset["objects"] = LLSD::emptyArray();
-
-	done = false;
-	do 
-	{
-		static S32 count = 0;
-		static F32 last_hundred = gFrameTimeSeconds;
-		if (gFrameTimeSeconds - last_hundred > 1.f)
-		{
-			last_hundred = gFrameTimeSeconds;
-			count = 0;
-		}
-
-		//how many requests to push before calling process
-		const S32 PUSH_PER_PROCESS = 32;
-
-		S32 tcount = llmin(count+PUSH_PER_PROCESS, 100);
-
-		while (!mUploadQ.empty() && count < tcount)
-		{ //send any pending upload requests
-			mMutex->lock();
-			LLMeshUploadData data = mUploadQ.front();
-			mUploadQ.pop();
-			mMutex->unlock();
-			sendCostRequest(data);
-			count++;
-		}
-
-		tcount = llmin(count+PUSH_PER_PROCESS, 100);
-		
-		while (!mConfirmedQ.empty() && count < tcount)
-		{ //process any meshes that have been confirmed for upload
-			LLMeshUploadData& data = mConfirmedQ.front();
-			doUploadModel(data);
-			mConfirmedQ.pop();
-			count++;
-		}
-	
-		tcount = llmin(count+PUSH_PER_PROCESS, 100);
-
-		while (!mInstanceQ.empty() && count < tcount && !isDiscarded())
-		{ //create any objects waiting for upload
-			count++;
-			object_asset["objects"].append(createObject(mInstanceQ.front()));
-			mInstanceQ.pop();
-		}
-			
-		mCurlRequest->process();
-			
-		done = isDiscarded() || (mInstanceQ.empty() && mConfirmedQ.empty() && mUploadQ.empty());
-	}
-	while (!done || mCurlRequest->getQueued() > 0);
-
-	delete mCurlRequest;
-	mCurlRequest = NULL;
-
-	// now upload the object asset
-	std::string url = mUploadObjectAssetCapability;
-
-	if (object_asset["objects"][0].has("permissions"))
-	{ //copy permissions from first available object to be used for coalesced object
-		object_asset["permissions"] = object_asset["objects"][0]["permissions"];
-	}
-
-	if(!isDiscarded())
-	{
-		mPendingUploads++;
-		LLHTTPClient::post(url, object_asset, new LLModelObjectUploadResponder(this,object_asset));
-	}
-	else
-	{
-		mFinished = true;
-	}
-}
-
 void LLMeshUploadThread::uploadModel(LLMeshUploadData& data)
 { //called from arbitrary thread
 	{
@@ -2937,102 +2772,6 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
 
 }
 
-void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data)
-{
-	if(isDiscarded())
-	{
-		return ;
-	}
-
-	//write model file to memory buffer
-	std::stringstream ostr;
-
-	LLModel::Decomposition& decomp =
-		data.mModel[LLModel::LOD_PHYSICS].notNull() ? 
-		data.mModel[LLModel::LOD_PHYSICS]->mPhysics : 
-		data.mBaseModel->mPhysics;
-
-	LLSD header = LLModel::writeModel(
-		ostr,
-		data.mModel[LLModel::LOD_PHYSICS],
-		data.mModel[LLModel::LOD_HIGH],
-		data.mModel[LLModel::LOD_MEDIUM],
-		data.mModel[LLModel::LOD_LOW],
-		data.mModel[LLModel::LOD_IMPOSTOR], 
-		decomp,
-		mUploadSkin,
-		mUploadJoints,
-		true);
-
-	std::string desc = data.mBaseModel->mLabel;
-	
-	// Grab the total vertex count of the model
-	// along with other information for the "asset_resources" map
-	// to send to the server.
-	LLSD asset_resources = LLSD::emptyMap();
-
-
-	std::string url = mNewInventoryCapability; 
-
-	if (!url.empty())
-	{
-		LLSD body = generate_new_resource_upload_capability_body(
-			LLAssetType::AT_MESH,
-			desc,
-			desc,
-			LLFolderType::FT_MESH,
-			LLInventoryType::IT_MESH,
-			LLFloaterPerms::getNextOwnerPerms(),
-			LLFloaterPerms::getGroupPerms(),
-			LLFloaterPerms::getEveryonePerms());
-
-		body["asset_resources"] = asset_resources;
-
-		mPendingConfirmations++;
-		LLCurlRequest::headers_t headers;
-
-		data.mPostData = body;
-
-		mCurlRequest->post(url, headers, body, new LLMeshCostResponder(data, this));
-	}	
-}
-
-void LLMeshUploadThread::sendCostRequest(LLTextureUploadData& data)
-{
-	if(isDiscarded())
-	{
-		return ;
-	}
-
-	if (data.mTexture && data.mTexture->getDiscardLevel() >= 0)
-	{
-		LLSD asset_resources = LLSD::emptyMap();
-
-		std::string url = mNewInventoryCapability; 
-
-		if (!url.empty())
-		{
-			LLSD body = generate_new_resource_upload_capability_body(
-				LLAssetType::AT_TEXTURE,
-				data.mLabel,
-				data.mLabel,
-				LLFolderType::FT_TEXTURE,
-				LLInventoryType::IT_TEXTURE,
-				LLFloaterPerms::getNextOwnerPerms(),
-				LLFloaterPerms::getGroupPerms(),
-				LLFloaterPerms::getEveryonePerms());
-
-			body["asset_resources"] = asset_resources;
-
-			mPendingConfirmations++;
-			LLCurlRequest::headers_t headers;
-			
-			data.mPostData = body;
-			mCurlRequest->post(url, headers, body, new LLTextureCostResponder(data, this));
-		}	
-	}
-}
-
 
 void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data)
 {
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 9b80fc02b3..a0c3989cf5 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -393,8 +393,6 @@ public:
 	BOOL            mDiscarded ;
 
 	LLHost			mHost;
-	std::string		mUploadObjectAssetCapability;
-	std::string		mNewInventoryCapability;
 	std::string		mWholeModelFeeCapability;
 	std::string		mWholeModelUploadURL;
 
@@ -413,12 +411,10 @@ public:
 
 	void uploadTexture(LLTextureUploadData& data);
 	void doUploadTexture(LLTextureUploadData& data);
-	void sendCostRequest(LLTextureUploadData& data);
 	void priceResult(LLTextureUploadData& data, const LLSD& content);
 	void onTextureUploaded(LLTextureUploadData& data);
 
 	void uploadModel(LLMeshUploadData& data);
-	void sendCostRequest(LLMeshUploadData& data);
 	void doUploadModel(LLMeshUploadData& data);
 	void onModelUploaded(LLMeshUploadData& data);
 	void createObjects(LLMeshUploadData& data);
@@ -432,7 +428,6 @@ public:
 	BOOL isDiscarded();
 
 	void doWholeModelUpload();
-	void doIterativeUpload();
 
 	void wholeModelToLLSD(LLSD& dest, bool include_textures);
 
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 37640ad0d4..b424f4952d 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -109,6 +109,7 @@ class LLMeshUploadVisible : public view_listener_t
 	{
 		return gSavedSettings.getBOOL("MeshEnabled") && 
 			   LLViewerParcelMgr::getInstance()->allowAgentBuild() && 
+			   // mesh *TODO: Use SimulatorFeatures cap to get this info instead.
 			   !gAgent.getRegion()->getCapability("ObjectAdd").empty();
 	}
 };
@@ -1203,78 +1204,6 @@ void upload_new_resource(
 	}
 }
 
-BOOL upload_new_variable_price_resource(
-	const LLTransactionID &tid, 
-	LLAssetType::EType asset_type,
-	std::string name,
-	std::string desc, 
-	LLFolderType::EType destination_folder_type,
-	LLInventoryType::EType inv_type,
-	U32 next_owner_perms,
-	U32 group_perms,
-	U32 everyone_perms,
-	const std::string& display_name,
-	const LLSD& asset_resources)
-{
-	LLAssetID uuid = 
-		upload_new_resource_prep(
-			tid,
-			asset_type,
-			inv_type,
-			name,
-			display_name,
-			desc);
-
-	llinfos << "*** Uploading: " << llendl;
-	llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
-	llinfos << "UUID: " << uuid << llendl;
-	llinfos << "Name: " << name << llendl;
-	llinfos << "Desc: " << desc << llendl;
-	lldebugs << "Folder: "
-		<< gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? (LLFolderType::EType)asset_type : destination_folder_type) << llendl;
-	lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
-
-	std::string url = gAgent.getRegion()->getCapability(
-		"NewFileAgentInventoryVariablePrice");
-
-	if ( !url.empty() )
-	{
-		lldebugs
-			<< "New Agent Inventory variable price upload" << llendl;
-		
-		// Each of the two capabilities has similar data, so
-		// let's reuse that code
-
-		LLSD body;
-
-		body = generate_new_resource_upload_capability_body(
-			asset_type,
-			name,
-			desc,
-			destination_folder_type,
-			inv_type,
-			next_owner_perms,
-			group_perms,
-			everyone_perms);
-
-		body["asset_resources"] = asset_resources;
-
-		LLHTTPClient::post(
-			url,
-			body,
-			new LLNewAgentInventoryVariablePriceResponder(
-				uuid,
-				asset_type,
-				body));
-
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
-}
-
 LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid)
 {
 	if ( gDisconnected )
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 1597821504..3136358b83 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -68,23 +68,6 @@ void upload_new_resource(
 	S32 expected_upload_cost,
 	void *userdata);
 
-// TODO* : Move all uploads to use this new function
-// since at some point, that upload path will be deprecated and no longer
-// used
-
-// We make a new function here to ensure that previous code is not broken
-BOOL upload_new_variable_price_resource(
-	const LLTransactionID& tid, 
-	LLAssetType::EType type,
-	std::string name,
-	std::string desc, 
-	LLFolderType::EType destination_folder_type,
-	LLInventoryType::EType inv_type,
-	U32 next_owner_perms,
-	U32 group_perms,
-	U32 everyone_perms,
-	const std::string& display_name,
-	const LLSD& asset_resources);
 
 LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid);
 void increase_new_upload_stats(LLAssetType::EType asset_type);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index c4ca5d37ce..b0ec5811a5 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1510,9 +1510,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	capabilityNames.append("LandResources");
 	capabilityNames.append("MapLayer");
 	capabilityNames.append("MapLayerGod");
-	capabilityNames.append("NewAccountingEnabled");
 	capabilityNames.append("NewFileAgentInventory");
-	capabilityNames.append("NewFileAgentInventoryVariablePrice");
+	// mesh *TODO: Use SimulatorFeatures cap to get this info instead.
 	capabilityNames.append("ObjectAdd");
 	capabilityNames.append("ParcelPropertiesUpdate");
 	capabilityNames.append("ParcelMediaURLFilterList");
@@ -1544,7 +1543,6 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	capabilityNames.append("UpdateNotecardTaskInventory");
 	capabilityNames.append("UpdateScriptTask");
 	capabilityNames.append("UploadBakedTexture");
-	capabilityNames.append("UploadObjectAsset");
 	capabilityNames.append("ViewerMetrics");
 	capabilityNames.append("ViewerStartAuction");
 	capabilityNames.append("ViewerStats");
-- 
cgit v1.2.3


From 9793f6c51d3eb4fd9752e2c74b283d748bbe0bd2 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 6 Jun 2011 16:54:15 -0500
Subject: Add "NoGeometry" identifier support to viewer.

---
 indra/llprimitive/llmodel.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 5acf93cfc4..337fa59f76 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1419,8 +1419,9 @@ LLSD LLModel::writeModel(
 			for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i)
 			{ //for each face
 				const LLVolumeFace& face = model[idx]->getVolumeFace(i);
-				if (!face.mNumVertices)
+				if (face.mNumVertices < 3)
 				{ //don't export an empty face
+					mdl[model_names[idx]][i]["NoGeometry"] = true;
 					continue;
 				}
 				LLSD::Binary verts(face.mNumVertices*3*2);
-- 
cgit v1.2.3


From aa21ad59aa1540be1839f0403b5a1291b86a74b3 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 6 Jun 2011 18:20:07 -0500
Subject: Fix for crash when viewing asset with "NoGeometry"

---
 indra/llmath/llvolume.cpp | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 3c1de3a422..f473a708cd 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2419,12 +2419,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 
 		for (U32 i = 0; i < face_count; ++i)
 		{
+			LLVolumeFace& face = mVolumeFaces[i];
+
+			if (mdl[i].has("NoGeometry"))
+			{ //face has no geometry, continue
+				face.resizeIndices(3);
+				face.resizeVertices(1);
+				memset(face.mPositions, 0, sizeof(LLVector4a));
+				memset(face.mNormals, 0, sizeof(LLVector4a));
+				memset(face.mTexCoords, 0, sizeof(LLVector2));
+				memset(face.mIndices, 0, sizeof(U16)*3);
+				continue;
+			}
+
 			LLSD::Binary pos = mdl[i]["Position"];
 			LLSD::Binary norm = mdl[i]["Normal"];
 			LLSD::Binary tc = mdl[i]["TexCoord0"];
 			LLSD::Binary idx = mdl[i]["TriangleList"];
 
-			LLVolumeFace& face = mVolumeFaces[i];
+			
 
 			//copy out indices
 			face.resizeIndices(idx.size()/2);
-- 
cgit v1.2.3


From b3fbb12f155ae1acc6b4d258d1c383d5d8e47964 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 6 Jun 2011 19:12:52 -0500
Subject: SH-1589 Fix for some meshes showing up in non mesh enabled regions.

---
 indra/newview/lldrawpoolavatar.cpp | 10 +---------
 indra/newview/llmeshrepository.cpp | 11 ++---------
 indra/newview/llviewerregion.cpp   | 12 ++++++++++++
 indra/newview/llviewerregion.h     |  3 +++
 indra/newview/llvovolume.cpp       |  2 +-
 5 files changed, 19 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 870aec4eff..9f790d03fe 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -459,14 +459,6 @@ S32 LLDrawPoolAvatar::getNumPasses()
 	{
 		return 10;
 	}
-	if (LLPipeline::sImpostorRender)
-	{
-		return 1;
-	}
-	else 
-	{
-		return 3;
-	}
 }
 
 
@@ -1419,7 +1411,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 
 void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 {
-	if (avatar->isSelf() && !gAgent.needsRenderAvatar())
+	if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled())
 	{
 		return;
 	}
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index ff9f0e1663..bfaddf9cde 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2379,7 +2379,6 @@ void LLMeshRepository::notifyLoadedMeshes()
 		if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived())
 		{
 			region_name = gAgent.getRegion()->getName();
-		
 			mGetMeshCapability = gAgent.getRegion()->getCapability("GetMesh");
 		}
 	}
@@ -3725,10 +3724,7 @@ bool LLMeshRepository::meshUploadEnabled()
 	   LLViewerParcelMgr::getInstance()->allowAgentBuild() &&
 	   region)
 	{
-		LLSD sim_features;
-		region->getSimulatorFeatures(sim_features);
-		return (sim_features.has("MeshUploadEnabled") &&
-				sim_features["MeshUploadEnabled"].asBoolean());
+		return region->meshUploadEnabled();
 	}
 	return false;
 }
@@ -3739,10 +3735,7 @@ bool LLMeshRepository::meshRezEnabled()
 	if(gSavedSettings.getBOOL("MeshEnabled") && 
 	   region)
 	{
-		LLSD sim_features;
-		region->getSimulatorFeatures(sim_features);
-		return (sim_features.has("MeshRezEnabled") &&
-				sim_features["MeshRezEnabled"].asBoolean());
+		return region->meshRezEnabled();
 	}
 	return false;
 }
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 80207d6568..a370e83410 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1716,4 +1716,16 @@ std::string LLViewerRegion::getDescription() const
     return stringize(*this);
 }
 
+bool LLViewerRegion::meshUploadEnabled() const
+{
+	return (mSimulatorFeatures.has("MeshUploadEnabled") &&
+		mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
+}
+
+bool LLViewerRegion::meshRezEnabled() const
+{
+	return (mSimulatorFeatures.has("MeshRezEnabled") &&
+				mSimulatorFeatures["MeshRezEnabled"].asBoolean());
+}
+
 
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index d936277231..3811b989e7 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -276,6 +276,9 @@ public:
 
 	void getInfo(LLSD& info);
 	
+	bool meshRezEnabled() const;
+	bool meshUploadEnabled() const;
+
 	void getSimulatorFeatures(LLSD& info);	
 	void setSimulatorFeatures(const LLSD& info);
 
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 39e555f781..d978167f50 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3983,7 +3983,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 
 		LLVOVolume* vobj = drawablep->getVOVolume();
 
-		if (vobj->getVolume() && vobj->getVolume()->isTetrahedron())
+		if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled()))
 		{
 			continue;
 		}
-- 
cgit v1.2.3


From a58e70261ef1584e243f813e858d22164ab00fd8 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 6 Jun 2011 19:27:47 -0500
Subject: SH-101 Fix for asset when uploading some models.

---
 indra/llprimitive/llmodel.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 337fa59f76..cee6927d20 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -2237,7 +2237,7 @@ LLSD LLModel::Decomposition::asLLSD() const
 		{
 			for (U32 k = 0; k < 3; k++)
 			{
-				llassert(mBaseHull[j].mV[k] <= 0.50001f && mBaseHull[j].mV[k] >= -0.50001f);
+				llassert(mBaseHull[j].mV[k] <= 0.501f && mBaseHull[j].mV[k] >= -0.501f);
 
 				//convert to 16-bit normalized across domain
 				U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535);
-- 
cgit v1.2.3


From faf9693be3f34cd1ef28e21ae1bd2bc466221c4e Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 7 Jun 2011 00:10:24 -0500
Subject: Make basehull assert even more forgiving (only error out on 10% over
 bounds).

---
 indra/llprimitive/llmodel.cpp    |  2 +-
 indra/newview/llviewerregion.cpp | 22 +++++++++++-----------
 2 files changed, 12 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index cee6927d20..e3b68156ca 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -2237,7 +2237,7 @@ LLSD LLModel::Decomposition::asLLSD() const
 		{
 			for (U32 k = 0; k < 3; k++)
 			{
-				llassert(mBaseHull[j].mV[k] <= 0.501f && mBaseHull[j].mV[k] >= -0.501f);
+				llassert(mBaseHull[j].mV[k] <= 0.51f && mBaseHull[j].mV[k] >= -0.51f);
 
 				//convert to 16-bit normalized across domain
 				U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index a370e83410..1dd92cd926 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1716,16 +1716,16 @@ std::string LLViewerRegion::getDescription() const
     return stringize(*this);
 }
 
-bool LLViewerRegion::meshUploadEnabled() const
-{
-	return (mSimulatorFeatures.has("MeshUploadEnabled") &&
-		mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
-}
-
-bool LLViewerRegion::meshRezEnabled() const
-{
-	return (mSimulatorFeatures.has("MeshRezEnabled") &&
-				mSimulatorFeatures["MeshRezEnabled"].asBoolean());
-}
+bool LLViewerRegion::meshUploadEnabled() const
+{
+	return (mSimulatorFeatures.has("MeshUploadEnabled") &&
+		mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
+}
+
+bool LLViewerRegion::meshRezEnabled() const
+{
+	return (mSimulatorFeatures.has("MeshRezEnabled") &&
+				mSimulatorFeatures["MeshRezEnabled"].asBoolean());
+}
 
 
-- 
cgit v1.2.3


From 81af06c95490a54e69b6bbf01ae2ef98adb66a02 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 7 Jun 2011 00:22:49 -0500
Subject: Fix for crash on clicking cancel while a model is still loading.

---
 indra/newview/llfloatermodelpreview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 675edd7643..1f6199ffb2 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -2787,7 +2787,7 @@ LLModelPreview::~LLModelPreview()
 {
 	if (mModelLoader)
 	{
-		delete mModelLoader;
+		mModelLoader->mPreview = NULL;
 		mModelLoader = NULL;
 	}
 	//*HACK : *TODO : turn this back on when we understand why this crashes
-- 
cgit v1.2.3


From d6730fddf6d8e711ca5af6e72a92734a70f86209 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 8 Jun 2011 00:16:02 -0500
Subject: don't use quota accounting manager

---
 indra/newview/llfloatertools.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 0f11d05175..0d798afdcc 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -424,6 +424,7 @@ void LLFloaterTools::refresh()
 	// Refresh object and prim count labels
 	LLLocale locale(LLLocale::USER_LOCALE);
 
+#if 0
 	if (gMeshRepo.meshRezEnabled())
 	{		
 		std::string obj_count_string;
@@ -448,6 +449,7 @@ void LLFloaterTools::refresh()
 		getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost);
 	}
 	else
+#endif
 	{
 		// Get the number of objects selected
 		std::string root_object_count_string;
-- 
cgit v1.2.3


From d9dfa9b8707b3bf68d7c5cd03a6ca738be7f891f Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 8 Jun 2011 14:31:22 -0500
Subject: SH-1777 Fix for "Prim" physics shape type not showing up on meshes
 with convex decompositions.

---
 indra/newview/llmeshrepository.cpp | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 29904c579c..3545b5128a 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2716,7 +2716,18 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
 bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
 {
 	LLSD mesh = mThread->getMeshHeader(mesh_id);
-	return mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0);
+	if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
+	{
+		return true;
+	}
+
+	LLModel::Decomposition* decomp = getDecomposition(mesh_id);
+	if (decomp && !decomp->mHull.empty())
+	{
+		return true;
+	}
+
+	return false;
 }
 
 LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
-- 
cgit v1.2.3


From 776353b4a6ced013a9406a6177d4cbc18177ccef Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Wed, 8 Jun 2011 15:25:59 -0600
Subject: fix for SH-1651 and SH-1652: Viewer Crash in Display:RenderUI when
 uploading skpfile.dae model with High LOD selected as Physics shape

---
 indra/newview/llfloatermodelpreview.cpp | 49 +------------------
 indra/newview/llfloatermodelwizard.cpp  | 49 +------------------
 indra/newview/llmeshrepository.cpp      | 86 ++++++++++++++++++++++-----------
 indra/newview/llmeshrepository.h        |  1 +
 4 files changed, 60 insertions(+), 125 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 1f6199ffb2..d56bc9cd10 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -5144,54 +5144,7 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
 	mParams = sInstance->mDecompParams;
 
 	//copy out positions and indices
-	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)
-		{
-			const LLVolumeFace& face = mdl->getVolumeFace(i);
-			if (mPositions.size() + face.mNumVertices > 65535)
-			{
-				continue;
-			}
-
-			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]) ;
-				}
-			}
-
-			updateTriangleAreaThreshold() ;
-
-			for (U32 j = 0; j+2 < face.mNumIndices; j += 3)
-			{
-				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;
-		}
-	}
+	assignData(mdl) ;	
 }
 
 void LLFloaterModelPreview::setStatusMessage(const std::string& msg)
diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp
index e44737f39e..0cd66fbdc2 100644
--- a/indra/newview/llfloatermodelwizard.cpp
+++ b/indra/newview/llfloatermodelwizard.cpp
@@ -438,54 +438,7 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM
 	mParams = sInstance->mDecompParams;
 
 	//copy out positions and indices
-	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)
-		{
-			const LLVolumeFace& face = mdl->getVolumeFace(i);
-			if (mPositions.size() + face.mNumVertices > 65535)
-			{
-				continue;
-			}
-
-			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]) ;
-				}
-			}
-
-			updateTriangleAreaThreshold() ;
-
-			for (U32 j = 0; j+2 < face.mNumIndices; j += 3)
-			{
-				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;
-		}
-	}
+	assignData(mdl) ;	
 }
 
 
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 29904c579c..0b10024663 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1323,35 +1323,7 @@ LLMeshUploadThread::DecompRequest::DecompRequest(LLModel* mdl, LLModel* base_mod
 	mThread = thread;
 	
 	//copy out positions and indices
-	if (mdl)
-	{
-		U16 index_offset = 0;
-
-		mPositions.clear();
-		mIndices.clear();
-			
-		//queue up vertex positions and indices
-		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
-		{
-			const LLVolumeFace& face = mdl->getVolumeFace(i);
-			if (mPositions.size() + face.mNumVertices > 65535)
-			{
-				continue;
-			}
-
-			for (U32 j = 0; j < face.mNumVertices; ++j)
-			{
-				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr()));
-			}
-
-			for (U32 j = 0; j < face.mNumIndices; ++j)
-			{
-				mIndices.push_back(face.mIndices[j]+index_offset);
-			}
-
-			index_offset += face.mNumVertices;
-		}
-	}
+	assignData(mdl) ;	
 
 	mThread->mFinalDecomp = this;
 	mThread->mPhysicsComplete = false;
@@ -3599,6 +3571,62 @@ void LLPhysicsDecomp::run()
 	mDone = true;
 }
 
+void LLPhysicsDecomp::Request::assignData(LLModel* mdl) 
+{
+	if (!mdl)
+	{
+		return ;
+	}
+
+	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)
+	{
+		const LLVolumeFace& face = mdl->getVolumeFace(i);
+		if (mPositions.size() + face.mNumVertices > 65535)
+		{
+			continue;
+		}
+
+		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]) ;
+			}
+		}
+
+		updateTriangleAreaThreshold() ;
+
+		for (U32 j = 0; j+2 < face.mNumIndices; j += 3)
+		{
+			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;
+	}
+
+	return ;
+}
+
 void LLPhysicsDecomp::Request::updateTriangleAreaThreshold() 
 {
 	F32 range = mBBox[1].mV[0] - mBBox[0].mV[0] ;
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index d5b06cc66f..adf60c7e03 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -166,6 +166,7 @@ public:
 		LLVector3 mBBox[2] ;
 		F32 mTriangleAreaThreshold ;
 
+		void assignData(LLModel* mdl) ;
 		void updateTriangleAreaThreshold() ;
 		bool isValidTriangle(U16 idx1, U16 idx2, U16 idx3) ;
 	};
-- 
cgit v1.2.3


From 73d807bd894e64c653efc6093c408d046e510a5b Mon Sep 17 00:00:00 2001
From: Roxie Linden <roxie@lindenlab.com>
Date: Wed, 8 Jun 2011 16:46:29 -0700
Subject: change the color specifier to 'diffuse_color' in the mesh upload
 blobs

---
 indra/newview/llmeshrepository.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 6b8b0f5a00..d4198041ec 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1533,7 +1533,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 					face_entry["offsett"] = 0.0;
 					face_entry["imagerot"] = 0.0;
 				}
-				face_entry["colors"] = ll_sd_from_color4(material.mDiffuseColor);
+				face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor);
 				face_entry["fullbright"] = material.mFullbright;
 				instance_entry["face_list"][face_num] = face_entry;
 		    }
-- 
cgit v1.2.3


From 0ee8d6dcb66421d8f12cc79c891cd119c673ae2f Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 8 Jun 2011 19:50:44 -0500
Subject: SH-560 Fix for "Loading..." text remaining in model importer when
 load fails.

---
 indra/newview/llfloatermodelpreview.cpp | 162 ++++++++++++++++----------------
 1 file changed, 79 insertions(+), 83 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 46d39db6cd..371579e5c8 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1286,11 +1286,7 @@ void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3&
 
 void LLModelLoader::run()
 {
-	if (!doLoadModel())
-	{
-		mPreview = NULL;
-	}
-
+	doLoadModel();
 	doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this));
 }
 
@@ -2302,87 +2298,87 @@ bool LLModelLoader::isNodeAJoint( domNode* pNode )
 //-----------------------------------------------------------------------------
 // verifyCount
 //-----------------------------------------------------------------------------
-bool LLModelPreview::verifyCount( int expected, int result )
-{
-	if ( expected != result )
-	{
-		llinfos<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<llendl;
-		return false;
-	}
-	return true;
-}
+bool LLModelPreview::verifyCount( int expected, int result )
+{
+	if ( expected != result )
+	{
+		llinfos<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<llendl;
+		return false;
+	}
+	return true;
+}
 //-----------------------------------------------------------------------------
 // verifyController
 //-----------------------------------------------------------------------------
-bool LLModelPreview::verifyController( domController* pController )
-{	
-
-	bool result = true;
-
-	domSkin* pSkin = pController->getSkin();
-
-	if ( pSkin )
-	{
-		xsAnyURI & uri = pSkin->getSource();
-		domElement* pElement = uri.getElement();
-
-		if ( !pElement )
-		{
-			llinfos<<"Can't resolve skin source"<<llendl;
-			return false;
-		}
-
-		daeString type_str = pElement->getTypeName();
-		if ( stricmp(type_str, "geometry") == 0 )
-		{	
-			//Skin is reference directly by geometry and get the vertex count from skin
-			domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights();
-			U32 vertexWeightsCount = pVertexWeights->getCount();
-			domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement();
-			domMesh* pMesh = pGeometry->getMesh();				
-			
-			if ( pMesh )
-			{
-				//Get vertex count from geometry
-				domVertices* pVertices = pMesh->getVertices();
-				if ( !pVertices )
-				{ 
-					llinfos<<"No vertices!"<<llendl;
-					return false;
-				}
-
-				if ( pVertices )
-				{
-					xsAnyURI src = pVertices->getInput_array()[0]->getSource();
-					domSource* pSource = (domSource*) (domElement*) src.getElement();
-					U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount();
-					result = verifyCount( verticesCount, vertexWeightsCount );
-					if ( !result )
-					{
-						return result;
-					}
-				}
-			}	
-
-			U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount();
-			result = verifyCount( vcountCount, vertexWeightsCount );	
-			if ( !result )
-			{
-				return result;
-			}
-
-			domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array();
-			U32 sum = 0;
-			for (size_t i=0; i<vcountCount; i++)
-			{
-				sum += pVertexWeights->getVcount()->getValue()[i];
-			}
-			result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() );
-		}
-	}
-	
-	return result;
-}
+bool LLModelPreview::verifyController( domController* pController )
+{	
+
+	bool result = true;
+
+	domSkin* pSkin = pController->getSkin();
+
+	if ( pSkin )
+	{
+		xsAnyURI & uri = pSkin->getSource();
+		domElement* pElement = uri.getElement();
+
+		if ( !pElement )
+		{
+			llinfos<<"Can't resolve skin source"<<llendl;
+			return false;
+		}
+
+		daeString type_str = pElement->getTypeName();
+		if ( stricmp(type_str, "geometry") == 0 )
+		{	
+			//Skin is reference directly by geometry and get the vertex count from skin
+			domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights();
+			U32 vertexWeightsCount = pVertexWeights->getCount();
+			domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement();
+			domMesh* pMesh = pGeometry->getMesh();				
+			
+			if ( pMesh )
+			{
+				//Get vertex count from geometry
+				domVertices* pVertices = pMesh->getVertices();
+				if ( !pVertices )
+				{ 
+					llinfos<<"No vertices!"<<llendl;
+					return false;
+				}
+
+				if ( pVertices )
+				{
+					xsAnyURI src = pVertices->getInput_array()[0]->getSource();
+					domSource* pSource = (domSource*) (domElement*) src.getElement();
+					U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount();
+					result = verifyCount( verticesCount, vertexWeightsCount );
+					if ( !result )
+					{
+						return result;
+					}
+				}
+			}	
+
+			U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount();
+			result = verifyCount( vcountCount, vertexWeightsCount );	
+			if ( !result )
+			{
+				return result;
+			}
+
+			domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array();
+			U32 sum = 0;
+			for (size_t i=0; i<vcountCount; i++)
+			{
+				sum += pVertexWeights->getVcount()->getValue()[i];
+			}
+			result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() );
+		}
+	}
+	
+	return result;
+}
 
 //-----------------------------------------------------------------------------
 // extractTranslation()
-- 
cgit v1.2.3