diff options
author | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
commit | cd17687f01420952712a500107e0f93e7ab8d5f8 (patch) | |
tree | ce48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/newview/llspatialpartition.cpp | |
parent | Second Life viewer sources 1.19.0.5 (diff) | |
download | meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2 meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz |
Second Life viewer sources 1.19.1.0
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llspatialpartition.cpp | 2125 |
1 files changed, 1021 insertions, 1104 deletions
diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp index 656b236..774bf6b 100644 --- a/linden/indra/newview/llspatialpartition.cpp +++ b/linden/indra/newview/llspatialpartition.cpp | |||
@@ -43,25 +43,47 @@ | |||
43 | #include "llviewerregion.h" | 43 | #include "llviewerregion.h" |
44 | #include "llcamera.h" | 44 | #include "llcamera.h" |
45 | #include "pipeline.h" | 45 | #include "pipeline.h" |
46 | 46 | #include "llglimmediate.h" | |
47 | static GLuint sBoxList = 0; | 47 | #include "lloctree.h" |
48 | 48 | ||
49 | const F32 SG_OCCLUSION_FUDGE = 1.01f; | 49 | const F32 SG_OCCLUSION_FUDGE = 1.01f; |
50 | //const S32 SG_LOD_PERIOD = 16; | 50 | #define SG_DISCARD_TOLERANCE 0.01f |
51 | |||
52 | #define SG_DISCARD_TOLERANCE 0.25f | ||
53 | 51 | ||
54 | #if LL_OCTREE_PARANOIA_CHECK | 52 | #if LL_OCTREE_PARANOIA_CHECK |
55 | #define assert_octree_valid(x) x->validate() | 53 | #define assert_octree_valid(x) x->validate() |
54 | #define assert_states_valid(x) ((LLSpatialGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates() | ||
56 | #else | 55 | #else |
57 | #define assert_octree_valid(x) | 56 | #define assert_octree_valid(x) |
57 | #define assert_states_valid(x) | ||
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | |||
60 | static U32 sZombieGroups = 0; | 61 | static U32 sZombieGroups = 0; |
62 | U32 LLSpatialGroup::sNodeCount = 0; | ||
61 | 63 | ||
62 | static F32 sLastMaxTexPriority = 1.f; | 64 | static F32 sLastMaxTexPriority = 1.f; |
63 | static F32 sCurMaxTexPriority = 1.f; | 65 | static F32 sCurMaxTexPriority = 1.f; |
64 | 66 | ||
67 | class LLOcclusionQueryPool : public LLGLNamePool | ||
68 | { | ||
69 | protected: | ||
70 | virtual GLuint allocateName() | ||
71 | { | ||
72 | GLuint name; | ||
73 | glGenQueriesARB(1, &name); | ||
74 | return name; | ||
75 | } | ||
76 | |||
77 | virtual void releaseName(GLuint name) | ||
78 | { | ||
79 | glDeleteQueriesARB(1, &name); | ||
80 | } | ||
81 | }; | ||
82 | |||
83 | static LLOcclusionQueryPool sQueryPool; | ||
84 | |||
85 | BOOL LLSpatialPartition::sFreezeState = FALSE; | ||
86 | |||
65 | //static counter for frame to switch LOD on | 87 | //static counter for frame to switch LOD on |
66 | 88 | ||
67 | void sg_assert(BOOL expr) | 89 | void sg_assert(BOOL expr) |
@@ -90,6 +112,134 @@ void validate_drawable(LLDrawable* drawablep) | |||
90 | #define validate_drawable(x) | 112 | #define validate_drawable(x) |
91 | #endif | 113 | #endif |
92 | 114 | ||
115 | |||
116 | S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) | ||
117 | { | ||
118 | F32 d = 0.f; | ||
119 | F32 t; | ||
120 | F32 r = rad*rad; | ||
121 | |||
122 | if ((min-origin).magVecSquared() < r && | ||
123 | (max-origin).magVecSquared() < r) | ||
124 | { | ||
125 | return 2; | ||
126 | } | ||
127 | |||
128 | for (U32 i = 0; i < 3; i++) | ||
129 | { | ||
130 | if (origin.mV[i] < min.mV[i]) | ||
131 | { | ||
132 | t = min.mV[i] - origin.mV[i]; | ||
133 | d += t*t; | ||
134 | } | ||
135 | else if (origin.mV[i] > max.mV[i]) | ||
136 | { | ||
137 | t = origin.mV[i] - max.mV[i]; | ||
138 | d += t*t; | ||
139 | } | ||
140 | |||
141 | if (d > r) | ||
142 | { | ||
143 | return 0; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | return 1; | ||
148 | } | ||
149 | |||
150 | |||
151 | typedef enum | ||
152 | { | ||
153 | b000 = 0x00, | ||
154 | b001 = 0x01, | ||
155 | b010 = 0x02, | ||
156 | b011 = 0x03, | ||
157 | b100 = 0x04, | ||
158 | b101 = 0x05, | ||
159 | b110 = 0x06, | ||
160 | b111 = 0x07, | ||
161 | } eLoveTheBits; | ||
162 | |||
163 | //contact Runitai Linden for a copy of the SL object used to write this table | ||
164 | //basically, you give the table a bitmask of the look-at vector to a node and it | ||
165 | //gives you a triangle fan index array | ||
166 | static U8 sOcclusionIndices[] = | ||
167 | { | ||
168 | // 000 | ||
169 | b111, b110, b010, b011, b001, b101, b100, b110, | ||
170 | //001 | ||
171 | b110, b000, b010, b011, b111, b101, b100, b000, | ||
172 | //010 | ||
173 | b101, b100, b110, b111, b011, b001, b000, b100, | ||
174 | //011 | ||
175 | b100, b010, b110, b111, b101, b001, b000, b010, | ||
176 | //100 | ||
177 | b011, b010, b000, b001, b101, b111, b110, b010, | ||
178 | //101 | ||
179 | b010, b100, b000, b001, b011, b111, b110, b100, | ||
180 | //110 | ||
181 | b001, b000, b100, b101, b111, b011, b010, b000, | ||
182 | //111 | ||
183 | b000, b110, b100, b101, b001, b011, b010, b110, | ||
184 | }; | ||
185 | |||
186 | U8* get_occlusion_indices(LLCamera* camera, const LLVector3& center) | ||
187 | { | ||
188 | LLVector3 d = center - camera->getOrigin(); | ||
189 | |||
190 | U8 cypher = 0; | ||
191 | if (d.mV[0] > 0) | ||
192 | { | ||
193 | cypher |= b100; | ||
194 | } | ||
195 | if (d.mV[1] > 0) | ||
196 | { | ||
197 | cypher |= b010; | ||
198 | } | ||
199 | if (d.mV[2] > 0) | ||
200 | { | ||
201 | cypher |= b001; | ||
202 | } | ||
203 | |||
204 | return sOcclusionIndices+cypher*8; | ||
205 | } | ||
206 | |||
207 | void LLSpatialGroup::buildOcclusion() | ||
208 | { | ||
209 | if (!mOcclusionVerts) | ||
210 | { | ||
211 | mOcclusionVerts = new F32[8*3]; | ||
212 | } | ||
213 | |||
214 | LLVector3 r = mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.1f,0.1f,0.1f); | ||
215 | |||
216 | for (U32 k = 0; k < 3; k++) | ||
217 | { | ||
218 | r.mV[k] = llmin(mBounds[1].mV[k]+0.25f, r.mV[k]); | ||
219 | } | ||
220 | |||
221 | F32* v = mOcclusionVerts; | ||
222 | F32* c = mBounds[0].mV; | ||
223 | F32* s = r.mV; | ||
224 | |||
225 | //vertex positions are encoded so the 3 bits of their vertex index | ||
226 | //correspond to their axis facing, with bit position 3,2,1 matching | ||
227 | //axis facing x,y,z, bit set meaning positive facing, bit clear | ||
228 | //meaning negative facing | ||
229 | v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000 | ||
230 | v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001 | ||
231 | v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010 | ||
232 | v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011 | ||
233 | |||
234 | v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100 | ||
235 | v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101 | ||
236 | v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110 | ||
237 | v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111 | ||
238 | |||
239 | clearState(LLSpatialGroup::OCCLUSION_DIRTY); | ||
240 | } | ||
241 | |||
242 | |||
93 | BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); | 243 | BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); |
94 | 244 | ||
95 | BOOL LLLineSegmentAABB(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size) | 245 | BOOL LLLineSegmentAABB(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size) |
@@ -150,6 +300,15 @@ LLSpatialGroup::~LLSpatialGroup() | |||
150 | sZombieGroups--; | 300 | sZombieGroups--; |
151 | } | 301 | } |
152 | 302 | ||
303 | sNodeCount--; | ||
304 | |||
305 | if (gGLManager.mHasOcclusionQuery && mOcclusionQuery) | ||
306 | { | ||
307 | sQueryPool.release(mOcclusionQuery); | ||
308 | } | ||
309 | |||
310 | delete [] mOcclusionVerts; | ||
311 | |||
153 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 312 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
154 | clearDrawMap(); | 313 | clearDrawMap(); |
155 | } | 314 | } |
@@ -159,55 +318,16 @@ void LLSpatialGroup::clearDrawMap() | |||
159 | mDrawMap.clear(); | 318 | mDrawMap.clear(); |
160 | } | 319 | } |
161 | 320 | ||
162 | class LLRelightPainter : public LLSpatialGroup::OctreeTraveler | 321 | BOOL LLSpatialGroup::isVisible() const |
163 | { | 322 | { |
164 | public: | 323 | return mVisible == LLDrawable::getCurrentFrame() ? TRUE : FALSE; |
165 | LLVector3 mOrigin, mDir; | 324 | } |
166 | F32 mRadius; | ||
167 | |||
168 | LLRelightPainter(LLVector3 origin, LLVector3 dir, F32 radius) | ||
169 | : mOrigin(origin), mDir(dir), mRadius(radius) | ||
170 | { } | ||
171 | |||
172 | virtual void traverse(const LLSpatialGroup::TreeNode* n) | ||
173 | { | ||
174 | LLSpatialGroup::OctreeNode* node = (LLSpatialGroup::OctreeNode*) n; | ||
175 | |||
176 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); | ||
177 | group->setState(LLSpatialGroup::RESHADOW); | ||
178 | |||
179 | for (U32 i = 0; i < node->getChildCount(); i++) | ||
180 | { | ||
181 | const LLSpatialGroup::OctreeNode* child = node->getChild(i); | ||
182 | LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); | ||
183 | |||
184 | LLVector3 res; | ||
185 | |||
186 | LLVector3 center, size; | ||
187 | |||
188 | center = group->mBounds[0]; | ||
189 | size = group->mBounds[1]; | ||
190 | |||
191 | if (child->isInside(LLVector3d(mOrigin)) || LLRayAABB(center, size, mOrigin, mDir, res, mRadius)) | ||
192 | { | ||
193 | traverse(child); | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | |||
198 | virtual void visit(const LLSpatialGroup::OctreeState* branch) { } | ||
199 | |||
200 | }; | ||
201 | 325 | ||
202 | BOOL LLSpatialGroup::isVisible() | 326 | void LLSpatialGroup::setVisible() |
203 | { | 327 | { |
204 | if (LLPipeline::sUseOcclusion) | 328 | if (!LLSpatialPartition::sFreezeState) |
205 | { | ||
206 | return !isState(CULLED | OCCLUDED); | ||
207 | } | ||
208 | else | ||
209 | { | 329 | { |
210 | return !isState(CULLED); | 330 | mVisible = LLDrawable::getCurrentFrame(); |
211 | } | 331 | } |
212 | } | 332 | } |
213 | 333 | ||
@@ -232,7 +352,7 @@ void LLSpatialGroup::validate() | |||
232 | sg_assert(drawable->getSpatialBridge() == mSpatialPartition->asBridge()); | 352 | sg_assert(drawable->getSpatialBridge() == mSpatialPartition->asBridge()); |
233 | } | 353 | } |
234 | 354 | ||
235 | if (drawable->isSpatialBridge()) | 355 | /*if (drawable->isSpatialBridge()) |
236 | { | 356 | { |
237 | LLSpatialPartition* part = drawable->asPartition(); | 357 | LLSpatialPartition* part = drawable->asPartition(); |
238 | if (!part) | 358 | if (!part) |
@@ -241,7 +361,7 @@ void LLSpatialGroup::validate() | |||
241 | } | 361 | } |
242 | LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); | 362 | LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); |
243 | group->validate(); | 363 | group->validate(); |
244 | } | 364 | }*/ |
245 | } | 365 | } |
246 | 366 | ||
247 | for (U32 i = 0; i < mOctreeNode->getChildCount(); ++i) | 367 | for (U32 i = 0; i < mOctreeNode->getChildCount(); ++i) |
@@ -267,6 +387,71 @@ void LLSpatialGroup::validate() | |||
267 | #endif | 387 | #endif |
268 | } | 388 | } |
269 | 389 | ||
390 | |||
391 | |||
392 | class LLOctreeStateCheck : public LLOctreeTraveler<LLDrawable> | ||
393 | { | ||
394 | public: | ||
395 | U32 mInheritedMask; | ||
396 | |||
397 | LLOctreeStateCheck(): mInheritedMask(0) { } | ||
398 | |||
399 | virtual void traverse(const LLSpatialGroup::OctreeNode* node) | ||
400 | { | ||
401 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); | ||
402 | |||
403 | node->accept(this); | ||
404 | |||
405 | U32 temp = mInheritedMask; | ||
406 | mInheritedMask |= group->getState() & | ||
407 | (LLSpatialGroup::OCCLUDED); | ||
408 | |||
409 | for (U32 i = 0; i < node->getChildCount(); i++) | ||
410 | { | ||
411 | traverse(node->getChild(i)); | ||
412 | } | ||
413 | |||
414 | mInheritedMask = temp; | ||
415 | } | ||
416 | |||
417 | virtual void visit(const LLOctreeNode<LLDrawable>* state) | ||
418 | { | ||
419 | LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); | ||
420 | |||
421 | if (mInheritedMask && !group->isState(mInheritedMask)) | ||
422 | { | ||
423 | llerrs << "Spatial group failed inherited mask test." << llendl; | ||
424 | } | ||
425 | |||
426 | if (group->isState(LLSpatialGroup::DIRTY)) | ||
427 | { | ||
428 | assert_parent_state(group, LLSpatialGroup::DIRTY); | ||
429 | } | ||
430 | } | ||
431 | |||
432 | void assert_parent_state(LLSpatialGroup* group, U32 state) | ||
433 | { | ||
434 | LLSpatialGroup* parent = group->getParent(); | ||
435 | while (parent) | ||
436 | { | ||
437 | if (!parent->isState(state)) | ||
438 | { | ||
439 | llerrs << "Spatial group failed parent state check." << llendl; | ||
440 | } | ||
441 | parent = parent->getParent(); | ||
442 | } | ||
443 | } | ||
444 | }; | ||
445 | |||
446 | |||
447 | void LLSpatialGroup::checkStates() | ||
448 | { | ||
449 | #if LL_OCTREE_PARANOIA_CHECK | ||
450 | LLOctreeStateCheck checker; | ||
451 | checker.traverse(mOctreeNode); | ||
452 | #endif | ||
453 | } | ||
454 | |||
270 | void validate_draw_info(LLDrawInfo& params) | 455 | void validate_draw_info(LLDrawInfo& params) |
271 | { | 456 | { |
272 | #if LL_OCTREE_PARANOIA_CHECK | 457 | #if LL_OCTREE_PARANOIA_CHECK |
@@ -316,8 +501,8 @@ void LLSpatialGroup::validateDrawMap() | |||
316 | #if LL_OCTREE_PARANOIA_CHECK | 501 | #if LL_OCTREE_PARANOIA_CHECK |
317 | for (draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i) | 502 | for (draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i) |
318 | { | 503 | { |
319 | std::vector<LLDrawInfo*>& draw_vec = i->second; | 504 | LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; |
320 | for (std::vector<LLDrawInfo*>::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) | 505 | for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) |
321 | { | 506 | { |
322 | LLDrawInfo& params = **j; | 507 | LLDrawInfo& params = **j; |
323 | 508 | ||
@@ -327,32 +512,6 @@ void LLSpatialGroup::validateDrawMap() | |||
327 | #endif | 512 | #endif |
328 | } | 513 | } |
329 | 514 | ||
330 | void LLSpatialGroup::makeStatic() | ||
331 | { | ||
332 | #if !LL_DARWIN | ||
333 | if (isState(GEOM_DIRTY | ALPHA_DIRTY)) | ||
334 | { | ||
335 | return; | ||
336 | } | ||
337 | |||
338 | if (mSpatialPartition->mRenderByGroup && mBufferUsage != GL_STATIC_DRAW_ARB) | ||
339 | { | ||
340 | mBufferUsage = GL_STATIC_DRAW_ARB; | ||
341 | if (mVertexBuffer.notNull()) | ||
342 | { | ||
343 | mVertexBuffer->makeStatic(); | ||
344 | } | ||
345 | |||
346 | for (buffer_map_t::iterator i = mBufferMap.begin(); i != mBufferMap.end(); ++i) | ||
347 | { | ||
348 | i->second->makeStatic(); | ||
349 | } | ||
350 | |||
351 | mBuilt = 1.f; | ||
352 | } | ||
353 | #endif | ||
354 | } | ||
355 | |||
356 | BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) | 515 | BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) |
357 | { | 516 | { |
358 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 517 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
@@ -369,7 +528,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) | |||
369 | { | 528 | { |
370 | unbound(); | 529 | unbound(); |
371 | setState(OBJECT_DIRTY); | 530 | setState(OBJECT_DIRTY); |
372 | setState(GEOM_DIRTY); | 531 | //setState(GEOM_DIRTY); |
373 | validate_drawable(drawablep); | 532 | validate_drawable(drawablep); |
374 | return TRUE; | 533 | return TRUE; |
375 | } | 534 | } |
@@ -389,8 +548,7 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc | |||
389 | { | 548 | { |
390 | drawablep->setSpatialGroup(this); | 549 | drawablep->setSpatialGroup(this); |
391 | validate_drawable(drawablep); | 550 | validate_drawable(drawablep); |
392 | setState(OBJECT_DIRTY | GEOM_DIRTY); | 551 | setState(OBJECT_DIRTY | GEOM_DIRTY | DISCARD_QUERY); |
393 | mLastAddTime = gFrameTimeSeconds; | ||
394 | if (drawablep->isSpatialBridge()) | 552 | if (drawablep->isSpatialBridge()) |
395 | { | 553 | { |
396 | mBridgeList.push_back((LLSpatialBridge*) drawablep); | 554 | mBridgeList.push_back((LLSpatialBridge*) drawablep); |
@@ -431,32 +589,27 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) | |||
431 | group->clearDrawMap(); | 589 | group->clearDrawMap(); |
432 | 590 | ||
433 | //get geometry count | 591 | //get geometry count |
434 | group->mIndexCount = 0; | 592 | U32 index_count = 0; |
435 | group->mVertexCount = 0; | 593 | U32 vertex_count = 0; |
436 | 594 | ||
437 | addGeometryCount(group, group->mVertexCount, group->mIndexCount); | 595 | addGeometryCount(group, vertex_count, index_count); |
438 | 596 | ||
439 | if (group->mVertexCount > 0 && group->mIndexCount > 0) | 597 | if (vertex_count > 0 && index_count > 0) |
440 | { //create vertex buffer containing volume geometry for this node | 598 | { //create vertex buffer containing volume geometry for this node |
441 | group->mBuilt = 1.f; | 599 | group->mBuilt = 1.f; |
442 | if (group->mVertexBuffer.isNull() || (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs)) | 600 | if (group->mVertexBuffer.isNull() || (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs)) |
443 | { | 601 | { |
444 | //LLFastTimer ftm(LLFastTimer::FTM_REBUILD_NONE_VB); | ||
445 | group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); | 602 | group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); |
446 | group->mVertexBuffer->allocateBuffer(group->mVertexCount, group->mIndexCount, true); | 603 | group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true); |
447 | stop_glerror(); | 604 | stop_glerror(); |
448 | } | 605 | } |
449 | else | 606 | else |
450 | { | 607 | { |
451 | //LLFastTimer ftm(LLFastTimer::FTM_REBUILD_NONE_VB); | 608 | group->mVertexBuffer->resizeBuffer(vertex_count, index_count); |
452 | group->mVertexBuffer->resizeBuffer(group->mVertexCount, group->mIndexCount); | ||
453 | stop_glerror(); | 609 | stop_glerror(); |
454 | } | 610 | } |
455 | 611 | ||
456 | { | 612 | getGeometry(group); |
457 | LLFastTimer ftm((LLFastTimer::EFastTimerType) ((U32) LLFastTimer::FTM_REBUILD_VOLUME_VB + mPartitionType)); | ||
458 | getGeometry(group); | ||
459 | } | ||
460 | } | 613 | } |
461 | else | 614 | else |
462 | { | 615 | { |
@@ -465,12 +618,12 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) | |||
465 | } | 618 | } |
466 | 619 | ||
467 | group->mLastUpdateTime = gFrameTimeSeconds; | 620 | group->mLastUpdateTime = gFrameTimeSeconds; |
468 | group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MATRIX_DIRTY); | 621 | group->clearState(LLSpatialGroup::GEOM_DIRTY); |
469 | } | 622 | } |
470 | 623 | ||
471 | BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut) | 624 | BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut) |
472 | { | 625 | { |
473 | const OctreeState* node = mOctreeNode->getOctState(); | 626 | const OctreeNode* node = mOctreeNode; |
474 | 627 | ||
475 | if (node->getData().empty()) | 628 | if (node->getData().empty()) |
476 | { //don't do anything if there are no objects | 629 | { //don't do anything if there are no objects |
@@ -489,7 +642,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO | |||
489 | clearState(OBJECT_DIRTY); | 642 | clearState(OBJECT_DIRTY); |
490 | 643 | ||
491 | //initialize bounding box to first element | 644 | //initialize bounding box to first element |
492 | OctreeState::const_element_iter i = node->getData().begin(); | 645 | OctreeNode::const_element_iter i = node->getData().begin(); |
493 | LLDrawable* drawablep = *i; | 646 | LLDrawable* drawablep = *i; |
494 | const LLVector3* minMax = drawablep->getSpatialExtents(); | 647 | const LLVector3* minMax = drawablep->getSpatialExtents(); |
495 | 648 | ||
@@ -612,6 +765,11 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) | |||
612 | } | 765 | } |
613 | } | 766 | } |
614 | } | 767 | } |
768 | |||
769 | if (getElementCount() == 0) | ||
770 | { //delete draw map on last element removal since a rebuild might never happen | ||
771 | clearDrawMap(); | ||
772 | } | ||
615 | } | 773 | } |
616 | return TRUE; | 774 | return TRUE; |
617 | } | 775 | } |
@@ -629,7 +787,21 @@ void LLSpatialGroup::shift(const LLVector3 &offset) | |||
629 | mObjectExtents[0] += offset; | 787 | mObjectExtents[0] += offset; |
630 | mObjectExtents[1] += offset; | 788 | mObjectExtents[1] += offset; |
631 | 789 | ||
632 | setState(GEOM_DIRTY | MATRIX_DIRTY | OCCLUSION_DIRTY); | 790 | if (!mSpatialPartition->mRenderByGroup) |
791 | { | ||
792 | setState(GEOM_DIRTY); | ||
793 | } | ||
794 | |||
795 | if (mOcclusionVerts) | ||
796 | { | ||
797 | for (U32 i = 0; i < 8; i++) | ||
798 | { | ||
799 | F32* v = mOcclusionVerts+i*3; | ||
800 | v[0] += offset.mV[0]; | ||
801 | v[1] += offset.mV[1]; | ||
802 | v[2] += offset.mV[2]; | ||
803 | } | ||
804 | } | ||
633 | } | 805 | } |
634 | 806 | ||
635 | class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler | 807 | class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler |
@@ -637,7 +809,7 @@ class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler | |||
637 | public: | 809 | public: |
638 | U32 mState; | 810 | U32 mState; |
639 | LLSpatialSetState(U32 state) : mState(state) { } | 811 | LLSpatialSetState(U32 state) : mState(state) { } |
640 | virtual void visit(const LLSpatialGroup::OctreeState* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } | 812 | virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } |
641 | }; | 813 | }; |
642 | 814 | ||
643 | class LLSpatialSetStateDiff : public LLSpatialSetState | 815 | class LLSpatialSetStateDiff : public LLSpatialSetState |
@@ -656,9 +828,22 @@ public: | |||
656 | } | 828 | } |
657 | }; | 829 | }; |
658 | 830 | ||
831 | void LLSpatialGroup::setState(U32 state) | ||
832 | { | ||
833 | if (!LLSpatialPartition::sFreezeState) | ||
834 | { | ||
835 | mState |= state; | ||
836 | } | ||
837 | } | ||
838 | |||
659 | void LLSpatialGroup::setState(U32 state, S32 mode) | 839 | void LLSpatialGroup::setState(U32 state, S32 mode) |
660 | { | 840 | { |
661 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 841 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
842 | if (LLSpatialPartition::sFreezeState) | ||
843 | { | ||
844 | return; | ||
845 | } | ||
846 | |||
662 | if (mode > STATE_MODE_SINGLE) | 847 | if (mode > STATE_MODE_SINGLE) |
663 | { | 848 | { |
664 | if (mode == STATE_MODE_DIFF) | 849 | if (mode == STATE_MODE_DIFF) |
@@ -683,7 +868,7 @@ class LLSpatialClearState : public LLSpatialGroup::OctreeTraveler | |||
683 | public: | 868 | public: |
684 | U32 mState; | 869 | U32 mState; |
685 | LLSpatialClearState(U32 state) : mState(state) { } | 870 | LLSpatialClearState(U32 state) : mState(state) { } |
686 | virtual void visit(const LLSpatialGroup::OctreeState* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } | 871 | virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } |
687 | }; | 872 | }; |
688 | 873 | ||
689 | class LLSpatialClearStateDiff : public LLSpatialClearState | 874 | class LLSpatialClearStateDiff : public LLSpatialClearState |
@@ -695,17 +880,29 @@ public: | |||
695 | { | 880 | { |
696 | LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); | 881 | LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); |
697 | 882 | ||
698 | if (!group->isState(mState)) | 883 | if (group->isState(mState)) |
699 | { | 884 | { |
700 | LLSpatialGroup::OctreeTraveler::traverse(n); | 885 | LLSpatialGroup::OctreeTraveler::traverse(n); |
701 | } | 886 | } |
702 | } | 887 | } |
703 | }; | 888 | }; |
704 | 889 | ||
890 | void LLSpatialGroup::clearState(U32 state) | ||
891 | { | ||
892 | if (!LLSpatialPartition::sFreezeState) | ||
893 | { | ||
894 | mState &= ~state; | ||
895 | } | ||
896 | } | ||
705 | 897 | ||
706 | void LLSpatialGroup::clearState(U32 state, S32 mode) | 898 | void LLSpatialGroup::clearState(U32 state, S32 mode) |
707 | { | 899 | { |
708 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 900 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
901 | if (LLSpatialPartition::sFreezeState) | ||
902 | { | ||
903 | return; | ||
904 | } | ||
905 | |||
709 | if (mode > STATE_MODE_SINGLE) | 906 | if (mode > STATE_MODE_SINGLE) |
710 | { | 907 | { |
711 | if (mode == STATE_MODE_DIFF) | 908 | if (mode == STATE_MODE_DIFF) |
@@ -723,20 +920,6 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) | |||
723 | { | 920 | { |
724 | mState &= ~state; | 921 | mState &= ~state; |
725 | } | 922 | } |
726 | |||
727 | #if LL_OCTREE_PARANOIA_CHECK | ||
728 | if (state & LLSpatialGroup::ACTIVE_OCCLUSION) | ||
729 | { | ||
730 | LLSpatialPartition* part = mSpatialPartition; | ||
731 | for (U32 i = 0; i < part->mOccludedList.size(); i++) | ||
732 | { | ||
733 | if (part->mOccludedList[i] == this) | ||
734 | { | ||
735 | llerrs << "LLSpatialGroup state error: " << mState << llendl; | ||
736 | } | ||
737 | } | ||
738 | } | ||
739 | #endif | ||
740 | } | 923 | } |
741 | 924 | ||
742 | //====================================== | 925 | //====================================== |
@@ -750,15 +933,15 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : | |||
750 | mSpatialPartition(part), | 933 | mSpatialPartition(part), |
751 | mVertexBuffer(NULL), | 934 | mVertexBuffer(NULL), |
752 | mBufferUsage(GL_STATIC_DRAW_ARB), | 935 | mBufferUsage(GL_STATIC_DRAW_ARB), |
936 | mVisible(0), | ||
753 | mDistance(0.f), | 937 | mDistance(0.f), |
754 | mDepth(0.f), | 938 | mDepth(0.f), |
755 | mLastUpdateDistance(-1.f), | 939 | mLastUpdateDistance(-1.f), |
756 | mLastUpdateTime(gFrameTimeSeconds), | 940 | mLastUpdateTime(gFrameTimeSeconds), |
757 | mLastAddTime(gFrameTimeSeconds), | ||
758 | mLastRenderTime(gFrameTimeSeconds), | ||
759 | mViewAngle(0.f), | 941 | mViewAngle(0.f), |
760 | mLastUpdateViewAngle(-1.f) | 942 | mLastUpdateViewAngle(-1.f) |
761 | { | 943 | { |
944 | sNodeCount++; | ||
762 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 945 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
763 | 946 | ||
764 | sg_assert(mOctreeNode->getListenerCount() == 0); | 947 | sg_assert(mOctreeNode->getListenerCount() == 0); |
@@ -771,6 +954,9 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : | |||
771 | part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; | 954 | part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; |
772 | mLODHash = part->mLODSeed; | 955 | mLODHash = part->mLODSeed; |
773 | 956 | ||
957 | mOcclusionQuery = 0; | ||
958 | mOcclusionVerts = NULL; | ||
959 | |||
774 | mRadius = 1; | 960 | mRadius = 1; |
775 | mPixelArea = 1024.f; | 961 | mPixelArea = 1024.f; |
776 | } | 962 | } |
@@ -783,7 +969,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) | |||
783 | llerrs << "Spatial group dirty on distance update." << llendl; | 969 | llerrs << "Spatial group dirty on distance update." << llendl; |
784 | } | 970 | } |
785 | #endif | 971 | #endif |
786 | if (!getData().empty()) | 972 | if (!getData().empty() && !LLSpatialPartition::sFreezeState) |
787 | { | 973 | { |
788 | mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() : | 974 | mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() : |
789 | (F32) mOctreeNode->getSize().magVec(); | 975 | (F32) mOctreeNode->getSize().magVec(); |
@@ -805,19 +991,22 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) | |||
805 | 991 | ||
806 | if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) | 992 | if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) |
807 | { | 993 | { |
808 | LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0), | 994 | if (!group->mSpatialPartition->isBridge()) |
809 | eye * LLVector3(0,1,0), | ||
810 | eye * LLVector3(0,0,1)); | ||
811 | |||
812 | if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f) | ||
813 | { | 995 | { |
814 | group->mViewAngle = view_angle; | 996 | LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0), |
815 | group->mLastUpdateViewAngle = view_angle; | 997 | eye * LLVector3(0,1,0), |
816 | //for occasional alpha sorting within the group | 998 | eye * LLVector3(0,0,1)); |
817 | //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, | 999 | |
818 | //not setting this node to dirty would be a very good thing | 1000 | if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f) |
819 | group->setState(LLSpatialGroup::ALPHA_DIRTY); | 1001 | { |
820 | } | 1002 | group->mViewAngle = view_angle; |
1003 | group->mLastUpdateViewAngle = view_angle; | ||
1004 | //for occasional alpha sorting within the group | ||
1005 | //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, | ||
1006 | //not setting this node to dirty would be a very good thing | ||
1007 | group->setState(LLSpatialGroup::ALPHA_DIRTY); | ||
1008 | } | ||
1009 | } | ||
821 | } | 1010 | } |
822 | 1011 | ||
823 | //calculate depth of node for alpha sorting | 1012 | //calculate depth of node for alpha sorting |
@@ -831,17 +1020,6 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) | |||
831 | } | 1020 | } |
832 | 1021 | ||
833 | group->mDepth = v * at; | 1022 | group->mDepth = v * at; |
834 | |||
835 | F32 water_height = gAgent.getRegion()->getWaterHeight(); | ||
836 | //figure out if this node is above or below water | ||
837 | if (group->mObjectBounds[0].mV[2] < water_height) | ||
838 | { | ||
839 | group->setState(LLSpatialGroup::BELOW_WATER); | ||
840 | } | ||
841 | else | ||
842 | { | ||
843 | group->clearState(LLSpatialGroup::BELOW_WATER); | ||
844 | } | ||
845 | } | 1023 | } |
846 | else | 1024 | else |
847 | { | 1025 | { |
@@ -863,6 +1041,11 @@ F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) | |||
863 | return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); | 1041 | return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); |
864 | } | 1042 | } |
865 | 1043 | ||
1044 | BOOL LLSpatialGroup::needsUpdate() | ||
1045 | { | ||
1046 | return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; | ||
1047 | } | ||
1048 | |||
866 | BOOL LLSpatialGroup::changeLOD() | 1049 | BOOL LLSpatialGroup::changeLOD() |
867 | { | 1050 | { |
868 | if (isState(ALPHA_DIRTY)) | 1051 | if (isState(ALPHA_DIRTY)) |
@@ -885,7 +1068,7 @@ BOOL LLSpatialGroup::changeLOD() | |||
885 | } | 1068 | } |
886 | } | 1069 | } |
887 | 1070 | ||
888 | if (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) | 1071 | if (needsUpdate()) |
889 | { | 1072 | { |
890 | return TRUE; | 1073 | return TRUE; |
891 | } | 1074 | } |
@@ -923,7 +1106,6 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) | |||
923 | } | 1106 | } |
924 | 1107 | ||
925 | clearDrawMap(); | 1108 | clearDrawMap(); |
926 | mOcclusionVerts = NULL; | ||
927 | mVertexBuffer = NULL; | 1109 | mVertexBuffer = NULL; |
928 | mBufferMap.clear(); | 1110 | mBufferMap.clear(); |
929 | sZombieGroups++; | 1111 | sZombieGroups++; |
@@ -954,6 +1136,8 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c | |||
954 | } | 1136 | } |
955 | 1137 | ||
956 | unbound(); | 1138 | unbound(); |
1139 | |||
1140 | assert_states_valid(this); | ||
957 | } | 1141 | } |
958 | 1142 | ||
959 | void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) | 1143 | void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) |
@@ -963,17 +1147,23 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo | |||
963 | 1147 | ||
964 | void LLSpatialGroup::destroyGL() | 1148 | void LLSpatialGroup::destroyGL() |
965 | { | 1149 | { |
966 | setState(LLSpatialGroup::GEOM_DIRTY | | 1150 | setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); |
967 | LLSpatialGroup::OCCLUSION_DIRTY | | ||
968 | LLSpatialGroup::IMAGE_DIRTY); | ||
969 | mLastUpdateTime = gFrameTimeSeconds; | 1151 | mLastUpdateTime = gFrameTimeSeconds; |
970 | mVertexBuffer = NULL; | 1152 | mVertexBuffer = NULL; |
971 | mBufferMap.clear(); | 1153 | mBufferMap.clear(); |
972 | 1154 | ||
973 | mOcclusionVerts = NULL; | ||
974 | mReflectionMap = NULL; | 1155 | mReflectionMap = NULL; |
975 | clearDrawMap(); | 1156 | clearDrawMap(); |
976 | 1157 | ||
1158 | if (mOcclusionQuery) | ||
1159 | { | ||
1160 | sQueryPool.release(mOcclusionQuery); | ||
1161 | mOcclusionQuery = 0; | ||
1162 | } | ||
1163 | |||
1164 | delete [] mOcclusionVerts; | ||
1165 | mOcclusionVerts = NULL; | ||
1166 | |||
977 | for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) | 1167 | for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) |
978 | { | 1168 | { |
979 | LLDrawable* drawable = *i; | 1169 | LLDrawable* drawable = *i; |
@@ -993,15 +1183,6 @@ BOOL LLSpatialGroup::rebound() | |||
993 | return TRUE; | 1183 | return TRUE; |
994 | } | 1184 | } |
995 | 1185 | ||
996 | LLVector3 oldBounds[2]; | ||
997 | |||
998 | if (mSpatialPartition->isVolatile() && isState(QUERY_OUT)) | ||
999 | { //a query has been issued, if our bounding box changes significantly | ||
1000 | //we need to discard the issued query | ||
1001 | oldBounds[0] = mBounds[0]; | ||
1002 | oldBounds[1] = mBounds[1]; | ||
1003 | } | ||
1004 | |||
1005 | if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) | 1186 | if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) |
1006 | { | 1187 | { |
1007 | LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); | 1188 | LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); |
@@ -1015,7 +1196,7 @@ BOOL LLSpatialGroup::rebound() | |||
1015 | 1196 | ||
1016 | group->setState(SKIP_FRUSTUM_CHECK); | 1197 | group->setState(SKIP_FRUSTUM_CHECK); |
1017 | } | 1198 | } |
1018 | else if (mOctreeNode->hasLeafState()) | 1199 | else if (mOctreeNode->isLeaf()) |
1019 | { //copy object bounding box if this is a leaf | 1200 | { //copy object bounding box if this is a leaf |
1020 | boundObjects(TRUE, mExtents[0], mExtents[1]); | 1201 | boundObjects(TRUE, mExtents[0], mExtents[1]); |
1021 | mBounds[0] = mObjectBounds[0]; | 1202 | mBounds[0] = mObjectBounds[0]; |
@@ -1060,19 +1241,6 @@ BOOL LLSpatialGroup::rebound() | |||
1060 | mBounds[1] = (newMax - newMin)*0.5f; | 1241 | mBounds[1] = (newMax - newMin)*0.5f; |
1061 | } | 1242 | } |
1062 | 1243 | ||
1063 | if (mSpatialPartition->isVolatile() && isState(QUERY_OUT)) | ||
1064 | { | ||
1065 | for (U32 i = 0; i < 3 && !isState(DISCARD_QUERY); i++) | ||
1066 | { | ||
1067 | if (fabsf(mBounds[0].mV[i]-oldBounds[0].mV[i]) > SG_DISCARD_TOLERANCE || | ||
1068 | fabsf(mBounds[1].mV[i]-oldBounds[1].mV[i]) > SG_DISCARD_TOLERANCE) | ||
1069 | { //bounding box changed significantly, discard last issued | ||
1070 | //occlusion query | ||
1071 | setState(DISCARD_QUERY); | ||
1072 | } | ||
1073 | } | ||
1074 | } | ||
1075 | |||
1076 | setState(OCCLUSION_DIRTY); | 1244 | setState(OCCLUSION_DIRTY); |
1077 | 1245 | ||
1078 | clearState(DIRTY); | 1246 | clearState(DIRTY); |
@@ -1080,14 +1248,95 @@ BOOL LLSpatialGroup::rebound() | |||
1080 | return TRUE; | 1248 | return TRUE; |
1081 | } | 1249 | } |
1082 | 1250 | ||
1251 | void LLSpatialGroup::checkOcclusion() | ||
1252 | { | ||
1253 | if (LLPipeline::sUseOcclusion > 1) | ||
1254 | { | ||
1255 | LLSpatialGroup* parent = getParent(); | ||
1256 | if (parent && parent->isState(LLSpatialGroup::OCCLUDED)) | ||
1257 | { //if the parent has been marked as occluded, the child is implicitly occluded | ||
1258 | clearState(QUERY_PENDING | DISCARD_QUERY); | ||
1259 | } | ||
1260 | else if (isState(QUERY_PENDING)) | ||
1261 | { //otherwise, if a query is pending, read it back | ||
1262 | LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); | ||
1263 | GLuint res = 1; | ||
1264 | if (!isState(DISCARD_QUERY) && mOcclusionQuery) | ||
1265 | { | ||
1266 | glGetQueryObjectuivARB(mOcclusionQuery, GL_QUERY_RESULT_ARB, &res); | ||
1267 | } | ||
1268 | |||
1269 | if (res > 0) | ||
1270 | { | ||
1271 | assert_states_valid(this); | ||
1272 | clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); | ||
1273 | assert_states_valid(this); | ||
1274 | } | ||
1275 | else | ||
1276 | { | ||
1277 | assert_states_valid(this); | ||
1278 | setState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); | ||
1279 | assert_states_valid(this); | ||
1280 | } | ||
1281 | |||
1282 | clearState(QUERY_PENDING | DISCARD_QUERY); | ||
1283 | } | ||
1284 | else if (mSpatialPartition->mOcclusionEnabled) | ||
1285 | { | ||
1286 | assert_states_valid(this); | ||
1287 | clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); | ||
1288 | assert_states_valid(this); | ||
1289 | } | ||
1290 | } | ||
1291 | } | ||
1292 | |||
1293 | void LLSpatialGroup::doOcclusion(LLCamera* camera) | ||
1294 | { | ||
1295 | if (mSpatialPartition->mOcclusionEnabled && LLPipeline::sUseOcclusion > 1) | ||
1296 | { | ||
1297 | if (earlyFail(camera, this)) | ||
1298 | { | ||
1299 | setState(LLSpatialGroup::DISCARD_QUERY); | ||
1300 | assert_states_valid(this); | ||
1301 | clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); | ||
1302 | assert_states_valid(this); | ||
1303 | } | ||
1304 | else | ||
1305 | { | ||
1306 | { | ||
1307 | LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION); | ||
1308 | |||
1309 | if (!mOcclusionQuery) | ||
1310 | { | ||
1311 | mOcclusionQuery = sQueryPool.allocate(); | ||
1312 | } | ||
1313 | |||
1314 | if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) | ||
1315 | { | ||
1316 | buildOcclusion(); | ||
1317 | } | ||
1318 | |||
1319 | glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery); | ||
1320 | glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); | ||
1321 | glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, | ||
1322 | GL_UNSIGNED_BYTE, get_occlusion_indices(camera, mBounds[0])); | ||
1323 | glEndQueryARB(GL_SAMPLES_PASSED_ARB); | ||
1324 | } | ||
1325 | |||
1326 | setState(LLSpatialGroup::QUERY_PENDING); | ||
1327 | clearState(LLSpatialGroup::DISCARD_QUERY); | ||
1328 | } | ||
1329 | } | ||
1330 | } | ||
1331 | |||
1083 | //============================================== | 1332 | //============================================== |
1084 | 1333 | ||
1085 | LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL is_volatile, U32 buffer_usage) | 1334 | LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage) |
1086 | { | 1335 | { |
1087 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1336 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1337 | mOcclusionEnabled = TRUE; | ||
1088 | mDrawableType = 0; | 1338 | mDrawableType = 0; |
1089 | mPartitionType = LLPipeline::PARTITION_NONE; | 1339 | mPartitionType = LLViewerRegion::PARTITION_NONE; |
1090 | mVolatile = is_volatile; | ||
1091 | mLODSeed = 0; | 1340 | mLODSeed = 0; |
1092 | mLODPeriod = 1; | 1341 | mLODPeriod = 1; |
1093 | mVertexDataMask = data_mask; | 1342 | mVertexDataMask = data_mask; |
@@ -1096,10 +1345,13 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL is_volatile, U32 buff | |||
1096 | mSlopRatio = 0.25f; | 1345 | mSlopRatio = 0.25f; |
1097 | mRenderByGroup = TRUE; | 1346 | mRenderByGroup = TRUE; |
1098 | mImageEnabled = FALSE; | 1347 | mImageEnabled = FALSE; |
1348 | mInfiniteFarClip = FALSE; | ||
1349 | |||
1350 | LLGLNamePool::registerPool(&sQueryPool); | ||
1099 | 1351 | ||
1100 | mOctree = new LLSpatialGroup::OctreeNode(LLVector3d(0,0,0), | 1352 | mOctree = new LLSpatialGroup::OctreeRoot(LLVector3d(0,0,0), |
1101 | LLVector3d(1,1,1), | 1353 | LLVector3d(1,1,1), |
1102 | new LLSpatialGroup::OctreeRoot(), NULL); | 1354 | NULL); |
1103 | new LLSpatialGroup(mOctree, this); | 1355 | new LLSpatialGroup(mOctree, this); |
1104 | } | 1356 | } |
1105 | 1357 | ||
@@ -1108,11 +1360,6 @@ LLSpatialPartition::~LLSpatialPartition() | |||
1108 | { | 1360 | { |
1109 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1361 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1110 | 1362 | ||
1111 | for (U32 i = 0; i < mOcclusionQueries.size(); i++) | ||
1112 | { | ||
1113 | glDeleteQueriesARB(1, (GLuint*)(&(mOcclusionQueries[i]))); | ||
1114 | } | ||
1115 | |||
1116 | delete mOctree; | 1363 | delete mOctree; |
1117 | mOctree = NULL; | 1364 | mOctree = NULL; |
1118 | } | 1365 | } |
@@ -1121,22 +1368,6 @@ LLSpatialPartition::~LLSpatialPartition() | |||
1121 | LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) | 1368 | LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) |
1122 | { | 1369 | { |
1123 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1370 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1124 | const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million | ||
1125 | |||
1126 | if (drawablep->getPositionGroup().magVecSquared() > MAX_MAG) | ||
1127 | { | ||
1128 | #if 0 //ndef LL_RELEASE_FOR_DOWNLOAD | ||
1129 | llwarns << "LLSpatialPartition::put Object out of range!" << llendl; | ||
1130 | llinfos << drawablep->getPositionGroup() << llendl; | ||
1131 | |||
1132 | if (drawablep->getVObj()) | ||
1133 | { | ||
1134 | llwarns << "Dumping debugging info: " << llendl; | ||
1135 | drawablep->getVObj()->dump(); | ||
1136 | } | ||
1137 | #endif | ||
1138 | return NULL; | ||
1139 | } | ||
1140 | 1371 | ||
1141 | drawablep->updateSpatialExtents(); | 1372 | drawablep->updateSpatialExtents(); |
1142 | validate_drawable(drawablep); | 1373 | validate_drawable(drawablep); |
@@ -1147,11 +1378,10 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) | |||
1147 | assert_octree_valid(mOctree); | 1378 | assert_octree_valid(mOctree); |
1148 | mOctree->insert(drawablep); | 1379 | mOctree->insert(drawablep); |
1149 | assert_octree_valid(mOctree); | 1380 | assert_octree_valid(mOctree); |
1150 | |||
1151 | LLSpatialGroup::OctreeNode* node = mOctree->getNodeAt(drawablep); | ||
1152 | 1381 | ||
1153 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); | 1382 | LLSpatialGroup* group = drawablep->getSpatialGroup(); |
1154 | if (was_visible && group->isState(LLSpatialGroup::QUERY_OUT)) | 1383 | |
1384 | if (group && was_visible && group->isState(LLSpatialGroup::QUERY_PENDING)) | ||
1155 | { | 1385 | { |
1156 | group->setState(LLSpatialGroup::DISCARD_QUERY); | 1386 | group->setState(LLSpatialGroup::DISCARD_QUERY); |
1157 | } | 1387 | } |
@@ -1178,11 +1408,11 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) | |||
1178 | void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) | 1408 | void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) |
1179 | { | 1409 | { |
1180 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1410 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1181 | LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); | 1411 | |
1182 | |||
1183 | // sanity check submitted by open source user bushing Spatula | 1412 | // sanity check submitted by open source user bushing Spatula |
1184 | // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne) | 1413 | // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne) |
1185 | if (!drawablep) { | 1414 | if (!drawablep) |
1415 | { | ||
1186 | OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << llendl; | 1416 | OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << llendl; |
1187 | return; | 1417 | return; |
1188 | } | 1418 | } |
@@ -1225,7 +1455,7 @@ class LLSpatialShift : public LLSpatialGroup::OctreeTraveler | |||
1225 | { | 1455 | { |
1226 | public: | 1456 | public: |
1227 | LLSpatialShift(LLVector3 offset) : mOffset(offset) { } | 1457 | LLSpatialShift(LLVector3 offset) : mOffset(offset) { } |
1228 | virtual void visit(const LLSpatialGroup::OctreeState* branch) | 1458 | virtual void visit(const LLSpatialGroup::OctreeNode* branch) |
1229 | { | 1459 | { |
1230 | ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); | 1460 | ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); |
1231 | } | 1461 | } |
@@ -1234,39 +1464,27 @@ public: | |||
1234 | }; | 1464 | }; |
1235 | 1465 | ||
1236 | void LLSpatialPartition::shift(const LLVector3 &offset) | 1466 | void LLSpatialPartition::shift(const LLVector3 &offset) |
1237 | { | 1467 | { //shift octree node bounding boxes by offset |
1238 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1468 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1239 | llinfos << "Shifting octree: " << offset << llendl; | ||
1240 | LLSpatialShift shifter(offset); | 1469 | LLSpatialShift shifter(offset); |
1241 | shifter.traverse(mOctree); | 1470 | shifter.traverse(mOctree); |
1242 | } | 1471 | } |
1243 | 1472 | ||
1244 | BOOL LLSpatialPartition::checkOcclusion(LLSpatialGroup* group, LLCamera* camera) | ||
1245 | { | ||
1246 | if (LLPipeline::sUseOcclusion && | ||
1247 | !group->isState(LLSpatialGroup::ACTIVE_OCCLUSION | LLSpatialGroup::OCCLUDED) && | ||
1248 | (!camera || !earlyFail(camera, group))) | ||
1249 | { | ||
1250 | group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); | ||
1251 | mQueryQueue.push(group); | ||
1252 | return TRUE; | ||
1253 | } | ||
1254 | |||
1255 | return FALSE; | ||
1256 | } | ||
1257 | |||
1258 | class LLOctreeCull : public LLSpatialGroup::OctreeTraveler | 1473 | class LLOctreeCull : public LLSpatialGroup::OctreeTraveler |
1259 | { | 1474 | { |
1260 | public: | 1475 | public: |
1261 | LLOctreeCull(LLCamera* camera) | 1476 | LLOctreeCull(LLCamera* camera) |
1262 | : mCamera(camera), mRes(0) { } | 1477 | : mCamera(camera), mRes(0) { } |
1263 | 1478 | ||
1264 | virtual bool earlyFail(const LLSpatialGroup* group) | 1479 | virtual bool earlyFail(LLSpatialGroup* group) |
1265 | { | 1480 | { |
1481 | group->checkOcclusion(); | ||
1482 | |||
1266 | if (group->mOctreeNode->getParent() && //never occlusion cull the root node | 1483 | if (group->mOctreeNode->getParent() && //never occlusion cull the root node |
1267 | LLPipeline::sUseOcclusion && //never occlusion cull selection | 1484 | LLPipeline::sUseOcclusion && //ignore occlusion if disabled |
1268 | group->isState(LLSpatialGroup::OCCLUDED)) | 1485 | group->isState(LLSpatialGroup::OCCLUDED)) |
1269 | { | 1486 | { |
1487 | gPipeline.markOccluder(group); | ||
1270 | return true; | 1488 | return true; |
1271 | } | 1489 | } |
1272 | 1490 | ||
@@ -1289,31 +1507,39 @@ public: | |||
1289 | } | 1507 | } |
1290 | else | 1508 | else |
1291 | { | 1509 | { |
1292 | mRes = mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); | 1510 | mRes = frustumCheck(group); |
1293 | 1511 | ||
1294 | if (mRes) | 1512 | if (mRes) |
1295 | { //at least partially in, run on down | 1513 | { //at least partially in, run on down |
1296 | LLSpatialGroup::OctreeTraveler::traverse(n); | 1514 | LLSpatialGroup::OctreeTraveler::traverse(n); |
1297 | } | 1515 | } |
1298 | else | 1516 | |
1299 | { | ||
1300 | lateFail(group); | ||
1301 | } | ||
1302 | mRes = 0; | 1517 | mRes = 0; |
1303 | } | 1518 | } |
1304 | } | 1519 | } |
1305 | 1520 | ||
1306 | virtual void lateFail(LLSpatialGroup* group) | 1521 | virtual S32 frustumCheck(const LLSpatialGroup* group) |
1307 | { | 1522 | { |
1308 | if (!group->isState(LLSpatialGroup::CULLED)) | 1523 | S32 res = mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); |
1309 | { //totally culled, so are all its children | 1524 | if (res != 0) |
1310 | group->setState(LLSpatialGroup::CULLED, LLSpatialGroup::STATE_MODE_DIFF); | 1525 | { |
1526 | res = llmin(res, AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); | ||
1311 | } | 1527 | } |
1528 | return res; | ||
1312 | } | 1529 | } |
1313 | 1530 | ||
1314 | virtual bool checkObjects(const LLSpatialGroup::OctreeState* branch, const LLSpatialGroup* group) | 1531 | virtual S32 frustumCheckObjects(const LLSpatialGroup* group) |
1532 | { | ||
1533 | S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); | ||
1534 | if (res != 0) | ||
1535 | { | ||
1536 | res = llmin(res, AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); | ||
1537 | } | ||
1538 | return res; | ||
1539 | } | ||
1540 | |||
1541 | virtual bool checkObjects(const LLSpatialGroup::OctreeNode* branch, const LLSpatialGroup* group) | ||
1315 | { | 1542 | { |
1316 | |||
1317 | if (branch->getElementCount() == 0) //no elements | 1543 | if (branch->getElementCount() == 0) //no elements |
1318 | { | 1544 | { |
1319 | return false; | 1545 | return false; |
@@ -1322,7 +1548,7 @@ public: | |||
1322 | { | 1548 | { |
1323 | return true; | 1549 | return true; |
1324 | } | 1550 | } |
1325 | else if (mRes == 1 && !mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1])) //no objects in frustum | 1551 | else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum |
1326 | { | 1552 | { |
1327 | return false; | 1553 | return false; |
1328 | } | 1554 | } |
@@ -1332,20 +1558,9 @@ public: | |||
1332 | 1558 | ||
1333 | virtual void preprocess(LLSpatialGroup* group) | 1559 | virtual void preprocess(LLSpatialGroup* group) |
1334 | { | 1560 | { |
1335 | if (group->isState(LLSpatialGroup::CULLED)) | ||
1336 | { //this is the first frame this node is visible | ||
1337 | group->clearState(LLSpatialGroup::CULLED); | ||
1338 | if (group->mOctreeNode->hasLeafState()) | ||
1339 | { //if it's a leaf, force it onto the active occlusion list to prevent | ||
1340 | //massive frame stutters | ||
1341 | group->mSpatialPartition->checkOcclusion(group, mCamera); | ||
1342 | } | ||
1343 | } | ||
1344 | |||
1345 | if (LLPipeline::sDynamicReflections && | 1561 | if (LLPipeline::sDynamicReflections && |
1346 | group->mOctreeNode->getSize().mdV[0] == 16.0 && | 1562 | group->mOctreeNode->getSize().mdV[0] == 16.0 && |
1347 | group->mDistance < 64.f && | 1563 | group->mDistance < 64.f) |
1348 | group->mLastAddTime < gFrameTimeSeconds - 2.f) | ||
1349 | { | 1564 | { |
1350 | group->mSpatialPartition->markReimage(group); | 1565 | group->mSpatialPartition->markReimage(group); |
1351 | } | 1566 | } |
@@ -1353,10 +1568,15 @@ public: | |||
1353 | 1568 | ||
1354 | virtual void processGroup(LLSpatialGroup* group) | 1569 | virtual void processGroup(LLSpatialGroup* group) |
1355 | { | 1570 | { |
1571 | if (group->needsUpdate() || | ||
1572 | group->mVisible < LLDrawable::getCurrentFrame() - 1) | ||
1573 | { | ||
1574 | group->doOcclusion(mCamera); | ||
1575 | } | ||
1356 | gPipeline.markNotCulled(group, *mCamera); | 1576 | gPipeline.markNotCulled(group, *mCamera); |
1357 | } | 1577 | } |
1358 | 1578 | ||
1359 | virtual void visit(const LLSpatialGroup::OctreeState* branch) | 1579 | virtual void visit(const LLSpatialGroup::OctreeNode* branch) |
1360 | { | 1580 | { |
1361 | LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); | 1581 | LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); |
1362 | 1582 | ||
@@ -1372,6 +1592,17 @@ public: | |||
1372 | S32 mRes; | 1592 | S32 mRes; |
1373 | }; | 1593 | }; |
1374 | 1594 | ||
1595 | class LLOctreeCullNoFarClip : public LLOctreeCull | ||
1596 | { | ||
1597 | public: | ||
1598 | LLOctreeCullNoFarClip(LLCamera* camera) | ||
1599 | : LLOctreeCull(camera) { } | ||
1600 | |||
1601 | virtual S32 frustumCheck(const LLSpatialGroup* group) | ||
1602 | { | ||
1603 | return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); | ||
1604 | } | ||
1605 | }; | ||
1375 | 1606 | ||
1376 | class LLOctreeSelect : public LLOctreeCull | 1607 | class LLOctreeSelect : public LLOctreeCull |
1377 | { | 1608 | { |
@@ -1379,15 +1610,14 @@ public: | |||
1379 | LLOctreeSelect(LLCamera* camera, std::vector<LLDrawable*>* results) | 1610 | LLOctreeSelect(LLCamera* camera, std::vector<LLDrawable*>* results) |
1380 | : LLOctreeCull(camera), mResults(results) { } | 1611 | : LLOctreeCull(camera), mResults(results) { } |
1381 | 1612 | ||
1382 | virtual bool earlyFail(const LLSpatialGroup* group) { return false; } | 1613 | virtual bool earlyFail(LLSpatialGroup* group) { return false; } |
1383 | virtual void lateFail(LLSpatialGroup* group) { } | ||
1384 | virtual void preprocess(LLSpatialGroup* group) { } | 1614 | virtual void preprocess(LLSpatialGroup* group) { } |
1385 | 1615 | ||
1386 | virtual void processGroup(LLSpatialGroup* group) | 1616 | virtual void processGroup(LLSpatialGroup* group) |
1387 | { | 1617 | { |
1388 | LLSpatialGroup::OctreeState* branch = group->mOctreeNode->getOctState(); | 1618 | LLSpatialGroup::OctreeNode* branch = group->mOctreeNode; |
1389 | 1619 | ||
1390 | for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) | 1620 | for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) |
1391 | { | 1621 | { |
1392 | LLDrawable* drawable = *i; | 1622 | LLDrawable* drawable = *i; |
1393 | 1623 | ||
@@ -1408,67 +1638,41 @@ public: | |||
1408 | std::vector<LLDrawable*>* mResults; | 1638 | std::vector<LLDrawable*>* mResults; |
1409 | }; | 1639 | }; |
1410 | 1640 | ||
1411 | 1641 | void drawBox(const LLVector3& c, const LLVector3& r) | |
1412 | void genBoxList() | ||
1413 | { | 1642 | { |
1414 | if (sBoxList != 0) | 1643 | gGL.begin(GL_TRIANGLE_STRIP); |
1415 | { | ||
1416 | return; | ||
1417 | } | ||
1418 | |||
1419 | sBoxList = glGenLists(1); | ||
1420 | glNewList(sBoxList, GL_COMPILE); | ||
1421 | |||
1422 | LLVector3 c,r; | ||
1423 | c = LLVector3(0,0,0); | ||
1424 | r = LLVector3(1,1,1); | ||
1425 | |||
1426 | glBegin(GL_TRIANGLE_STRIP); | ||
1427 | //left front | 1644 | //left front |
1428 | glVertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); | 1645 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); |
1429 | glVertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); | 1646 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); |
1430 | //right front | 1647 | //right front |
1431 | glVertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); | 1648 | gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); |
1432 | glVertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); | 1649 | gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); |
1433 | //right back | 1650 | //right back |
1434 | glVertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); | 1651 | gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); |
1435 | glVertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); | 1652 | gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); |
1436 | //left back | 1653 | //left back |
1437 | glVertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); | 1654 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); |
1438 | glVertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); | 1655 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); |
1439 | //left front | 1656 | //left front |
1440 | glVertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); | 1657 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); |
1441 | glVertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); | 1658 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); |
1442 | glEnd(); | 1659 | gGL.end(); |
1443 | 1660 | ||
1444 | //bottom | 1661 | //bottom |
1445 | glBegin(GL_TRIANGLE_STRIP); | 1662 | gGL.begin(GL_TRIANGLE_STRIP); |
1446 | glVertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); | 1663 | gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); |
1447 | glVertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); | 1664 | gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); |
1448 | glVertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); | 1665 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); |
1449 | glVertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); | 1666 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); |
1450 | glEnd(); | 1667 | gGL.end(); |
1451 | 1668 | ||
1452 | //top | 1669 | //top |
1453 | glBegin(GL_TRIANGLE_STRIP); | 1670 | gGL.begin(GL_TRIANGLE_STRIP); |
1454 | glVertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); | 1671 | gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); |
1455 | glVertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); | 1672 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); |
1456 | glVertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); | 1673 | gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); |
1457 | glVertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); | 1674 | gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); |
1458 | glEnd(); | 1675 | gGL.end(); |
1459 | |||
1460 | glEndList(); | ||
1461 | } | ||
1462 | |||
1463 | void drawBox(const LLVector3& c, const LLVector3& r) | ||
1464 | { | ||
1465 | genBoxList(); | ||
1466 | |||
1467 | glPushMatrix(); | ||
1468 | glTranslatef(c.mV[0], c.mV[1], c.mV[2]); | ||
1469 | glScalef(r.mV[0], r.mV[1], r.mV[2]); | ||
1470 | glCallList(sBoxList); | ||
1471 | glPopMatrix(); | ||
1472 | } | 1676 | } |
1473 | 1677 | ||
1474 | void drawBoxOutline(const LLVector3& pos, const LLVector3& size) | 1678 | void drawBoxOutline(const LLVector3& pos, const LLVector3& size) |
@@ -1478,44 +1682,49 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size) | |||
1478 | LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1)); | 1682 | LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1)); |
1479 | LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1)); | 1683 | LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1)); |
1480 | 1684 | ||
1481 | glBegin(GL_LINE_LOOP); //top | 1685 | gGL.begin(GL_LINES); |
1482 | glVertex3fv((pos+v1).mV); | 1686 | |
1483 | glVertex3fv((pos+v2).mV); | 1687 | //top |
1484 | glVertex3fv((pos+v3).mV); | 1688 | gGL.vertex3fv((pos+v1).mV); |
1485 | glVertex3fv((pos+v4).mV); | 1689 | gGL.vertex3fv((pos+v2).mV); |
1486 | glEnd(); | 1690 | gGL.vertex3fv((pos+v2).mV); |
1487 | 1691 | gGL.vertex3fv((pos+v3).mV); | |
1488 | glBegin(GL_LINE_LOOP); //bottom | 1692 | gGL.vertex3fv((pos+v3).mV); |
1489 | glVertex3fv((pos-v1).mV); | 1693 | gGL.vertex3fv((pos+v4).mV); |
1490 | glVertex3fv((pos-v2).mV); | 1694 | gGL.vertex3fv((pos+v4).mV); |
1491 | glVertex3fv((pos-v3).mV); | 1695 | gGL.vertex3fv((pos+v1).mV); |
1492 | glVertex3fv((pos-v4).mV); | 1696 | |
1493 | glEnd(); | 1697 | //bottom |
1494 | 1698 | gGL.vertex3fv((pos-v1).mV); | |
1495 | 1699 | gGL.vertex3fv((pos-v2).mV); | |
1496 | glBegin(GL_LINES); | 1700 | gGL.vertex3fv((pos-v2).mV); |
1497 | 1701 | gGL.vertex3fv((pos-v3).mV); | |
1702 | gGL.vertex3fv((pos-v3).mV); | ||
1703 | gGL.vertex3fv((pos-v4).mV); | ||
1704 | gGL.vertex3fv((pos-v4).mV); | ||
1705 | gGL.vertex3fv((pos-v1).mV); | ||
1706 | |||
1498 | //right | 1707 | //right |
1499 | glVertex3fv((pos+v1).mV); | 1708 | gGL.vertex3fv((pos+v1).mV); |
1500 | glVertex3fv((pos-v3).mV); | 1709 | gGL.vertex3fv((pos-v3).mV); |
1501 | 1710 | ||
1502 | glVertex3fv((pos+v4).mV); | 1711 | gGL.vertex3fv((pos+v4).mV); |
1503 | glVertex3fv((pos-v2).mV); | 1712 | gGL.vertex3fv((pos-v2).mV); |
1504 | 1713 | ||
1505 | //left | 1714 | //left |
1506 | glVertex3fv((pos+v2).mV); | 1715 | gGL.vertex3fv((pos+v2).mV); |
1507 | glVertex3fv((pos-v4).mV); | 1716 | gGL.vertex3fv((pos-v4).mV); |
1508 | 1717 | ||
1509 | glVertex3fv((pos+v3).mV); | 1718 | gGL.vertex3fv((pos+v3).mV); |
1510 | glVertex3fv((pos-v1).mV); | 1719 | gGL.vertex3fv((pos-v1).mV); |
1511 | 1720 | ||
1512 | glEnd(); | 1721 | gGL.end(); |
1513 | } | 1722 | } |
1514 | 1723 | ||
1515 | class LLOctreeDirty : public LLOctreeTraveler<LLDrawable> | 1724 | class LLOctreeDirty : public LLOctreeTraveler<LLDrawable> |
1516 | { | 1725 | { |
1517 | public: | 1726 | public: |
1518 | virtual void visit(const LLOctreeState<LLDrawable>* state) | 1727 | virtual void visit(const LLOctreeNode<LLDrawable>* state) |
1519 | { | 1728 | { |
1520 | LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); | 1729 | LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); |
1521 | group->destroyGL(); | 1730 | group->destroyGL(); |
@@ -1540,47 +1749,45 @@ public: | |||
1540 | void LLSpatialPartition::restoreGL() | 1749 | void LLSpatialPartition::restoreGL() |
1541 | { | 1750 | { |
1542 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1751 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1543 | mOcclusionQueries.clear(); | ||
1544 | sBoxList = 0; | ||
1545 | |||
1546 | //generate query ids | ||
1547 | while (mOcclusionQueries.size() < mOccludedList.size()) | ||
1548 | { | ||
1549 | GLuint id; | ||
1550 | glGenQueriesARB(1, &id); | ||
1551 | mOcclusionQueries.push_back(id); | ||
1552 | } | ||
1553 | |||
1554 | for (U32 i = 0; i < mOccludedList.size(); i++) | ||
1555 | { //previously issued queries are now invalid | ||
1556 | mOccludedList[i]->setState(LLSpatialGroup::DISCARD_QUERY); | ||
1557 | } | ||
1558 | |||
1559 | genBoxList(); | ||
1560 | } | 1752 | } |
1561 | 1753 | ||
1562 | void LLSpatialPartition::resetVertexBuffers() | 1754 | void LLSpatialPartition::resetVertexBuffers() |
1563 | { | 1755 | { |
1564 | LLOctreeDirty dirty; | 1756 | LLOctreeDirty dirty; |
1565 | dirty.traverse(mOctree); | 1757 | dirty.traverse(mOctree); |
1566 | |||
1567 | mOcclusionIndices = NULL; | ||
1568 | } | 1758 | } |
1569 | 1759 | ||
1570 | S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select) | 1760 | S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select) |
1571 | { | 1761 | { |
1572 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1762 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1763 | #if LL_OCTREE_PARANOIA_CHECK | ||
1764 | ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); | ||
1765 | #endif | ||
1573 | { | 1766 | { |
1767 | BOOL temp = sFreezeState; | ||
1768 | sFreezeState = FALSE; | ||
1574 | LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); | 1769 | LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); |
1575 | LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); | 1770 | LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); |
1576 | group->rebound(); | 1771 | group->rebound(); |
1772 | sFreezeState = temp; | ||
1577 | } | 1773 | } |
1774 | |||
1775 | #if LL_OCTREE_PARANOIA_CHECK | ||
1776 | ((LLSpatialGroup*)mOctree->getListener(0))->validate(); | ||
1777 | #endif | ||
1778 | |||
1578 | 1779 | ||
1579 | if (for_select) | 1780 | if (for_select) |
1580 | { | 1781 | { |
1581 | LLOctreeSelect selecter(&camera, results); | 1782 | LLOctreeSelect selecter(&camera, results); |
1582 | selecter.traverse(mOctree); | 1783 | selecter.traverse(mOctree); |
1583 | } | 1784 | } |
1785 | else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) | ||
1786 | { | ||
1787 | LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); | ||
1788 | LLOctreeCullNoFarClip culler(&camera); | ||
1789 | culler.traverse(mOctree); | ||
1790 | } | ||
1584 | else | 1791 | else |
1585 | { | 1792 | { |
1586 | LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); | 1793 | LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); |
@@ -1591,61 +1798,13 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result | |||
1591 | return 0; | 1798 | return 0; |
1592 | } | 1799 | } |
1593 | 1800 | ||
1594 | class LLOctreeClearOccludedNotActive : public LLSpatialGroup::OctreeTraveler | ||
1595 | { | ||
1596 | public: | ||
1597 | LLOctreeClearOccludedNotActive() { } | ||
1598 | |||
1599 | virtual void traverse(const LLSpatialGroup::TreeNode* n) | ||
1600 | { | ||
1601 | LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); | ||
1602 | if ((!group->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) //|| group->isState(LLSpatialGroup::QUERY_PENDING) | ||
1603 | || group->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) | ||
1604 | { //the children are all occluded or culled as well | ||
1605 | group->clearState(LLSpatialGroup::OCCLUDED); | ||
1606 | for (U32 i = 0; i < group->mOctreeNode->getChildCount(); i++) | ||
1607 | { | ||
1608 | traverse(group->mOctreeNode->getChild(i)); | ||
1609 | } | ||
1610 | } | ||
1611 | } | ||
1612 | |||
1613 | virtual void visit(const LLSpatialGroup::OctreeState* branch) { } | ||
1614 | }; | ||
1615 | |||
1616 | class LLQueueNonCulled : public LLSpatialGroup::OctreeTraveler | ||
1617 | { | ||
1618 | public: | ||
1619 | std::queue<LLSpatialGroup*>* mQueue; | ||
1620 | LLQueueNonCulled(std::queue<LLSpatialGroup*> *queue) : mQueue(queue) { } | ||
1621 | |||
1622 | virtual void traverse(const LLSpatialGroup::TreeNode* n) | ||
1623 | { | ||
1624 | LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); | ||
1625 | if (group->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED)) | ||
1626 | { //the children are all occluded or culled as well | ||
1627 | return; | ||
1628 | } | ||
1629 | |||
1630 | if (!group->isState(LLSpatialGroup::IN_QUEUE)) | ||
1631 | { | ||
1632 | group->setState(LLSpatialGroup::IN_QUEUE); | ||
1633 | mQueue->push(group); | ||
1634 | } | ||
1635 | |||
1636 | LLSpatialGroup::OctreeTraveler::traverse(n); | ||
1637 | } | ||
1638 | |||
1639 | virtual void visit(const LLSpatialGroup::OctreeState* branch) { } | ||
1640 | }; | ||
1641 | |||
1642 | BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) | 1801 | BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) |
1643 | { | 1802 | { |
1803 | const F32 vel = (gCamera->getVelocityStat()->getCurrent()+0.2f); | ||
1644 | LLVector3 c = group->mBounds[0]; | 1804 | LLVector3 c = group->mBounds[0]; |
1645 | LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.2f,0.2f,0.2f); | 1805 | LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(vel,vel,vel); |
1646 | 1806 | ||
1647 | //if (group->isState(LLSpatialGroup::CULLED)) // || | 1807 | if (r.magVecSquared() > 1024.0*1024.0) |
1648 | if (!camera->AABBInFrustum(c, r)) | ||
1649 | { | 1808 | { |
1650 | return TRUE; | 1809 | return TRUE; |
1651 | } | 1810 | } |
@@ -1687,23 +1846,34 @@ void LLSpatialPartition::processImagery(LLCamera* camera) | |||
1687 | 1846 | ||
1688 | U32 process_count = 1; | 1847 | U32 process_count = 1; |
1689 | 1848 | ||
1690 | while (process_count > 0 && !mImageQueue.empty()) | 1849 | S32 pull_count = (S32) mImageQueue.size(); |
1850 | |||
1851 | while (process_count > 0 && pull_count > 0 && !mImageQueue.empty()) | ||
1691 | { | 1852 | { |
1853 | pull_count--; | ||
1692 | LLPointer<LLSpatialGroup> group = mImageQueue.front(); | 1854 | LLPointer<LLSpatialGroup> group = mImageQueue.front(); |
1693 | mImageQueue.pop(); | 1855 | mImageQueue.pop(); |
1694 | 1856 | ||
1695 | group->clearState(LLSpatialGroup::IN_IMAGE_QUEUE); | ||
1696 | |||
1697 | if (group->isDead()) | 1857 | if (group->isDead()) |
1698 | { | 1858 | { |
1699 | continue; | 1859 | continue; |
1700 | } | 1860 | } |
1701 | 1861 | ||
1862 | if (group->isState(LLSpatialGroup::GEOM_DIRTY)) | ||
1863 | { //put it back | ||
1864 | mImageQueue.push(group); | ||
1865 | continue; | ||
1866 | } | ||
1867 | |||
1868 | group->clearState(LLSpatialGroup::IN_IMAGE_QUEUE); | ||
1702 | if (LLPipeline::sDynamicReflections) | 1869 | if (LLPipeline::sDynamicReflections) |
1703 | { | 1870 | { |
1704 | process_count--; | 1871 | process_count--; |
1705 | LLVector3 origin = group->mBounds[0]; | 1872 | LLVector3 origin = group->mBounds[0]; |
1706 | 1873 | /*LLVector3 at = camera->getOrigin()-origin; | |
1874 | at.normVec(); | ||
1875 | origin += at* (at * group->mBounds[1]);*/ | ||
1876 | |||
1707 | LLCamera cube_cam; | 1877 | LLCamera cube_cam; |
1708 | cube_cam.setOrigin(origin); | 1878 | cube_cam.setOrigin(origin); |
1709 | cube_cam.setFar(64.f); | 1879 | cube_cam.setFar(64.f); |
@@ -1716,15 +1886,8 @@ void LLSpatialPartition::processImagery(LLCamera* camera) | |||
1716 | cube_map->initGL(); | 1886 | cube_map->initGL(); |
1717 | } | 1887 | } |
1718 | 1888 | ||
1719 | if (gPipeline.mCubeBuffer.isNull()) | 1889 | gPipeline.generateReflectionMap(gPipeline.mCubeBuffer, cube_cam); |
1720 | { | 1890 | gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map); |
1721 | gPipeline.mCubeBuffer = new LLCubeMap(); | ||
1722 | gPipeline.mCubeBuffer->initGL(); | ||
1723 | } | ||
1724 | |||
1725 | S32 res = gSavedSettings.getS32("RenderReflectionRes"); | ||
1726 | gPipeline.generateReflectionMap(gPipeline.mCubeBuffer, cube_cam, 128); | ||
1727 | gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map, res); | ||
1728 | group->mReflectionMap = cube_map; | 1891 | group->mReflectionMap = cube_map; |
1729 | group->setState(LLSpatialGroup::GEOM_DIRTY); | 1892 | group->setState(LLSpatialGroup::GEOM_DIRTY); |
1730 | } | 1893 | } |
@@ -1733,601 +1896,75 @@ void LLSpatialPartition::processImagery(LLCamera* camera) | |||
1733 | } | 1896 | } |
1734 | } | 1897 | } |
1735 | 1898 | ||
1736 | void validate_occlusion_list(std::vector<LLPointer<LLSpatialGroup> >& occluded_list) | 1899 | void pushVerts(LLDrawInfo* params, U32 mask) |
1737 | { | 1900 | { |
1738 | #if !LL_RELEASE_FOR_DOWNLOAD | 1901 | LLRenderPass::applyModelMatrix(*params); |
1739 | for (U32 i = 0; i < occluded_list.size(); i++) | 1902 | params->mVertexBuffer->setBuffer(mask); |
1740 | { | 1903 | U16* indicesp = (U16*) params->mVertexBuffer->getIndicesPointer(); |
1741 | LLSpatialGroup* group = occluded_list[i]; | 1904 | glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount, |
1742 | for (U32 j = i+1; j < occluded_list.size(); j++) | 1905 | GL_UNSIGNED_SHORT, indicesp+params->mOffset); |
1743 | { | ||
1744 | if (occluded_list[i] == occluded_list[j]) | ||
1745 | { | ||
1746 | llerrs << "Duplicate node in occlusion list." << llendl; | ||
1747 | } | ||
1748 | } | ||
1749 | |||
1750 | LLSpatialGroup::OctreeNode* parent = group->mOctreeNode->getOctParent(); | ||
1751 | while (parent) | ||
1752 | { | ||
1753 | LLSpatialGroup* parent_group = (LLSpatialGroup*) parent->getListener(0); | ||
1754 | if (parent_group->isState(LLSpatialGroup::OCCLUDED)) | ||
1755 | { | ||
1756 | llerrs << "Child node of occluded node in occlusion list (redundant query)." << llendl; | ||
1757 | } | ||
1758 | parent = parent->getOctParent(); | ||
1759 | } | ||
1760 | } | ||
1761 | #endif | ||
1762 | } | 1906 | } |
1763 | 1907 | ||
1764 | void LLSpatialPartition::processOcclusion(LLCamera* camera) | 1908 | void pushVerts(LLSpatialGroup* group, U32 mask) |
1765 | { | 1909 | { |
1766 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1910 | LLDrawInfo* params = NULL; |
1767 | LLSpatialGroup* rootGroup = (LLSpatialGroup*) mOctree->getListener(0); | ||
1768 | { | ||
1769 | LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); | ||
1770 | rootGroup->rebound(); | ||
1771 | } | ||
1772 | |||
1773 | //update potentials | ||
1774 | if (!rootGroup->isState(LLSpatialGroup::IN_QUEUE)) | ||
1775 | { | ||
1776 | rootGroup->setState(LLSpatialGroup::IN_QUEUE); | ||
1777 | mOcclusionQueue.push(rootGroup); | ||
1778 | } | ||
1779 | |||
1780 | const U32 MAX_PULLED = 32; | ||
1781 | const U32 MAX_PUSHED = mOcclusionQueue.size(); | ||
1782 | U32 count = 0; | ||
1783 | U32 pcount = 0; | ||
1784 | |||
1785 | while (pcount < MAX_PUSHED && count < MAX_PULLED && !mOcclusionQueue.empty()) | ||
1786 | { | ||
1787 | LLFastTimer t(LLFastTimer::FTM_OCCLUSION); | ||
1788 | |||
1789 | LLPointer<LLSpatialGroup> group = mOcclusionQueue.front(); | ||
1790 | if (!group->isState(LLSpatialGroup::IN_QUEUE)) | ||
1791 | { | ||
1792 | OCT_ERRS << "Spatial Group State Error. Group in queue not tagged as such." << llendl; | ||
1793 | } | ||
1794 | |||
1795 | mOcclusionQueue.pop(); | ||
1796 | group->clearState(LLSpatialGroup::IN_QUEUE); | ||
1797 | |||
1798 | if (group->isDead()) | ||
1799 | { | ||
1800 | continue; | ||
1801 | } | ||
1802 | |||
1803 | if (group->isState(LLSpatialGroup::CULLED | LLSpatialGroup::OCCLUDED)) | ||
1804 | { //already culled, skip it | ||
1805 | continue; | ||
1806 | } | ||
1807 | |||
1808 | //before we process, enqueue this group's children | ||
1809 | for (U32 i = 0; i < group->mOctreeNode->getChildCount(); i++) | ||
1810 | { | ||
1811 | LLSpatialGroup* child = (LLSpatialGroup*) group->mOctreeNode->getChild(i)->getListener(0); | ||
1812 | |||
1813 | //if (!child->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED) | ||
1814 | if (!child->isState(LLSpatialGroup::IN_QUEUE | LLSpatialGroup::ACTIVE_OCCLUSION)) | ||
1815 | { | ||
1816 | child->setState(LLSpatialGroup::IN_QUEUE); | ||
1817 | mOcclusionQueue.push(child); | ||
1818 | } | ||
1819 | } | ||
1820 | |||
1821 | if (earlyFail(camera, group)) | ||
1822 | { | ||
1823 | sg_assert(!group->isState(LLSpatialGroup::OCCLUDED)); | ||
1824 | group->setState(LLSpatialGroup::IN_QUEUE); | ||
1825 | mOcclusionQueue.push(group); | ||
1826 | pcount++; | ||
1827 | continue; | ||
1828 | } | ||
1829 | |||
1830 | //add to pending queue | ||
1831 | if (!group->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) | ||
1832 | { | ||
1833 | #if LL_OCTREE_PARANOIA_CHECK | ||
1834 | for (U32 i = 0; i < mOccludedList.size(); ++i) | ||
1835 | { | ||
1836 | sg_assert(mOccludedList[i] != group); | ||
1837 | } | ||
1838 | #endif | ||
1839 | group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); | ||
1840 | mQueryQueue.push(group); | ||
1841 | count++; | ||
1842 | } | ||
1843 | } | ||
1844 | |||
1845 | //read back results from last frame | ||
1846 | for (U32 i = 0; i < mOccludedList.size(); i++) | ||
1847 | { | ||
1848 | LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); | ||
1849 | |||
1850 | if (mOccludedList[i]->isDead() || mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) | ||
1851 | { | ||
1852 | continue; | ||
1853 | } | ||
1854 | GLuint res = 0; | ||
1855 | |||
1856 | if (mOccludedList[i]->isState(LLSpatialGroup::EARLY_FAIL | LLSpatialGroup::DISCARD_QUERY) || | ||
1857 | !mOccludedList[i]->isState(LLSpatialGroup::QUERY_OUT)) | ||
1858 | { | ||
1859 | mOccludedList[i]->clearState(LLSpatialGroup::EARLY_FAIL); | ||
1860 | mOccludedList[i]->clearState(LLSpatialGroup::DISCARD_QUERY); | ||
1861 | res = 1; | ||
1862 | } | ||
1863 | else | ||
1864 | { | ||
1865 | glGetQueryObjectuivARB(mOcclusionQueries[i], GL_QUERY_RESULT_ARB, &res); | ||
1866 | stop_glerror(); | ||
1867 | } | ||
1868 | |||
1869 | if (res) //NOT OCCLUDED | ||
1870 | { | ||
1871 | if (mOccludedList[i]->isState(LLSpatialGroup::OCCLUDED)) | ||
1872 | { //this node was occluded last frame | ||
1873 | LLSpatialGroup::OctreeNode* node = mOccludedList[i]->mOctreeNode; | ||
1874 | //add any immediate children to the queue that are not already there | ||
1875 | for (U32 j = 0; j < node->getChildCount(); j++) | ||
1876 | { | ||
1877 | LLSpatialGroup* group = (LLSpatialGroup*) node->getChild(j)->getListener(0); | ||
1878 | checkOcclusion(group, camera); | ||
1879 | } | ||
1880 | } | ||
1881 | |||
1882 | //clear occlusion status for everything not on the active list | ||
1883 | LLOctreeClearOccludedNotActive clear_occluded; | ||
1884 | mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION); | ||
1885 | mOccludedList[i]->clearState(LLSpatialGroup::OCCLUDED); | ||
1886 | mOccludedList[i]->clearState(LLSpatialGroup::OCCLUDING); | ||
1887 | clear_occluded.traverse(mOccludedList[i]->mOctreeNode); | ||
1888 | } | ||
1889 | else | ||
1890 | { //OCCLUDED | ||
1891 | if (mOccludedList[i]->isState(LLSpatialGroup::OCCLUDING)) | ||
1892 | { | ||
1893 | if (!mOccludedList[i]->isState(LLSpatialGroup::OCCLUDED)) | ||
1894 | { | ||
1895 | LLSpatialGroup::OctreeNode* oct_parent = (LLSpatialGroup::OctreeNode*) mOccludedList[i]->mOctreeNode->getParent(); | ||
1896 | if (oct_parent) | ||
1897 | { | ||
1898 | LLSpatialGroup* parent = (LLSpatialGroup*) oct_parent->getListener(0); | ||
1899 | |||
1900 | if (checkOcclusion(parent, camera)) | ||
1901 | { //force a guess on the parent and siblings | ||
1902 | for (U32 i = 0; i < parent->mOctreeNode->getChildCount(); i++) | ||
1903 | { | ||
1904 | LLSpatialGroup* child = (LLSpatialGroup*) parent->mOctreeNode->getChild(i)->getListener(0); | ||
1905 | checkOcclusion(child, camera); | ||
1906 | } | ||
1907 | } | ||
1908 | } | ||
1909 | |||
1910 | //take children off the active list | ||
1911 | mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_BRANCH); | ||
1912 | mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); | ||
1913 | } | ||
1914 | mOccludedList[i]->setState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); | ||
1915 | } | ||
1916 | else | ||
1917 | { | ||
1918 | //take children off the active list | ||
1919 | mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_BRANCH); | ||
1920 | |||
1921 | //keep this node on the active list | ||
1922 | mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); | ||
1923 | |||
1924 | //this node is a top level occluder | ||
1925 | mOccludedList[i]->setState(LLSpatialGroup::OCCLUDING); | ||
1926 | } | ||
1927 | } | ||
1928 | |||
1929 | mOccludedList[i]->clearState(LLSpatialGroup::QUERY_OUT); | ||
1930 | } | ||
1931 | 1911 | ||
1932 | //remove non-occluded groups from occluded list | 1912 | for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) |
1933 | for (U32 i = 0; i < mOccludedList.size(); ) | ||
1934 | { | 1913 | { |
1935 | if (mOccludedList[i]->isDead() || //needs to be deleted | 1914 | for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) |
1936 | !mOccludedList[i]->isState(LLSpatialGroup::OCCLUDING) || //is not occluding | ||
1937 | mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) //parent is occluded | ||
1938 | { | ||
1939 | LLSpatialGroup* groupp = mOccludedList[i]; | ||
1940 | if (!groupp->isDead()) | ||
1941 | { | ||
1942 | groupp->clearState(LLSpatialGroup::ACTIVE_OCCLUSION); | ||
1943 | groupp->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); | ||
1944 | groupp->clearState(LLSpatialGroup::OCCLUDING); | ||
1945 | } | ||
1946 | mOccludedList.erase(mOccludedList.begin()+i); | ||
1947 | } | ||
1948 | else | ||
1949 | { | 1915 | { |
1950 | i++; | 1916 | params = *j; |
1917 | pushVerts(params, mask); | ||
1951 | } | 1918 | } |
1952 | } | 1919 | } |
1953 | |||
1954 | validate_occlusion_list(mOccludedList); | ||
1955 | |||
1956 | //pump some non-culled items onto the occlusion list | ||
1957 | //count = MAX_PULLED; | ||
1958 | while (!mQueryQueue.empty()) | ||
1959 | { | ||
1960 | LLPointer<LLSpatialGroup> group = mQueryQueue.front(); | ||
1961 | mQueryQueue.pop(); | ||
1962 | //group->clearState(LLSpatialGroup::QUERY_PENDING); | ||
1963 | mOccludedList.push_back(group); | ||
1964 | } | ||
1965 | |||
1966 | //generate query ids | ||
1967 | while (mOcclusionQueries.size() < mOccludedList.size()) | ||
1968 | { | ||
1969 | GLuint id; | ||
1970 | glGenQueriesARB(1, &id); | ||
1971 | mOcclusionQueries.push_back(id); | ||
1972 | } | ||
1973 | } | 1920 | } |
1974 | 1921 | ||
1975 | class LLOcclusionIndexBuffer : public LLVertexBuffer | 1922 | void pushVerts(LLFace* face, U32 mask) |
1976 | { | 1923 | { |
1977 | public: | 1924 | LLVertexBuffer* buffer = face->mVertexBuffer; |
1978 | LLOcclusionIndexBuffer(U32 size) | ||
1979 | : LLVertexBuffer(0, GL_STREAM_DRAW_ARB) | ||
1980 | { | ||
1981 | allocateBuffer(0, size, TRUE); | ||
1982 | |||
1983 | LLStrider<U32> idx; | ||
1984 | |||
1985 | getIndexStrider(idx); | ||
1986 | |||
1987 | //12 triangles' indices | ||
1988 | idx[0] = 1; idx[1] = 0; idx[2] = 2; //front | ||
1989 | idx[3] = 3; idx[4] = 2; idx[5] = 0; | ||
1990 | |||
1991 | idx[6] = 4; idx[7] = 5; idx[8] = 1; //top | ||
1992 | idx[9] = 0; idx[10] = 1; idx[11] = 5; | ||
1993 | |||
1994 | idx[12] = 5; idx[13] = 4; idx[14] = 6; //back | ||
1995 | idx[15] = 7; idx[16] = 6; idx[17] = 4; | ||
1996 | |||
1997 | idx[18] = 6; idx[19] = 7; idx[20] = 3; //bottom | ||
1998 | idx[21] = 2; idx[22] = 3; idx[23] = 7; | ||
1999 | |||
2000 | idx[24] = 0; idx[25] = 5; idx[26] = 3; //left | ||
2001 | idx[27] = 6; idx[28] = 3; idx[29] = 5; | ||
2002 | |||
2003 | idx[30] = 4; idx[31] = 1; idx[32] = 7; //right | ||
2004 | idx[33] = 2; idx[34] = 7; idx[35] = 1; | ||
2005 | } | ||
2006 | |||
2007 | //virtual BOOL useVBOs() const { return FALSE; } | ||
2008 | |||
2009 | void setBuffer(U32 data_mask) | ||
2010 | { | ||
2011 | if (useVBOs()) | ||
2012 | { | ||
2013 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); | ||
2014 | sIBOActive = TRUE; | ||
2015 | unmapBuffer(); | ||
2016 | } | ||
2017 | else if (sIBOActive) | ||
2018 | { | ||
2019 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); | ||
2020 | sIBOActive = FALSE; | ||
2021 | } | ||
2022 | |||
2023 | sGLRenderIndices = mGLIndices; | ||
2024 | } | ||
2025 | }; | ||
2026 | 1925 | ||
2027 | class LLOcclusionVertexBuffer : public LLVertexBuffer | 1926 | if (buffer) |
2028 | { | ||
2029 | public: | ||
2030 | LLOcclusionVertexBuffer(S32 usage) | ||
2031 | : LLVertexBuffer(MAP_VERTEX, usage) | ||
2032 | { | 1927 | { |
2033 | allocateBuffer(8, 0, TRUE); | 1928 | buffer->setBuffer(mask); |
2034 | } | 1929 | U16* indicesp = (U16*) buffer->getIndicesPointer(); |
2035 | 1930 | U16 start = face->getGeomStart(); | |
2036 | //virtual BOOL useVBOs() const { return FALSE; } | 1931 | U16 end = start + face->getGeomCount()-1; |
2037 | 1932 | U32 count = face->getIndicesCount(); | |
2038 | void setBuffer(U32 data_mask) | 1933 | U16 offset = face->getIndicesStart(); |
2039 | { | ||
2040 | if (useVBOs()) | ||
2041 | { | ||
2042 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); | ||
2043 | sVBOActive = TRUE; | ||
2044 | unmapBuffer(); | ||
2045 | } | ||
2046 | else if (sVBOActive) | ||
2047 | { | ||
2048 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); | ||
2049 | sVBOActive = FALSE; | ||
2050 | } | ||
2051 | |||
2052 | if (data_mask) | ||
2053 | { | ||
2054 | glVertexPointer(3,GL_FLOAT, 0, useVBOs() ? 0 : mMappedData); | ||
2055 | } | ||
2056 | |||
2057 | sGLRenderBuffer = mGLBuffer; | ||
2058 | } | ||
2059 | }; | ||
2060 | |||
2061 | void LLSpatialPartition::buildOcclusion() | ||
2062 | { | ||
2063 | if (mOccludedList.empty()) | ||
2064 | { | ||
2065 | return; | ||
2066 | } | ||
2067 | |||
2068 | BOOL reset_all = FALSE; | ||
2069 | if (mOcclusionIndices.isNull()) | ||
2070 | { | ||
2071 | mOcclusionIndices = new LLOcclusionIndexBuffer(36); | ||
2072 | reset_all = TRUE; | ||
2073 | } | ||
2074 | |||
2075 | //fill occlusion vertex buffers | ||
2076 | for (U32 i = 0; i < mOccludedList.size(); i++) | ||
2077 | { | ||
2078 | LLSpatialGroup* group = mOccludedList[i]; | ||
2079 | |||
2080 | if (group->isState(LLSpatialGroup::OCCLUSION_DIRTY) || reset_all) | ||
2081 | { | ||
2082 | LLFastTimer ftm(LLFastTimer::FTM_REBUILD_OCCLUSION_VB); | ||
2083 | |||
2084 | if (group->mOcclusionVerts.isNull()) | ||
2085 | { | ||
2086 | group->mOcclusionVerts = new LLOcclusionVertexBuffer(GL_STREAM_DRAW_ARB); | ||
2087 | } | ||
2088 | |||
2089 | group->clearState(LLSpatialGroup::OCCLUSION_DIRTY); | ||
2090 | |||
2091 | LLStrider<LLVector3> vert; | ||
2092 | |||
2093 | group->mOcclusionVerts->getVertexStrider(vert); | ||
2094 | |||
2095 | LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.1f,0.1f,0.1f); | ||
2096 | |||
2097 | for (U32 k = 0; k < 3; k++) | ||
2098 | { | ||
2099 | r.mV[k] = llmin(group->mBounds[1].mV[k]+0.25f, r.mV[k]); | ||
2100 | } | ||
2101 | |||
2102 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,1,1)); // 0 - left top front | ||
2103 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,1,1)); // 1 - right top front | ||
2104 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,-1,1)); // 2 - right bottom front | ||
2105 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,-1,1)); // 3 - left bottom front | ||
2106 | 1934 | ||
2107 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,1,-1)); // 4 - left top back | 1935 | glDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, indicesp + offset); |
2108 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,1,-1)); // 5 - right top back | ||
2109 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back | ||
2110 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back | ||
2111 | } | ||
2112 | } | 1936 | } |
2113 | 1937 | ||
2114 | /* for (U32 i = 0; i < mOccludedList.size(); i++) | ||
2115 | { | ||
2116 | LLSpatialGroup* group = mOccludedList[i]; | ||
2117 | if (!group->mOcclusionVerts.isNull() && group->mOcclusionVerts->isLocked()) | ||
2118 | { | ||
2119 | LLFastTimer ftm(LLFastTimer::FTM_REBUILD_OCCLUSION_VB); | ||
2120 | group->mOcclusionVerts->setBuffer(0); | ||
2121 | } | ||
2122 | }*/ | ||
2123 | } | 1938 | } |
2124 | 1939 | ||
2125 | void LLSpatialPartition::doOcclusion(LLCamera* camera) | 1940 | void pushBufferVerts(LLVertexBuffer* buffer, U32 mask) |
2126 | { | 1941 | { |
2127 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1942 | if (buffer) |
2128 | |||
2129 | LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION); | ||
2130 | |||
2131 | #if LL_OCTREE_PARANOIA_CHECK | ||
2132 | LLSpatialGroup* check = (LLSpatialGroup*) mOctree->getListener(0); | ||
2133 | check->validate(); | ||
2134 | #endif | ||
2135 | |||
2136 | stop_glerror(); | ||
2137 | |||
2138 | U32 num_verts = mOccludedList.size() * 8; | ||
2139 | |||
2140 | if (num_verts == 0) | ||
2141 | { | 1943 | { |
2142 | return; | 1944 | buffer->setBuffer(mask); |
1945 | U16* indicesp = (U16*) buffer->getIndicesPointer(); | ||
1946 | glDrawRangeElements(GL_TRIANGLES, 0, buffer->getRequestedVerts(), buffer->getRequestedIndices(), | ||
1947 | GL_UNSIGNED_SHORT, indicesp); | ||
2143 | } | 1948 | } |
2144 | |||
2145 | //actually perform the occlusion queries | ||
2146 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | ||
2147 | LLGLDisable(GL_TEXTURE_2D); | ||
2148 | gPipeline.disableLights(); | ||
2149 | LLGLEnable cull_face(GL_CULL_FACE); | ||
2150 | LLGLDisable blend(GL_BLEND); | ||
2151 | LLGLDisable alpha_test(GL_ALPHA_TEST); | ||
2152 | LLGLDisable fog(GL_FOG); | ||
2153 | glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); | ||
2154 | glColor4f(1,1,1,1); | ||
2155 | |||
2156 | mOcclusionIndices->setBuffer(0); | ||
2157 | |||
2158 | U32* indicesp = (U32*) mOcclusionIndices->getIndicesPointer(); | ||
2159 | |||
2160 | glDisableClientState(GL_NORMAL_ARRAY); | ||
2161 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
2162 | glDisableClientState(GL_COLOR_ARRAY); | ||
2163 | #if !LL_RELEASE_FOR_DOWNLOAD | ||
2164 | LLGLState::checkClientArrays(LLVertexBuffer::MAP_VERTEX); | ||
2165 | #endif | ||
2166 | for (U32 i = 0; i < mOccludedList.size(); i++) | ||
2167 | { | ||
2168 | #if LL_OCTREE_PARANOIA_CHECK | ||
2169 | for (U32 j = i+1; j < mOccludedList.size(); j++) | ||
2170 | { | ||
2171 | sg_assert(mOccludedList[i] != mOccludedList[j]); | ||
2172 | } | ||
2173 | #endif | ||
2174 | LLSpatialGroup* group = mOccludedList[i]; | ||
2175 | if (group->isDead()) | ||
2176 | { | ||
2177 | continue; | ||
2178 | } | ||
2179 | |||
2180 | if (earlyFail(camera, group)) | ||
2181 | { | ||
2182 | group->setState(LLSpatialGroup::EARLY_FAIL); | ||
2183 | } | ||
2184 | else | ||
2185 | { //early rejection criteria passed, send some geometry to the query | ||
2186 | group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); | ||
2187 | glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQueries[i]); | ||
2188 | glDrawRangeElements(GL_TRIANGLES, 0, 7, 36, | ||
2189 | GL_UNSIGNED_INT, indicesp); | ||
2190 | glEndQueryARB(GL_SAMPLES_PASSED_ARB); | ||
2191 | |||
2192 | group->setState(LLSpatialGroup::QUERY_OUT); | ||
2193 | group->clearState(LLSpatialGroup::DISCARD_QUERY); | ||
2194 | } | ||
2195 | } | ||
2196 | stop_glerror(); | ||
2197 | |||
2198 | gPipeline.mTrianglesDrawn += mOccludedList.size()*12; | ||
2199 | |||
2200 | glFlush(); | ||
2201 | |||
2202 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | ||
2203 | } | 1949 | } |
2204 | 1950 | ||
2205 | class LLOctreeGet : public LLSpatialGroup::OctreeTraveler | 1951 | void pushBufferVerts(LLSpatialGroup* group, U32 mask) |
2206 | { | 1952 | { |
2207 | public: | 1953 | if (!group->mDrawMap.empty()) |
2208 | LLOctreeGet(LLVector3 pos, F32 rad, LLDrawable::drawable_set_t* results, BOOL lights) | ||
2209 | : mPosition(pos), mRad(rad), mResults(results), mLights(lights), mRes(0) | ||
2210 | { | ||
2211 | |||
2212 | } | ||
2213 | |||
2214 | virtual void traverse(const LLSpatialGroup::TreeNode* n) | ||
2215 | { | 1954 | { |
2216 | LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); | 1955 | LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin()); |
2217 | 1956 | LLRenderPass::applyModelMatrix(*params); | |
2218 | if (mRes == 2) | 1957 | |
2219 | { //fully in, just add everything | 1958 | pushBufferVerts(group->mVertexBuffer, mask); |
2220 | LLSpatialGroup::OctreeTraveler::traverse(n); | ||
2221 | } | ||
2222 | else | ||
2223 | { | ||
2224 | LLVector3 center, size; | ||
2225 | |||
2226 | center = group->mBounds[0]; | ||
2227 | size = group->mBounds[1]; | ||
2228 | |||
2229 | mRes = LLSphereAABB(center, size, mPosition, mRad); | ||
2230 | if (mRes > 0) | ||
2231 | { | ||
2232 | LLSpatialGroup::OctreeTraveler::traverse(n); | ||
2233 | } | ||
2234 | mRes = 0; | ||
2235 | } | ||
2236 | } | ||
2237 | |||
2238 | static BOOL skip(LLDrawable* drawable, BOOL get_lights) | ||
2239 | { | ||
2240 | if (get_lights != drawable->isLight()) | ||
2241 | { | ||
2242 | return TRUE; | ||
2243 | } | ||
2244 | if (get_lights && drawable->getVObj()->isHUDAttachment()) | ||
2245 | { | ||
2246 | return TRUE; // no lighting from HUD objects | ||
2247 | } | ||
2248 | if (get_lights && drawable->isState(LLDrawable::ACTIVE)) | ||
2249 | { | ||
2250 | return TRUE; // ignore active lights | ||
2251 | } | ||
2252 | return FALSE; | ||
2253 | } | ||
2254 | 1959 | ||
2255 | virtual void visit(const LLSpatialGroup::OctreeState* branch) | 1960 | for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) |
2256 | { | ||
2257 | for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) | ||
2258 | { | 1961 | { |
2259 | LLDrawable* drawable = *i; | 1962 | for (LLSpatialGroup::buffer_list_t::iterator j = i->second.begin(); j != i->second.end(); ++j) |
2260 | if (!skip(drawable, mLights)) | ||
2261 | { | 1963 | { |
2262 | if (mRes == 2) | 1964 | pushBufferVerts(*j, mask); |
2263 | { | ||
2264 | mResults->insert(drawable); | ||
2265 | } | ||
2266 | else | ||
2267 | { | ||
2268 | LLVector3 v = LLVector3(drawable->getPositionGroup())-mPosition; | ||
2269 | float dsq = v.magVecSquared(); | ||
2270 | float maxd = mRad + drawable->getVisibilityRadius(); | ||
2271 | if (dsq <= maxd*maxd) | ||
2272 | { | ||
2273 | mResults->insert(drawable); | ||
2274 | } | ||
2275 | } | ||
2276 | } | 1965 | } |
2277 | } | 1966 | } |
2278 | } | 1967 | } |
2279 | |||
2280 | LLVector3 mPosition; | ||
2281 | F32 mRad; | ||
2282 | LLDrawable::drawable_set_t* mResults; | ||
2283 | BOOL mLights; | ||
2284 | U32 mRes; | ||
2285 | }; | ||
2286 | |||
2287 | S32 LLSpatialPartition::getDrawables(const LLVector3& pos, F32 rad, | ||
2288 | LLDrawable::drawable_set_t &results, | ||
2289 | BOOL get_lights) | ||
2290 | { | ||
2291 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | ||
2292 | |||
2293 | LLOctreeGet getter(pos, rad, &results, get_lights); | ||
2294 | getter.traverse(mOctree); | ||
2295 | |||
2296 | return results.size(); | ||
2297 | } | ||
2298 | |||
2299 | S32 LLSpatialPartition::getObjects(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results) | ||
2300 | { | ||
2301 | LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); | ||
2302 | group->rebound(); | ||
2303 | return getDrawables(pos, rad, results, FALSE); | ||
2304 | } | ||
2305 | |||
2306 | S32 LLSpatialPartition::getLights(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results) | ||
2307 | { | ||
2308 | return getDrawables(pos, rad, results, TRUE); | ||
2309 | } | ||
2310 | |||
2311 | void pushVerts(LLDrawInfo* params, U32 mask) | ||
2312 | { | ||
2313 | params->mVertexBuffer->setBuffer(mask); | ||
2314 | U32* indicesp = (U32*) params->mVertexBuffer->getIndicesPointer(); | ||
2315 | glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount, | ||
2316 | GL_UNSIGNED_INT, indicesp+params->mOffset); | ||
2317 | } | ||
2318 | |||
2319 | void pushVerts(LLSpatialGroup* group, U32 mask) | ||
2320 | { | ||
2321 | LLDrawInfo* params = NULL; | ||
2322 | |||
2323 | for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) | ||
2324 | { | ||
2325 | for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) | ||
2326 | { | ||
2327 | params = *j; | ||
2328 | pushVerts(params, mask); | ||
2329 | } | ||
2330 | } | ||
2331 | } | 1968 | } |
2332 | 1969 | ||
2333 | void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) | 1970 | void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) |
@@ -2353,11 +1990,12 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) | |||
2353 | for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) | 1990 | for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) |
2354 | { | 1991 | { |
2355 | params = *j; | 1992 | params = *j; |
1993 | LLRenderPass::applyModelMatrix(*params); | ||
2356 | glColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f); | 1994 | glColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f); |
2357 | params->mVertexBuffer->setBuffer(mask); | 1995 | params->mVertexBuffer->setBuffer(mask); |
2358 | U32* indicesp = (U32*) params->mVertexBuffer->getIndicesPointer(); | 1996 | U16* indicesp = (U16*) params->mVertexBuffer->getIndicesPointer(); |
2359 | glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount, | 1997 | glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount, |
2360 | GL_UNSIGNED_INT, indicesp+params->mOffset); | 1998 | GL_UNSIGNED_SHORT, indicesp+params->mOffset); |
2361 | col = (col+1)%col_count; | 1999 | col = (col+1)%col_count; |
2362 | } | 2000 | } |
2363 | } | 2001 | } |
@@ -2368,7 +2006,7 @@ void renderOctree(LLSpatialGroup* group) | |||
2368 | //render solid object bounding box, color | 2006 | //render solid object bounding box, color |
2369 | //coded by buffer usage and activity | 2007 | //coded by buffer usage and activity |
2370 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); | 2008 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); |
2371 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | 2009 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); |
2372 | LLVector4 col; | 2010 | LLVector4 col; |
2373 | if (group->mBuilt > 0.f) | 2011 | if (group->mBuilt > 0.f) |
2374 | { | 2012 | { |
@@ -2385,34 +2023,59 @@ void renderOctree(LLSpatialGroup* group) | |||
2385 | 2023 | ||
2386 | if (group->mBufferUsage != GL_STATIC_DRAW_ARB) | 2024 | if (group->mBufferUsage != GL_STATIC_DRAW_ARB) |
2387 | { | 2025 | { |
2388 | if (group->mBufferUsage == GL_DYNAMIC_DRAW_ARB) | ||
2389 | { | ||
2390 | glColor4f(1,0,0,group->mBuilt); | ||
2391 | } | ||
2392 | else | ||
2393 | { | ||
2394 | glColor4f(1,1,0,group->mBuilt); | ||
2395 | } | ||
2396 | |||
2397 | LLGLDepthTest gl_depth(FALSE, FALSE); | 2026 | LLGLDepthTest gl_depth(FALSE, FALSE); |
2398 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | 2027 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
2028 | |||
2029 | gGL.color4f(1,0,0,group->mBuilt); | ||
2030 | gGL.flush(); | ||
2031 | glLineWidth(5.f); | ||
2032 | drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); | ||
2033 | gGL.flush(); | ||
2034 | glLineWidth(1.f); | ||
2035 | gGL.stop(); | ||
2399 | for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) | 2036 | for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) |
2400 | { | 2037 | { |
2401 | LLDrawable* drawable = *i; | 2038 | LLDrawable* drawable = *i; |
2039 | if (!group->mSpatialPartition->isBridge()) | ||
2040 | { | ||
2041 | glPushMatrix(); | ||
2042 | LLVector3 trans = drawable->getRegion()->getOriginAgent(); | ||
2043 | glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]); | ||
2044 | } | ||
2045 | |||
2402 | for (S32 j = 0; j < drawable->getNumFaces(); j++) | 2046 | for (S32 j = 0; j < drawable->getNumFaces(); j++) |
2403 | { | 2047 | { |
2404 | LLFace* face = drawable->getFace(j); | 2048 | LLFace* face = drawable->getFace(j); |
2405 | if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f && face->mVertexBuffer.notNull()) | 2049 | if (face->mVertexBuffer.notNull()) |
2406 | { | 2050 | { |
2051 | if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f) | ||
2052 | { | ||
2053 | glColor4f(0, 1, 0, group->mBuilt); | ||
2054 | } | ||
2055 | else if (gFrameTimeSeconds - face->mLastMoveTime < 0.5f) | ||
2056 | { | ||
2057 | glColor4f(1, 0, 0, group->mBuilt); | ||
2058 | } | ||
2059 | else | ||
2060 | { | ||
2061 | continue; | ||
2062 | } | ||
2063 | |||
2407 | face->mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); | 2064 | face->mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); |
2408 | //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f, | 2065 | //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f, |
2409 | // (face->mExtents[1]-face->mExtents[0])*0.5f); | 2066 | // (face->mExtents[1]-face->mExtents[0])*0.5f); |
2410 | glDrawElements(GL_TRIANGLES, face->getIndicesCount(), GL_UNSIGNED_INT, | 2067 | glDrawElements(GL_TRIANGLES, face->getIndicesCount(), GL_UNSIGNED_SHORT, |
2411 | ((U32*) face->mVertexBuffer->getIndicesPointer())+face->getIndicesStart()); | 2068 | ((U16*) face->mVertexBuffer->getIndicesPointer())+face->getIndicesStart()); |
2412 | } | 2069 | } |
2413 | } | 2070 | } |
2071 | |||
2072 | if (!group->mSpatialPartition->isBridge()) | ||
2073 | { | ||
2074 | glPopMatrix(); | ||
2075 | } | ||
2414 | } | 2076 | } |
2415 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | 2077 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
2078 | gGL.start(); | ||
2416 | } | 2079 | } |
2417 | } | 2080 | } |
2418 | else | 2081 | else |
@@ -2428,50 +2091,80 @@ void renderOctree(LLSpatialGroup* group) | |||
2428 | } | 2091 | } |
2429 | } | 2092 | } |
2430 | 2093 | ||
2431 | glColor4fv(col.mV); | 2094 | gGL.color4fv(col.mV); |
2432 | drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); | 2095 | drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); |
2096 | |||
2433 | glDepthMask(GL_TRUE); | 2097 | glDepthMask(GL_TRUE); |
2434 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 2098 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
2435 | 2099 | ||
2436 | //draw opaque outline | 2100 | if (group->mBuilt <= 0.f) |
2437 | glColor4f(col.mV[0], col.mV[1], col.mV[2], 1.f); | ||
2438 | drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); | ||
2439 | |||
2440 | if (group->mOctreeNode->hasLeafState()) | ||
2441 | { | ||
2442 | glColor4f(1,1,1,1); | ||
2443 | } | ||
2444 | else | ||
2445 | { | 2101 | { |
2446 | glColor4f(0,1,1,1); | 2102 | //draw opaque outline |
2103 | gGL.color4f(col.mV[0], col.mV[1], col.mV[2], 1.f); | ||
2104 | drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); | ||
2105 | |||
2106 | if (group->mOctreeNode->isLeaf()) | ||
2107 | { | ||
2108 | gGL.color4f(1,1,1,1); | ||
2109 | } | ||
2110 | else | ||
2111 | { | ||
2112 | gGL.color4f(0,1,1,1); | ||
2113 | } | ||
2114 | |||
2115 | drawBoxOutline(group->mBounds[0],group->mBounds[1]); | ||
2447 | } | 2116 | } |
2448 | |||
2449 | drawBoxOutline(group->mBounds[0],group->mBounds[1]); | ||
2450 | 2117 | ||
2451 | // LLSpatialGroup::OctreeNode* node = group->mOctreeNode; | 2118 | // LLSpatialGroup::OctreeNode* node = group->mOctreeNode; |
2452 | // glColor4f(0,1,0,1); | 2119 | // gGL.color4f(0,1,0,1); |
2453 | // drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize())); | 2120 | // drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize())); |
2454 | } | 2121 | } |
2455 | 2122 | ||
2456 | void renderVisibility(LLSpatialGroup* group) | 2123 | void renderVisibility(LLSpatialGroup* group, LLCamera* camera) |
2457 | { | 2124 | { |
2458 | LLGLEnable blend(GL_BLEND); | 2125 | LLGLEnable blend(GL_BLEND); |
2459 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 2126 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
2460 | LLGLEnable cull(GL_CULL_FACE); | 2127 | LLGLEnable cull(GL_CULL_FACE); |
2461 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | 2128 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
2129 | |||
2130 | BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) && group->isVisible() && | ||
2131 | !group->getData().empty(); | ||
2132 | if (render_objects) | ||
2462 | { | 2133 | { |
2463 | LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); | 2134 | LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); |
2464 | glColor4f(0, 0.5f, 0, 0.5f); | 2135 | glColor4f(0, 0.5f, 0, 0.5f); |
2465 | pushVerts(group, LLVertexBuffer::MAP_VERTEX); | 2136 | pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); |
2466 | } | 2137 | } |
2467 | 2138 | ||
2468 | { | 2139 | { |
2469 | LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL); | 2140 | LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL); |
2470 | pushVertsColorCoded(group, LLVertexBuffer::MAP_VERTEX); | 2141 | |
2142 | if (render_objects) | ||
2143 | { | ||
2144 | glColor4f(0.f, 0.5f, 0.f,1.f); | ||
2145 | pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); | ||
2146 | } | ||
2471 | 2147 | ||
2472 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | 2148 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
2473 | 2149 | ||
2474 | pushVertsColorCoded(group, LLVertexBuffer::MAP_VERTEX); | 2150 | if (render_objects) |
2151 | { | ||
2152 | glColor4f(0.f, 0.75f, 0.f,0.5f); | ||
2153 | pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); | ||
2154 | } | ||
2155 | else if (camera && group->mOcclusionVerts) | ||
2156 | { | ||
2157 | LLVertexBuffer::unbind(); | ||
2158 | glVertexPointer(3, GL_FLOAT, 0, group->mOcclusionVerts); | ||
2159 | |||
2160 | glColor4f(1.0f, 0.f, 0.f, 0.5f); | ||
2161 | glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_occlusion_indices(camera, group->mBounds[0])); | ||
2162 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||
2163 | |||
2164 | glColor4f(1.0f, 1.f, 1.f, 1.0f); | ||
2165 | glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_occlusion_indices(camera, group->mBounds[0])); | ||
2166 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||
2167 | } | ||
2475 | } | 2168 | } |
2476 | } | 2169 | } |
2477 | 2170 | ||
@@ -2479,17 +2172,17 @@ void renderBoundingBox(LLDrawable* drawable) | |||
2479 | { | 2172 | { |
2480 | if (drawable->isSpatialBridge()) | 2173 | if (drawable->isSpatialBridge()) |
2481 | { | 2174 | { |
2482 | glColor4f(1,0.5f,0,1); | 2175 | gGL.color4f(1,0.5f,0,1); |
2483 | } | 2176 | } |
2484 | else if (drawable->getVOVolume()) | 2177 | else if (drawable->getVOVolume()) |
2485 | { | 2178 | { |
2486 | if (drawable->isRoot()) | 2179 | if (drawable->isRoot()) |
2487 | { | 2180 | { |
2488 | glColor4f(1,1,0,1); | 2181 | gGL.color4f(1,1,0,1); |
2489 | } | 2182 | } |
2490 | else | 2183 | else |
2491 | { | 2184 | { |
2492 | glColor4f(0,1,0,1); | 2185 | gGL.color4f(0,1,0,1); |
2493 | } | 2186 | } |
2494 | } | 2187 | } |
2495 | else if (drawable->getVObj()) | 2188 | else if (drawable->getVObj()) |
@@ -2497,27 +2190,27 @@ void renderBoundingBox(LLDrawable* drawable) | |||
2497 | switch (drawable->getVObj()->getPCode()) | 2190 | switch (drawable->getVObj()->getPCode()) |
2498 | { | 2191 | { |
2499 | case LLViewerObject::LL_VO_SURFACE_PATCH: | 2192 | case LLViewerObject::LL_VO_SURFACE_PATCH: |
2500 | glColor4f(0,1,1,1); | 2193 | gGL.color4f(0,1,1,1); |
2501 | break; | 2194 | break; |
2502 | case LLViewerObject::LL_VO_CLOUDS: | 2195 | case LLViewerObject::LL_VO_CLOUDS: |
2503 | glColor4f(0.5f,0.5f,0.5f,1.0f); | 2196 | gGL.color4f(0.5f,0.5f,0.5f,1.0f); |
2504 | break; | 2197 | break; |
2505 | case LLViewerObject::LL_VO_PART_GROUP: | 2198 | case LLViewerObject::LL_VO_PART_GROUP: |
2506 | glColor4f(0,0,1,1); | 2199 | gGL.color4f(0,0,1,1); |
2507 | break; | 2200 | break; |
2508 | case LLViewerObject::LL_VO_WATER: | 2201 | case LLViewerObject::LL_VO_WATER: |
2509 | glColor4f(0,0.5f,1,1); | 2202 | gGL.color4f(0,0.5f,1,1); |
2510 | break; | 2203 | break; |
2511 | case LL_PCODE_LEGACY_TREE: | 2204 | case LL_PCODE_LEGACY_TREE: |
2512 | glColor4f(0,0.5f,0,1); | 2205 | gGL.color4f(0,0.5f,0,1); |
2513 | default: | 2206 | default: |
2514 | glColor4f(1,0,1,1); | 2207 | gGL.color4f(1,0,1,1); |
2515 | break; | 2208 | break; |
2516 | } | 2209 | } |
2517 | } | 2210 | } |
2518 | else | 2211 | else |
2519 | { | 2212 | { |
2520 | glColor4f(1,0,0,1); | 2213 | gGL.color4f(1,0,0,1); |
2521 | } | 2214 | } |
2522 | 2215 | ||
2523 | const LLVector3* ext; | 2216 | const LLVector3* ext; |
@@ -2545,7 +2238,20 @@ void renderBoundingBox(LLDrawable* drawable) | |||
2545 | pos = (ext[0] + ext[1]) * 0.5f; | 2238 | pos = (ext[0] + ext[1]) * 0.5f; |
2546 | size = (ext[1] - ext[0]) * 0.5f; | 2239 | size = (ext[1] - ext[0]) * 0.5f; |
2547 | 2240 | ||
2548 | drawBoxOutline(pos,size); | 2241 | LLViewerObject* vobj = drawable->getVObj(); |
2242 | if (vobj && vobj->onActiveList()) | ||
2243 | { | ||
2244 | gGL.flush(); | ||
2245 | glLineWidth(4.f*sinf(gFrameTimeSeconds*2.f)+1.f); | ||
2246 | drawBoxOutline(pos,size); | ||
2247 | gGL.flush(); | ||
2248 | glLineWidth(1.f); | ||
2249 | } | ||
2250 | else | ||
2251 | { | ||
2252 | drawBoxOutline(pos,size); | ||
2253 | } | ||
2254 | |||
2549 | } | 2255 | } |
2550 | 2256 | ||
2551 | void renderTexturePriority(LLDrawable* drawable) | 2257 | void renderTexturePriority(LLDrawable* drawable) |
@@ -2578,14 +2284,12 @@ void renderTexturePriority(LLDrawable* drawable) | |||
2578 | F32 t = vsize/sLastMaxTexPriority; | 2284 | F32 t = vsize/sLastMaxTexPriority; |
2579 | 2285 | ||
2580 | LLVector4 col = lerp(cold, hot, t); | 2286 | LLVector4 col = lerp(cold, hot, t); |
2581 | glColor4fv(col.mV); | 2287 | gGL.color4fv(col.mV); |
2582 | } | 2288 | } |
2583 | //else | 2289 | //else |
2584 | //{ | 2290 | //{ |
2585 | // glColor4f(1,0,1,1); | 2291 | // gGL.color4f(1,0,1,1); |
2586 | //} | 2292 | //} |
2587 | |||
2588 | |||
2589 | 2293 | ||
2590 | LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f; | 2294 | LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f; |
2591 | LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f); | 2295 | LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f); |
@@ -2597,10 +2301,10 @@ void renderTexturePriority(LLDrawable* drawable) | |||
2597 | F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1); | 2301 | F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1); |
2598 | LLVector4 col = lerp(boost_cold, boost_hot, t); | 2302 | LLVector4 col = lerp(boost_cold, boost_hot, t); |
2599 | LLGLEnable blend_on(GL_BLEND); | 2303 | LLGLEnable blend_on(GL_BLEND); |
2600 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | 2304 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); |
2601 | glColor4fv(col.mV); | 2305 | gGL.color4fv(col.mV); |
2602 | drawBox(center, size); | 2306 | drawBox(center, size); |
2603 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 2307 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
2604 | }*/ | 2308 | }*/ |
2605 | } | 2309 | } |
2606 | } | 2310 | } |
@@ -2608,14 +2312,17 @@ void renderTexturePriority(LLDrawable* drawable) | |||
2608 | void renderPoints(LLDrawable* drawablep) | 2312 | void renderPoints(LLDrawable* drawablep) |
2609 | { | 2313 | { |
2610 | LLGLDepthTest depth(GL_FALSE, GL_FALSE); | 2314 | LLGLDepthTest depth(GL_FALSE, GL_FALSE); |
2611 | glBegin(GL_POINTS); | 2315 | if (drawablep->getNumFaces()) |
2612 | glColor3f(1,1,1); | ||
2613 | LLVector3 center(drawablep->getPositionGroup()); | ||
2614 | for (S32 i = 0; i < drawablep->getNumFaces(); i++) | ||
2615 | { | 2316 | { |
2616 | glVertex3fv(drawablep->getFace(i)->mCenterLocal.mV); | 2317 | gGL.begin(GL_POINTS); |
2318 | gGL.color3f(1,1,1); | ||
2319 | LLVector3 center(drawablep->getPositionGroup()); | ||
2320 | for (S32 i = 0; i < drawablep->getNumFaces(); i++) | ||
2321 | { | ||
2322 | gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV); | ||
2323 | } | ||
2324 | gGL.end(); | ||
2617 | } | 2325 | } |
2618 | glEnd(); | ||
2619 | } | 2326 | } |
2620 | 2327 | ||
2621 | void renderTextureAnim(LLDrawInfo* params) | 2328 | void renderTextureAnim(LLDrawInfo* params) |
@@ -2626,29 +2333,67 @@ void renderTextureAnim(LLDrawInfo* params) | |||
2626 | } | 2333 | } |
2627 | 2334 | ||
2628 | LLGLEnable blend(GL_BLEND); | 2335 | LLGLEnable blend(GL_BLEND); |
2629 | glColor4f(1,1,0,0.5f); | 2336 | gGL.color4f(1,1,0,0.5f); |
2630 | pushVerts(params, LLVertexBuffer::MAP_VERTEX); | 2337 | pushVerts(params, LLVertexBuffer::MAP_VERTEX); |
2631 | } | 2338 | } |
2632 | 2339 | ||
2340 | void renderBatchSize(LLDrawInfo* params) | ||
2341 | { | ||
2342 | glColor3ubv((GLubyte*) &(params->mDebugColor)); | ||
2343 | pushVerts(params, LLVertexBuffer::MAP_VERTEX); | ||
2344 | } | ||
2345 | |||
2346 | void renderLights(LLDrawable* drawablep) | ||
2347 | { | ||
2348 | if (!drawablep->isLight()) | ||
2349 | { | ||
2350 | return; | ||
2351 | } | ||
2352 | |||
2353 | if (drawablep->getNumFaces()) | ||
2354 | { | ||
2355 | LLGLEnable blend(GL_BLEND); | ||
2356 | glColor4f(0,1,1,0.5f); | ||
2357 | |||
2358 | for (S32 i = 0; i < drawablep->getNumFaces(); i++) | ||
2359 | { | ||
2360 | pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); | ||
2361 | } | ||
2362 | |||
2363 | const LLVector3* ext = drawablep->getSpatialExtents(); | ||
2364 | |||
2365 | LLVector3 pos = (ext[0] + ext[1]) * 0.5f; | ||
2366 | LLVector3 size = (ext[1] - ext[0]) * 0.5f; | ||
2367 | |||
2368 | { | ||
2369 | LLGLDepthTest depth(GL_FALSE, GL_TRUE); | ||
2370 | gGL.color4f(1,1,1,1); | ||
2371 | drawBoxOutline(pos, size); | ||
2372 | } | ||
2373 | |||
2374 | gGL.color4f(1,1,0,1); | ||
2375 | F32 rad = drawablep->getVOVolume()->getLightRadius(); | ||
2376 | drawBoxOutline(pos, LLVector3(rad,rad,rad)); | ||
2377 | } | ||
2378 | } | ||
2379 | |||
2633 | class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> | 2380 | class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> |
2634 | { | 2381 | { |
2635 | public: | 2382 | public: |
2636 | LLOctreeRenderNonOccluded() {} | 2383 | LLCamera* mCamera; |
2384 | LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {} | ||
2637 | 2385 | ||
2638 | virtual void traverse(const LLSpatialGroup::OctreeNode* node) | 2386 | virtual void traverse(const LLSpatialGroup::OctreeNode* node) |
2639 | { | 2387 | { |
2640 | const LLSpatialGroup::OctreeState* state = node->getOctState(); | ||
2641 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); | 2388 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); |
2642 | 2389 | ||
2643 | 2390 | if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) | |
2644 | if ((!gPipeline.sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) && | ||
2645 | !group->isState(LLSpatialGroup::CULLED)) | ||
2646 | { | 2391 | { |
2647 | state->accept(this); | 2392 | node->accept(this); |
2648 | 2393 | ||
2649 | for (U32 i = 0; i < state->getChildCount(); i++) | 2394 | for (U32 i = 0; i < node->getChildCount(); i++) |
2650 | { | 2395 | { |
2651 | traverse(state->getChild(i)); | 2396 | traverse(node->getChild(i)); |
2652 | } | 2397 | } |
2653 | 2398 | ||
2654 | //draw tight fit bounding boxes for spatial group | 2399 | //draw tight fit bounding boxes for spatial group |
@@ -2659,19 +2404,25 @@ public: | |||
2659 | 2404 | ||
2660 | //render visibility wireframe | 2405 | //render visibility wireframe |
2661 | if (group->mSpatialPartition->mRenderByGroup && | 2406 | if (group->mSpatialPartition->mRenderByGroup && |
2662 | gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && | 2407 | gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) |
2663 | !group->isState(LLSpatialGroup::GEOM_DIRTY)) | ||
2664 | { | 2408 | { |
2665 | renderVisibility(group); | 2409 | gGL.stop(); |
2410 | glPushMatrix(); | ||
2411 | gGLLastMatrix = NULL; | ||
2412 | glLoadMatrixd(gGLModelView); | ||
2413 | renderVisibility(group, mCamera); | ||
2414 | gGLLastMatrix = NULL; | ||
2415 | glPopMatrix(); | ||
2416 | gGL.start(); | ||
2666 | } | 2417 | } |
2667 | } | 2418 | } |
2668 | } | 2419 | } |
2669 | 2420 | ||
2670 | virtual void visit(const LLSpatialGroup::OctreeState* branch) | 2421 | virtual void visit(const LLSpatialGroup::OctreeNode* branch) |
2671 | { | 2422 | { |
2672 | LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); | 2423 | LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); |
2673 | 2424 | ||
2674 | if (group->isState(LLSpatialGroup::CULLED | LLSpatialGroup::OCCLUDED)) | 2425 | if (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) |
2675 | { | 2426 | { |
2676 | return; | 2427 | return; |
2677 | } | 2428 | } |
@@ -2679,7 +2430,7 @@ public: | |||
2679 | LLVector3 nodeCenter = group->mBounds[0]; | 2430 | LLVector3 nodeCenter = group->mBounds[0]; |
2680 | LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); | 2431 | LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); |
2681 | 2432 | ||
2682 | for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) | 2433 | for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) |
2683 | { | 2434 | { |
2684 | LLDrawable* drawable = *i; | 2435 | LLDrawable* drawable = *i; |
2685 | 2436 | ||
@@ -2697,6 +2448,11 @@ public: | |||
2697 | { | 2448 | { |
2698 | renderPoints(drawable); | 2449 | renderPoints(drawable); |
2699 | } | 2450 | } |
2451 | |||
2452 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LIGHTS)) | ||
2453 | { | ||
2454 | renderLights(drawable); | ||
2455 | } | ||
2700 | } | 2456 | } |
2701 | 2457 | ||
2702 | for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) | 2458 | for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) |
@@ -2709,6 +2465,10 @@ public: | |||
2709 | { | 2465 | { |
2710 | renderTextureAnim(draw_info); | 2466 | renderTextureAnim(draw_info); |
2711 | } | 2467 | } |
2468 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BATCH_SIZE)) | ||
2469 | { | ||
2470 | renderBatchSize(draw_info); | ||
2471 | } | ||
2712 | } | 2472 | } |
2713 | } | 2473 | } |
2714 | } | 2474 | } |
@@ -2718,6 +2478,8 @@ void LLSpatialPartition::renderDebug() | |||
2718 | { | 2478 | { |
2719 | if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | | 2479 | if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | |
2720 | LLPipeline::RENDER_DEBUG_OCCLUSION | | 2480 | LLPipeline::RENDER_DEBUG_OCCLUSION | |
2481 | LLPipeline::RENDER_DEBUG_LIGHTS | | ||
2482 | LLPipeline::RENDER_DEBUG_BATCH_SIZE | | ||
2721 | LLPipeline::RENDER_DEBUG_BBOXES | | 2483 | LLPipeline::RENDER_DEBUG_BBOXES | |
2722 | LLPipeline::RENDER_DEBUG_POINTS | | 2484 | LLPipeline::RENDER_DEBUG_POINTS | |
2723 | LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | | 2485 | LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | |
@@ -2737,57 +2499,23 @@ void LLSpatialPartition::renderDebug() | |||
2737 | 2499 | ||
2738 | LLGLDisable cullface(GL_CULL_FACE); | 2500 | LLGLDisable cullface(GL_CULL_FACE); |
2739 | LLGLEnable blend(GL_BLEND); | 2501 | LLGLEnable blend(GL_BLEND); |
2740 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 2502 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
2741 | LLGLDisable tex(GL_TEXTURE_2D); | 2503 | LLImageGL::unbindTexture(0); |
2742 | gPipeline.disableLights(); | 2504 | gPipeline.disableLights(); |
2743 | |||
2744 | LLOctreeRenderNonOccluded render_debug; | ||
2745 | render_debug.traverse(mOctree); | ||
2746 | 2505 | ||
2747 | LLGLDisable cull_face(GL_CULL_FACE); | 2506 | LLSpatialBridge* bridge = asBridge(); |
2507 | LLCamera* camera = gCamera; | ||
2748 | 2508 | ||
2749 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && !mOccludedList.empty() && | 2509 | if (bridge) |
2750 | mOcclusionIndices.notNull()) | ||
2751 | { | 2510 | { |
2752 | LLGLDisable fog(GL_FOG); | 2511 | camera = NULL; |
2753 | LLGLDepthTest gls_depth(GL_FALSE); | 2512 | } |
2754 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | ||
2755 | mOcclusionIndices->setBuffer(0); | ||
2756 | U32* indicesp = (U32*) mOcclusionIndices->getIndicesPointer(); | ||
2757 | |||
2758 | LLGLEnable blend(GL_BLEND); | ||
2759 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
2760 | LLGLEnable cull(GL_CULL_FACE); | ||
2761 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||
2762 | |||
2763 | for (U32 i = 0; i < mOccludedList.size(); i++) | ||
2764 | { //draw occluded nodes | ||
2765 | LLSpatialGroup* node = mOccludedList[i]; | ||
2766 | if (node->isDead() || | ||
2767 | !node->isState(LLSpatialGroup::OCCLUDED) || | ||
2768 | node->mOcclusionVerts.isNull()) | ||
2769 | { | ||
2770 | continue; | ||
2771 | } | ||
2772 | |||
2773 | node->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); | ||
2774 | { | ||
2775 | LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); | ||
2776 | glColor4f(0.5, 0.5f, 0, 0.25f); | ||
2777 | glDrawRangeElements(GL_TRIANGLES, 0, 7, 36, | ||
2778 | GL_UNSIGNED_INT, indicesp); | ||
2779 | } | ||
2780 | 2513 | ||
2781 | { | 2514 | LLOctreeStateCheck checker; |
2782 | LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL); | 2515 | checker.traverse(mOctree); |
2783 | glColor4f(0.0,1.0f,1.0f,1.0f); | ||
2784 | glDrawRangeElements(GL_TRIANGLES, 0, 7, 36, | ||
2785 | GL_UNSIGNED_INT, indicesp); | ||
2786 | } | ||
2787 | } | ||
2788 | 2516 | ||
2789 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | 2517 | LLOctreeRenderNonOccluded render_debug(camera); |
2790 | } | 2518 | render_debug.traverse(mOctree); |
2791 | } | 2519 | } |
2792 | 2520 | ||
2793 | 2521 | ||
@@ -2816,8 +2544,7 @@ public: | |||
2816 | 2544 | ||
2817 | virtual LLDrawable* check(const LLSpatialGroup::OctreeNode* node) | 2545 | virtual LLDrawable* check(const LLSpatialGroup::OctreeNode* node) |
2818 | { | 2546 | { |
2819 | const LLSpatialGroup::OctreeState* state = node->getOctState(); | 2547 | node->accept(this); |
2820 | state->accept(this); | ||
2821 | 2548 | ||
2822 | for (U32 i = 0; i < node->getChildCount(); i++) | 2549 | for (U32 i = 0; i < node->getChildCount(); i++) |
2823 | { | 2550 | { |
@@ -2841,9 +2568,9 @@ public: | |||
2841 | return mRet; | 2568 | return mRet; |
2842 | } | 2569 | } |
2843 | 2570 | ||
2844 | virtual void visit(const LLSpatialGroup::OctreeState* branch) | 2571 | virtual void visit(const LLSpatialGroup::OctreeNode* branch) |
2845 | { | 2572 | { |
2846 | for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) | 2573 | for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) |
2847 | { | 2574 | { |
2848 | check(*i); | 2575 | check(*i); |
2849 | } | 2576 | } |
@@ -2869,13 +2596,14 @@ LLDrawable* LLSpatialPartition::pickDrawable(const LLVector3& start, const LLVec | |||
2869 | return ret; | 2596 | return ret; |
2870 | } | 2597 | } |
2871 | 2598 | ||
2872 | LLDrawInfo::LLDrawInfo(U32 start, U32 end, U32 count, U32 offset, | 2599 | LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, |
2873 | LLViewerImage* texture, LLVertexBuffer* buffer, | 2600 | LLViewerImage* texture, LLVertexBuffer* buffer, |
2874 | BOOL fullbright, U8 bump, BOOL particle, F32 part_size) | 2601 | BOOL fullbright, U8 bump, BOOL particle, F32 part_size) |
2875 | : | 2602 | : |
2876 | mVertexBuffer(buffer), | 2603 | mVertexBuffer(buffer), |
2877 | mTexture(texture), | 2604 | mTexture(texture), |
2878 | mTextureMatrix(NULL), | 2605 | mTextureMatrix(NULL), |
2606 | mModelMatrix(NULL), | ||
2879 | mStart(start), | 2607 | mStart(start), |
2880 | mEnd(end), | 2608 | mEnd(end), |
2881 | mCount(count), | 2609 | mCount(count), |
@@ -2884,8 +2612,10 @@ LLDrawInfo::LLDrawInfo(U32 start, U32 end, U32 count, U32 offset, | |||
2884 | mBump(bump), | 2612 | mBump(bump), |
2885 | mParticle(particle), | 2613 | mParticle(particle), |
2886 | mPartSize(part_size), | 2614 | mPartSize(part_size), |
2887 | mVSize(0.f) | 2615 | mVSize(0.f), |
2616 | mGroup(NULL) | ||
2888 | { | 2617 | { |
2618 | mDebugColor = (rand() << 16) + rand(); | ||
2889 | } | 2619 | } |
2890 | 2620 | ||
2891 | LLDrawInfo::~LLDrawInfo() | 2621 | LLDrawInfo::~LLDrawInfo() |
@@ -2897,3 +2627,190 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) | |||
2897 | { | 2627 | { |
2898 | return new LLVertexBuffer(type_mask, usage); | 2628 | return new LLVertexBuffer(type_mask, usage); |
2899 | } | 2629 | } |
2630 | |||
2631 | LLCullResult::LLCullResult() | ||
2632 | { | ||
2633 | clear(); | ||
2634 | } | ||
2635 | |||
2636 | void LLCullResult::clear() | ||
2637 | { | ||
2638 | mVisibleGroupsSize = 0; | ||
2639 | mAlphaGroupsSize = 0; | ||
2640 | mOcclusionGroupsSize = 0; | ||
2641 | mDrawableGroupsSize = 0; | ||
2642 | mVisibleListSize = 0; | ||
2643 | mVisibleBridgeSize = 0; | ||
2644 | |||
2645 | for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) | ||
2646 | { | ||
2647 | mRenderMapSize[i] = 0; | ||
2648 | } | ||
2649 | } | ||
2650 | |||
2651 | LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups() | ||
2652 | { | ||
2653 | return mVisibleGroups.begin(); | ||
2654 | } | ||
2655 | |||
2656 | LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups() | ||
2657 | { | ||
2658 | return mVisibleGroups.begin() + mVisibleGroupsSize; | ||
2659 | } | ||
2660 | |||
2661 | LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups() | ||
2662 | { | ||
2663 | return mAlphaGroups.begin(); | ||
2664 | } | ||
2665 | |||
2666 | LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups() | ||
2667 | { | ||
2668 | return mAlphaGroups.begin() + mAlphaGroupsSize; | ||
2669 | } | ||
2670 | |||
2671 | LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups() | ||
2672 | { | ||
2673 | return mOcclusionGroups.begin(); | ||
2674 | } | ||
2675 | |||
2676 | LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups() | ||
2677 | { | ||
2678 | return mOcclusionGroups.begin() + mOcclusionGroupsSize; | ||
2679 | } | ||
2680 | |||
2681 | LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups() | ||
2682 | { | ||
2683 | return mDrawableGroups.begin(); | ||
2684 | } | ||
2685 | |||
2686 | LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups() | ||
2687 | { | ||
2688 | return mDrawableGroups.begin() + mDrawableGroupsSize; | ||
2689 | } | ||
2690 | |||
2691 | LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList() | ||
2692 | { | ||
2693 | return mVisibleList.begin(); | ||
2694 | } | ||
2695 | |||
2696 | LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList() | ||
2697 | { | ||
2698 | return mVisibleList.begin() + mVisibleListSize; | ||
2699 | } | ||
2700 | |||
2701 | LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge() | ||
2702 | { | ||
2703 | return mVisibleBridge.begin(); | ||
2704 | } | ||
2705 | |||
2706 | LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge() | ||
2707 | { | ||
2708 | return mVisibleBridge.begin() + mVisibleBridgeSize; | ||
2709 | } | ||
2710 | |||
2711 | LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type) | ||
2712 | { | ||
2713 | return mRenderMap[type].begin(); | ||
2714 | } | ||
2715 | |||
2716 | LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type) | ||
2717 | { | ||
2718 | return mRenderMap[type].begin() + mRenderMapSize[type]; | ||
2719 | } | ||
2720 | |||
2721 | void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) | ||
2722 | { | ||
2723 | if (mVisibleGroupsSize < mVisibleGroups.size()) | ||
2724 | { | ||
2725 | mVisibleGroups[mVisibleGroupsSize] = group; | ||
2726 | } | ||
2727 | else | ||
2728 | { | ||
2729 | mVisibleGroups.push_back(group); | ||
2730 | } | ||
2731 | ++mVisibleGroupsSize; | ||
2732 | } | ||
2733 | |||
2734 | void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) | ||
2735 | { | ||
2736 | if (mAlphaGroupsSize < mAlphaGroups.size()) | ||
2737 | { | ||
2738 | mAlphaGroups[mAlphaGroupsSize] = group; | ||
2739 | } | ||
2740 | else | ||
2741 | { | ||
2742 | mAlphaGroups.push_back(group); | ||
2743 | } | ||
2744 | ++mAlphaGroupsSize; | ||
2745 | } | ||
2746 | |||
2747 | void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) | ||
2748 | { | ||
2749 | if (mOcclusionGroupsSize < mOcclusionGroups.size()) | ||
2750 | { | ||
2751 | mOcclusionGroups[mOcclusionGroupsSize] = group; | ||
2752 | } | ||
2753 | else | ||
2754 | { | ||
2755 | mOcclusionGroups.push_back(group); | ||
2756 | } | ||
2757 | ++mOcclusionGroupsSize; | ||
2758 | } | ||
2759 | |||
2760 | void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) | ||
2761 | { | ||
2762 | if (mDrawableGroupsSize < mDrawableGroups.size()) | ||
2763 | { | ||
2764 | mDrawableGroups[mDrawableGroupsSize] = group; | ||
2765 | } | ||
2766 | else | ||
2767 | { | ||
2768 | mDrawableGroups.push_back(group); | ||
2769 | } | ||
2770 | ++mDrawableGroupsSize; | ||
2771 | } | ||
2772 | |||
2773 | void LLCullResult::pushDrawable(LLDrawable* drawable) | ||
2774 | { | ||
2775 | if (mVisibleListSize < mVisibleList.size()) | ||
2776 | { | ||
2777 | mVisibleList[mVisibleListSize] = drawable; | ||
2778 | } | ||
2779 | else | ||
2780 | { | ||
2781 | mVisibleList.push_back(drawable); | ||
2782 | } | ||
2783 | ++mVisibleListSize; | ||
2784 | } | ||
2785 | |||
2786 | void LLCullResult::pushBridge(LLSpatialBridge* bridge) | ||
2787 | { | ||
2788 | if (mVisibleBridgeSize < mVisibleBridge.size()) | ||
2789 | { | ||
2790 | mVisibleBridge[mVisibleBridgeSize] = bridge; | ||
2791 | } | ||
2792 | else | ||
2793 | { | ||
2794 | mVisibleBridge.push_back(bridge); | ||
2795 | } | ||
2796 | ++mVisibleBridgeSize; | ||
2797 | } | ||
2798 | |||
2799 | void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) | ||
2800 | { | ||
2801 | if (mRenderMapSize[type] < mRenderMap[type].size()) | ||
2802 | { | ||
2803 | mRenderMap[type][mRenderMapSize[type]] = draw_info; | ||
2804 | } | ||
2805 | else | ||
2806 | { | ||
2807 | mRenderMap[type].push_back(draw_info); | ||
2808 | } | ||
2809 | ++mRenderMapSize[type]; | ||
2810 | } | ||
2811 | |||
2812 | |||
2813 | |||
2814 | |||
2815 | |||
2816 | |||