diff options
| author | Dave Parks <davep@lindenlab.com> | 2010-09-19 23:07:15 -0500 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2010-09-19 23:07:15 -0500 | 
| commit | 90da6d6fdc33343be72252101aed1be641e822b5 (patch) | |
| tree | 66f6045cdf869324d16a57af613ab8213fedab42 /indra | |
| parent | 3cda7606380109beb3f331b8b53d38914f8ba8f5 (diff) | |
Raycasting for rigged attachments now works for your own attachments while in edit mode.
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llmath/llvolume.cpp | 17 | ||||
| -rw-r--r-- | indra/llmath/llvolume.h | 4 | ||||
| -rw-r--r-- | indra/llmath/llvolumeoctree.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/lldrawable.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/lldrawable.h | 56 | ||||
| -rw-r--r-- | indra/newview/llface.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llspatialpartition.cpp | 80 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 230 | ||||
| -rw-r--r-- | indra/newview/llvovolume.h | 22 | 
10 files changed, 372 insertions, 75 deletions
| diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 4798197921..07339f7526 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2569,14 +2569,13 @@ void LLVolume::makeTetrahedron()  	mIsTetrahedron = TRUE;  } -void LLVolume::copyVolumeFaces(LLVolume* volume) +void LLVolume::copyVolumeFaces(const LLVolume* volume)  {  	mVolumeFaces = volume->mVolumeFaces;  	mSculptLevel = 0;  	mIsTetrahedron = FALSE;  } -  S32	LLVolume::getNumFaces() const  {  #if LL_MESH_ENABLED @@ -5462,12 +5461,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  } -void LLVolumeFace::createOctree() +void LLVolumeFace::createOctree(F32 scaler)  { +	if (mOctree) +	{ +		return; +	} +  	LLVector4a center;  	LLVector4a size;  	center.splat(0.f); -	size.splat(1.f); +	size.splat(0.5f);  	mOctree = new LLOctreeRoot<LLVolumeTriangle>(center, size, NULL);  	new LLVolumeOctreeListener(mOctree); @@ -5511,12 +5515,15 @@ void LLVolumeFace::createOctree()  		LLVector4a size;  		size.setSub(max,min); -		tri->mRadius = size.getLength3().getF32() * 0.5f; +		tri->mRadius = size.getLength3().getF32() * scaler;  		//insert  		mOctree->insert(tri);  	} +	//remove unneeded octree layers +	while (!mOctree->balance())	{ } +  	//calculate AABB for each node  	LLVolumeOctreeRebound rebound(this);  	rebound.traverse(mOctree); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index af28337f57..ff5e3d9dfa 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(); +	void createOctree(F32 scaler = 0.25f);  	enum  	{ @@ -1044,7 +1044,7 @@ public:  	LLVector3			mLODScaleBias;		// vector for biasing LOD based on scale  	void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level); -	void copyVolumeFaces(LLVolume* volume); +	void copyVolumeFaces(const LLVolume* volume);  private:  	void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index 12fe90f35d..cb6211f63c 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -223,14 +223,14 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)  	test_min.setSub(center, size);  	test_max.setAdd(center, size); -	if (!test_min.equals3(min) || -		!test_max.equals3(max)) +	if (!test_min.equals3(min, 0.001f) || +		!test_max.equals3(max, 0.001f))  	{  		llerrs << "Bad bounding box data found." << llendl;  	} -	test_min.sub(LLVector4a::getEpsilon()); -	test_max.add(LLVector4a::getEpsilon()); +	test_min.sub(LLVector4a(0.001f)); +	test_max.add(LLVector4a(0.001f));  	for (U32 i = 0; i < branch->getChildCount(); ++i)  	{ diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 68f52e04bc..5949a373ae 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -189,6 +189,20 @@ 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(); +} +  BOOL LLDrawable::isLight() const  {  	LLViewerObject* objectp = mVObjp; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index fc90bc57c4..a17e2172aa 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -101,7 +101,7 @@ public:  	LLVOVolume*	getVOVolume() const; // cast mVObjp tp LLVOVolume if OK  	const LLMatrix4&      getWorldMatrix() const		{ return mXform.getWorldMatrix(); } -	const LLMatrix4&	  getRenderMatrix() const		{ return isRoot() ? getWorldMatrix() : getParent()->getWorldMatrix(); } +	const LLMatrix4&	  getRenderMatrix() const;  	void				  setPosition(LLVector3 v) const { }  	const LLVector3&	  getPosition() const			{ return mXform.getPosition(); }  	const LLVector3&      getWorldPosition() const		{ return mXform.getPositionW(); } @@ -250,35 +250,37 @@ public:  	typedef enum e_drawable_flags  	{ - 		IN_REBUILD_Q1	= 0x00000002, - 		IN_REBUILD_Q2	= 0x00000004, - 		IN_LIGHT_Q		= 0x00000008, -		EARLY_MOVE		= 0x00000010, -		MOVE_UNDAMPED	= 0x00000020, -		ON_MOVE_LIST	= 0x00000040, -		USE_BACKLIGHT	= 0x00000080, -		UV				= 0x00000100, -		UNLIT			= 0x00000200, -		LIGHT			= 0x00000400, -		LIGHTING_BUILT	= 0x00000800, -		REBUILD_VOLUME  = 0x00001000,	//volume changed LOD or parameters, or vertex buffer changed -		REBUILD_TCOORD	= 0x00002000,	//texture coordinates changed -		REBUILD_COLOR	= 0x00004000,	//color changed -		REBUILD_POSITION= 0x00010000,	//vertex positions/normals changed + 		IN_REBUILD_Q1	= 0x00000001, + 		IN_REBUILD_Q2	= 0x00000002, + 		IN_LIGHT_Q		= 0x00000004, +		EARLY_MOVE		= 0x00000008, +		MOVE_UNDAMPED	= 0x00000010, +		ON_MOVE_LIST	= 0x00000020, +		USE_BACKLIGHT	= 0x00000040, +		UV				= 0x00000080, +		UNLIT			= 0x00000100, +		LIGHT			= 0x00000200, +		LIGHTING_BUILT	= 0x00000400, +		REBUILD_VOLUME  = 0x00000800,	//volume changed LOD or parameters, or vertex buffer changed +		REBUILD_TCOORD	= 0x00001000,	//texture coordinates changed +		REBUILD_COLOR	= 0x00002000,	//color changed +		REBUILD_POSITION= 0x00004000,	//vertex positions/normals changed  		REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR,  		REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR,  		REBUILD_ALL		= REBUILD_GEOMETRY|REBUILD_VOLUME, -		ON_SHIFT_LIST	= 0x00100000, -		BLOCKER			= 0x00400000, -		ACTIVE			= 0x00800000, -		DEAD			= 0x01000000, -		INVISIBLE		= 0x02000000, // stay invisible until flag is cleared - 		NEARBY_LIGHT	= 0x04000000, // In gPipeline.mNearbyLightSet -		BUILT			= 0x08000000, -		FORCE_INVISIBLE = 0x10000000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) -		CLEAR_INVISIBLE = 0x20000000, // clear FORCE_INVISIBLE next draw frame -		REBUILD_SHADOW =  0x40000000, -		HAS_ALPHA		= 0x80000000, +		REBUILD_RIGGED	= 0x00008000, +		ON_SHIFT_LIST	= 0x00010000, +		BLOCKER			= 0x00020000, +		ACTIVE			= 0x00040000, +		DEAD			= 0x00080000, +		INVISIBLE		= 0x00100000, // stay invisible until flag is cleared + 		NEARBY_LIGHT	= 0x00200000, // In gPipeline.mNearbyLightSet +		BUILT			= 0x00400000, +		FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) +		CLEAR_INVISIBLE = 0x01000000, // clear FORCE_INVISIBLE next draw frame +		REBUILD_SHADOW =  0x02000000, +		HAS_ALPHA		= 0x04000000, +		RIGGED			= 0x08000000,  	} EDrawableFlags;  	LLXformMatrix       mXform; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 7c24eb77cd..9a178985cf 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -720,7 +720,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  	LLMemType mt1(LLMemType::MTYPE_DRAWABLE);  	//get bounding box -	if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION)) +	if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))  	{  		//VECTORIZE THIS  		LLMatrix4a mat_vert; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 2f0641489d..191cdac981 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3047,19 +3047,21 @@ public:  		LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0);  		LLVector3 center, size; -		center.set(vl->mBounds[0].getF32ptr()); -		size.set(vl->mBounds[1].getF32ptr()); - +		  		if (branch->getData().empty())  		{  			gGL.color3f(1.f,0.2f,0.f); +			center.set(branch->getCenter().getF32ptr()); +			size.set(branch->getSize().getF32ptr());  		}  		else  		{  			gGL.color3f(0.75f, 1.f, 0.f); +			center.set(vl->mBounds[0].getF32ptr()); +			size.set(vl->mBounds[1].getF32ptr());  		} -		 -		drawBoxOutline(center, size); + +		drawBoxOutline(center, size);	  		for (U32 i = 0; i < 2; i++)  		{ @@ -3072,10 +3074,7 @@ public:  			else  			{  				gGL.color4f(0,0.5f,0.5f, 0.25f); -				if (!branch->getData().empty()) -				{ -					drawBoxOutline(center, size); -				} +				drawBoxOutline(center, size);  			}  			if (i == 1) @@ -3121,34 +3120,53 @@ void renderRaycast(LLDrawable* drawablep)  			LLVOVolume* vobj = drawablep->getVOVolume();  			LLVolume* volume = vobj->getVolume(); -			for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + +			if (drawablep->isState(LLDrawable::RIGGED)) +			{ +				volume = NULL; +			} + +			if (volume)  			{ -				const LLVolumeFace& face = volume->getVolumeFace(i); -				if (!face.mOctree) +				for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)  				{ -					((LLVolumeFace*) &face)->createOctree();  -				} +					const LLVolumeFace& face = volume->getVolumeFace(i); +					if (!face.mOctree) +					{ +						((LLVolumeFace*) &face)->createOctree();  +					} -				gGL.pushMatrix(); -				glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); -				LLVector3 start, end; -				start = vobj->agentPositionToVolume(gDebugRaycastStart); -				end = vobj->agentPositionToVolume(gDebugRaycastEnd); +					gGL.pushMatrix(); +					glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); -				LLVector4a starta, enda; -				starta.load3(start.mV); -				enda.load3(end.mV); -				LLVector4a dir; -				dir.setSub(enda, starta); +					LLVector3 start, end; +					start = vobj->agentPositionToVolume(gDebugRaycastStart); +					end = vobj->agentPositionToVolume(gDebugRaycastEnd); -				F32 t = 1.f; +					LLVector4a starta, enda; +					starta.load3(start.mV); +					enda.load3(end.mV); +					LLVector4a dir; +					dir.setSub(enda, starta); -				LLRenderOctreeRaycast render(starta, dir, &t); -				gGL.flush(); -				glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -				render.traverse(face.mOctree); -				gGL.popMatrix();		 -				glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +					F32 t = 1.f; + +					LLRenderOctreeRaycast render(starta, dir, &t); +					gGL.flush(); +					glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + +					{ +						//render face positions +						LLVertexBuffer::unbind(); +						glColor4f(0,1,1,0.5f); +						glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions); +						glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); +					} +						 +					render.traverse(face.mOctree); +					gGL.popMatrix();		 +					glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +				}  			}  		}  		else if (drawablep->isAvatar()) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index fd2212f25d..4c1a1958e8 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3279,6 +3279,15 @@ const LLVector3 LLViewerObject::getPositionEdit() const  const LLVector3 LLViewerObject::getRenderPosition() const  { +	if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) +	{ +		LLVOAvatar* avatar = getAvatar(); +		if (avatar) +		{ +			return avatar->getPositionAgent(); +		} +	} +  	if (mDrawable.isNull() || mDrawable->getGeneration() < 0)  	{  		return getPositionAgent(); @@ -3297,6 +3306,11 @@ const LLVector3 LLViewerObject::getPivotPositionAgent() const  const LLQuaternion LLViewerObject::getRenderRotation() const  {  	LLQuaternion ret; +	if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) +	{ +		return ret; +	} +	  	if (mDrawable.isNull() || mDrawable->isStatic())  	{  		ret = getRotationEdit(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 5448e7dcd9..60bdfc24b9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -41,9 +41,11 @@  #include "llviewercontrol.h"  #include "lldir.h"  #include "llflexibleobject.h" +#include "llfloatertools.h"  #include "llmaterialtable.h"  #include "llprimitive.h"  #include "llvolume.h" +#include "llvolumeoctree.h"  #include "llvolumemgr.h"  #include "llvolumemessage.h"  #include "material_codes.h" @@ -70,6 +72,7 @@  #include "llselectmgr.h"  #include "pipeline.h"  #include "llsdutil.h" +#include "llmatrix4a.h"  #include "llmediaentry.h"  #include "llmediadataclient.h"  #include "llmeshrepository.h" @@ -1355,7 +1358,13 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  	LLVector4a min,max; -	BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION); +	BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION) || mRiggedVolume.notNull(); + +	LLVolume* volume = mRiggedVolume; +	if (!volume) +	{ +		volume = getVolume(); +	}  	for (S32 i = 0; i < getVolume()->getNumVolumeFaces(); i++)  	{ @@ -1364,7 +1373,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  		{  			continue;  		} -		res &= face->genVolumeBBoxes(*getVolume(), i, +		res &= face->genVolumeBBoxes(*volume, i,  										mRelativeXform, mRelativeXformInvTrans,  										(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); @@ -1415,7 +1424,12 @@ void LLVOVolume::updateRelativeXform()  	LLDrawable* drawable = mDrawable; -	if (drawable->isActive()) +	if (drawable->isState(LLDrawable::RIGGED)) +	{ +		mRelativeXform.setIdentity(); +		mRelativeXformInvTrans.setIdentity(); +	} +	else if (drawable->isActive())  	{				  		// setup relative transforms  		LLQuaternion delta_rot; @@ -1497,11 +1511,22 @@ void LLVOVolume::updateRelativeXform()  static LLFastTimer::DeclareTimer FTM_GEN_FLEX("Generate Flexies");  static LLFastTimer::DeclareTimer FTM_UPDATE_PRIMITIVES("Update Primitives"); +static LLFastTimer::DeclareTimer FTM_UPDATE_RIGGED_VOLUME("Update Rigged");  BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  {  	LLFastTimer t(FTM_UPDATE_PRIMITIVES); +	if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) +	{ +		{ +			LLFastTimer t(FTM_UPDATE_RIGGED_VOLUME); +			updateRiggedVolume(); +		} +		genBBoxes(FALSE); +		mDrawable->clearState(LLDrawable::REBUILD_RIGGED); +	} +  	if (mVolumeImpl != NULL)  	{  		BOOL res; @@ -1597,7 +1622,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  	{  		LLPipeline::sCompiles++;  	} -	 +		  	mVolumeChanged = FALSE;  	mLODChanged = FALSE;  	mSculptChanged = FALSE; @@ -2724,6 +2749,11 @@ BOOL LLVOVolume::isVolumeGlobal() const  	{  		return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE;  	} +	else if (mRiggedVolume.notNull()) +	{ +		return TRUE; +	} +  	return FALSE;  } @@ -3390,6 +3420,20 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	BOOL ret = FALSE;  	LLVolume* volume = getVolume(); + +	if (mDrawable->isState(LLDrawable::RIGGED)) +	{ +		if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf()) +		{ +			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); +			volume = mRiggedVolume; +		} +		else +		{ //cannot pick rigged attachments on other avatars or when not in build mode +			return FALSE; +		} +	} +	  	if (volume)  	{	  		LLVector3 v_start, v_end, v_dir; @@ -3484,6 +3528,170 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	return ret;  } +void LLVOVolume::updateRiggedVolume() +{ +	//Update mRiggedVolume to match current animation frame of avatar.  +	//Also update position/size in octree.   + +	LLVolume* volume = getVolume(); + +	const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(volume->getParams().getSculptID()); + +	if (!skin) +	{ +		mRiggedVolume = NULL; +		return; +	} + +	LLVOAvatar* avatar = getAvatar(); + +	if (!avatar) +	{ +		mRiggedVolume = NULL; +		return; +	} + +	if (!mRiggedVolume) +	{ +		LLVolumeParams p; +		mRiggedVolume = new LLRiggedVolume(p); +	} + +	mRiggedVolume->update(skin, avatar, volume); + +} + +static LLFastTimer::DeclareTimer FTM_SKIN_RIGGED("Skin"); +static LLFastTimer::DeclareTimer FTM_RIGGED_OCTREE("Octree"); + +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume) +{ +	bool copy = false; +	if (volume->getNumVolumeFaces() != getNumVolumeFaces()) +	{  +		copy = true; +	} + +	for (S32 i = 0; i < volume->getNumVolumeFaces() && !copy; ++i) +	{ +		const LLVolumeFace& src_face = volume->getVolumeFace(i); +		const LLVolumeFace& dst_face = getVolumeFace(i); + +		if (src_face.mNumIndices != dst_face.mNumIndices || +			src_face.mNumVertices != dst_face.mNumVertices) +		{ +			copy = true; +		} +	} + +	if (copy) +	{ +		copyVolumeFaces(volume);	 +	} + +	//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]); +		if (joint) +		{ +			mat[j] = skin->mInvBindMatrix[j]; +			mat[j] *= joint->getWorldMatrix(); +		} +	} + +	for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) +	{ +		const LLVolumeFace& vol_face = volume->getVolumeFace(i); +		 +		LLVolumeFace& dst_face = mVolumeFaces[i]; +		 +		LLVector4a* weight = vol_face.mWeights; + +		LLMatrix4a bind_shape_matrix; +		bind_shape_matrix.loadu(skin->mBindShapeMatrix); + +		LLVector4a* pos = dst_face.mPositions; + +		{ +			LLFastTimer t(FTM_SKIN_RIGGED); + +			for (U32 j = 0; j < dst_face.mNumVertices; ++j) +			{ +				LLMatrix4a final_mat; +				final_mat.clear(); + +				S32 idx[4]; + +				LLVector4 wght; + +				F32 scale = 0.f; +				for (U32 k = 0; k < 4; k++) +				{ +					F32 w = weight[j][k]; + +					idx[k] = (S32) floorf(w); +					wght[k] = w - floorf(w); +					scale += wght[k]; +				} + +				wght *= 1.f/scale; + +				for (U32 k = 0; k < 4; k++) +				{ +					F32 w = wght[k]; + +					LLMatrix4a src; +					src.setMul(mp[idx[k]], w); + +					final_mat.add(src); +				} + +				 +				LLVector4a& v = vol_face.mPositions[j]; +				LLVector4a t; +				LLVector4a dst; +				bind_shape_matrix.affineTransform(v, t); +				final_mat.affineTransform(t, dst); +				dst.sub(origin); +				pos[j] = dst; +			} + +			//update bounding box +			LLVector4a& min = dst_face.mExtents[0]; +			LLVector4a& max = dst_face.mExtents[1]; + +			min = pos[0]; +			max = pos[1]; + +			for (U32 j = 1; j < dst_face.mNumVertices; ++j) +			{ +				min.setMin(min, pos[j]); +				max.setMax(max, pos[j]); +			} + +			dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); +			dst_face.mCenter->mul(0.5f); + +		} + +		{ +			LLFastTimer t(FTM_RIGGED_OCTREE); +			delete dst_face.mOctree; +			dst_face.mOctree = NULL; +			dst_face.createOctree(2.f); +		} +	} +} +  U32 LLVOVolume::getPartitionType() const  {  	if (isHUDAttachment()) @@ -3732,6 +3940,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); +		bool is_rigged = false; +  		//for each face  		for (S32 i = 0; i < drawablep->getNumFaces(); i++)  		{ @@ -3747,8 +3957,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  					facep->mVertexBuffer = NULL;  					facep->mLastVertexBuffer = NULL;  				} -				 +		  				facep->setState(LLFace::RIGGED); +				is_rigged = true;  				//get drawpool of avatar with rigged face  				LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); @@ -3958,6 +4169,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				facep->mLastVertexBuffer = NULL;  			}		  		} + +		if (is_rigged) +		{ +			drawablep->setState(LLDrawable::RIGGED); +		} +		else +		{ +			drawablep->clearState(LLDrawable::RIGGED); +		}  	}  	group->mBufferUsage = useage; diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index eeb98726c9..d868099eeb 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -46,6 +46,8 @@ class LLDrawPool;  class LLSelectNode;  class LLObjectMediaDataClient;  class LLObjectMediaNavigateClient; +class LLVOAvatar; +class LLMeshSkinInfo;  typedef std::vector<viewer_media_t> media_list_t; @@ -54,6 +56,18 @@ enum LLVolumeInterfaceType  	INTERFACE_FLEXIBLE = 1,  }; + +class LLRiggedVolume : public LLVolume +{ +public: +	LLRiggedVolume(const LLVolumeParams& params) +		: LLVolume(params, 0.f) +	{ +	} + +	void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume); +}; +  // Base class for implementations of the volume - Primitive, Flexible Object, etc.  class LLVolumeInterface  { @@ -289,6 +303,11 @@ public:  	void removeMDCImpl() { --mMDCImplCount; }  	S32 getMDCImplCount() { return mMDCImplCount; } + +	//rigged volume update (for raycasting) +	void updateRiggedVolume(); +	LLRiggedVolume* getRiggedVolume() { return mRiggedVolume; } +  protected:  	S32	computeLODDetail(F32	distance, F32 radius);  	BOOL calcLOD(); @@ -322,6 +341,9 @@ private:  	S32			mLastFetchedMediaVersion; // as fetched from the server, starts as -1  	S32 mIndexInTex;  	S32 mMDCImplCount; + +	LLPointer<LLRiggedVolume> mRiggedVolume; +  	// statics  public:  	static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop  | 
