diff options
| -rw-r--r-- | indra/llmath/llmatrix4a.h | 6 | ||||
| -rw-r--r-- | indra/llmath/llvector4a.h | 7 | ||||
| -rw-r--r-- | indra/llmath/llvolume.cpp | 11 | ||||
| -rw-r--r-- | indra/llprimitive/lldaeloader.cpp | 10 | ||||
| -rw-r--r-- | indra/llprimitive/llmodel.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/lldrawable.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llface.cpp | 17 | ||||
| -rw-r--r-- | indra/newview/llspatialpartition.cpp | 48 | ||||
| -rw-r--r-- | indra/newview/llvieweroctree.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 38 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_object.xml | 2 | 
11 files changed, 121 insertions, 25 deletions
| diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 216334752a..baa3a89176 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -176,4 +176,10 @@ inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res)      res.mMatrix[3] = row3;  } +inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m) +{ +    s << "[" << m.mMatrix[0] << ", " << m.mMatrix[1] << ", " << m.mMatrix[2] << ", " << m.mMatrix[3] << "]"; +    return s; +}  +  #endif diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 79d0a44551..222f3cf235 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -320,7 +320,7 @@ public:  	inline const LLVector4a& operator= ( const LLQuad& rhs );  	inline operator LLQuad() const;	 - +      private:  	LLQuad mQ;  } LL_ALIGN_POSTFIX(16); @@ -331,4 +331,9 @@ inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p  	max.setMax(max, p);  } +inline std::ostream& operator<<(std::ostream& s, const LLVector4a& v) +{ +    s << "(" << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ")"; +    return s; +}  #endif diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index f1e9817cb2..8556e5294c 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2636,6 +2636,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			}  			//calculate bounding box +			// VFExtents change  			LLVector4a& min = face.mExtents[0];  			LLVector4a& max = face.mExtents[1]; @@ -4721,6 +4722,7 @@ LLVolumeFace::~LLVolumeFace()  {  	ll_aligned_free_16(mExtents);  	mExtents = NULL; +	mCenter = NULL;  	freeData();  } @@ -5496,7 +5498,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  	// S32 i;  	S32	grid_size = (profile.size()-1)/4; - +	// VFExtents change  	LLVector4a& min = mExtents[0];  	LLVector4a& max = mExtents[1]; @@ -5773,7 +5775,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	LLVector2 cuv;  	LLVector2 min_uv, max_uv; - +	// VFExtents change  	LLVector4a& min = mExtents[0];  	LLVector4a& max = mExtents[1]; @@ -6398,14 +6400,17 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  		if (offset == 0 && i == 0)  		{ //initialize bounding box +			// VFExtents change  			mExtents[0] = mExtents[1] = dst_pos[i];  		}  		else  		{  			//stretch bounding box +			// VFExtents change  			update_min_max(mExtents[0], mExtents[1], dst_pos[i]);  		}  	} +    LL_DEBUGS("RiggedBox") << "appendFace got extents " << mExtents[0] << ", " << mExtents[1] << " from dst_pos " << LL_ENDL;  	new_count = mNumIndices + face.mNumIndices; @@ -6568,7 +6573,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	{  		update_min_max(face_min, face_max, *cur_pos++);  	} - +	// VFExtents change  	mExtents[0] = face_min;  	mExtents[1] = face_max; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 8401cb976e..8f75d89e5a 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -192,7 +192,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  		{  			return LLModel::BAD_ELEMENT;  		} - +		// VFExtents change  		face.mExtents[0].set(v[0], v[1], v[2]);  		face.mExtents[1].set(v[0], v[1], v[2]);  	} @@ -254,6 +254,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  		if (!found)  		{ +			// VFExtents change  			update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition());  			verts.push_back(cv);  			if (verts.size() >= 65535) @@ -305,6 +306,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  			}  			face = LLVolumeFace(); +			// VFExtents change  			face.mExtents[0].set(v[0], v[1], v[2]);  			face.mExtents[1].set(v[0], v[1], v[2]);  			point_map.clear(); @@ -383,6 +385,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  	if (pos_source)  	{  		v = pos_source->getFloat_array()->getValue(); +		// VFExtents change  		face.mExtents[0].set(v[0], v[1], v[2]);  		face.mExtents[1].set(v[0], v[1], v[2]);  	} @@ -482,6 +485,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  			if (!found)  			{ +				// VFExtents change  				update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition());  				verts.push_back(cv);  				if (verts.size() >= 65535) @@ -551,6 +555,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  				}  				face = LLVolumeFace(); +				// VFExtents change  				face.mExtents[0].set(v[0], v[1], v[2]);  				face.mExtents[1].set(v[0], v[1], v[2]);  				verts.clear(); @@ -734,7 +739,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  	{  		return LLModel::NO_ERRORS;  	} - +	// VFExtents change  	face.mExtents[0] = verts[0].getPosition();  	face.mExtents[1] = verts[0].getPosition(); @@ -758,6 +763,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac  	for (std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.begin(); iter != vert_idx.end(); ++iter)  	{  		new_verts[iter->second] = iter->first; +		// VFExtents change  		update_min_max(face.mExtents[0], face.mExtents[1], iter->first.getPosition());  	} diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index db6d00bc2c..597cc66088 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -276,6 +276,7 @@ void LLModel::normalizeVolumeFaces()  			// We shrink the extents so  			// that they fall within  			// the unit cube. +			// VFExtents change  			face.mExtents[0].add(trans);  			face.mExtents[0].mul(scale); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 6799c3f862..7e51389655 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -51,6 +51,7 @@  #include "llviewerwindow.h"  #include "llvocache.h"  #include "llcontrolavatar.h" +#include "llcallstack.h"  const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;  const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; @@ -1086,7 +1087,8 @@ void LLDrawable::setGroup(LLViewerOctreeGroup *groupp)  	llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this));  	if (cur_groupp != groupp && getVOVolume()) -	{ //NULL out vertex buffer references for volumes on spatial group change to maintain +	{ +		//NULL out vertex buffer references for volumes on spatial group change to maintain  		//requirement that every face vertex buffer is either NULL or points to a vertex buffer  		//contained by its drawable's spatial group  		for (S32 i = 0; i < getNumFaces(); ++i) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 0a7e0c92be..efd57ec39f 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -831,6 +831,9 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		min = face.mExtents[0];  		max = face.mExtents[1]; +        LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " starting extents " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; +        LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " starting vf extents " << face.mExtents[0] << ", " << face.mExtents[1] << " num verts " << face.mNumVertices << LL_ENDL; +  		llassert(less_than_max_mag(min));  		llassert(less_than_max_mag(max)); @@ -859,6 +862,14 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		v[6] = min;  		v[7] = max; +        // MAINT-8264 - stray vertices, especially in low LODs, cause bounding box errors. +		if (face.mNumVertices < 3)  +        { +            LL_DEBUGS("RiggedBox") << "skipping face " << f << ", bad num vertices "  +                                   << face.mNumVertices << " " << face.mNumIndices << " " << face.mWeights << LL_ENDL; +            return FALSE; +        } +          		for (U32 i = 0; i < 6; ++i)  		{  			v[i].setSelectWithMask(mask[i], min, max); @@ -866,10 +877,13 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		LLVector4a tv[8]; +        LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " mat is " << mat_vert << LL_ENDL; +  		//transform bounding box into drawable space  		for (U32 i = 0; i < 8; ++i)  		{  			mat_vert.affineTransform(v[i], tv[i]); +            LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " i " << i << " v and tv " << v[i] << ", " << tv[i] << LL_ENDL;  		}  		//find bounding box @@ -883,6 +897,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  			newMin.setMin(newMin, tv[i]);  			newMax.setMax(newMax, tv[i]);  		} +        LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " bbox gave extents " << mExtents[0] << ", " << mExtents[1] << LL_ENDL;  		if (!mDrawablep->isActive())  		{	// Shift position for region @@ -890,8 +905,10 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  			offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);  			newMin.add(offset);  			newMax.add(offset); +            LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " not active, added offset " << offset << LL_ENDL;  		} +        LL_DEBUGS("RiggedBox") << "updated extents for face " << f << " to " << mExtents[0] << ", " << mExtents[1] << LL_ENDL;  		LLVector4a t;  		t.setAdd(newMin,newMax);  		t.mul(0.5f); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index d0328a7539..8b1a23fe89 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -29,6 +29,7 @@  #include "llspatialpartition.h"  #include "llappviewer.h" +#include "llcallstack.h"  #include "lltexturecache.h"  #include "lltexturefetch.h"  #include "llimageworker.h" @@ -777,6 +778,10 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)  		dist = eye.getLength3().getF32();  	} +    LL_DEBUGS("RiggedBox") << "calcDistance, group " << group << " camera " << origin << " obj bounds "  +                           << group->mObjectBounds[0] << ", " << group->mObjectBounds[1]  +                           << " dist " << dist << " radius " << group->mRadius << LL_ENDL; +  	if (dist < 16.f)  	{  		dist /= 16.f; @@ -808,7 +813,8 @@ F32 LLSpatialGroup::getUpdateUrgency() const  BOOL LLSpatialGroup::changeLOD()  {  	if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) -	{ ///a rebuild is going to happen, update distance and LoD +	{ +		//a rebuild is going to happen, update distance and LoD  		return TRUE;  	} @@ -816,8 +822,28 @@ BOOL LLSpatialGroup::changeLOD()  	{  		F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius)); +        // MAINT-8264 - this check is not robust if it needs to work +        // for bounding boxes much larger than the actual enclosed +        // objects, and using distance to box center is also +        // problematic. Consider the case that you have a large box +        // where the enclosed object is in one corner. As you zoom in +        // on the corner, the object gets much closer to the camera, +        // but the distance to the box center changes very little, and +        // an LOD change will not trigger, so object LOD gets "stuck" +        // at a too-low value. In the case of the above JIRA, the box +        // was large only due to another error, so this logic did not +        // need to be changed. +  		if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio)  		{ +            LL_DEBUGS("RiggedBox") << "changeLOD true because of ratio compare " +                                   << fabsf(ratio) << " " << getSpatialPartition()->mSlopRatio << LL_ENDL; +            LL_DEBUGS("RiggedBox") << "sg " << this << "\nmDistance " << mDistance +                                   << " mLastUpdateDistance " << mLastUpdateDistance +                                   << " mRadius " << mRadius +                                   << " fab ratio " << fabsf(ratio)  +                                   << " slop " << getSpatialPartition()->mSlopRatio << LL_ENDL; +         			return TRUE;  		} @@ -2109,17 +2135,17 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)  	{  		if (drawable->isSpatialBridge())  		{ -			gGL.diffuseColor4f(1,0.5f,0,1); +			gGL.diffuseColor4f(1,0.5f,0,1); // orange  		}  		else if (drawable->getVOVolume()) -		{ -			if (drawable->isRoot()) +		{  +            if (drawable->isRoot())  			{ -				gGL.diffuseColor4f(1,1,0,1); +				gGL.diffuseColor4f(1,1,0,1); // yellow  			}  			else  			{ -				gGL.diffuseColor4f(0,1,0,1); +				gGL.diffuseColor4f(0,1,0,1); // green  			}  		}  		else if (drawable->getVObj()) @@ -2127,24 +2153,24 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)  			switch (drawable->getVObj()->getPCode())  			{  				case LLViewerObject::LL_VO_SURFACE_PATCH: -						gGL.diffuseColor4f(0,1,1,1); +                    	gGL.diffuseColor4f(0,1,1,1); // cyan  						break;  				case LLViewerObject::LL_VO_CLOUDS:  						// no longer used  						break;  				case LLViewerObject::LL_VO_PART_GROUP:  				case LLViewerObject::LL_VO_HUD_PART_GROUP: -						gGL.diffuseColor4f(0,0,1,1); +                    	gGL.diffuseColor4f(0,0,1,1); // blue  						break;  				case LLViewerObject::LL_VO_VOID_WATER:  				case LLViewerObject::LL_VO_WATER: -						gGL.diffuseColor4f(0,0.5f,1,1); +                    	gGL.diffuseColor4f(0,0.5f,1,1); // medium blue  						break;  				case LL_PCODE_LEGACY_TREE: -						gGL.diffuseColor4f(0,0.5f,0,1); +                    	gGL.diffuseColor4f(0,0.5f,0,1); // dark green  						break;  				default: -						gGL.diffuseColor4f(1,0,1,1); +                    	gGL.diffuseColor4f(1,0,1,1); // magenta  						break;  			}  		} diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 023f1b92ba..e7916ebd3b 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -731,7 +731,7 @@ bool LLViewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4  			update_min_max(newMin, newMax, minMax[0]);  			update_min_max(newMin, newMax, minMax[1]);  		} -		 +  		mObjectBounds[0].setAdd(newMin, newMax);  		mObjectBounds[0].mul(0.5f);  		mObjectBounds[1].setSub(newMax, newMin); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c007b446f7..a07e3f8be1 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1515,14 +1515,22 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  	BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); -	//	bool rigged = false; +    if (getRiggedVolume()) +    { +        updateRiggedVolume(TRUE); +    } +      	LLVolume* volume = mRiggedVolume;  	if (!volume)  	{  		volume = getVolume();  	} -	// There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() +    if (getRiggedVolume()) +    { +        LL_DEBUGS("RiggedBox") << "rebuilding box, volume face count " << getVolume()->getNumVolumeFaces() << " drawable face count " << mDrawable->getNumFaces() << LL_ENDL; +    } +    // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces()  	for (S32 i = 0;  		 i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs();  		 i++) @@ -1532,12 +1540,18 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  		{  			continue;  		} -		res &= face->genVolumeBBoxes(*volume, i, -										mRelativeXform,  -										(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); + +        BOOL face_res = face->genVolumeBBoxes(*volume, i, +                                              mRelativeXform,  +                                              (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); +        res &= face_res; // note that this result is never used  		if (rebuild)  		{ +            if (getRiggedVolume()) +            { +                LL_DEBUGS("RiggedBox") << "rebuilding box, face " << i << " extents " << face->mExtents[0] << ", " << face->mExtents[1] << LL_ENDL; +            }  			if (i == 0)  			{  				min = face->mExtents[0]; @@ -1545,6 +1559,11 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  			}  			else  			{ +                if (!face_res) +                { +                    // MAINT-8264 - ignore bboxes of ill-formed faces. +                    continue; +                }  				min.setMin(min, face->mExtents[0]);  				max.setMax(max, face->mExtents[1]);  			} @@ -1553,6 +1572,10 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  	if (rebuild)  	{ +        if (getRiggedVolume()) +        { +            LL_DEBUGS("RiggedBox") << "rebuilding got extents " << min << ", " << max << LL_ENDL; +        }  		mDrawable->setSpatialExtents(min,max);  		min.add(max);  		min.mul(0.5f); @@ -4512,6 +4535,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  				}  				//update bounding box +				// VFExtents change  				LLVector4a& min = dst_face.mExtents[0];  				LLVector4a& max = dst_face.mExtents[1]; @@ -4528,6 +4552,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  					min.setMin(min, pos[j]);  					max.setMax(max, pos[j]);  				} +                  box_min.setMin(min,box_min);                  box_max.setMax(max,box_max); @@ -5065,6 +5090,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)                                                  << " is_animated " << vobj->isAnimatedObject()                                                  << " can_animate " << vobj->canBeAnimatedObject()                                                   << " cav " << vobj->getControlAvatar()  +                                                << " lod " << vobj->getLOD() +                                                << " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED)) +                                                << " drawable state " << drawablep->getState()                                                  << " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false)                                                  << " frame " << LLFrameTimer::getFrameCount()                                                  << LL_ENDL; diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml index 91e7328979..ce34508303 100644 --- a/indra/newview/skins/default/xui/en/menu_object.xml +++ b/indra/newview/skins/default/xui/en/menu_object.xml @@ -228,6 +228,6 @@              <menu_item_call.on_click                  function="Avatar.ResetSkeleton" />              <menu_item_call.on_visible -             function="Advanced.EnableResetSkeleton"/> +             function="Avatar.EnableResetSkeleton"/>      </menu_item_call>  </context_menu> | 
