From 54dd30cc426e16aa99b4f7eea080bbeae0656843 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 15 Apr 2010 00:04:17 -0500
Subject: More rigged attachments work.

---
 indra/newview/lldrawpoolavatar.cpp |  3 ++-
 indra/newview/llvoavatar.cpp       | 12 +++++++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index de9b71a9b8..1a2558ac5f 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -325,7 +325,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
 
 S32 LLDrawPoolAvatar::getNumPasses()
 {
-	return LLPipeline::sImpostorRender ? 1 : 3;
+	return LLPipeline::sImpostorRender ? 1 : 4;
 }
 
 void LLDrawPoolAvatar::render(S32 pass)
@@ -588,6 +588,7 @@ void LLDrawPoolAvatar::beginRigged()
 void LLDrawPoolAvatar::endRigged()
 {
 	sVertexProgram = NULL;
+	LLVertexBuffer::unbind();
 	gSkinnedObjectSimpleProgram.unbind();
 	LLVertexBuffer::sWeight4Loc = -1;
 }
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 201c4ce1d5..8bf4c0ab96 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3728,8 +3728,8 @@ U32 LLVOAvatar::renderSkinnedAttachments()
 										LLJoint* joint = getJoint(skin->mJointNames[i]);
 										if (joint)
 										{
-											mat[i] = skin->mInvBindMatrix[i];
-											mat[i] *= joint->getWorldMatrix();
+											mat[i*2+0] = skin->mInvBindMatrix[i];
+											mat[i*2+1] = joint->getWorldMatrix();
 										}
 									}
 									
@@ -3737,6 +3737,10 @@ U32 LLVOAvatar::renderSkinnedAttachments()
 										skin->mJointNames.size(),
 										FALSE,
 										(GLfloat*) mat[0].mMatrix);
+									gSkinnedObjectSimpleProgram.uniformMatrix4fv("matrixPalette[0]", 
+										skin->mJointNames.size(),
+										FALSE,
+										(GLfloat*) mat[0].mMatrix);
 
 									buff->setBuffer(data_mask);
 
@@ -3745,7 +3749,9 @@ U32 LLVOAvatar::renderSkinnedAttachments()
 									S32 offset = face->getIndicesStart();
 									U32 count = face->getIndicesCount();
 
-									buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+									glPointSize(8.f);
+									buff->drawRange(LLRender::POINTS, start, end, count, offset);
+									glPointSize(1.f);
 								}
 							}
 						}
-- 
cgit v1.2.3


From b0554832e2cffac344590bf49897119e72d142cb Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 15 Apr 2010 00:06:53 -0500
Subject: Quick port of fix for avatar mesh rebuilding bug from viewer-hotfix.

---
 indra/newview/llvoavatarself.cpp | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index c15dbeb8c6..8b87254f81 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -697,15 +697,6 @@ BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL
 /*virtual*/ 
 void LLVOAvatarSelf::updateVisualParams()
 {
-	for (U32 type = 0; type < WT_COUNT; type++)
-	{
-		LLWearable *wearable = gAgentWearables.getTopWearable((EWearableType)type);
-		if (wearable)
-		{
-			wearable->writeToAvatar();
-		}
-	}
-
 	LLVOAvatar::updateVisualParams();
 }
 
@@ -716,7 +707,14 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
 	gAgentWearables.animateAllWearableParams(calcMorphAmount(), FALSE);
 
 	// apply wearable visual params to avatar
-	updateVisualParams();
+	for (U32 type = 0; type < WT_COUNT; type++)
+	{
+		LLWearable *wearable = gAgentWearables.getTopWearable((EWearableType)type);
+		if (wearable)
+		{
+			wearable->writeToAvatar();
+		}
+	}
 
 	//allow avatar to process updates
 	LLVOAvatar::idleUpdateAppearanceAnimation();
-- 
cgit v1.2.3


From 71b0a63c8df29d5d69b777306dcf6280fd98886a Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 16 Apr 2010 13:00:01 -0500
Subject: Optimize LLViewerJointMesh::updateFaceData

---
 indra/newview/lldrawpoolavatar.cpp  |  2 +-
 indra/newview/llviewerjointmesh.cpp | 88 +++++++++++++++++++++++++++++--------
 2 files changed, 70 insertions(+), 20 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 7ab85ae3e4..b509b363b7 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -123,7 +123,7 @@ void LLDrawPoolAvatar::prerender()
 	
 	if (sShaderLevel > 0)
 	{
-		sBufferUsage = GL_STATIC_DRAW_ARB;
+		sBufferUsage = GL_DYNAMIC_DRAW_ARB;
 	}
 	else
 	{
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 92029d10f6..90a5a29bb4 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -661,6 +661,8 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32
 //-----------------------------------------------------------------------------
 // updateFaceData()
 //-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_AVATAR_FACE("Avatar Face");
+
 void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind)
 {
 	mFace = face;
@@ -670,6 +672,8 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
 		return;
 	}
 
+	LLFastTimer t(FTM_AVATAR_FACE);
+
 	LLStrider<LLVector3> verticesp;
 	LLStrider<LLVector3> normalsp;
 	LLStrider<LLVector2> tex_coordsp;
@@ -688,30 +692,76 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
 			face->mVertexBuffer->getIndexStrider(indicesp);
 			stop_glerror();
 
-			for (U16 i = 0; i < mMesh->getNumVertices(); i++)
+			verticesp += mMesh->mFaceVertexOffset;
+			tex_coordsp += mMesh->mFaceVertexOffset;
+			normalsp += mMesh->mFaceVertexOffset;
+			vertex_weightsp += mMesh->mFaceVertexOffset;
+			clothing_weightsp += mMesh->mFaceVertexOffset;
+
+			U32* __restrict v = (U32*) verticesp.get();
+			const U32 vert_skip = verticesp.getSkip()/sizeof(U32);
+
+			U32* __restrict tc = (U32*) tex_coordsp.get();
+			const U32 tc_skip = tex_coordsp.getSkip()/sizeof(U32);
+
+			U32* __restrict n = (U32*) normalsp.get();
+			const U32 n_skip = normalsp.getSkip()/sizeof(U32);
+			
+			U32* __restrict vw = (U32*) vertex_weightsp.get();
+			const U32 vw_skip = vertex_weightsp.getSkip()/sizeof(U32);
+
+
+			U32* __restrict cw = (U32*) clothing_weightsp.get();
+			const U32 cw_skip = vertex_weightsp.getSkip()/sizeof(U32);
+
+			const U32* __restrict coords = (U32*) mMesh->getCoords();
+			const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords();
+			const U32* __restrict normals = (U32*) mMesh->getNormals();
+			const U32* __restrict weights = (U32*) mMesh->getWeights();
+			const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights();
+
+			const U32 num_verts = mMesh->getNumVertices();
+
+			U32 i = 0;
+			do
 			{
-				verticesp[mMesh->mFaceVertexOffset + i] = *(mMesh->getCoords() + i);
-				tex_coordsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getTexCoords() + i);
-				normalsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getNormals() + i);
-				vertex_weightsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getWeights() + i);
-				if (damp_wind)
-				{
-					clothing_weightsp[mMesh->mFaceVertexOffset + i] = LLVector4(0,0,0,0);
-				}
-				else
-				{
-					clothing_weightsp[mMesh->mFaceVertexOffset + i] = (*(mMesh->getClothingWeights() + i));
-				}
+				v[0] = *(coords++); 
+				v[1] = *(coords++); 
+				v[2] = *(coords++);
+				v += vert_skip;
+
+				tc[0] = *(tex_coords++); 
+				tc[1] = *(tex_coords++);
+				tc += tc_skip;
+
+				n[0] = *(normals++); 
+				n[1] = *(normals++);
+				n[2] = *(normals++);
+				n += n_skip;
+
+				vw[0] = *(weights++);
+				vw += vw_skip;
+
+				cw[0] = *(cloth_weights++);
+				cw[1] = *(cloth_weights++);
+				cw[2] = *(cloth_weights++);
+				cw[3] = *(cloth_weights++);
+				cw += cw_skip;
 			}
+			while (++i < num_verts);
+
+			const U32 idx_count = mMesh->getNumFaces()*3;
 
-			for (S32 i = 0; i < mMesh->getNumFaces(); i++)
+			U16* __restrict idx = indicesp.get();
+			S32* __restrict src_idx = (S32*) mMesh->getFaces();
+
+			i = 0;
+
+			do
 			{
-				for (U32 j = 0; j < 3; j++)
-				{
-					U32 k = i*3+j+mMesh->mFaceIndexOffset;
-					indicesp[k] = mMesh->getFaces()[i][j] + mMesh->mFaceVertexOffset;
-				}
+				*(idx++) = *(src_idx++);
 			}
+			while (++i < idx_count);
 		}
 	}
 }
-- 
cgit v1.2.3


From 12499cebcba81175ae5d92926f5ec89632f00926 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 16 Apr 2010 15:53:26 -0500
Subject: Fix for busted optimizations.

---
 indra/newview/lldrawpoolavatar.cpp  | 4 +---
 indra/newview/llviewerjointmesh.cpp | 6 +++++-
 2 files changed, 6 insertions(+), 4 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index b509b363b7..b3942d559a 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -881,9 +881,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
 
 LLVertexBufferAvatar::LLVertexBufferAvatar()
 : LLVertexBuffer(sDataMask, 
-	LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 ?	
-	GL_DYNAMIC_DRAW_ARB : 
-	GL_STREAM_DRAW_ARB)
+	GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets
 {
 
 }
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 90a5a29bb4..db2279d925 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -752,14 +752,18 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
 
 			const U32 idx_count = mMesh->getNumFaces()*3;
 
+			indicesp += mMesh->mFaceIndexOffset;
+
 			U16* __restrict idx = indicesp.get();
 			S32* __restrict src_idx = (S32*) mMesh->getFaces();
 
 			i = 0;
 
+			const S32 offset = (S32) mMesh->mFaceVertexOffset;
+
 			do
 			{
-				*(idx++) = *(src_idx++);
+				*(idx++) = *(src_idx++)+offset;
 			}
 			while (++i < idx_count);
 		}
-- 
cgit v1.2.3


From 8b88b093b9b59ba530e5e716609390fd00015efa Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 19 Apr 2010 23:31:38 -0500
Subject: Fix for ridiculous bug that causes all sitting avatars to rebuild
 their geometry every frame.

---
 indra/newview/lldrawable.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 390e950d75..03eee12707 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -533,7 +533,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
 		{
 			// snap to final position
 			dist_squared = 0.0f;
-			if (!isRoot())
+			if (getVOVolume() && !isRoot())
 			{ //child prim snapping to some position, needs a rebuild
 				gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
 			}
-- 
cgit v1.2.3


From 1651dd9c5b98923716a80ea476ec47360748f343 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 19 Apr 2010 23:32:27 -0500
Subject: Remove foot shadows, renaming foot shadow pass to impostor pass.

---
 indra/newview/lldrawpoolavatar.cpp | 12 ++++--------
 indra/newview/lldrawpoolavatar.h   |  4 ++--
 2 files changed, 6 insertions(+), 10 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index b3942d559a..c4581b2c78 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -353,7 +353,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
 	switch (pass)
 	{
 	case 0:
-		beginFootShadow();
+		beginImpostor();
 		break;
 	case 1:
 		beginRigid();
@@ -380,7 +380,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
 	switch (pass)
 	{
 	case 0:
-		endFootShadow();
+		endImpostor();
 		break;
 	case 1:
 		endRigid();
@@ -394,7 +394,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
 	}
 }
 
-void LLDrawPoolAvatar::beginFootShadow()
+void LLDrawPoolAvatar::beginImpostor()
 {
 	if (!LLPipeline::sReflectionRender)
 	{
@@ -406,7 +406,7 @@ void LLDrawPoolAvatar::beginFootShadow()
 	diffuse_channel = 0;
 }
 
-void LLDrawPoolAvatar::endFootShadow()
+void LLDrawPoolAvatar::endImpostor()
 {
 	gPipeline.enableLightsDynamic();
 }
@@ -718,10 +718,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 			}
 			avatarp->renderImpostor(LLColor4U(255,255,255,255), diffuse_channel);
 		}
-		else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred)
-		{
-			avatarp->renderFootShadows();	
-		}
 		return;
 	}
 
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index c43aa9b1e3..45f694ccd9 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -88,12 +88,12 @@ public:
 	/*virtual*/ void renderShadow(S32 pass);
 
 	void beginRigid();
-	void beginFootShadow();
+	void beginImpostor();
 	void beginSkinned();
 	void beginRigged();
 		
 	void endRigid();
-	void endFootShadow();
+	void endImpostor();
 	void endSkinned();
 	void endRigged();
 
-- 
cgit v1.2.3


From e994b9dcee82b510dc881e2b14d053a27fe35472 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 19 Apr 2010 23:33:34 -0500
Subject: Remove foot shadows from llvoavatar and add terse update to
 LLViewerJointMesh::updateFaceData.

---
 indra/newview/llviewerjoint.cpp     |   4 +-
 indra/newview/llviewerjoint.h       |   2 +-
 indra/newview/llviewerjointmesh.cpp | 121 +++++++++++--------
 indra/newview/llviewerjointmesh.h   |   2 +-
 indra/newview/llvoavatar.cpp        | 231 ++++++------------------------------
 indra/newview/llvoavatar.h          |   5 +-
 6 files changed, 110 insertions(+), 255 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index 95f05b5f5f..8f2006b431 100644
--- a/indra/newview/llviewerjoint.cpp
+++ b/indra/newview/llviewerjoint.cpp
@@ -440,13 +440,13 @@ void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix
 	}
 }
 
-void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind)
+void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
 {
 	for (child_list_t::iterator iter = mChildren.begin();
 		 iter != mChildren.end(); ++iter)
 	{
 		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		joint->updateFaceData(face, pixel_area, damp_wind);
+		joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
 	}
 }
 
diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h
index 0d3092a044..67bd7786c3 100644
--- a/indra/newview/llviewerjoint.h
+++ b/indra/newview/llviewerjoint.h
@@ -126,7 +126,7 @@ public:
 	PickName getPickName() { return mPickName; }
 
 	virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
-	virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE);
+	virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
 	virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
 	virtual void updateJointGeometry();
 	virtual void dump();
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index db2279d925..fb6cc8d790 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -663,7 +663,7 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32
 //-----------------------------------------------------------------------------
 static LLFastTimer::DeclareTimer FTM_AVATAR_FACE("Avatar Face");
 
-void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind)
+void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
 {
 	mFace = face;
 
@@ -698,22 +698,6 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
 			vertex_weightsp += mMesh->mFaceVertexOffset;
 			clothing_weightsp += mMesh->mFaceVertexOffset;
 
-			U32* __restrict v = (U32*) verticesp.get();
-			const U32 vert_skip = verticesp.getSkip()/sizeof(U32);
-
-			U32* __restrict tc = (U32*) tex_coordsp.get();
-			const U32 tc_skip = tex_coordsp.getSkip()/sizeof(U32);
-
-			U32* __restrict n = (U32*) normalsp.get();
-			const U32 n_skip = normalsp.getSkip()/sizeof(U32);
-			
-			U32* __restrict vw = (U32*) vertex_weightsp.get();
-			const U32 vw_skip = vertex_weightsp.getSkip()/sizeof(U32);
-
-
-			U32* __restrict cw = (U32*) clothing_weightsp.get();
-			const U32 cw_skip = vertex_weightsp.getSkip()/sizeof(U32);
-
 			const U32* __restrict coords = (U32*) mMesh->getCoords();
 			const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords();
 			const U32* __restrict normals = (U32*) mMesh->getNormals();
@@ -723,49 +707,84 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
 			const U32 num_verts = mMesh->getNumVertices();
 
 			U32 i = 0;
-			do
+
+			const U32 skip = verticesp.getSkip()/sizeof(U32);
+
+			U32* __restrict v = (U32*) verticesp.get();
+			U32* __restrict n = (U32*) normalsp.get();
+			
+			if (terse_update)
 			{
-				v[0] = *(coords++); 
-				v[1] = *(coords++); 
-				v[2] = *(coords++);
-				v += vert_skip;
-
-				tc[0] = *(tex_coords++); 
-				tc[1] = *(tex_coords++);
-				tc += tc_skip;
-
-				n[0] = *(normals++); 
-				n[1] = *(normals++);
-				n[2] = *(normals++);
-				n += n_skip;
-
-				vw[0] = *(weights++);
-				vw += vw_skip;
-
-				cw[0] = *(cloth_weights++);
-				cw[1] = *(cloth_weights++);
-				cw[2] = *(cloth_weights++);
-				cw[3] = *(cloth_weights++);
-				cw += cw_skip;
+				for (S32 i = num_verts; i > 0; --i)
+				{
+					//morph target application only, only update positions and normals
+					v[0] = coords[0]; 
+					v[1] = coords[1]; 
+					v[2] = coords[2];		
+					coords += 3;
+					v += skip;
+				}
+
+				for (S32 i = num_verts; i > 0; --i)
+				{
+					n[0] = normals[0]; 
+					n[1] = normals[1];
+					n[2] = normals[2];
+					normals += 3;
+					n += skip;
+				}
 			}
-			while (++i < num_verts);
+			else
+				{
 
-			const U32 idx_count = mMesh->getNumFaces()*3;
+				U32* __restrict tc = (U32*) tex_coordsp.get();
+				U32* __restrict vw = (U32*) vertex_weightsp.get();
+				U32* __restrict cw = (U32*) clothing_weightsp.get();
+				
+				do
+				{
+					v[0] = *(coords++); 
+					v[1] = *(coords++); 
+					v[2] = *(coords++);
+					v += skip;
+
+					tc[0] = *(tex_coords++); 
+					tc[1] = *(tex_coords++);
+					tc += skip;
+
+					n[0] = *(normals++); 
+					n[1] = *(normals++);
+					n[2] = *(normals++);
+					n += skip;
+
+					vw[0] = *(weights++);
+					vw += skip;
+
+					cw[0] = *(cloth_weights++);
+					cw[1] = *(cloth_weights++);
+					cw[2] = *(cloth_weights++);
+					cw[3] = *(cloth_weights++);
+					cw += skip;
+				}
+				while (++i < num_verts);
 
-			indicesp += mMesh->mFaceIndexOffset;
+				const U32 idx_count = mMesh->getNumFaces()*3;
 
-			U16* __restrict idx = indicesp.get();
-			S32* __restrict src_idx = (S32*) mMesh->getFaces();
+				indicesp += mMesh->mFaceIndexOffset;
 
-			i = 0;
+				U16* __restrict idx = indicesp.get();
+				S32* __restrict src_idx = (S32*) mMesh->getFaces();
 
-			const S32 offset = (S32) mMesh->mFaceVertexOffset;
+				i = 0;
 
-			do
-			{
-				*(idx++) = *(src_idx++)+offset;
+				const S32 offset = (S32) mMesh->mFaceVertexOffset;
+
+				do
+				{
+					*(idx++) = *(src_idx++)+offset;
+				}
+				while (++i < idx_count);
 			}
-			while (++i < idx_count);
 		}
 	}
 }
diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h
index d62b0ada85..3b8d9c82b8 100644
--- a/indra/newview/llviewerjointmesh.h
+++ b/indra/newview/llviewerjointmesh.h
@@ -140,7 +140,7 @@ public:
 	/*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy );
 
 	/*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
-	/*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE);
+	/*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
 	/*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate);
 	/*virtual*/ void updateJointGeometry();
 	/*virtual*/ void dump();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 33ea0199b6..e30a211185 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -693,10 +693,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 		mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);
 	}
 
-	mDirtyMesh = TRUE;	// Dirty geometry, need to regenerate.
+	mDirtyMesh = 2;	// Dirty geometry, need to regenerate.
 	mMeshTexturesDirty = FALSE;
-	mShadow0Facep = NULL;
-	mShadow1Facep = NULL;
 	mHeadp = NULL;
 
 	mIsBuilt = FALSE;
@@ -732,12 +730,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 
 	mRippleTimeLast = 0.f;
 
-	mShadowImagep = LLViewerTextureManager::getFetchedTextureFromFile("foot_shadow.j2c");
-	
-	// GL NOT ACTIVE HERE
-	//gGL.getTexUnit(0)->bind(mShadowImagep.get());
-	//mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
-	
 	mInAir = FALSE;
 
 	mStepOnLand = TRUE;
@@ -1923,7 +1915,7 @@ void LLVOAvatar::updateMeshData()
 			}
 			if(num_vertices < 1)//skip empty meshes
 			{
-				break ;
+				continue ;
 			}
 			if(last_v_num > 0)//put the last inserted part into next vertex buffer.
 			{
@@ -1945,6 +1937,8 @@ void LLVOAvatar::updateMeshData()
 			// resize immediately
 			facep->setSize(num_vertices, num_indices);
 
+			bool terse_update = false;
+
 			if(facep->mVertexBuffer.isNull())
 			{
 				facep->mVertexBuffer = new LLVertexBufferAvatar();
@@ -1952,7 +1946,15 @@ void LLVOAvatar::updateMeshData()
 			}
 			else
 			{
-				facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ;
+				if (facep->mVertexBuffer->getRequestedIndices() == num_indices &&
+					facep->mVertexBuffer->getRequestedVerts() == num_vertices)
+				{
+					terse_update = true;
+				}
+				else
+				{
+					facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ;
+				}
 			}
 		
 			facep->setGeomIndex(0);
@@ -1967,7 +1969,7 @@ void LLVOAvatar::updateMeshData()
 
 			for(S32 k = j ; k < part_index ; k++)
 			{
-				mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR);
+				mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update);
 			}
 
 			stop_glerror();
@@ -2320,12 +2322,6 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
 	LLJoint::sNumUpdates = 0;
 	LLJoint::sNumTouches = 0;
 
-	// *NOTE: this is necessary for the floating name text above your head.
-	if (mDrawable.notNull())
-	{
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_SHADOW, TRUE);
-	}
-
 	BOOL visible = isVisible() || mNeedsAnimUpdate;
 
 	// update attachments positions
@@ -3778,12 +3774,19 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 		return num_indices;
 	}
 
-	if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
+	LLFace* face = mDrawable->getFace(0);
+
+	bool needs_rebuild = !face || face->mVertexBuffer.isNull();
+
+	if (needs_rebuild || mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
 	{	//LOD changed or new mesh created, allocate new vertex buffer if needed
-		updateMeshData();
-		mDirtyMesh = FALSE;
-		mNeedsSkin = TRUE;
-		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+		if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
+		{
+			updateMeshData();
+			mDirtyMesh = 0;
+			mNeedsSkin = TRUE;
+			mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+		}
 	}
 
 	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
@@ -4031,54 +4034,6 @@ U32 LLVOAvatar::renderRigid()
 	return num_indices;
 }
 
-U32 LLVOAvatar::renderFootShadows()
-{
-	U32 num_indices = 0;
-
-	if (!mIsBuilt)
-	{
-		return 0;
-	}
-
-	if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
-	{
-		return 0;
-	}
-	
-	if (!mIsBuilt)
-	{
-		return 0;
-	}
-	
-	// Don't render foot shadows if your lower body is completely invisible.
-	// (non-humanoid avatars rule!)
-	if (!isTextureVisible(TEX_LOWER_BAKED))
-	{
-		return 0;
-	}
-
-	// Update the shadow, tractor, and text label geometry.
-	if (mDrawable->isState(LLDrawable::REBUILD_SHADOW) && !isImpostor())
-	{
-		updateShadowFaces();
-		mDrawable->clearState(LLDrawable::REBUILD_SHADOW);
-	}
-
-	U32 foot_mask = LLVertexBuffer::MAP_VERTEX |
-					LLVertexBuffer::MAP_TEXCOORD0;
-
-	LLGLDepthTest test(GL_TRUE, GL_FALSE);
-	//render foot shadows
-	LLGLEnable blend(GL_BLEND);
-	gGL.getTexUnit(0)->bind(mShadowImagep, TRUE);
-	glColor4fv(mShadow0Facep->getRenderColor().mV);
-	mShadow0Facep->renderIndexed(foot_mask);
-	glColor4fv(mShadow1Facep->getRenderColor().mV);
-	mShadow1Facep->renderIndexed(foot_mask);
-	
-	return num_indices;
-}
-
 U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
 {
 	if (!mImpostor.isComplete())
@@ -4199,11 +4154,6 @@ void LLVOAvatar::updateTextures()
 	{
 		setDebugText(llformat("%4.0f:%4.0f", fsqrtf(mMinPixelArea),fsqrtf(mMaxPixelArea)));
 	}	
-	
-	if( render_avatar )
-	{
-		mShadowImagep->addTextureStats(mPixelArea);
-	}
 }
 
 
@@ -5347,7 +5297,7 @@ BOOL LLVOAvatar::updateJointLODs()
  		if (res)
 		{
 			sNumLODChangesThisFrame++;
-			dirtyMesh();
+			dirtyMesh(2);
 			return TRUE;
 		}
 	}
@@ -5371,18 +5321,9 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
 	mDrawable->addFace(poolp, NULL);
 	mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR);
 	
-	LLFace *facep;
-
-	// Add faces for the foot shadows
-	facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
-	mShadow0Facep = facep;
-
-	facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
-	mShadow1Facep = facep;
-
 	mNumInitFaces = mDrawable->getNumFaces() ;
 
-	dirtyMesh();
+	dirtyMesh(2);
 	return mDrawable;
 }
 
@@ -5421,107 +5362,6 @@ BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
 	return TRUE;
 }
 
-//-----------------------------------------------------------------------------
-// updateShadowFaces()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::updateShadowFaces()
-{
-	LLFace *face0p = mShadow0Facep;
-	LLFace *face1p = mShadow1Facep;
-
-	//
-	// render avatar shadows
-	//
-	if (mInAir || mUpdatePeriod >= IMPOSTOR_PERIOD)
-	{
-		face0p->setSize(0, 0);
-		face1p->setSize(0, 0);
-		return;
-	}
-
-	LLSprite sprite(mShadowImagep.notNull() ? mShadowImagep->getID() : LLUUID::null);
-	sprite.setFollow(FALSE);
-	const F32 cos_angle = gSky.getSunDirection().mV[2];
-	F32 cos_elev = sqrt(1 - cos_angle * cos_angle);
-	if (cos_angle < 0) cos_elev = -cos_elev;
-	sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f);
-	LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f);
-
-	if (mShadowImagep->hasGLTexture())
-	{
-		LLVector3 normal;
-		LLVector3d shadow_pos;
-		LLVector3 shadow_pos_agent;
-		F32 foot_height;
-
-		if (mFootLeftp)
-		{
-			LLVector3 joint_world_pos = mFootLeftp->getWorldPosition();
-			// this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
-			// but we make an explicit ray trace call in expectation of future improvements
-			resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos), 
-									 gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
-			shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
-			foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
-
-			// Pull sprite in direction of surface normal
-			shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
-
-			// Render sprite
-			sprite.setNormal(normal);
-			if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
-			{
-				sprite.setColor(0.f, 0.f, 0.f, 0.f);
-			}
-			else
-			{
-				sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
-			}
-			sprite.setPosition(shadow_pos_agent);
-
-			LLVector3 foot_to_knee = mKneeLeftp->getWorldPosition() - joint_world_pos;
-			//foot_to_knee.normalize();
-			foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
-			sprite.setYaw(azimuth(sun_vec - foot_to_knee));
-		
-			sprite.updateFace(*face0p);
-		}
-
-		if (mFootRightp)
-		{
-			LLVector3 joint_world_pos = mFootRightp->getWorldPosition();
-			// this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
-			// but we make an explicit ray trace call in expectation of future improvements
-			resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos), 
-									 gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
-			shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
-			foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
-
-			// Pull sprite in direction of surface normal
-			shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
-
-			// Render sprite
-			sprite.setNormal(normal);
-			if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
-			{
-				sprite.setColor(0.f, 0.f, 0.f, 0.f);
-			}
-			else
-			{
-				sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
-			}
-			sprite.setPosition(shadow_pos_agent);
-
-			LLVector3 foot_to_knee = mKneeRightp->getWorldPosition() - joint_world_pos;
-			//foot_to_knee.normalize();
-			foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
-			sprite.setYaw(azimuth(sun_vec - foot_to_knee));
-	
-			sprite.updateFace(*face1p);
-		}
-	}
-}
-
 //-----------------------------------------------------------------------------
 // updateSexDependentLayerSets()
 //-----------------------------------------------------------------------------
@@ -5535,9 +5375,9 @@ void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake )
 //-----------------------------------------------------------------------------
 // dirtyMesh()
 //-----------------------------------------------------------------------------
-void LLVOAvatar::dirtyMesh()
+void LLVOAvatar::dirtyMesh(S32 priority)
 {
-	mDirtyMesh = TRUE;
+	mDirtyMesh = llmax(mDirtyMesh, priority);
 }
 
 //-----------------------------------------------------------------------------
@@ -7696,18 +7536,15 @@ BOOL LLVOAvatar::updateLOD()
 	BOOL res = updateJointLODs();
 
 	LLFace* facep = mDrawable->getFace(0);
-	if (facep->mVertexBuffer.isNull() ||
-		(LLVertexBuffer::sEnableVBOs &&
-		((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) !=
-		 (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE))))
+	if (facep->mVertexBuffer.isNull())
 	{
-		mDirtyMesh = TRUE;
+		dirtyMesh(2);
 	}
 
-	if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
+	if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
 	{	//LOD changed or new mesh created, allocate new vertex buffer if needed
 		updateMeshData();
-		mDirtyMesh = FALSE;
+		mDirtyMesh = 0;
 		mNeedsSkin = TRUE;
 		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
 	}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index d0ad2b727b..19e2c23ddd 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -336,7 +336,6 @@ private:
  **/
 
 public:
-	U32 		renderFootShadows();
 	U32 		renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);
 	U32 		renderRigid();
 	U32 		renderSkinned(EAvatarRenderPass pass);
@@ -565,13 +564,13 @@ private:
 public:
 	void 			updateMeshTextures();
 	void 			updateSexDependentLayerSets(BOOL upload_bake);
-	void 			dirtyMesh(); // Dirty the avatar mesh
+	void 			dirtyMesh(S32 priority = 1); // Dirty the avatar mesh
 	void 			updateMeshData();
 protected:
 	void 			releaseMeshData();
 	virtual void restoreMeshData();
 private:
-	BOOL 			mDirtyMesh;
+	S32 			mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD
 	BOOL			mMeshTexturesDirty;
 
 	typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
-- 
cgit v1.2.3