diff options
| author | Loren Shih <seraph@lindenlab.com> | 2011-05-25 09:12:36 -0400 | 
|---|---|---|
| committer | Loren Shih <seraph@lindenlab.com> | 2011-05-25 09:12:36 -0400 | 
| commit | e03f25d51a5840d9d4f29d0ee238ed4b881b8cee (patch) | |
| tree | 7d8ad6f2fd58abc004388c8174293ee78bb927bd /indra/newview | |
| parent | bc0df31d1beaa6eddd48431eb9e42d38d3698673 (diff) | |
| parent | cb797532c0bd7ca0ab4caf66c48aa55ec99160a0 (diff) | |
automated merge mesh-development -> mesh-development
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/newview/llaccountingquotamanager.cpp | 264 | ||||
| -rw-r--r-- | indra/newview/llaccountingquotamanager.h | 60 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 25 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelwizard.cpp | 25 | ||||
| -rw-r--r-- | indra/newview/llfloatertools.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 238 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 10 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 9 | ||||
| -rw-r--r-- | indra/newview/llviewerobjectlist.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llviewerobjectlist.h | 3 | ||||
| -rw-r--r-- | indra/newview/llviewerregion.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llviewerregion.h | 1 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 23 | 
16 files changed, 589 insertions, 97 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index cbf22b75e8..769dcf8457 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -77,6 +77,7 @@ include_directories(  set(viewer_SOURCE_FILES      groupchatlistener.cpp +    llaccountingquotamanager.cpp      llagent.cpp      llagentaccess.cpp      llagentcamera.cpp @@ -626,6 +627,7 @@ set(viewer_HEADER_FILES      CMakeLists.txt      ViewerInstall.cmake      groupchatlistener.h +    llaccountingquotamanager.h      llagent.h      llagentaccess.h      llagentcamera.h diff --git a/indra/newview/llaccountingquotamanager.cpp b/indra/newview/llaccountingquotamanager.cpp new file mode 100644 index 0000000000..ada74ea44c --- /dev/null +++ b/indra/newview/llaccountingquotamanager.cpp @@ -0,0 +1,264 @@ +/** 
 + * @file LLAccountingQuotaManager.cpp
 + * @ Handles the setting and accessing for costs associated with mesh 
 + *
 + * $LicenseInfo:firstyear=2001&license=viewergpl$
 + * 
 + * Copyright (c) 2001-2010, Linden Research, Inc.
 + * 
 + * Second Life Viewer Source Code
 + * The source code in this file ("Source Code") is provided by Linden Lab
 + * to you under the terms of the GNU General Public License, version 2.0
 + * ("GPL"), unless you have obtained a separate licensing agreement
 + * ("Other License"), formally executed by you and Linden Lab.  Terms of
 + * the GPL can be found in doc/GPL-license.txt in this distribution, or
 + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 + * 
 + * There are special exceptions to the terms and conditions of the GPL as
 + * it is applied to this Source Code. View the full text of the exception
 + * in the file doc/FLOSS-exception.txt in this software distribution, or
 + * online at
 + * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 + * 
 + * By copying, modifying or distributing this software, you acknowledge
 + * that you have read and understood your obligations described above,
 + * and agree to abide by those obligations.
 + * 
 + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 + * COMPLETENESS OR PERFORMANCE.
 + * $/LicenseInfo$
 + */
 +
 +#include "llviewerprecompiledheaders.h"
 +#include "llaccountingquotamanager.h"
 +#include "llagent.h"
 +#include "llviewerregion.h"
 +#include "llviewerobject.h"
 +#include "llviewerobjectlist.h"
 +#include "llviewerparcelmgr.h"
 +#include "llparcel.h"
 +
 +//===============================================================================
 +LLAccountingQuotaManager::LLAccountingQuotaManager()
 +{	
 +}
 +//===============================================================================
 +class LLAccountingQuotaResponder : public LLCurl::Responder
 +{
 +public:
 +	LLAccountingQuotaResponder( const LLSD& objectIDs )
 +	: mObjectIDs( objectIDs )
 +	{
 +	}
 +		
 +	void clearPendingRequests ( void )
 +	{
 +		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
 +		{
 +			LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( iter->asUUID() );
 +		}
 +	}
 +	
 +	void error( U32 statusNum, const std::string& reason )
 +	{
 +		llwarns	<< "Transport error "<<reason<<llendl;	
 +		//prep#do we really want to remove all because of one failure - verify
 +		clearPendingRequests();
 +	}
 +	
 +	void result( const LLSD& content )
 +	{
 +		if ( !content.isMap() || content.has("error") )
 +		{
 +			llwarns	<< "Error on fetched data"<< llendl;
 +			//prep#do we really want to remove all because of one failure - verify
 +			clearPendingRequests();
 +			return;
 +		}
 +		
 +		//Differentiate what the incoming caps could be from the data
 +		//bool VOContent  = content.has("Objects");
 +		bool containsParcel    = content.has("parcel");
 +		bool containsSelection = content.has("selected");
 +		//bool VORegion   = content.has("region");
 +				
 +		//Loop over the stored object ids checking against the incoming data
 +		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
 +		{
 +			LLUUID objectID = iter->asUUID();
 +						
 +			LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
 +				
 +			if ( containsParcel )
 +			{
 +					//Typically should be one
 +					S32 dataCount = content["parcel"].size();
 +					for(S32 i = 0; i < dataCount; i++)
 +					{
 +						//prep#todo verify that this is safe, otherwise just add a bool
 +						S32 parcelId = 0;
 +						S32 parcelOwner = 0;
 +						if ( content["parcel"][i].has("parcel_id") )
 +						{
 +							parcelId = content["parcel"][i]["parcel_id"].asInteger();
 +						}
 +						if ( content["parcel"][i].has("parcel_owner") )
 +						{
 +							parcelOwner = content["parcel"][i]["parcel_owner"].asInteger();
 +						}
 +											
 +						F32 ownerRenderCost		= 0;
 +						F32 ownerPhysicsCost	= 0;
 +						F32 ownerNetworkCost	= 0;
 +						F32 ownerSimulationCost = 0;
 +						
 +						F32 groupRenderCost		= 0;
 +						F32 groupPhysicsCost	= 0;
 +						F32 groupNetworkCost	= 0;
 +						F32 groupSimulationCost = 0;
 +						
 +						F32 otherRenderCost		= 0;
 +						F32 otherPhysicsCost	= 0;
 +						F32 otherNetworkCost	= 0;
 +						F32 otherSimulationCost = 0;
 +						
 +						F32 totalRenderCost		= 0;
 +						F32 totalPhysicsCost	= 0;
 +						F32 totalNetworkCost	= 0;
 +						F32 totalSimulationCost = 0;
 +						
 +						if ( content["parcel"][i].has("owner") )
 +						{
 +							ownerRenderCost		= content["parcel"][i]["owner"]["render"].asReal();
 +							ownerPhysicsCost	= content["parcel"][i]["owner"]["physics"].asReal();
 +							ownerNetworkCost	= content["parcel"][i]["owner"]["network"].asReal();
 +							ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal();
 +							
 +						}
 +						if ( content["parcel"][i].has("group") )
 +						{
 +							groupRenderCost		= content["parcel"][i]["group"]["render"].asReal();
 +							groupPhysicsCost	= content["parcel"][i]["group"]["physics"].asReal();
 +							groupNetworkCost	= content["parcel"][i]["group"]["network"].asReal();
 +							groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal();
 +							
 +						}
 +						if ( content["parcel"][i].has("other") )
 +						{
 +							otherRenderCost		= content["parcel"][i]["other"]["render"].asReal();
 +							otherPhysicsCost	= content["parcel"][i]["other"]["physics"].asReal();
 +							otherNetworkCost	= content["parcel"][i]["other"]["network"].asReal();
 +							otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal();
 +						}
 +						
 +						if ( content["parcel"][i].has("total") )
 +						{
 +							totalRenderCost		= content["parcel"][i]["total"]["render"].asReal();
 +							totalPhysicsCost	= content["parcel"][i]["total"]["physics"].asReal();
 +							totalNetworkCost	= content["parcel"][i]["total"]["network"].asReal();
 +							totalSimulationCost = content["parcel"][i]["total"]["simulation"].asReal();
 +							
 +						}
 +						
 +						ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost,
 +												 groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost,
 +												 otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost,
 +												 totalRenderCost, totalPhysicsCost, totalNetworkCost, totalSimulationCost );
 +						//Update the Parcel						
 +						LLParcel* pParcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
 +						if ( pParcel )
 +						{
 +							pParcel->updateQuota( objectID, parcelQuota ); 
 +						}
 +					}					
 +				}
 +			else 
 +			if ( containsSelection )
 +			{
 +				S32 dataCount = content["selected"].size();
 +				for(S32 i = 0; i < dataCount; i++)
 +				{
 +					
 +					F32 renderCost		= 0;
 +					F32 physicsCost		= 0;
 +					F32 networkCost		= 0;
 +					F32 simulationCost	= 0;
 +					
 +					S32 localId = 0;
 +					
 +					localId			= content["selected"][i]["local_id"].asInteger();
 +					renderCost		= content["selected"][i]["render"].asReal();
 +					physicsCost		= content["selected"][i]["physics"].asReal();
 +					networkCost		= content["selected"][i]["network"].asReal();
 +					simulationCost	= content["selected"][i]["simulation"].asReal();
 +					
 +					SelectionQuota selectionQuota( localId, renderCost, physicsCost, networkCost, simulationCost );
 +					
 +					//Update the objects					
 +					//gObjectList.updateQuota( localId, selectionQuota ); 
 +					
 +				}
 +			}
 +			else
 +			{
 +				//Nothing in string 
 +				LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
 +			}
 +		}
 +	}
 +	
 +private:
 +	//List of posted objects
 +	LLSD mObjectIDs;
 +};
 +//===============================================================================
 +void LLAccountingQuotaManager::fetchQuotas( const std::string& url )
 +{
 +	// Invoking system must have already determined capability availability
 +	if ( !url.empty() )
 +	{
 +		LLSD objectList;
 +		U32  objectIndex = 0;
 +		IDIt IDIter = mUpdateObjectQuota.begin();
 +		IDIt IDIterEnd = mUpdateObjectQuota.end();
 +		
 +		for ( ; IDIter != IDIterEnd; ++IDIter )
 +		{
 +			// Check to see if a request for this object has already been made.
 +			if ( mPendingObjectQuota.find( *IDIter ) ==	mPendingObjectQuota.end() )
 +			{
 +				mPendingObjectQuota.insert( *IDIter );	
 +				objectList[objectIndex++] = *IDIter;
 +			}
 +		}
 +	
 +		mUpdateObjectQuota.clear();
 +		
 +		//Post results
 +		if ( objectList.size() > 0 )
 +		{
 +			LLSD dataToPost = LLSD::emptyMap();			
 +			dataToPost["object_ids"] = objectList;
 +			LLHTTPClient::post( url, dataToPost, new LLAccountingQuotaResponder( objectList ));
 +		}
 +	}
 +	else
 +	{
 +		//url was empty - warn & continue
 +		llwarns<<"Supplied url is empty "<<llendl;
 +		mUpdateObjectQuota.clear();
 +		mPendingObjectQuota.clear();
 +	}
 +}
 +//===============================================================================
 +void LLAccountingQuotaManager::updateObjectCost( const LLUUID& objectID )
 +{
 +	mUpdateObjectQuota.insert( objectID );
 +}
 +//===============================================================================
 +void LLAccountingQuotaManager::removePendingObjectQuota( const LLUUID& objectID )
 +{
 +	mPendingObjectQuota.erase( objectID );
 +}
 +//===============================================================================
 diff --git a/indra/newview/llaccountingquotamanager.h b/indra/newview/llaccountingquotamanager.h new file mode 100644 index 0000000000..f605d1e6b2 --- /dev/null +++ b/indra/newview/llaccountingquotamanager.h @@ -0,0 +1,60 @@ +/**  + * @file lllAccountingQuotaManager.h + * @ + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + *  + * Copyright (c) 2001-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_ACCOUNTINGQUOTAMANAGER_H +#define LL_ACCOUNTINGQUOTAMANAGER_H +//=============================================================================== +#include "llaccountingquota.h" +//=============================================================================== +class LLAccountingQuotaManager : public LLSingleton<LLAccountingQuotaManager> +{ +public: +	//Ctor +	LLAccountingQuotaManager(); +	//Store an object that will be eventually fetched +	void updateObjectCost( const LLUUID& objectID ); +	//Request quotas for object list +	void fetchQuotas( const std::string& url ); +	//Delete a specific object from the pending list +	void removePendingObjectQuota( const LLUUID& objectID ); +	 +private: +	//Set of objects that need to update their cost +	std::set<LLUUID> mUpdateObjectQuota; +	//During fetchQuota we move object into a the pending set to signify that  +	//a fetch has been instigated. +	std::set<LLUUID> mPendingObjectQuota; +	typedef std::set<LLUUID>::iterator IDIt; +}; +//=============================================================================== + +#endif diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 9dd5269a6b..2a3bd37129 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -4962,9 +4962,12 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL  	if (mdl)  	{  		U16 index_offset = 0; +		U16 tri[3] ;  		mPositions.clear();  		mIndices.clear(); +		mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ; +		mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ;  		//queue up vertex positions and indices  		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) @@ -4978,12 +4981,28 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL  			for (U32 j = 0; j < face.mNumVertices; ++j)  			{  				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); +				for(U32 k = 0 ; k < 3 ; k++) +				{ +					mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ; +					mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ; +				}  			} -			for (U32 j = 0; j < face.mNumIndices; ++j) +			updateTriangleAreaThreshold() ; + +			for (U32 j = 0; j+2 < face.mNumIndices; j += 3)  			{ -				mIndices.push_back(face.mIndices[j]+index_offset); -			} +				tri[0] = face.mIndices[j] + index_offset ; +				tri[1] = face.mIndices[j + 1] + index_offset ; +				tri[2] = face.mIndices[j + 2] + index_offset ; +				 +				if(isValidTriangle(tri[0], tri[1], tri[2])) +				{ +					mIndices.push_back(tri[0]); +					mIndices.push_back(tri[1]); +					mIndices.push_back(tri[2]); +				} +			}			  			index_offset += face.mNumVertices;  		} diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp index faf81dbc5c..e44737f39e 100644 --- a/indra/newview/llfloatermodelwizard.cpp +++ b/indra/newview/llfloatermodelwizard.cpp @@ -441,10 +441,13 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM  	if (mdl)  	{  		U16 index_offset = 0; +		U16 tri[3] ;  		mPositions.clear();  		mIndices.clear(); - +		mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ; +		mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ; +		  		//queue up vertex positions and indices  		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)  		{ @@ -457,11 +460,27 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM  			for (U32 j = 0; j < face.mNumVertices; ++j)  			{  				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); +				for(U32 k = 0 ; k < 3 ; k++) +				{ +					mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ; +					mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ; +				}  			} -			for (U32 j = 0; j < face.mNumIndices; ++j) +			updateTriangleAreaThreshold() ; + +			for (U32 j = 0; j+2 < face.mNumIndices; j += 3)  			{ -				mIndices.push_back(face.mIndices[j]+index_offset); +				tri[0] = face.mIndices[j] + index_offset ; +				tri[1] = face.mIndices[j + 1] + index_offset ; +				tri[2] = face.mIndices[j + 2] + index_offset ; +				 +				if(isValidTriangle(tri[0], tri[1], tri[2])) +				{ +					mIndices.push_back(tri[0]); +					mIndices.push_back(tri[1]); +					mIndices.push_back(tri[2]); +				}  			}  			index_offset += face.mNumVertices; diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 73c1f99fa0..061a42ab57 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -85,6 +85,7 @@  #include "llviewerwindow.h"  #include "llvovolume.h"  #include "lluictrlfactory.h" +#include "llaccountingquotamanager.h"  // Globals  LLFloaterTools *gFloaterTools = NULL; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index b5180854ef..318beafe65 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -632,10 +632,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)  	}  	// We're hiding mesh types +#if 0  	if (item->getType() == LLAssetType::AT_MESH)  	{  		return mask;  	} +#endif  	LLViewerInventoryItem* old_item = getItem(item->getUUID());  	LLPointer<LLViewerInventoryItem> new_item; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index d9a58d56fe..b79f120eda 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -498,18 +498,29 @@ public:  		//assert_main_thread();  		llinfos << "completed" << llendl;  		mThread->mPendingUploads--; -		dumpLLSDToFile(content,"whole_model_response.xml"); +		dumpLLSDToFile(content,"whole_model_fee_response.xml"); +		if (isGoodStatus(status)) +		{ +			mThread->mWholeModelUploadURL = content["uploader"].asString();  +		} +		else +		{ +			llinfos << "upload failed" << llendl; +			mThread->mWholeModelUploadURL = ""; +		} -		mThread->mWholeModelUploadURL = content["uploader"].asString();   	}  };  class LLWholeModelUploadResponder: public LLCurl::Responder  {  	LLMeshUploadThread* mThread; +	LLSD mPostData; +	  public: -	LLWholeModelUploadResponder(LLMeshUploadThread* thread): -		mThread(thread) +	LLWholeModelUploadResponder(LLMeshUploadThread* thread, LLSD& post_data): +		mThread(thread), +		mPostData(post_data)  	{  	}  	virtual void completed(U32 status, @@ -520,6 +531,10 @@ public:  		llinfos << "upload completed" << llendl;  		mThread->mPendingUploads--;  		dumpLLSDToFile(content,"whole_model_upload_response.xml"); +		// requested "mesh" asset type isn't actually the type +		// of the resultant object, fix it up here. +		mPostData["asset_type"] = "object"; +		gMeshRepo.updateInventory(LLMeshRepository::inventory_data(mPostData,content));  	}  }; @@ -1386,108 +1401,131 @@ void LLMeshUploadThread::run()  	}  } -#if 1  void dumpLLSDToFile(const LLSD& content, std::string filename)  { +#if 1  	std::ofstream of(filename.c_str());  	LLSDSerialize::toPrettyXML(content,of); -}  #endif +}  void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  { -	// TODO where do textures go? -  	LLSD result;  	LLSD res;  	result["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);  	result["asset_type"] = "mesh";  	result["inventory_type"] = "object"; -	result["name"] = "your name here"; +	result["name"] = "mesh model";  	result["description"] = "your description here"; -	// TODO "optional" fields from the spec -	  	res["mesh_list"] = LLSD::emptyArray(); -// TODO Textures -	//res["texture_list"] = LLSD::emptyArray(); +	res["texture_list"] = LLSD::emptyArray(); +	res["instance_list"] = LLSD::emptyArray();  	S32 mesh_num = 0;  	S32 texture_num = 0;  	std::set<LLViewerTexture* > textures; +	std::map<LLViewerTexture*,S32> texture_index; +	std::map<LLModel*,S32> mesh_index; + +	S32 instance_num = 0; +	  	for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)  	{  		LLMeshUploadData data;  		data.mBaseModel = iter->first; -  		LLModelInstance& instance = *(iter->second.begin()); +		LLModel* model = instance.mModel; +		if (mesh_index.find(model) == mesh_index.end()) +		{ +			// Have not seen this model before - create a new mesh_list entry for it. +			std::string model_name = data.mBaseModel->getName(); +			if (!model_name.empty()) +			{ +				result["name"] = model_name; +			} +			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); + +			data.mAssetData = ostr.str(); +			std::string str = ostr.str(); + +			res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());  +			mesh_index[model] = mesh_num; +			mesh_num++; +		} +		 +		LLSD instance_entry; +		  		for (S32 i = 0; i < 5; i++)  		{  			data.mModel[i] = instance.mLOD[i];  		} - -		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); - -		data.mAssetData = ostr.str(); - -		LLSD mesh_entry; - +		  		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()); +		 +		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 0 -		mesh_entry["childpos"] = ll_sd_from_vector3(pos); -		mesh_entry["childrot"] = ll_sd_from_quaternion(rot); -		mesh_entry["scale"] = ll_sd_from_vector3(scale); -#endif -		mesh_entry["position"] = ll_sd_from_vector3(LLVector3()); -		mesh_entry["rotation"] = ll_sd_from_quaternion(rot); -		mesh_entry["scale"] = ll_sd_from_vector3(scale); - -		// TODO should be binary. -		std::string str = ostr.str(); -		mesh_entry["mesh_data"] = LLSD::Binary(str.begin(),str.end());  - -		res["mesh_list"][mesh_num] = mesh_entry; - -		// TODO how do textures in the list map to textures in the meshes?  		if (mUploadTextures)  		{ -			for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin(); -				material_iter != instance.mMaterial.end(); ++material_iter) -			{ +			instance_entry["face_list"] = LLSD::emptyArray(); -				if (textures.find(material_iter->mDiffuseMap.get()) == textures.end()) +			for (S32 face_num = 0; face_num < model->getNumVolumeFaces(); face_num++) +			{ +				LLImportMaterial& material = instance.mMaterial[face_num]; +				LLSD face_entry = LLSD::emptyMap(); +				LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); +				 +				if (texture != NULL)  				{ -					textures.insert(material_iter->mDiffuseMap.get()); +					if (textures.find(texture) == textures.end()) +					{ +						textures.insert(texture); +					}  					std::stringstream ostr;  					if (include_textures) // otherwise data is blank.  					{ -						LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel); +						LLTextureUploadData data(texture, material.mDiffuseMapLabel);  						if (!data.mTexture->isRawImageValid())  						{  							data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); @@ -1497,21 +1535,38 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  							LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage());  						ostr.write((const char*) upload_file->getData(), upload_file->getDataSize());  					} -					LLSD texture_entry; -					texture_entry["texture_data"] = ostr.str(); -					res["texture_list"][texture_num] = texture_entry; -					texture_num++; + +					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++; +					}  				} + +				// 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;  			}  		} -		mesh_num++; +		res["instance_list"][instance_num] = instance_entry; +		instance_num++;  	}  	result["asset_resources"] = res; -#if 1	  	dumpLLSDToFile(result,"whole_model.xml"); -#endif  	dest = result;  } @@ -1563,9 +1618,9 @@ void LLMeshUploadThread::doWholeModelUpload()  		apr_sleep(100);  	} -	bool do_include_textures = false; // not needed for initial cost/validation check.  	LLSD model_data; -	wholeModelToLLSD(model_data, do_include_textures); +	wholeModelToLLSD(model_data,false); +	dumpLLSDToFile(model_data,"whole_model_fee_request.xml");  	mPendingUploads++;  	LLCurlRequest::headers_t headers; @@ -1577,12 +1632,24 @@ void LLMeshUploadThread::doWholeModelUpload()  		mCurlRequest->process();  	} while (mCurlRequest->getQueued() > 0); -	mCurlRequest->post(mWholeModelUploadURL, headers, model_data["asset_resources"], new LLWholeModelUploadResponder(this)); -	 -	do + +	if (mWholeModelUploadURL.empty())  	{ -		mCurlRequest->process(); -	} while (mCurlRequest->getQueued() > 0); +		llinfos << "unable to upload, fee request failed" << llendl; +	} +	else +	{ +		LLSD full_model_data; +		wholeModelToLLSD(full_model_data, true); +		LLSD body = full_model_data["asset_resources"]; +		dumpLLSDToFile(body,"whole_model_body.xml"); +		mCurlRequest->post(mWholeModelUploadURL, headers, body, +						   new LLWholeModelUploadResponder(this, model_data)); +		do +		{ +			mCurlRequest->process(); +		} while (mCurlRequest->getQueued() > 0); +	}  	delete mCurlRequest;  	mCurlRequest = NULL; @@ -3243,6 +3310,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");  	mInventoryQ.push(data);  } @@ -3751,6 +3820,25 @@ void LLPhysicsDecomp::run()  	mDone = true;  } +void LLPhysicsDecomp::Request::updateTriangleAreaThreshold()  +{ +	F32 range = mBBox[1].mV[0] - mBBox[0].mV[0] ; +	range = llmin(range, mBBox[1].mV[1] - mBBox[0].mV[1]) ; +	range = llmin(range, mBBox[1].mV[2] - mBBox[0].mV[2]) ; + +	mTriangleAreaThreshold = llmin(0.0002f, range * 0.000002f) ; +} + +//check if the triangle area is large enough to qualify for a valid triangle +bool LLPhysicsDecomp::Request::isValidTriangle(U16 idx1, U16 idx2, U16 idx3)  +{ +	LLVector3 a = mPositions[idx2] - mPositions[idx1] ; +	LLVector3 b = mPositions[idx3] - mPositions[idx1] ; +	F32 c = a * b ; + +	return ((a*a) * (b*b) - c * c) > mTriangleAreaThreshold ; +} +  void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)  {  	mStatusMessage = msg; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f859e29c07..0a6954bade 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -152,7 +152,7 @@ public:  		std::string mStatusMessage;  		std::vector<LLModel::PhysicsMesh> mHullMesh;  		LLModel::convex_hull_decomposition mHull; -		 +			  		//status message callback, called from decomposition thread  		virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0; @@ -160,6 +160,14 @@ public:  		virtual void completed() = 0;  		virtual void setStatusMessage(const std::string& msg); + +	protected: +		//internal use +		LLVector3 mBBox[2] ; +		F32 mTriangleAreaThreshold ; + +		void updateTriangleAreaThreshold() ; +		bool isValidTriangle(U16 idx1, U16 idx2, U16 idx3) ;  	};  	LLCondition* mSignal; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f5fee662e6..e7878d8adf 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -102,6 +102,7 @@  #include "lltrans.h"  #include "llsdutil.h"  #include "llmediaentry.h" +#include "llaccountingquota.h"  //#define DEBUG_UPDATE_TYPE @@ -5702,3 +5703,10 @@ public:  LLHTTPRegistration<ObjectPhysicsProperties>  	gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties"); + + +void LLViewerObject::updateQuota( const SelectionQuota& quota ) +{ +	//update quotas +	mSelectionQuota = quota; +} diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 21198f7dd1..a0ad52df6b 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -43,6 +43,7 @@  #include "v3dmath.h"  #include "v3math.h"  #include "llvertexbuffer.h" +#include "llaccountingquota.h"  class LLAgent;			// TODO: Get rid of this.  class LLAudioSource; @@ -643,7 +644,11 @@ protected:  	void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id);  	void deleteParticleSource();  	void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); - +	 +public: +	void  updateQuota(  const SelectionQuota& quota ); +	const SelectionQuota& getQuota( void ) { return mSelectionQuota; } +	  private:  	void setNameValueList(const std::string& list);		// clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string  	void deleteTEImages(); // correctly deletes list of images @@ -705,6 +710,8 @@ protected:  	F32 mPhysicsCost;  	F32 mLinksetPhysicsCost; +	SelectionQuota mSelectionQuota; +	  	bool mCostStale;  	mutable bool mPhysicsShapeUnknown; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index ab2e07e4df..007b3416f1 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1418,6 +1418,15 @@ void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id)  	mPendingObjectCost.erase(object_id);  } +void LLViewerObjectList::updateQuotaCost( const LLUUID& objectId, const SelectionQuota& quota  ) +{ +	LLViewerObject* pVO = findObject( objectId ); +	if ( pVO ) +	{ +		//pVO->updateQuota( quota ); +	} +} +  void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object)  {  	mStalePhysicsFlags.insert(object->getID()); diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 65374bca70..8e211eaf73 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -36,6 +36,7 @@  // project includes  #include "llviewerobject.h" +#include "llaccountingquota.h"  class LLCamera;  class LLNetMap; @@ -101,6 +102,8 @@ public:  									F32 restitution,  									F32 gravity_multiplier); +	void updateQuotaCost( const LLUUID& objectId, const SelectionQuota& costs ); +	  	void shiftObjects(const LLVector3 &offset);  	bool hasMapObjectInRegion(LLViewerRegion* regionp) ; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index f835351c04..fb608b3a4f 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1508,6 +1508,7 @@ 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");  	capabilityNames.append("ObjectAdd"); @@ -1545,6 +1546,10 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); +	//prep# Finalize these!!!!!!!!! +	capabilityNames.append("AccountingParcel"); +	capabilityNames.append("AccountingSelection"); +	  	// Please add new capabilities alphabetically to reduce  	// merge conflicts. @@ -1658,3 +1663,4 @@ std::string LLViewerRegion::getDescription() const  {      return stringize(*this);  } + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 9c5b85b77f..a6e5c47b86 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -275,6 +275,7 @@ public:  	F32 getLandHeightRegion(const LLVector3& region_pos);  	void getInfo(LLSD& info); +	  	typedef enum  	{ diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ec2b5a4c98..dc355362ce 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4968,19 +4968,6 @@ void LLVOAvatar::resetSpecificJointPosition( const std::string& name )  //-----------------------------------------------------------------------------  void LLVOAvatar::resetJointPositionsToDefault( void )  { -	const LLVector3& avPos = getCharacterPosition(); -	 -	//Reposition the pelvis -	LLJoint* pPelvis = mRoot.findJoint("mPelvis"); -	if ( pPelvis ) -	{ -		pPelvis->setPosition( avPos + pPelvis->getPosition() ); -	} -	else  -	{ -		llwarns<<"Can't get pelvis joint."<<llendl;	 -		return; -	}  	//Subsequent joints are relative to pelvis  	for( S32 i = 0; i < (S32)mNumJoints; ++i ) @@ -4991,7 +4978,7 @@ void LLVOAvatar::resetJointPositionsToDefault( void )  			pJoint->setId( LLUUID::null );  			//restore joints to default positions, however skip over the pelvis -			if ( pJoint && pPelvis != pJoint ) +			if ( pJoint )  			{  				pJoint->restoreOldXform();  			} @@ -6028,6 +6015,14 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )  					if ( bindCnt > 0 )  					{  						LLVOAvatar::resetJointPositionsToDefault(); +						//Need to handle the repositioning of the cam, updating rig data etc during outfit editing  +						//This handles the case where we detach a replacement rig. +						if ( gAgentCamera.cameraCustomizeAvatar() ) +						{ +							gAgent.unpauseAnimation(); +							//Still want to refocus on head bone +							gAgentCamera.changeCameraToCustomizeAvatar(); +						}  					}  				}  			}				 | 
