diff options
Diffstat (limited to 'indra/newview/llspatialpartition.cpp')
-rw-r--r-- | indra/newview/llspatialpartition.cpp | 345 |
1 files changed, 282 insertions, 63 deletions
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index dc4b8134dc..6e5231bddd 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -49,7 +49,7 @@ #include "lloctree.h" #include "llvoavatar.h" -const F32 SG_OCCLUSION_FUDGE = 1.01f; +const F32 SG_OCCLUSION_FUDGE = 0.25f; #define SG_DISCARD_TOLERANCE 0.01f #if LL_OCTREE_PARANOIA_CHECK @@ -191,7 +191,7 @@ static U8 sOcclusionIndices[] = b000, b110, b100, b101, b001, b011, b010, b110, }; -U8* get_occlusion_indices(LLCamera* camera, const LLVector3& center) +U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center) { LLVector3 d = center - camera->getOrigin(); @@ -219,7 +219,7 @@ void LLSpatialGroup::buildOcclusion() mOcclusionVerts = new F32[8*3]; } - LLVector3 r = mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.1f,0.1f,0.1f); + LLVector3 r = mBounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE); for (U32 k = 0; k < 3; k++) { @@ -562,8 +562,21 @@ void LLSpatialGroup::rebuildGeom() } } +void LLSpatialGroup::rebuildMesh() +{ + if (!isDead()) + { + mSpatialPartition->rebuildMesh(this); + } +} + void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { + if (!gPipeline.hasRenderType(mDrawableType)) + { + return; + } + if (group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; @@ -612,6 +625,11 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->clearState(LLSpatialGroup::GEOM_DIRTY); } +void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) +{ + +} + BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut) { const OctreeNode* node = mOctreeNode; @@ -778,7 +796,7 @@ void LLSpatialGroup::shift(const LLVector3 &offset) mObjectExtents[0] += offset; mObjectExtents[1] += offset; - if (!mSpatialPartition->mRenderByGroup) + //if (!mSpatialPartition->mRenderByGroup) { setState(GEOM_DIRTY); } @@ -1271,8 +1289,8 @@ void LLSpatialGroup::checkOcclusion() clearState(QUERY_PENDING | DISCARD_QUERY); } - else if (mSpatialPartition->mOcclusionEnabled) - { + else if (mSpatialPartition->isOcclusionEnabled() && isState(LLSpatialGroup::OCCLUDED)) + { //check occlusion has been issued for occluded node that has not had a query issued assert_states_valid(this); clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); assert_states_valid(this); @@ -1282,7 +1300,7 @@ void LLSpatialGroup::checkOcclusion() void LLSpatialGroup::doOcclusion(LLCamera* camera) { - if (mSpatialPartition->mOcclusionEnabled && LLPipeline::sUseOcclusion > 1) + if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) { if (earlyFail(camera, this)) { @@ -1309,7 +1327,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery); glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_occlusion_indices(camera, mBounds[0])); + GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); glEndQueryARB(GL_SAMPLES_PASSED_ARB); } @@ -1470,7 +1488,7 @@ public: group->checkOcclusion(); if (group->mOctreeNode->getParent() && //never occlusion cull the root node - LLPipeline::sUseOcclusion && //ignore occlusion if disabled + LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isState(LLSpatialGroup::OCCLUDED)) { gPipeline.markOccluder(group); @@ -1594,6 +1612,86 @@ public: } }; +class LLOctreeCullShadow : public LLOctreeCull +{ +public: + LLOctreeCullShadow(LLCamera* camera) + : LLOctreeCull(camera) { } + + virtual S32 frustumCheck(const LLSpatialGroup* group) + { + return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); + } + + virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + { + return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); + } +}; + +class LLOctreeCullVisExtents: public LLOctreeCullShadow +{ +public: + LLOctreeCullVisExtents(LLCamera* camera, LLVector3& min, LLVector3& max) + : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { } + + virtual bool earlyFail(LLSpatialGroup* group) + { + if (group->mOctreeNode->getParent() && //never occlusion cull the root node + LLPipeline::sUseOcclusion && //ignore occlusion if disabled + group->isState(LLSpatialGroup::OCCLUDED)) + { + return true; + } + + return false; + } + + virtual void processGroup(LLSpatialGroup* group) + { + if (group->mObjectBounds[1].magVecSquared() < 256.f * 256.f) + { //megaprims and water edge patches be damned! + mEmpty = FALSE; + update_min_max(mMin, mMax, group->mObjectExtents[0]); + update_min_max(mMin, mMax, group->mObjectExtents[1]); + } + } + + BOOL mEmpty; + LLVector3& mMin; + LLVector3& mMax; +}; + +class LLOctreeCullDetectVisible: public LLOctreeCullShadow +{ +public: + LLOctreeCullDetectVisible(LLCamera* camera) + : LLOctreeCullShadow(camera), mResult(FALSE) { } + + virtual bool earlyFail(LLSpatialGroup* group) + { + if (mResult || //already found a node, don't check any more + group->mOctreeNode->getParent() && //never occlusion cull the root node + LLPipeline::sUseOcclusion && //ignore occlusion if disabled + group->isState(LLSpatialGroup::OCCLUDED)) + { + return true; + } + + return false; + } + + virtual void processGroup(LLSpatialGroup* group) + { + if (group->isVisible()) + { + mResult = TRUE; + } + } + + BOOL mResult; +}; + class LLOctreeSelect : public LLOctreeCull { public: @@ -1747,6 +1845,25 @@ void LLSpatialPartition::resetVertexBuffers() dirty.traverse(mOctree); } +BOOL LLSpatialPartition::isOcclusionEnabled() +{ + return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2; +} + +BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) +{ + LLOctreeCullVisExtents vis(&camera, visMin, visMax); + vis.traverse(mOctree); + return vis.mEmpty; +} + +BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera) +{ + LLOctreeCullDetectVisible vis(&camera); + vis.traverse(mOctree); + return vis.mResult; +} + S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -1772,6 +1889,12 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result LLOctreeSelect selecter(&camera, results); selecter.traverse(mOctree); } + else if (LLPipeline::sShadowRender) + { + LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); + LLOctreeCullShadow culler(&camera); + culler.traverse(mOctree); + } else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) { LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); @@ -1790,14 +1913,14 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) { - const F32 vel = (LLViewerCamera::getInstance()->getVelocityStat()->getCurrent()+0.2f); + const F32 vel = SG_OCCLUSION_FUDGE*2.f; LLVector3 c = group->mBounds[0]; - LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(vel,vel,vel); + LLVector3 r = group->mBounds[1] + LLVector3(vel,vel,vel); - if (r.magVecSquared() > 1024.0*1024.0) + /*if (r.magVecSquared() > 1024.0*1024.0) { return TRUE; - } + }*/ LLVector3 e = camera->getOrigin(); @@ -1865,21 +1988,31 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask) void pushBufferVerts(LLSpatialGroup* group, U32 mask) { - if (!group->mDrawMap.empty()) + if (group->mSpatialPartition->mRenderByGroup) { - LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin()); - LLRenderPass::applyModelMatrix(*params); - - pushBufferVerts(group->mVertexBuffer, mask); - - for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) + if (!group->mDrawMap.empty()) { - for (LLSpatialGroup::buffer_list_t::iterator j = i->second.begin(); j != i->second.end(); ++j) + LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin()); + LLRenderPass::applyModelMatrix(*params); + + pushBufferVerts(group->mVertexBuffer, mask); + + for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) { - pushBufferVerts(*j, mask); + for (LLSpatialGroup::buffer_texture_map_t::iterator j = i->second.begin(); j != i->second.end(); ++j) + { + for (LLSpatialGroup::buffer_list_t::iterator k = j->second.begin(); k != j->second.end(); ++k) + { + pushBufferVerts(*k, mask); + } + } } } } + else + { + drawBox(group->mBounds[0], group->mBounds[1]); + } } void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) @@ -2026,6 +2159,23 @@ void renderOctree(LLSpatialGroup* group) } drawBoxOutline(group->mBounds[0],group->mBounds[1]); + + + //draw bounding box for draw info + if (group->mSpatialPartition->mRenderByGroup) + { + gGL.color4f(1.0f, 0.75f, 0.25f, 0.6f); + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + 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; + drawBoxOutline(center, size); + } + } + } } // LLSpatialGroup::OctreeNode* node = group->mOctreeNode; @@ -2046,6 +2196,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) { LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); glColor4f(0, 0.5f, 0, 0.5f); + gGL.color4f(0, 0.5f, 0, 0.5f); pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); } @@ -2055,6 +2206,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) if (render_objects) { glColor4f(0.f, 0.5f, 0.f,1.f); + gGL.color4f(0.f, 0.5f, 0.f, 1.f); pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); } @@ -2063,6 +2215,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) if (render_objects) { glColor4f(0.f, 0.75f, 0.f,0.5f); + gGL.color4f(0.f, 0.75f, 0.f, 0.5f); pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); } else if (camera && group->mOcclusionVerts) @@ -2071,60 +2224,63 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) glVertexPointer(3, GL_FLOAT, 0, group->mOcclusionVerts); glColor4f(1.0f, 0.f, 0.f, 0.5f); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_occlusion_indices(camera, group->mBounds[0])); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0])); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glColor4f(1.0f, 1.f, 1.f, 1.0f); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_occlusion_indices(camera, group->mBounds[0])); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0])); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } } -void renderBoundingBox(LLDrawable* drawable) +void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) { - if (drawable->isSpatialBridge()) - { - gGL.color4f(1,0.5f,0,1); - } - else if (drawable->getVOVolume()) + if (set_color) { - if (drawable->isRoot()) + if (drawable->isSpatialBridge()) { - gGL.color4f(1,1,0,1); + gGL.color4f(1,0.5f,0,1); } - else + else if (drawable->getVOVolume()) { - gGL.color4f(0,1,0,1); + if (drawable->isRoot()) + { + gGL.color4f(1,1,0,1); + } + else + { + gGL.color4f(0,1,0,1); + } } - } - else if (drawable->getVObj()) - { - switch (drawable->getVObj()->getPCode()) + else if (drawable->getVObj()) { - case LLViewerObject::LL_VO_SURFACE_PATCH: - gGL.color4f(0,1,1,1); - break; - case LLViewerObject::LL_VO_CLOUDS: - gGL.color4f(0.5f,0.5f,0.5f,1.0f); - break; - case LLViewerObject::LL_VO_PART_GROUP: + switch (drawable->getVObj()->getPCode()) + { + case LLViewerObject::LL_VO_SURFACE_PATCH: + gGL.color4f(0,1,1,1); + break; + case LLViewerObject::LL_VO_CLOUDS: + gGL.color4f(0.5f,0.5f,0.5f,1.0f); + break; + case LLViewerObject::LL_VO_PART_GROUP: case LLViewerObject::LL_VO_HUD_PART_GROUP: - gGL.color4f(0,0,1,1); - break; - case LLViewerObject::LL_VO_WATER: - gGL.color4f(0,0.5f,1,1); - break; - case LL_PCODE_LEGACY_TREE: - gGL.color4f(0,0.5f,0,1); - default: - gGL.color4f(1,0,1,1); - break; + gGL.color4f(0,0,1,1); + break; + case LLViewerObject::LL_VO_WATER: + gGL.color4f(0,0.5f,1,1); + break; + case LL_PCODE_LEGACY_TREE: + gGL.color4f(0,0.5f,0,1); + default: + gGL.color4f(1,0,1,1); + break; + } + } + else + { + gGL.color4f(1,0,0,1); } - } - else - { - gGL.color4f(1,0,0,1); } const LLVector3* ext; @@ -2156,7 +2312,8 @@ void renderBoundingBox(LLDrawable* drawable) if (vobj && vobj->onActiveList()) { gGL.flush(); - glLineWidth(4.f*(sinf(gFrameTimeSeconds*2.f)*0.25f+0.75f)); + glLineWidth(llmax(4.f*sinf(gFrameTimeSeconds*2.f)+1.f, 1.f)); + //glLineWidth(4.f*(sinf(gFrameTimeSeconds*2.f)*0.25f+0.75f)); stop_glerror(); drawBoxOutline(pos,size); gGL.flush(); @@ -2379,8 +2536,7 @@ public: } //render visibility wireframe - if (group->mSpatialPartition->mRenderByGroup && - gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { gGL.flush(); glPushMatrix(); @@ -2456,6 +2612,51 @@ public: } }; +class LLOctreePushBBoxVerts : public LLOctreeTraveler<LLDrawable> +{ +public: + LLCamera* mCamera; + LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {} + + virtual void traverse(const LLSpatialGroup::OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + if (!mCamera || mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1])) + { + node->accept(this); + + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + } + } + } + + virtual void visit(const LLSpatialGroup::OctreeNode* branch) + { + LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); + + if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))) + { + return; + } + + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + { + LLDrawable* drawable = *i; + + renderBoundingBox(drawable, FALSE); + } + } +}; + +void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) +{ + LLOctreePushBBoxVerts pusher(camera); + pusher.traverse(mOctree); +} + void LLSpatialPartition::renderDebug() { if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | @@ -2661,9 +2862,22 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, mParticle(particle), mPartSize(part_size), mVSize(0.f), - mGroup(NULL) + mGroup(NULL), + mFace(NULL), + mDistance(0.f) { mDebugColor = (rand() << 16) + rand(); + if (mStart >= mVertexBuffer->getRequestedVerts() || + mEnd >= mVertexBuffer->getRequestedVerts()) + { + llerrs << "Invalid draw info vertex range." << llendl; + } + + if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() || + mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices()) + { + llerrs << "Invalid draw info index range." << llendl; + } } LLDrawInfo::~LLDrawInfo() @@ -2672,6 +2886,11 @@ LLDrawInfo::~LLDrawInfo() { llerrs << "LLDrawInfo deleted illegally!" << llendl; } + + if (mFace) + { + mFace->setDrawInfo(NULL); + } } LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) |