diff options
| author | Dave Parks <davep@lindenlab.com> | 2011-03-30 18:38:22 -0500 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2011-03-30 18:38:22 -0500 | 
| commit | 6b9a2d24cce8efaa72c2fd60655998844394312d (patch) | |
| tree | 77438ba1c0e742c2acf7372b968f32368290fa8a | |
| parent | 1aecac62eb88125546057be2a2a70a6b2eba1a57 (diff) | |
SH-477 Better mesh streaming cost estimation.
| -rw-r--r-- | indra/llcommon/llsdserialize.cpp | 5 | ||||
| -rwxr-xr-x | indra/llprimitive/llmodel.cpp | 360 | ||||
| -rwxr-xr-x | indra/llprimitive/llmodel.h | 103 | ||||
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 2 | ||||
| -rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 34 | ||||
| -rwxr-xr-x | indra/newview/llmeshrepository.cpp | 109 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 7 | ||||
| -rw-r--r-- | indra/newview/llselectmgr.cpp | 18 | ||||
| -rw-r--r-- | indra/newview/llselectmgr.h | 4 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 21 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llvovolume.h | 2 | 
14 files changed, 351 insertions, 324 deletions
| diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index f3cbfab77a..5be5ecc492 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -2095,11 +2095,6 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)  	S32 ret = inflateInit(&strm); -	if (ret != Z_OK) -	{ -		llerrs << "WTF?" << llendl; -	} -	  	do  	{  		strm.avail_out = CHUNK; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 595f9aa307..049cf6b71f 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1333,70 +1333,6 @@ std::string LLModel::getName() const  		return mLabel;  } -//static  -LLSD LLModel::writeModel( -	std::string filename, -	LLModel* physics, -	LLModel* high, -	LLModel* medium, -	LLModel* low, -	LLModel* impostor, -	const convex_hull_decomposition& decomp, -	BOOL upload_skin, -	BOOL upload_joints, -	BOOL nowrite) -{ -	LLModel::hull dummy_hull; -	return writeModel( -		filename, -		physics, -		high, -		medium, -		low, -		impostor, -		decomp, -		dummy_hull, -		upload_skin, -		upload_joints, -		nowrite); -} - -//static  -LLSD LLModel::writeModel( -	std::string filename, -	LLModel* physics, -	LLModel* high, -	LLModel* medium, -	LLModel* low, -	LLModel* impostor, -	const convex_hull_decomposition& decomp, -	const hull& base_hull, -	BOOL upload_skin, -	BOOL upload_joints, -	BOOL nowrite) -{ -	std::ofstream os( -		filename.c_str(), -		std::ofstream::out | std::ofstream::binary); - -	LLSD header = writeModel( -		os, -		physics, -		high, -		medium, -		low, -		impostor, -		decomp, -		base_hull, -		upload_skin, -		upload_joints, -		nowrite); - -	os.close(); - -	return header; -} -  //static  LLSD LLModel::writeModel(  	std::ostream& ostr, @@ -1405,8 +1341,7 @@ LLSD LLModel::writeModel(  	LLModel* medium,  	LLModel* low,  	LLModel* impostor, -	const convex_hull_decomposition& decomp, -	const hull& base_hull, +	const LLModel::Decomposition& decomp,  	BOOL upload_skin,  	BOOL upload_joints,  	BOOL nowrite) @@ -1429,119 +1364,10 @@ LLSD LLModel::writeModel(  		mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints);  	} -	if (!decomp.empty() || !base_hull.empty()) +	if (!decomp.mBaseHull.empty() || +		!decomp.mHull.empty())		  	{ -		//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 -		 -		 -		//get minimum and maximum -		LLVector3 min; -		 -		if (decomp.empty()) -		{ -			min = base_hull[0]; -		} -		else -		{ -			min = decomp[0][0]; -		} - -		LLVector3 max = min; - -		LLSD::Binary hulls(decomp.size()); - -		U32 total = 0; - -		for (U32 i = 0; i < decomp.size(); ++i) -		{ -			U32 size = decomp[i].size(); -			total += size; -			hulls[i] = (U8) (size); - -			for (U32 j = 0; j < decomp[i].size(); ++j) -			{ -				update_min_max(min, max, decomp[i][j]); -			} - -		} - -		for (U32 i = 0; i < base_hull.size(); ++i) -		{ -			update_min_max(min, max, base_hull[i]);	 -		} - -		mdl["decomposition"]["Min"] = min.getValue(); -		mdl["decomposition"]["Max"] = max.getValue(); - -		if (!hulls.empty()) -		{ -			mdl["decomposition"]["HullList"] = hulls; -		} - -		if (total > 0) -		{ -			LLSD::Binary p(total*3*2); - -			LLVector3 range = max-min; - -			U32 vert_idx = 0; -			for (U32 i = 0; i < decomp.size(); ++i) -			{ -				for (U32 j = 0; j < decomp[i].size(); ++j) -				{ -					for (U32 k = 0; k < 3; k++) -					{ -						//convert to 16-bit normalized across domain -						U16 val = (U16) (((decomp[i][j].mV[k]-min.mV[k])/range.mV[k])*65535); - -						U8* buff = (U8*) &val; -						//write to binary buffer -						p[vert_idx++] = buff[0]; -						p[vert_idx++] = buff[1]; - -						if (vert_idx > p.size()) -						{ -							llerrs << "WTF?" << llendl; -						} -					} -				} -			} - -			mdl["decomposition"]["Position"] = p; -		} - -		if (!base_hull.empty()) -		{ -			LLSD::Binary p(base_hull.size()*3*2); - -			LLVector3 range = max-min; - -			U32 vert_idx = 0; -			for (U32 j = 0; j < base_hull.size(); ++j) -			{ -				for (U32 k = 0; k < 3; k++) -				{ -					//convert to 16-bit normalized across domain -					U16 val = (U16) (((base_hull[j].mV[k]-min.mV[k])/range.mV[k])*65535); - -					U8* buff = (U8*) &val; -					//write to binary buffer -					p[vert_idx++] = buff[0]; -					p[vert_idx++] = buff[1]; - -					if (vert_idx > p.size()) -					{ -						llerrs << "WTF?" << llendl; -					} -				} -			} -			 -			mdl["decomposition"]["Hull"] = p; -		} +		mdl["decomposition"] = decomp.asLLSD();  	}  	for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx) @@ -1906,7 +1732,11 @@ void LLModel::updateHullCenters()  		mHullPoints += mPhysics.mHull[i].size();  	} -	mCenterOfHullCenters *= 1.f / mHullPoints; +	if (mHullPoints > 0) +	{ +		mCenterOfHullCenters *= 1.f / mHullPoints; +		llassert(mPhysics.asLLSD().has("HullList")); +	}  }  bool LLModel::loadModel(std::istream& is)
 @@ -2182,19 +2012,33 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)  		max.setValue(decomp["Max"]);  		range = max-min; +		  		for (U32 i = 0; i < hulls.size(); ++i)  		{  			U16 count = (hulls[i] == 0) ? 256 : hulls[i]; +			std::set<U64> valid; + +			//must have at least 4 points +			llassert(count > 3); +  			for (U32 j = 0; j < count; ++j)  			{ +				U64 test = (U64) p[0] | ((U64) p[1] << 16) | ((U64) p[2] << 32); +				//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],  					(F32) p[2]/65535.f*range.mV[2]+min.mV[2]));  				p += 3; -			}		  + +			} + +			//each hull must contain at least 4 unique points +			llassert(valid.size() > 3);  		}  	} @@ -2208,8 +2052,17 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)  		LLVector3 max;  		LLVector3 range; -		min.setValue(decomp["Min"]); -		max.setValue(decomp["Max"]); +		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; @@ -2229,7 +2082,145 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)  		//but contains no base hull  		mBaseHullMesh.clear();;  	} +} + +LLSD LLModel::Decomposition::asLLSD() const +{ +	LLSD ret; +	 +	if (mBaseHull.empty() && mHull.empty()) +	{ //nothing to write +		return ret; +	} + +	//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 +	 +	 +	//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; + +	for (U32 i = 0; i < mHull.size(); ++i) +	{ +		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; +	} + +	if (total > 0) +	{ +		LLSD::Binary p(total*3*2); + +		LLVector3 range = max-min; + +		U32 vert_idx = 0; +		 +		for (U32 i = 0; i < mHull.size(); ++i) +		{ +			std::set<U64> valid; + +			llassert(!mHull[i].empty()); + +			for (U32 j = 0; j < mHull[i].size(); ++j) +			{ +				U64 test = 0; +				for (U32 k = 0; k < 3; k++) +				{ +					//convert to 16-bit normalized across domain +					U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535); + +					switch (k) +					{ +						case 0: test = test | (U64) val; break; +						case 1: test = test | ((U64) val << 16); break; +						case 2: test = test | ((U64) val << 32); break; +					}; + +					valid.insert(test); +					 +					U8* buff = (U8*) &val; +					//write to binary buffer +					p[vert_idx++] = buff[0]; +					p[vert_idx++] = buff[1]; + +					//makes sure we haven't run off the end of the array +					llassert(vert_idx <= p.size()); +				} +			} + +			//must have at least 4 unique points +			llassert(valid.size() > 3); +		} + +		ret["Position"] = p; +	} + +	if (!mBaseHull.empty()) +	{ +		LLSD::Binary p(mBaseHull.size()*3*2); + +		LLVector3 range = max-min; + +		U32 vert_idx = 0; +		for (U32 j = 0; j < mBaseHull.size(); ++j) +		{ +			for (U32 k = 0; k < 3; k++) +			{ +				//convert to 16-bit normalized across domain +				U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535); + +				U8* buff = (U8*) &val; +				//write to binary buffer +				p[vert_idx++] = buff[0]; +				p[vert_idx++] = buff[1]; + +				if (vert_idx > p.size()) +				{ +					llerrs << "WTF?" << llendl; +				} +			} +		} +		 +		ret["Hull"] = p; +	} + +	return ret;  }  void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs) @@ -2256,5 +2247,10 @@ void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs)  	{ //take physics shape mesh from rhs  		mPhysicsShapeMesh = rhs->mPhysicsShapeMesh;  	} + +	if (!mHull.empty()) +	{ //verify +		llassert(asLLSD().has("HullList")); +	}  } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index e9450d2967..962e422a26 100755 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -71,38 +71,53 @@ public:  	//convex_hull_decomposition is a vector of convex hulls  	//each convex hull is a set of points -	typedef  std::vector<std::vector<LLVector3> > convex_hull_decomposition; +	typedef std::vector<std::vector<LLVector3> > convex_hull_decomposition;  	typedef std::vector<LLVector3> hull; +	class PhysicsMesh +	{ +	public: +		std::vector<LLVector3> mPositions; +		std::vector<LLVector3> mNormals; + +		void clear() +		{ +			mPositions.clear(); +			mNormals.clear(); +		} + +		bool empty() const +		{ +			return mPositions.empty(); +		} +	}; + +	class Decomposition +	{ +	public: +		Decomposition() { } +		Decomposition(LLSD& data); +		void fromLLSD(LLSD& data); +		LLSD asLLSD() const; + +		void merge(const Decomposition* rhs); + +		LLUUID mMeshID; +		LLModel::convex_hull_decomposition mHull; +		LLModel::hull mBaseHull; + +		std::vector<LLModel::PhysicsMesh> mMesh; +		LLModel::PhysicsMesh mBaseHullMesh; +		LLModel::PhysicsMesh mPhysicsShapeMesh; +	}; +  	LLModel(LLVolumeParams& params, F32 detail);  	~LLModel();  	bool loadModel(std::istream& is);  	bool loadSkinInfo(LLSD& header, std::istream& is);  	bool loadDecomposition(LLSD& header, std::istream& is); -	static LLSD writeModel( -		std::string filename, -		LLModel* physics, -		LLModel* high, -		LLModel* medium, -		LLModel* low, -		LLModel* imposotr, -		const LLModel::convex_hull_decomposition& convex_hull_decomposition, -		const LLModel::hull& base_hull, -		BOOL upload_skin, -		BOOL upload_joints, -		BOOL nowrite = FALSE); -	static LLSD writeModel( -		std::string filename, -		LLModel* physics, -		LLModel* high, -		LLModel* medium, -		LLModel* low, -		LLModel* imposotr, -		const LLModel::convex_hull_decomposition& convex_hull_decomposition, -		BOOL upload_skin, -		BOOL upload_joints, -		BOOL nowrite = FALSE); +	  	static LLSD writeModel(  		std::ostream& ostr,  		LLModel* physics, @@ -110,11 +125,11 @@ public:  		LLModel* medium,  		LLModel* low,  		LLModel* imposotr, -		const LLModel::convex_hull_decomposition& convex_hull_decomposition, -		const LLModel::hull& base_hull, +		const LLModel::Decomposition& decomp,  		BOOL upload_skin,  		BOOL upload_joints,  		BOOL nowrite = FALSE); +  	static LLSD writeModelToStream(  		std::ostream& ostr,  		LLSD& mdl, @@ -220,42 +235,6 @@ public:  	//ID for storing this model in a .slm file  	S32 mLocalID; -	class PhysicsMesh -	{ -	public: -		std::vector<LLVector3> mPositions; -		std::vector<LLVector3> mNormals; - -		void clear() -		{ -			mPositions.clear(); -			mNormals.clear(); -		} - -		bool empty() const -		{ -			return mPositions.empty(); -		} -	}; - -	class Decomposition -	{ -	public: -		Decomposition() { } -		Decomposition(LLSD& data); -		void fromLLSD(LLSD& data); -		 -		void merge(const Decomposition* rhs); - -		LLUUID mMeshID; -		LLModel::convex_hull_decomposition mHull; -		LLModel::hull mBaseHull; - -		std::vector<LLModel::PhysicsMesh> mMesh; -		LLModel::PhysicsMesh mBaseHullMesh; -		LLModel::PhysicsMesh mPhysicsShapeMesh; -	}; -  	Decomposition mPhysics;  protected: diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c11de57c42..4c042435f2 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8974,7 +8974,7 @@      <key>Type</key>      <string>F32</string>      <key>Value</key> -    <real>2.0</real> +    <real>3.0</real>    </map>    <key>MeshThreadCount</key>    <map> diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 541511e448..243f301e9d 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1093,7 +1093,7 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev  	{
  		//only try to load from slm if viewer is configured to do so and this is the 
  		//initial model load (not an LoD or physics shape)
 -		mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mPreview->mBaseModel.empty();
 +		mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mPreview->mUploadData.empty();
  		mPreview->setLoadState(STARTING);
  	}
  	else
 @@ -1889,6 +1889,14 @@ void LLModelLoader::loadModelCallback()  	{ //wait until this thread is stopped before deleting self
  		apr_sleep(100);
  	}
 +
 +	//cleanup model loader
 +	if (mPreview)
 +	{
 +		mPreview->mModelLoader = NULL;
 +	}
 +
 +	delete this;
  }
  void LLModelLoader::handlePivotPoint( daeElement* pRoot )
 @@ -2518,13 +2526,13 @@ U32 LLModelPreview::calcResourceCost()  		{
  			accounted.insert(instance.mModel);
 -			LLModel::convex_hull_decomposition& decomp =
 +			LLModel::Decomposition& decomp =
  			instance.mLOD[LLModel::LOD_PHYSICS] ?
 -			instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics.mHull :
 -			instance.mModel->mPhysics.mHull;
 +			instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics :
 +			instance.mModel->mPhysics;
 -			LLSD ret = LLModel::writeModel(
 -										   "",
 +			std::stringstream ostr;
 +			LLSD ret = LLModel::writeModel(ostr,
  										   instance.mLOD[4],
  										   instance.mLOD[3],
  										   instance.mLOD[2],
 @@ -2536,10 +2544,10 @@ U32 LLModelPreview::calcResourceCost()  										   TRUE);
  			cost += gMeshRepo.calcResourceCost(ret);
 -			num_hulls += decomp.size();
 -			for (U32 i = 0; i < decomp.size(); ++i)
 +			num_hulls += decomp.mHull.size();
 +			for (U32 i = 0; i < decomp.mHull.size(); ++i)
  			{
 -				num_points += decomp[i].size();
 +				num_points += decomp.mHull[i].size();
  			}
  			//calculate streaming cost
 @@ -2737,10 +2745,10 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw  			std::stringstream str;
 -			LLModel::convex_hull_decomposition& decomp =
 +			LLModel::Decomposition& decomp =
  				instance.mLOD[LLModel::LOD_PHYSICS].notNull() ? 
 -				instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics.mHull : 
 -				instance.mModel->mPhysics.mHull;
 +				instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics : 
 +				instance.mModel->mPhysics;
  			LLModel::writeModel(str, 
  				instance.mLOD[LLModel::LOD_PHYSICS], 
 @@ -2749,7 +2757,7 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw  				instance.mLOD[LLModel::LOD_LOW], 
  				instance.mLOD[LLModel::LOD_IMPOSTOR], 
  				decomp, 
 -				empty_hull, save_skinweights, save_joint_positions);
 +				save_skinweights, save_joint_positions);
  			data["mesh"][instance.mModel->mLocalID] = str.str();
 diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 752e4c8744..78943ef1b6 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1535,8 +1535,6 @@ void LLMeshRepoThread::notifyLoadedMeshes()  S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod)   { //only ever called from main thread -	lod = llclamp(lod, 0, 3); -  	LLMutexLock lock(mHeaderMutex);  	mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID()); @@ -1544,40 +1542,48 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo  	{  		LLSD& header = iter->second; -		if (header.has("404")) -		{ -			return -1; -		} +		return LLMeshRepository::getActualMeshLOD(header, lod); +	} -		if (header[header_lod[lod]]["size"].asInteger() > 0) -		{ -			return lod; -		} +	return lod; +} + +//static +S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) +{ +	lod = llclamp(lod, 0, 3); + +	if (header.has("404")) +	{ +		return -1; +	} -		//search down to find the next available lower lod -		for (S32 i = lod-1; i >= 0; --i) +	if (header[header_lod[lod]]["size"].asInteger() > 0) +	{ +		return lod; +	} + +	//search down to find the next available lower lod +	for (S32 i = lod-1; i >= 0; --i) +	{ +		if (header[header_lod[i]]["size"].asInteger() > 0)  		{ -			if (header[header_lod[i]]["size"].asInteger() > 0) -			{ -				return i; -			} +			return i;  		} +	} -		//search up to find then ext available higher lod -		for (S32 i = lod+1; i < 4; ++i) +	//search up to find then ext available higher lod +	for (S32 i = lod+1; i < 4; ++i) +	{ +		if (header[header_lod[i]]["size"].asInteger() > 0)  		{ -			if (header[header_lod[i]]["size"].asInteger() > 0) -			{ -				return i; -			} +			return i;  		} - -		//header exists and no good lod found, treat as 404 -		header["404"] = 1; -		return -1;  	} -	return lod; +	//header exists and no good lod found, treat as 404 +	header["404"] = 1; +	return -1;  }  U32 LLMeshRepoThread::getResourceCost(const LLUUID& mesh_id) @@ -2514,12 +2520,12 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)  	return mesh.has("physics_shape") && mesh["physics_shape"].has("size") && (mesh["physics_shape"]["size"].asInteger() > 0);  } -const LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id) +LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)  {  	return mThread->getMeshHeader(mesh_id);  } -const LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id) +LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)  {  	static LLSD dummy_ret;  	if (mesh_id.notNull()) @@ -2577,12 +2583,10 @@ void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data)  	//write model file to memory buffer  	std::stringstream ostr; -	LLModel::convex_hull_decomposition& decomp = +	LLModel::Decomposition& decomp =  		data.mModel[LLModel::LOD_PHYSICS].notNull() ?  -		data.mModel[LLModel::LOD_PHYSICS]->mPhysics.mHull :  -		data.mBaseModel->mPhysics.mHull; - -	LLModel::hull dummy_hull; +		data.mModel[LLModel::LOD_PHYSICS]->mPhysics :  +		data.mBaseModel->mPhysics;  	LLSD header = LLModel::writeModel(  		ostr, @@ -2592,7 +2596,6 @@ void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data)  		data.mModel[LLModel::LOD_LOW],  		data.mModel[LLModel::LOD_IMPOSTOR],   		decomp, -		dummy_hull,  		mUploadSkin,  		mUploadJoints,  		true); @@ -2678,10 +2681,12 @@ void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data)  	{  		std::stringstream ostr; -		LLModel::convex_hull_decomposition& decomp = +		LLModel::Decomposition& decomp =  			data.mModel[LLModel::LOD_PHYSICS].notNull() ?  -			data.mModel[LLModel::LOD_PHYSICS]->mPhysics.mHull :  -			data.mBaseModel->mPhysics.mHull; +			data.mModel[LLModel::LOD_PHYSICS]->mPhysics :  +			data.mBaseModel->mPhysics; + +		decomp.mBaseHull = mHullMap[data.mBaseModel];  		LLModel::writeModel(  			ostr,   @@ -2691,7 +2696,6 @@ void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data)  			data.mModel[LLModel::LOD_LOW],  			data.mModel[LLModel::LOD_IMPOSTOR],   			decomp, -			mHullMap[data.mBaseModel],  			mUploadSkin,  			mUploadJoints); @@ -2939,17 +2943,36 @@ void LLMeshRepository::uploadError(LLSD& args)  }  //static -F32 LLMeshRepository::getStreamingCost(const LLSD& header, F32 radius) +F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod)  { -	F32 dlowest = llmin(radius/0.06f, 256.f); -	F32 dlow = llmin(radius/0.24f, 256.f); -	F32 dmid = llmin(radius/1.0f, 256.f); +	F32 dlowest = llmin(radius/0.03f, 256.f); +	F32 dlow = llmin(radius/0.06f, 256.f); +	F32 dmid = llmin(radius/0.24f, 256.f);  	F32 bytes_lowest = header["lowest_lod"]["size"].asReal()/1024.f;  	F32 bytes_low = header["low_lod"]["size"].asReal()/1024.f;  	F32 bytes_mid = header["medium_lod"]["size"].asReal()/1024.f;  	F32 bytes_high = header["high_lod"]["size"].asReal()/1024.f; +	if (bytes) +	{ +		*bytes = 0; +		*bytes += header["lowest_lod"]["size"].asInteger(); +		*bytes += header["low_lod"]["size"].asInteger(); +		*bytes += header["medium_lod"]["size"].asInteger(); +		*bytes += header["high_lod"]["size"].asInteger(); +	} + + +	if (bytes_visible) +	{ +		lod = LLMeshRepository::getActualMeshLOD(header, lod); +		if (lod >= 0 && lod <= 3) +		{ +			*bytes_visible = header[header_lod[lod]]["size"].asInteger(); +		} +	} +  	if (bytes_high == 0.f)  	{  		return 0.f; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 31c2049c32..5983a282a2 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -318,7 +318,7 @@ public:  	bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);  	bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);  	bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); -	const LLSD& getMeshHeader(const LLUUID& mesh_id); +	LLSD& getMeshHeader(const LLUUID& mesh_id);  	void notifyLoadedMeshes();  	S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); @@ -434,7 +434,7 @@ public:  	static U32 sCacheBytesWritten;  	static U32 sPeakKbps; -	static F32 getStreamingCost(const LLSD& header, F32 radius); +	static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1);  	LLMeshRepository(); @@ -452,6 +452,7 @@ public:  	void notifyDecompositionReceived(LLModel::Decomposition* info);  	S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); +	static S32 getActualMeshLOD(LLSD& header, S32 lod);  	U32 calcResourceCost(LLSD& header);  	U32 getResourceCost(const LLUUID& mesh_params);  	const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id); @@ -462,7 +463,7 @@ public:  	void buildHull(const LLVolumeParams& params, S32 detail);  	void buildPhysicsMesh(LLModel::Decomposition& decomp); -	const LLSD& getMeshHeader(const LLUUID& mesh_id); +	LLSD& getMeshHeader(const LLUUID& mesh_id);  	void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,  			bool upload_skin, bool upload_joints); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index b139ba361e..78ffc7908d 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6374,7 +6374,7 @@ BOOL LLObjectSelection::isEmpty() const  //-----------------------------------------------------------------------------  // getObjectCount() - returns number of non null objects  //----------------------------------------------------------------------------- -S32 LLObjectSelection::getObjectCount(BOOL mesh_adjust) +S32 LLObjectSelection::getObjectCount()  {  	cleanupNodes();  	S32 count = mList.size(); @@ -6478,7 +6478,7 @@ F32 LLObjectSelection::getSelectedLinksetPhysicsCost()  	return cost;  } -F32 LLObjectSelection::getSelectedObjectStreamingCost() +F32 LLObjectSelection::getSelectedObjectStreamingCost(S32* total_bytes, S32* visible_bytes)  {  	F32 cost = 0.f;  	for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) @@ -6488,7 +6488,19 @@ F32 LLObjectSelection::getSelectedObjectStreamingCost()  		if (object)  		{ -			cost += object->getStreamingCost(); +			S32 bytes = 0; +			S32 visible = 0; +			cost += object->getStreamingCost(&bytes, &visible); + +			if (total_bytes) +			{ +				*total_bytes += bytes; +			} + +			if (visible_bytes) +			{ +				*visible_bytes += visible; +			}  		}  	} diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 031898d7c5..166616e13e 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -278,14 +278,14 @@ public:  	LLSelectNode* findNode(LLViewerObject* objectp);  	// count members -	S32 getObjectCount(BOOL mesh_adjust = FALSE); +	S32 getObjectCount();  	F32 getSelectedObjectCost();  	F32 getSelectedLinksetCost();  	F32 getSelectedPhysicsCost();  	F32 getSelectedLinksetPhysicsCost();  	S32 getSelectedObjectRenderCost(); -	F32 getSelectedObjectStreamingCost(); +	F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL);  	U32 getSelectedObjectTriangleCount();  	S32 getTECount(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index bcdc774c5e..70b1809033 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3134,7 +3134,7 @@ F32 LLViewerObject::getLinksetPhysicsCost()  	return mLinksetPhysicsCost;  } -F32 LLViewerObject::getStreamingCost() +F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes)  {  	return 0.f;  } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 2b2b7bd59d..44f46b8c0f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -326,7 +326,7 @@ public:  	virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE); -	virtual F32 getStreamingCost(); +	virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL);  	virtual U32 getTriangleCount();  	void setObjectCost(F32 cost); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 39ef56d156..141ade8079 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -493,6 +493,10 @@ public:  			{  				F32 cost = 0.f;  				S32 count = 0; +				S32 object_count = 0; +				S32 total_bytes = 0; +				S32 visible_bytes = 0; +  				const char* label = "Region";  				if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 0)  				{ //region @@ -506,8 +510,13 @@ public:  								object->getRegion() == region &&  								object->getVolume())  							{ -								cost += object->getStreamingCost(); +								object_count++; +								S32 bytes = 0;	 +								S32 visible = 0; +								cost += object->getStreamingCost(&bytes, &visible);  								count += object->getTriangleCount(); +								total_bytes += bytes; +								visible_bytes += visible;  							}  						}  					} @@ -515,12 +524,16 @@ public:  				else  				{  					label = "Selection"; -					cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(); +					cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes);  					count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(); +					object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();  				} -				addText(xpos,ypos, llformat("%s streaming cost: %.1f (%.1f KTris)", -							label, cost, count/1000.f)); +				addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost)); +				ypos += y_inc; + +				addText(xpos, ypos, llformat("    %.1f KTris, %.1f/%.1f KB, %d objects", +										count/1024.f, visible_bytes/1024.f, total_bytes/1024.f, object_count));  				ypos += y_inc;  			} diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 98e5e4c6de..7c4a4c13ba 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3082,15 +3082,15 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const  }
 -F32 LLVOVolume::getStreamingCost()
 +F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
  {
  	if (isMesh())
  	{	
 -		const LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
 +		LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
  		F32 radius = getScale().length();
 -		return LLMeshRepository::getStreamingCost(header, radius);
 +		return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD);
  	}
  	return 0.f;
 diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index b09243055c..029811886d 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -130,7 +130,7 @@ public:  	const LLMatrix3&	getRelativeXformInvTrans() const		{ return mRelativeXformInvTrans; }  	/*virtual*/	const LLMatrix4	getRenderMatrix() const;  				U32 	getRenderCost(std::set<LLUUID> &textures) const; -	/*virtual*/	F32		getStreamingCost(); +	/*virtual*/	F32		getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL);  	/*virtual*/ U32		getTriangleCount();  	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES | 
