aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llspatialpartition.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:50 -0500
committerJacek Antonelli2008-08-15 23:44:50 -0500
commit89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch)
treebcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/newview/llspatialpartition.cpp
parentSecond Life viewer sources 1.13.3.2 (diff)
downloadmeta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/newview/llspatialpartition.cpp')
-rw-r--r--linden/indra/newview/llspatialpartition.cpp1887
1 files changed, 1230 insertions, 657 deletions
diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp
index fd9eec0..24ac1ca 100644
--- a/linden/indra/newview/llspatialpartition.cpp
+++ b/linden/indra/newview/llspatialpartition.cpp
@@ -29,25 +29,21 @@
29 29
30#include "llspatialpartition.h" 30#include "llspatialpartition.h"
31 31
32#include "llglheaders.h" 32#include "llviewerwindow.h"
33
34#include "llviewerobjectlist.h" 33#include "llviewerobjectlist.h"
35#include "llvovolume.h" 34#include "llvovolume.h"
36#include "llviewercamera.h" 35#include "llviewercamera.h"
37#include "llface.h" 36#include "llface.h"
38#include "viewer.h" 37#include "viewer.h"
39 38#include "llagent.h"
39#include "llviewerregion.h"
40#include "llcamera.h" 40#include "llcamera.h"
41#include "pipeline.h" 41#include "pipeline.h"
42 42
43static BOOL sIgnoreOcclusion = TRUE;
44static GLuint sBoxList = 0; 43static GLuint sBoxList = 0;
45 44
46const S32 SG_LOD_SWITCH_STAGGER = 4; 45const F32 SG_OCCLUSION_FUDGE = 1.01f;
47const F32 SG_MAX_OBJ_RAD = 1.f; 46//const S32 SG_LOD_PERIOD = 16;
48const F32 SG_OCCLUSION_FUDGE = 1.1f;
49const S32 SG_MOVE_PERIOD = 32;
50const S32 SG_LOD_PERIOD = 16;
51 47
52#define SG_DISCARD_TOLERANCE 0.25f 48#define SG_DISCARD_TOLERANCE 0.25f
53 49
@@ -57,11 +53,12 @@ const S32 SG_LOD_PERIOD = 16;
57#define assert_octree_valid(x) 53#define assert_octree_valid(x)
58#endif 54#endif
59 55
56static U32 sZombieGroups = 0;
57
60static F32 sLastMaxTexPriority = 1.f; 58static F32 sLastMaxTexPriority = 1.f;
61static F32 sCurMaxTexPriority = 1.f; 59static F32 sCurMaxTexPriority = 1.f;
62 60
63//static counter for frame to switch LOD on 61//static counter for frame to switch LOD on
64S32 LLSpatialGroup::sLODSeed = 0;
65 62
66void sg_assert(BOOL expr) 63void sg_assert(BOOL expr)
67{ 64{
@@ -144,30 +141,22 @@ S32 LLSphereAABB(const LLVector3& center, const LLVector3& size, const LLVector3
144 141
145LLSpatialGroup::~LLSpatialGroup() 142LLSpatialGroup::~LLSpatialGroup()
146{ 143{
147 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 144 if (isState(DEAD))
148 if (!safeToDelete())
149 { 145 {
150#ifdef LL_RELEASE_FOR_DOWNLOAD 146 sZombieGroups--;
151 llwarns << "Spatial Group deleted while being tracked " << ((void*) mState) << llendl;
152#else
153 llerrs << "Spatial Group deleted while being tracked " << ((void*) mState) << llendl;
154#endif
155 } 147 }
156 148
157#if LL_OCTREE_PARANOIA_CHECK 149 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
158 for (U32 i = 0; i < mSpatialPartition->mOccludedList.size(); i++) 150 clearDrawMap();
159 {
160 if (mSpatialPartition->mOccludedList[i] == this)
161 {
162 llerrs << "Spatial Group deleted while being tracked STATE ERROR " << ((void*) mState) << llendl;
163 }
164 }
165#endif
166} 151}
167 152
168BOOL LLSpatialGroup::safeToDelete() 153void LLSpatialGroup::clearDrawMap()
169{ 154{
170 return gQuit || !isState(IN_QUEUE | ACTIVE_OCCLUSION | RESHADOW_QUEUE); 155 for (LLSpatialGroup::draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i)
156 {
157 std::for_each(i->second.begin(), i->second.end(), DeletePointer());
158 }
159 mDrawMap.clear();
171} 160}
172 161
173class LLRelightPainter : public LLSpatialGroup::OctreeTraveler 162class LLRelightPainter : public LLSpatialGroup::OctreeTraveler
@@ -212,13 +201,13 @@ public:
212 201
213BOOL LLSpatialGroup::isVisible() 202BOOL LLSpatialGroup::isVisible()
214{ 203{
215 if (sIgnoreOcclusion) 204 if (LLPipeline::sUseOcclusion)
216 { 205 {
217 return !isState(CULLED); 206 return !isState(CULLED | OCCLUDED);
218 } 207 }
219 else 208 else
220 { 209 {
221 return !isState(CULLED | OCCLUDED); 210 return !isState(CULLED);
222 } 211 }
223} 212}
224 213
@@ -254,6 +243,90 @@ void LLSpatialGroup::validate()
254#endif 243#endif
255} 244}
256 245
246void validate_draw_info(LLDrawInfo& params)
247{
248#if LL_DEBUG
249/* if (params.mVertexBuffer.isNull())
250 {
251 llerrs << "Draw batch has no vertex buffer." << llendl;
252 }
253
254 //bad range
255 if (params.mStart >= params.mEnd)
256 {
257 llerrs << "Draw batch has invalid range." << llendl;
258 }
259
260 if (params.mEnd >= params.mVertexBuffer->getNumVerts())
261 {
262 llerrs << "Draw batch has buffer overrun error." << llendl;
263 }
264
265 if (params.mOffset + params.mCount > params.mVertexBuffer->getNumIndices())
266 {
267 llerrs << "Draw batch has index buffer ovverrun error." << llendl;
268 }
269
270 //bad indices
271 U32* indicesp = (U32*) params.mVertexBuffer->getIndicesPointer();
272 if (indicesp)
273 {
274 for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++)
275 {
276 if (indicesp[i] < params.mStart)
277 {
278 llerrs << "Draw batch has vertex buffer index out of range error (index too low)." << llendl;
279 }
280
281 if (indicesp[i] > params.mEnd)
282 {
283 llerrs << "Draw batch has vertex buffer index out of range error (index too high)." << llendl;
284 }
285 }
286 }*/
287#endif
288}
289
290void LLSpatialGroup::validateDrawMap()
291{
292/* for (draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i)
293 {
294 std::vector<LLDrawInfo*>& draw_vec = i->second;
295 for (std::vector<LLDrawInfo*>::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
296 {
297 LLDrawInfo& params = **j;
298
299 validate_draw_info(params);
300 }
301 }*/
302}
303
304void LLSpatialGroup::makeStatic()
305{
306#if !LL_DARWIN
307 if (isState(GEOM_DIRTY | ALPHA_DIRTY))
308 {
309 return;
310 }
311
312 if (mSpatialPartition->mRenderByGroup && mBufferUsage != GL_STATIC_DRAW_ARB)
313 {
314 mBufferUsage = GL_STATIC_DRAW_ARB;
315 if (mVertexBuffer.notNull())
316 {
317 mVertexBuffer->makeStatic();
318 }
319
320 for (buffer_map_t::iterator i = mBufferMap.begin(); i != mBufferMap.end(); ++i)
321 {
322 i->second->makeStatic();
323 }
324
325 mBuilt = 1.f;
326 }
327#endif
328}
329
257BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) 330BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
258{ 331{
259 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 332 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
@@ -261,10 +334,16 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
261 drawablep->updateSpatialExtents(); 334 drawablep->updateSpatialExtents();
262 validate_drawable(drawablep); 335 validate_drawable(drawablep);
263 336
264 if (mOctreeNode->isInside(drawablep) && mOctreeNode->contains(drawablep)) 337 OctreeNode* parent = mOctreeNode->getOctParent();
338
339 if (mOctreeNode->isInside(drawablep->getPositionGroup()) &&
340 (mOctreeNode->contains(drawablep) ||
341 (drawablep->getBinRadius() > mOctreeNode->getSize().mdV[0] &&
342 parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY)))
265 { 343 {
266 unbound(); 344 unbound();
267 setState(OBJECT_DIRTY); 345 setState(OBJECT_DIRTY);
346 setState(GEOM_DIRTY);
268 validate_drawable(drawablep); 347 validate_drawable(drawablep);
269 return TRUE; 348 return TRUE;
270 } 349 }
@@ -284,11 +363,82 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc
284 { 363 {
285 drawablep->setSpatialGroup(this, 0); 364 drawablep->setSpatialGroup(this, 0);
286 validate_drawable(drawablep); 365 validate_drawable(drawablep);
366 setState(OBJECT_DIRTY | GEOM_DIRTY);
367 mLastAddTime = gFrameTimeSeconds;
368 if (drawablep->isSpatialBridge())
369 {
370 mBridgeList.push_back((LLSpatialBridge*) drawablep);
371 }
372 setState(IMAGE_DIRTY);
287 } 373 }
288 374
289 return TRUE; 375 return TRUE;
290} 376}
291 377
378void LLSpatialGroup::rebuildGeom()
379{
380 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
381 if (!isDead())
382 {
383 mSpatialPartition->rebuildGeom(this);
384 }
385}
386
387void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
388{
389 if (group->changeLOD())
390 {
391 group->mLastUpdateDistance = group->mDistance;
392 group->mLastUpdateViewAngle = group->mViewAngle;
393 }
394
395 if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY))
396 {
397 return;
398 }
399
400 LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO);
401
402 group->clearDrawMap();
403
404 //get geometry count
405 group->mIndexCount = 0;
406 group->mVertexCount = 0;
407
408 addGeometryCount(group, group->mVertexCount, group->mIndexCount);
409
410 if (group->mVertexCount > 0 && group->mIndexCount > 0)
411 { //create vertex buffer containing volume geometry for this node
412 group->mBuilt = 1.f;
413 if (group->mVertexBuffer.isNull() || (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
414 {
415 //LLFastTimer ftm(LLFastTimer::FTM_REBUILD_NONE_VB);
416 group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
417 group->mVertexBuffer->allocateBuffer(group->mVertexCount, group->mIndexCount, true);
418 stop_glerror();
419 }
420 else
421 {
422 //LLFastTimer ftm(LLFastTimer::FTM_REBUILD_NONE_VB);
423 group->mVertexBuffer->resizeBuffer(group->mVertexCount, group->mIndexCount);
424 stop_glerror();
425 }
426
427 {
428 LLFastTimer ftm((LLFastTimer::EFastTimerType) ((U32) LLFastTimer::FTM_REBUILD_VOLUME_VB + mPartitionType));
429 getGeometry(group);
430 }
431 }
432 else
433 {
434 group->mVertexBuffer = NULL;
435 group->mBufferMap.clear();
436 }
437
438 group->mLastUpdateTime = gFrameTimeSeconds;
439 group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MATRIX_DIRTY);
440}
441
292BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut) 442BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut)
293{ 443{
294 const OctreeState* node = mOctreeNode->getOctState(); 444 const OctreeState* node = mOctreeNode->getOctState();
@@ -304,7 +454,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO
304 454
305 LLVector3& newMin = mObjectExtents[0]; 455 LLVector3& newMin = mObjectExtents[0];
306 LLVector3& newMax = mObjectExtents[1]; 456 LLVector3& newMax = mObjectExtents[1];
307 457
308 if (isState(OBJECT_DIRTY)) 458 if (isState(OBJECT_DIRTY))
309 { //calculate new bounding box 459 { //calculate new bounding box
310 clearState(OBJECT_DIRTY); 460 clearState(OBJECT_DIRTY);
@@ -390,11 +540,28 @@ void LLSpatialGroup::unbound()
390 } 540 }
391} 541}
392 542
543LLSpatialGroup* LLSpatialGroup::getParent()
544{
545 if (isDead())
546 {
547 return NULL;
548 }
549
550 OctreeNode* parent = mOctreeNode->getOctParent();
551
552 if (parent)
553 {
554 return (LLSpatialGroup*) parent->getListener(0);
555 }
556
557 return NULL;
558}
559
393BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) 560BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
394{ 561{
395 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 562 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
396 unbound(); 563 unbound();
397 if (!from_octree) 564 if (mOctreeNode && !from_octree)
398 { 565 {
399 if (!mOctreeNode->remove(drawablep)) 566 if (!mOctreeNode->remove(drawablep))
400 { 567 {
@@ -404,6 +571,18 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
404 else 571 else
405 { 572 {
406 drawablep->setSpatialGroup(NULL, -1); 573 drawablep->setSpatialGroup(NULL, -1);
574 setState(GEOM_DIRTY);
575 if (drawablep->isSpatialBridge())
576 {
577 for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i)
578 {
579 if (*i == drawablep)
580 {
581 mBridgeList.erase(i);
582 break;
583 }
584 }
585 }
407 } 586 }
408 return TRUE; 587 return TRUE;
409} 588}
@@ -420,6 +599,8 @@ void LLSpatialGroup::shift(const LLVector3 &offset)
420 mObjectBounds[0] += offset; 599 mObjectBounds[0] += offset;
421 mObjectExtents[0] += offset; 600 mObjectExtents[0] += offset;
422 mObjectExtents[1] += offset; 601 mObjectExtents[1] += offset;
602
603 setState(GEOM_DIRTY | MATRIX_DIRTY | OCCLUSION_DIRTY);
423} 604}
424 605
425class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler 606class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler
@@ -533,30 +714,160 @@ void LLSpatialGroup::clearState(U32 state, S32 mode)
533// Octree Listener Implementation 714// Octree Listener Implementation
534//====================================== 715//======================================
535 716
536LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) 717LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
537: mState(0), mOctreeNode(node), mSpatialPartition(part) 718 mState(0),
719 mBuilt(0.f),
720 mOctreeNode(node),
721 mSpatialPartition(part),
722 mVertexBuffer(NULL),
723 mBufferUsage(GL_STATIC_DRAW_ARB),
724 mDistance(0.f),
725 mDepth(0.f),
726 mLastUpdateDistance(-1.f),
727 mLastUpdateTime(gFrameTimeSeconds),
728 mLastAddTime(gFrameTimeSeconds),
729 mLastRenderTime(gFrameTimeSeconds),
730 mViewAngle(0.f),
731 mLastUpdateViewAngle(-1.f)
538{ 732{
539 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 733 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
734
540 sg_assert(mOctreeNode->getListenerCount() == 0); 735 sg_assert(mOctreeNode->getListenerCount() == 0);
541 mOctreeNode->addListener(this); 736 mOctreeNode->addListener(this);
542 setState(DIRTY); 737 setState(SG_INITIAL_STATE_MASK);
543 738
544 mBounds[0] = LLVector3(node->getCenter()); 739 mBounds[0] = LLVector3(node->getCenter());
545 mBounds[1] = LLVector3(node->getSize()); 740 mBounds[1] = LLVector3(node->getSize());
546 741
547 sLODSeed = (sLODSeed+1)%SG_LOD_PERIOD; 742 part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod;
548 mLODHash = sLODSeed; 743 mLODHash = part->mLODSeed;
744
745 mRadius = 1;
746 mPixelArea = 1024.f;
747}
748
749void LLSpatialGroup::updateDistance(LLCamera &camera)
750{
751#if !LL_RELEASE_FOR_DOWNLOAD
752 if (isState(LLSpatialGroup::OBJECT_DIRTY))
753 {
754 llerrs << "Spatial group dirty on distance update." << llendl;
755 }
756#endif
757 if (!getData().empty())
758 {
759 mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() :
760 (F32) mOctreeNode->getSize().magVec();
761 mDistance = mSpatialPartition->calcDistance(this, camera);
762 mPixelArea = mSpatialPartition->calcPixelArea(this, camera);
763 }
764}
765
766F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)
767{
768 LLVector3 eye = group->mObjectBounds[0] - camera.getOrigin();
769
770 F32 dist = 0.f;
771
772 if (group->mDrawMap.find(LLRenderPass::PASS_ALPHA) != group->mDrawMap.end())
773 {
774 LLVector3 v = eye;
775 dist = eye.normVec();
776
777 if (!group->isState(LLSpatialGroup::ALPHA_DIRTY))
778 {
779 LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0),
780 eye * LLVector3(0,1,0),
781 eye * LLVector3(0,0,1));
782
783 if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f)
784 {
785 group->mViewAngle = view_angle;
786 group->mLastUpdateViewAngle = view_angle;
787 //for occasional alpha sorting within the group
788 //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order,
789 //not setting this node to dirty would be a very good thing
790 group->setState(LLSpatialGroup::ALPHA_DIRTY);
791 }
792 }
793
794 //calculate depth of node for alpha sorting
795
796 LLVector3 at = camera.getAtAxis();
797
798 //front of bounding box
799 for (U32 i = 0; i < 3; i++)
800 {
801 v.mV[i] -= group->mObjectBounds[1].mV[i]*0.25f * at.mV[i];
802 }
803
804 group->mDepth = v * at;
805
806 F32 water_height = gAgent.getRegion()->getWaterHeight();
807 //figure out if this node is above or below water
808 if (group->mObjectBounds[0].mV[2] < water_height)
809 {
810 group->setState(LLSpatialGroup::BELOW_WATER);
811 }
812 else
813 {
814 group->clearState(LLSpatialGroup::BELOW_WATER);
815 }
816 }
817 else
818 {
819 dist = eye.magVec();
820 }
821
822 if (dist < 16.f)
823 {
824 dist /= 16.f;
825 dist *= dist;
826 dist *= 16.f;
827 }
828
829 return dist;
830}
831
832F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera)
833{
834 return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera);
549} 835}
550 836
551BOOL LLSpatialGroup::changeLOD() 837BOOL LLSpatialGroup::changeLOD()
552{ 838{
553 return LLDrawable::getCurrentFrame()%SG_LOD_PERIOD == mLODHash; 839 if (isState(ALPHA_DIRTY))
840 { ///an alpha sort is going to happen, update distance and LOD
841 return TRUE;
842 }
843
844 if (mSpatialPartition->mSlopRatio > 0.f)
845 {
846 F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius));
847
848 if (fabsf(ratio) >= mSpatialPartition->mSlopRatio)
849 {
850 return TRUE;
851 }
852
853 if (mDistance > mRadius)
854 {
855 return FALSE;
856 }
857 }
858
859 if (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash)
860 {
861 return TRUE;
862 }
863
864 return FALSE;
554} 865}
555 866
556void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawable) 867void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep)
557{ 868{
558 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 869 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
559 addObject(drawable, FALSE, TRUE); 870 addObject(drawablep, FALSE, TRUE);
560 unbound(); 871 unbound();
561 setState(OBJECT_DIRTY); 872 setState(OBJECT_DIRTY);
562} 873}
@@ -571,29 +882,13 @@ void LLSpatialGroup::handleRemoval(const TreeNode* node, LLDrawable* drawable)
571void LLSpatialGroup::handleDestruction(const TreeNode* node) 882void LLSpatialGroup::handleDestruction(const TreeNode* node)
572{ 883{
573 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 884 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
574 885 setState(DEAD);
575 if (mOctreeNode) 886 clearDrawMap();
576 { 887 mOcclusionVerts = NULL;
577 OctreeState* state = mOctreeNode->getOctState(); 888 mVertexBuffer = NULL;
578 for (OctreeState::element_iter i = state->getData().begin(); i != state->getData().end(); ++i) 889 mBufferMap.clear();
579 { 890 sZombieGroups++;
580 LLDrawable* drawable = *i; 891 mOctreeNode = NULL;
581 if (!drawable->isDead())
582 {
583 drawable->setSpatialGroup(NULL, -1);
584 }
585 }
586 }
587
588 if (safeToDelete())
589 {
590 delete this;
591 }
592 else
593 {
594 setState(DEAD);
595 mOctreeNode = NULL;
596 }
597} 892}
598 893
599void LLSpatialGroup::handleStateChange(const TreeNode* node) 894void LLSpatialGroup::handleStateChange(const TreeNode* node)
@@ -611,7 +906,8 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c
611 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 906 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
612 if (child->getListenerCount() == 0) 907 if (child->getListenerCount() == 0)
613 { 908 {
614 (new LLSpatialGroup(child, mSpatialPartition))->setState(mState & SG_STATE_INHERIT_MASK); 909 LLSpatialGroup* group = new LLSpatialGroup(child, mSpatialPartition);
910 group->setState(mState & SG_STATE_INHERIT_MASK);
615 } 911 }
616 else 912 else
617 { 913 {
@@ -626,6 +922,31 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo
626 unbound(); 922 unbound();
627} 923}
628 924
925void LLSpatialGroup::destroyGL()
926{
927 setState(LLSpatialGroup::GEOM_DIRTY |
928 LLSpatialGroup::OCCLUSION_DIRTY |
929 LLSpatialGroup::IMAGE_DIRTY);
930 mLastUpdateTime = gFrameTimeSeconds;
931 mVertexBuffer = NULL;
932 mBufferMap.clear();
933
934 mOcclusionVerts = NULL;
935 mReflectionMap = NULL;
936 clearDrawMap();
937
938 for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i)
939 {
940 LLDrawable* drawable = *i;
941 for (S32 j = 0; j < drawable->getNumFaces(); j++)
942 {
943 LLFace* facep = drawable->getFace(j);
944 facep->mVertexBuffer = NULL;
945 facep->mLastVertexBuffer = NULL;
946 }
947 }
948}
949
629BOOL LLSpatialGroup::rebound() 950BOOL LLSpatialGroup::rebound()
630{ 951{
631 if (!isState(DIRTY)) 952 if (!isState(DIRTY))
@@ -635,7 +956,7 @@ BOOL LLSpatialGroup::rebound()
635 956
636 LLVector3 oldBounds[2]; 957 LLVector3 oldBounds[2];
637 958
638 if (isState(QUERY_OUT)) 959 if (mSpatialPartition->isVolatile() && isState(QUERY_OUT))
639 { //a query has been issued, if our bounding box changes significantly 960 { //a query has been issued, if our bounding box changes significantly
640 //we need to discard the issued query 961 //we need to discard the issued query
641 oldBounds[0] = mBounds[0]; 962 oldBounds[0] = mBounds[0];
@@ -700,7 +1021,7 @@ BOOL LLSpatialGroup::rebound()
700 mBounds[1] = (newMax - newMin)*0.5f; 1021 mBounds[1] = (newMax - newMin)*0.5f;
701 } 1022 }
702 1023
703 if (isState(QUERY_OUT)) 1024 if (mSpatialPartition->isVolatile() && isState(QUERY_OUT))
704 { 1025 {
705 for (U32 i = 0; i < 3 && !isState(DISCARD_QUERY); i++) 1026 for (U32 i = 0; i < 3 && !isState(DISCARD_QUERY); i++)
706 { 1027 {
@@ -713,6 +1034,8 @@ BOOL LLSpatialGroup::rebound()
713 } 1034 }
714 } 1035 }
715 1036
1037 setState(OCCLUSION_DIRTY);
1038
716 clearState(DIRTY); 1039 clearState(DIRTY);
717 1040
718 return TRUE; 1041 return TRUE;
@@ -720,9 +1043,21 @@ BOOL LLSpatialGroup::rebound()
720 1043
721//============================================== 1044//==============================================
722 1045
723LLSpatialPartition::LLSpatialPartition() 1046LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL is_volatile, U32 buffer_usage)
724{ 1047{
725 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 1048 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
1049 mDrawableType = 0;
1050 mPartitionType = LLPipeline::PARTITION_NONE;
1051 mVolatile = is_volatile;
1052 mLODSeed = 0;
1053 mLODPeriod = 1;
1054 mVertexDataMask = data_mask;
1055 mBufferUsage = buffer_usage;
1056 mDepthMask = FALSE;
1057 mSlopRatio = 0.25f;
1058 mRenderByGroup = TRUE;
1059 mImageEnabled = FALSE;
1060
726 mOctree = new LLSpatialGroup::OctreeNode(LLVector3d(0,0,0), 1061 mOctree = new LLSpatialGroup::OctreeNode(LLVector3d(0,0,0),
727 LLVector3d(1,1,1), 1062 LLVector3d(1,1,1),
728 new LLSpatialGroup::OctreeRoot(), NULL); 1063 new LLSpatialGroup::OctreeRoot(), NULL);
@@ -733,19 +1068,25 @@ LLSpatialPartition::LLSpatialPartition()
733LLSpatialPartition::~LLSpatialPartition() 1068LLSpatialPartition::~LLSpatialPartition()
734{ 1069{
735 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 1070 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
1071
1072 for (U32 i = 0; i < mOcclusionQueries.size(); i++)
1073 {
1074 glDeleteQueriesARB(1, (GLuint*)(&(mOcclusionQueries[i])));
1075 }
1076
736 delete mOctree; 1077 delete mOctree;
737 mOctree = NULL; 1078 mOctree = NULL;
738} 1079}
739 1080
740 1081
741LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep) 1082LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
742{ 1083{
743 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 1084 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
744 const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million 1085 const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million
745 1086
746 if (drawablep->getPositionGroup().magVecSquared() > MAX_MAG) 1087 if (drawablep->getPositionGroup().magVecSquared() > MAX_MAG)
747 { 1088 {
748#ifndef LL_RELEASE_FOR_DOWNLOAD 1089#if 0 //ndef LL_RELEASE_FOR_DOWNLOAD
749 llwarns << "LLSpatialPartition::put Object out of range!" << llendl; 1090 llwarns << "LLSpatialPartition::put Object out of range!" << llendl;
750 llinfos << drawablep->getPositionGroup() << llendl; 1091 llinfos << drawablep->getPositionGroup() << llendl;
751 1092
@@ -770,7 +1111,13 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep)
770 1111
771 LLSpatialGroup::OctreeNode* node = mOctree->getNodeAt(drawablep); 1112 LLSpatialGroup::OctreeNode* node = mOctree->getNodeAt(drawablep);
772 1113
773 return (LLSpatialGroup*) node->getListener(0); 1114 LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
1115 if (was_visible && group->isState(LLSpatialGroup::QUERY_OUT))
1116 {
1117 group->setState(LLSpatialGroup::DISCARD_QUERY);
1118 }
1119
1120 return group;
774} 1121}
775 1122
776BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) 1123BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
@@ -793,14 +1140,16 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL
793{ 1140{
794 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 1141 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
795 LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); 1142 LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE);
796 1143
1144 BOOL was_visible = curp ? curp->isVisible() : FALSE;
1145
797 if (curp && curp->mSpatialPartition != this) 1146 if (curp && curp->mSpatialPartition != this)
798 { 1147 {
799 //keep drawable from being garbage collected 1148 //keep drawable from being garbage collected
800 LLPointer<LLDrawable> ptr = drawablep; 1149 LLPointer<LLDrawable> ptr = drawablep;
801 if (curp->mSpatialPartition->remove(drawablep, curp)) 1150 if (curp->mSpatialPartition->remove(drawablep, curp))
802 { 1151 {
803 put(drawablep); 1152 put(drawablep, was_visible);
804 return; 1153 return;
805 } 1154 }
806 else 1155 else
@@ -823,7 +1172,7 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL
823 OCT_ERRS << "Move couldn't find existing spatial group!" << llendl; 1172 OCT_ERRS << "Move couldn't find existing spatial group!" << llendl;
824 } 1173 }
825 1174
826 put(drawablep); 1175 put(drawablep, was_visible);
827} 1176}
828 1177
829class LLSpatialShift : public LLSpatialGroup::OctreeTraveler 1178class LLSpatialShift : public LLSpatialGroup::OctreeTraveler
@@ -848,13 +1197,9 @@ void LLSpatialPartition::shift(const LLVector3 &offset)
848 1197
849BOOL LLSpatialPartition::checkOcclusion(LLSpatialGroup* group, LLCamera* camera) 1198BOOL LLSpatialPartition::checkOcclusion(LLSpatialGroup* group, LLCamera* camera)
850{ 1199{
851 if (sIgnoreOcclusion) 1200 if (LLPipeline::sUseOcclusion &&
852 { 1201 !group->isState(LLSpatialGroup::ACTIVE_OCCLUSION | LLSpatialGroup::OCCLUDED) &&
853 return FALSE; 1202 (!camera || !earlyFail(camera, group)))
854 }
855
856 if (!group->isState(LLSpatialGroup::ACTIVE_OCCLUSION | LLSpatialGroup::OCCLUDED) &&
857 !earlyFail(camera, group))
858 { 1203 {
859 group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); 1204 group->setState(LLSpatialGroup::ACTIVE_OCCLUSION);
860 mQueryQueue.push(group); 1205 mQueryQueue.push(group);
@@ -872,8 +1217,8 @@ public:
872 1217
873 virtual bool earlyFail(const LLSpatialGroup* group) 1218 virtual bool earlyFail(const LLSpatialGroup* group)
874 { 1219 {
875 if (mRes && //never occlusion cull the root node 1220 if (group->mOctreeNode->getParent() && //never occlusion cull the root node
876 !sIgnoreOcclusion && //never occlusion cull selection 1221 LLPipeline::sUseOcclusion && //never occlusion cull selection
877 group->isState(LLSpatialGroup::OCCLUDED)) 1222 group->isState(LLSpatialGroup::OCCLUDED))
878 { 1223 {
879 return true; 1224 return true;
@@ -950,22 +1295,19 @@ public:
950 group->mSpatialPartition->checkOcclusion(group, mCamera); 1295 group->mSpatialPartition->checkOcclusion(group, mCamera);
951 } 1296 }
952 } 1297 }
1298
1299 if (LLPipeline::sDynamicReflections &&
1300 group->mOctreeNode->getSize().mdV[0] == 16.0 &&
1301 group->mDistance < 64.f &&
1302 group->mLastAddTime < gFrameTimeSeconds - 2.f)
1303 {
1304 group->mSpatialPartition->markReimage(group);
1305 }
953 } 1306 }
954 1307
955 virtual void processDrawable(LLDrawable* drawable) 1308 virtual void processGroup(LLSpatialGroup* group)
956 { 1309 {
957 if (!drawable->isDead()) 1310 gPipeline.markNotCulled(group, *mCamera);
958 {
959 const LLVector3* extents = drawable->getSpatialExtents();
960
961 F32 objRad = drawable->getRadius();
962 objRad *= objRad;
963 F32 distSqr = ((extents[0]+extents[1])*0.5f - mCamera->getOrigin()).magVecSquared();
964 if (objRad/distSqr > SG_MIN_DIST_RATIO)
965 {
966 gPipeline.markNotCulled(drawable, *mCamera);
967 }
968 }
969 } 1311 }
970 1312
971 virtual void visit(const LLSpatialGroup::OctreeState* branch) 1313 virtual void visit(const LLSpatialGroup::OctreeState* branch)
@@ -976,10 +1318,7 @@ public:
976 1318
977 if (checkObjects(branch, group)) 1319 if (checkObjects(branch, group))
978 { 1320 {
979 for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) 1321 processGroup(group);
980 {
981 processDrawable(*i);
982 }
983 } 1322 }
984 } 1323 }
985 1324
@@ -998,34 +1337,32 @@ public:
998 virtual void lateFail(LLSpatialGroup* group) { } 1337 virtual void lateFail(LLSpatialGroup* group) { }
999 virtual void preprocess(LLSpatialGroup* group) { } 1338 virtual void preprocess(LLSpatialGroup* group) { }
1000 1339
1001 virtual void processDrawable(LLDrawable* drawable) 1340 virtual void processGroup(LLSpatialGroup* group)
1002 { 1341 {
1003 if (!drawable->isDead()) 1342 LLSpatialGroup::OctreeState* branch = group->mOctreeNode->getOctState();
1343
1344 for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
1004 { 1345 {
1005 if (drawable->isSpatialBridge()) 1346 LLDrawable* drawable = *i;
1006 { 1347
1007 drawable->setVisible(*mCamera, mResults, TRUE); 1348 if (!drawable->isDead())
1008 }
1009 else
1010 { 1349 {
1011 mResults->push_back(drawable); 1350 if (drawable->isSpatialBridge())
1012 } 1351 {
1013 } 1352 drawable->setVisible(*mCamera, mResults, TRUE);
1353 }
1354 else
1355 {
1356 mResults->push_back(drawable);
1357 }
1358 }
1359 }
1014 } 1360 }
1015 1361
1016 std::vector<LLDrawable*>* mResults; 1362 std::vector<LLDrawable*>* mResults;
1017}; 1363};
1018 1364
1019 1365
1020void drawBox(const LLVector3& c, const LLVector3& r)
1021{
1022 glPushMatrix();
1023 glTranslatef(c.mV[0], c.mV[1], c.mV[2]);
1024 glScalef(r.mV[0], r.mV[1], r.mV[2]);
1025 glCallList(sBoxList);
1026 glPopMatrix();
1027}
1028
1029void genBoxList() 1366void genBoxList()
1030{ 1367{
1031 if (sBoxList != 0) 1368 if (sBoxList != 0)
@@ -1077,6 +1414,83 @@ void genBoxList()
1077 glEndList(); 1414 glEndList();
1078} 1415}
1079 1416
1417void drawBox(const LLVector3& c, const LLVector3& r)
1418{
1419 genBoxList();
1420
1421 glPushMatrix();
1422 glTranslatef(c.mV[0], c.mV[1], c.mV[2]);
1423 glScalef(r.mV[0], r.mV[1], r.mV[2]);
1424 glCallList(sBoxList);
1425 glPopMatrix();
1426}
1427
1428void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
1429{
1430 LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
1431 LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1));
1432 LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1));
1433 LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1));
1434
1435 glBegin(GL_LINE_LOOP); //top
1436 glVertex3fv((pos+v1).mV);
1437 glVertex3fv((pos+v2).mV);
1438 glVertex3fv((pos+v3).mV);
1439 glVertex3fv((pos+v4).mV);
1440 glEnd();
1441
1442 glBegin(GL_LINE_LOOP); //bottom
1443 glVertex3fv((pos-v1).mV);
1444 glVertex3fv((pos-v2).mV);
1445 glVertex3fv((pos-v3).mV);
1446 glVertex3fv((pos-v4).mV);
1447 glEnd();
1448
1449
1450 glBegin(GL_LINES);
1451
1452 //right
1453 glVertex3fv((pos+v1).mV);
1454 glVertex3fv((pos-v3).mV);
1455
1456 glVertex3fv((pos+v4).mV);
1457 glVertex3fv((pos-v2).mV);
1458
1459 //left
1460 glVertex3fv((pos+v2).mV);
1461 glVertex3fv((pos-v4).mV);
1462
1463 glVertex3fv((pos+v3).mV);
1464 glVertex3fv((pos-v1).mV);
1465
1466 glEnd();
1467}
1468
1469class LLOctreeDirty : public LLOctreeTraveler<LLDrawable>
1470{
1471public:
1472 virtual void visit(const LLOctreeState<LLDrawable>* state)
1473 {
1474 LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
1475 group->destroyGL();
1476
1477 for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
1478 {
1479 LLDrawable* drawable = *i;
1480 if (drawable->getVObj() && !group->mSpatialPartition->mRenderByGroup)
1481 {
1482 gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE);
1483 }
1484 }
1485
1486 for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
1487 {
1488 LLSpatialBridge* bridge = *i;
1489 traverse(bridge->mOctree);
1490 }
1491 }
1492};
1493
1080void LLSpatialPartition::restoreGL() 1494void LLSpatialPartition::restoreGL()
1081{ 1495{
1082 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 1496 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
@@ -1099,6 +1513,14 @@ void LLSpatialPartition::restoreGL()
1099 genBoxList(); 1513 genBoxList();
1100} 1514}
1101 1515
1516void LLSpatialPartition::resetVertexBuffers()
1517{
1518 LLOctreeDirty dirty;
1519 dirty.traverse(mOctree);
1520
1521 mOcclusionIndices = NULL;
1522}
1523
1102S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select) 1524S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select)
1103{ 1525{
1104 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 1526 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
@@ -1115,11 +1537,11 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
1115 } 1537 }
1116 else 1538 else
1117 { 1539 {
1540 LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL);
1118 LLOctreeCull culler(&camera); 1541 LLOctreeCull culler(&camera);
1119 culler.traverse(mOctree); 1542 culler.traverse(mOctree);
1120 } 1543 }
1121 1544
1122 sIgnoreOcclusion = !(gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery);
1123 return 0; 1545 return 0;
1124} 1546}
1125 1547
@@ -1174,9 +1596,10 @@ public:
1174BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) 1596BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group)
1175{ 1597{
1176 LLVector3 c = group->mBounds[0]; 1598 LLVector3 c = group->mBounds[0];
1177 LLVector3 r = group->mBounds[1] * (SG_OCCLUSION_FUDGE*2.f) + LLVector3(0.01f,0.01f,0.01f); 1599 LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.2f,0.2f,0.2f);
1178 1600
1179 if (group->isState(LLSpatialGroup::CULLED) || !camera->AABBInFrustum(c, r)) 1601 //if (group->isState(LLSpatialGroup::CULLED)) // ||
1602 if (!camera->AABBInFrustum(c, r))
1180 { 1603 {
1181 return TRUE; 1604 return TRUE;
1182 } 1605 }
@@ -1197,6 +1620,100 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group)
1197 return TRUE; 1620 return TRUE;
1198} 1621}
1199 1622
1623void LLSpatialPartition::markReimage(LLSpatialGroup* group)
1624{
1625 if (mImageEnabled && group->isState(LLSpatialGroup::IMAGE_DIRTY))
1626 {
1627 if (!group->isState(LLSpatialGroup::IN_IMAGE_QUEUE))
1628 {
1629 group->setState(LLSpatialGroup::IN_IMAGE_QUEUE);
1630 mImageQueue.push(group);
1631 }
1632 }
1633}
1634
1635void LLSpatialPartition::processImagery(LLCamera* camera)
1636{
1637 if (!mImageEnabled)
1638 {
1639 return;
1640 }
1641
1642 U32 process_count = 1;
1643
1644 while (process_count > 0 && !mImageQueue.empty())
1645 {
1646 LLPointer<LLSpatialGroup> group = mImageQueue.front();
1647 mImageQueue.pop();
1648
1649 group->clearState(LLSpatialGroup::IN_IMAGE_QUEUE);
1650
1651 if (group->isDead())
1652 {
1653 continue;
1654 }
1655
1656 if (LLPipeline::sDynamicReflections)
1657 {
1658 process_count--;
1659 LLVector3 origin = group->mBounds[0];
1660
1661 LLCamera cube_cam;
1662 cube_cam.setOrigin(origin);
1663 cube_cam.setFar(64.f);
1664
1665 LLPointer<LLCubeMap> cube_map = group->mReflectionMap;
1666 group->mReflectionMap = NULL;
1667 if (cube_map.isNull())
1668 {
1669 cube_map = new LLCubeMap();
1670 cube_map->initGL();
1671 }
1672
1673 if (gPipeline.mCubeBuffer == NULL)
1674 {
1675 gPipeline.mCubeBuffer = new LLCubeMap();
1676 gPipeline.mCubeBuffer->initGL();
1677 }
1678
1679 gPipeline.generateReflectionMap(gPipeline.mCubeBuffer, cube_cam, 128);
1680 gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map, 64);
1681 group->mReflectionMap = cube_map;
1682 group->setState(LLSpatialGroup::GEOM_DIRTY);
1683 }
1684
1685 group->clearState(LLSpatialGroup::IMAGE_DIRTY);
1686 }
1687}
1688
1689void validate_occlusion_list(std::vector<LLPointer<LLSpatialGroup> >& occluded_list)
1690{
1691#if !LL_RELEASE_FOR_DOWNLOAD
1692 for (U32 i = 0; i < occluded_list.size(); i++)
1693 {
1694 LLSpatialGroup* group = occluded_list[i];
1695 for (U32 j = i+1; j < occluded_list.size(); j++)
1696 {
1697 if (occluded_list[i] == occluded_list[j])
1698 {
1699 llerrs << "Duplicate node in occlusion list." << llendl;
1700 }
1701 }
1702
1703 LLSpatialGroup::OctreeNode* parent = group->mOctreeNode->getOctParent();
1704 while (parent)
1705 {
1706 LLSpatialGroup* parent_group = (LLSpatialGroup*) parent->getListener(0);
1707 if (parent_group->isState(LLSpatialGroup::OCCLUDED))
1708 {
1709 llerrs << "Child node of occluded node in occlusion list (redundant query)." << llendl;
1710 }
1711 parent = parent->getOctParent();
1712 }
1713 }
1714#endif
1715}
1716
1200void LLSpatialPartition::processOcclusion(LLCamera* camera) 1717void LLSpatialPartition::processOcclusion(LLCamera* camera)
1201{ 1718{
1202 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 1719 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
@@ -1217,12 +1734,12 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1217 const U32 MAX_PUSHED = mOcclusionQueue.size(); 1734 const U32 MAX_PUSHED = mOcclusionQueue.size();
1218 U32 count = 0; 1735 U32 count = 0;
1219 U32 pcount = 0; 1736 U32 pcount = 0;
1220 1737
1221 while (pcount < MAX_PUSHED && count < MAX_PULLED && !mOcclusionQueue.empty()) 1738 while (pcount < MAX_PUSHED && count < MAX_PULLED && !mOcclusionQueue.empty())
1222 { 1739 {
1223 LLFastTimer t(LLFastTimer::FTM_OCCLUSION); 1740 LLFastTimer t(LLFastTimer::FTM_OCCLUSION);
1224 1741
1225 LLSpatialGroup* group = mOcclusionQueue.front(); 1742 LLPointer<LLSpatialGroup> group = mOcclusionQueue.front();
1226 if (!group->isState(LLSpatialGroup::IN_QUEUE)) 1743 if (!group->isState(LLSpatialGroup::IN_QUEUE))
1227 { 1744 {
1228 OCT_ERRS << "Spatial Group State Error. Group in queue not tagged as such." << llendl; 1745 OCT_ERRS << "Spatial Group State Error. Group in queue not tagged as such." << llendl;
@@ -1233,10 +1750,6 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1233 1750
1234 if (group->isDead()) 1751 if (group->isDead())
1235 { 1752 {
1236 if (group->safeToDelete())
1237 {
1238 delete group;
1239 }
1240 continue; 1753 continue;
1241 } 1754 }
1242 1755
@@ -1250,22 +1763,14 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1250 { 1763 {
1251 LLSpatialGroup* child = (LLSpatialGroup*) group->mOctreeNode->getChild(i)->getListener(0); 1764 LLSpatialGroup* child = (LLSpatialGroup*) group->mOctreeNode->getChild(i)->getListener(0);
1252 1765
1253 if (!child->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED) 1766 //if (!child->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED)
1254 && !child->isState(LLSpatialGroup::IN_QUEUE | LLSpatialGroup::ACTIVE_OCCLUSION)) 1767 if (!child->isState(LLSpatialGroup::IN_QUEUE | LLSpatialGroup::ACTIVE_OCCLUSION))
1255 { 1768 {
1256 child->setState(LLSpatialGroup::IN_QUEUE); 1769 child->setState(LLSpatialGroup::IN_QUEUE);
1257 mOcclusionQueue.push(child); 1770 mOcclusionQueue.push(child);
1258 } 1771 }
1259 } 1772 }
1260 1773
1261 /*if (group->isState(LLSpatialGroup::QUERY_PENDING))
1262 { //already on the pending group, put it back
1263 group->setState(LLSpatialGroup::IN_QUEUE);
1264 mOcclusionQueue.push(group);
1265 pcount++;
1266 continue;
1267 }*/
1268
1269 if (earlyFail(camera, group)) 1774 if (earlyFail(camera, group))
1270 { 1775 {
1271 sg_assert(!group->isState(LLSpatialGroup::OCCLUDED)); 1776 sg_assert(!group->isState(LLSpatialGroup::OCCLUDED));
@@ -1284,7 +1789,6 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1284 sg_assert(mOccludedList[i] != group); 1789 sg_assert(mOccludedList[i] != group);
1285 } 1790 }
1286#endif 1791#endif
1287 //group->setState(LLSpatialGroup::QUERY_PENDING);
1288 group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); 1792 group->setState(LLSpatialGroup::ACTIVE_OCCLUSION);
1289 mQueryQueue.push(group); 1793 mQueryQueue.push(group);
1290 count++; 1794 count++;
@@ -1296,7 +1800,7 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1296 { 1800 {
1297 LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); 1801 LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK);
1298 1802
1299 if (mOccludedList[i]->isDead() || !mOccludedList[i]->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) 1803 if (mOccludedList[i]->isDead() || mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION))
1300 { 1804 {
1301 continue; 1805 continue;
1302 } 1806 }
@@ -1347,8 +1851,7 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1347 LLSpatialGroup* parent = (LLSpatialGroup*) oct_parent->getListener(0); 1851 LLSpatialGroup* parent = (LLSpatialGroup*) oct_parent->getListener(0);
1348 1852
1349 if (checkOcclusion(parent, camera)) 1853 if (checkOcclusion(parent, camera))
1350 { //force a guess on the parent and siblings 1854 { //force a guess on the parent and siblings
1351
1352 for (U32 i = 0; i < parent->mOctreeNode->getChildCount(); i++) 1855 for (U32 i = 0; i < parent->mOctreeNode->getChildCount(); i++)
1353 { 1856 {
1354 LLSpatialGroup* child = (LLSpatialGroup*) parent->mOctreeNode->getChild(i)->getListener(0); 1857 LLSpatialGroup* child = (LLSpatialGroup*) parent->mOctreeNode->getChild(i)->getListener(0);
@@ -1356,13 +1859,17 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1356 } 1859 }
1357 } 1860 }
1358 } 1861 }
1862
1863 //take children off the active list
1864 mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_BRANCH);
1865 mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION);
1359 } 1866 }
1360 mOccludedList[i]->setState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); 1867 mOccludedList[i]->setState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
1361 } 1868 }
1362 else 1869 else
1363 { 1870 {
1364 //take children off the active list 1871 //take children off the active list
1365 mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_DIFF); 1872 mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_BRANCH);
1366 1873
1367 //keep this node on the active list 1874 //keep this node on the active list
1368 mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); 1875 mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION);
@@ -1383,15 +1890,13 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1383 mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) //parent is occluded 1890 mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) //parent is occluded
1384 { 1891 {
1385 LLSpatialGroup* groupp = mOccludedList[i]; 1892 LLSpatialGroup* groupp = mOccludedList[i];
1386 mOccludedList.erase(mOccludedList.begin()+i); 1893 if (!groupp->isDead())
1387 groupp->clearState(LLSpatialGroup::ACTIVE_OCCLUSION);
1388 groupp->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION);
1389 groupp->clearState(LLSpatialGroup::OCCLUDING);
1390
1391 if (groupp->isDead() && groupp->safeToDelete())
1392 { 1894 {
1393 delete groupp; 1895 groupp->clearState(LLSpatialGroup::ACTIVE_OCCLUSION);
1896 groupp->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION);
1897 groupp->clearState(LLSpatialGroup::OCCLUDING);
1394 } 1898 }
1899 mOccludedList.erase(mOccludedList.begin()+i);
1395 } 1900 }
1396 else 1901 else
1397 { 1902 {
@@ -1399,11 +1904,13 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1399 } 1904 }
1400 } 1905 }
1401 1906
1907 validate_occlusion_list(mOccludedList);
1908
1402 //pump some non-culled items onto the occlusion list 1909 //pump some non-culled items onto the occlusion list
1403 //count = MAX_PULLED; 1910 //count = MAX_PULLED;
1404 while (!mQueryQueue.empty()) 1911 while (!mQueryQueue.empty())
1405 { 1912 {
1406 LLSpatialGroup* group = mQueryQueue.front(); 1913 LLPointer<LLSpatialGroup> group = mQueryQueue.front();
1407 mQueryQueue.pop(); 1914 mQueryQueue.pop();
1408 //group->clearState(LLSpatialGroup::QUERY_PENDING); 1915 //group->clearState(LLSpatialGroup::QUERY_PENDING);
1409 mOccludedList.push_back(group); 1916 mOccludedList.push_back(group);
@@ -1418,12 +1925,161 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera)
1418 } 1925 }
1419} 1926}
1420 1927
1928class LLOcclusionIndexBuffer : public LLVertexBuffer
1929{
1930public:
1931 LLOcclusionIndexBuffer(U32 size)
1932 : LLVertexBuffer(0, GL_STREAM_DRAW_ARB)
1933 {
1934 allocateBuffer(0, size, TRUE);
1935
1936 LLStrider<U32> idx;
1937
1938 getIndexStrider(idx);
1939
1940 //12 triangles' indices
1941 idx[0] = 1; idx[1] = 0; idx[2] = 2; //front
1942 idx[3] = 3; idx[4] = 2; idx[5] = 0;
1943
1944 idx[6] = 4; idx[7] = 5; idx[8] = 1; //top
1945 idx[9] = 0; idx[10] = 1; idx[11] = 5;
1946
1947 idx[12] = 5; idx[13] = 4; idx[14] = 6; //back
1948 idx[15] = 7; idx[16] = 6; idx[17] = 4;
1949
1950 idx[18] = 6; idx[19] = 7; idx[20] = 3; //bottom
1951 idx[21] = 2; idx[22] = 3; idx[23] = 7;
1952
1953 idx[24] = 0; idx[25] = 5; idx[26] = 3; //left
1954 idx[27] = 6; idx[28] = 3; idx[29] = 5;
1955
1956 idx[30] = 4; idx[31] = 1; idx[32] = 7; //right
1957 idx[33] = 2; idx[34] = 7; idx[35] = 1;
1958 }
1959
1960 //virtual BOOL useVBOs() const { return FALSE; }
1961
1962 void setBuffer(U32 data_mask)
1963 {
1964 if (useVBOs())
1965 {
1966 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
1967 sIBOActive = TRUE;
1968 unmapBuffer();
1969 }
1970 else if (sIBOActive)
1971 {
1972 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1973 sIBOActive = FALSE;
1974 }
1975
1976 sGLRenderIndices = mGLIndices;
1977 }
1978};
1979
1980class LLOcclusionVertexBuffer : public LLVertexBuffer
1981{
1982public:
1983 LLOcclusionVertexBuffer(S32 usage)
1984 : LLVertexBuffer(MAP_VERTEX, usage)
1985 {
1986 allocateBuffer(8, 0, TRUE);
1987 }
1988
1989 //virtual BOOL useVBOs() const { return FALSE; }
1990
1991 void setBuffer(U32 data_mask)
1992 {
1993 if (useVBOs())
1994 {
1995 glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
1996 sVBOActive = TRUE;
1997 unmapBuffer();
1998 }
1999 else if (sVBOActive)
2000 {
2001 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
2002 sVBOActive = FALSE;
2003 }
2004
2005 if (data_mask)
2006 {
2007 glVertexPointer(3,GL_FLOAT, 0, useVBOs() ? 0 : mMappedData);
2008 }
2009
2010 sGLRenderBuffer = mGLBuffer;
2011 }
2012};
2013
2014void LLSpatialPartition::buildOcclusion()
2015{
2016 if (mOccludedList.empty())
2017 {
2018 return;
2019 }
2020
2021 BOOL reset_all = FALSE;
2022 if (mOcclusionIndices.isNull())
2023 {
2024 mOcclusionIndices = new LLOcclusionIndexBuffer(36);
2025 reset_all = TRUE;
2026 }
2027
2028 //fill occlusion vertex buffers
2029 for (U32 i = 0; i < mOccludedList.size(); i++)
2030 {
2031 LLSpatialGroup* group = mOccludedList[i];
2032
2033 if (group->isState(LLSpatialGroup::OCCLUSION_DIRTY) || reset_all)
2034 {
2035 LLFastTimer ftm(LLFastTimer::FTM_REBUILD_OCCLUSION_VB);
2036
2037 if (group->mOcclusionVerts.isNull())
2038 {
2039 group->mOcclusionVerts = new LLOcclusionVertexBuffer(GL_STREAM_DRAW_ARB);
2040 }
2041
2042 group->clearState(LLSpatialGroup::OCCLUSION_DIRTY);
2043
2044 LLStrider<LLVector3> vert;
2045
2046 group->mOcclusionVerts->getVertexStrider(vert);
2047
2048 LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.1f,0.1f,0.1f);
2049
2050 for (U32 k = 0; k < 3; k++)
2051 {
2052 r.mV[k] = llmin(group->mBounds[1].mV[k]+0.25f, r.mV[k]);
2053 }
2054
2055 *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,1,1)); // 0 - left top front
2056 *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,1,1)); // 1 - right top front
2057 *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,-1,1)); // 2 - right bottom front
2058 *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,-1,1)); // 3 - left bottom front
2059
2060 *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,1,-1)); // 4 - left top back
2061 *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,1,-1)); // 5 - right top back
2062 *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back
2063 *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back
2064 }
2065 }
2066
2067/* for (U32 i = 0; i < mOccludedList.size(); i++)
2068 {
2069 LLSpatialGroup* group = mOccludedList[i];
2070 if (!group->mOcclusionVerts.isNull() && group->mOcclusionVerts->isLocked())
2071 {
2072 LLFastTimer ftm(LLFastTimer::FTM_REBUILD_OCCLUSION_VB);
2073 group->mOcclusionVerts->setBuffer(0);
2074 }
2075 }*/
2076}
2077
1421void LLSpatialPartition::doOcclusion(LLCamera* camera) 2078void LLSpatialPartition::doOcclusion(LLCamera* camera)
1422{ 2079{
1423 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); 2080 LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
1424 2081
1425 sIgnoreOcclusion = gUseWireframe; 2082 LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION);
1426 LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION);
1427 2083
1428#if LL_OCTREE_PARANOIA_CHECK 2084#if LL_OCTREE_PARANOIA_CHECK
1429 LLSpatialGroup* check = (LLSpatialGroup*) mOctree->getListener(0); 2085 LLSpatialGroup* check = (LLSpatialGroup*) mOctree->getListener(0);
@@ -1432,9 +2088,16 @@ void LLSpatialPartition::doOcclusion(LLCamera* camera)
1432 2088
1433 stop_glerror(); 2089 stop_glerror();
1434 2090
2091 U32 num_verts = mOccludedList.size() * 8;
2092
2093 if (num_verts == 0)
2094 {
2095 return;
2096 }
2097
1435 //actually perform the occlusion queries 2098 //actually perform the occlusion queries
1436 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); 2099 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
1437 glDisable(GL_TEXTURE_2D); 2100 LLGLDisable(GL_TEXTURE_2D);
1438 gPipeline.disableLights(); 2101 gPipeline.disableLights();
1439 LLGLEnable cull_face(GL_CULL_FACE); 2102 LLGLEnable cull_face(GL_CULL_FACE);
1440 LLGLDisable blend(GL_BLEND); 2103 LLGLDisable blend(GL_BLEND);
@@ -1443,25 +2106,16 @@ void LLSpatialPartition::doOcclusion(LLCamera* camera)
1443 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 2106 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1444 glColor4f(1,1,1,1); 2107 glColor4f(1,1,1,1);
1445 2108
1446 //sort occlusion queries front to back 2109 mOcclusionIndices->setBuffer(0);
1447 /*for (U32 i = 0; i < mOccludedList.size(); i++)
1448 {
1449 LLSpatialGroup* group = mOccludedList[i];
1450
1451 LLVector3 v = group->mOctreeNode->getCenter()-camera->getOrigin();
1452 group->mDistance = v*v;
1453 }
1454
1455 std::sort(mOccludedList.begin(), mOccludedList.end(), dist_greater());
1456 2110
1457 glClearStencil(0); 2111 U32* indicesp = (U32*) mOcclusionIndices->getIndicesPointer();
1458 glClear(GL_STENCIL_BUFFER_BIT);
1459 LLGLEnable stencil(GL_STENCIL_TEST);
1460 glStencilFunc(GL_GREATER, 1, 0xFFFFFFFF);
1461 glStencilOp(GL_KEEP, GL_SET, GL_KEEP);*/
1462
1463 genBoxList();
1464 2112
2113 glDisableClientState(GL_NORMAL_ARRAY);
2114 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2115 glDisableClientState(GL_COLOR_ARRAY);
2116#if !LL_RELEASE_FOR_DOWNLOAD
2117 LLGLState::checkClientArrays(LLVertexBuffer::MAP_VERTEX);
2118#endif
1465 for (U32 i = 0; i < mOccludedList.size(); i++) 2119 for (U32 i = 0; i < mOccludedList.size(); i++)
1466 { 2120 {
1467#if LL_OCTREE_PARANOIA_CHECK 2121#if LL_OCTREE_PARANOIA_CHECK
@@ -1482,32 +2136,10 @@ void LLSpatialPartition::doOcclusion(LLCamera* camera)
1482 } 2136 }
1483 else 2137 else
1484 { //early rejection criteria passed, send some geometry to the query 2138 { //early rejection criteria passed, send some geometry to the query
1485 LLVector3 c; 2139 group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
1486 LLVector3 r;
1487
1488 sg_assert(!group->isState(LLSpatialGroup::DIRTY));
1489
1490 c = group->mBounds[0];
1491 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.01f,0.01f,0.01f);
1492 for (U32 k = 0; k < 3; k++)
1493 {
1494 r.mV[k] = llmin(group->mBounds[1].mV[k]+0.25f, r.mV[k]);
1495 }
1496
1497#if LL_OCTREE_PARANOIA_CHECK
1498 LLVector3 e = camera->getOrigin();
1499 LLVector3 min = c - r;
1500 LLVector3 max = c + r;
1501 BOOL outside = FALSE;
1502 for (U32 j = 0; j < 3; j++)
1503 {
1504 outside = outside || (e.mV[j] < min.mV[j] || e.mV[j] > max.mV[j]);
1505 }
1506 sg_assert(outside);
1507#endif
1508
1509 glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQueries[i]); 2140 glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQueries[i]);
1510 drawBox(c,r); 2141 glDrawRangeElements(GL_TRIANGLES, 0, 7, 36,
2142 GL_UNSIGNED_INT, indicesp);
1511 glEndQueryARB(GL_SAMPLES_PASSED_ARB); 2143 glEndQueryARB(GL_SAMPLES_PASSED_ARB);
1512 2144
1513 group->setState(LLSpatialGroup::QUERY_OUT); 2145 group->setState(LLSpatialGroup::QUERY_OUT);
@@ -1516,10 +2148,11 @@ void LLSpatialPartition::doOcclusion(LLCamera* camera)
1516 } 2148 }
1517 stop_glerror(); 2149 stop_glerror();
1518 2150
2151 gPipeline.mTrianglesDrawn += mOccludedList.size()*12;
2152
1519 glFlush(); 2153 glFlush();
1520 2154
1521 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 2155 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1522 glEnable(GL_TEXTURE_2D);
1523} 2156}
1524 2157
1525class LLOctreeGet : public LLSpatialGroup::OctreeTraveler 2158class LLOctreeGet : public LLSpatialGroup::OctreeTraveler
@@ -1618,6 +2251,8 @@ S32 LLSpatialPartition::getDrawables(const LLVector3& pos, F32 rad,
1618 2251
1619S32 LLSpatialPartition::getObjects(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results) 2252S32 LLSpatialPartition::getObjects(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results)
1620{ 2253{
2254 LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
2255 group->rebound();
1621 return getDrawables(pos, rad, results, FALSE); 2256 return getDrawables(pos, rad, results, FALSE);
1622} 2257}
1623 2258
@@ -1626,182 +2261,363 @@ S32 LLSpatialPartition::getLights(const LLVector3& pos, F32 rad, LLDrawable::dra
1626 return getDrawables(pos, rad, results, TRUE); 2261 return getDrawables(pos, rad, results, TRUE);
1627} 2262}
1628 2263
1629class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> 2264void pushVerts(LLDrawInfo* params, U32 mask)
1630{ 2265{
1631public: 2266 params->mVertexBuffer->setBuffer(mask);
1632 LLOctreeRenderNonOccluded() {} 2267 U32* indicesp = (U32*) params->mVertexBuffer->getIndicesPointer();
1633 2268 glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount,
1634 virtual void traverse(const LLSpatialGroup::OctreeNode* node) 2269 GL_UNSIGNED_INT, indicesp+params->mOffset);
2270}
2271
2272void pushVerts(LLSpatialGroup* group, U32 mask)
2273{
2274 LLDrawInfo* params = NULL;
2275
2276 for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
1635 { 2277 {
1636 const LLSpatialGroup::OctreeState* state = node->getOctState(); 2278 for (std::vector<LLDrawInfo*>::iterator j = i->second.begin(); j != i->second.end(); ++j)
1637 LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); 2279 {
2280 params = *j;
2281 pushVerts(params, mask);
2282 }
2283 }
2284}
2285
2286void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
2287{
2288 LLDrawInfo* params = NULL;
2289
2290 LLColor4 colors[] = {
2291 LLColor4::green,
2292 LLColor4::green1,
2293 LLColor4::green2,
2294 LLColor4::green3,
2295 LLColor4::green4,
2296 LLColor4::green5,
2297 LLColor4::green6
2298 };
1638 2299
1639 if (!group->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED)) 2300 static const U32 col_count = sizeof(colors)/sizeof(LLColor4);
2301
2302 U32 col = 0;
2303
2304 for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
2305 {
2306 for (std::vector<LLDrawInfo*>::iterator j = i->second.begin(); j != i->second.end(); ++j)
1640 { 2307 {
1641 state->accept(this); 2308 params = *j;
2309 glColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f);
2310 params->mVertexBuffer->setBuffer(mask);
2311 U32* indicesp = (U32*) params->mVertexBuffer->getIndicesPointer();
2312 glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount,
2313 GL_UNSIGNED_INT, indicesp+params->mOffset);
2314 col = (col+1)%col_count;
2315 }
2316 }
2317}
1642 2318
1643 for (U32 i = 0; i < state->getChildCount(); i++) 2319void renderOctree(LLSpatialGroup* group)
2320{
2321 //render solid object bounding box, color
2322 //coded by buffer usage and activity
2323 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
2324 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
2325 LLVector4 col;
2326 if (group->mBuilt > 0.f)
2327 {
2328 group->mBuilt -= 2.f * gFrameIntervalSeconds;
2329 if (group->mBufferUsage == GL_STATIC_DRAW_ARB)
2330 {
2331 col.setVec(1.0f, 0, 0, group->mBuilt*0.5f);
2332 }
2333 else
2334 {
2335 col.setVec(0.1f,0.1f,1,0.1f);
2336 //col.setVec(1.0f, 1.0f, 0, sinf(group->mBuilt*3.14159f)*0.5f);
2337 }
2338
2339 if (group->mBufferUsage != GL_STATIC_DRAW_ARB)
2340 {
2341 if (group->mBufferUsage == GL_DYNAMIC_DRAW_ARB)
1644 { 2342 {
1645 traverse(state->getChild(i)); 2343 glColor4f(1,0,0,group->mBuilt);
1646 } 2344 }
1647 2345 else
1648 /*if (state->getElementCount() == 0)
1649 { 2346 {
1650 return; 2347 glColor4f(1,1,0,group->mBuilt);
1651 }*/ 2348 }
1652 2349
1653 //draw tight fit bounding box for spatial group 2350 LLGLDepthTest gl_depth(FALSE, FALSE);
1654 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) 2351 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2352 for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
1655 { 2353 {
1656 if (node->getElementCount() == 0) 2354 LLDrawable* drawable = *i;
1657 { 2355 for (S32 j = 0; j < drawable->getNumFaces(); j++)
1658 return;
1659 }
1660
1661 if (node->hasLeafState())
1662 {
1663 glColor4f(1,1,1,1);
1664 }
1665 else
1666 { 2356 {
1667 glColor4f(0,1,1,1); 2357 LLFace* face = drawable->getFace(j);
2358 if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f && face->mVertexBuffer.notNull())
2359 {
2360 face->mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX);
2361 //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f,
2362 // (face->mExtents[1]-face->mExtents[0])*0.5f);
2363 glDrawElements(GL_TRIANGLES, face->getIndicesCount(), GL_UNSIGNED_INT,
2364 ((U32*) face->mVertexBuffer->getIndicesPointer())+face->getIndicesStart());
2365 }
1668 } 2366 }
2367 }
2368 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2369 }
2370 }
2371 else
2372 {
2373 if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty()
2374 && group->mSpatialPartition->mRenderByGroup)
2375 {
2376 col.setVec(0.8f, 0.4f, 0.1f, 0.1f);
2377 }
2378 else
2379 {
2380 col.setVec(0.1f, 0.1f, 1.f, 0.1f);
2381 }
2382 }
1669 2383
2384 glColor4fv(col.mV);
2385 drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f));
2386 glDepthMask(GL_TRUE);
2387 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1670 2388
1671 LLVector3 pos; 2389 //draw opaque outline
1672 LLVector3 size; 2390 glColor4f(col.mV[0], col.mV[1], col.mV[2], 1.f);
1673 2391 drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]);
1674 pos = group->mObjectBounds[0];
1675 size = group->mObjectBounds[1];
1676
1677 LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
1678 LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1));
1679 LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1));
1680 LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1));
1681
1682 glBegin(GL_LINE_LOOP); //top
1683 glVertex3fv((pos+v1).mV);
1684 glVertex3fv((pos+v2).mV);
1685 glVertex3fv((pos+v3).mV);
1686 glVertex3fv((pos+v4).mV);
1687 glEnd();
1688
1689 glBegin(GL_LINE_LOOP); //bottom
1690 glVertex3fv((pos-v1).mV);
1691 glVertex3fv((pos-v2).mV);
1692 glVertex3fv((pos-v3).mV);
1693 glVertex3fv((pos-v4).mV);
1694 glEnd();
1695
1696
1697 glBegin(GL_LINES);
1698
1699 //right
1700 glVertex3fv((pos+v1).mV);
1701 glVertex3fv((pos-v3).mV);
1702
1703 glVertex3fv((pos+v4).mV);
1704 glVertex3fv((pos-v2).mV);
1705
1706 //left
1707 glVertex3fv((pos+v2).mV);
1708 glVertex3fv((pos-v4).mV);
1709
1710 glVertex3fv((pos+v3).mV);
1711 glVertex3fv((pos-v1).mV);
1712 2392
1713 glEnd(); 2393 if (group->mOctreeNode->hasLeafState())
2394 {
2395 glColor4f(1,1,1,1);
2396 }
2397 else
2398 {
2399 glColor4f(0,1,1,1);
2400 }
2401
2402 drawBoxOutline(group->mBounds[0],group->mBounds[1]);
2403
2404// LLSpatialGroup::OctreeNode* node = group->mOctreeNode;
2405// glColor4f(0,1,0,1);
2406// drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize()));
2407}
1714 2408
1715 LLVector3 nc = LLVector3(node->getCenter()); 2409void renderVisibility(LLSpatialGroup* group)
1716 LLVector3 ns = LLVector3(node->getSize()); 2410{
2411 LLGLEnable blend(GL_BLEND);
2412 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2413 LLGLEnable cull(GL_CULL_FACE);
2414 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2415 {
2416 LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
2417 glColor4f(0, 0.5f, 0, 0.5f);
2418 pushVerts(group, LLVertexBuffer::MAP_VERTEX);
2419 }
1717 2420
1718 LLVector3 nv1 = ns.scaledVec(LLVector3( 1, 1,1)); 2421 {
1719 LLVector3 nv2 = ns.scaledVec(LLVector3(-1, 1,1)); 2422 LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL);
1720 LLVector3 nv3 = ns.scaledVec(LLVector3(-1,-1,1)); 2423 pushVertsColorCoded(group, LLVertexBuffer::MAP_VERTEX);
1721 LLVector3 nv4 = ns.scaledVec(LLVector3( 1,-1,1));
1722 2424
1723 2425 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1724 2426
1725 /*if (node->getElementCount() > 0) 2427 pushVertsColorCoded(group, LLVertexBuffer::MAP_VERTEX);
1726 { 2428 }
1727 //spokes 2429}
1728 glColor4f(1,1,0,1);
1729 glVertex3fv(pos.mV);
1730 glColor4f(1,1,0,0);
1731 glVertex3fv(nc.mV);
1732
1733 glColor4f(1,1,0,1); glVertex3fv((pos+v1).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV);
1734 glColor4f(1,1,0,1); glVertex3fv((pos-v1).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV);
1735 glColor4f(1,1,0,1); glVertex3fv((pos+v2).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV);
1736 glColor4f(1,1,0,1); glVertex3fv((pos-v2).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV);
1737 glColor4f(1,1,0,1); glVertex3fv((pos+v3).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV);
1738 glColor4f(1,1,0,1); glVertex3fv((pos-v3).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV);
1739 glColor4f(1,1,0,1); glVertex3fv((pos+v4).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV);
1740 glColor4f(1,1,0,1); glVertex3fv((pos-v4).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV);
1741 }*/
1742 2430
1743 2431void renderBoundingBox(LLDrawable* drawable)
2432{
2433 if (drawable->isSpatialBridge())
2434 {
2435 glColor4f(1,0.5f,0,1);
2436 }
2437 else if (drawable->getVOVolume())
2438 {
2439 if (drawable->isRoot())
2440 {
2441 glColor4f(1,1,0,1);
2442 }
2443 else
2444 {
2445 glColor4f(0,1,0,1);
2446 }
2447 }
2448 else if (drawable->getVObj())
2449 {
2450 switch (drawable->getVObj()->getPCode())
2451 {
2452 case LLViewerObject::LL_VO_SURFACE_PATCH:
2453 glColor4f(0,1,1,1);
2454 break;
2455 case LLViewerObject::LL_VO_CLOUDS:
2456 glColor4f(0.5f,0.5f,0.5f,1.0f);
2457 break;
2458 case LLViewerObject::LL_VO_PART_GROUP:
2459 glColor4f(0,0,1,1);
2460 break;
2461 case LLViewerObject::LL_VO_WATER:
2462 glColor4f(0,0.5f,1,1);
2463 break;
2464 case LL_PCODE_LEGACY_TREE:
2465 glColor4f(0,0.5f,0,1);
2466 default:
2467 glColor4f(1,0,1,1);
2468 break;
2469 }
2470 }
2471 else
2472 {
2473 glColor4f(1,0,0,1);
2474 }
1744 2475
1745 /*glColor4f(0,1,0,1); 2476 const LLVector3* ext;
1746 glBegin(GL_LINE_LOOP); //top 2477 LLVector3 pos, size;
1747 glVertex3fv((nc+nv1).mV);
1748 glVertex3fv((nc+nv2).mV);
1749 glVertex3fv((nc+nv3).mV);
1750 glVertex3fv((nc+nv4).mV);
1751 glEnd();
1752 2478
1753 glBegin(GL_LINE_LOOP); //bottom 2479 //render face bounding boxes
1754 glVertex3fv((nc-nv1).mV); 2480 for (S32 i = 0; i < drawable->getNumFaces(); i++)
1755 glVertex3fv((nc-nv2).mV); 2481 {
1756 glVertex3fv((nc-nv3).mV); 2482 LLFace* facep = drawable->getFace(i);
1757 glVertex3fv((nc-nv4).mV);
1758 glEnd();
1759 2483
2484 ext = facep->mExtents;
1760 2485
1761 glBegin(GL_LINES); 2486 if (ext[0].isExactlyZero() && ext[1].isExactlyZero())
2487 {
2488 continue;
2489 }
2490 pos = (ext[0] + ext[1]) * 0.5f;
2491 size = (ext[1] - ext[0]) * 0.5f;
2492 drawBoxOutline(pos,size);
2493 }
1762 2494
1763 //right 2495 //render drawable bounding box
1764 glVertex3fv((nc+nv1).mV); 2496 ext = drawable->getSpatialExtents();
1765 glVertex3fv((nc-nv3).mV);
1766
1767 glVertex3fv((nc+nv4).mV);
1768 glVertex3fv((nc-nv2).mV);
1769 2497
1770 //left 2498 pos = (ext[0] + ext[1]) * 0.5f;
1771 glVertex3fv((nc+nv2).mV); 2499 size = (ext[1] - ext[0]) * 0.5f;
1772 glVertex3fv((nc-nv4).mV); 2500
2501 drawBoxOutline(pos,size);
2502}
1773 2503
1774 glVertex3fv((nc+nv3).mV); 2504void renderTexturePriority(LLDrawable* drawable)
1775 glVertex3fv((nc-nv1).mV); 2505{
1776 glEnd();*/ 2506 for (int face=0; face<drawable->getNumFaces(); ++face)
2507 {
2508 LLFace *facep = drawable->getFace(face);
2509
2510 LLVector4 cold(0,0,0.25f);
2511 LLVector4 hot(1,0.25f,0.25f);
2512
2513 LLVector4 boost_cold(0,0,0,0);
2514 LLVector4 boost_hot(0,1,0,1);
2515
2516 LLGLDisable blend(GL_BLEND);
2517
2518 //LLViewerImage* imagep = facep->getTexture();
2519 //if (imagep)
2520 {
2521
2522 //F32 vsize = LLVOVolume::getTextureVirtualSize(facep);
2523 //F32 vsize = imagep->mMaxVirtualSize;
2524 F32 vsize = facep->getPixelArea();
1777 2525
1778 glLineWidth(1); 2526 if (vsize > sCurMaxTexPriority)
1779 2527 {
1780 glDepthMask(GL_FALSE); 2528 sCurMaxTexPriority = vsize;
1781 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1782 glColor4f(0.1f,0.1f,1,0.1f);
1783 drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f));
1784 glDepthMask(GL_TRUE);
1785 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1786 } 2529 }
2530
2531 F32 t = vsize/sLastMaxTexPriority;
2532
2533 LLVector4 col = lerp(cold, hot, t);
2534 glColor4fv(col.mV);
1787 } 2535 }
1788 /*else 2536 //else
2537 //{
2538 // glColor4f(1,0,1,1);
2539 //}
2540
2541
2542
2543 LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f;
2544 LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f);
2545 drawBox(center, size);
2546
2547 /*S32 boost = imagep->getBoostLevel();
2548 if (boost)
2549 {
2550 F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1);
2551 LLVector4 col = lerp(boost_cold, boost_hot, t);
2552 LLGLEnable blend_on(GL_BLEND);
2553 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
2554 glColor4fv(col.mV);
2555 drawBox(center, size);
2556 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2557 }*/
2558 }
2559}
2560
2561void renderPoints(LLDrawable* drawablep)
2562{
2563 LLGLDepthTest depth(GL_FALSE, GL_FALSE);
2564 glBegin(GL_POINTS);
2565 glColor3f(1,1,1);
2566 LLVector3 center(drawablep->getPositionGroup());
2567 for (S32 i = 0; i < drawablep->getNumFaces(); i++)
2568 {
2569 glVertex3fv(drawablep->getFace(i)->mCenterLocal.mV);
2570 }
2571 glEnd();
2572}
2573
2574void renderTextureAnim(LLDrawInfo* params)
2575{
2576 if (!params->mTextureMatrix)
2577 {
2578 return;
2579 }
2580
2581 LLGLEnable blend(GL_BLEND);
2582 glColor4f(1,1,0,0.5f);
2583 pushVerts(params, LLVertexBuffer::MAP_VERTEX);
2584}
2585
2586class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>
2587{
2588public:
2589 LLOctreeRenderNonOccluded() {}
2590
2591 virtual void traverse(const LLSpatialGroup::OctreeNode* node)
2592 {
2593 const LLSpatialGroup::OctreeState* state = node->getOctState();
2594 LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
2595
2596
2597 if ((!gPipeline.sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) &&
2598 !group->isState(LLSpatialGroup::CULLED))
1789 { 2599 {
1790 //occlusion paranoia check 2600 state->accept(this);
1791 const LLSpatialGroup::OctreeNode* parent = node; 2601
1792 while (parent != NULL) 2602 for (U32 i = 0; i < state->getChildCount(); i++)
1793 { 2603 {
1794 LLSpatialGroup* grp = (LLSpatialGroup*) parent->getListener(0); 2604 traverse(state->getChild(i));
1795 if (grp->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) 2605 }
1796 { 2606
1797 return; 2607 //draw tight fit bounding boxes for spatial group
1798 } 2608 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE))
1799 parent = (const LLSpatialGroup::OctreeNode*) parent->getParent(); 2609 {
2610 renderOctree(group);
1800 } 2611 }
1801 2612
1802 glColor4f(1,0,1,1); 2613 //render visibility wireframe
1803 drawBox(group->mBounds[0], group->mBounds[1]); 2614 if (group->mSpatialPartition->mRenderByGroup &&
1804 }*/ 2615 gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) &&
2616 !group->isState(LLSpatialGroup::GEOM_DIRTY))
2617 {
2618 renderVisibility(group);
2619 }
2620 }
1805 } 2621 }
1806 2622
1807 virtual void visit(const LLSpatialGroup::OctreeState* branch) 2623 virtual void visit(const LLSpatialGroup::OctreeState* branch)
@@ -1816,276 +2632,37 @@ public:
1816 LLVector3 nodeCenter = group->mBounds[0]; 2632 LLVector3 nodeCenter = group->mBounds[0];
1817 LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); 2633 LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter());
1818 2634
1819 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE))
1820 {
1821 glBegin(GL_LINES);
1822 glColor4f(1,0.5f,0,1);
1823 glVertex3fv(nodeCenter.mV);
1824 glColor4f(0,1,1,0);
1825 glVertex3fv(octCenter.mV);
1826 glEnd();
1827 }
1828
1829 for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) 2635 for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
1830 { 2636 {
1831 LLDrawable* drawable = *i; 2637 LLDrawable* drawable = *i;
1832 2638
1833 if (drawable->isSpatialBridge())
1834 {
1835 LLSpatialBridge* bridge = (LLSpatialBridge*) drawable;
1836 glPushMatrix();
1837 glMultMatrixf((F32*)bridge->mDrawable->getWorldMatrix().mMatrix);
1838 traverse(bridge->mOctree);
1839 glPopMatrix();
1840 }
1841
1842 if (!drawable->isVisible())
1843 {
1844 continue;
1845 }
1846
1847 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) 2639 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
1848 { 2640 {
1849 if (drawable->isSpatialBridge()) 2641 renderBoundingBox(drawable);
1850 {
1851 glColor4f(1,0.5f,0,1);
1852 }
1853 else if (drawable->getVOVolume())
1854 {
1855 if (drawable->isRoot())
1856 {
1857 glColor4f(1,1,0,1);
1858 }
1859 else
1860 {
1861 glColor4f(0,1,0,1);
1862 }
1863 }
1864 else if (drawable->getVObj())
1865 {
1866 switch (drawable->getVObj()->getPCode())
1867 {
1868 case LLViewerObject::LL_VO_SURFACE_PATCH:
1869 glColor4f(0,1,1,1);
1870 break;
1871 case LLViewerObject::LL_VO_CLOUDS:
1872 glColor4f(0.5f,0.5f,0.5f,1.0f);
1873 break;
1874 case LLViewerObject::LL_VO_PART_GROUP:
1875 glColor4f(0,0,1,1);
1876 break;
1877 case LLViewerObject::LL_VO_WATER:
1878 glColor4f(0,0.5f,1,1);
1879 break;
1880 case LL_PCODE_LEGACY_TREE:
1881 glColor4f(0,0.5f,0,1);
1882 default:
1883 glColor4f(1,0,1,1);
1884 break;
1885 }
1886 }
1887 else
1888 {
1889 glColor4f(1,0,0,1);
1890 }
1891
1892
1893 const LLVector3* ext = drawable->getSpatialExtents();
1894
1895 LLVector3 pos = (ext[0] + ext[1]) * 0.5f;
1896 LLVector3 size = (ext[1] - ext[0]) * 0.5f;
1897
1898 LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
1899 LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1));
1900 LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1));
1901 LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1));
1902
1903 glBegin(GL_LINE_LOOP); //top
1904 glVertex3fv((pos+v1).mV);
1905 glVertex3fv((pos+v2).mV);
1906 glVertex3fv((pos+v3).mV);
1907 glVertex3fv((pos+v4).mV);
1908 glEnd();
1909
1910 glBegin(GL_LINE_LOOP); //bottom
1911 glVertex3fv((pos-v1).mV);
1912 glVertex3fv((pos-v2).mV);
1913 glVertex3fv((pos-v3).mV);
1914 glVertex3fv((pos-v4).mV);
1915 glEnd();
1916
1917
1918 glBegin(GL_LINES);
1919
1920 //right
1921 glVertex3fv((pos+v1).mV);
1922 glVertex3fv((pos-v3).mV);
1923
1924 glVertex3fv((pos+v4).mV);
1925 glVertex3fv((pos-v2).mV);
1926
1927 //left
1928 glVertex3fv((pos+v2).mV);
1929 glVertex3fv((pos-v4).mV);
1930
1931 glVertex3fv((pos+v3).mV);
1932 glVertex3fv((pos-v1).mV);
1933
1934 glEnd();
1935
1936 //render space partition trace
1937 glBegin(GL_LINE_STRIP);
1938 glColor4f(1,0,0,1);
1939 glVertex3fv(pos.mV);
1940 glColor4f(0,1,0,1);
1941 glVertex3dv(drawable->getPositionGroup().mdV);
1942 glColor4f(0,0,1,1);
1943 glVertex3fv(nodeCenter.mV);
1944 glColor4f(1,1,0,1);
1945 glVertex3fv(octCenter.mV);
1946 glEnd();
1947 } 2642 }
1948 2643
1949 if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_CHAINS | LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) 2644 if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
1950 { 2645 {
1951 glLineWidth(3); 2646 renderTexturePriority(drawable);
1952
1953 for (int face=0; face<drawable->getNumFaces(); ++face)
1954 {
1955 LLFace *facep = drawable->getFace(face);
1956
1957 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_CHAINS))
1958 {
1959 LLGLDepthTest depth(GL_FALSE);
1960 if (facep->mNextFace)
1961 {
1962 glBegin(GL_LINE_STRIP);
1963
1964 if (facep->isState(LLFace::GLOBAL))
1965 {
1966 glColor4f(0,1,0,1);
1967 }
1968 else
1969 {
1970 glColor4f(1,0.5f,0.25f,1);
1971 }
1972
1973 if (drawable->isActive())
1974 {
1975 glVertex3fv(facep->mCenterLocal.mV);
1976 glVertex3fv(facep->mNextFace->mCenterLocal.mV);
1977 }
1978 else
1979 {
1980 glVertex3fv(facep->mCenterAgent.mV);
1981 glVertex3fv(facep->mNextFace->mCenterAgent.mV);
1982 }
1983
1984 glEnd();
1985 }
1986 else
1987 {
1988 glPointSize(5);
1989 glBegin(GL_POINTS);
1990
1991 if (!facep->isState(LLFace::GLOBAL))
1992 {
1993 glColor4f(1,0.75f,0,1);
1994 glVertex3fv(facep->mCenterLocal.mV);
1995 }
1996 else
1997 {
1998 glColor4f(0,0.75f,1,1);
1999 glVertex3fv(facep->mCenterAgent.mV);
2000 }
2001
2002 glEnd();
2003 glPointSize(1);
2004 }
2005 }
2006
2007 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
2008 {
2009 LLVector4 cold(0,0,0.25f);
2010 LLVector4 hot(1,0.25f,0.25f);
2011
2012 LLVector4 boost_cold(0,0,0,0);
2013 LLVector4 boost_hot(0,1,0,1);
2014
2015 LLGLDisable blend(GL_BLEND);
2016
2017 LLViewerImage* imagep = facep->getTexture();
2018 if (imagep)
2019 {
2020
2021 //F32 vsize = LLVOVolume::getTextureVirtualSize(facep);
2022 F32 vsize = imagep->mMaxVirtualSize;
2023
2024 if (vsize > sCurMaxTexPriority)
2025 {
2026 sCurMaxTexPriority = vsize;
2027 }
2028
2029 F32 t = vsize/sLastMaxTexPriority;
2030
2031 LLVector4 col = lerp(cold, hot, t);
2032 glColor4fv(col.mV);
2033 }
2034 else
2035 {
2036 glColor4f(1,0,1,1);
2037 }
2038
2039 LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f;
2040 LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f);
2041 drawBox(center, size);
2042
2043 S32 boost = imagep->getBoostLevel();
2044 if (boost)
2045 {
2046 F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1);
2047 LLVector4 col = lerp(boost_cold, boost_hot, t);
2048 LLGLEnable blend_on(GL_BLEND);
2049 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
2050 glColor4fv(col.mV);
2051 drawBox(center, size);
2052 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2053 }
2054
2055 }
2056 }
2057 } 2647 }
2058 2648
2059 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS)) 2649 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS))
2060 { 2650 {
2061 glPointSize(4); 2651 renderPoints(drawable);
2062 glColor4f(1,1,1,1); 2652 }
2063 glBegin(GL_POINTS); 2653 }
2064 S32 num_faces = drawable->getNumFaces(); 2654
2065 for (S32 i = 0; i < num_faces; i++) 2655 for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
2656 {
2657 std::vector<LLDrawInfo*>& draw_vec = i->second;
2658 for (std::vector<LLDrawInfo*>::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
2659 {
2660 LLDrawInfo* draw_info = *j;
2661 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_ANIM))
2066 { 2662 {
2067 LLStrider<LLVector3> vertices; 2663 renderTextureAnim(draw_info);
2068 drawable->getFace(i)->getVertices(vertices);
2069
2070 LLFace* face = drawable->getFace(i);
2071
2072 for (S32 v = 0; v < (S32)drawable->getFace(i)->getGeomCount(); v++)
2073 {
2074 if (!face->getDrawable()->isActive())
2075 {
2076 //glVertex3fv(vertices[v].mV);
2077 }
2078 else
2079 {
2080 glVertex3fv((vertices[v]*face->getRenderMatrix()).mV);
2081 }
2082 }
2083 } 2664 }
2084 glEnd();
2085 glPointSize(1);
2086 } 2665 }
2087
2088 glLineWidth(1);
2089 } 2666 }
2090 } 2667 }
2091}; 2668};
@@ -2096,8 +2673,8 @@ void LLSpatialPartition::renderDebug()
2096 LLPipeline::RENDER_DEBUG_OCCLUSION | 2673 LLPipeline::RENDER_DEBUG_OCCLUSION |
2097 LLPipeline::RENDER_DEBUG_BBOXES | 2674 LLPipeline::RENDER_DEBUG_BBOXES |
2098 LLPipeline::RENDER_DEBUG_POINTS | 2675 LLPipeline::RENDER_DEBUG_POINTS |
2099 LLPipeline::RENDER_DEBUG_FACE_CHAINS | 2676 LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY |
2100 LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) 2677 LLPipeline::RENDER_DEBUG_TEXTURE_ANIM))
2101 { 2678 {
2102 return; 2679 return;
2103 } 2680 }
@@ -2105,7 +2682,7 @@ void LLSpatialPartition::renderDebug()
2105 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) 2682 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
2106 { 2683 {
2107 //sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds); 2684 //sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds);
2108 sLastMaxTexPriority = sCurMaxTexPriority; 2685 sLastMaxTexPriority = (F32) gCamera->getScreenPixelArea();
2109 sCurMaxTexPriority = 0.f; 2686 sCurMaxTexPriority = 0.f;
2110 } 2687 }
2111 2688
@@ -2119,78 +2696,50 @@ void LLSpatialPartition::renderDebug()
2119 2696
2120 LLOctreeRenderNonOccluded render_debug; 2697 LLOctreeRenderNonOccluded render_debug;
2121 render_debug.traverse(mOctree); 2698 render_debug.traverse(mOctree);
2122
2123 LLGLDisable cull_face(GL_CULL_FACE);
2124 2699
2125 { 2700 LLGLDisable cull_face(GL_CULL_FACE);
2126 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
2127
2128 //draw frustum
2129 glColor4f(0,0,1,0.5f);
2130 glBegin(GL_QUADS);
2131 //glVertex3fv(gCamera->mAgentFrustum[0].mV);
2132 //glVertex3fv(gCamera->mAgentFrustum[1].mV);
2133 //glVertex3fv(gCamera->mAgentFrustum[2].mV);
2134 //glVertex3fv(gCamera->mAgentFrustum[3].mV);
2135 2701
2136 //glVertex3fv(gCamera->mAgentFrustum[4].mV); 2702 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && !mOccludedList.empty() &&
2137 //glVertex3fv(gCamera->mAgentFrustum[5].mV); 2703 mOcclusionIndices.notNull())
2138 //glVertex3fv(gCamera->mAgentFrustum[6].mV);
2139 //glVertex3fv(gCamera->mAgentFrustum[7].mV);
2140
2141 glVertex3fv(gCamera->mAgentFrustum[0].mV);
2142 glVertex3fv(gCamera->mAgentFrustum[1].mV);
2143 glVertex3fv(gCamera->mAgentFrustum[5].mV);
2144 glVertex3fv(gCamera->mAgentFrustum[4].mV);
2145
2146 glVertex3fv(gCamera->mAgentFrustum[1].mV);
2147 glVertex3fv(gCamera->mAgentFrustum[2].mV);
2148 glVertex3fv(gCamera->mAgentFrustum[6].mV);
2149 glVertex3fv(gCamera->mAgentFrustum[5].mV);
2150
2151 glVertex3fv(gCamera->mAgentFrustum[2].mV);
2152 glVertex3fv(gCamera->mAgentFrustum[3].mV);
2153 glVertex3fv(gCamera->mAgentFrustum[7].mV);
2154 glVertex3fv(gCamera->mAgentFrustum[6].mV);
2155
2156 glVertex3fv(gCamera->mAgentFrustum[3].mV);
2157 glVertex3fv(gCamera->mAgentFrustum[0].mV);
2158 glVertex3fv(gCamera->mAgentFrustum[4].mV);
2159 glVertex3fv(gCamera->mAgentFrustum[7].mV);
2160
2161 glEnd();
2162 }
2163
2164 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
2165 { 2704 {
2166 LLGLDisable fog(GL_FOG); 2705 LLGLDisable fog(GL_FOG);
2167 LLGLDepthTest gls_depth(GL_FALSE); 2706 LLGLDepthTest gls_depth(GL_FALSE);
2168 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 2707 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
2708 mOcclusionIndices->setBuffer(0);
2709 U32* indicesp = (U32*) mOcclusionIndices->getIndicesPointer();
2710
2711 LLGLEnable blend(GL_BLEND);
2712 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2713 LLGLEnable cull(GL_CULL_FACE);
2714 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2169 2715
2170 for (std::vector<LLSpatialGroup*>::iterator i = mOccludedList.begin(); i != mOccludedList.end(); ++i) 2716 for (U32 i = 0; i < mOccludedList.size(); i++)
2171 { //draw occluded nodes 2717 { //draw occluded nodes
2172 LLSpatialGroup* node = *i; 2718 LLSpatialGroup* node = mOccludedList[i];
2173 if (node->isDead()) 2719 if (node->isDead() ||
2720 !node->isState(LLSpatialGroup::OCCLUDED) ||
2721 node->mOcclusionVerts.isNull())
2174 { 2722 {
2175 continue; 2723 continue;
2176 } 2724 }
2177 if (!node->isState(LLSpatialGroup::OCCLUDED)) 2725
2726 node->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
2178 { 2727 {
2179 continue; 2728 LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
2729 glColor4f(0.5, 0.5f, 0, 0.25f);
2730 glDrawRangeElements(GL_TRIANGLES, 0, 7, 36,
2731 GL_UNSIGNED_INT, indicesp);
2180 } 2732 }
2181 else 2733
2182 { 2734 {
2183 glColor4f(0.25f,0.125f,0.1f,0.125f); 2735 LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL);
2736 glColor4f(0.0,1.0f,1.0f,1.0f);
2737 glDrawRangeElements(GL_TRIANGLES, 0, 7, 36,
2738 GL_UNSIGNED_INT, indicesp);
2184 } 2739 }
2185 LLVector3 c;
2186 LLVector3 r;
2187
2188 c = node->mBounds[0];
2189 r = node->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.01f,0.01f,0.01f);;
2190
2191 drawBox(c,r);
2192 } 2740 }
2193 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2741
2742 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2194 } 2743 }
2195} 2744}
2196 2745
@@ -2272,3 +2821,27 @@ LLDrawable* LLSpatialPartition::pickDrawable(const LLVector3& start, const LLVec
2272 collision.setVec(pick.mEnd); 2821 collision.setVec(pick.mEnd);
2273 return ret; 2822 return ret;
2274} 2823}
2824
2825LLDrawInfo::LLDrawInfo(U32 start, U32 end, U32 count, U32 offset,
2826 LLViewerImage* texture, LLVertexBuffer* buffer,
2827 BOOL fullbright, U8 bump, BOOL particle, F32 part_size)
2828:
2829 mVertexBuffer(buffer),
2830 mTexture(texture),
2831 mTextureMatrix(NULL),
2832 mStart(start),
2833 mEnd(end),
2834 mCount(count),
2835 mOffset(offset),
2836 mFullbright(fullbright),
2837 mBump(bump),
2838 mParticle(particle),
2839 mPartSize(part_size),
2840 mVSize(0.f)
2841{
2842}
2843
2844LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)
2845{
2846 return new LLVertexBuffer(type_mask, usage);
2847}