SH-2694 Fix for FPS drop when mousing over flexi objects (don't use an octree for flexi raycast)

Dave Parks 2011-12-16 17:43:30 -06:00
parent 349eabb635
commit d42dc0c367
3 changed files with 111 additions and 36 deletions

View File

@ -80,8 +80,8 @@ public:
typedef LLOctreeTraveler<T> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler;
typedef typename std::set<LLPointer<T> > element_list;
typedef typename std::set<LLPointer<T> >::iterator element_iter;
typedef typename std::set<LLPointer<T> >::const_iterator const_element_iter;
typedef typename element_list::iterator element_iter;
typedef typename element_list::const_iterator const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
typedef typename std::vector<LLOctreeNode<T>* > child_list;
typedef LLTreeNode<T> BaseType;
@ -114,6 +114,8 @@ public:
mOctant = ((oct_node*) mParent)->getOctant(mCenter);
}
mElementCount = 0;
clearChildren();
}
@ -219,11 +221,11 @@ public:
void accept(oct_traveler* visitor) { visitor->visit(this); }
virtual bool isLeaf() const { return mChild.empty(); }
U32 getElementCount() const { return mData.size(); }
U32 getElementCount() const { return mElementCount; }
element_list& getData() { return mData; }
const element_list& getData() const { return mData; }
U32 getChildCount() const { return mChild.size(); }
U32 getChildCount() const { return mChildCount; }
oct_node* getChild(U32 index) { return mChild[index]; }
const oct_node* getChild(U32 index) const { return mChild[index]; }
child_list& getChildren() { return mChild; }
@ -300,17 +302,13 @@ public:
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
#if LL_OCTREE_PARANOIA_CHECK
//if this is a redundant insertion, error out (should never happen)
if (mData.find(data) != mData.end())
{
llwarns << "Redundant octree insertion detected. " << data << llendl;
return false;
}
#endif
llassert(mData.find(data) == mData.end());
mData.insert(data);
BaseType::insert(data);
mElementCount = mData.size();
return true;
}
else
@ -346,6 +344,8 @@ public:
{
mData.insert(data);
BaseType::insert(data);
mElementCount = mData.size();
return true;
}
@ -399,6 +399,7 @@ public:
if (mData.find(data) != mData.end())
{ //we have data
mData.erase(data);
mElementCount = mData.size();
notifyRemoval(data);
checkAlive();
return true;
@ -436,6 +437,7 @@ public:
if (mData.find(data) != mData.end())
{
mData.erase(data);
mElementCount = mData.size();
notifyRemoval(data);
llwarns << "FOUND!" << llendl;
checkAlive();
@ -452,7 +454,7 @@ public:
void clearChildren()
{
mChild.clear();
mChildCount = 0;
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
}
@ -512,9 +514,10 @@ public:
}
#endif
mChildMap[child->getOctant()] = (U8) mChild.size();
mChildMap[child->getOctant()] = mChildCount;
mChild.push_back(child);
++mChildCount;
child->setParent(this);
if (!silent)
@ -534,21 +537,20 @@ public:
oct_listener* listener = getOctListener(i);
listener->handleChildRemoval(this, getChild(index));
}
if (destroy)
{
mChild[index]->destroy();
delete mChild[index];
}
mChild.erase(mChild.begin() + index);
--mChildCount;
//rebuild child map
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
for (U32 i = 0; i < mChild.size(); ++i)
for (U32 i = 0; i < mChildCount; ++i)
{
mChildMap[mChild[i]->getOctant()] = i;
}
@ -601,8 +603,10 @@ protected:
child_list mChild;
U8 mChildMap[8];
U32 mChildCount;
element_list mData;
U32 mElementCount;
};

View File

@ -4615,18 +4615,83 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
genBinormals(i);
}
if (!face.mOctree)
{
face.createOctree();
}
//LLVector4a* p = (LLVector4a*) face.mPositions;
if (isUnique())
{ //don't bother with an octree for flexi volumes
U32 tri_count = face.mNumIndices/3;
LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal);
intersect.traverse(face.mOctree);
if (intersect.mHitFace)
for (U32 j = 0; j < tri_count; ++j)
{
U16 idx0 = face.mIndices[j*3+0];
U16 idx1 = face.mIndices[j*3+1];
U16 idx2 = face.mIndices[j*3+2];
const LLVector4a& v0 = face.mPositions[idx0];
const LLVector4a& v1 = face.mPositions[idx1];
const LLVector4a& v2 = face.mPositions[idx2];
F32 a,b,t;
if (LLTriangleRayIntersect(v0, v1, v2,
start, dir, a, b, t))
{
if ((t >= 0.f) && // if hit is after start
(t <= 1.f) && // and before end
(t < closest_t)) // and this hit is closer
{
closest_t = t;
hit_face = i;
if (intersection != NULL)
{
LLVector4a intersect = dir;
intersect.mul(closest_t);
intersect.add(start);
intersection->set(intersect.getF32ptr());
}
if (tex_coord != NULL)
{
LLVector2* tc = (LLVector2*) face.mTexCoords;
*tex_coord = ((1.f - a - b) * tc[idx0] +
a * tc[idx1] +
b * tc[idx2]);
}
if (normal!= NULL)
{
LLVector4* norm = (LLVector4*) face.mNormals;
*normal = ((1.f - a - b) * LLVector3(norm[idx0]) +
a * LLVector3(norm[idx1]) +
b * LLVector3(norm[idx2]));
}
if (bi_normal != NULL)
{
LLVector4* binormal = (LLVector4*) face.mBinormals;
*bi_normal = ((1.f - a - b) * LLVector3(binormal[idx0]) +
a * LLVector3(binormal[idx1]) +
b * LLVector3(binormal[idx2]));
}
}
}
}
}
else
{
hit_face = i;
if (!face.mOctree)
{
face.createOctree();
}
LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal);
intersect.traverse(face.mOctree);
if (intersect.mHitFace)
{
hit_face = i;
}
}
}
}

View File

@ -3735,11 +3735,7 @@ void renderRaycast(LLDrawable* drawablep)
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
if (!face.mOctree)
{
((LLVolumeFace*) &face)->createOctree();
}
gGL.pushMatrix();
glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]);
glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix);
@ -3762,9 +3758,6 @@ void renderRaycast(LLDrawable* drawablep)
LLVector4a dir;
dir.setSub(enda, starta);
F32 t = 1.f;
LLRenderOctreeRaycast render(starta, dir, &t);
gGL.flush();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@ -3775,8 +3768,21 @@ void renderRaycast(LLDrawable* drawablep)
glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions);
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
}
render.traverse(face.mOctree);
if (!volume->isUnique())
{
F32 t = 1.f;
if (!face.mOctree)
{
((LLVolumeFace*) &face)->createOctree();
}
LLRenderOctreeRaycast render(starta, dir, &t);
render.traverse(face.mOctree);
}
gGL.popMatrix();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}