diff options
Diffstat (limited to 'indra/newview/llmeshrepository.cpp')
| -rwxr-xr-x | indra/newview/llmeshrepository.cpp | 629 | 
1 files changed, 366 insertions, 263 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 8f50555a73..91d665ed34 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -489,6 +489,12 @@ void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res,  	}  } +LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMaterial& material) +{ +	LLPointer< LLViewerFetchedTexture > * ppTex = static_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData); +	return ppTex ? (*ppTex).get() : NULL; +} +  volatile S32 LLMeshRepoThread::sActiveHeaderRequests = 0;  volatile S32 LLMeshRepoThread::sActiveLODRequests = 0;  U32	LLMeshRepoThread::sMaxConcurrentRequests = 1; @@ -573,23 +579,23 @@ public:  //  // Thread:  repo  class LLMeshLODHandler : public LLMeshHandlerBase -	{ +{  public:  	LLMeshLODHandler(const LLVolumeParams & mesh_params, S32 lod, U32 offset, U32 requested_bytes)  		: LLMeshHandlerBase(),  		  mLOD(lod),  		  mRequestedBytes(requested_bytes),  		  mOffset(offset) -		{ +	{  		mMeshParams = mesh_params;  		LLMeshRepoThread::incActiveLODRequests(); -			} +	}  	virtual ~LLMeshLODHandler(); - +	  protected:  	LLMeshLODHandler(const LLMeshLODHandler &);					// Not defined  	void operator=(const LLMeshLODHandler &);					// Not defined - +	  public:  	virtual void processData(LLCore::BufferArray * body, U8 * data, S32 data_size);  	virtual void processFailure(LLCore::HttpStatus status); @@ -605,7 +611,7 @@ public:  //  // Thread:  repo  class LLMeshSkinInfoHandler : public LLMeshHandlerBase -	{ +{  public:  	LOG_CLASS(LLMeshSkinInfoHandler);  	LLMeshSkinInfoHandler(const LLUUID& id, U32 offset, U32 size) @@ -635,7 +641,7 @@ public:  //  // Thread:  repo  class LLMeshDecompositionHandler : public LLMeshHandlerBase -	{ +{  public:  	LOG_CLASS(LLMeshDecompositionHandler);  	LLMeshDecompositionHandler(const LLUUID& id, U32 offset, U32 size) @@ -665,7 +671,7 @@ public:  //  // Thread:  repo  class LLMeshPhysicsShapeHandler : public LLMeshHandlerBase -	{ +{  public:  	LOG_CLASS(LLMeshPhysicsShapeHandler);  	LLMeshPhysicsShapeHandler(const LLUUID& id, U32 offset, U32 size) @@ -754,7 +760,7 @@ LLMeshRepoThread::LLMeshRepoThread()    mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),    mHttpPriority(0),    mGetMeshVersion(2) -	{ +{   	mMutex = new LLMutex(NULL);  	mHeaderMutex = new LLMutex(NULL);  	mSignal = new LLCondition(NULL); @@ -770,11 +776,11 @@ LLMeshRepoThread::LLMeshRepoThread()  	mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_MESH2);  	mHttpLegacyPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_MESH1);  	mHttpLargePolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_LARGE_MESH); -	} +} + -			  LLMeshRepoThread::~LLMeshRepoThread() -		{ +{  	LL_INFOS(LOG_MESH) << "Small GETs issued:  " << LLMeshRepository::sHTTPRequestCount  					   << ", Large GETs issued:  " << LLMeshRepository::sHTTPLargeRequestCount  					   << ", Max Lock Holdoffs:  " << LLMeshRepository::sMaxLockHoldoffs @@ -785,23 +791,23 @@ LLMeshRepoThread::~LLMeshRepoThread()  		 ++iter)  	{  		delete *iter; -		} +	}  	mHttpRequestSet.clear();  	if (mHttpHeaders) -		{ +	{  		mHttpHeaders->release();  		mHttpHeaders = NULL; -		} +	}  	if (mHttpOptions) -		{ +	{  		mHttpOptions->release();  		mHttpOptions = NULL; -			} +	}  	if (mHttpLargeOptions) -{  +	{  		mHttpLargeOptions->release();  		mHttpLargeOptions = NULL; -} +	}  	delete mHttpRequest;  	mHttpRequest = NULL;  	delete mMutex; @@ -841,53 +847,53 @@ void LLMeshRepoThread::run()  		{  			break;  		} - +		  		if (! mHttpRequestSet.empty())  		{  			// Dispatch all HttpHandler notifications  			mHttpRequest->update(0L); -			} +		}  		sRequestWaterLevel = mHttpRequestSet.size();			// Stats data update - -		// NOTE: order of queue processing intentionally favors LOD requests over header requests +		// NOTE: order of queue processing intentionally favors LOD requests over header requests +  		while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) -			{ +		{  			if (! mMutex) -				{ +			{  				break;  			} -					mMutex->lock(); -					LODRequest req = mLODReqQ.front(); -					mLODReqQ.pop(); -					LLMeshRepository::sLODProcessing--; -					mMutex->unlock(); +			mMutex->lock(); +			LODRequest req = mLODReqQ.front(); +			mLODReqQ.pop(); +			LLMeshRepository::sLODProcessing--; +			mMutex->unlock();  			if (!fetchMeshLOD(req.mMeshParams, req.mLOD))		// failed, resubmit -					{ -						mMutex->lock(); -						mLODReqQ.push(req);  +			{ +				mMutex->lock(); +				mLODReqQ.push(req) ;   				++LLMeshRepository::sLODProcessing; -						mMutex->unlock(); -					} -				} +				mMutex->unlock(); +			} +		}  		while (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) -			{ +		{  			if (! mMutex) -				{ +			{  				break;  			} -					mMutex->lock(); -					HeaderRequest req = mHeaderReqQ.front(); -					mHeaderReqQ.pop(); -					mMutex->unlock(); +			mMutex->lock(); +			HeaderRequest req = mHeaderReqQ.front(); +			mHeaderReqQ.pop(); +			mMutex->unlock();  			if (!fetchMeshHeader(req.mMeshParams))//failed, resubmit -					{ -						mMutex->lock(); -						mHeaderReqQ.push(req) ; -						mMutex->unlock(); -					} -				} +			{ +				mMutex->lock(); +				mHeaderReqQ.push(req) ; +				mMutex->unlock(); +			} +		}  		// For the final three request lists, similar goal to above but  		// slightly different queue structures.  Stay off the mutex when @@ -913,7 +919,7 @@ void LLMeshRepoThread::run()  					mSkinRequests.erase(iter);  					mMutex->unlock(); -					if (!fetchMeshSkinInfo(mesh_id)) +					if (! fetchMeshSkinInfo(mesh_id))  					{  						incomplete.insert(mesh_id);  					} @@ -942,7 +948,7 @@ void LLMeshRepoThread::run()  					mDecompositionRequests.erase(iter);  					mMutex->unlock(); -					if (!fetchMeshDecomposition(mesh_id)) +					if (! fetchMeshDecomposition(mesh_id))  					{  						incomplete.insert(mesh_id);  					} @@ -968,7 +974,7 @@ void LLMeshRepoThread::run()  					mPhysicsShapeRequests.erase(iter);  					mMutex->unlock(); -					if (!fetchMeshPhysicsShape(mesh_id)) +					if (! fetchMeshPhysicsShape(mesh_id))  					{  						incomplete.insert(mesh_id);  					} @@ -983,7 +989,7 @@ void LLMeshRepoThread::run()  				}  			}  			mMutex->unlock(); -			} +		}  		// For dev purposes only.  A dynamic change could make this false  		// and that shouldn't assert. @@ -1191,7 +1197,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)  	}  	++LLMeshRepository::sMeshRequestCount; -	bool ret = true ; +	bool ret = true;  	U32 header_size = mMeshHeaderSize[mesh_id];  	if (header_size > 0) @@ -1239,7 +1245,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)  			constructUrl(mesh_id, &http_url, &cap_version);  			if (!http_url.empty()) -			{				 +			{  				LLMeshSkinInfoHandler * handler = new LLMeshSkinInfoHandler(mesh_id, offset, size);  				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle) @@ -1286,7 +1292,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)  	++LLMeshRepository::sMeshRequestCount;  	U32 header_size = mMeshHeaderSize[mesh_id]; -	bool ret = true ; +	bool ret = true;  	if (header_size > 0)  	{ @@ -1332,9 +1338,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)  			int cap_version(2);  			std::string http_url;  			constructUrl(mesh_id, &http_url, &cap_version); - +			  			if (!http_url.empty()) -			{				 +			{  				LLMeshDecompositionHandler * handler = new LLMeshDecompositionHandler(mesh_id, offset, size);  				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle) @@ -1380,7 +1386,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)  	++LLMeshRepository::sMeshRequestCount;  	U32 header_size = mMeshHeaderSize[mesh_id]; -	bool ret = true ; +	bool ret = true;  	if (header_size > 0)  	{ @@ -1425,9 +1431,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)  			int cap_version(2);  			std::string http_url;  			constructUrl(mesh_id, &http_url, &cap_version); - +			  			if (!http_url.empty()) -			{				 +			{  				LLMeshPhysicsShapeHandler * handler = new LLMeshPhysicsShapeHandler(mesh_id, offset, size);  				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle) @@ -1516,11 +1522,11 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)  	}  	//either cache entry doesn't exist or is corrupt, request header from simulator	 -	bool retval = true ; +	bool retval = true;  	int cap_version(2);  	std::string http_url;  	constructUrl(mesh_params.getSculptID(), &http_url, &cap_version); - +	  	if (!http_url.empty())  	{  		//grab first 4KB if we're going to bother with a fetch.  Cache will prevent future fetches if a full mesh fits @@ -1608,9 +1614,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)  			int cap_version(2);  			std::string http_url;  			constructUrl(mesh_id, &http_url, &cap_version); - +			  			if (!http_url.empty()) -			{				 +			{  				LLMeshLODHandler * handler = new LLMeshLODHandler(mesh_params, lod, offset, size);  				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle) @@ -1860,7 +1866,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,  									   bool upload_skin, bool upload_joints, const std::string & upload_url, bool do_upload,  									   LLHandle<LLWholeModelFeeObserver> fee_observer,  									   LLHandle<LLWholeModelUploadObserver> upload_observer) -: LLThread("mesh upload"), +  : LLThread("mesh upload"),  	LLCore::HttpHandler(),  	mDiscarded(false),  	mDoUpload(do_upload), @@ -1882,7 +1888,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,  	mOrigin += gAgent.getAtAxis() * scale.magVec(); -	mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut") ; +	mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut");  	mHttpRequest = new LLCore::HttpRequest;  	mHttpOptions = new LLCore::HttpOptions; @@ -1950,14 +1956,14 @@ void LLMeshUploadThread::preStart()  void LLMeshUploadThread::discard()  { -	LLMutexLock lock(mMutex) ; +	LLMutexLock lock(mMutex);  	mDiscarded = true;  }  bool LLMeshUploadThread::isDiscarded() const  { -	LLMutexLock lock(mMutex) ; -	return mDiscarded ; +	LLMutexLock lock(mMutex); +	return mDiscarded;  }  void LLMeshUploadThread::run() @@ -2022,6 +2028,14 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  	{  		LLMeshUploadData data;  		data.mBaseModel = iter->first; + +		if (data.mBaseModel->mSubmodelID) +		{ +			// These are handled below to insure correct parenting order on creation +			// due to map walking being based on model address (aka random) +			continue; +		} +  		LLModelInstance& first_instance = *(iter->second.begin());  		for (S32 i = 0; i < 5; i++)  		{ @@ -2059,7 +2073,10 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  				data.mModel[LLModel::LOD_IMPOSTOR],   				decomp,  				mUploadSkin, -				mUploadJoints); +				mUploadJoints, +				FALSE, +				FALSE, +				data.mBaseModel->mSubmodelID);  			data.mAssetData = ostr.str();  			std::string str = ostr.str(); @@ -2093,17 +2110,26 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  			instance_entry["scale"] = ll_sd_from_vector3(scale);  			instance_entry["material"] = LL_MCODE_WOOD; -			instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); +			instance_entry["physics_shape_type"] = data.mModel[LLModel::LOD_PHYSICS].notNull() ? (U8)(LLViewerObject::PHYSICS_SHAPE_PRIM) : (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);  			instance_entry["mesh"] = mesh_index[data.mBaseModel];  			instance_entry["face_list"] = LLSD::emptyArray(); -			S32 end = llmin((S32)data.mBaseModel->mMaterialList.size(), data.mBaseModel->getNumVolumeFaces()) ; +			// We want to be able to allow more than 8 materials... +			// +			S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ; +  			for (S32 face_num = 0; face_num < end; face_num++)  			{  				LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];  				LLSD face_entry = LLSD::emptyMap(); -				LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); + +				LLViewerFetchedTexture *texture = NULL; + +				if (material.mDiffuseMapFilename.size()) +				{ +					texture = FindViewerTexture(material); +				}  				if ((texture != NULL) &&  					(textures.find(texture) == textures.end())) @@ -2118,9 +2144,171 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  					{											  						LLPointer<LLImageJ2C> upload_file =  							LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage()); + +						if (!upload_file.isNull() && upload_file->getDataSize()) +						{ +						texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize()); +					} +				} +				} + +				if (texture != NULL && +					mUploadTextures && +					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 != 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["diffuse_color"] = 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++; +		} +	} + +	for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) +	{ +		LLMeshUploadData data; +		data.mBaseModel = iter->first; + +		if (!data.mBaseModel->mSubmodelID) +		{ +			// These were handled above already... +			// +			continue; +		} + +		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. +			if (model_name.empty()) +			{ +				model_name = data.mBaseModel->getName(); +			} + +			if (model_metric.empty()) +			{ +				model_metric = data.mBaseModel->getMetric(); +			} + +			std::stringstream ostr; +			 +			LLModel::Decomposition& decomp = +				data.mModel[LLModel::LOD_PHYSICS].notNull() ?  +				data.mModel[LLModel::LOD_PHYSICS]->mPhysics :  +				data.mBaseModel->mPhysics; + +			decomp.mBaseHull = mHullMap[data.mBaseModel]; + +			LLSD mesh_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, +				FALSE, +				FALSE, +				data.mBaseModel->mSubmodelID); + +			data.mAssetData = ostr.str(); +			std::string str = ostr.str(); + +			res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());  +			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; +		 +			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); +		 +			instance_entry["material"] = LL_MCODE_WOOD; +			instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_NONE); +			instance_entry["mesh"] = mesh_index[data.mBaseModel]; + +			instance_entry["face_list"] = LLSD::emptyArray(); + +			// We want to be able to allow more than 8 materials... +			// +			S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ; + +			for (S32 face_num = 0; face_num < end; face_num++) +			{ +				LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]]; +				LLSD face_entry = LLSD::emptyMap(); + +				LLViewerFetchedTexture *texture = NULL; + +				if (material.mDiffuseMapFilename.size()) +				{ +					texture = FindViewerTexture(material); +				} + +				if ((texture != NULL) && +					(textures.find(texture) == textures.end())) +				{ +					textures.insert(texture); +				} + +				std::stringstream texture_str; +				if (texture != NULL && include_textures && mUploadTextures) +				{ +					if(texture->hasSavedRawImage()) +					{											 +						LLPointer<LLImageJ2C> upload_file = +							LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage()); + +						if (!upload_file.isNull() && upload_file->getDataSize()) +						{  						texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());  					}  				} +				}  				if (texture != NULL &&  					mUploadTextures && @@ -2208,7 +2396,7 @@ void LLMeshUploadThread::generateHulls()  		}  	} -	if(has_valid_requests) +	if (has_valid_requests)  	{  		// *NOTE:  Interesting livelock condition on shutdown.  If there  		// is an upload request in generateHulls() when shutdown starts, @@ -2240,7 +2428,7 @@ void LLMeshUploadThread::doWholeModelUpload()  		mModelData = LLSD::emptyMap();  		wholeModelToLLSD(mModelData, true);  		LLSD body = mModelData["asset_resources"]; -		dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num)); +		dump_llsd_to_file(body, make_dump_name("whole_model_body_", dump_num));  		LLCore::BufferArray * ba = new LLCore::BufferArray;  		LLCore::BufferArrayStream bas(ba); @@ -2271,7 +2459,7 @@ void LLMeshUploadThread::doWholeModelUpload()  			mHttpRequest->update(0);  			while (! LLApp::isQuitting() && ! finished() && ! isDiscarded()) -		{ +			{  				ms_sleep(sleep_time);  				sleep_time = llmin(250U, sleep_time + sleep_time);  				mHttpRequest->update(0); @@ -2287,7 +2475,7 @@ void LLMeshUploadThread::doWholeModelUpload()  			}  		}  	} -			} +}  void LLMeshUploadThread::requestWholeModelFee()  { @@ -2318,11 +2506,11 @@ void LLMeshUploadThread::requestWholeModelFee()  		LL_WARNS(LOG_MESH) << "Couldn't issue request for model fee.  Reason:  " << mHttpStatus.toString()  						   << " (" << mHttpStatus.toTerseString() << ")"  						   << LL_ENDL; -		} +	}  	else  	{  		U32 sleep_time(10); - +		  		mHttpRequest->update(0);  		while (! LLApp::isQuitting() && ! finished() && ! isDiscarded())  		{ @@ -2335,7 +2523,7 @@ void LLMeshUploadThread::requestWholeModelFee()  			LL_DEBUGS(LOG_MESH) << "Mesh fee query operation discarded." << LL_ENDL;  		}  	} -	} +}  // Does completion duty for both fee queries and actual uploads. @@ -2388,12 +2576,12 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp  				{  					LLCore::BufferArrayStream bas(ba);  					LLSDSerialize::fromXML(body, bas); -} +				}  			}  			dump_llsd_to_file(body, make_dump_name("whole_model_upload_response_", dump_num));  			if (body["state"].asString() == "complete") -{ +			{  				// requested "mesh" asset type isn't actually the type  				// of the resultant object, fix it up here.  				mModelData["asset_type"] = "object"; @@ -2421,7 +2609,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp  		// model fee case  		LLWholeModelFeeObserver* observer(mFeeObserverHandle.get());  		mWholeModelUploadURL.clear(); - +		  		if (! status)  		{  			LL_WARNS(LOG_MESH) << "Fee request failed.  Reason:  " << reason @@ -2446,18 +2634,18 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp  				body = llsd_from_file("fake_upload_error.xml");  			}  			else -	{ +			{  				LLCore::BufferArray * ba(response->getBody());  				if (ba && ba->size()) -		{ +				{  					LLCore::BufferArrayStream bas(ba);  					LLSDSerialize::fromXML(body, bas); -		} -	} +				} +			}  			dump_llsd_to_file(body, make_dump_name("whole_model_fee_response_", dump_num)); - +		  			if (body["state"].asString() == "upload") -	{ +			{  				mWholeModelUploadURL = body["uploader"].asString();  				if (observer) @@ -2526,7 +2714,7 @@ void LLMeshRepoThread::notifyLoadedMeshes()  		LODRequest req = mUnavailableQ.front();  		mUnavailableQ.pop();  		mMutex->unlock(); -		 +  		update_metrics = true;  		gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD);  	} @@ -2543,18 +2731,18 @@ void LLMeshRepoThread::notifyLoadedMeshes()  				skin_info_q.swap(mSkinInfoQ);  			}  			if (! mDecompositionQ.empty()) -	{ +			{  				decomp_q.swap(mDecompositionQ); -	} +			}  			mMutex->unlock();  			// Process the elements free of the lock  			while (! skin_info_q.empty()) -	{ +			{  				gMeshRepo.notifySkinInfoReceived(skin_info_q.front());  				skin_info_q.pop_front(); -	} +			}  			while (! decomp_q.empty())  			{ @@ -2651,7 +2839,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)  void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)  {  	mProcessed = true; -	 +  	unsigned int retries(0U);  	response->getRetries(NULL, &retries);  	LLMeshRepository::sHTTPRetryCount += retries; @@ -2683,18 +2871,18 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo  			LL_WARNS_ONCE(LOG_MESH) << "Non-206 successful status received for fetch:  "  									<< status.toTerseString() << LL_ENDL;  		} - +		  		LLCore::BufferArray * body(response->getBody());  		S32 data_size(body ? body->size() : 0);  		U8 * data(NULL); -	if (data_size > 0) -	{ +		if (data_size > 0) +		{  			// *TODO: Try to get rid of data copying and add interfaces  			// that support BufferArray directly.  Introduce a two-phase  			// handler, optional first that takes a body, fallback second  			// that requires a temporary allocation and data copy. -		data = new U8[data_size]; +			data = new U8[data_size];  			body->read(0, (char *) data, data_size);  			LLMeshRepository::sBytesReceived += data_size;  		} @@ -2739,7 +2927,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status)  	{  		gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i));  	} -	} +}  void LLMeshHeaderHandler::processData(LLCore::BufferArray * body, U8 * data, S32 data_size)  { @@ -2756,12 +2944,12 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * body, U8 * data, S32  		// Can't get the header so none of the LODs will be available  		LLMutexLock lock(gMeshRepo.mThread->mMutex);  		for (int i(0); i < 4; ++i) -	{ +		{  			gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); -	}  		} +	}  	else if (data && data_size > 0) -		{ +	{  		// header was successfully retrieved from sim, cache in vfs  		LLSD header = gMeshRepo.mThread->mMeshHeader[mesh_id]; @@ -2774,12 +2962,12 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * body, U8 * data, S32  			S32 lod_bytes = 0;  			for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i) -	{ +			{  				// figure out how many bytes we'll need to reserve in the file  				const std::string & lod_name = header_lod[i];  				lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger()); -	} - +			} +		  			// just in case skin info or decomposition is at the end of the file (which it shouldn't be)  			lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());  			lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger()); @@ -2787,37 +2975,37 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * body, U8 * data, S32  			S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];  			S32 bytes = lod_bytes + header_bytes;  - +		  			// It's possible for the remote asset to have more data than is needed for the local cache  			// only allocate as much space in the VFS as is needed for the local cache  			data_size = llmin(data_size, bytes);  			LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH, LLVFile::WRITE);  			if (file.getMaxSize() >= bytes || file.setMaxSize(bytes)) -		{ +			{  				LLMeshRepository::sCacheBytesWritten += data_size;  				++LLMeshRepository::sCacheWrites;  				file.write(data, data_size); - +			  				// zero out the rest of the file   				U8 block[MESH_HEADER_SIZE];  				memset(block, 0, sizeof(block)); -	 +  				while (bytes-file.tell() > sizeof(block)) -	{ +				{  					file.write(block, sizeof(block)); -	} +				}  				S32 remaining = bytes-file.tell();  				if (remaining > 0) -	{ +				{  					file.write(block, remaining);  				}  			}  		}  	} -	} +}  LLMeshLODHandler::~LLMeshLODHandler()  { @@ -2829,8 +3017,8 @@ LLMeshLODHandler::~LLMeshLODHandler()  			gMeshRepo.mThread->lockAndLoadMeshLOD(mMeshParams, mLOD);  		}  		LLMeshRepoThread::decActiveLODRequests(); -		}  	} +}  void LLMeshLODHandler::processFailure(LLCore::HttpStatus status)  { @@ -2844,10 +3032,10 @@ void LLMeshLODHandler::processFailure(LLCore::HttpStatus status)  }  void LLMeshLODHandler::processData(LLCore::BufferArray * body, U8 * data, S32 data_size) -	{ +{  	if ((! MESH_LOD_PROCESS_FAILED) && gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size))  	{ -		//good fetch from sim, write to VFS for caching +		// good fetch from sim, write to VFS for caching  		LLVFile file(gVFS, mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLVFile::WRITE);  		S32 offset = mOffset; @@ -2860,7 +3048,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * body, U8 * data, S32 da  			LLMeshRepository::sCacheBytesWritten += size;  			++LLMeshRepository::sCacheWrites;  		} -		} +	}  	else  	{  		LL_WARNS(LOG_MESH) << "Error during mesh LOD processing.  ID:  " << mMeshParams.getSculptID() @@ -2872,12 +3060,12 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * body, U8 * data, S32 da  }  LLMeshSkinInfoHandler::~LLMeshSkinInfoHandler() -	{ +{  		llassert(mProcessed); -	} +}  void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status) -	{ +{  	LL_WARNS(LOG_MESH) << "Error during mesh skin info handling.  ID:  " << mMeshID  					   << ", Reason:  " << status.toString()  					   << " (" << status.toTerseString() << ").  Not retrying." @@ -2885,13 +3073,13 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status)  	// *TODO:  Mark mesh unavailable on error.  For now, simply leave  	// request unfulfilled rather than retry forever. -		} +}  void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * body, U8 * data, S32 data_size) -	{ +{  	if ((! MESH_SKIN_INFO_PROCESS_FAILED) && gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size))  	{ -		//good fetch from sim, write to VFS for caching +		// good fetch from sim, write to VFS for caching  		LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);  		S32 offset = mOffset; @@ -2920,14 +3108,14 @@ LLMeshDecompositionHandler::~LLMeshDecompositionHandler()  }  void LLMeshDecompositionHandler::processFailure(LLCore::HttpStatus status) -	{ +{  	LL_WARNS(LOG_MESH) << "Error during mesh decomposition handling.  ID:  " << mMeshID  					   << ", Reason:  " << status.toString()  					   << " (" << status.toTerseString() << ").  Not retrying."  					   << LL_ENDL;  	// *TODO:  Mark mesh unavailable on error.  For now, simply leave  	// request unfulfilled rather than retry forever. -	} +}  void LLMeshDecompositionHandler::processData(LLCore::BufferArray * body, U8 * data, S32 data_size)  { @@ -2946,34 +3134,34 @@ void LLMeshDecompositionHandler::processData(LLCore::BufferArray * body, U8 * da  			file.seek(offset);  			file.write(data, size);  		} -		} -		else -		{ +	} +	else +	{  		LL_WARNS(LOG_MESH) << "Error during mesh decomposition processing.  ID:  " << mMeshID  						   << ", Unknown reason.  Not retrying."  						   << LL_ENDL;  		// *TODO:  Mark mesh unavailable on error -		}  	} +}  LLMeshPhysicsShapeHandler::~LLMeshPhysicsShapeHandler() -	{ +{  		llassert(mProcessed); -	} +}  void LLMeshPhysicsShapeHandler::processFailure(LLCore::HttpStatus status) -	{ +{  	LL_WARNS(LOG_MESH) << "Error during mesh physics shape handling.  ID:  " << mMeshID  					   << ", Reason:  " << status.toString()  					   << " (" << status.toTerseString() << ").  Not retrying."  					   << LL_ENDL;  	// *TODO:  Mark mesh unavailable on error -	} +}  void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * body, U8 * data, S32 data_size) -			{ +{  	if ((! MESH_PHYS_SHAPE_PROCESS_FAILED) && gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size)) -				{ +	{  		// good fetch from sim, write to VFS for caching  		LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE); @@ -2981,13 +3169,13 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * body, U8 * dat  		S32 size = mRequestedBytes;  		if (file.getSize() >= offset+size) -				{ +		{  			LLMeshRepository::sCacheBytesWritten += size;  			++LLMeshRepository::sCacheWrites;  			file.seek(offset);  			file.write(data, size); -			}  		} +	}  	else  	{  		LL_WARNS(LOG_MESH) << "Error during mesh physics shape processing.  ID:  " << mMeshID @@ -3187,7 +3375,7 @@ void LLMeshRepository::notifyLoadedMeshes()  	if (1 == mGetMeshVersion)  	{  		// Legacy GetMesh operation with high connection concurrency -	LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("MeshMaxConcurrentRequests"); +		LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("MeshMaxConcurrentRequests");  		LLMeshRepoThread::sRequestHighWater = llclamp(2 * S32(LLMeshRepoThread::sMaxConcurrentRequests),  													  REQUEST_HIGH_WATER_MIN,  													  REQUEST_HIGH_WATER_MAX); @@ -3207,7 +3395,7 @@ void LLMeshRepository::notifyLoadedMeshes()  													 REQUEST2_LOW_WATER_MIN,  													 REQUEST2_LOW_WATER_MAX);  	} - +	  	//clean up completed upload threads  	for (std::vector<LLMeshUploadThread*>::iterator iter = mUploads.begin(); iter != mUploads.end(); )  	{ @@ -3284,7 +3472,7 @@ void LLMeshRepository::notifyLoadedMeshes()  	//call completed callbacks on finished decompositions  	mDecompThread->notifyCompleted(); -	 +  	// For major operations, attempt to get the required locks  	// without blocking and punt if they're not available.  The  	// longest run of holdoffs is kept in sMaxLockHoldoffs just @@ -3300,18 +3488,18 @@ void LLMeshRepository::notifyLoadedMeshes()  			// If we can't get the locks, skip and pick this up later.  			++hold_offs;  			sMaxLockHoldoffs = llmax(sMaxLockHoldoffs, hold_offs); -		return; -	} +			return; +		}  		hold_offs = 0; - +		  		if (gAgent.getRegion())  		{  			// Update capability urls -	static std::string region_name("never name a region this"); - -		if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived()) -		{ -			region_name = gAgent.getRegion()->getName(); +			static std::string region_name("never name a region this"); +			 +			if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived()) +			{ +				region_name = gAgent.getRegion()->getName();  				const bool use_v1(gSavedSettings.getBOOL("MeshUseGetMesh1"));  				const std::string mesh1(gAgent.getRegion()->getCapability("GetMesh"));  				const std::string mesh2(gAgent.getRegion()->getCapability("GetMesh2")); @@ -3322,9 +3510,9 @@ void LLMeshRepository::notifyLoadedMeshes()  									<< ", GetMesh:  " << mesh1  									<< ", using version:  " << mGetMeshVersion  									<< LL_ENDL; +			}  		} -	} - +		  		//popup queued error messages from background threads  		while (!mUploadErrorQ.empty())  		{ @@ -3338,46 +3526,46 @@ void LLMeshRepository::notifyLoadedMeshes()  			S32 push_count = LLMeshRepoThread::sRequestHighWater - active_count;  			if (mPendingRequests.size() > push_count) -		{ +			{  				// More requests than the high-water limit allows so  				// sort and forward the most important. -			//calculate "score" for pending requests +				//calculate "score" for pending requests -			//create score map -			std::map<LLUUID, F32> score_map; +				//create score map +				std::map<LLUUID, F32> score_map; -			for (U32 i = 0; i < 4; ++i) -			{ -				for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin();  iter != mLoadingMeshes[i].end(); ++iter) +				for (U32 i = 0; i < 4; ++i)  				{ -					F32 max_score = 0.f; -					for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) +					for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin();  iter != mLoadingMeshes[i].end(); ++iter)  					{ -						LLViewerObject* object = gObjectList.findObject(*obj_iter); - -						if (object) +						F32 max_score = 0.f; +						for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter)  						{ -							LLDrawable* drawable = object->mDrawable; -							if (drawable) +							LLViewerObject* object = gObjectList.findObject(*obj_iter); + +							if (object)  							{ -								F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f); -								max_score = llmax(max_score, cur_score); +								LLDrawable* drawable = object->mDrawable; +								if (drawable) +								{ +									F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f); +									max_score = llmax(max_score, cur_score); +								}  							}  						} -					} -					score_map[iter->first.getSculptID()] = max_score; +						score_map[iter->first.getSculptID()] = max_score; +					}  				} -			} -			//set "score" for pending requests -			for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter) -			{ -				iter->mScore = score_map[iter->mMeshParams.getSculptID()]; -			} +				//set "score" for pending requests +				for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter) +				{ +					iter->mScore = score_map[iter->mMeshParams.getSculptID()]; +				} -			//sort by "score" +				//sort by "score"  				std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count,  								  mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater());  			} @@ -3680,7 +3868,7 @@ LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)  void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, -									bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload, +								   bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload,  								   LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer)  {  	LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, upload_url,  @@ -3751,37 +3939,6 @@ void LLMeshUploadThread::decomposeMeshMatrix(LLMatrix4& transformation,  	result_rot = quat_rotation;   } -bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const -{ -	if (mDiffuseMap != rhs.mDiffuseMap) -	{ -		return mDiffuseMap < rhs.mDiffuseMap; -	} - -	if (mDiffuseMapFilename != rhs.mDiffuseMapFilename) -	{ -		return mDiffuseMapFilename < rhs.mDiffuseMapFilename; -	} - -	if (mDiffuseMapLabel != rhs.mDiffuseMapLabel) -	{ -		return mDiffuseMapLabel < rhs.mDiffuseMapLabel; -	} - -	if (mDiffuseColor != rhs.mDiffuseColor) -	{ -		return mDiffuseColor < rhs.mDiffuseColor; -	} - -	if (mBinding != rhs.mBinding) -	{ -		return mBinding < rhs.mBinding; -	} - -	return mFullbright < rhs.mFullbright; -} - -  void LLMeshRepository::updateInventory(inventory_data data)  {  	LLMutexLock lock(mMeshMutex); @@ -4179,7 +4336,7 @@ void LLPhysicsDecomp::doDecompositionSingleHull()  	setMeshData(mesh, true);  	LLCDResult ret = decomp->buildSingleHull() ; -	if(ret) +	if (ret)  	{  		LL_WARNS(LOG_MESH) << "Could not execute decomposition stage when attempting to create single hull." << LL_ENDL;  		make_box(mCurRequest); @@ -4367,60 +4524,6 @@ void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)  	mStatusMessage = msg;  } -LLModelInstance::LLModelInstance(LLSD& data) -{ -	mLocalMeshID = data["mesh_id"].asInteger(); -	mLabel = data["label"].asString(); -	mTransform.setValue(data["transform"]); - -	for (U32 i = 0; i < data["material"].size(); ++i) -	{ -		LLImportMaterial mat(data["material"][i]); -		mMaterial[mat.mBinding] = mat; -	} -} - - -LLSD LLModelInstance::asLLSD() -{	 -	LLSD ret; - -	ret["mesh_id"] = mModel->mLocalID; -	ret["label"] = mLabel; -	ret["transform"] = mTransform.getValue(); -	 -	U32 i = 0; -	for (std::map<std::string, LLImportMaterial>::iterator iter = mMaterial.begin(); iter != mMaterial.end(); ++iter) -	{ -		ret["material"][i++] = iter->second.asLLSD(); -	} - -	return ret; -} - -LLImportMaterial::LLImportMaterial(LLSD& data) -{ -	mDiffuseMapFilename = data["diffuse"]["filename"].asString(); -	mDiffuseMapLabel = data["diffuse"]["label"].asString(); -	mDiffuseColor.setValue(data["diffuse"]["color"]); -	mFullbright = data["fullbright"].asBoolean(); -	mBinding = data["binding"].asString(); -} - - -LLSD LLImportMaterial::asLLSD() -{ -	LLSD ret; - -	ret["diffuse"]["filename"] = mDiffuseMapFilename; -	ret["diffuse"]["label"] = mDiffuseMapLabel; -	ret["diffuse"]["color"] = mDiffuseColor.getValue(); -	ret["fullbright"] = mFullbright; -	ret["binding"] = mBinding; - -	return ret; -} -  void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp)  {  	decomp.mMesh.resize(decomp.mHull.size());  | 
