diff options
| author | Dave Parks <davep@lindenlab.com> | 2010-12-10 20:42:29 -0600 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2010-12-10 20:42:29 -0600 | 
| commit | 6f8ff871cdd0402d07800444f0524079fe02fac6 (patch) | |
| tree | 071fc033d8b721934650e79584cd415d3da501bb /indra | |
| parent | 285ba513368c6b692ea2eb5d13b85300c76adbea (diff) | |
| parent | 8e5f15a3b64e1e7cd14c8c4c9535299b93f3496b (diff) | |
merge
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llvertexbuffer.h | 2 | ||||
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 33 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl | 80 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 791 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.h | 42 | ||||
| -rw-r--r-- | indra/newview/llmeshreduction.cpp | 15 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 63 | ||||
| -rw-r--r-- | indra/newview/skins/default/textures/textures.xml | 4 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_model_preview.xml | 260 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml | 79 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_viewer.xml | 12 | 
11 files changed, 925 insertions, 456 deletions
| diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 953b7e6757..f40f013306 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -198,7 +198,7 @@ public:  	U8* getIndicesPointer() const			{ return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }  	U8* getVerticesPointer() const			{ return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }  	U32 getTypeMask() const					{ return mTypeMask; } -	BOOL hasDataType(S32 type) const		{ return ((1 << type) & getTypeMask()) ? TRUE : FALSE; } +	bool hasDataType(S32 type) const		{ return ((1 << type) & getTypeMask()); }  	S32 getSize() const;  	S32 getIndicesSize() const				{ return mNumIndices * sizeof(U16); }  	U8* getMappedData() const				{ return mMappedData; } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index a27492f1c0..0be94ce2d1 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1353,7 +1353,7 @@      <key>Type</key>      <string>F32</string>      <key>Value</key> -    <real>11.0</real> +    <real>9.0</real>    </map>    <key>CameraFocalLength</key> @@ -1365,21 +1365,32 @@      <key>Type</key>      <string>F32</string>      <key>Value</key> -    <real>35</real> +    <real>50</real>    </map> -  <key>CameraCoCRatio</key> +  <key>CameraFieldOfView</key>    <map>      <key>Comment</key> -    <string>Ratio of circle of confusion to vertical resolution for DoF effect.</string> +    <string>Vertical camera field of view for DoF effect (in degrees)</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key>      <string>F32</string>      <key>Value</key> -    <real>54</real> +    <real>60.0</real>    </map> +  <key>CameraAspectRatio</key> +  <map> +    <key>Comment</key> +    <string>Camera aspect ratio for DoF effect</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>1.5</real> +  </map>    <key>CertStore</key>      <map> @@ -6622,9 +6633,9 @@      <string>Vector3</string>      <key>Value</key>      <array> -      <real>-0.35</real> +      <real>-0.75</real>        <real>1</real> -      <real>0.7</real> +      <real>1.0</real>      </array>    </map> @@ -6638,9 +6649,9 @@      <string>Vector3</string>      <key>Value</key>      <array> -      <real>-1</real> -      <real>-1</real> +      <real>0.5</real>        <real>-0.6</real> +      <real>0.4</real>      </array>    </map> @@ -6654,9 +6665,9 @@      <string>Vector3</string>      <key>Value</key>      <array> -      <real>-0.2</real> +      <real>0.5</real>        <real>-0.8</real> -      <real>-0.2</real> +      <real>0.3</real>      </array>    </map> diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 02712e0a5b..7c89c01ea4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -17,8 +17,10 @@ uniform sampler2D bloomMap;  uniform float depth_cutoff;  uniform float norm_cutoff; -uniform float near_focal_distance; -uniform float far_focal_distance; +uniform float focal_distance; +uniform float blur_constant; +uniform float tan_pixel_angle; +uniform float magnification;  uniform mat4 inv_proj;  uniform vec2 screen_res; @@ -39,11 +41,22 @@ void dofSample(inout vec4 diff, inout float w, float fd, float x, float y)  	vec2 tc = vary_fragcoord.xy+vec2(x,y);  	float d = getDepth(tc); -	if (d < fd) +	float wg = 1.0; +	//if (d < fd) +	//{ +	//	diff += texture2DRect(diffuseRect, tc); +	//	w = 1.0; +	//} +	if (d > fd)  	{ -		diff += texture2DRect(diffuseRect, tc); -		w += 1.0; +		wg = max(d/fd, 0.1);  	} +	 +	diff += texture2DRect(diffuseRect, tc+vec2(0.5,0.5))*wg*0.25; +	diff += texture2DRect(diffuseRect, tc+vec2(-0.5,0.5))*wg*0.25; +	diff += texture2DRect(diffuseRect, tc+vec2(0.5,-0.5))*wg*0.25; +	diff += texture2DRect(diffuseRect, tc+vec2(-0.5,-0.5))*wg*0.25; +	w += wg;  }  void dofSampleNear(inout vec4 diff, inout float w, float x, float y) @@ -64,22 +77,30 @@ void main()  	float sc = 0.75; -	float depth[5]; -	depth[0] = getDepth(tc); +	float depth; +	depth = getDepth(tc);  	vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); -	if (depth[0] < far_focal_distance)  	{ //pixel is behind far focal plane  		float w = 1.0; -		float fd = (depth[0]-far_focal_distance)*0.5+far_focal_distance; -		float sc = far_focal_distance - depth[0]; -		sc /= near_focal_distance-far_focal_distance; +		sc = (abs(depth-focal_distance)/-depth)*blur_constant; +		 +		sc /= magnification; +		 +		// tan_pixel_angle = pixel_length/-depth; +		float pixel_length =  tan_pixel_angle*-focal_distance; +		 +		sc = sc/pixel_length; +		 +		//diff.r = sc; -		sc = sqrt(sc); +		sc = min(abs(sc), 8.0); -		sc = min(sc, 8.0); +		//sc = 4.0; +		 +		float fd = depth*0.5f;  		while (sc > 1.0)  		{ @@ -96,41 +117,10 @@ void main()  			dofSample(diff,w, fd, sc2,0);  			sc -= 0.5;  		} +		  		diff /= w;  	} -	else -	{ -		float fd = near_focal_distance; -		if (depth[0] > fd) -		{ //pixel is in front of near focal plane -			//diff.r = 1.0; -			float w = 1.0; -			float sc = near_focal_distance-depth[0]; -			sc /= near_focal_distance; -			sc *= 8.0; -			sc = min(sc, 8.0); -						 -			fd = depth[0]; -			while (sc > 1.0) -			{ -				dofSampleNear(diff,w, sc,sc); -				dofSampleNear(diff,w, -sc,sc); -				dofSampleNear(diff,w, sc,-sc); -				dofSampleNear(diff,w, -sc,-sc); -				 -				sc -= 0.5; -				float sc2 = sc*1.414; -				dofSampleNear(diff,w, 0,sc2); -				dofSampleNear(diff,w, 0,-sc2); -				dofSampleNear(diff,w, -sc2,0); -				dofSampleNear(diff,w, sc2,0); -				sc -= 0.5; -			} -			diff /= w; -		}	 -	} -	  	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);  	gl_FragColor = diff + bloom; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 9aa8e62885..54277b8557 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -67,7 +67,9 @@  #include "lleconomy.h"  #include "llfocusmgr.h"  #include "llfloaterperms.h" +#include "lliconctrl.h"  #include "llmatrix4a.h" +#include "llmenubutton.h"  #include "llmeshrepository.h"  #include "llsdutil_math.h"  #include "lltextbox.h" @@ -80,17 +82,21 @@  #include "llvoavatarself.h"  #include "pipeline.h"  #include "lluictrlfactory.h" +#include "llviewermenu.h"  #include "llviewermenufile.h"  #include "llviewerregion.h" +#include "llviewertexturelist.h"  #include "llstring.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llsliderctrl.h"  #include "llspinctrl.h" +#include "lltoggleablemenu.h"  #include "llvfile.h"  #include "llvfs.h" +  #include "glod/glod.h"  //static @@ -133,7 +139,7 @@ std::string lod_vertices_name[NUM_LOD+1] =  	"high_vertices",  	"I went off the end of the lod_vertices_name array.  Me so smart."  }; -	 +  std::string lod_status_name[NUM_LOD+1] =  {  	"lowest_status", @@ -143,6 +149,23 @@ std::string lod_status_name[NUM_LOD+1] =  	"I went off the end of the lod_status_name array.  Me so smart."  }; +std::string lod_icon_name[NUM_LOD+1] =  +{ +	"status_icon_lowest", +	"status_icon_low", +	"status_icon_medium", +	"status_icon_high", +	"I went off the end of the lod_status_name array.  Me so smart." +}; + +std::string lod_status_image[NUM_LOD+1] =  +{ +	"ModelImport_Status_Good", +	"ModelImport_Status_Warning", +	"ModelImport_Status_Error", +	"I went off the end of the lod_status_image array.  Me so smart." +}; +  std::string lod_label_name[NUM_LOD+1] =  {  	"lowest_label", @@ -153,7 +176,6 @@ std::string lod_label_name[NUM_LOD+1] =  }; -  bool validate_face(const LLVolumeFace& face)  {  	for (U32 i = 0; i < face.mNumIndices; ++i) @@ -248,21 +270,28 @@ BOOL LLFloaterModelPreview::postBuild()  		return FALSE;  	} +	setViewOption("show_textures", true); +	  	childSetAction("lod_browse", onBrowseLOD, this); -	childSetCommitCallback("lod_triangle_limit", onTriangleLimitCommit, this);  	childSetCommitCallback("crease_angle", onGenerateNormalsCommit, this);  	childSetCommitCallback("generate_normals", onGenerateNormalsCommit, this); -	childSetCommitCallback("show edges", onShowEdgesCommit, this);  	childSetCommitCallback("lod_generate", onAutoFillCommit, this); + +	childSetCommitCallback("lod_mode", onLODParamCommit, this); +	childSetCommitCallback("lod_error_threshold", onLODParamCommit, this); +	childSetCommitCallback("lod_triangle_limit", onLODParamCommit, this); +	childSetCommitCallback("build_operator", onLODParamCommit, this); +	childSetCommitCallback("queue_mode", onLODParamCommit, this); +	childSetCommitCallback("border_mode", onLODParamCommit, this); +	childSetCommitCallback("share_tolerance", onLODParamCommit, this);  	childSetTextArg("status", "[STATUS]", getString("status_idle"));  	//childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount));  	childSetAction("ok_btn", onUpload, this); -	childSetAction("consolidate", onConsolidate, this);  	childSetAction("clear_materials", onClearMaterials, this);  	childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this); @@ -279,6 +308,17 @@ BOOL LLFloaterModelPreview::postBuild()  	childDisable("upload_joints");  	childDisable("ok_btn");  +	mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn"); + +	mCommitCallbackRegistrar.add("ModelImport.ViewOption.Action", boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _2)); +	mEnableCallbackRegistrar.add("ModelImport.ViewOption.Check", boost::bind(&LLFloaterModelPreview::isViewOptionChecked, this, _2)); +	mEnableCallbackRegistrar.add("ModelImport.ViewOption.Enabled", boost::bind(&LLFloaterModelPreview::isViewOptionEnabled, this, _2)); +	 +	 + +	mViewOptionMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_model_import_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +	mViewOptionMenuButton->setMenu(mViewOptionMenu, LLMenuButton::MP_BOTTOM_LEFT); +  	initDecompControls();  	LLView* preview_panel = getChild<LLView>("preview_panel"); @@ -339,21 +379,47 @@ LLFloaterModelPreview::~LLFloaterModelPreview()  	}  } -void LLFloaterModelPreview::loadModel(S32 lod) +void LLFloaterModelPreview::onViewOptionChecked(const LLSD& userdata)  { -	 mModelPreview->mLoading = true; -	 -	(new LLMeshFilePicker(mModelPreview, lod))->getFile(); +	mViewOption[userdata.asString()] = !mViewOption[userdata.asString()]; +	mModelPreview->refresh();  } -void LLFloaterModelPreview::setLimit(S32 lod, S32 limit) +bool LLFloaterModelPreview::isViewOptionChecked(const LLSD& userdata)  { -	if (limit != mModelPreview->mLimit[lod]) -	{ -		mModelPreview->mLimit[lod] = limit; -		mModelPreview->genLODs(lod); -		mModelPreview->setPreviewLOD(lod); -	} +	return mViewOption[userdata.asString()]; +} + +bool LLFloaterModelPreview::isViewOptionEnabled(const LLSD& userdata) +{ +	return !mViewOptionDisabled[userdata.asString()]; +} + +void LLFloaterModelPreview::setViewOptionEnabled(const std::string& option, bool enabled) +{ +	mViewOptionDisabled[option] = !enabled; +} + +void LLFloaterModelPreview::enableViewOption(const std::string& option) +{ +	setViewOptionEnabled(option, true); +} + +void LLFloaterModelPreview::disableViewOption(const std::string& option) +{ +	setViewOptionEnabled(option, false); +} + +void LLFloaterModelPreview::setViewOption(const std::string& option, bool value) +{ +	mViewOption[option] = value; +} + +void LLFloaterModelPreview::loadModel(S32 lod) +{ +	mModelPreview->mLoading = true; +	 +	(new LLMeshFilePicker(mModelPreview, lod))->getFile();  }  //static  @@ -419,30 +485,6 @@ void LLFloaterModelPreview::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata)  	fp->mModelPreview->setPreviewLOD(which_mode);  } -//static  -void LLFloaterModelPreview::setLimit(S32 lod, void* userdata) -{ -	LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata; -	 -	if (!fp->mModelPreview) -	{ -		return; -	} -	 -	S32 limit = fp->childGetValue("lod_triangle_limit").asInteger(); -	 -	 -	fp->setLimit(lod, limit); -} - -//static  -void LLFloaterModelPreview::onTriangleLimitCommit(LLUICtrl* ctrl, void* userdata) -{ -	LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; - -	LLFloaterModelPreview::setLimit(fp->mModelPreview->mPreviewLOD, userdata); -} -  //static  void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userdata)  { @@ -452,14 +494,6 @@ void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userda  }  //static -void LLFloaterModelPreview::onShowEdgesCommit(LLUICtrl* ctrl, void* userdata) -{ -	LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; -	 -	fp->mModelPreview->refresh(); -} - -//static  void LLFloaterModelPreview::onExplodeCommit(LLUICtrl* ctrl, void* userdata)  {  	LLFloaterModelPreview* fp = LLFloaterModelPreview::sInstance; @@ -475,6 +509,15 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)  	fp->mModelPreview->genLODs();  } +//static  +void LLFloaterModelPreview::onLODParamCommit(LLUICtrl* ctrl, void* userdata) +{ +	LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; +	fp->mModelPreview->genLODs(fp->mModelPreview->mPreviewLOD); +	fp->mModelPreview->updateStatusMessages(); +	fp->mModelPreview->refresh(); +} +  //-----------------------------------------------------------------------------  // draw() @@ -877,7 +920,6 @@ void LLFloaterModelPreview::initDecompControls()  	childSetCommitCallback("physics_layer", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance);  	childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this); -	childSetCommitCallback("show physics", LLFloaterModelPreview::refresh, this);  }  //----------------------------------------------------------------------------- @@ -1970,13 +2012,15 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)  	mTextureName = 0;  	mPreviewLOD = 0;  	mModelLoader = NULL; +	mMaxTriangleLimit = 0;  	mDirty = false; +	mGenLOD = false;  	mLoading = false; -	 -	for (U32 i = 0; i < LLModel::NUM_LODS; i++) -	{ -		mLimit[i] = 0; -	} +	mGroup = 0; +	mBuildShareTolerance = 0.f; +	mBuildQueueMode = GLOD_QUEUE_GREEDY; +	mBuildBorderMode = GLOD_BORDER_UNLOCK; +	mBuildOperator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE;  	mFMP = fmp; @@ -2216,22 +2260,9 @@ void LLModelPreview::loadModel(std::string filename, S32 lod)  	mLODFile[lod] = filename; -	if (lod == 3 && !mGroup.empty()) +	if (lod == LLModel::LOD_HIGH)  	{ -		for (std::map<LLPointer<LLModel>, U32>::iterator iter = mGroup.begin(); iter != mGroup.end(); ++iter) -		{ -			glodDeleteGroup(iter->second); -			stop_gloderror(); -		} -		 -		for (std::map<LLPointer<LLModel>, U32>::iterator iter = mObject.begin(); iter != mObject.end(); ++iter) -		{ -			glodDeleteObject(iter->second); -			stop_gloderror(); -		} -		 -		mGroup.clear(); -		mObject.clear(); +		clearGLODGroup();  	}  	mModelLoader = new LLModelLoader(filename, lod, this); @@ -2270,6 +2301,7 @@ void LLModelPreview::setPhysicsFromLOD(S32 lod)  		mVertexBuffer[LLModel::LOD_PHYSICS].clear();  		rebuildUploadData();  		refresh(); +		updateStatusMessages();  	}  } @@ -2288,6 +2320,7 @@ void LLModelPreview::clearIncompatible(S32 lod)  				if (i == LLModel::LOD_HIGH)  				{  					mBaseModel = mModel[lod]; +					clearGLODGroup();  					mBaseScene = mScene[lod];  					mVertexBuffer[5].clear();  				} @@ -2296,6 +2329,23 @@ void LLModelPreview::clearIncompatible(S32 lod)  	}  } +void LLModelPreview::clearGLODGroup() +{ +	if (mGroup) +	{ +		for (std::map<LLPointer<LLModel>, U32>::iterator iter = mObject.begin(); iter != mObject.end(); ++iter) +		{ +			glodDeleteObject(iter->second); +			stop_gloderror(); +		} +		mObject.clear(); + +		glodDeleteGroup(mGroup); +		stop_gloderror(); +		mGroup = 0; +	} +} +  void LLModelPreview::loadModelCallback(S32 lod)  { //NOT the main thread  	LLMutexLock lock(this); @@ -2318,16 +2368,22 @@ void LLModelPreview::loadModelCallback(S32 lod)  	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(); -		//mModel[lod] = NULL;  	}  	clearIncompatible(lod);  	mDirty = true; -	 +		  	if (lod == LLModel::LOD_HIGH)  	{  		resetPreviewTarget(); @@ -2547,6 +2603,7 @@ void LLModelPreview::consolidate()  	{  		mBaseScene = new_scene;  		mBaseModel = new_model; +		clearGLODGroup();  		mVertexBuffer[5].clear();  	} @@ -2589,6 +2646,7 @@ void LLModelPreview::clearMaterials()  	{  		mBaseScene = mScene[mPreviewLOD];  		mBaseModel = mModel[mPreviewLOD]; +		clearGLODGroup();  		mVertexBuffer[5].clear();  	} @@ -2630,11 +2688,6 @@ void LLModelPreview::genLODs(S32 which_lod)  	S32 limit = -1; -	if (which_lod != -1) -	{ -		limit = mLimit[which_lod]; -	} -	  	U32 triangle_count = 0;  	for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) @@ -2650,37 +2703,132 @@ void LLModelPreview::genLODs(S32 which_lod)  	U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; -	if (mGroup[mBaseModel[0]] == 0) -	{ //clear LOD maps -		mGroup.clear(); -		mObject.clear(); -		mPercentage.clear(); -		mPatch.clear(); +	U32 lod_mode = 0; +	 +	LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode"); +	if (iface) +	{ +		lod_mode = iface->getFirstSelectedIndex();  	} + +	F32 lod_error_threshold = mFMP->childGetValue("lod_error_threshold").asReal(); -	for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) -	{ //build GLOD objects for each model in base model list -		LLModel* mdl = *iter; -		if (mGroup[mdl] == 0) +	if (lod_mode == 0) +	{ +		lod_mode = GLOD_TRIANGLE_BUDGET; +		if (which_lod != -1)  		{ -			mGroup[mdl] = cur_name++; -			mObject[mdl] = cur_name++; -			 -			glodNewGroup(mGroup[mdl]); -			stop_gloderror(); -			 -			glodGroupParameteri(mGroup[mdl], GLOD_ADAPT_MODE, GLOD_TRIANGLE_BUDGET); -			stop_gloderror();		 -			 -			glodGroupParameteri(mGroup[mdl], GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR); -			stop_gloderror(); +			limit = mFMP->childGetValue("lod_triangle_limit").asInteger(); +		} +	} +	else +	{ +		lod_mode = GLOD_ERROR_THRESHOLD; +	} + +	U32 build_operator = 0; + +	iface = mFMP->childGetSelectionInterface("build_operator"); +	if (iface) +	{ +		build_operator = iface->getFirstSelectedIndex(); +	} + +	if (build_operator == 0) +	{ +		build_operator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE; +	} +	else +	{ +		build_operator = GLOD_OPERATOR_EDGE_COLLAPSE; +	} + +	U32 queue_mode; +	iface = mFMP->childGetSelectionInterface("queue_mode"); +	if (iface) +	{ +		queue_mode = iface->getFirstSelectedIndex(); +	} + +	if (queue_mode == 0) +	{ +		queue_mode = GLOD_QUEUE_GREEDY; +	} +	else if (queue_mode == 1) +	{ +		queue_mode = GLOD_QUEUE_LAZY; +	} +	else +	{ +		queue_mode = GLOD_QUEUE_INDEPENDENT; +	} + +	U32 border_mode = 0; + +	iface = mFMP->childGetSelectionInterface("border_mode"); +	if (iface) +	{ +		border_mode = iface->getFirstSelectedIndex(); +	} + +	if (border_mode == 0) +	{ +		border_mode = GLOD_BORDER_UNLOCK; +	} +	else +	{ +		border_mode = GLOD_BORDER_LOCK; +	} + +	bool object_dirty = false; +	if (border_mode != mBuildBorderMode) +	{ +		mBuildBorderMode = border_mode; +		object_dirty = true; +	} + +	if (queue_mode != mBuildQueueMode) +	{ +		mBuildQueueMode = queue_mode; +		object_dirty = true; +	} + +	if (build_operator != mBuildOperator) +	{ +		mBuildOperator = build_operator; +		object_dirty = true; +	} + +	F32 share_tolerance = mFMP->childGetValue("share_tolerance").asReal(); +	if (share_tolerance != mBuildShareTolerance) +	{ +		mBuildShareTolerance = share_tolerance; +		object_dirty = true; +	} + +	if (mGroup == 0) +	{ +		object_dirty = true; +		mGroup = cur_name++; +		glodNewGroup(mGroup); +	} + +	if (object_dirty) +	{ +		for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) +		{ //build GLOD objects for each model in base model list +			LLModel* mdl = *iter; -			glodGroupParameterf(mGroup[mdl], GLOD_OBJECT_SPACE_ERROR_THRESHOLD, 0.025f); -			stop_gloderror(); +			if (mObject[mdl] != 0) +			{ +				glodDeleteObject(mObject[mdl]); +			} + +			mObject[mdl] = cur_name++; -			glodNewObject(mObject[mdl], mGroup[mdl], GLOD_DISCRETE); +			glodNewObject(mObject[mdl], mGroup, GLOD_DISCRETE);  			stop_gloderror(); -			 +  			if (iter == mBaseModel.begin() && !mdl->mSkinWeights.empty())  			{ //regenerate vertex buffer for skinned models to prevent animation feedback during LOD generation  				mVertexBuffer[5].clear(); @@ -2703,38 +2851,22 @@ void LLModelPreview::genLODs(S32 which_lod)  				tri_count += num_indices/3;  				stop_gloderror();  			} -			 -			//store what percentage of total model (in terms of triangle count) this model makes up -			mPercentage[mdl] = (F32) tri_count / (F32) base_triangle_count; -			 -			//build glodobject + +			glodObjectParameteri(mObject[mdl], GLOD_BUILD_OPERATOR, build_operator); +			stop_gloderror(); + +			glodObjectParameteri(mObject[mdl], GLOD_BUILD_QUEUE_MODE, queue_mode); +			stop_gloderror(); + +			glodObjectParameteri(mObject[mdl], GLOD_BUILD_BORDER_MODE, border_mode); +			stop_gloderror(); + +			glodObjectParameterf(mObject[mdl], GLOD_BUILD_SHARE_TOLERANCE, share_tolerance); +			stop_gloderror(); +  			glodBuildObject(mObject[mdl]); -			if (stop_gloderror()) -			{ -				glodDeleteGroup(mGroup[mdl]); -				stop_gloderror(); -				glodDeleteObject(mObject[mdl]); -				stop_gloderror(); -				 -				mGroup[mdl] = 0; -				mObject[mdl] = 0; -				 -				if (which_lod == -1) -				{ -					mModel[LLModel::LOD_HIGH] = mBaseModel; -				} -				 -				return; -			} -			 +			stop_gloderror();  		} -		 -		//generating LODs for all entries, or this entry has a triangle budget -		glodGroupParameteri(mGroup[mdl], GLOD_ADAPT_MODE, GLOD_TRIANGLE_BUDGET); -		stop_gloderror();		 -		 -		glodGroupParameterf(mGroup[mdl], GLOD_OBJECT_SPACE_ERROR_THRESHOLD, 0.025f); -		stop_gloderror();  	} @@ -2746,9 +2878,8 @@ void LLModelPreview::genLODs(S32 which_lod)  		start = end = which_lod;  	} -	LLSpinCtrl* lim = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit", TRUE); -	lim->setMaxValue(base_triangle_count); -	 +	mMaxTriangleLimit = base_triangle_count; +  	for (S32 lod = start; lod >= end; --lod)  	{  		if (which_lod == -1) @@ -2771,23 +2902,25 @@ void LLModelPreview::genLODs(S32 which_lod)  		U32 actual_verts = 0;  		U32 submeshes = 0; +		glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode); +		stop_gloderror();		 +		 +		glodGroupParameteri(mGroup, GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR); +		stop_gloderror(); +		 +		glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, triangle_count); +		stop_gloderror(); +	 +		glodGroupParameterf(mGroup, GLOD_OBJECT_SPACE_ERROR_THRESHOLD, lod_error_threshold); +		stop_gloderror(); +				 +		glodAdaptGroup(mGroup); +		stop_gloderror(); +  		for (U32 mdl_idx = 0; mdl_idx < mBaseModel.size(); ++mdl_idx)  		{   			LLModel* base = mBaseModel[mdl_idx]; -			U32 target_count = U32(mPercentage[base]*triangle_count); -			 -			if (target_count < 4) -			{  -				target_count = 4; -			} -			 -			glodGroupParameteri(mGroup[base], GLOD_MAX_TRIANGLES, target_count); -			stop_gloderror(); -			 -			glodAdaptGroup(mGroup[base]); -			stop_gloderror(); -			  			GLint patch_count = 0;  			glodGetObjectParameteriv(mObject[base], GLOD_NUM_PATCHES, &patch_count);  			stop_gloderror(); @@ -2837,8 +2970,7 @@ void LLModelPreview::genLODs(S32 which_lod)  				buff->getNormalStrider(norm);  				buff->getTexCoord0Strider(tc);  				buff->getIndexStrider(index); -				 -				 +								  				target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices());  				actual_tris += buff->getNumIndices()/3;  				actual_verts += buff->getNumVerts(); @@ -2952,17 +3084,26 @@ void LLModelPreview::updateStatusMessages()  		}  	} +	if (mMaxTriangleLimit == 0) +	{ +		mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH]; +	} + +  	mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH])); -	std::string mesh_status_good = mFMP->getString("mesh_status_good"); -	std::string mesh_status_bad = mFMP->getString("mesh_status_bad");  	std::string mesh_status_na = mFMP->getString("mesh_status_na"); -	std::string mesh_status_none = mFMP->getString("mesh_status_none"); +		 +	S32 upload_status[LLModel::LOD_HIGH+1];  	bool upload_ok = true; -	 +  	for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)  	{ +		upload_status[lod] = 0; + +		std::string message = "mesh_status_good"; +  		if (total_tris[lod] > 0)  		{  			mFMP->childSetText(lod_triangles_name[lod], llformat("%d", total_tris[lod])); @@ -2970,26 +3111,40 @@ void LLModelPreview::updateStatusMessages()  		}  		else  		{ +			if (lod == LLModel::LOD_HIGH) +			{ +				upload_status[lod] = 2; +				message = "mesh_status_missing_lod"; +			} +			else +			{ +				for (S32 i = lod-1; i >= 0; --i) +				{ +					if (total_tris[i] > 0) +					{ +						upload_status[lod] = 2; +						message = "mesh_status_missing_lod"; +					} +				} +			} +  			mFMP->childSetText(lod_triangles_name[lod], mesh_status_na);  			mFMP->childSetText(lod_vertices_name[lod], mesh_status_na);  		} -		 -		std::string message = mesh_status_good; -		  		const U32 lod_high = LLModel::LOD_HIGH;  		if (lod != lod_high)  		{  			if (total_submeshes[lod] && total_submeshes[lod] != total_submeshes[lod_high])  			{ //number of submeshes is different -				message = mesh_status_bad; -				upload_ok = false; +				message = "mesh_status_submesh_mismatch"; +				upload_status[lod] = 2;  			}  			else if (!tris[lod].empty() && tris[lod].size() != tris[lod_high].size())  			{ //number of meshes is different -				message = mesh_status_bad; -				upload_ok = false; +				message = "mesh_status_mesh_mismatch"; +				upload_status[lod] = 2;  			}  			else if (!verts[lod].empty())  			{ @@ -2997,20 +3152,34 @@ void LLModelPreview::updateStatusMessages()  				{  					S32 max_verts = i < verts[lod+1].size() ? verts[lod+1][i] : 0; -					if (verts[lod][i] > max_verts) -					{ //too many vertices in this lod -						message = mesh_status_bad; -						upload_ok = false; +					if (max_verts > 0) +					{ +						if (verts[lod][i] > max_verts) +						{ //too many vertices in this lod +							message = "mesh_status_too_many_vertices"; +							upload_status[lod] = 2; +						}  					}  				}  			} -			else -			{ //no mesh -				message = mesh_status_none; -			}  		} -		mFMP->childSetText(lod_status_name[lod], message); +		LLIconCtrl* icon = mFMP->getChild<LLIconCtrl>(lod_icon_name[lod]); +		LLUIImagePtr img = LLUI::getUIImage(lod_status_image[upload_status[lod]]); +		icon->setVisible(true); +		icon->setImage(img); +		 +		if (upload_status[lod] >= 2) +		{ +			upload_ok = false; +		} + +		if (lod == mPreviewLOD) +		{ +			mFMP->childSetText("lod_status_message_text", mFMP->getString(message)); +			icon = mFMP->getChild<LLIconCtrl>("lod_status_message_icon"); +			icon->setImage(img); +		}  	}  	bool errorStateFromLoader = mModelLoader->getLoadState() == LLModelLoader::ERROR_PARSING ? true : false; @@ -3085,20 +3254,125 @@ void LLModelPreview::updateStatusMessages()  		mFMP->childSetTextArg("physics_points", "[POINTS]", mesh_status_na);  	} +	LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; +	if (fmp) +	{ +		if (phys_tris > 0 || phys_hulls > 0) +		{ +			if (!fmp->isViewOptionEnabled("show_physics")) +			{ +				fmp->enableViewOption("show_physics"); +				fmp->setViewOption("show_physics", true); +			} +		} +		else +		{ +			fmp->disableViewOption("show_physics"); +			fmp->setViewOption("show_physics", false); +		} +	} + +	const char* lod_controls[] =  +	{ +		"lod_mode", +		"lod_triangle_limit", +		"lod_error_tolerance", +		"build_operator_text", +		"queue_mode_text", +		"border_mode_text", +		"share_tolerance_text", +		"build_operator", +		"queue_mode", +		"border_mode", +		"share_tolerance" +	}; +	const U32 num_lod_controls = sizeof(lod_controls)/sizeof(char*); + +	const char* file_controls[] = +	{ +		"lod_browse", +		"lod_file" +	}; +	const U32 num_file_controls = sizeof(file_controls)/sizeof(char*); +  	//enable/disable controls based on radio groups  	if (mFMP->childGetValue("lod_from_file").asBoolean())  	{  -		mFMP->childDisable("lod_triangle_limit"); -		mFMP->childDisable("lod_generate"); -		mFMP->childEnable("lod_file"); -		mFMP->childEnable("lod_browse"); +		for (U32 i = 0; i < num_file_controls; ++i) +		{ +			mFMP->childEnable(file_controls[i]); +		} + +		for (U32 i = 0; i < num_lod_controls; ++i) +		{ +			mFMP->childDisable(lod_controls[i]); +		} + +		  	} -	else +	else if (mFMP->childGetValue("lod_auto_generate").asBoolean())  	{ -		mFMP->childEnable("lod_triangle_limit"); -		mFMP->childEnable("lod_generate"); -		mFMP->childDisable("lod_file"); -		mFMP->childDisable("lod_browse"); +		for (U32 i = 0; i < num_file_controls; ++i) +		{ +			mFMP->childDisable(file_controls[i]); +		} + +		for (U32 i = 0; i < num_lod_controls; ++i) +		{ +			mFMP->childEnable(lod_controls[i]); +		} + +		//if (threshold) +		{	 +			U32 lod_mode = 0; +			LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode"); +			if (iface) +			{ +				lod_mode = iface->getFirstSelectedIndex(); +			} + +			LLSpinCtrl* threshold = mFMP->getChild<LLSpinCtrl>("lod_error_threshold"); +			LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit"); + +			limit->setMaxValue(mMaxTriangleLimit); +			limit->setValue(total_tris[mPreviewLOD]); + +			if (lod_mode == 0) +			{ +				limit->setVisible(true); +				threshold->setVisible(false); + +				limit->setMaxValue(mMaxTriangleLimit); +			} +			else +			{ +				limit->setVisible(false); +				threshold->setVisible(true); +			} +		} +	} +	else +	{ // "None" is chosen +		for (U32 i = 0; i < num_file_controls; ++i) +		{ +			mFMP->childDisable(file_controls[i]); +		} + +		for (U32 i = 0; i < num_lod_controls; ++i) +		{ +			mFMP->childDisable(lod_controls[i]); +		} + +		if (!mModel[mPreviewLOD].empty()) +		{ +			mModel[mPreviewLOD].clear(); +			mScene[mPreviewLOD].clear(); +			mVertexBuffer[mPreviewLOD].clear(); + +			//this can cause phasing issues with the UI, so reenter this function and return +			updateStatusMessages(); +			return; +		}  	}  	if (mFMP->childGetValue("physics_load_from_file").asBoolean()) @@ -3132,7 +3406,7 @@ void LLModelPreview::clearBuffers()  	}  } -void LLModelPreview::genBuffers(S32 lod, bool avatar_preview) +void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  {  	U32 tri_count = 0;  	U32 vertex_count = 0; @@ -3183,7 +3457,7 @@ void LLModelPreview::genBuffers(S32 lod, bool avatar_preview)  			LLVertexBuffer* vb = NULL; -			bool skinned = avatar_preview && !mdl->mSkinWeights.empty(); +			bool skinned = include_skin_weights && !mdl->mSkinWeights.empty();  			U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; @@ -3265,7 +3539,17 @@ void LLModelPreview::update()  		mDirty = false;  		mResourceCost = calcResourceCost();  		refresh(); +		updateStatusMessages(); +	} + +	if (mGenLOD) +	{ +		mGenLOD = false; +		genLODs(); +		refresh(); +		updateStatusMessages();  	} +  }  //----------------------------------------------------------------------------- @@ -3276,6 +3560,22 @@ BOOL LLModelPreview::render()  	LLMutexLock lock(this);  	mNeedsUpdate = FALSE; +	bool edges = false; +	bool joint_positions = false; +	bool skin_weight = false; +	bool textures = false; +	bool physics = false; + +	LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; +	if (fmp) +	{ +		edges = fmp->isViewOptionChecked("show_edges"); +		joint_positions = fmp->isViewOptionChecked("show_joint_positions"); +		skin_weight = fmp->isViewOptionChecked("show_skin_weight"); +		textures = fmp->isViewOptionChecked("show_textures"); +		physics = fmp->isViewOptionChecked("show_physics"); +	} +  	S32 width = getWidth();  	S32 height = getHeight(); @@ -3307,7 +3607,7 @@ BOOL LLModelPreview::render()  		gGL.popMatrix();  	} -	bool avatar_preview = false; +	bool has_skin_weights = false;  	bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();  	bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean(); @@ -3319,45 +3619,45 @@ BOOL LLModelPreview::render()  			LLModel* model = instance.mModel;  			if (!model->mSkinWeights.empty())  			{ -				avatar_preview = true; +				has_skin_weights = true;  			}  		}  	} -	 -	if (upload_skin && !avatar_preview) + +	if (has_skin_weights) +	{ //model has skin weights, enable view options for skin weights and joint positions +		if (fmp) +		{ +			fmp->enableViewOption("show_skin_weight"); +			fmp->setViewOptionEnabled("show_joint_positions", skin_weight); +		} +		mFMP->childEnable("upload_skin"); +	} +	else  	{ +		mFMP->childDisable("upload_skin"); +		if (fmp) +		{ +			fmp->setViewOption("show_skin_weight", false); +			fmp->disableViewOption("show_skin_weight"); +			fmp->disableViewOption("show_joint_positions"); +		} +		skin_weight = false; +	} +	 +	if (upload_skin && !has_skin_weights) +	{ //can't upload skin weights if model has no skin weights  		mFMP->childSetValue("upload_skin", false);  		upload_skin = false;  	}  	if (!upload_skin && upload_joints) -	{ +	{ //can't upload joints if not uploading skin weights  		mFMP->childSetValue("upload_joints", false);  		upload_joints = false;  	} -	if (!avatar_preview) -	{ -		mFMP->childDisable("upload_skin"); -	} -	else -	{ -		mFMP->childEnable("upload_skin"); -	} -	 -	if (!upload_skin) -	{ -		mFMP->childDisable("upload_joints"); -	} -	else -	{ -		mFMP->childEnable("upload_joints"); -	} -	 -	avatar_preview = avatar_preview && upload_skin; -	 -	 -	mFMP->childSetEnabled("consolidate", !avatar_preview); +	mFMP->childSetEnabled("upload_joints", upload_skin);  	F32 explode = mFMP->childGetValue("physics_explode").asReal(); @@ -3376,7 +3676,7 @@ BOOL LLModelPreview::render()  	F32 z_near = 0.001f;  	F32 z_far = mCameraDistance+mPreviewScale.magVec()+mCameraOffset.magVec(); -	if (avatar_preview) +	if (skin_weight)  	{  		target_pos = gAgentAvatarp->getPositionAgent();  		z_near = 0.01f; @@ -3387,6 +3687,7 @@ BOOL LLModelPreview::render()  		refresh();  	} +	glLoadIdentity();  	gPipeline.enableLightsPreview();  	LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *  @@ -3411,22 +3712,32 @@ BOOL LLModelPreview::render()  	if (!mBaseModel.empty() && mVertexBuffer[5].empty())  	{ -		genBuffers(-1, avatar_preview); +		genBuffers(-1, skin_weight);  		//genBuffers(3);  		//genLODs();  	} -	bool physics = mFMP->childGetValue("show physics").asBoolean();  	S32 physics_idx = mFMP->childGetValue("physics_layer").asInteger();  	if (!mModel[mPreviewLOD].empty())  	{ -		if (mVertexBuffer[mPreviewLOD].empty()) +		bool regen = mVertexBuffer[mPreviewLOD].empty(); +		if (!regen) +		{ +			const std::vector<LLPointer<LLVertexBuffer> >& vb_vec = mVertexBuffer[mPreviewLOD].begin()->second; +			if (!vb_vec.empty()) +			{ +				const LLVertexBuffer* buff = vb_vec[0]; +				regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != skin_weight; +			} +		} + +		if (regen)  		{ -			genBuffers(mPreviewLOD, avatar_preview); +			genBuffers(mPreviewLOD, skin_weight);  		} -		if (!avatar_preview) +		if (!skin_weight)  		{  			for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)  			{ @@ -3450,21 +3761,28 @@ BOOL LLModelPreview::render()  					buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); -					glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); -					if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull()) +					if (textures)  					{ -						gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true); -						if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1) +						glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); +						if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull())  						{ -							mTextureSet.insert(instance.mMaterial[i].mDiffuseMap); +							gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true); +							if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1) +							{ +								mTextureSet.insert(instance.mMaterial[i].mDiffuseMap); +							}  						}  					} +					else +					{ +						glColor4f(1,1,1,1); +					}  					buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);  					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  					glColor3f(0.4f, 0.4f, 0.4f); -					if (mFMP->childGetValue("show edges").asBoolean()) +					if (edges)  					{  						glLineWidth(3.f);  						glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -3545,7 +3863,7 @@ BOOL LLModelPreview::render()  									glColor4ubv(hull_colors[i].mV);  									buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts()); -									if (mFMP->childGetValue("show edges").asBoolean()) +									if (edges)  									{  										glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);  										glLineWidth(3.f); @@ -3576,21 +3894,28 @@ BOOL LLModelPreview::render()  							buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); -							glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); -							if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull()) +							if (textures)  							{ -								gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true); -								if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1) +								glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); +								if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull())  								{ -									mTextureSet.insert(instance.mMaterial[i].mDiffuseMap); +									gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true); +									if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1) +									{ +										mTextureSet.insert(instance.mMaterial[i].mDiffuseMap); +									}  								}  							} +							else +							{ +								glColor4f(1,1,1,1); +							}  							buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);  							gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  							glColor3f(0.4f, 0.4f, 0.4f); -							if (mFMP->childGetValue("show edges").asBoolean() || model == physics_model) +							if (edges || model == physics_model)  							{  								if (model == physics_model)  								{ @@ -3622,7 +3947,10 @@ BOOL LLModelPreview::render()  															  LLVector3::z_axis,																	// up  															  target_pos);											// point of interest -			avatar->renderCollisionVolumes(); +			if (joint_positions) +			{ +				avatar->renderCollisionVolumes(); +			}  			for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)  			{ @@ -3707,7 +4035,7 @@ BOOL LLModelPreview::render()  							buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);  							glColor3f(0.4f, 0.4f, 0.4f); -							if (mFMP->childGetValue("show edges").asBoolean()) +							if (edges)  							{  								glLineWidth(3.f);  								glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -3788,6 +4116,7 @@ void LLModelPreview::setPreviewLOD(S32 lod)  		}  	}  	refresh(); +	updateStatusMessages();  }  //static  @@ -3810,12 +4139,6 @@ void LLFloaterModelPreview::onUpload(void* user_data)  	mp->closeFloater(false);  } -//static  -void LLFloaterModelPreview::onConsolidate(void* user_data) -{ -	LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data; -	mp->mModelPreview->consolidate(); -}  //static   void LLFloaterModelPreview::onClearMaterials(void* user_data) diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index a7d43a3d53..e233f3672a 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -49,6 +49,8 @@ class domProfile_COMMON;  class domInstance_geometry;  class domNode;  class domTranslate; +class LLMenuButton; +class LLToggleableMenu;  class LLModelLoader : public LLThread  { @@ -146,7 +148,6 @@ public:  	static void onUpload(void* data); -	static void onConsolidate(void* data);  	static void onClearMaterials(void* data);  	static void onModelDecompositionComplete(LLModel* model, std::vector<LLPointer<LLVertexBuffer> >& physics_mesh); @@ -156,6 +157,14 @@ public:  	void			loadModel(S32 lod); +	void onViewOptionChecked(const LLSD& userdata); +	bool isViewOptionChecked(const LLSD& userdata); +	bool isViewOptionEnabled(const LLSD& userdata); +	void setViewOptionEnabled(const std::string& option, bool enabled); +	void enableViewOption(const std::string& option); +	void disableViewOption(const std::string& option); +	void setViewOption(const std::string& option, bool value); +  protected:  	friend class LLModelPreview;  	friend class LLMeshFilePicker; @@ -167,12 +176,10 @@ protected:  	static void		onPreviewLODCommit(LLUICtrl*,void*); -	static void		onTriangleLimitCommit(LLUICtrl*,void*); -	  	static void		onGenerateNormalsCommit(LLUICtrl*,void*);  	static void		onAutoFillCommit(LLUICtrl*,void*); -	static void		onShowEdgesCommit(LLUICtrl*,void*); +	static void		onLODParamCommit(LLUICtrl*,void*);  	static void		onExplodeCommit(LLUICtrl*, void*); @@ -190,9 +197,6 @@ protected:  	void			draw(); -	static void		setLimit(S32 lod, void* userdata); -	void			setLimit(S32 lod, S32 limit); -	  	void initDecompControls();  	LLModelPreview*	mModelPreview; @@ -207,6 +211,13 @@ protected:  	LLPointer<DecompRequest> mCurRequest; +	std::map<std::string, bool> mViewOption; + +	//use "disabled" as false by default +	std::map<std::string, bool> mViewOptionDisabled; + +	LLMenuButton* mViewOptionMenuButton; +	LLToggleableMenu* mViewOptionMenu;  }; @@ -256,6 +267,8 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex  	void clearIncompatible(S32 lod);  	void updateStatusMessages();  	bool containsRiggedAsset( void ); +	void clearGLODGroup(); +  	static void	textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); @@ -269,6 +282,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex  	BOOL        mNeedsUpdate;  	bool		mDirty; +	bool		mGenLOD;  	U32         mTextureName;  	F32			mCameraDistance;  	F32			mCameraYaw; @@ -279,10 +293,16 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex  	LLVector3	mPreviewScale;  	S32			mPreviewLOD;  	U32			mResourceCost; -	S32			mLimit[LLModel::NUM_LODS];  	std::string mLODFile[LLModel::NUM_LODS];  	bool		mLoading; +	//GLOD object parameters (must rebuild object if these change) +	F32 mBuildShareTolerance; +	U32 mBuildQueueMode; +	U32 mBuildOperator; +	U32 mBuildBorderMode; +	 +  	LLModelLoader* mModelLoader; @@ -292,11 +312,9 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex  	LLModelLoader::model_list mModel[LLModel::NUM_LODS];  	LLModelLoader::model_list mBaseModel; -	std::map<LLPointer<LLModel>, U32> mGroup; +	U32 mGroup;  	std::map<LLPointer<LLModel>, U32> mObject; -	std::map<LLPointer<LLModel>, std::vector<U32> > mPatch; -	std::map<LLPointer<LLModel>, F32> mPercentage; - +	U32 mMaxTriangleLimit;  	std::map<LLPointer<LLModel>, std::vector<LLPointer<LLVertexBuffer> > > mPhysicsMesh;  	LLMeshUploadThread::instance_list mUploadData; diff --git a/indra/newview/llmeshreduction.cpp b/indra/newview/llmeshreduction.cpp index b50b4cf063..14e8dd37b4 100644 --- a/indra/newview/llmeshreduction.cpp +++ b/indra/newview/llmeshreduction.cpp @@ -32,19 +32,8 @@  #include "glod/glod.h" -static BOOL stop_gloderror() -{ -	GLuint error = glodGetError(); - -	if (error != GLOD_NO_ERROR) -	{ -		llwarns << "GLOD error detected: " << std::hex << error << llendl; -		return TRUE; -	} - -	return FALSE; -} +#if 0 //not used ?  void create_vertex_buffers_from_model(LLModel* model, std::vector<LLPointer <LLVertexBuffer> >& vertex_buffers)  { @@ -280,4 +269,4 @@ LLPointer<LLModel> LLMeshReduction::reduce(LLModel* in_model, F32 limit, S32 mod  	return out_model;  } - +#endif diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f0446b024c..64c24750b7 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6160,44 +6160,49 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		//convert to mm  		subject_distance *= 1000.f;  		F32 fnumber = gSavedSettings.getF32("CameraFNumber"); -		F32 focal_length = gSavedSettings.getF32("CameraFocalLength"); -		F32 coc_ratio = gSavedSettings.getF32("CameraCoCRatio"); - -		F32 coc = coc_ratio/mScreen.getHeight(); - -		F32 hyperfocal_distance = (focal_length*focal_length)/(fnumber*coc); - -		subject_distance = llmin(hyperfocal_distance, subject_distance); - -		//adjust focal length for subject distance -		focal_length = llmax(focal_length, 1.f/(1.f/focal_length - 1.f/subject_distance)); - -		//adjust focal length for zoom +		const F32 default_focal_length = gSavedSettings.getF32("CameraFocalLength"); +		  		F32 fov = LLViewerCamera::getInstance()->getView(); -		focal_length *= 1.f/fov; - -		F32 near_focal_distance = hyperfocal_distance*subject_distance/(hyperfocal_distance+subject_distance); -		//beyond far clip plane is effectively infinity -		F32 far_focal_distance = 4096.f; - -		if (subject_distance < hyperfocal_distance) -		{ -			far_focal_distance = hyperfocal_distance*subject_distance/(hyperfocal_distance-subject_distance); -			far_focal_distance /= 1000.f; -		} - -		near_focal_distance /= 1000.f; +		const F32 default_fov = gSavedSettings.getF32("CameraFieldOfView") * F_PI/180.f; +		const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio"); +		 +		F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); +		 +		F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); +		F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f); -		shader->uniform1f("far_focal_distance", -far_focal_distance); -		shader->uniform1f("near_focal_distance", -near_focal_distance); +		F32 focal_length = dv/(2*tanf(fov/2.f)); +		  +		F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); +	 +		// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) +		// where	 N = fnumber +		//			 s2 = dot distance +		//			 s1 = subject distance +		//			 f = focal length +		//	 + +		F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); +		blur_constant /= 1000.f; //convert to meters for shader +		F32 magnification = focal_length/(subject_distance-focal_length); + +		shader->uniform1f("focal_distance", -subject_distance/1000.f); +		shader->uniform1f("blur_constant", blur_constant); +		shader->uniform1f("tan_pixel_angle", tanf(1.f/LLDrawable::sCurPixelAngle)); +		shader->uniform1f("magnification", magnification);  		S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);  		if (channel > -1)  		{  			mScreen.bindTexture(0, channel); -			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);  		} +		//channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); +		//if (channel > -1) +		//{ +			//gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); +		//}  		gGL.begin(LLRender::TRIANGLE_STRIP);  		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index b8030bfa91..e522159181 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -256,6 +256,10 @@ with the same filename but different name    <texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" /> +  <texture name="ModelImport_Status_Good" file_name="lag_status_good.tga" preload="false"/> +  <texture name="ModelImport_Status_Warning" file_name="lag_status_warning.tga" preload="false"/> +  <texture name="ModelImport_Status_Error" file_name="lag_status_critical.tga" preload="false"/> +      <texture name="MouseLook_View_Off" file_name="bottomtray/MouseLook_view_off.png" preload="false" />    <texture name="MouseLook_View_On" file_name="bottomtray/MouseLook_view_on.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 779eeacb43..952deb26f9 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <floater can_close="true" can_drag_on_left="false" can_minimize="false" -     can_resize="true" height="520" min_height="520" min_width="630" -     name="Model Preview" title="Upload Model" width="630"> +     can_resize="true" height="550" min_height="550" min_width="620" +     name="Model Preview" title="Upload Model" width="620">    <string name="status_idle">Idle</string>    <string name="status_reading_file">Loading...</string> @@ -10,103 +10,89 @@    <string name="medium">Medium</string>    <string name="low">Low</string>    <string name="lowest">Lowest</string> -  <string name="mesh_status_good">Good</string> -  <string name="mesh_status_bad">Bad</string>" +  <string name="mesh_status_good">Ship it!</string>    <string name="mesh_status_na">N/A</string>    <string name="mesh_status_none">None</string> +  <string name="mesh_status_submesh_mismatch">Levels of detail have a different number of textureable faces.</string> +  <string name="mesh_status_mesh_mismatch">Levels of detail have a different number of mesh instances.</string> +  <string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string> +  <string name="mesh_status_missing_lod">Missing required level of detail.</string>    <string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->    <text left="15" bottom="25" follows="top|left" height="15" name="name_label">      Name:    </text> -  <line_editor bottom_delta="20" follows="top|left|right" height="19" max_length="254" -	     name="description_form" width="310" /> -  <text bottom_delta="24" follows="top|left" height="15" name="preview_label"> +  <line_editor bottom_delta="20" follows="top|left|right" height="19"  +	     name="description_form" width="290" /> +   +  <text bottom_delta="20" left="15" follows="left|top" height="15" name="lod_label">      Preview:    </text> +  <combo_box bottom_delta="20" follows="left|top" height="18" +	     name="preview_lod_combo" width="240" tool_tip="LOD to view in preview render"> +    <combo_item name="lowest"> +      Level of Detail: Lowest +    </combo_item> +    <combo_item name="low"> +      Level of Detail: Low +    </combo_item> +    <combo_item name="medium"> +      Level of Detail: Medium +    </combo_item> +    <combo_item name="high"> +      Level of Detail: High +    </combo_item> +  </combo_box> +    <menu_button follows="top|left"  +         image_hover_unselected="Toolbar_Left_Over" +         image_overlay="OptionsMenu_Off" +         image_selected="Toolbar_Left_Selected" +         image_unselected="Toolbar_Left_Off" +         layout="topleft" +         left_pad="5" +         name="options_gear_btn" +         width="31" +         height="25"/>    <!-- Placeholder panel for 3D preview render -->    <panel      name="preview_panel"      left="15" -    width="310" -    height="310" +    width="290" +    height="290"      follows="all"/> -  <text bottom_delta="25" left="15" width="100"  follows="bottom|left" height="15" name="streaming cost"> -    Prim Cost: [COST] -  </text> - -  <text right="320" width="100" height="15" bottom_delta="0" follows="bottom|right" name="status">[STATUS]</text> - -  <text bottom_delta="20" left="15" follows="left|bottom" height="15" name="lod_label"> -    Level of Detail: -  </text> -  <combo_box bottom_delta="20" follows="left|bottom" list_position="below" height="18" -	     name="preview_lod_combo" width="90" tool_tip="LOD to view in preview render"> -    <combo_item name="high"> -      High -    </combo_item> -    <combo_item name="medium"> -      Medium -    </combo_item> -    <combo_item name="lowest"> -      Lowest -    </combo_item> -    <combo_item name="low"> -      Low -    </combo_item> -  </combo_box> - -  <check_box bottom="450" left="125" follows="left|bottom" label="Show Edges" name="show edges" width="120" height="16" tool_tip="Render wireframe in preview window"/> -  <check_box bottom_delta="15" left="125" follows="left|bottom" label="Show Physics" name="show physics" width="120" height="16" tool_tip="Show physics shape."/> +  <text bottom_delta="25" left="25" width="100" follows="bottom|left">Upload Details</text> +  <panel top_pad="5" border="true" left="15" width="290" height="70" follows="bottom|left" +          bevel_style="in" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3"> +    <text left="25" follows="bottom|left" width="140" height="15" name="streaming cost"> +      Resource Cost: [COST] +    </text> +    <text left="25" top_pad="5" width="140" follows="bottom|left" height="15" name="physics cost"> +      Physics Cost: Unknown +    </text> +    <text left="25" top_pad="5" follows="bottom|left" height="15" name="upload fee"> +      Upload Fee: N/A +    </text> +  </panel> + +  <text left="10" bottom="540" width="290" height="15" follows="bottom|left|right" name="status">[STATUS]</text> -  <button bottom="510" follows="bottom|left" height="20" label="Upload" -	     left="15" width="80" name="ok_btn" tool_tip="Upload to simulator"/> -  <button left_pad="10" follows="left|bottom" height="20" width="80" label="Cancel" name="cancel_btn"/> +   +  <button bottom="540" left="430"  follows="bottom|right" height="20" label="Upload" +	     width="80" name="ok_btn" tool_tip="Upload to simulator"/> +  <button left_pad="10" follows="right|bottom" height="20" width="80" label="Cancel" name="cancel_btn"/>    <tab_container      follows="right|top|bottom"      top="15" -    left="330" -    height="475" -    width="280" +    left="310" +    height="470" +    width="300"      name="import_tab"      border="true"      tab_position="top"> -    <!-- MODIFIERS PANEL --> -    <panel -      border="true" -      label="Modifiers" -      name="modifiers_panel" -      left="330" -      width="280" -      height="450"> - -      <text left="10" width="90" bottom="30" follows="top|left" height="15"> -        Scale: -      </text> -      <text left_pad="5" width="140" follows="top|left" height="15"> -        Dimensions: -      </text> - -      <spinner left="10" height="20" follows="top|left" width="80" top_pad="5" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/> - -      <text left_pad="20" height="15" name="import_dimensions" follows="top|left"> -        [X] x [Y] x [Z] m -      </text> - -      <text left="10" top_pad="20" follows="top|left" height="15"> -        Include: -      </text> - -      <check_box top_pad="5" name="upload_textures" height="15" follows="top|left" label="Textures"/> -      <check_box top_pad="5" name="upload_skin" height="15" follows="top|left" label="Skin weight"/> -      <check_box top_pad="5" left="20" name="upload_joints" height="15" follows="top|left" label="Joint positions"/> -    </panel> - -      <!-- LOD PANEL -->      <panel        border="true" @@ -124,60 +110,110 @@        <text valign="center" halign="center" bg_visible="true" name="high_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="High"/>        <text valign="center" halign="center" bg_visible="true" name="high_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>        <text valign="center" halign="center" bg_visible="true" name="high_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/> -      <text valign="center" halign="center" bg_visible="true" name="high_status" left_pad="0" width="65" height="18" follows="left|top" value="Good"/> +      <text valign="center" halign="center" bg_visible="true" name="high_status" left_pad="0" width="65" height="18" follows="left|top" value=""/> +      <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_high" left_delta="20" top_delta="0" />        <text valign="center" halign="center" bg_visible="true" name="medium_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Medium"/>        <text valign="center" halign="center" bg_visible="true" name="medium_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>        <text valign="center" halign="center" bg_visible="true" name="medium_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/> -      <text valign="center" halign="center" bg_visible="true" name="medium_status" left_pad="0" width="65" height="18" follows="left|top" value="Good"/> +      <text valign="center" halign="center" bg_visible="true" name="medium_status" left_pad="0" width="65" height="18" follows="left|top" value=""/> +      <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_medium" left_delta="20" top_delta="0" />        <text valign="center" halign="center" bg_visible="true" name="low_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Low"/>        <text valign="center" halign="center" bg_visible="true" name="low_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>        <text valign="center" halign="center" bg_visible="true" name="low_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/> -      <text valign="center" halign="center" bg_visible="true" name="low_status" left_pad="0" width="65" height="18" follows="left|top" value="Good"/> +      <text valign="center" halign="center" bg_visible="true" name="low_status" left_pad="0" width="65" height="18" follows="left|top" value=""/> +      <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_low" left_delta="20" top_delta="0" />        <text valign="center" halign="center" bg_visible="true" name="lowest_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Lowest"/>        <text valign="center" halign="center" bg_visible="true" name="lowest_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>        <text valign="center" halign="center" bg_visible="true" name="lowest_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/> -      <text valign="center" halign="center" bg_visible="true" name="lowest_status" left_pad="0" width="65" height="18" follows="left|top" value="Good"/> - -      <text left="10" width="240" height="15" top_pad="15" follows="left|top" name="lod_tabel_footer"> +      <text valign="center" halign="center" bg_visible="true" name="lowest_status" left_pad="0" width="65" height="18" follows="left|top" value=""/> +      <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_lowest" left_delta="20" top_delta="0" /> +       +      <text left="10" width="240" height="15" top_pad="15" follows="left|top" name="lod_table_footer">          Level of Detail: [DETAIL]        </text> -      <text top_pad="10" height="15" follows="left|top"> +      <icon height="16" width="16" left="20" follows="left|top" name="lod_status_message_icon"/> +      <text left_pad="5" width="200" height="15" follows="left|top" name="lod_status_message_text"/> +         +      <text top_pad="10" left="10" height="15" follows="left|top">          Mesh        </text> -      <radio_group follows="top|left" height="100" left="30" name="lod_file_or_limit" width="240" value="lod_from_file"> -        <radio_item bottom="85" label="Load from file" name="lod_from_file"/> -        <radio_item bottom="40" label="Auto generate" name="lod_auuto_generate"/> +      <radio_group follows="top|left" height="210" left="30" name="lod_file_or_limit" width="240" value="lod_from_file"> +        <radio_item bottom="195" label="Load from file" name="lod_from_file"/> +        <radio_item bottom="150" label="Auto generate" name="lod_auto_generate"/> +        <radio_item bottom="0" label="None" name="lod_none"/>        </radio_group> -      <line_editor follows="left|top" bottom_delta="-60" width="140" left="45" value="" name="lod_file" height="20"/> +      <line_editor follows="left|top" bottom_delta="-170" width="140" left="45" value="" name="lod_file" height="20"/>        <button bottom_delta="3" name="lod_browse" label="Browse..." left_pad="5" follows="left|top" width="70" height="25"/> -      <text follows="top|left" top_pad="22" width="140" left="45" height="15"> -        Triangle Limit: +      <combo_box follows="top|left" name="lod_mode" top_pad="22" width="100" left="45" height="20"> +        <combo_item name="triangle_limit"> +          Triangle Limit +        </combo_item> +        <combo_item name="error_threshold"> +          Error Threshold +        </combo_item> +      </combo_box> +      <spinner follows="top|left" name="lod_triangle_limit" left_pad="5" height="20" width="100" decimal_digits="0" enabled="true"/> +      <spinner left_delta="0" bottom_delta="0"  follows="top|left" name="lod_error_threshold" min_val="0" max_val="100" height="20" width="100" decimal_digits="3" visible="false" enabled="true"/> + +      <text follows="top|left" name="build_operator_text" left="45" top_pad="10" width="100" height="15"> +        Build Operator:   +      </text> +      <text follows="top|left" name="queue_mode_text" left_pad="5" width="100" height="15"> +        Queue Mode: +      </text> +      <combo_box follows="top|left" name="build_operator" top_pad="5" left="45" width="100" height="20"> +        <combo_item name="half_edge_collapse"> +          Half Edge Collapse +        </combo_item> +        <combo_item name="edge_collapse"> +          Edge Collapse +        </combo_item> +      </combo_box> + +      <combo_box follows="top|left" name="queue_mode" left_pad="5" width="100" height="20"> +        <combo_item name="greedy"> +          Greedy +        </combo_item> +        <combo_item name="lazy"> +          Lazy +        </combo_item> +        <combo_item name="independent"> +          Independent +        </combo_item> +      </combo_box> + +      <text top_pad="10" name="border_mode_text" left="45" follows="left|top" width="100" height="15"> +        Border Mode:        </text> -      <spinner follows="top|left" name="lod_triangle_limit" top_pad="5" height="20" width="60" decimal_digits="0" enabled="true"/> - -      <button bottom_delta="3" left_pad="5" name="lod_generate" label="Generate" height="25" width="70" follows="left|top"/> -      <text name="submeshes_info" follows="left|top" left="10" top_pad="7" height="15 width=240"> -        Layers: [SUBMESHES] +      <text left_pad="5" name="share_tolderance_text"  follows="left|top" width="100" height="15"> +        Share Tolerance:        </text> -      <button left="30" follows="top|left" top_pad="5" name="clear_materials" label="Clear Materials" width="100" height="25"/> -      <button left="30" follows="top|left" top_pad="5" name="consolidate" label="Consolidate" width="100" height="25"/> -      <text left="10" top_pad="10" follows="top|left" width="240" height="15"> -        Normals +      <combo_box follows="left|top" left="45" height="20" name="border_mode" width="100"> +        <combo_item name="border_unlock"> +          Unlock +        </combo_item> +        <combo_item name="border_lock"> +          Lock +        </combo_item> +      </combo_box> +      <spinner follows="left|top" name="share_tolerance" left_pad="5" width="100" height="20"/> +              +      <text left="10" top_pad="35" follows="top|left" width="240" height="15"> +        Generate Normals        </text>        <text left="35" top_pad="5" follows="top|left" width="100" height="15">          Crease Angle:        </text> -      <spinner follows="top|left" top_pad="5" min_val="0" max_val="180" value="75" width="60" height="20" name="crease_angle"/> -      <button follows="top|left" bottom_delta="3" left_pad="5" width="140" height="25" label="Generate Normals" name="generate_normals"/> +      <spinner follows="top|left" left_pad="5" min_val="0" max_val="180" value="75" width="60" height="20" name="crease_angle"/>        </panel>      <!--  PANEL --> @@ -341,8 +377,32 @@        </panel>      </panel> -    -     +    <!-- MODIFIERS PANEL --> +    <panel +      border="true" +      label="Modifiers" +      name="modifiers_panel"> +      <text left="10" width="90" bottom="30" follows="top|left" height="15"> +        Scale: +      </text> +      <text left_pad="5" width="140" follows="top|left" height="15"> +        Dimensions: +      </text> + +      <spinner left="10" height="20" follows="top|left" width="80" top_pad="5" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/> + +      <text left_pad="20" height="15" name="import_dimensions" follows="top|left"> +        [X] x [Y] x [Z] m +      </text> + +      <text left="10" top_pad="20" follows="top|left" height="15"> +        Include: +      </text> + +      <check_box top_pad="5" name="upload_textures" height="15" follows="top|left" label="Textures"/> +      <check_box top_pad="5" name="upload_skin" height="15" follows="top|left" label="Skin weight"/> +      <check_box top_pad="5" left="20" name="upload_joints" height="15" follows="top|left" label="Joint positions"/> +    </panel>    </tab_container>    <!-- diff --git a/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml new file mode 100644 index 0000000000..2650903f88 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + bottom="806" + layout="topleft" + left="0" + mouse_opaque="false" + name="model_menu_gear_default" + visible="false"> +  <menu_item_check +   label="Show edges" +   layout="topleft" +   name="show_edges"> +    <on_click +       function="ModelImport.ViewOption.Action" +       parameter="show_edges" /> +    <on_check +       function="ModelImport.ViewOption.Check" +       parameter="show_edges" /> +    <on_enable +			 function="ModelImport.ViewOption.Enabled" +			 parameter="show_edges" /> +  </menu_item_check> +  <menu_item_check +   label="Show physics" +   layout="topleft" +   name="show_physics"> +    <on_click +       function="ModelImport.ViewOption.Action" +       parameter="show_physics" /> +    <on_check +       function="ModelImport.ViewOption.Check" +       parameter="show_physics" /> +    <on_enable +			 function="ModelImport.ViewOption.Enabled" +			 parameter="show_physics" /> +  </menu_item_check> +  <menu_item_check +  label="Show textures" +  layout="topleft" +  name="show_textures"> +    <on_click +       function="ModelImport.ViewOption.Action" +       parameter="show_textures" /> +    <on_check +       function="ModelImport.ViewOption.Check" +       parameter="show_textures" /> +    <on_enable +			 function="ModelImport.ViewOption.Enabled" +			 parameter="show_textures" /> +  </menu_item_check> +  <menu_item_check +  label="Show skin weight" +  layout="topleft" +  name="show_skin_weight"> +    <on_click +       function="ModelImport.ViewOption.Action" +       parameter="show_skin_weight" /> +    <on_check +       function="ModelImport.ViewOption.Check" +       parameter="show_skin_weight" /> +    <on_enable +			 function="ModelImport.ViewOption.Enabled" +			 parameter="show_skin_weight" /> +  </menu_item_check> +  <menu_item_check +  label="Show joint positions" +  layout="topleft" +  name="show_joint_positions"> +    <on_click +       function="ModelImport.ViewOption.Action" +       parameter="show_joint_positions" /> +    <on_check +       function="ModelImport.ViewOption.Check" +       parameter="show_joint_positions" /> +    <on_enable +			 function="ModelImport.ViewOption.Enabled" +			 parameter="show_joint_positions" /> +  </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 38833d14df..6c1e9a3082 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3153,17 +3153,7 @@              <menu_item_call.on_click               function="Advanced.LeaveAdminStatus" />          </menu_item_call> -		<menu_item_call -           label="HACK Upload Model..." -           layout="topleft" -           name="Upload Model"> -          <menu_item_call.on_click -             function="File.UploadModel" -             parameter="" /> -          <menu_item_call.on_enable -             function="File.EnableUploadModel" /> -        </menu_item_call> -        <menu_item_check +		    <menu_item_check           label="Show Admin Menu"           name="View Admin Options">              <menu_item_check.on_enable | 
