aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/lloctree.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmath/lloctree.h')
-rw-r--r--linden/indra/llmath/lloctree.h94
1 files changed, 59 insertions, 35 deletions
diff --git a/linden/indra/llmath/lloctree.h b/linden/indra/llmath/lloctree.h
index 6e068cd..22f298c 100644
--- a/linden/indra/llmath/lloctree.h
+++ b/linden/indra/llmath/lloctree.h
@@ -40,6 +40,11 @@
40#endif 40#endif
41 41
42#define LL_OCTREE_PARANOIA_CHECK 0 42#define LL_OCTREE_PARANOIA_CHECK 0
43#if LL_DARWIN
44#define LL_OCTREE_MAX_CAPACITY 32
45#else
46#define LL_OCTREE_MAX_CAPACITY 256
47#endif
43 48
44template <class T> class LLOctreeState; 49template <class T> class LLOctreeState;
45template <class T> class LLOctreeNode; 50template <class T> class LLOctreeNode;
@@ -107,7 +112,8 @@ public:
107 virtual void removeByAddress(T* data) { getOctState()->removeByAddress(data); } 112 virtual void removeByAddress(T* data) { getOctState()->removeByAddress(data); }
108 virtual bool hasLeafState() const { return getOctState()->isLeaf(); } 113 virtual bool hasLeafState() const { return getOctState()->isLeaf(); }
109 virtual void destroy() { getOctState()->destroy(); } 114 virtual void destroy() { getOctState()->destroy(); }
110 virtual oct_node* getNodeAt(T* data) { return getOctState()->getNodeAt(data); } 115 virtual oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); }
116 virtual oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) { return getOctState()->getNodeAt(pos, rad); }
111 virtual U8 getOctant() const { return mOctant; } 117 virtual U8 getOctant() const { return mOctant; }
112 virtual void setOctant(U8 octant) { mOctant = octant; } 118 virtual void setOctant(U8 octant) { mOctant = octant; }
113 virtual const oct_state* getOctState() const { return (const oct_state*) BaseType::mState; } 119 virtual const oct_state* getOctState() const { return (const oct_state*) BaseType::mState; }
@@ -136,9 +142,14 @@ public:
136 return ret; 142 return ret;
137 } 143 }
138 144
145 virtual bool isInside(const LLVector3d& pos, const F64& rad) const
146 {
147 return rad <= mSize.mdV[0]*2.0 && isInside(pos);
148 }
149
139 virtual bool isInside(T* data) const 150 virtual bool isInside(T* data) const
140 { 151 {
141 return data->getBinRadius() <= mSize.mdV[0]*2.0 && isInside(data->getPositionGroup()); 152 return isInside(data->getPositionGroup(), data->getBinRadius());
142 } 153 }
143 154
144 virtual bool isInside(const LLVector3d& pos) const 155 virtual bool isInside(const LLVector3d& pos) const
@@ -174,6 +185,11 @@ public:
174 185
175 bool contains(T* xform) 186 bool contains(T* xform)
176 { 187 {
188 return contains(xform->getBinRadius());
189 }
190
191 bool contains(F64 radius)
192 {
177 if (mParent == NULL) 193 if (mParent == NULL)
178 { //root node contains nothing 194 { //root node contains nothing
179 return false; 195 return false;
@@ -181,7 +197,6 @@ public:
181 197
182 F64 size = mSize.mdV[0]; 198 F64 size = mSize.mdV[0];
183 F64 p_size = size * 2.0; 199 F64 p_size = size * 2.0;
184 F64 radius = xform->getBinRadius();
185 200
186 return (radius <= 0.001 && size <= 0.001) || 201 return (radius <= 0.001 && size <= 0.001) ||
187 (radius <= p_size && radius > size); 202 (radius <= p_size && radius > size);
@@ -189,17 +204,10 @@ public:
189 204
190 static void pushCenter(LLVector3d &center, LLVector3d &size, T* data) 205 static void pushCenter(LLVector3d &center, LLVector3d &size, T* data)
191 { 206 {
192 LLVector3 pos(data->getPositionGroup()); 207 LLVector3d pos(data->getPositionGroup());
193 F64 p[] =
194 {
195 (F64) pos.mV[0],
196 (F64) pos.mV[1],
197 (F64) pos.mV[2]
198 };
199
200 for (U32 i = 0; i < 3; i++) 208 for (U32 i = 0; i < 3; i++)
201 { 209 {
202 if (p[i] > center.mdV[i]) 210 if (pos.mdV[i] > center.mdV[i])
203 { 211 {
204 center.mdV[i] += size.mdV[i]; 212 center.mdV[i] += size.mdV[i];
205 } 213 }
@@ -273,11 +281,15 @@ public:
273 oct_node* getOctNode() { return (oct_node*) BaseType::getNode(); } 281 oct_node* getOctNode() { return (oct_node*) BaseType::getNode(); }
274 282
275 virtual oct_node* getNodeAt(T* data) 283 virtual oct_node* getNodeAt(T* data)
284 {
285 return getNodeAt(data->getPositionGroup(), data->getBinRadius());
286 }
287
288 virtual oct_node* getNodeAt(const LLVector3d& pos, const F64& rad)
276 { 289 {
277 const LLVector3d& pos = data->getPositionGroup();
278 LLOctreeNode<T>* node = getOctNode(); 290 LLOctreeNode<T>* node = getOctNode();
279 291
280 if (node->isInside(data)) 292 if (node->isInside(pos, rad))
281 { 293 {
282 //do a quick search by octant 294 //do a quick search by octant
283 U8 octant = node->getOctant(pos.mdV); 295 U8 octant = node->getOctant(pos.mdV);
@@ -287,7 +299,7 @@ public:
287 //at the appropriate octant or is smaller than the object. 299 //at the appropriate octant or is smaller than the object.
288 //by definition, that node is the smallest node that contains 300 //by definition, that node is the smallest node that contains
289 // the data 301 // the data
290 while (keep_going && node->getSize().mdV[0] >= data->getBinRadius()) 302 while (keep_going && node->getSize().mdV[0] >= rad)
291 { 303 {
292 keep_going = FALSE; 304 keep_going = FALSE;
293 for (U32 i = 0; i < node->getChildCount() && !keep_going; i++) 305 for (U32 i = 0; i < node->getChildCount() && !keep_going; i++)
@@ -301,9 +313,9 @@ public:
301 } 313 }
302 } 314 }
303 } 315 }
304 else if (!node->contains(data) && node->getParent()) 316 else if (!node->contains(rad) && node->getParent())
305 { //if we got here, data does not exist in this node 317 { //if we got here, data does not exist in this node
306 return ((LLOctreeNode<T>*) node->getParent())->getNodeAt(data); 318 return ((LLOctreeNode<T>*) node->getParent())->getNodeAt(pos, rad);
307 } 319 }
308 320
309 return node; 321 return node;
@@ -317,22 +329,15 @@ public:
317 return false; 329 return false;
318 } 330 }
319 LLOctreeNode<T>* node = getOctNode(); 331 LLOctreeNode<T>* node = getOctNode();
332 LLOctreeNode<T>* parent = node->getOctParent();
320 333
321 if (data->getBinRadius() <= node->getSize().mdV[0]) 334 //is it here?
322 { 335 if (node->isInside(data->getPositionGroup()))
323 oct_node* dest = getNodeAt(data);
324
325 if (dest != node)
326 {
327 dest->insert(data);
328 return false;
329 }
330 }
331
332 //no kid found, is it even here?
333 if (node->isInside(data))
334 { 336 {
335 if (node->contains(data)) 337 if (getElementCount() < LL_OCTREE_MAX_CAPACITY &&
338 (node->contains(data->getBinRadius()) ||
339 (data->getBinRadius() > node->getSize().mdV[0] &&
340 parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY)))
336 { //it belongs here 341 { //it belongs here
337 if (data == NULL) 342 if (data == NULL)
338 { 343 {
@@ -353,7 +358,19 @@ public:
353 return true; 358 return true;
354 } 359 }
355 else 360 else
356 { 361 {
362 //find a child to give it to
363 oct_node* child = NULL;
364 for (U32 i = 0; i < getChildCount(); i++)
365 {
366 child = getChild(i);
367 if (child->isInside(data->getPositionGroup()))
368 {
369 child->insert(data);
370 return false;
371 }
372 }
373
357 //it's here, but no kids are in the right place, make a new kid 374 //it's here, but no kids are in the right place, make a new kid
358 LLVector3d center(node->getCenter()); 375 LLVector3d center(node->getCenter());
359 LLVector3d size(node->getSize()*0.5); 376 LLVector3d size(node->getSize()*0.5);
@@ -385,7 +402,7 @@ public:
385 402
386 //make the new kid 403 //make the new kid
387 LLOctreeState<T>* newstate = new LLOctreeState<T>(); 404 LLOctreeState<T>* newstate = new LLOctreeState<T>();
388 oct_node* child = new LLOctreeNode<T>(center, size, newstate, node); 405 child = new LLOctreeNode<T>(center, size, newstate, node);
389 addChild(child); 406 addChild(child);
390 407
391 child->insert(data); 408 child->insert(data);
@@ -393,8 +410,15 @@ public:
393 } 410 }
394 else 411 else
395 { 412 {
396 //it's not in here, give it to the parent 413 //it's not in here, give it to the root
397 node->getOctParent()->insert(data); 414 LLOctreeNode<T>* parent = node->getOctParent();
415 while (parent)
416 {
417 node = parent;
418 parent = node->getOctParent();
419 }
420
421 node->insert(data);
398 } 422 }
399 423
400 return false; 424 return false;