diff options
| -rw-r--r-- | indra/llmath/llvolume.cpp | 34 | ||||
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 11 | ||||
| -rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 226 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.h | 2 | ||||
| -rwxr-xr-x | indra/newview/llmeshrepository.cpp | 22 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 6 | 
6 files changed, 252 insertions, 49 deletions
| diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c4be176353..7a2f06da8f 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2162,7 +2162,7 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is)  	LLSD header;
  	{
 -		if (!LLSDSerialize::deserialize(header, is, 1024*1024*1024))
 +		if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024))
  		{
  			llwarns << "Mesh header parse error.  Not a valid mesh asset!" << llendl;
  			return FALSE;
 @@ -2174,34 +2174,18 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is)  		"lowest_lod",
  		"low_lod",
  		"medium_lod",
 -		"high_lod"
 +		"high_lod",
 +		"physics_shape",
  	};
 -	S32 lod = llclamp((S32) mDetail, 0, 3);
 +	const S32 MODEL_LODS = 5;
 -	while (lod < 4 && 
 -		(header[nm[lod]]["offset"].asInteger() == -1 || 
 -		header[nm[lod]]["size"].asInteger() == 0 ))
 -	{
 -		++lod;
 -	}
 -
 -	if (lod >= 4)
 -	{
 -		lod = llclamp((S32) mDetail, 0, 3);
 +	S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS);
 -		while (lod >= 0 && 
 -				(header[nm[lod]]["offset"].asInteger() == -1 ||
 -				header[nm[lod]]["size"].asInteger() == 0) )
 -		{
 -			--lod;
 -		}
 -
 -		if (lod < 0)
 -		{
 -			llwarns << "Mesh header missing LOD offsets.  Not a valid mesh asset!" << llendl;
 -			return FALSE;
 -		}
 +	if (header[nm[lod]]["offset"].asInteger() == -1 || 
 +		header[nm[lod]]["size"].asInteger() == 0 )
 +	{ //cannot load requested LOD
 +		return FALSE;
  	}
  	is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur);
 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e27397ab1a..c11de57c42 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5523,6 +5523,17 @@      <key>Value</key>      <real>1</real>    </map> +  <key>MeshImportUseSLM</key> +  <map> +    <key>Comment</key> +    <string>Use cached copy of last upload for a dae if available instead of loading dae file from scratch.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <real>0</real> +  </map>    <key>MigrateCacheDirectory</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 04dfcac20b..6145c6c16d 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -82,6 +82,7 @@  #include "llvoavatarself.h"  #include "pipeline.h"  #include "lluictrlfactory.h" +#include "llviewercontrol.h"  #include "llviewermenu.h"  #include "llviewermenufile.h"  #include "llviewerregion.h" @@ -1088,8 +1089,15 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev  	if (mPreview)  	{ +		//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();  		mPreview->setLoadState(STARTING);  	} +	else +	{ +		mTrySLM = false; +	}  }  void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform) @@ -1167,6 +1175,38 @@ void LLModelLoader::run()  bool LLModelLoader::doLoadModel()  { +	//first, look for a .slm file of the same name that was modified later +	//than the .dae + +	if (mTrySLM) +	{ +		std::string filename = mFilename; +			 +		std::string::size_type i = filename.rfind("."); +		if (i != std::string::npos) +		{ +			filename.replace(i, filename.size()-1, ".slm"); +			llstat slm_status; +			if (LLFile::stat(filename, &slm_status) == 0) +			{ //slm file exists +				llstat dae_status; +				if (LLFile::stat(mFilename, &dae_status) != 0 || +					dae_status.st_mtime < slm_status.st_mtime) +				{ +					if (loadFromSLM(filename)) +					{ //slm successfully loaded, if this fails, fall through and +						//try loading from dae + +						mLod = -1; //successfully loading from an slm implicitly sets all  +									//LoDs +						return true; +					} +				} +			}	 +		} +	} + +	//no suitable slm exists, load from the .dae file  	DAE dae;  	domCOLLADA* dom = dae.open(mFilename); @@ -1744,6 +1784,91 @@ void LLModelLoader::setLoadState(U32 state)  	}  } +bool LLModelLoader::loadFromSLM(const std::string& filename) +{  +	//only need to populate mScene with data from slm +	llstat stat; + +	if (LLFile::stat(filename, &stat)) +	{ //file does not exist +		return false; +	} + +	S32 file_size = (S32) stat.st_size; +	 +	llifstream ifstream(filename, std::ifstream::in | std::ifstream::binary); +	LLSD data; +	LLSDSerialize::fromBinary(data, ifstream, file_size); +	ifstream.close(); + +	//build model list for each LoD +	model_list model[LLModel::NUM_LODS]; + +	LLSD& mesh = data["mesh"]; + +	LLVolumeParams volume_params; +	volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + +	for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) +	{ +		for (U32 i = 0; i < mesh.size(); ++i) +		{ +			std::stringstream str(mesh[i].asString()); +			LLPointer<LLModel> loaded_model = new LLModel(volume_params, (F32) lod); +			if (loaded_model->createVolumeFacesFromStream(str)) +			{ +				loaded_model->mLocalID = i; +				model[lod].push_back(loaded_model); +			} +			else +			{ +				llassert(model[lod].empty()); +			} +		} +	}	 + +	if (model[LLModel::LOD_HIGH].empty()) +	{ //failed to load high lod +		return false; +	} + +	//load instance list +	model_instance_list instance_list; + +	LLSD& instance = data["instance"]; + +	for (U32 i = 0; i < instance.size(); ++i) +	{ +		//deserialize instance list +		instance_list.push_back(LLModelInstance(instance[i])); + +		//match up model instance pointers +		S32 idx = instance_list[i].mLocalMeshID; + +		for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod) +		{ +			if (!model[lod].empty()) +			{ +				instance_list[i].mLOD[lod] = model[lod][idx]; +			} +		} + +		instance_list[i].mModel = model[LLModel::LOD_HIGH][idx]; +	} + + +	//convert instance_list to mScene +	mFirstTransform = TRUE; +	for (U32 i = 0; i < instance_list.size(); ++i) +	{ +		LLModelInstance& cur_instance = instance_list[i]; +		mScene[cur_instance.mTransform].push_back(cur_instance); +		stretch_extents(cur_instance.mModel, cur_instance.mTransform, mExtents[0], mExtents[1], mFirstTransform); +	} + +	return true; +} +  void LLModelLoader::loadModelCallback()  {  	if (mPreview) @@ -2614,6 +2739,7 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw  				decomp,   				empty_hull, save_skinweights, save_joint_positions); +			  			data["mesh"][instance.mModel->mLocalID] = str.str();  		} @@ -2626,8 +2752,6 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw  	out.close();  } - -  void LLModelPreview::clearModel(S32 lod)  {  	if (lod < 0 || lod > LLModel::LOD_PHYSICS) @@ -2769,39 +2893,93 @@ void LLModelPreview::loadModelCallback(S32 lod)  	}  	mModelLoader->loadTextures() ; -	mModel[lod] = mModelLoader->mModelList; -	mScene[lod] = mModelLoader->mScene; -	mVertexBuffer[lod].clear(); -	if (lod == LLModel::LOD_PHYSICS) -	{ -		mPhysicsMesh.clear(); -	} +	if (lod == -1) +	{ //populate all LoDs from model loader scene +		mBaseModel.clear(); +		mBaseScene.clear(); -	setPreviewLOD(lod); +		for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) +		{ //for each LoD +			//clear scene and model info +			mScene[lod].clear(); +			mModel[lod].clear(); +			mVertexBuffer[lod].clear(); +			 +			if (mModelLoader->mScene.begin()->second[0].mLOD[lod].notNull()) +			{ //if this LoD exists in the loaded scene -	if (lod == LLModel::LOD_HIGH) -	{ //save a copy of the highest LOD for automatic LOD manipulation -		if (mBaseModel.empty()) -		{ //first time we've loaded a model, auto-gen LoD -			mGenLOD = true; +				//copy scene to current LoD +				mScene[lod] = mModelLoader->mScene; +			 +				//touch up copied scene to look like current LoD +				for (LLModelLoader::scene::iterator iter = mScene[lod].begin(); iter != mScene[lod].end(); ++iter) +				{ +					LLModelLoader::model_instance_list& list = iter->second; + +					for (LLModelLoader::model_instance_list::iterator list_iter = list.begin(); list_iter != list.end(); ++list_iter) +					{	 +						//override displayed model with current LoD +						list_iter->mModel = list_iter->mLOD[lod]; + +						//add current model to current LoD's model list (LLModel::mLocalID makes a good vector index) +						S32 idx = list_iter->mModel->mLocalID; + +						if (mModel[lod].size() <= idx) +						{ //stretch model list to fit model at given index +							mModel[lod].resize(idx+1); +						} + +						mModel[lod][idx] = list_iter->mModel;	 +					} +				} +			}  		} -		mBaseModel = mModel[lod]; -		clearGLODGroup(); +		//copy high lod to base scene for LoD generation +		mBaseScene = mScene[LLModel::LOD_HIGH]; +		mBaseModel = mModel[LLModel::LOD_HIGH]; -		mBaseScene = mScene[lod]; -		mVertexBuffer[5].clear(); +		mDirty = true; +		resetPreviewTarget();  	} +	else +	{ //only replace given LoD +		mModel[lod] = mModelLoader->mModelList; +		mScene[lod] = mModelLoader->mScene; +		mVertexBuffer[lod].clear(); -	clearIncompatible(lod); +		if (lod == LLModel::LOD_PHYSICS) +		{ +			mPhysicsMesh.clear(); +		} -	mDirty = true; +		setPreviewLOD(lod); -	if (lod == LLModel::LOD_HIGH) -	{ -		resetPreviewTarget(); + +		if (lod == LLModel::LOD_HIGH) +		{ //save a copy of the highest LOD for automatic LOD manipulation +			if (mBaseModel.empty()) +			{ //first time we've loaded a model, auto-gen LoD +				mGenLOD = true; +			} + +			mBaseModel = mModel[lod]; +			clearGLODGroup(); + +			mBaseScene = mScene[lod]; +			mVertexBuffer[5].clear(); +		} + +		clearIncompatible(lod); + +		mDirty = true; + +		if (lod == LLModel::LOD_HIGH) +		{ +			resetPreviewTarget(); +		}  	}  	mLoading = false; diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 5efac91ba3..68fa0fa4c1 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -76,6 +76,7 @@ public:  	LLMatrix4 mTransform;  	BOOL mFirstTransform;  	LLVector3 mExtents[2]; +	bool mTrySLM;  	std::map<daeElement*, LLPointer<LLModel> > mModel; @@ -97,6 +98,7 @@ public:  	virtual void run();  	bool doLoadModel(); +	bool loadFromSLM(const std::string& filename);  	void loadModelCallback();  	void loadTextures() ; //called in the main thread. diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 47dc343f5e..a227627bc1 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3584,6 +3584,19 @@ 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) +	{ +		mMaterial.push_back(LLImportMaterial(data["material"][i])); +	} +} + +  LLSD LLModelInstance::asLLSD()  {	  	LLSD ret; @@ -3600,6 +3613,15 @@ LLSD LLModelInstance::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(); +} + +  LLSD LLImportMaterial::asLLSD()  {  	LLSD ret; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 4d727bf1f2..f0c0f308d5 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -102,6 +102,8 @@ public:  		mDiffuseColor.set(1,1,1,1);  	} +	LLImportMaterial(LLSD& data); +  	LLSD asLLSD();  }; @@ -114,6 +116,7 @@ public:  	std::string mLabel;  	LLUUID mMeshID; +	S32 mLocalMeshID;  	LLMatrix4 mTransform;  	std::vector<LLImportMaterial> mMaterial; @@ -121,8 +124,11 @@ public:  	LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, std::vector<LLImportMaterial>& materials)  		: mModel(model), mLabel(label), mTransform(transform), mMaterial(materials)  	{ +		mLocalMeshID = -1;  	} +	LLModelInstance(LLSD& data); +  	LLSD asLLSD();  }; | 
