diff options
23 files changed, 748 insertions, 488 deletions
| diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index f473a708cd..618b056768 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6023,6 +6023,11 @@ void LLVolumeFace::cacheOptimize()  	LLVCacheLRU cache; +	if (mNumVertices < 3) +	{ //nothing to do +		return; +	} +  	//mapping of vertices to triangles and indices  	std::vector<LLVCacheVertexData> vertex_data; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index e3b68156ca..b3d5c7b072 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -149,9 +149,10 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr  	}  } -void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride, +bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,  					 domSource* &pos_source, domSource* &tc_source, domSource* &norm_source)  { +	  	idx_stride = 0;  	for (U32 j = 0; j < inputs.getCount(); ++j) @@ -163,7 +164,11 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S  			const domURIFragmentType& uri = inputs[j]->getSource();  			daeElementRef elem = uri.getElement();  			domVertices* vertices = (domVertices*) elem.cast(); - +			if ( !vertices ) +			{ +				return false; +			} +				  			domInputLocal_Array& v_inp = vertices->getInput_array(); @@ -207,6 +212,8 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S  	}  	idx_stride += 1; +	 +	return true;  }  LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domTrianglesRef& tri) @@ -227,8 +234,12 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  	S32 idx_stride = 0; -	get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source); +	if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source ) +	{ +		return LLModel::BAD_ELEMENT; +	} +	  	domPRef p = tri->getP();  	domListOfUInts& idx = p->getValue(); @@ -367,7 +378,10 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  	S32 idx_stride = 0; -	get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source); +	if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source)) +	{ +		return LLModel::BAD_ELEMENT; +	}  	LLVolumeFace face; @@ -564,7 +578,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  			const domURIFragmentType& uri = inputs[i]->getSource();  			daeElementRef elem = uri.getElement();  			domVertices* vertices = (domVertices*) elem.cast(); - +			if (!vertices) +			{ +				return LLModel::BAD_ELEMENT; +			}  			domInputLocal_Array& v_inp = vertices->getInput_array();  			for (U32 k = 0; k < v_inp.getCount(); ++k) @@ -574,6 +591,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  					const domURIFragmentType& uri = v_inp[k]->getSource();  					daeElementRef elem = uri.getElement();  					domSource* src = (domSource*) elem.cast(); +					if (!src) +					{ +						return LLModel::BAD_ELEMENT; +					}  					v = &(src->getFloat_array()->getValue());  				}  			} @@ -585,6 +606,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  			const domURIFragmentType& uri = inputs[i]->getSource();  			daeElementRef elem = uri.getElement();  			domSource* src = (domSource*) elem.cast(); +			if (!src) +			{ +				return LLModel::BAD_ELEMENT; +			}  			n = &(src->getFloat_array()->getValue());  		}  		else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0) @@ -593,6 +618,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  			const domURIFragmentType& uri = inputs[i]->getSource();  			daeElementRef elem = uri.getElement();  			domSource* src = (domSource*) elem.cast(); +			if (!src) +			{ +				return LLModel::BAD_ELEMENT; +			}  			t = &(src->getFloat_array()->getValue());  		}  	} @@ -712,7 +741,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  //static  std::string LLModel::getStatusString(U32 status)  { -	const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow"}; +	const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"};  	if(status < INVALID_STATUS)  	{ @@ -750,7 +779,6 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)  	for (U32 i = 0; i < polys.getCount(); ++i)  	{  		domPolylistRef& poly = polys.get(i); -  		mStatus = load_face_from_dom_polylist(mVolumeFaces, mMaterialList, poly);  		if(mStatus != NO_ERRORS) @@ -760,12 +788,12 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)  			return ; //abort  		}  	} - +	  	domPolygons_Array& polygons = mesh->getPolygons_array(); +	  	for (U32 i = 0; i < polygons.getCount(); ++i)  	{  		domPolygonsRef& poly = polygons.get(i); -  		mStatus = load_face_from_dom_polygons(mVolumeFaces, mMaterialList, poly);  		if(mStatus != NO_ERRORS) @@ -775,7 +803,7 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)  			return ; //abort  		}  	} - +   }  BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh) diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index ebca1f9d9d..cd9f76fcb7 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -73,6 +73,7 @@ public:  	{  		NO_ERRORS = 0,  		VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535. +		BAD_ELEMENT,  		INVALID_STATUS  	} ; diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 6b4e9cf923..15a7438ec9 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params()  :	label_width("label_width"),  	decimal_digits("decimal_digits"),  	allow_text_entry("allow_text_entry", true), +	label_wrap("label_wrap", false),  	text_enabled_color("text_enabled_color"),  	text_disabled_color("text_disabled_color"),  	up_button("up_button"), @@ -80,6 +81,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)  	{  		LLRect label_rect( 0, centered_top, label_width, centered_bottom );  		LLTextBox::Params params; +		params.wrap(p.label_wrap);  		params.name("SpinCtrl Label");  		params.rect(label_rect);  		params.initial_value(p.label()); diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h index 8960971594..d197084e38 100644 --- a/indra/llui/llspinctrl.h +++ b/indra/llui/llspinctrl.h @@ -44,6 +44,7 @@ public:  		Optional<S32> label_width;  		Optional<U32> decimal_digits;  		Optional<bool> allow_text_entry; +		Optional<bool> label_wrap;  		Optional<LLUIColor> text_enabled_color;  		Optional<LLUIColor> text_disabled_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 029f282d7c..5e6c5ebec8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -9,34 +9,6 @@  #extension GL_ARB_texture_rectangle : enable -varying float vary_texture_index; - -uniform sampler2D tex0; -uniform sampler2D tex1; -uniform sampler2D tex2; -uniform sampler2D tex3; -uniform sampler2D tex4; -uniform sampler2D tex5; -uniform sampler2D tex6; -uniform sampler2D tex7; - -vec4 textureLookup(vec2 texcoord) -{ -	switch (int(vary_texture_index+0.25)) -	{ -		case 0: return texture2D(tex0, texcoord); -		case 1: return texture2D(tex1, texcoord); -		case 2: return texture2D(tex2, texcoord); -		case 3: return texture2D(tex3, texcoord); -		case 4: return texture2D(tex4, texcoord); -		case 5: return texture2D(tex5, texcoord); -		case 6: return texture2D(tex6, texcoord); -		case 7: return texture2D(tex7, texcoord); -	} - -	return vec4(0,0,0,0); -} -  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -45,12 +17,13 @@ void main()  {  	float shadow = 1.0; -	vec4 color = textureLookup(gl_TexCoord[0].xy)*gl_Color; +	vec4 color = diffuseLookup(gl_TexCoord[0].xy)*gl_Color;  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	gl_FragColor = color; +	//gl_FragColor = color; +	gl_FragColor = vec4(1,0,1,1);  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 6dbcc479e1..d53850b489 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -234,7 +234,7 @@ void main()  	gl_FragColor[0] = shadow;  	gl_FragColor[1] = calcAmbientOcclusion(pos, norm); -	spos.xyz = shadow_pos+offset*spot_shadow_offset; +	spos.xyz = shadow_pos+norm*spot_shadow_offset;  	//spotlight shadow 1  	vec4 lpos = shadow_matrix[4]*spos; diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 25dd2ffe78..1d29c5b597 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 27 +version 28  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -64,6 +64,7 @@ RenderDeferredSSAO			1	1  RenderShadowDetail			1	2  WatchdogDisabled				1	1  RenderUseStreamVBO			1	1 +RenderFSAASamples			1	16  //  // Low Graphics Settings @@ -95,6 +96,7 @@ SkyUseClassicClouds			1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // Mid Graphics Settings @@ -124,6 +126,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // High Graphics Settings (purty) @@ -153,6 +156,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	4  //  // Ultra graphics (REALLY PURTY!) @@ -181,6 +185,7 @@ WLSkyDetail					1	128  RenderDeferred				1	1  RenderDeferredSSAO			1	1  RenderShadowDetail			1	2 +RenderFSAASamples			1	8  //  // Class Unknown Hardware (unknown) diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 058bdcc730..9daa5a5b29 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 23 +version 24  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -62,6 +62,7 @@ RenderShaderLightingMaxLevel		1	3  RenderDeferred				1	1  RenderDeferredSSAO			1	1  RenderShadowDetail			1	2 +RenderFSAASamples			1	16  //  // Low Graphics Settings @@ -93,6 +94,7 @@ SkyUseClassicClouds			1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // Mid Graphics Settings @@ -122,6 +124,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // High Graphics Settings (purty) @@ -151,6 +154,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	4  //  // Ultra graphics (REALLY PURTY!) @@ -180,6 +184,7 @@ WLSkyDetail					1	128  RenderDeferred				1	1  RenderDeferredSSAO			1	1  RenderShadowDetail			1	2 +RenderFSAASamples			1	8  //  // Class Unknown Hardware (unknown) diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 8b8340bd71..d7b4128ca2 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 24 +version 25  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -64,6 +64,7 @@ RenderDeferredSSAO			1	1  RenderShadowDetail			1	2  WatchdogDisabled				1	1  RenderUseStreamVBO			1	1 +RenderFSAASamples			1	16  //  // Low Graphics Settings @@ -95,6 +96,7 @@ SkyUseClassicClouds			1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // Mid Graphics Settings @@ -124,6 +126,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // High Graphics Settings (purty) @@ -153,6 +156,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	2 +RenderFSAASamples			1	4  //  // Ultra graphics (REALLY PURTY!) @@ -182,6 +186,7 @@ WLSkyDetail					1	128  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	2 +RenderFSAASamples			1	8  //  // Class Unknown Hardware (unknown) diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index 65a6f59bbe..0a23b4d6a6 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 27 +version 28  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -64,6 +64,7 @@ RenderDeferredSSAO			1	0  RenderShadowDetail			1	0  WatchdogDisabled				1	1  RenderUseStreamVBO			1	1 +RenderFSAASamples			1	16  //  // Low Graphics Settings @@ -95,6 +96,7 @@ SkyUseClassicClouds			1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // Mid Graphics Settings @@ -124,6 +126,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	0 +RenderFSAASamples			1	0  //  // High Graphics Settings (purty) @@ -153,6 +156,7 @@ WLSkyDetail					1	48  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	2 +RenderFSAASamples			1	4  //  // Ultra graphics (REALLY PURTY!) @@ -182,6 +186,7 @@ WLSkyDetail					1	128  RenderDeferred				1	0  RenderDeferredSSAO			1	0  RenderShadowDetail			1	2 +RenderFSAASamples			1	8  //  // Class Unknown Hardware (unknown) diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 8985d3680e..813b3820ee 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -537,6 +537,12 @@ void LLDrawPoolBump::beginFullbrightShiny()  		gGL.getTexUnit(cube_channel)->bind(cube_map);  		gGL.getTexUnit(0)->activate();  	} + +	if (mVertexShaderLevel > 1) +	{ //indexed texture rendering, channel 0 is always diffuse +		diffuse_channel = 0; +	} +  	mShiny = TRUE;  } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 1f6199ffb2..46d39db6cd 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -697,6 +697,11 @@ void LLFloaterModelPreview::draw()  			childSetTextArg("status", "[STATUS]", getString(LLModel::getStatusString(mModelPreview->getLoadState() - LLModelLoader::ERROR_PARSING)));  		}  		else +		if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_PARSING ) +		{ +			childSetTextArg("status", "[STATUS]", getString("status_parse_error")); +		} +		else  		{  			childSetTextArg("status", "[STATUS]", getString("status_idle"));  		} @@ -1349,6 +1354,23 @@ bool LLModelLoader::doLoadModel()  		return false;  	} +	//Verify some basic properties of the dae +	//1. Basic validity check on controller  +	U32 controllerCount = (int) db->getElementCount( NULL, "controller" ); +	bool result = false; +	for ( int i=0; i<controllerCount; ++i ) +	{ +		domController* pController = NULL; +		db->getElement( (daeElement**) &pController, i , NULL, "controller" ); +		result = mPreview->verifyController( pController ); +		if (!result) +		{ +			setLoadState( ERROR_PARSING ); +			return true; +		} +	} + +  	//get unit scale  	mTransform.setIdentity(); @@ -2277,6 +2299,90 @@ bool LLModelLoader::isNodeAJoint( domNode* pNode )  	return false;  } +//----------------------------------------------------------------------------- +// verifyCount +//----------------------------------------------------------------------------- +bool LLModelPreview::verifyCount( int expected, int result )
 +{
 +	if ( expected != result )
 +	{
 +		llinfos<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<llendl;
 +		return false;
 +	}
 +	return true;
 +}
 +//----------------------------------------------------------------------------- +// verifyController +//----------------------------------------------------------------------------- +bool LLModelPreview::verifyController( domController* pController )
 +{	
 +
 +	bool result = true;
 +
 +	domSkin* pSkin = pController->getSkin();
 +
 +	if ( pSkin )
 +	{
 +		xsAnyURI & uri = pSkin->getSource();
 +		domElement* pElement = uri.getElement();
 +
 +		if ( !pElement )
 +		{
 +			llinfos<<"Can't resolve skin source"<<llendl;
 +			return false;
 +		}
 +
 +		daeString type_str = pElement->getTypeName();
 +		if ( stricmp(type_str, "geometry") == 0 )
 +		{	
 +			//Skin is reference directly by geometry and get the vertex count from skin
 +			domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights();
 +			U32 vertexWeightsCount = pVertexWeights->getCount();
 +			domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement();
 +			domMesh* pMesh = pGeometry->getMesh();				
 +			
 +			if ( pMesh )
 +			{
 +				//Get vertex count from geometry
 +				domVertices* pVertices = pMesh->getVertices();
 +				if ( !pVertices )
 +				{ 
 +					llinfos<<"No vertices!"<<llendl;
 +					return false;
 +				}
 +
 +				if ( pVertices )
 +				{
 +					xsAnyURI src = pVertices->getInput_array()[0]->getSource();
 +					domSource* pSource = (domSource*) (domElement*) src.getElement();
 +					U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount();
 +					result = verifyCount( verticesCount, vertexWeightsCount );
 +					if ( !result )
 +					{
 +						return result;
 +					}
 +				}
 +			}	
 +
 +			U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount();
 +			result = verifyCount( vcountCount, vertexWeightsCount );	
 +			if ( !result )
 +			{
 +				return result;
 +			}
 +
 +			domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array();
 +			U32 sum = 0;
 +			for (size_t i=0; i<vcountCount; i++)
 +			{
 +				sum += pVertexWeights->getVcount()->getValue()[i];
 +			}
 +			result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() );
 +		}
 +	}
 +	
 +	return result;
 +}
  //-----------------------------------------------------------------------------  // extractTranslation() diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index ed7cbe6d1e..a328bfb4dd 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -1,433 +1,438 @@ -/** - * @file llfloatermodelpreview.h - * @brief LLFloaterModelPreview class definition - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFLOATERMODELPREVIEW_H -#define LL_LLFLOATERMODELPREVIEW_H - -#include "llfloaternamedesc.h" - -#include "lldynamictexture.h" -#include "llfloatermodelwizard.h" -#include "llquaternion.h" -#include "llmeshrepository.h" -#include "llmodel.h" -#include "llthread.h" -#include "llviewermenufile.h" - -class LLComboBox; -class LLJoint; -class LLViewerJointMesh; -class LLVOAvatar; -class LLTextBox; -class LLVertexBuffer; -class LLModelPreview; -class LLFloaterModelPreview; -class daeElement; -class domProfile_COMMON; -class domInstance_geometry; -class domNode; -class domTranslate; -class LLMenuButton; -class LLToggleableMenu; - -typedef std::map<std::string, LLMatrix4> JointTransformMap; -typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt; - -const S32 NUM_LOD = 4; - -class LLModelLoader : public LLThread -{ -public: -	typedef enum -	{ -		STARTING = 0, -		READING_FILE, -		CREATING_FACES, -		GENERATING_VERTEX_BUFFERS, -		GENERATING_LOD, -		DONE, -		ERROR_PARSING //basically loading failed -	} eLoadState; - -	U32 mState; -	std::string mFilename; -	S32 mLod; -	LLModelPreview* mPreview; -	LLMatrix4 mTransform; -	BOOL mFirstTransform; -	LLVector3 mExtents[2]; -	bool mTrySLM; -	 -	std::map<daeElement*, LLPointer<LLModel> > mModel; -	 -	typedef std::vector<LLPointer<LLModel> > model_list; -	model_list mModelList; - -	typedef std::vector<LLModelInstance> model_instance_list; -	 -	typedef std::map<LLMatrix4, model_instance_list > scene; - -	scene mScene; - -	typedef std::queue<LLPointer<LLModel> > model_queue; - -	//queue of models that need a physics rep -	model_queue mPhysicsQ; - -	LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap,  -				   std::deque<std::string>& jointsFromNodes ); -	~LLModelLoader() ; - -	virtual void run(); -	bool doLoadModel(); -	bool loadFromSLM(const std::string& filename); -	void loadModelCallback(); - -	void loadTextures() ; //called in the main thread. -	void processElement(daeElement* element); -	std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo); -	LLImportMaterial profileToMaterial(domProfile_COMMON* material); -	std::string getElementLabel(daeElement *element); -	LLColor4 getDaeColor(daeElement* element); -	 -	daeElement* getChildFromElement( daeElement* pElement, std::string const & name ); -	 -	bool isNodeAJoint( domNode* pNode ); -	void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms ); -	void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); -	void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); -	 -	void setLoadState(U32 state); - -	void buildJointToNodeMappingFromScene( daeElement* pRoot ); -	void processJointToNodeMapping( domNode* pNode ); - - -	//map of avatar joints as named in COLLADA assets to internal joint names -	std::map<std::string, std::string> mJointMap; -	JointTransformMap& mJointList;	 -	std::deque<std::string>& mJointsFromNode; - -private: -	static std::list<LLModelLoader*> sActiveLoaderList; -	static bool isAlive(LLModelLoader* loader) ; -}; - -class LLFloaterModelPreview : public LLFloater -{ -public: -	 -	class DecompRequest : public LLPhysicsDecomp::Request -	{ -	public: -		S32 mContinue; -		LLPointer<LLModel> mModel; -		 -		DecompRequest(const std::string& stage, LLModel* mdl); -		virtual S32 statusCallback(const char* status, S32 p1, S32 p2); -		virtual void completed(); -		 -	}; -	static LLFloaterModelPreview* sInstance; -	 -	LLFloaterModelPreview(const LLSD& key); -	virtual ~LLFloaterModelPreview(); -	 -	virtual BOOL postBuild(); -	 -	BOOL handleMouseDown(S32 x, S32 y, MASK mask); -	BOOL handleMouseUp(S32 x, S32 y, MASK mask); -	BOOL handleHover(S32 x, S32 y, MASK mask); -	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);  -	 -	static void onMouseCaptureLostModelPreview(LLMouseHandler*); -	static void setUploadAmount(S32 amount) { sUploadAmount = amount; } - -	void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost); -	 -	static void onBrowseLOD(void* data); -	 -	static void onReset(void* data); - -	static void onUpload(void* data); -	 -	static void onClearMaterials(void* data); -	 -	static void refresh(LLUICtrl* ctrl, void* data); -	 -	void updateResourceCost(); -	 -	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); - -protected: -	friend class LLModelPreview; -	friend class LLMeshFilePicker; -	friend class LLPhysicsDecomp; -	 -	static void		onImportScaleCommit(LLUICtrl*, void*); -	static void		onPelvisOffsetCommit(LLUICtrl*, void*); -	static void		onUploadJointsCommit(LLUICtrl*,void*); -	static void		onUploadSkinCommit(LLUICtrl*,void*); -	 -	static void		onPhysicsLoadRadioCommit(LLUICtrl*,void *data); - -	static void		onPreviewLODCommit(LLUICtrl*,void*); -	 -	static void		onGenerateNormalsCommit(LLUICtrl*,void*); -	 -	static void		onAutoFillCommit(LLUICtrl*,void*); -	static void		onLODParamCommit(LLUICtrl*,void*); -	static void		onLODParamCommitTriangleLimit(LLUICtrl*,void*); -	 -	static void		onExplodeCommit(LLUICtrl*, void*); -	 -	static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata); -	static void onCancel(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata); -	 -	static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata); -	static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata); -		 -	void			draw(); -	 -	void initDecompControls(); -	 -	void setStatusMessage(const std::string& msg); - -	LLModelPreview*	mModelPreview; -	 -	LLPhysicsDecomp::decomp_params mDecompParams; -	 -	S32				mLastMouseX; -	S32				mLastMouseY; -	LLRect			mPreviewRect; -	U32				mGLName; -	static S32		sUploadAmount; -	 -	std::set<LLPointer<DecompRequest> > mCurRequest; -	std::string mStatusMessage; - -	//use "disabled" as false by default -	std::map<std::string, bool> mViewOptionDisabled; -	 -	//store which lod mode each LOD is using -	// 0 - load from file -	// 1 - auto generate -	// 2 - None -	S32 mLODMode[4]; - -	LLMenuButton* mViewOptionMenuButton; -	LLToggleableMenu* mViewOptionMenu; -	LLMutex* mStatusLock; - -}; - -class LLMeshFilePicker : public LLFilePickerThread -{ -public: -	LLMeshFilePicker(LLModelPreview* mp, S32 lod); -	virtual void notify(const std::string& filename); - -private: -	LLModelPreview* mMP; -	S32 mLOD; -}; - - -class LLModelPreview : public LLViewerDynamicTexture, public LLMutex -{	 -	typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t; -	typedef boost::signals2::signal<void (void)> model_loaded_signal_t; - -public: -	LLModelPreview(S32 width, S32 height, LLFloater* fmp); -	virtual ~LLModelPreview(); - -	void resetPreviewTarget(); -	void setPreviewTarget(F32 distance); -	void setTexture(U32 name) { mTextureName = name; } - -	void setPhysicsFromLOD(S32 lod); -	BOOL render(); -	void update(); -	void genBuffers(S32 lod, bool skinned); -	void clearBuffers(); -	void refresh(); -	void rotate(F32 yaw_radians, F32 pitch_radians); -	void zoom(F32 zoom_amt); -	void pan(F32 right, F32 up); -	virtual BOOL needsRender() { return mNeedsUpdate; } -	void setPreviewLOD(S32 lod); -	void clearModel(S32 lod); -	void loadModel(std::string filename, S32 lod); -	void loadModelCallback(S32 lod); -	void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); -	void generateNormals(); -	void clearMaterials(); -	U32 calcResourceCost(); -	void rebuildUploadData(); -	void saveUploadData(bool save_skinweights, bool save_joint_poisitions); -	void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions); -	void clearIncompatible(S32 lod); -	void updateStatusMessages(); -	void clearGLODGroup(); -	void onLODParamCommit(bool enforce_tri_limit); - -	const bool getModelPivot( void ) const { return mHasPivot; } -	void setHasPivot( bool val ) { mHasPivot = val; } -	void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; } - -	//Sets the current avatars joints to new positions -	//Makes in world go to shit, however -	void changeAvatarsJointPositions( LLModel* pModel ); -	//Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) -	void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); -	void critiqueJointToNodeMappingFromScene( void  ); -	//Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions -	//Accessors for joint position upload friendly rigs -	const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } -	void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } -	bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ); -	//Determines if a rig is a legacy from the joint list -	bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );	 -	//Accessors for the legacy rigs -	const bool isLegacyRigValid( void ) const { return mLegacyRigValid; } -	void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }	 - -	static void	textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); -	 -	boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){  return mDetailsSignal.connect(cb);  } -	boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){  return mModelLoadedSignal.connect(cb);  } -	 -	void setLoadState( U32 state ) { mLoadState = state; } -	U32 getLoadState() { return mLoadState; } -	//setRestJointFlag: If an asset comes through that changes the joints, we want the reset to persist -	void setResetJointFlag( bool state ) { if ( !mResetJoints ) mResetJoints = state; } -	const bool getResetJointFlag( void ) const { return mResetJoints; } -	void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } -	const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } -	 -	LLVector3 getTranslationForJointOffset( std::string joint ); - -	void		createPreviewAvatar( void ); -	LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; } - - protected: -	friend class LLModelLoader; -	friend class LLFloaterModelPreview; -	friend class LLFloaterModelWizard; -	friend class LLFloaterModelPreview::DecompRequest; -	friend class LLFloaterModelWizard::DecompRequest; -	friend class LLPhysicsDecomp; - -	LLFloater*  mFMP; - -	BOOL        mNeedsUpdate; -	bool		mDirty; -	bool		mGenLOD; -	U32         mTextureName; -	F32			mCameraDistance; -	F32			mCameraYaw; -	F32			mCameraPitch; -	F32			mCameraZoom; -	LLVector3	mCameraOffset; -	LLVector3	mPreviewTarget; -	LLVector3	mPreviewScale; -	S32			mPreviewLOD; -	U32			mResourceCost; -	std::string mLODFile[LLModel::NUM_LODS]; -	bool		mLoading; -	U32			mLoadState; -	bool		mResetJoints; -	bool		mRigParityWithScene; -	 -	std::map<std::string, bool> mViewOption; - -	//GLOD object parameters (must rebuild object if these change) -	bool mLODFrozen; -	F32 mBuildShareTolerance; -	U32 mBuildQueueMode; -	U32 mBuildOperator; -	U32 mBuildBorderMode; -	U32 mRequestedLoDMode[LLModel::NUM_LODS]; -	S32 mRequestedTriangleCount[LLModel::NUM_LODS]; -	F32 mRequestedErrorThreshold[LLModel::NUM_LODS]; -	U32 mRequestedBuildOperator[LLModel::NUM_LODS]; -	U32 mRequestedQueueMode[LLModel::NUM_LODS]; -	U32 mRequestedBorderMode[LLModel::NUM_LODS]; -	F32 mRequestedShareTolerance[LLModel::NUM_LODS]; -	F32 mRequestedCreaseAngle[LLModel::NUM_LODS]; - -	LLModelLoader* mModelLoader; - -	LLModelLoader::scene mScene[LLModel::NUM_LODS]; -	LLModelLoader::scene mBaseScene; - -	LLModelLoader::model_list mModel[LLModel::NUM_LODS]; -	LLModelLoader::model_list mBaseModel; - -	U32 mGroup; -	std::map<LLPointer<LLModel>, U32> mObject; -	U32 mMaxTriangleLimit; -	 -	LLMeshUploadThread::instance_list mUploadData; -	std::set<LLViewerFetchedTexture* > mTextureSet; - -	//map of vertex buffers to models (one vertex buffer in vector per face in model -	std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1]; - -	details_signal_t mDetailsSignal; -	model_loaded_signal_t mModelLoadedSignal; -	 -	LLVector3	mModelPivot; -	bool		mHasPivot; -	 -	float		mPelvisZOffset; -	 -	bool		mRigValidJointUpload; -	bool		mLegacyRigValid; - -	bool		mLastJointUpdate; - -	std::deque<std::string> mMasterJointList; -	std::deque<std::string> mMasterLegacyJointList; -	std::deque<std::string> mJointsFromNode; -	JointTransformMap		mJointTransformMap; -	LLPointer<LLVOAvatar>	mPreviewAvatar; -}; - -#endif  // LL_LLFLOATERMODELPREVIEW_H +/**
 + * @file llfloatermodelpreview.h
 + * @brief LLFloaterModelPreview class definition
 + *
 + * $LicenseInfo:firstyear=2004&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2010, Linden Research, Inc.
 + * 
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation;
 + * version 2.1 of the License only.
 + * 
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + * 
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 + * 
 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 + * $/LicenseInfo$
 + */
 +
 +#ifndef LL_LLFLOATERMODELPREVIEW_H
 +#define LL_LLFLOATERMODELPREVIEW_H
 +
 +#include "llfloaternamedesc.h"
 +
 +#include "lldynamictexture.h"
 +#include "llfloatermodelwizard.h"
 +#include "llquaternion.h"
 +#include "llmeshrepository.h"
 +#include "llmodel.h"
 +#include "llthread.h"
 +#include "llviewermenufile.h"
 +
 +class LLComboBox;
 +class LLJoint;
 +class LLViewerJointMesh;
 +class LLVOAvatar;
 +class LLTextBox;
 +class LLVertexBuffer;
 +class LLModelPreview;
 +class LLFloaterModelPreview;
 +class daeElement;
 +class domProfile_COMMON;
 +class domInstance_geometry;
 +class domNode;
 +class domTranslate;
 +class domController;
 +class LLMenuButton;
 +class LLToggleableMenu;
 +
 +typedef std::map<std::string, LLMatrix4> JointTransformMap;
 +typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt;
 +
 +const S32 NUM_LOD = 4;
 +
 +class LLModelLoader : public LLThread
 +{
 +public:
 +	typedef enum
 +	{
 +		STARTING = 0,
 +		READING_FILE,
 +		CREATING_FACES,
 +		GENERATING_VERTEX_BUFFERS,
 +		GENERATING_LOD,
 +		DONE,
 +		ERROR_PARSING //basically loading failed
 +	} eLoadState;
 +
 +	U32 mState;
 +	std::string mFilename;
 +	S32 mLod;
 +	LLModelPreview* mPreview;
 +	LLMatrix4 mTransform;
 +	BOOL mFirstTransform;
 +	LLVector3 mExtents[2];
 +	bool mTrySLM;
 +	
 +	std::map<daeElement*, LLPointer<LLModel> > mModel;
 +	
 +	typedef std::vector<LLPointer<LLModel> > model_list;
 +	model_list mModelList;
 +
 +	typedef std::vector<LLModelInstance> model_instance_list;
 +	
 +	typedef std::map<LLMatrix4, model_instance_list > scene;
 +
 +	scene mScene;
 +
 +	typedef std::queue<LLPointer<LLModel> > model_queue;
 +
 +	//queue of models that need a physics rep
 +	model_queue mPhysicsQ;
 +
 +	LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap, 
 +				   std::deque<std::string>& jointsFromNodes );
 +	~LLModelLoader() ;
 +
 +	virtual void run();
 +	bool doLoadModel();
 +	bool loadFromSLM(const std::string& filename);
 +	void loadModelCallback();
 +
 +	void loadTextures() ; //called in the main thread.
 +	void processElement(daeElement* element);
 +	std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
 +	LLImportMaterial profileToMaterial(domProfile_COMMON* material);
 +	std::string getElementLabel(daeElement *element);
 +	LLColor4 getDaeColor(daeElement* element);
 +	
 +	daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
 +	
 +	bool isNodeAJoint( domNode* pNode );
 +	void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
 +	void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
 +	void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
 +	
 +	void setLoadState(U32 state);
 +
 +	void buildJointToNodeMappingFromScene( daeElement* pRoot );
 +	void processJointToNodeMapping( domNode* pNode );
 +
 +
 +	//map of avatar joints as named in COLLADA assets to internal joint names
 +	std::map<std::string, std::string> mJointMap;
 +	JointTransformMap& mJointList;	
 +	std::deque<std::string>& mJointsFromNode;
 +
 +private:
 +	static std::list<LLModelLoader*> sActiveLoaderList;
 +	static bool isAlive(LLModelLoader* loader) ;
 +};
 +
 +class LLFloaterModelPreview : public LLFloater
 +{
 +public:
 +	
 +	class DecompRequest : public LLPhysicsDecomp::Request
 +	{
 +	public:
 +		S32 mContinue;
 +		LLPointer<LLModel> mModel;
 +		
 +		DecompRequest(const std::string& stage, LLModel* mdl);
 +		virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
 +		virtual void completed();
 +		
 +	};
 +	static LLFloaterModelPreview* sInstance;
 +	
 +	LLFloaterModelPreview(const LLSD& key);
 +	virtual ~LLFloaterModelPreview();
 +	
 +	virtual BOOL postBuild();
 +	
 +	BOOL handleMouseDown(S32 x, S32 y, MASK mask);
 +	BOOL handleMouseUp(S32 x, S32 y, MASK mask);
 +	BOOL handleHover(S32 x, S32 y, MASK mask);
 +	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); 
 +	
 +	static void onMouseCaptureLostModelPreview(LLMouseHandler*);
 +	static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
 +
 +	void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
 +	
 +	static void onBrowseLOD(void* data);
 +	
 +	static void onReset(void* data);
 +
 +	static void onUpload(void* data);
 +	
 +	static void onClearMaterials(void* data);
 +	
 +	static void refresh(LLUICtrl* ctrl, void* data);
 +	
 +	void updateResourceCost();
 +	
 +	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);
 +
 +protected:
 +	friend class LLModelPreview;
 +	friend class LLMeshFilePicker;
 +	friend class LLPhysicsDecomp;
 +	
 +	static void		onImportScaleCommit(LLUICtrl*, void*);
 +	static void		onPelvisOffsetCommit(LLUICtrl*, void*);
 +	static void		onUploadJointsCommit(LLUICtrl*,void*);
 +	static void		onUploadSkinCommit(LLUICtrl*,void*);
 +	
 +	static void		onPhysicsLoadRadioCommit(LLUICtrl*,void *data);
 +
 +	static void		onPreviewLODCommit(LLUICtrl*,void*);
 +	
 +	static void		onGenerateNormalsCommit(LLUICtrl*,void*);
 +	
 +	static void		onAutoFillCommit(LLUICtrl*,void*);
 +	static void		onLODParamCommit(LLUICtrl*,void*);
 +	static void		onLODParamCommitTriangleLimit(LLUICtrl*,void*);
 +	
 +	static void		onExplodeCommit(LLUICtrl*, void*);
 +	
 +	static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata);
 +	static void onCancel(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata);
 +	
 +	static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata);
 +	static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata);
 +		
 +	void			draw();
 +	
 +	void initDecompControls();
 +	
 +	void setStatusMessage(const std::string& msg);
 +
 +	LLModelPreview*	mModelPreview;
 +	
 +	LLPhysicsDecomp::decomp_params mDecompParams;
 +	
 +	S32				mLastMouseX;
 +	S32				mLastMouseY;
 +	LLRect			mPreviewRect;
 +	U32				mGLName;
 +	static S32		sUploadAmount;
 +	
 +	std::set<LLPointer<DecompRequest> > mCurRequest;
 +	std::string mStatusMessage;
 +
 +	//use "disabled" as false by default
 +	std::map<std::string, bool> mViewOptionDisabled;
 +	
 +	//store which lod mode each LOD is using
 +	// 0 - load from file
 +	// 1 - auto generate
 +	// 2 - None
 +	S32 mLODMode[4];
 +
 +	LLMenuButton* mViewOptionMenuButton;
 +	LLToggleableMenu* mViewOptionMenu;
 +	LLMutex* mStatusLock;
 +
 +};
 +
 +class LLMeshFilePicker : public LLFilePickerThread
 +{
 +public:
 +	LLMeshFilePicker(LLModelPreview* mp, S32 lod);
 +	virtual void notify(const std::string& filename);
 +
 +private:
 +	LLModelPreview* mMP;
 +	S32 mLOD;
 +};
 +
 +
 +class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
 +{	
 +	typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t;
 +	typedef boost::signals2::signal<void (void)> model_loaded_signal_t;
 +
 +public:
 +	LLModelPreview(S32 width, S32 height, LLFloater* fmp);
 +	virtual ~LLModelPreview();
 +
 +	void resetPreviewTarget();
 +	void setPreviewTarget(F32 distance);
 +	void setTexture(U32 name) { mTextureName = name; }
 +
 +	void setPhysicsFromLOD(S32 lod);
 +	BOOL render();
 +	void update();
 +	void genBuffers(S32 lod, bool skinned);
 +	void clearBuffers();
 +	void refresh();
 +	void rotate(F32 yaw_radians, F32 pitch_radians);
 +	void zoom(F32 zoom_amt);
 +	void pan(F32 right, F32 up);
 +	virtual BOOL needsRender() { return mNeedsUpdate; }
 +	void setPreviewLOD(S32 lod);
 +	void clearModel(S32 lod);
 +	void loadModel(std::string filename, S32 lod);
 +	void loadModelCallback(S32 lod);
 +	void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
 +	void generateNormals();
 +	void clearMaterials();
 +	U32 calcResourceCost();
 +	void rebuildUploadData();
 +	void saveUploadData(bool save_skinweights, bool save_joint_poisitions);
 +	void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions);
 +	void clearIncompatible(S32 lod);
 +	void updateStatusMessages();
 +	void clearGLODGroup();
 +	void onLODParamCommit(bool enforce_tri_limit);
 +
 +	const bool getModelPivot( void ) const { return mHasPivot; }
 +	void setHasPivot( bool val ) { mHasPivot = val; }
 +	void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; }
 +
 +	//Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps)
 +	void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset );
 +	void critiqueJointToNodeMappingFromScene( void  );
 +	//Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions
 +	//Accessors for joint position upload friendly rigs
 +	const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
 +	void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
 +	bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
 +	//Determines if a rig is a legacy from the joint list
 +	bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );	
 +	//Accessors for the legacy rigs
 +	const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
 +	void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }	
 +	//Verify that a controller matches vertex counts
 +	bool verifyController( domController* pController );
 +
 +	static void	textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
 +	
 +	boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){  return mDetailsSignal.connect(cb);  }
 +	boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){  return mModelLoadedSignal.connect(cb);  }
 +	
 +	void setLoadState( U32 state ) { mLoadState = state; }
 +	U32 getLoadState() { return mLoadState; }
 +	//setRestJointFlag: If an asset comes through that changes the joints, we want the reset to persist
 +	void setResetJointFlag( bool state ) { if ( !mResetJoints ) mResetJoints = state; }
 +	const bool getResetJointFlag( void ) const { return mResetJoints; }
 +	void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; }
 +	const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; }
 +	
 +	LLVector3 getTranslationForJointOffset( std::string joint );
 +
 +private:
 +	//Utility function for controller vertex compare
 +	bool verifyCount( int expected, int result );
 +	//Creates the dummy avatar for the preview window
 +	void		createPreviewAvatar( void );
 +	//Accessor for the dummy avatar
 +	LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; }
 +
 + protected:
 +	friend class LLModelLoader;
 +	friend class LLFloaterModelPreview;
 +	friend class LLFloaterModelWizard;
 +	friend class LLFloaterModelPreview::DecompRequest;
 +	friend class LLFloaterModelWizard::DecompRequest;
 +	friend class LLPhysicsDecomp;
 +
 +	LLFloater*  mFMP;
 +
 +	BOOL        mNeedsUpdate;
 +	bool		mDirty;
 +	bool		mGenLOD;
 +	U32         mTextureName;
 +	F32			mCameraDistance;
 +	F32			mCameraYaw;
 +	F32			mCameraPitch;
 +	F32			mCameraZoom;
 +	LLVector3	mCameraOffset;
 +	LLVector3	mPreviewTarget;
 +	LLVector3	mPreviewScale;
 +	S32			mPreviewLOD;
 +	U32			mResourceCost;
 +	std::string mLODFile[LLModel::NUM_LODS];
 +	bool		mLoading;
 +	U32			mLoadState;
 +	bool		mResetJoints;
 +	bool		mRigParityWithScene;
 +	
 +	std::map<std::string, bool> mViewOption;
 +
 +	//GLOD object parameters (must rebuild object if these change)
 +	bool mLODFrozen;
 +	F32 mBuildShareTolerance;
 +	U32 mBuildQueueMode;
 +	U32 mBuildOperator;
 +	U32 mBuildBorderMode;
 +	U32 mRequestedLoDMode[LLModel::NUM_LODS];
 +	S32 mRequestedTriangleCount[LLModel::NUM_LODS];
 +	F32 mRequestedErrorThreshold[LLModel::NUM_LODS];
 +	U32 mRequestedBuildOperator[LLModel::NUM_LODS];
 +	U32 mRequestedQueueMode[LLModel::NUM_LODS];
 +	U32 mRequestedBorderMode[LLModel::NUM_LODS];
 +	F32 mRequestedShareTolerance[LLModel::NUM_LODS];
 +	F32 mRequestedCreaseAngle[LLModel::NUM_LODS];
 +
 +	LLModelLoader* mModelLoader;
 +
 +	LLModelLoader::scene mScene[LLModel::NUM_LODS];
 +	LLModelLoader::scene mBaseScene;
 +
 +	LLModelLoader::model_list mModel[LLModel::NUM_LODS];
 +	LLModelLoader::model_list mBaseModel;
 +
 +	U32 mGroup;
 +	std::map<LLPointer<LLModel>, U32> mObject;
 +	U32 mMaxTriangleLimit;
 +	
 +	LLMeshUploadThread::instance_list mUploadData;
 +	std::set<LLViewerFetchedTexture* > mTextureSet;
 +
 +	//map of vertex buffers to models (one vertex buffer in vector per face in model
 +	std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
 +
 +	details_signal_t mDetailsSignal;
 +	model_loaded_signal_t mModelLoadedSignal;
 +	
 +	LLVector3	mModelPivot;
 +	bool		mHasPivot;
 +	
 +	float		mPelvisZOffset;
 +	
 +	bool		mRigValidJointUpload;
 +	bool		mLegacyRigValid;
 +
 +	bool		mLastJointUpdate;
 +
 +	std::deque<std::string> mMasterJointList;
 +	std::deque<std::string> mMasterLegacyJointList;
 +	std::deque<std::string> mJointsFromNode;
 +	JointTransformMap		mJointTransformMap;
 +	LLPointer<LLVOAvatar>	mPreviewAvatar;
 +};
 +
 +#endif  // LL_LLFLOATERMODELPREVIEW_H
 diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 7f91f9a952..d96fa087b1 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -35,6 +35,7 @@  #include "llvolumeoctree.h"  #include "llviewercamera.h"  #include "llface.h" +#include "llfloatertools.h"  #include "llviewercontrol.h"  #include "llviewerregion.h"  #include "llcamera.h" @@ -4272,7 +4273,29 @@ public:  			if (vobj)  			{  				LLVector3 intersection; -				if (vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) +				bool skip_check = false; +				if (vobj->isAvatar()) +				{ +					LLVOAvatar* avatar = (LLVOAvatar*) vobj; +					if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools)) +					{ +						LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal); +						if (hit) +						{ +							mEnd = intersection; +							if (mIntersection) +							{ +								*mIntersection = intersection; +							} +							 +							mHit = hit->mDrawable; +							skip_check = true; +						} + +					} +				} + +				if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))  				{  					mEnd = intersection;  // shorten ray so we only find CLOSER hits  					if (mIntersection) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 5dadd2c33b..f725f0fe86 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -996,8 +996,7 @@ void render_hud_attachments()  		S32 use_occlusion = LLPipeline::sUseOcclusion;  		LLPipeline::sUseOcclusion = 0; -		LLPipeline::sDisableShaders = TRUE; -		 +				  		//cull, sort, and render hud objects  		static LLCullResult result;  		LLSpatialGroup::sNoDelete = TRUE; @@ -1037,7 +1036,6 @@ void render_hud_attachments()  			gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);  		}  		LLPipeline::sUseOcclusion = use_occlusion; -		LLPipeline::sDisableShaders = FALSE;  	}  	glMatrixMode(GL_PROJECTION);  	glPopMatrix(); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index a1cb6d4ea6..e3ed2d0649 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1303,8 +1303,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredFullbrightProgram.mFeatures.hasGamma = true;  		gDeferredFullbrightProgram.mFeatures.hasTransport = true; -		gDeferredFullbrightProgram.mFeatures.isFullbright = true; -		gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = 0; +		gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits;  		gDeferredFullbrightProgram.mShaderFiles.clear();  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 77bbf994e9..1b53348b43 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -56,6 +56,7 @@  #include "lleditingmotion.h"  #include "llemote.h"  //#include "llfirstuse.h" +#include "llfloatertools.h"  #include "llheadrotmotion.h"  #include "llhudeffecttrail.h"  #include "llhudmanager.h" @@ -1541,7 +1542,35 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				return TRUE;  			}  		} + +		if (isSelf()) +		{ +			for (attachment_map_t::iterator iter = mAttachmentPoints.begin();  +			 iter != mAttachmentPoints.end(); +			 ++iter) +			{ +				LLViewerJointAttachment* attachment = iter->second; + +				for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +					 attachment_iter != attachment->mAttachedObjects.end(); +					 ++attachment_iter) +				{ +					LLViewerObject* attached_object = (*attachment_iter); +					 +					if (attached_object && !attached_object->isDead() && attachment->getValid()) +					{ +						LLDrawable* drawable = attached_object->mDrawable; +						if (drawable->isState(LLDrawable::RIGGED)) +						{ //regenerate octree for rigged attachment +							gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); +						} +					} +				} +			} +		}  	} + +	  	LLVector3 position;  	if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position)) @@ -1557,6 +1586,56 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	return FALSE;  } +LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +									  S32 face, +									  BOOL pick_transparent, +									  S32* face_hit, +									  LLVector3* intersection, +									  LLVector2* tex_coord, +									  LLVector3* normal, +									  LLVector3* bi_normal) +{ +	if (isSelf() && !gAgent.needsRenderAvatar()) +	{ +		return NULL; +	} + +	LLViewerObject* hit = NULL; + +	if (lineSegmentBoundingBox(start, end)) +	{ +		LLVector3 local_end = end; +		LLVector3 local_intersection; + +		for (attachment_map_t::iterator iter = mAttachmentPoints.begin();  +			iter != mAttachmentPoints.end(); +			++iter) +		{ +			LLViewerJointAttachment* attachment = iter->second; + +			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +					attachment_iter != attachment->mAttachedObjects.end(); +					++attachment_iter) +			{ +				LLViewerObject* attached_object = (*attachment_iter); +					 +				if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal)) +				{ +					local_end = local_intersection; +					if (intersection) +					{ +						*intersection = local_intersection; +					} +					 +					hit = attached_object; +				} +			} +		} +	} +		 +	return hit; +} +  //-----------------------------------------------------------------------------  // parseSkeletonFile()  //----------------------------------------------------------------------------- diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 295799fd24..03c0498a2a 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -145,6 +145,14 @@ public:  												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point  												 LLVector3* normal = NULL,         // return the surface normal at the intersection point  												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point +	LLViewerObject*	lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES +												 BOOL pick_transparent = FALSE, +												 S32* face_hit = NULL,             // which face was hit +												 LLVector3* intersection = NULL,   // return the intersection point +												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point +												 LLVector3* normal = NULL,         // return the surface normal at the intersection point +												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point  	//--------------------------------------------------------------------  	// LLCharacter interface and related diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d978167f50..c5e2c56e4b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3365,7 +3365,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	{  		if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf())  		{ -			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); +			updateRiggedVolume(); +			genBBoxes(FALSE);  			volume = mRiggedVolume;  			transform = 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 4677d014b8..f58595b3c5 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -4,9 +4,11 @@       name="Model Preview" title="Upload Model" width="620">    <string name="status_idle">Idle</string> +  <string name="status_parse_error">Dae parsing issue - see log for details.</string>    <string name="status_reading_file">Loading...</string>    <string name="status_generating_meshes">Generating Meshes...</string>    <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> +  <string name="bad_element">Error: element is invalid</string>    <string name="high">High</string>    <string name="medium">Medium</string>    <string name="low">Low</string> diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml index 47b2e5fd79..8603682e3a 100644 --- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml +++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml @@ -1019,9 +1019,11 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se  	<spinner visible="false" left="10" height="20" follows="top|left" width="80" top_pad="-50" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/>  	<string name="status_idle">Idle</string> +  <string name="status_parse_error">Dae parsing issue - see log for details.</string>  	<string name="status_reading_file">Loading...</string>  	<string name="status_generating_meshes">Generating Meshes...</string> -  <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> +	<string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> +	<string name="bad_element">Error: element is invalid</string>  	<string name="high">High</string>  	<string name="medium">Medium</string>  	<string name="low">Low</string> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index f5f6b990d1..7441b2cd9c 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2457,8 +2457,9 @@ even though the user gets a free copy.               height="19"               increment="0.1"               initial_value="0" -             label="Density" +             label="Density in 100 kg/m^3"               label_width="70" +             label_wrap="true"               layout="topleft"               left_delta="0"               max_val="22587" @@ -2479,7 +2480,7 @@ even though the user gets a free copy.               max_val="1"               min_val="0"               name="Physics Restitution" -             top_pad="4" +             top_pad="8"               width="132" />          </panel>           <panel | 
