summaryrefslogtreecommitdiff
path: root/indra/newview/llspatialpartition.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llspatialpartition.cpp')
-rw-r--r--indra/newview/llspatialpartition.cpp520
1 files changed, 324 insertions, 196 deletions
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 355173772b..3cf0138303 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -102,23 +102,6 @@ void sg_assert(BOOL expr)
#endif
}
-#if LL_DEBUG
-void validate_drawable(LLDrawable* drawablep)
-{
- F64 rad = drawablep->getBinRadius();
- const LLVector3* ext = drawablep->getSpatialExtents();
-
- if (rad < 0 || rad > 4096 ||
- (ext[1]-ext[0]).magVec() > 4096)
- {
- llwarns << "Invalid drawable found in octree." << llendl;
- }
-}
-#else
-#define validate_drawable(x)
-#endif
-
-
S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad)
{
return AABBSphereIntersectR2(min, max, origin, rad*rad);
@@ -158,6 +141,55 @@ S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVe
}
+S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad)
+{
+ return AABBSphereIntersectR2(min, max, origin, rad*rad);
+}
+
+S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r)
+{
+ F32 d = 0.f;
+ F32 t;
+
+ LLVector4a origina;
+ origina.load3(origin.mV);
+
+ LLVector4a v;
+ v.setSub(min, origina);
+
+ if (v.dot3(v) < r)
+ {
+ v.setSub(max, origina);
+ if (v.dot3(v) < r)
+ {
+ return 2;
+ }
+ }
+
+
+ for (U32 i = 0; i < 3; i++)
+ {
+ if (origin.mV[i] < min[i])
+ {
+ t = min[i] - origin.mV[i];
+ d += t*t;
+ }
+ else if (origin.mV[i] > max[i])
+ {
+ t = origin.mV[i] - max[i];
+ d += t*t;
+ }
+
+ if (d > r)
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+
typedef enum
{
b000 = 0x00,
@@ -193,24 +225,13 @@ static U8 sOcclusionIndices[] =
b000, b110, b100, b101, b001, b011, b010, b110,
};
-U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center)
+U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
{
- LLVector3 d = center - camera->getOrigin();
-
- U8 cypher = 0;
- if (d.mV[0] > 0)
- {
- cypher |= b100;
- }
- if (d.mV[1] > 0)
- {
- cypher |= b010;
- }
- if (d.mV[2] > 0)
- {
- cypher |= b001;
- }
+ LLVector4a origin;
+ origin.load3(camera->getOrigin().mV);
+ S32 cypher = center.greaterThan4(origin).getComparisonMask() & 0x7;
+
return sOcclusionIndices+cypher*8;
}
@@ -218,33 +239,49 @@ void LLSpatialGroup::buildOcclusion()
{
if (!mOcclusionVerts)
{
- mOcclusionVerts = new F32[8*3];
+ mOcclusionVerts = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*8, 16);
}
- LLVector3 r = mBounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE);
+ LLVector4a fudge;
+ fudge.splat(SG_OCCLUSION_FUDGE);
- for (U32 k = 0; k < 3; k++)
- {
- r.mV[k] = llmin(mBounds[1].mV[k]+0.25f, r.mV[k]);
- }
+ LLVector4a r;
+ r.setAdd(mBounds[1], fudge);
- F32* v = mOcclusionVerts;
- F32* c = mBounds[0].mV;
- F32* s = r.mV;
+ LLVector4a r2;
+ r2.splat(0.25f);
+ r2.add(mBounds[1]);
+
+ r.setMin(r2);
+
+ LLVector4a* v = mOcclusionVerts;
+ const LLVector4a& c = mBounds[0];
+ const LLVector4a& s = r;
+ static const LLVector4a octant[] =
+ {
+ LLVector4a(-1.f, -1.f, -1.f),
+ LLVector4a(-1.f, -1.f, 1.f),
+ LLVector4a(-1.f, 1.f, -1.f),
+ LLVector4a(-1.f, 1.f, 1.f),
+
+ LLVector4a(1.f, -1.f, -1.f),
+ LLVector4a(1.f, -1.f, 1.f),
+ LLVector4a(1.f, 1.f, -1.f),
+ LLVector4a(1.f, 1.f, 1.f),
+ };
+
//vertex positions are encoded so the 3 bits of their vertex index
//correspond to their axis facing, with bit position 3,2,1 matching
//axis facing x,y,z, bit set meaning positive facing, bit clear
//meaning negative facing
- v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000
- v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001
- v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010
- v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011
-
- v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100
- v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101
- v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110
- v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111
+
+ for (S32 i = 0; i < 8; ++i)
+ {
+ v[i] = s;
+ v[i].mul(octant[i]);
+ v[i].add(c);
+ }
clearState(LLSpatialGroup::OCCLUSION_DIRTY);
}
@@ -288,6 +325,11 @@ LLSpatialGroup::~LLSpatialGroup()
llerrs << "Illegal deletion of LLSpatialGroup!" << llendl;
}*/
+ if (gDebugGL)
+ {
+ gPipeline.checkReferences(this);
+ }
+
if (isState(DEAD))
{
sZombieGroups--;
@@ -300,11 +342,13 @@ LLSpatialGroup::~LLSpatialGroup()
sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
}
- delete [] mOcclusionVerts;
+ _mm_free(mOcclusionVerts);
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
clearDrawMap();
clearAtlasList() ;
+
+ _mm_free(mBounds);
}
BOOL LLSpatialGroup::hasAtlas(LLTextureAtlas* atlasp)
@@ -456,8 +500,10 @@ void LLSpatialGroup::validate()
sg_assert(!isState(DIRTY));
sg_assert(!isDead());
- LLVector3 myMin = mBounds[0] - mBounds[1];
- LLVector3 myMax = mBounds[0] + mBounds[1];
+ LLVector4a myMin;
+ myMin.setSub(mBounds[0], mBounds[1]);
+ LLVector4a myMax;
+ myMax.setAdd(mBounds[0], mBounds[1]);
validateDrawMap();
@@ -489,16 +535,18 @@ void LLSpatialGroup::validate()
group->validate();
//ensure all children are enclosed in this node
- LLVector3 center = group->mBounds[0];
- LLVector3 size = group->mBounds[1];
+ LLVector4a center = group->mBounds[0];
+ LLVector4a size = group->mBounds[1];
- LLVector3 min = center - size;
- LLVector3 max = center + size;
+ LLVector4a min;
+ min.setSub(center, size);
+ LLVector4a max;
+ max.setAdd(center, size);
for (U32 j = 0; j < 3; j++)
{
- sg_assert(min.mV[j] >= myMin.mV[j]-0.02f);
- sg_assert(max.mV[j] <= myMax.mV[j]+0.02f);
+ sg_assert(min[j] >= myMin[j]-0.02f);
+ sg_assert(max[j] <= myMax[j]+0.02f);
}
}
@@ -508,8 +556,8 @@ void LLSpatialGroup::validate()
void LLSpatialGroup::checkStates()
{
#if LL_OCTREE_PARANOIA_CHECK
- LLOctreeStateCheck checker;
- checker.traverse(mOctreeNode);
+ //LLOctreeStateCheck checker;
+ //checker.traverse(mOctreeNode);
#endif
}
@@ -534,19 +582,17 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
drawablep->updateSpatialExtents();
- validate_drawable(drawablep);
OctreeNode* parent = mOctreeNode->getOctParent();
if (mOctreeNode->isInside(drawablep->getPositionGroup()) &&
(mOctreeNode->contains(drawablep) ||
- (drawablep->getBinRadius() > mOctreeNode->getSize().mdV[0] &&
+ (drawablep->getBinRadius() > mOctreeNode->getSize()[0] &&
parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY)))
{
unbound();
setState(OBJECT_DIRTY);
//setState(GEOM_DIRTY);
- validate_drawable(drawablep);
return TRUE;
}
@@ -564,7 +610,6 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc
else
{
drawablep->setSpatialGroup(this);
- validate_drawable(drawablep);
setState(OBJECT_DIRTY | GEOM_DIRTY);
setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
gPipeline.markRebuild(this, TRUE);
@@ -665,7 +710,7 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group)
}
-BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut)
+BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut)
{
const OctreeNode* node = mOctreeNode;
@@ -678,8 +723,8 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO
return FALSE;
}
- LLVector3& newMin = mObjectExtents[0];
- LLVector3& newMax = mObjectExtents[1];
+ LLVector4a& newMin = mObjectExtents[0];
+ LLVector4a& newMax = mObjectExtents[1];
if (isState(OBJECT_DIRTY))
{ //calculate new bounding box
@@ -688,10 +733,10 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO
//initialize bounding box to first element
OctreeNode::const_element_iter i = node->getData().begin();
LLDrawable* drawablep = *i;
- const LLVector3* minMax = drawablep->getSpatialExtents();
+ const LLVector4a* minMax = drawablep->getSpatialExtents();
- newMin.setVec(minMax[0]);
- newMax.setVec(minMax[1]);
+ newMin = minMax[0];
+ newMax = minMax[1];
for (++i; i != node->getData().end(); ++i)
{
@@ -715,8 +760,10 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO
}*/
}
- mObjectBounds[0] = (newMin + newMax) * 0.5f;
- mObjectBounds[1] = (newMax - newMin) * 0.5f;
+ mObjectBounds[0].setAdd(newMin, newMax);
+ mObjectBounds[0].mul(0.5f);
+ mObjectBounds[1].setSub(newMax, newMin);
+ mObjectBounds[1].mul(0.5f);
}
if (empty)
@@ -726,17 +773,8 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO
}
else
{
- for (U32 i = 0; i < 3; i++)
- {
- if (newMin.mV[i] < minOut.mV[i])
- {
- minOut.mV[i] = newMin.mV[i];
- }
- if (newMax.mV[i] > maxOut.mV[i])
- {
- maxOut.mV[i] = newMax.mV[i];
- }
- }
+ minOut.setMin(newMin);
+ maxOut.setMax(newMax);
}
return TRUE;
@@ -827,18 +865,19 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
return TRUE;
}
-void LLSpatialGroup::shift(const LLVector3 &offset)
+void LLSpatialGroup::shift(const LLVector4a &offset)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
- LLVector3d offsetd(offset);
- mOctreeNode->setCenter(mOctreeNode->getCenter()+offsetd);
+ LLVector4a t = mOctreeNode->getCenter();
+ t.add(offset);
+ mOctreeNode->setCenter(t);
mOctreeNode->updateMinMax();
- mBounds[0] += offset;
- mExtents[0] += offset;
- mExtents[1] += offset;
- mObjectBounds[0] += offset;
- mObjectExtents[0] += offset;
- mObjectExtents[1] += offset;
+ mBounds[0].add(offset);
+ mExtents[0].add(offset);
+ mExtents[1].add(offset);
+ mObjectBounds[0].add(offset);
+ mObjectExtents[0].add(offset);
+ mObjectExtents[1].add(offset);
//if (!mSpatialPartition->mRenderByGroup)
{
@@ -850,10 +889,7 @@ void LLSpatialGroup::shift(const LLVector3 &offset)
{
for (U32 i = 0; i < 8; i++)
{
- F32* v = mOcclusionVerts+i*3;
- v[0] += offset.mV[0];
- v[1] += offset.mV[1];
- v[2] += offset.mV[2];
+ mOcclusionVerts[i].add(offset);
}
}
}
@@ -1119,8 +1155,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mDepth(0.f),
mLastUpdateDistance(-1.f),
mLastUpdateTime(gFrameTimeSeconds),
- mViewAngle(0.f),
- mLastUpdateViewAngle(-1.f),
mAtlasList(4),
mCurUpdatingTime(0),
mCurUpdatingSlotp(NULL),
@@ -1129,13 +1163,25 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
sNodeCount++;
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
+ mBounds = (LLVector4a*) _mm_malloc(sizeof(LLVector4a) * V4_COUNT, 16);
+ mExtents = mBounds + EXTENTS;
+ mObjectBounds = mBounds + OBJECT_BOUNDS;
+ mObjectExtents = mBounds + OBJECT_EXTENTS;
+ mViewAngle = mBounds+VIEW_ANGLE;
+ mLastUpdateViewAngle = mBounds+LAST_VIEW_ANGLE;
+
+ mViewAngle->splat(0.f);
+ mLastUpdateViewAngle->splat(-1.f);
+ mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =
+ mObjectExtents[0] = mObjectExtents[1] = *mViewAngle;
+
sg_assert(mOctreeNode->getListenerCount() == 0);
mOctreeNode->addListener(this);
setState(SG_INITIAL_STATE_MASK);
gPipeline.markRebuild(this, TRUE);
- mBounds[0] = LLVector3(node->getCenter());
- mBounds[1] = LLVector3(node->getSize());
+ mBounds[0] = node->getCenter();
+ mBounds[1] = node->getSize();
part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod;
mLODHash = part->mLODSeed;
@@ -1172,8 +1218,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
#endif
if (!getData().empty())
{
- mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() :
- (F32) mOctreeNode->getSize().magVec();
+ mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].length3() :
+ (F32) mOctreeNode->getSize().length3();
mDistance = mSpatialPartition->calcDistance(this, camera);
mPixelArea = mSpatialPartition->calcPixelArea(this, camera);
}
@@ -1181,27 +1227,34 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)
{
- LLVector3 eye = group->mObjectBounds[0] - camera.getOrigin();
+ LLVector4a eye;
+ LLVector4a origin;
+ origin.load3(camera.getOrigin().mV);
+
+ eye.setSub(group->mObjectBounds[0], origin);
F32 dist = 0.f;
if (group->mDrawMap.find(LLRenderPass::PASS_ALPHA) != group->mDrawMap.end())
{
- LLVector3 v = eye;
- dist = eye.normVec();
+ LLVector4a v = eye;
+
+ dist = eye.length3();
+ eye.normalize3fast();
if (!group->isState(LLSpatialGroup::ALPHA_DIRTY))
{
if (!group->mSpatialPartition->isBridge())
{
- LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0),
- eye * LLVector3(0,1,0),
- eye * LLVector3(0,0,1));
+ LLVector4a view_angle = eye;
- if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f)
+ LLVector4a diff;
+ diff.setSub(view_angle, *group->mLastUpdateViewAngle);
+
+ if (diff.length3() > 0.64f)
{
- group->mViewAngle = view_angle;
- group->mLastUpdateViewAngle = view_angle;
+ *group->mViewAngle = view_angle;
+ *group->mLastUpdateViewAngle = view_angle;
//for occasional alpha sorting within the group
//NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order,
//not setting this node to dirty would be a very good thing
@@ -1215,17 +1268,20 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)
LLVector3 at = camera.getAtAxis();
- //front of bounding box
- for (U32 i = 0; i < 3; i++)
- {
- v.mV[i] -= group->mObjectBounds[1].mV[i]*0.25f * at.mV[i];
- }
+ LLVector4a ata;
+ ata.load3(at.mV);
- group->mDepth = v * at;
+ LLVector4a t = ata;
+ //front of bounding box
+ t.mul(0.25f);
+ t.mul(group->mObjectBounds[1]);
+ v.sub(t);
+
+ group->mDepth = v.dot3(ata);
}
else
{
- dist = eye.magVec();
+ dist = eye.length3();
}
if (dist < 16.f)
@@ -1378,7 +1434,7 @@ void LLSpatialGroup::destroyGL()
}
}
- delete [] mOcclusionVerts;
+ _mm_free(mOcclusionVerts);
mOcclusionVerts = NULL;
for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i)
@@ -1421,8 +1477,8 @@ BOOL LLSpatialGroup::rebound()
}
else
{
- LLVector3& newMin = mExtents[0];
- LLVector3& newMax = mExtents[1];
+ LLVector4a& newMin = mExtents[0];
+ LLVector4a& newMax = mExtents[1];
LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
group->clearState(SKIP_FRUSTUM_CHECK);
group->rebound();
@@ -1436,26 +1492,19 @@ BOOL LLSpatialGroup::rebound()
group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0);
group->clearState(SKIP_FRUSTUM_CHECK);
group->rebound();
- const LLVector3& max = group->mExtents[1];
- const LLVector3& min = group->mExtents[0];
+ const LLVector4a& max = group->mExtents[1];
+ const LLVector4a& min = group->mExtents[0];
- for (U32 j = 0; j < 3; j++)
- {
- if (max.mV[j] > newMax.mV[j])
- {
- newMax.mV[j] = max.mV[j];
- }
- if (min.mV[j] < newMin.mV[j])
- {
- newMin.mV[j] = min.mV[j];
- }
- }
+ newMax.setMax(max);
+ newMin.setMin(min);
}
boundObjects(FALSE, newMin, newMax);
- mBounds[0] = (newMin + newMax)*0.5f;
- mBounds[1] = (newMax - newMin)*0.5f;
+ mBounds[0].setAdd(newMin, newMax);
+ mBounds[0].mul(0.5f);
+ mBounds[1].setSub(newMax, newMin);
+ mBounds[1].mul(0.5f);
}
setState(OCCLUSION_DIRTY);
@@ -1540,7 +1589,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
}
glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
- glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts);
+ glVertexPointer(3, GL_FLOAT, 16, mOcclusionVerts);
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
@@ -1581,8 +1630,11 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32
LLGLNamePool::registerPool(&sQueryPool);
- mOctree = new LLSpatialGroup::OctreeRoot(LLVector3d(0,0,0),
- LLVector3d(1,1,1),
+ LLVector4a center, size;
+ center.splat(0.f);
+ size.splat(1.f);
+
+ mOctree = new LLSpatialGroup::OctreeRoot(center,size,
NULL);
new LLSpatialGroup(mOctree, this);
}
@@ -1602,7 +1654,6 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
drawablep->updateSpatialExtents();
- validate_drawable(drawablep);
//keep drawable from being garbage collected
LLPointer<LLDrawable> ptr = drawablep;
@@ -1686,16 +1737,16 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL
class LLSpatialShift : public LLSpatialGroup::OctreeTraveler
{
public:
- LLSpatialShift(LLVector3 offset) : mOffset(offset) { }
+ const LLVector4a& mOffset;
+
+ LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { }
virtual void visit(const LLSpatialGroup::OctreeNode* branch)
{
((LLSpatialGroup*) branch->getListener(0))->shift(mOffset);
}
-
- LLVector3 mOffset;
};
-void LLSpatialPartition::shift(const LLVector3 &offset)
+void LLSpatialPartition::shift(const LLVector4a &offset)
{ //shift octree node bounding boxes by offset
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
LLSpatialShift shifter(offset);
@@ -1857,7 +1908,7 @@ public:
class LLOctreeCullVisExtents: public LLOctreeCullShadow
{
public:
- LLOctreeCullVisExtents(LLCamera* camera, LLVector3& min, LLVector3& max)
+ LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max)
: LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { }
virtual bool earlyFail(LLSpatialGroup* group)
@@ -1924,8 +1975,8 @@ public:
}
BOOL mEmpty;
- LLVector3& mMin;
- LLVector3& mMax;
+ LLVector4a& mMin;
+ LLVector4a& mMax;
};
class LLOctreeCullDetectVisible: public LLOctreeCullShadow
@@ -2029,6 +2080,11 @@ void drawBox(const LLVector3& c, const LLVector3& r)
gGL.end();
}
+void drawBox(const LLVector4a& c, const LLVector4a& r)
+{
+ drawBox(reinterpret_cast<const LLVector3&>(c), reinterpret_cast<const LLVector3&>(r));
+}
+
void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
{
LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
@@ -2075,6 +2131,11 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
gGL.end();
}
+void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size)
+{
+ drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size));
+}
+
class LLOctreeDirty : public LLOctreeTraveler<LLDrawable>
{
public:
@@ -2118,14 +2179,21 @@ BOOL LLSpatialPartition::isOcclusionEnabled()
BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax)
{
+ LLVector4a visMina, visMaxa;
+ visMina.load3(visMin.mV);
+ visMaxa.load3(visMax.mV);
+
{
LLFastTimer ftm(FTM_CULL_REBOUND);
LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
group->rebound();
}
- LLOctreeCullVisExtents vis(&camera, visMin, visMax);
+ LLOctreeCullVisExtents vis(&camera, visMina, visMaxa);
vis.traverse(mOctree);
+
+ visMin.set(visMina.getF32());
+ visMax.set(visMina.getF32());
return vis.mEmpty;
}
@@ -2188,25 +2256,36 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group)
}
const F32 vel = SG_OCCLUSION_FUDGE*2.f;
- LLVector3 c = group->mBounds[0];
- LLVector3 r = group->mBounds[1] + LLVector3(vel,vel,vel);
-
+ LLVector4a fudge;
+ fudge.splat(vel);
+
+ const LLVector4a& c = group->mBounds[0];
+ LLVector4a r;
+ r.setAdd(group->mBounds[1], fudge);
+
/*if (r.magVecSquared() > 1024.0*1024.0)
{
return TRUE;
}*/
- LLVector3 e = camera->getOrigin();
+ LLVector4a e;
+ e.load3(camera->getOrigin().mV);
- LLVector3 min = c - r;
- LLVector3 max = c + r;
+ LLVector4a min;
+ min.setSub(c,r);
+ LLVector4a max;
+ max.setAdd(c,r);
- for (U32 j = 0; j < 3; j++)
+ S32 lt = e.lessThan4(min).getComparisonMask() & 0x7;
+ if (lt)
{
- if (e.mV[j] < min.mV[j] || e.mV[j] > max.mV[j])
- {
- return FALSE;
- }
+ return FALSE;
+ }
+
+ S32 gt = e.greaterThan4(max).getComparisonMask() & 0x7;
+ if (gt)
+ {
+ return FALSE;
}
return TRUE;
@@ -2411,7 +2490,13 @@ void renderOctree(LLSpatialGroup* group)
}
gGL.color4fv(col.mV);
- drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f));
+ LLVector4a fudge;
+ fudge.splat(0.001f);
+ LLVector4a size = group->mObjectBounds[1];
+ size.mul(1.01f);
+ size.add(fudge);
+
+ drawBox(group->mObjectBounds[0], fudge);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -2442,8 +2527,12 @@ void renderOctree(LLSpatialGroup* group)
for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
{
LLDrawInfo* draw_info = *j;
- LLVector3 center = (draw_info->mExtents[1] + draw_info->mExtents[0])*0.5f;
- LLVector3 size = (draw_info->mExtents[1] - draw_info->mExtents[0])*0.5f;
+ LLVector4a center;
+ center.setAdd(draw_info->mExtents[1], draw_info->mExtents[0]);
+ center.mul(0.5f);
+ LLVector4a size;
+ size.setSub(draw_info->mExtents[1], draw_info->mExtents[0]);
+ size.mul(0.5f);
drawBoxOutline(center, size);
}
}
@@ -2493,7 +2582,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
else if (camera && group->mOcclusionVerts)
{
LLVertexBuffer::unbind();
- glVertexPointer(3, GL_FLOAT, 0, group->mOcclusionVerts);
+ glVertexPointer(3, GL_FLOAT, 16, group->mOcclusionVerts);
glColor4f(1.0f, 0.f, 0.f, 0.5f);
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0]));
@@ -2572,8 +2661,8 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
}
}
- const LLVector3* ext;
- LLVector3 pos, size;
+ const LLVector4a* ext;
+ LLVector4a pos, size;
//render face bounding boxes
for (S32 i = 0; i < drawable->getNumFaces(); i++)
@@ -2582,20 +2671,21 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
ext = facep->mExtents;
- if (ext[0].isExactlyZero() && ext[1].isExactlyZero())
- {
- continue;
- }
- pos = (ext[0] + ext[1]) * 0.5f;
- size = (ext[1] - ext[0]) * 0.5f;
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
+
drawBoxOutline(pos,size);
}
//render drawable bounding box
ext = drawable->getSpatialExtents();
- pos = (ext[0] + ext[1]) * 0.5f;
- size = (ext[1] - ext[0]) * 0.5f;
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
LLViewerObject* vobj = drawable->getVObj();
if (vobj && vobj->onActiveList())
@@ -2651,8 +2741,13 @@ void renderTexturePriority(LLDrawable* drawable)
// gGL.color4f(1,0,1,1);
//}
- LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f;
- LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f);
+ LLVector4a center;
+ center.setAdd(facep->mExtents[1],facep->mExtents[0]);
+ center.mul(0.5f);
+ LLVector4a size;
+ size.setSub(facep->mExtents[1],facep->mExtents[0]);
+ size.mul(0.5f);
+ size.add(LLVector4a(0.01f));
drawBox(center, size);
/*S32 boost = imagep->getBoostLevel();
@@ -2676,7 +2771,6 @@ void renderPoints(LLDrawable* drawablep)
{
gGL.begin(LLRender::POINTS);
gGL.color3f(1,1,1);
- LLVector3 center(drawablep->getPositionGroup());
for (S32 i = 0; i < drawablep->getNumFaces(); i++)
{
gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV);
@@ -2708,8 +2802,12 @@ void renderShadowFrusta(LLDrawInfo* params)
LLGLEnable blend(GL_BLEND);
gGL.setSceneBlendType(LLRender::BT_ADD);
- LLVector3 center = (params->mExtents[1]+params->mExtents[0])*0.5f;
- LLVector3 size = (params->mExtents[1]-params->mExtents[0])*0.5f;
+ LLVector4a center;
+ center.setAdd(params->mExtents[1], params->mExtents[0]);
+ center.mul(0.5f);
+ LLVector4a size;
+ size.setSub(params->mExtents[1],params->mExtents[0]);
+ size.mul(0.5f);
if (gPipeline.mShadowCamera[4].AABBInFrustum(center, size))
{
@@ -2753,10 +2851,14 @@ void renderLights(LLDrawable* drawablep)
pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX);
}
- const LLVector3* ext = drawablep->getSpatialExtents();
+ const LLVector4a* ext = drawablep->getSpatialExtents();
- LLVector3 pos = (ext[0] + ext[1]) * 0.5f;
- LLVector3 size = (ext[1] - ext[0]) * 0.5f;
+ LLVector4a pos;
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ LLVector4a size;
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
{
LLGLDepthTest depth(GL_FALSE, GL_TRUE);
@@ -2766,7 +2868,7 @@ void renderLights(LLDrawable* drawablep)
gGL.color4f(1,1,0,1);
F32 rad = drawablep->getVOVolume()->getLightRadius();
- drawBoxOutline(pos, LLVector3(rad,rad,rad));
+ drawBoxOutline(pos, LLVector4a(rad));
}
}
@@ -2781,7 +2883,7 @@ public:
mDir.setSub(mEnd, mStart);
}
- void visit(const LLOctreeNode<LLVolumeFace::Triangle>* branch)
+ void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0);
@@ -2859,10 +2961,14 @@ void renderRaycast(LLDrawable* drawablep)
glPopMatrix();
// draw bounding box of prim
- const LLVector3* ext = drawablep->getSpatialExtents();
+ const LLVector4a* ext = drawablep->getSpatialExtents();
- LLVector3 pos = (ext[0] + ext[1]) * 0.5f;
- LLVector3 size = (ext[1] - ext[0]) * 0.5f;
+ LLVector4a pos;
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ LLVector4a size;
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
LLGLDepthTest depth(GL_FALSE, GL_TRUE);
gGL.color4f(0,0.5f,0.5f,1);
@@ -2949,8 +3055,8 @@ public:
return;
}
- LLVector3 nodeCenter = group->mBounds[0];
- LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter());
+ LLVector4a nodeCenter = group->mBounds[0];
+ LLVector4a octCenter = group->mOctreeNode->getCenter();
group->rebuildGeom();
group->rebuildMesh();
@@ -2979,8 +3085,14 @@ public:
if (drawable->isState(LLDrawable::IN_REBUILD_Q2))
{
gGL.color4f(0.6f, 0.6f, 0.1f, 1.f);
- const LLVector3* ext = drawable->getSpatialExtents();
- drawBoxOutline((ext[0]+ext[1])*0.5f, (ext[1]-ext[0])*0.5f);
+ const LLVector4a* ext = drawable->getSpatialExtents();
+ LLVector4a center;
+ center.setAdd(ext[0], ext[1]);
+ center.mul(0.5f);
+ LLVector4a size;
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
+ drawBoxOutline(center, size);
}
}
@@ -3211,7 +3323,11 @@ void LLSpatialPartition::renderDebug()
void LLSpatialGroup::drawObjectBox(LLColor4 col)
{
gGL.color4fv(col.mV);
- drawBox(mObjectBounds[0], mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f));
+ LLVector4a size;
+ size = mObjectBounds[0];
+ size.mul(1.01f);
+ size.add(LLVector4a(0.001f));
+ drawBox(mObjectBounds[0], size);
}
@@ -3271,8 +3387,8 @@ public:
LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0);
- LLVector3 size;
- LLVector3 center;
+ LLVector4a size;
+ LLVector4a center;
size = group->mBounds[1];
center = group->mBounds[0];
@@ -3289,7 +3405,11 @@ public:
local_end = mEnd * local_matrix;
}
- if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))
+ LLVector4a start, end;
+ start.load3(local_start.mV);
+ end.load3(local_end.mV);
+
+ if (LLLineSegmentBoxIntersect(start, end, center, size))
{
check(child);
}
@@ -3380,6 +3500,7 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
mDrawMode(LLRender::TRIANGLES)
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
+ mExtents = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*2, 16);
mDebugColor = (rand() << 16) + rand();
}
@@ -3395,6 +3516,13 @@ LLDrawInfo::~LLDrawInfo()
{
mFace->setDrawInfo(NULL);
}
+
+ if (gDebugGL)
+ {
+ gPipeline.checkReferences(this);
+ }
+
+ _mm_free(mExtents);
}
void LLDrawInfo::validate()