diff options
| -rw-r--r-- | indra/llmath/llvolume.cpp | 108 | ||||
| -rw-r--r-- | indra/llmath/llvolume.h | 2 | ||||
| -rw-r--r-- | indra/newview/lldrawable.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llface.cpp | 32 | ||||
| -rw-r--r-- | indra/newview/llselectmgr.cpp | 50 | ||||
| -rw-r--r-- | indra/newview/llspatialpartition.cpp | 16 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 114 | ||||
| -rw-r--r-- | indra/newview/llvovolume.h | 12 | 
9 files changed, 247 insertions, 109 deletions
| diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 07339f7526..24528a8ce9 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1990,7 +1990,7 @@ void LLVolumeFace::VertexData::init()  {  	if (!mData)  	{ -		mData = (LLVector4a*) ll_aligned_malloc_16(32); +		mData = new LLVector4a[2];  	}  } @@ -2019,7 +2019,7 @@ const LLVolumeFace::VertexData& LLVolumeFace::VertexData::operator=(const LLVolu  LLVolumeFace::VertexData::~VertexData()  { -	ll_aligned_free_16(mData); +	delete [] mData;  }  LLVector4a& LLVolumeFace::VertexData::getPosition() @@ -2257,12 +2257,12 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  					U32 cur_influence = 0;  					LLVector4 wght(0,0,0,0); -					while (joint != END_INFLUENCES) +					while (joint != END_INFLUENCES && idx < weights.size())  					{  						U16 influence = weights[idx++];  						influence |= ((U16) weights[idx++] << 8); -						F32 w = llmin((F32) influence / 65535.f, 0.99999f); +						F32 w = llclamp((F32) influence / 65535.f, 0.f, 0.99999f);  						wght.mV[cur_influence++] = (F32) joint + w;  						if (cur_influence >= 4) @@ -5230,7 +5230,7 @@ LLVolumeFace::LLVolumeFace() :  	mWeights(NULL),  	mOctree(NULL)  { -	mExtents = (LLVector4a*) ll_aligned_malloc_16(48); +	mExtents = new LLVector4a[3];  	mCenter = mExtents+2;  } @@ -5251,7 +5251,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)  	mWeights(NULL),  	mOctree(NULL)  {  -	mExtents = (LLVector4a*) ll_aligned_malloc_16(48); +	mExtents = new LLVector4a[3];  	mCenter = mExtents+2;  	*this = src;  } @@ -5286,7 +5286,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  	if (mNumVertices)  	{ -		S32 vert_size = mNumVertices*4*sizeof(F32); +		S32 vert_size = mNumVertices*sizeof(LLVector4a);  		S32 tc_size = (mNumVertices*8+0xF) & ~0xF;  		LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); @@ -5301,7 +5301,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  		}  		else  		{ -			ll_aligned_free_16(mBinormals); +			delete [] mBinormals;  			mBinormals = NULL;  		} @@ -5312,7 +5312,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  		}  		else  		{ -			ll_aligned_free_16(mWeights); +			delete [] mWeights;  			mWeights = NULL;  		}  	} @@ -5330,7 +5330,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  LLVolumeFace::~LLVolumeFace()  { -	ll_aligned_free_16(mExtents); +	delete [] mExtents;  	mExtents = NULL;  	freeData(); @@ -5338,17 +5338,17 @@ LLVolumeFace::~LLVolumeFace()  void LLVolumeFace::freeData()  { -	ll_aligned_free_16(mPositions); +	delete [] mPositions;  	mPositions = NULL; -	ll_aligned_free_16(mNormals); +	delete []  mNormals;  	mNormals = NULL; -	ll_aligned_free_16(mTexCoords); +	delete [] mTexCoords;  	mTexCoords = NULL; -	ll_aligned_free_16(mIndices); +	delete [] mIndices;  	mIndices = NULL; -	ll_aligned_free_16(mBinormals); +	delete [] mBinormals;  	mBinormals = NULL; -	ll_aligned_free_16(mWeights); +	delete [] mWeights;  	mWeights = NULL;  	delete mOctree; @@ -5461,18 +5461,13 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  } -void LLVolumeFace::createOctree(F32 scaler) +void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size)  {  	if (mOctree)  	{  		return;  	} -	LLVector4a center; -	LLVector4a size; -	center.splat(0.f); -	size.splat(0.5f); -  	mOctree = new LLOctreeRoot<LLVolumeTriangle>(center, size, NULL);  	new LLVolumeOctreeListener(mOctree); @@ -6166,21 +6161,21 @@ void LLVolumeFace::createBinormals()  void LLVolumeFace::resizeVertices(S32 num_verts)  { -	ll_aligned_free_16(mPositions); -	ll_aligned_free_16(mNormals); -	ll_aligned_free_16(mBinormals); -	ll_aligned_free_16(mTexCoords); +	delete [] mPositions; +	delete [] mNormals; +	delete [] mBinormals; +	delete [] mTexCoords;  	mBinormals = NULL;  	if (num_verts)  	{ -		mPositions = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); -		mNormals = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); +		mPositions = new LLVector4a[num_verts];  +		mNormals = new LLVector4a[num_verts];   		//pad texture coordinate block end to allow for QWORD reads  		S32 size = ((num_verts*8) + 0xF) & ~0xF; -		mTexCoords = (LLVector2*) ll_aligned_malloc_16(size); +		mTexCoords = new LLVector2[size/8];  	}  	else  	{ @@ -6204,20 +6199,20 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con  	S32 old_size = mNumVertices*16;  	//positions -	LLVector4a* dst = (LLVector4a*) ll_aligned_malloc_16(new_size); +	LLVector4a* dst = new LLVector4a[new_verts];  	if (mPositions)  	{  		LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mPositions, old_size); -		ll_aligned_free_16(mPositions); +		delete [] mPositions;  	}  	mPositions = dst;  	//normals -	dst = (LLVector4a*) ll_aligned_malloc_16(new_size); +	dst = new LLVector4a[new_verts];   	if (mNormals)  	{  		LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mNormals, old_size); -		ll_aligned_free_16(mNormals); +		delete [] mNormals;  	}  	mNormals = dst; @@ -6225,19 +6220,18 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con  	new_size = ((new_verts*8)+0xF) & ~0xF;  	old_size = ((mNumVertices*8)+0xF) & ~0xF; -	dst = (LLVector4a*) ll_aligned_malloc_16(new_size);  	{ -		LLVector2* dst = (LLVector2*) ll_aligned_malloc_16(new_size); +		LLVector2* dst = new LLVector2[new_size/8];   		if (mTexCoords)  		{  			LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mTexCoords, old_size); -			ll_aligned_free_16(mTexCoords); +			delete [] mTexCoords;  		} +		mTexCoords = dst;  	} -	mTexCoords = (LLVector2*) dst;  	//just clear binormals -	ll_aligned_free_16(mBinormals); +	delete [] mBinormals;  	mBinormals = NULL;  	mPositions[mNumVertices] = pos; @@ -6249,26 +6243,26 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con  void LLVolumeFace::allocateBinormals(S32 num_verts)  { -	ll_aligned_free_16(mBinormals); -	mBinormals = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); +	delete [] mBinormals; +	mBinormals = new LLVector4a[num_verts];   }  void LLVolumeFace::allocateWeights(S32 num_verts)  { -	ll_aligned_free_16(mWeights); -	mWeights = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); +	delete [] mWeights;  +	mWeights = new LLVector4a[num_verts];   }  void LLVolumeFace::resizeIndices(S32 num_indices)  { -	ll_aligned_free_16(mIndices); - +	delete [] mIndices; +	  	if (num_indices)  	{  		//pad index block end to allow for QWORD reads  		S32 size = ((num_indices*2) + 0xF) & ~0xF; -		mIndices = (U16*) ll_aligned_malloc_16(size);	 +		mIndices = new U16[size/2];  	}  	else  	{ @@ -6286,11 +6280,11 @@ void LLVolumeFace::pushIndex(const U16& idx)  	S32 old_size = ((mNumIndices*2)+0xF) & ~0xF;  	if (new_size != old_size)  	{ -		U16* dst = (U16*) ll_aligned_malloc_16(new_size); +		U16* dst = new U16[new_size/2];  		if (mIndices)  		{  			LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mIndices, old_size); -			ll_aligned_free_16(mIndices); +			delete [] mIndices;  		}  		mIndices = dst;  	} @@ -6333,9 +6327,9 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  	}  	//allocate new buffer space -	LLVector4a* new_pos = (LLVector4a*) ll_aligned_malloc_16(new_count*16); -	LLVector4a* new_norm = (LLVector4a*) ll_aligned_malloc_16(new_count*16); -	LLVector2* new_tc = (LLVector2*) ll_aligned_malloc_16((new_count*8+0xF) & ~0xF); +	LLVector4a* new_pos = new LLVector4a[new_count]; +	LLVector4a* new_norm = new LLVector4a[new_count]; +	LLVector2* new_tc = new LLVector2[((new_count*8+0xF) & ~0xF)/8];  	if (mNumVertices > 0) @@ -6346,10 +6340,10 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  	}  	//free old buffer space -	ll_aligned_free_16(mPositions); -	ll_aligned_free_16(mNormals); -	ll_aligned_free_16(mTexCoords); - +	delete [] mPositions; +	delete [] mNormals; +	delete [] mTexCoords; +	  	//point to new buffers  	mPositions = new_pos;  	mNormals = new_norm; @@ -6399,7 +6393,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  	new_count = mNumIndices + face.mNumIndices;  	//allocate new index buffer -	U16* new_indices = (U16*) ll_aligned_malloc_16((new_count*2+0xF) & ~0xF); +	U16* new_indices = new U16[((new_count*2+0xF) & ~0xF)/2];  	if (mNumIndices > 0)  	{ //copy old index buffer  		S32 old_size = (mNumIndices*2+0xF) & ~0xF; @@ -6407,8 +6401,8 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  	}  	//free old index buffer -	ll_aligned_free_16(mIndices); - +	delete [] mIndices; +	  	//point to new index buffer  	mIndices = new_indices; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index ff5e3d9dfa..32364bd4b8 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -882,7 +882,7 @@ public:  	};  	void optimize(F32 angle_cutoff = 2.f); -	void createOctree(F32 scaler = 0.25f); +	void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f));  	enum  	{ diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 5949a373ae..efbb62011c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -191,15 +191,6 @@ LLVOVolume* LLDrawable::getVOVolume() const  const LLMatrix4& LLDrawable::getRenderMatrix() const  {  -	if (LLDrawable::isState(LLDrawable::RIGGED)) -	{ -		LLVOAvatar* avatar = mVObjp->getAvatar(); -		if (avatar) -		{ -			return avatar->mDrawable->getWorldMatrix(); -		} -	} -  	return isRoot() ? getWorldMatrix() : getParent()->getWorldMatrix();  } @@ -727,8 +718,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)  		LLVOVolume* volume = getVOVolume();  		if (volume)  		{ -			volume->updateRelativeXform(); -			pos = volume->getRelativeXform().getTranslation(); +			pos.set(getPositionGroup().getF32ptr());  			if (isStatic())  			{  				pos += volume->getRegion()->getOriginAgent(); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index ccc060f3fa..5cf6082f12 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1325,6 +1325,12 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  #if LL_MESH_ENABLED  void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)  { +	LLVector4a* weight = vol_face.mWeights; +	if (!weight) +	{ +		return; +	} +  	LLVertexBuffer* buffer = face->mVertexBuffer;  	U32 data_mask = 0; @@ -1403,8 +1409,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  			}  		} -		LLVector4a* weight = vol_face.mWeights; -  		LLMatrix4a bind_shape_matrix;  		bind_shape_matrix.loadu(skin->mBindShapeMatrix); @@ -1422,7 +1426,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  			{  				F32 w = weight[j][k]; -				idx[k] = (S32) floorf(w); +				idx[k] = llclamp((S32) floorf(w), 0, 63);  				wght[k] = w - floorf(w);  				scale += wght[k];  			} diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 9a178985cf..3fa60e9f1e 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -556,8 +556,36 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)  		}  		glColor4fv(color.mV); -		mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); -		mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); +	 +		if (mDrawablep->isState(LLDrawable::RIGGED)) +		{ +			LLVOVolume* volume = mDrawablep->getVOVolume(); +			if (volume) +			{ +				LLRiggedVolume* rigged = volume->getRiggedVolume(); +				if (rigged) +				{ +					LLGLEnable offset(GL_POLYGON_OFFSET_FILL); +					glPolygonOffset(-1.f, -1.f); +					glMultMatrixf((F32*) volume->getRelativeXform().mMatrix); +					const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset()); +					LLVertexBuffer::unbind(); +					glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions); +					if (vol_face.mTexCoords) +					{ +						glEnableClientState(GL_TEXTURE_COORD_ARRAY); +						glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords); +					} +					glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices); +					glDisableClientState(GL_TEXTURE_COORD_ARRAY); +				} +			} +		} +		else +		{ +			mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); +			mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); +		}  		gGL.popMatrix();  	} diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index ff2929695d..21f7e780e2 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -5395,6 +5395,42 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power)  	return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id));  } + +//helper function for pushing relevant vertices from drawable to GL +void pushWireframe(LLDrawable* drawable) +{ +	if (drawable->isState(LLDrawable::RIGGED)) +	{ //render straight from rigged volume if this is a rigged attachment +		LLVOVolume* vobj = drawable->getVOVolume(); +		if (vobj) +		{ +			vobj->updateRiggedVolume(); +			LLRiggedVolume* rigged_volume = vobj->getRiggedVolume(); +			if (rigged_volume) +			{ +				LLVertexBuffer::unbind(); +				gGL.pushMatrix(); +				glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); +				for (S32 i = 0; i < rigged_volume->getNumVolumeFaces(); ++i) +				{ +					const LLVolumeFace& face = rigged_volume->getVolumeFace(i); +					glVertexPointer(3, GL_FLOAT, 16, face.mPositions); +					glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); +				} +				gGL.popMatrix(); +			} +		} +	} +	else +	{ +		for (S32 i = 0; i < drawable->getNumFaces(); ++i) +		{ +			LLFace* face = drawable->getFace(i); +			pushVerts(face, LLVertexBuffer::MAP_VERTEX); +		} +	} +} +  void LLSelectNode::renderOneWireframe(const LLColor4& color)  {  	LLViewerObject* objectp = getObject(); @@ -5442,11 +5478,7 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)  		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  		{  			glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); -			for (S32 i = 0; i < drawable->getNumFaces(); ++i) -			{ -				LLFace* face = drawable->getFace(i); -				pushVerts(face, LLVertexBuffer::MAP_VERTEX); -			} +			pushWireframe(drawable);  		}  	} @@ -5455,13 +5487,9 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)  	glColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);  	LLGLEnable offset(GL_POLYGON_OFFSET_LINE); -	glPolygonOffset(3.f, 2.f); +	glPolygonOffset(3.f, 3.f);  	glLineWidth(3.f); -	for (S32 i = 0; i < drawable->getNumFaces(); ++i) -	{ -		LLFace* face = drawable->getFace(i); -		pushVerts(face, LLVertexBuffer::MAP_VERTEX); -	} +	pushWireframe(drawable);  	glLineWidth(1.f);  	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);  	gGL.popMatrix(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 191cdac981..0f9f35dc57 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3121,9 +3121,11 @@ void renderRaycast(LLDrawable* drawablep)  			LLVOVolume* vobj = drawablep->getVOVolume();  			LLVolume* volume = vobj->getVolume(); +			bool transform = true;  			if (drawablep->isState(LLDrawable::RIGGED))  			{ -				volume = NULL; +				volume = vobj->getRiggedVolume(); +				transform = false;  			}  			if (volume) @@ -3140,8 +3142,16 @@ void renderRaycast(LLDrawable* drawablep)  					glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix);  					LLVector3 start, end; -					start = vobj->agentPositionToVolume(gDebugRaycastStart); -					end = vobj->agentPositionToVolume(gDebugRaycastEnd); +					if (transform) +					{ +						start = vobj->agentPositionToVolume(gDebugRaycastStart); +						end = vobj->agentPositionToVolume(gDebugRaycastEnd); +					} +					else +					{ +						start = gDebugRaycastStart; +						end = gDebugRaycastEnd; +					}  					LLVector4a starta, enda;  					starta.load3(start.mV); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 60bdfc24b9..f09ce5b363 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1358,8 +1358,9 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  	LLVector4a min,max; -	BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION) || mRiggedVolume.notNull(); +	BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); +	bool rigged = false;  	LLVolume* volume = mRiggedVolume;  	if (!volume)  	{ @@ -1424,10 +1425,19 @@ void LLVOVolume::updateRelativeXform()  	LLDrawable* drawable = mDrawable; -	if (drawable->isState(LLDrawable::RIGGED)) -	{ -		mRelativeXform.setIdentity(); -		mRelativeXformInvTrans.setIdentity(); +	if (drawable->isState(LLDrawable::RIGGED) && mRiggedVolume.notNull()) +	{ //rigged volume (which is in agent space) is used for generating bounding boxes etc +	  //inverse of render matrix should go to partition space +		mRelativeXform = getRenderMatrix(); + +		F32* dst = (F32*) mRelativeXformInvTrans.mMatrix; +		F32* src = (F32*) mRelativeXform.mMatrix; +		dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; +		dst[3] = src[4]; dst[4] = src[5]; dst[5] = src[6]; +		dst[6] = src[8]; dst[7] = src[9]; dst[8] = src[10]; +		 +		mRelativeXform.invert(); +		mRelativeXformInvTrans.transpose();  	}  	else if (drawable->isActive())  	{				 @@ -3421,12 +3431,15 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	LLVolume* volume = getVolume(); +	bool transform = true; +  	if (mDrawable->isState(LLDrawable::RIGGED))  	{  		if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf())  		{  			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE);  			volume = mRiggedVolume; +			transform = false;  		}  		else  		{ //cannot pick rigged attachments on other avatars or when not in build mode @@ -3438,8 +3451,16 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	{	  		LLVector3 v_start, v_end, v_dir; -		v_start = agentPositionToVolume(start); -		v_end = agentPositionToVolume(end); +		if (transform) +		{ +			v_start = agentPositionToVolume(start); +			v_end = agentPositionToVolume(end); +		} +		else +		{ +			v_start = start; +			v_end = end; +		}  		LLVector3 p;  		LLVector3 n; @@ -3499,18 +3520,40 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  					if (intersection != NULL)  					{ -						*intersection = volumePositionToAgent(p);  // must map back to agent space +						if (transform) +						{ +							*intersection = volumePositionToAgent(p);  // must map back to agent space +						} +						else +						{ +							*intersection = p; +						}  					}  					if (normal != NULL)  					{ -						*normal = volumeDirectionToAgent(n); +						if (transform) +						{ +							*normal = volumeDirectionToAgent(n); +						} +						else +						{ +							*normal = n; +						} +  						(*normal).normVec();  					}  					if (bi_normal != NULL)  					{ -						*bi_normal = volumeDirectionToAgent(bn); +						if (transform) +						{ +							*bi_normal = volumeDirectionToAgent(bn); +						} +						else +						{ +							*bi_normal = bn; +						}  						(*bi_normal).normVec();  					} @@ -3528,18 +3571,49 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	return ret;  } +bool LLVOVolume::treatAsRigged() +{ +	return LLFloater::isVisible(gFloaterTools) &&  +			isAttachment() &&  +			getAvatar() && +			getAvatar()->isSelf() && +			mDrawable.notNull() && +			mDrawable->isState(LLDrawable::RIGGED); +} + +LLRiggedVolume* LLVOVolume::getRiggedVolume() +{ +	return mRiggedVolume; +} + +void LLVOVolume::clearRiggedVolume() +{ +	if (mRiggedVolume.notNull()) +	{ +		mRiggedVolume = NULL; +		updateRelativeXform(); +	} +} +  void LLVOVolume::updateRiggedVolume()  {  	//Update mRiggedVolume to match current animation frame of avatar.   	//Also update position/size in octree.   +	if (!treatAsRigged()) +	{ +		clearRiggedVolume(); +		 +		return; +	} +  	LLVolume* volume = getVolume();  	const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(volume->getParams().getSculptID());  	if (!skin)  	{ -		mRiggedVolume = NULL; +		clearRiggedVolume();  		return;  	} @@ -3547,7 +3621,7 @@ void LLVOVolume::updateRiggedVolume()  	if (!avatar)  	{ -		mRiggedVolume = NULL; +		clearRiggedVolume();  		return;  	} @@ -3555,6 +3629,7 @@ void LLVOVolume::updateRiggedVolume()  	{  		LLVolumeParams p;  		mRiggedVolume = new LLRiggedVolume(p); +		updateRelativeXform();  	}  	mRiggedVolume->update(skin, avatar, volume); @@ -3592,12 +3667,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  	//build matrix palette  	LLMatrix4a mp[64];  	LLMatrix4* mat = (LLMatrix4*) mp; - -	LLMatrix4 agent_to_root; - -	LLVector4a origin; -	origin.load3(avatar->getPositionAgent().mV); - +	  	for (U32 j = 0; j < skin->mJointNames.size(); ++j)  	{  		LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); @@ -3661,7 +3731,6 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  				LLVector4a dst;  				bind_shape_matrix.affineTransform(v, t);  				final_mat.affineTransform(t, dst); -				dst.sub(origin);  				pos[j] = dst;  			} @@ -3687,7 +3756,12 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  			LLFastTimer t(FTM_RIGGED_OCTREE);  			delete dst_face.mOctree;  			dst_face.mOctree = NULL; -			dst_face.createOctree(2.f); + +			LLVector4a size; +			size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); +			size.splat(size.getLength3().getF32()*0.5f); +			 +			dst_face.createOctree(1.f);  		}  	}  } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index d868099eeb..f058710a27 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -306,7 +306,17 @@ public:  	//rigged volume update (for raycasting)  	void updateRiggedVolume(); -	LLRiggedVolume* getRiggedVolume() { return mRiggedVolume; } +	LLRiggedVolume* getRiggedVolume(); + +	//returns true if volume should be treated as a rigged volume +	// - Build tools are open +	// - object is an attachment +	// - object is attached to self +	// - object is rendered as rigged +	bool treatAsRigged(); + +	//clear out rigged volume and revert back to non-rigged state for picking/LOD/distance updates +	void clearRiggedVolume();  protected:  	S32	computeLODDetail(F32	distance, F32 radius); | 
