Commits

davep  committed b52601f Draft Merge
  • Participants
  • Parent commits b56b238, 45a7f39

Comments (0)

Files changed (27)

File doc/contributions.txt

 	VWR-1358
 	VWR-2041
 Darien Caldwell
+	SH-3055
 Dartagan Shepherd
 Debs Regent
 Decro Schmooz
 	VWR-2682
 	VWR-2684
 Nick Rhodes
+NickyD
+	MAINT-873
 Nicky Perian
 	OPEN-1
 	STORM-1087
 Whimsy Winx
 Whirly Fizzle
 	STORM-1895
+	MAINT-873
 Whoops Babii
 	VWR-631
 	VWR-1640

File indra/llcharacter/llmotioncontroller.cpp

 //-----------------------------------------------------------------------------
 // Constants and statics
 //-----------------------------------------------------------------------------
+F32 LLMotionController::sCurrentTimeFactor = 1.f;
 LLMotionRegistry LLMotionController::sRegistry;
 
 //-----------------------------------------------------------------------------
 // Class Constructor
 //-----------------------------------------------------------------------------
 LLMotionController::LLMotionController()
-	: mTimeFactor(1.f),
+	: mTimeFactor(sCurrentTimeFactor),
 	  mCharacter(NULL),
 	  mAnimTime(0.f),
 	  mPrevTimerElapsed(0.f),

File indra/llcharacter/llmotioncontroller.h

 
 	const LLFrameTimer& getFrameTimer() { return mTimer; }
 
+	static F32	getCurrentTimeFactor()				{ return sCurrentTimeFactor;	};
+	static void setCurrentTimeFactor(F32 factor)	{ sCurrentTimeFactor = factor;	};
+
 protected:
 	// internal operations act on motion instances directly
 	// as there can be duplicate motions per id during blending overlap
 	void deactivateStoppedMotions();
 
 protected:
-	F32					mTimeFactor;
+	F32					mTimeFactor;			// 1.f for normal speed
+	static F32			sCurrentTimeFactor;		// Value to use for initialization
 	static LLMotionRegistry	sRegistry;
 	LLPoseBlender		mPoseBlender;
 

File indra/llmessage/llurlrequest.cpp

 			}
 		}
 
-		while(1)
+		bool keep_looping = true;
+		while(keep_looping)
 		{
 			CURLcode result;
 
 				case CURLE_FAILED_INIT:
 				case CURLE_COULDNT_CONNECT:
 					status = STATUS_NO_CONNECTION;
+					keep_looping = false;
 					break;
-				default:
+				default:			// CURLE_URL_MALFORMAT
 					llwarns << "URLRequest Error: " << result
 							<< ", "
 							<< LLCurl::strerror(result)
 							<< (mDetail->mURL.empty() ? "<EMPTY URL>" : mDetail->mURL)
 							<< llendl;
 					status = STATUS_ERROR;
+					keep_looping = false;
 					break;
 			}
 		}

File indra/newview/app_settings/settings.xml

         <real>1.0</real>
       </array>
     </map>
+    
+    <key>HideUIControls</key>
+    <map>
+      <key>Comment</key>
+      <string>Hide all menu items and buttons</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
 </map>
 </llsd>

File indra/newview/app_settings/shaders/class1/objects/previewF.glsl

+/** 
+ * @file previewF.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+	frag_color = color;
+}

File indra/newview/app_settings/shaders/class1/objects/previewV.glsl

  * $/LicenseInfo$
  */
 
+float calcDirectionalLight(vec3 n, vec3 l);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
+
 uniform mat3 normal_matrix;
 uniform mat4 texture_matrix0;
 uniform mat4 modelview_matrix;
 ATTRIBUTE vec3 normal;
 ATTRIBUTE vec2 texcoord0;
 
+uniform vec4 color;
+
 VARYING vec4 vertex_color;
 VARYING vec2 vary_texcoord0;
 
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-void calcAtmospherics(vec3 inPositionEye);
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
 
 void main()
 {
 	vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
 	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
 	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-		
+	
 	vec3 norm = normalize(normal_matrix * normal);
 
-	calcAtmospherics(pos.xyz);
+	vec4 col = vec4(0,0,0,1);
 
-	vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.));
-	vertex_color = color;
-
-	
+	// Collect normal lights (need to be divided by two, as we later multiply by 2)
+	col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
+		
+	vertex_color = col*color;
 }

File indra/newview/llagentcamera.cpp

 #include "llfloaterreg.h"
 #include "llhudmanager.h"
 #include "lljoystickbutton.h"
+#include "llmoveview.h"
 #include "llselectmgr.h"
 #include "llsmoothstep.h"
 #include "lltoolmgr.h"
 	{
 		changeCameraToThirdPerson();
 	}
+	if (gSavedSettings.getBOOL("HideUIControls"))
+	{
+		gViewerWindow->setUIVisibility(false);
+		LLPanelStandStopFlying::getInstance()->setVisible(false);
+	}
 }
 
 

File indra/newview/lldrawable.cpp

 			}
 		}
 	}
+	else if (!damped && isVisible())
+	{
+		dist_squared = dist_vec_squared(old_pos, target_pos);
+	}
 
 	LLVector3 vec = mCurrentScale-target_scale;
 	

File indra/newview/llfloaterimagepreview.cpp

 	{
 		gObjectPreviewProgram.bind();
 	}
+	gPipeline.enableLightsPreview();
+
 	gGL.pushMatrix();
 	const F32 SCALE = 1.25f;
 	gGL.scalef(SCALE, SCALE, SCALE);
 	const F32 BRIGHTNESS = 0.9f;
-	gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
+	gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
 
 	mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
 	mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);

File indra/newview/llfloatermodelpreview.cpp

 
 	U32 triangle_count = 0;
 
-	for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter)
-	{
-		LLModel* mdl = *iter;
-		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
+	U32 instanced_triangle_count = 0;
+
+	//get the triangle count for the whole scene
+	for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter)
+	{
+		for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
 		{
-			triangle_count += mdl->getVolumeFace(i).mNumIndices/3;
+			LLModel* mdl = instance->mModel;
+			if (mdl)
+			{
+				instanced_triangle_count += mdl->getNumTriangles();
+			}
 		}
 	}
 
+	//get the triangle count for the non-instanced set of models
+	for (U32 i = 0; i < mBaseModel.size(); ++i)
+	{
+		triangle_count += mBaseModel[i]->getNumTriangles();
+	}
+	
+	//get ratio of uninstanced triangles to instanced triangles
+	F32 triangle_ratio = (F32) triangle_count / (F32) instanced_triangle_count;
+
 	U32 base_triangle_count = triangle_count;
 
 	U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
 		if (which_lod > -1 && which_lod < NUM_LOD)
 		{
 			limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asInteger();
+			//convert from "scene wide" to "non-instanced" triangle limit
+			limit = (S32) ( (F32) limit*triangle_ratio );
 		}
 	}
 	else
 		U32 actual_verts = 0;
 		U32 submeshes = 0;
 
-		mRequestedTriangleCount[lod] = triangle_count;
+		mRequestedTriangleCount[lod] = (S32) ( (F32) triangle_count / triangle_ratio );
 		mRequestedErrorThreshold[lod] = lod_error_threshold;
 
 		glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode);
 		//initialize total for this lod to 0
 		total_tris[lod] = total_verts[lod] = total_submeshes[lod] = 0;
 
-		for (U32 i = 0; i < mModel[lod].size(); ++i)
-		{ //for each model in the lod
-			S32 cur_tris = 0;
-			S32 cur_verts = 0;
-			S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
-
-			for (S32 j = 0; j < cur_submeshes; ++j)
-			{ //for each submesh (face), add triangles and vertices to current total
-				const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
-				cur_tris += face.mNumIndices/3;
-				cur_verts += face.mNumVertices;
+		for (LLModelLoader::scene::iterator iter = mScene[lod].begin(), endIter = mScene[lod].end(); iter != endIter; ++iter)
+		{
+			for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
+			{
+				LLModel* model = instance->mModel;
+				if (model)
+				{
+					 //for each model in the lod
+					S32 cur_tris = 0;
+					S32 cur_verts = 0;
+					S32 cur_submeshes = model->getNumVolumeFaces();
+
+					for (S32 j = 0; j < cur_submeshes; ++j)
+					{ //for each submesh (face), add triangles and vertices to current total
+						const LLVolumeFace& face = model->getVolumeFace(j);
+						cur_tris += face.mNumIndices/3;
+						cur_verts += face.mNumVertices;
+					}
+
+					//add this model to the lod total
+					total_tris[lod] += cur_tris;
+					total_verts[lod] += cur_verts;
+					total_submeshes[lod] += cur_submeshes;
+
+					//store this model's counts to asset data
+					tris[lod].push_back(cur_tris);
+					verts[lod].push_back(cur_verts);
+					submeshes[lod].push_back(cur_submeshes);
+				}
 			}
-
-			//add this model to the lod total
-			total_tris[lod] += cur_tris;
-			total_verts[lod] += cur_verts;
-			total_submeshes[lod] += cur_submeshes;
-
-			//store this model's counts to asset data
-			tris[lod].push_back(cur_tris);
-			verts[lod].push_back(cur_verts);
-			submeshes[lod].push_back(cur_submeshes);
 		}
 	}
 
 	}
 	
 	//add up physics triangles etc
-	S32 start = 0;
-	S32 end = mModel[LLModel::LOD_PHYSICS].size();
-
 	S32 phys_tris = 0;
 	S32 phys_hulls = 0;
 	S32 phys_points = 0;
 
-	for (S32 i = start; i < end; ++i)
-	{ //add up hulls and points and triangles for selected mesh(es)
-		LLModel* model = mModel[LLModel::LOD_PHYSICS][i];
-		S32 cur_submeshes = model->getNumVolumeFaces();
-
-		LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull;
-
-		if (!decomp.empty())
+	//get the triangle count for the whole scene
+	for (LLModelLoader::scene::iterator iter = mScene[LLModel::LOD_PHYSICS].begin(), endIter = mScene[LLModel::LOD_PHYSICS].end(); iter != endIter; ++iter)
+	{
+		for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
 		{
-			phys_hulls += decomp.size();
-			for (U32 i = 0; i < decomp.size(); ++i)
+			LLModel* model = instance->mModel;
+			if (model)
 			{
-				phys_points += decomp[i].size();
-			}
-		}
-		else
-		{ //choose physics shape OR decomposition, can't use both
-			for (S32 j = 0; j < cur_submeshes; ++j)
-			{ //for each submesh (face), add triangles and vertices to current total
-				const LLVolumeFace& face = model->getVolumeFace(j);
-				phys_tris += face.mNumIndices/3;
+				S32 cur_submeshes = model->getNumVolumeFaces();
+
+				LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull;
+
+				if (!decomp.empty())
+				{
+					phys_hulls += decomp.size();
+					for (U32 i = 0; i < decomp.size(); ++i)
+					{
+						phys_points += decomp[i].size();
+					}
+				}
+				else
+				{ //choose physics shape OR decomposition, can't use both
+					for (S32 j = 0; j < cur_submeshes; ++j)
+					{ //for each submesh (face), add triangles and vertices to current total
+						const LLVolumeFace& face = model->getVolumeFace(j);
+						phys_tris += face.mNumIndices/3;
+					}
+				}
 			}
 		}
 	}
 		refresh();
 	}
 
+	if (use_shaders)
+	{
+		gObjectPreviewProgram.bind();
+	}
+
 	gGL.loadIdentity();
 	gPipeline.enableLightsPreview();
 
 
 	const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
 
-	if (use_shaders)
-	{
-		gObjectPreviewProgram.bind();
-	}
-
 	LLGLEnable normalize(GL_NORMALIZE);
 
 	if (!mBaseModel.empty() && mVertexBuffer[5].empty())
 											hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
 										}
 
-										glColor4ubv(hull_colors[i].mV);
+										gGL.diffuseColor4ubv(hull_colors[i].mV);
 										LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
 
 										if (explode > 0.f)

File indra/newview/llfloatertools.cpp

 	LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex());
 }
 
+// static
+void LLFloaterTools::setGridMode(S32 mode)
+{
+	LLFloaterTools* tools_floater = LLFloaterReg::getTypedInstance<LLFloaterTools>("build");
+	if (!tools_floater || !tools_floater->mComboGridMode)
+	{
+		return;
+	}
+
+	tools_floater->mComboGridMode->setCurrentByIndex(mode);
+}
 
 void LLFloaterTools::onClickGridOptions()
 {

File indra/newview/llfloatertools.h

 	bool selectedMediaEditable();
 	void updateLandImpacts();
 
+	static void setGridMode(S32 mode);
+
 private:
 	void refresh();
 	void refreshMedia();

File indra/newview/llfloaterurlentry.cpp

 	}
 
 	// Discover the MIME type only for "http" scheme.
-	if(scheme == "http" || scheme == "https")
+	if(!media_url.empty() && 
+	   (scheme == "http" || scheme == "https"))
 	{
 		LLHTTPClient::getHeaderOnly( media_url,
 			new LLMediaTypeResponder(self->getHandle()));

File indra/newview/llmanip.cpp

 	LLDrawable* drawablep = vobj->mDrawable;
 	if (drawablep && drawablep->getVOVolume())
 	{
-		
 		gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME, TRUE);
 		drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
 		drawablep->updateMove();
 			group->dirtyGeom();
 			gPipeline.markRebuild(group, TRUE);
 		}
+
+		LLViewerObject::const_child_list_t& child_list = vobj->getChildren();
+		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(), endIter = child_list.end();
+			 iter != endIter; ++iter)
+		{
+			LLViewerObject* child = *iter;
+			rebuild(child);
+		}
 	}
 }
 

File indra/newview/llmeshrepository.cpp

 {
 public:
 	LLVolumeParams mMeshParams;
-	
+	bool mProcessed;
+
 	LLMeshHeaderResponder(const LLVolumeParams& mesh_params)
 		: mMeshParams(mesh_params)
 	{
 		LLMeshRepoThread::sActiveHeaderRequests++;
+		mProcessed = false;
 	}
 
 	~LLMeshHeaderResponder()
 	{
+		llassert(mProcessed);
 		LLMeshRepoThread::sActiveHeaderRequests--;
 	}
 
 	S32 mLOD;
 	U32 mRequestedBytes;
 	U32 mOffset;
+	bool mProcessed;
 
 	LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes)
 		: mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes)
 	{
 		LLMeshRepoThread::sActiveLODRequests++;
+		mProcessed = false;
 	}
 
 	~LLMeshLODResponder()
 	{
+		llassert(mProcessed);
 		LLMeshRepoThread::sActiveLODRequests--;
 	}
 
 	LLUUID mMeshID;
 	U32 mRequestedBytes;
 	U32 mOffset;
+	bool mProcessed;
 
 	LLMeshSkinInfoResponder(const LLUUID& id, U32 offset, U32 size)
 		: mMeshID(id), mRequestedBytes(size), mOffset(offset)
 	{
+		mProcessed = false;
+	}
+
+	~LLMeshSkinInfoResponder()
+	{
+		llassert(mProcessed);
 	}
 
 	virtual void completedRaw(U32 status, const std::string& reason,
 	LLUUID mMeshID;
 	U32 mRequestedBytes;
 	U32 mOffset;
+	bool mProcessed;
 
 	LLMeshDecompositionResponder(const LLUUID& id, U32 offset, U32 size)
 		: mMeshID(id), mRequestedBytes(size), mOffset(offset)
 	{
+		mProcessed = false;
+	}
+
+	~LLMeshDecompositionResponder()
+	{
+		llassert(mProcessed);
 	}
 
 	virtual void completedRaw(U32 status, const std::string& reason,
 	LLUUID mMeshID;
 	U32 mRequestedBytes;
 	U32 mOffset;
+	bool mProcessed;
 
 	LLMeshPhysicsShapeResponder(const LLUUID& id, U32 offset, U32 size)
 		: mMeshID(id), mRequestedBytes(size), mOffset(offset)
 	{
+		mProcessed = false;
+	}
+
+	~LLMeshPhysicsShapeResponder()
+	{
+		llassert(mProcessed);
 	}
 
 	virtual void completedRaw(U32 status, const std::string& reason,
 		mModelData(model_data),
 		mObserverHandle(observer_handle)
 	{
+		if (mThread)
+		{
+			mThread->startRequest();
+		}
 	}
+
+	~LLWholeModelFeeResponder()
+	{
+		if (mThread)
+		{
+			mThread->stopRequest();
+		}
+	}
+
 	virtual void completed(U32 status,
 						   const std::string& reason,
 						   const LLSD& content)
 			cc = llsd_from_file("fake_upload_error.xml");
 		}
 			
-		mThread->mPendingUploads--;
 		dump_llsd_to_file(cc,make_dump_name("whole_model_fee_response_",dump_num));
 
 		LLWholeModelFeeObserver* observer = mObserverHandle.get();
 		mModelData(model_data),
 		mObserverHandle(observer_handle)
 	{
+		if (mThread)
+		{
+			mThread->startRequest();
+		}
 	}
+
+	~LLWholeModelUploadResponder()
+	{
+		if (mThread)
+		{
+			mThread->stopRequest();
+		}
+	}
+
 	virtual void completed(U32 status,
 						   const std::string& reason,
 						   const LLSD& content)
 			cc = llsd_from_file("fake_upload_error.xml");
 		}
 
-		mThread->mPendingUploads--;
 		dump_llsd_to_file(cc,make_dump_name("whole_model_upload_response_",dump_num));
 		
 		LLWholeModelUploadObserver* observer = mObserverHandle.get();
 			mCurlRequest->process();
 			//sleep for 10ms to prevent eating a whole core
 			apr_sleep(10000);
-		} while (!LLAppViewer::isQuitting() && mCurlRequest->getQueued() > 0);
+		} while (!LLAppViewer::isQuitting() && mPendingUploads > 0);
 	}
 
 	delete mCurlRequest;
 	wholeModelToLLSD(model_data,false);
 	dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num));
 
-	mPendingUploads++;
 	LLCurlRequest::headers_t headers;
 
 	{
 		mCurlRequest->process();
 		//sleep for 10ms to prevent eating a whole core
 		apr_sleep(10000);
-	} while (!LLApp::isQuitting() && mCurlRequest->getQueued() > 0);
+	} while (!LLApp::isQuitting() && mPendingUploads > 0);
 
 	delete mCurlRequest;
 	mCurlRequest = NULL;
 							  const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer)
 {
+	mProcessed = true;
 
 	S32 data_size = buffer->countAfter(channels.in(), NULL);
 
 	{
 		if (status == 499 || status == 503)
 		{ //timeout or service unavailable, try again
+			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
 			gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD);
 		}
 		else
 		{
+			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
 			llwarns << "Unhandled status " << status << llendl;
 		}
 		return;
 							  const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer)
 {
+	mProcessed = true;
+
 	S32 data_size = buffer->countAfter(channels.in(), NULL);
 
 	if (status < 200 || status > 400)
 	{
 		if (status == 499 || status == 503)
 		{ //timeout or service unavailable, try again
+			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
 			gMeshRepo.mThread->loadMeshSkinInfo(mMeshID);
 		}
 		else
 		{
+			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
 			llwarns << "Unhandled status " << status << llendl;
 		}
 		return;
 							  const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer)
 {
+	mProcessed = true;
+
 	S32 data_size = buffer->countAfter(channels.in(), NULL);
 
 	if (status < 200 || status > 400)
 	{
 		if (status == 499 || status == 503)
 		{ //timeout or service unavailable, try again
+			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
 			gMeshRepo.mThread->loadMeshDecomposition(mMeshID);
 		}
 		else
 		{
+			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
 			llwarns << "Unhandled status " << status << llendl;
 		}
 		return;
 							  const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer)
 {
+	mProcessed = true;
+
 	S32 data_size = buffer->countAfter(channels.in(), NULL);
 
 	if (status < 200 || status > 400)
 	{
 		if (status == 499 || status == 503)
 		{ //timeout or service unavailable, try again
+			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
 			gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID);
 		}
 		else
 		{
+			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
 			llwarns << "Unhandled status " << status << llendl;
 		}
 		return;
 							  const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer)
 {
+	mProcessed = true;
+
 	if (status < 200 || status > 400)
 	{
 		//llwarns
 		// TODO*: Add maximum retry logic, exponential backoff
 		// and (somewhat more optional than the others) retries
 		// again after some set period of time
+
+		llassert(status == 503 || status == 499);
+
 		if (status == 503 || status == 499)
 		{ //retry
+			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
 			LLMeshRepoThread::HeaderRequest req(mMeshParams);
 			LLMutexLock lock(gMeshRepo.mThread->mMutex);
 
 			return;
 		}
+		else
+		{
+			llwarns << "Unhandled status." << llendl;
+		}
 	}
 
 	S32 data_size = buffer->countAfter(channels.in(), NULL);
 
 	LLMeshRepository::sBytesReceived += llmin(data_size, 4096);
 
-	if (!gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size))
+	bool success = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
+	
+	llassert(success);
+
+	if (!success)
 	{
 		llwarns
 			<< "Unable to parse mesh header: "

File indra/newview/llmeshrepository.h

 					   LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>()));
 	~LLMeshUploadThread();
 
+	void startRequest() { ++mPendingUploads; }
+	void stopRequest() { --mPendingUploads; }
+
 	bool finished() { return mFinished; }
 	virtual void run();
 	void preStart();

File indra/newview/llpanelpermissions.cpp

 		}
 	}
 	
-	getChildView("button set group")->setEnabled(owners_identical && (mOwnerID == gAgent.getID()) && is_nonpermanent_enforced);
+	getChildView("button set group")->setEnabled(root_selected && owners_identical && (mOwnerID == gAgent.getID()) && is_nonpermanent_enforced);
 
 	getChildView("Name:")->setEnabled(TRUE);
 	LLLineEditor* LineEditorObjectName = getChild<LLLineEditor>("Object Name");

File indra/newview/llselectmgr.cpp

 
 	mGridMode = GRID_MODE_WORLD;
 	gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD);
-	mGridValid = FALSE;
 
 	mSelectedObjects = new LLObjectSelection();
 	mHoverObjects = new LLObjectSelection();
 	mGridMode = mode;
 	gSavedSettings.setS32("GridMode", mode);
 	updateSelectionCenter();
-	mGridValid = FALSE;
 }
 
 void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale)
 	origin = mGridOrigin;
 	rotation = mGridRotation;
 	scale = mGridScale;
-	mGridValid = TRUE;
 }
 
 //-----------------------------------------------------------------------------
 	return TRUE;
 }
 
-//-----------------------------------------------------------------------------
-// selectGetCreator()
-// Creator information only applies to root objects.
-//-----------------------------------------------------------------------------
-BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name)
-{
-	BOOL identical = TRUE;
-	BOOL first = TRUE;
-	LLUUID first_id;
-	for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
-		 iter != getSelection()->root_object_end(); iter++ )
-	{
-		LLSelectNode* node = *iter;	
-		if (!node->mValid)
-		{
-			return FALSE;
-		}
-
-		if (first)
-		{
-			first_id = node->mPermissions->getCreator();
-			first = FALSE;
+struct LLSelectGetFirstTest
+{
+	LLSelectGetFirstTest() : mIdentical(true), mFirst(true)	{ }
+	virtual ~LLSelectGetFirstTest() { }
+
+	// returns false to break out of the iteration.
+	bool checkMatchingNode(LLSelectNode* node)
+	{
+		if (!node || !node->mValid)
+		{
+			return false;
+		}
+
+		if (mFirst)
+		{
+			mFirstValue = getValueFromNode(node);
+			mFirst = false;
 		}
 		else
 		{
-			if ( !(first_id == node->mPermissions->getCreator() ) )
+			if ( mFirstValue != getValueFromNode(node) )
 			{
-				identical = FALSE;
+				mIdentical = false;
+				// stop testing once we know not all selected are identical.
+				return false;
+			}
+		}
+		// continue testing.
+		return true;
+	}
+
+	bool mIdentical;
+	LLUUID mFirstValue;
+
+protected:
+	virtual const LLUUID& getValueFromNode(LLSelectNode* node) = 0;
+
+private:
+	bool mFirst;
+};
+
+void LLSelectMgr::getFirst(LLSelectGetFirstTest* test)
+{
+	if (gSavedSettings.getBOOL("EditLinkedParts"))
+	{
+		for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();
+			iter != getSelection()->valid_end(); ++iter )
+		{
+			if (!test->checkMatchingNode(*iter))
+			{
 				break;
 			}
 		}
 	}
-	if (first_id.isNull())
+	else
+	{
+		for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
+			iter != getSelection()->root_object_end(); ++iter )
+		{
+			if (!test->checkMatchingNode(*iter))
+			{
+				break;
+			}
+		}
+	}
+}
+
+//-----------------------------------------------------------------------------
+// selectGetCreator()
+// Creator information only applies to roots unless editing linked parts.
+//-----------------------------------------------------------------------------
+struct LLSelectGetFirstCreator : public LLSelectGetFirstTest
+{
+protected:
+	virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+	{
+		return node->mPermissions->getCreator();
+	}
+};
+
+BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name)
+{
+	LLSelectGetFirstCreator test;
+	getFirst(&test);
+
+	if (test.mFirstValue.isNull())
 	{
 		name = LLTrans::getString("AvatarNameNobody");
 		return FALSE;
 	}
 	
-	result_id = first_id;
+	result_id = test.mFirstValue;
 	
-	if (identical)
-	{
-		name = LLSLURL("agent", first_id, "inspect").getSLURLString();
+	if (test.mIdentical)
+	{
+		name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
 	}
 	else
 	{
 		name = LLTrans::getString("AvatarNameMultiple");
 	}
 
-	return identical;
-}
-
+	return test.mIdentical;
+}
 
 //-----------------------------------------------------------------------------
 // selectGetOwner()
-// Owner information only applies to roots.
-//-----------------------------------------------------------------------------
+// Owner information only applies to roots unless editing linked parts.
+//-----------------------------------------------------------------------------
+struct LLSelectGetFirstOwner : public LLSelectGetFirstTest
+{
+protected:
+	virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+	{
+		// Don't use 'getOwnership' since we return a reference, not a copy.
+		// Will return LLUUID::null if unowned (which is not allowed and should never happen.)
+		return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner();
+	}
+};
+
 BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name)
 {
-	BOOL identical = TRUE;
-	BOOL first = TRUE;
-	BOOL first_group_owned = FALSE;
-	LLUUID first_id;
-	for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
-		 iter != getSelection()->root_object_end(); iter++ )
-	{
-		LLSelectNode* node = *iter;	
-		if (!node->mValid)
-		{
-			return FALSE;
-		}
-		
-		if (first)
-		{
-			node->mPermissions->getOwnership(first_id, first_group_owned);
-			first = FALSE;
+	LLSelectGetFirstOwner test;
+	getFirst(&test);
+
+	if (test.mFirstValue.isNull())
+	{
+		return FALSE;
+	}
+
+	result_id = test.mFirstValue;
+	
+	if (test.mIdentical)
+	{
+		bool group_owned = selectIsGroupOwned();
+		if (group_owned)
+		{
+			name = LLSLURL("group", test.mFirstValue, "inspect").getSLURLString();
 		}
 		else
 		{
-			LLUUID owner_id;
-			BOOL is_group_owned = FALSE;
-			if (!(node->mPermissions->getOwnership(owner_id, is_group_owned))
-				|| owner_id != first_id || is_group_owned != first_group_owned)
-			{
-				identical = FALSE;
-				break;
-			}
-		}
-	}
-	if (first_id.isNull())
+			name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
+		}
+	}
+	else
+	{
+		name = LLTrans::getString("AvatarNameMultiple");
+	}
+
+	return test.mIdentical;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetLastOwner()
+// Owner information only applies to roots unless editing linked parts.
+//-----------------------------------------------------------------------------
+struct LLSelectGetFirstLastOwner : public LLSelectGetFirstTest
+{
+protected:
+	virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+	{
+		return node->mPermissions->getLastOwner();
+	}
+};
+
+BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name)
+{
+	LLSelectGetFirstLastOwner test;
+	getFirst(&test);
+
+	if (test.mFirstValue.isNull())
 	{
 		return FALSE;
 	}
 
-	result_id = first_id;
+	result_id = test.mFirstValue;
 	
-	if (identical)
-	{
-		BOOL public_owner = (first_id.isNull() && !first_group_owned);
-		if (first_group_owned)
-		{
-			name = LLSLURL("group", first_id, "inspect").getSLURLString();
-		}
-		else if(!public_owner)
-		{
-			name = LLSLURL("agent", first_id, "inspect").getSLURLString();
-		}
-		else
-		{
-			name = LLTrans::getString("AvatarNameNobody");
-		}
+	if (test.mIdentical)
+	{
+		name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
 	}
 	else
 	{
-		name = LLTrans::getString("AvatarNameMultiple");
-	}
-
-	return identical;
-}
-
-
-//-----------------------------------------------------------------------------
-// selectGetLastOwner()
-// Owner information only applies to roots.
-//-----------------------------------------------------------------------------
-BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name)
-{
-	BOOL identical = TRUE;
-	BOOL first = TRUE;
-	LLUUID first_id;
-	for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
-		 iter != getSelection()->root_object_end(); iter++ )
-	{
-		LLSelectNode* node = *iter;	
-		if (!node->mValid)
-		{
-			return FALSE;
-		}
-
-		if (first)
-		{
-			first_id = node->mPermissions->getLastOwner();
-			first = FALSE;
-		}
-		else
-		{
-			if ( !(first_id == node->mPermissions->getLastOwner() ) )
-			{
-				identical = FALSE;
-				break;
-			}
-		}
-	}
-	if (first_id.isNull())
-	{
-		return FALSE;
-	}
-
-	result_id = first_id;
-	
-	if (identical)
-	{
-		BOOL public_owner = (first_id.isNull());
-		if(!public_owner)
-		{
-			name = LLSLURL("agent", first_id, "inspect").getSLURLString();
-		}
-		else
-		{
-			name.assign("Public or Group");
-		}
-	}
-	else
-	{
 		name.assign( "" );
 	}
 
-	return identical;
-}
-
+	return test.mIdentical;
+}
 
 //-----------------------------------------------------------------------------
 // selectGetGroup()
-// Group information only applies to roots.
-//-----------------------------------------------------------------------------
+// Group information only applies to roots unless editing linked parts.
+//-----------------------------------------------------------------------------
+struct LLSelectGetFirstGroup : public LLSelectGetFirstTest
+{
+protected:
+	virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+	{
+		return node->mPermissions->getGroup();
+	}
+};
+
 BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id)
 {
-	BOOL identical = TRUE;
-	BOOL first = TRUE;
-	LLUUID first_id;
-	for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
-		 iter != getSelection()->root_object_end(); iter++ )
-	{
-		LLSelectNode* node = *iter;	
-		if (!node->mValid)
-		{
-			return FALSE;
-		}
-
-		if (first)
-		{
-			first_id = node->mPermissions->getGroup();
-			first = FALSE;
-		}
-		else
-		{
-			if ( !(first_id == node->mPermissions->getGroup() ) )
-			{
-				identical = FALSE;
-				break;
-			}
-		}
-	}
-
-	result_id = first_id;
-
-	return identical;
+	LLSelectGetFirstGroup test;
+	getFirst(&test);
+
+	result_id = test.mFirstValue;
+	return test.mIdentical;
 }
 
 //-----------------------------------------------------------------------------
 // selectIsGroupOwned()
-// Only operates on root nodes.  
-// Returns TRUE if all have valid data and they are all group owned.
-//-----------------------------------------------------------------------------
+// Only operates on root nodes unless editing linked parts.  
+// Returns TRUE if the first selected is group owned.
+//-----------------------------------------------------------------------------
+struct LLSelectGetFirstGroupOwner : public LLSelectGetFirstTest
+{
+protected:
+	virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+	{
+		if (node->mPermissions->isGroupOwned())
+		{
+			return node->mPermissions->getGroup();
+		}
+		return LLUUID::null;
+	}
+};
+
 BOOL LLSelectMgr::selectIsGroupOwned()
 {
-	BOOL found_one = FALSE;
-	for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
-		 iter != getSelection()->root_object_end(); iter++ )
-	{
-		LLSelectNode* node = *iter;	
-		if (!node->mValid)
-		{
-			return FALSE;
-		}
-		found_one = TRUE;
-		if (!node->mPermissions->isGroupOwned())
-		{
-			return FALSE;
-		}
-	}	
-	return found_one ? TRUE : FALSE;
+	LLSelectGetFirstGroupOwner test;
+	getFirst(&test);
+
+	return test.mFirstValue.notNull() ? TRUE : FALSE;
 }
 
 //-----------------------------------------------------------------------------
 		} func(id);
 		LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
 
-		if (node)
+		if (!node)
+		{
+			llwarns << "Couldn't find object " << id << " selected." << llendl;
+		}
+		else
 		{
 			if (node->mInventorySerial != inv_serial)
 			{

File indra/newview/llselectmgr.h

 extern template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance();
 #endif
 
+// For use with getFirstTest()
+struct LLSelectGetFirstTest;
+
 class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 {
 public:
 	static void packGodlikeHead(void* user_data);
 	static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle);
 
+	// Get the first ID that matches test and whether or not all ids are identical in selected objects.
+	void getFirst(LLSelectGetFirstTest* test);
+
 public:
 	// Observer/callback support for when object selection changes or
 	// properties are received/updated
 	LLVector3				mGridOrigin;
 	LLVector3				mGridScale;
 	EGridMode				mGridMode;
-	BOOL					mGridValid;
-
 
 	BOOL					mTEMode;			// render te
 	LLVector3d				mSelectionCenterGlobal;

File indra/newview/llviewermedia.cpp

 	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
 	{
 		LL_WARNS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL;
-		LL_WARNS("MediaAuth") << content << LL_ENDL;
+
+		LLSD stripped_content = content;
+		stripped_content.erase("set-cookie");
+		LL_WARNS("MediaAuth") << stripped_content << LL_ENDL;
 
 		std::string cookie = content["set-cookie"].asString();
+		LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
 
 		LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost);
 

File indra/newview/llviewermenu.cpp

 };
 
 
+//////////////////////////
+//   ANIMATION SPEED    //
+//////////////////////////
+
+// Utility function to set all AV time factors to the same global value
+static void set_all_animation_time_factors(F32	time_factor)
+{
+	LLMotionController::setCurrentTimeFactor(time_factor);
+	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+		iter != LLCharacter::sInstances.end(); ++iter)
+	{
+		(*iter)->setAnimTimeFactor(time_factor);
+	}
+}
+
+class LLAdvancedAnimTenFaster : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		//llinfos << "LLAdvancedAnimTenFaster" << llendl;
+		F32 time_factor = LLMotionController::getCurrentTimeFactor();
+		time_factor = llmin(time_factor + 0.1f, 2.f);	// Upper limit is 200% speed
+		set_all_animation_time_factors(time_factor);
+		return true;
+	}
+};
+
+class LLAdvancedAnimTenSlower : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		//llinfos << "LLAdvancedAnimTenSlower" << llendl;
+		F32 time_factor = LLMotionController::getCurrentTimeFactor();
+		time_factor = llmax(time_factor - 0.1f, 0.1f);	// Lower limit is at 10% of normal speed
+		set_all_animation_time_factors(time_factor);
+		return true;
+	}
+};
+
+class LLAdvancedAnimResetAll : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		set_all_animation_time_factors(1.f);
+		return true;
+	}
+};
+
 
 //////////////////////////
 // RELOAD VERTEX SHADER //
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		LLNotification::Params params("ConfirmHideUI");
-		params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2));
-		LLSD substitutions;
+		if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+		{
+			LLNotification::Params params("ConfirmHideUI");
+			params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2));
+			LLSD substitutions;
 #if LL_DARWIN
-		substitutions["SHORTCUT"] = "Cmd+Shift+U";
+			substitutions["SHORTCUT"] = "Cmd+Shift+U";
 #else
-		substitutions["SHORTCUT"] = "Ctrl+Shift+U";
+			substitutions["SHORTCUT"] = "Ctrl+Shift+U";
 #endif
-		params.substitutions = substitutions;
-		if (gViewerWindow->getUIVisibility())
-		{
-			// hiding, so show notification
-			LLNotifications::instance().add(params);
-		}
-		else
-		{
-			LLNotifications::instance().forceResponse(params, 0);
-		}
-
+			params.substitutions = substitutions;
+			if (!gSavedSettings.getBOOL("HideUIControls"))
+			{
+				// hiding, so show notification
+				LLNotifications::instance().add(params);
+			}
+			else
+			{
+				LLNotifications::instance().forceResponse(params, 0);
+			}
+		}
 		return true;
 	}
 
 
 		if (option == 0) // OK
 		{
-			gViewerWindow->setUIVisibility(!gViewerWindow->getUIVisibility());
-			LLPanelStandStopFlying::getInstance()->setVisible(gViewerWindow->getUIVisibility());
+			gViewerWindow->setUIVisibility(gSavedSettings.getBOOL("HideUIControls"));
+			LLPanelStandStopFlying::getInstance()->setVisible(gSavedSettings.getBOOL("HideUIControls"));
+			gSavedSettings.setBOOL("HideUIControls",!gSavedSettings.getBOOL("HideUIControls"));
 		}
 	}
 };
 		} func;
 		LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);
 		LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT);
+		LLFloaterTools::setGridMode((S32)GRID_MODE_REF_OBJECT);
 		return true;
 	}
 };
 	view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale");
 	view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale");
 	
+	// Advanced > Character > Animation Speed
+	view_listener_t::addMenu(new LLAdvancedAnimTenFaster(), "Advanced.AnimTenFaster");
+	view_listener_t::addMenu(new LLAdvancedAnimTenSlower(), "Advanced.AnimTenSlower");
+	view_listener_t::addMenu(new LLAdvancedAnimResetAll(), "Advanced.AnimResetAll");
+
 	// Advanced > Character (toplevel)
 	view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault");
 	view_listener_t::addMenu(new LLAdvancedReloadVertexShader(), "Advanced.ReloadVertexShader");

File indra/newview/llviewershadermgr.cpp

 	{
 		gObjectPreviewProgram.mName = "Simple Shader";
 		gObjectPreviewProgram.mFeatures.calculatesLighting = true;
-		gObjectPreviewProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false;
 		gObjectPreviewProgram.mFeatures.hasGamma = true;
-		gObjectPreviewProgram.mFeatures.hasAtmospherics = true;
+		gObjectPreviewProgram.mFeatures.hasAtmospherics = false;
 		gObjectPreviewProgram.mFeatures.hasLighting = true;
 		gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
 		gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
 		gObjectPreviewProgram.mShaderFiles.clear();
 		gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB));
-		gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gObjectPreviewProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
 		success = gObjectPreviewProgram.createShader(NULL, NULL);
 	}

File indra/newview/pipeline.cpp

 	
 	LLVector4 light_pos(dir0, 0.0f);
 
-	LLLightState* light = gGL.getLight(0);
+	LLLightState* light = gGL.getLight(1);
 
 	light->enable();
 	light->setPosition(light_pos);
 
 	light_pos = LLVector4(dir1, 0.f);
 
-	light = gGL.getLight(1);
+	light = gGL.getLight(2);
 	light->enable();
 	light->setPosition(light_pos);
 	light->setDiffuse(diffuse1);
 	light->setSpotCutoff(180.f);
 
 	light_pos = LLVector4(dir2, 0.f);
-	light = gGL.getLight(2);
+	light = gGL.getLight(3);
 	light->enable();
 	light->setPosition(light_pos);
 	light->setDiffuse(diffuse2);

File indra/newview/skins/default/xui/en/menu_inventory_add.xml

  layout="topleft"
  left="0"
  mouse_opaque="false"
- can_tear_off="true"
+ can_tear_off="false"
  name="menu_inventory_add"
  visible="false">
             <menu

File indra/newview/skins/default/xui/en/menu_viewer.xml

                      parameter="AllowSelectAvatar" />
                 </menu_item_check>
             </menu>
+            <menu
+             create_jump_keys="true"
+             label="Animation Speed"
+             name="Animation Speed"
+             tear_off="true">
+                <menu_item_call
+                 label="All Animations 10% Faster"
+                 name="All Animations 10 Faster">
+                    <menu_item_call.on_click
+                     function="Advanced.AnimTenFaster" />
+                </menu_item_call>
+                <menu_item_call
+                 label="All Animations 10% Slower"
+                 name="All Animations 10 Slower">
+                    <menu_item_call.on_click
+                     function="Advanced.AnimTenSlower" />
+                </menu_item_call>
+                <menu_item_call
+                 label="Reset All Animation Speed"
+                 name="Reset All Animation Speed">
+                    <menu_item_call.on_click
+                     function="Advanced.AnimResetAll" />
+                </menu_item_call>
+				<menu_item_check
+				 label="Slow Motion Animations"
+				 name="Slow Motion Animations">
+					<menu_item_check.on_check
+					 function="CheckControl"
+					 parameter="SlowMotionAnimation" />
+					<menu_item_check.on_click
+					 function="ToggleControl"
+					 parameter="SlowMotionAnimation" />
+				</menu_item_check>
+            </menu>
             <menu_item_call
              label="Force Params to Default"
              name="Force Params to Default">
                  parameter="" />
             </menu_item_check>
             <menu_item_check
-             label="Slow Motion Animations"
-             name="Slow Motion Animations">
-                <menu_item_check.on_check
-                 function="CheckControl"
-                 parameter="SlowMotionAnimation" />
-                <menu_item_check.on_click
-                 function="ToggleControl"
-                 parameter="SlowMotionAnimation" />
-            </menu_item_check>
-            <menu_item_check
              label="Show Look At"
              name="Show Look At">
                 <menu_item_check.on_check

File indra/newview/skins/default/xui/en/notifications.xml

 An internal error prevented us from properly updating your viewer.  The L$ balance or parcel holdings displayed in your viewer may not reflect your actual balance on the servers.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="LargePrimAgentIntersect"
+   type="notify">
+   <tag>fail</tag>
+Cannot create large prims that intersect other players.  Please re-try when other players have moved.
+  </notification>
 
 </notifications>