summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2010-09-19 23:08:12 -0500
committerDave Parks <davep@lindenlab.com>2010-09-19 23:08:12 -0500
commit2c4c1c47bce3db7420f0eb27bdaa7598fbbbb65a (patch)
treea3ffe2463739f9677fa6ceca29b5676bcd4a50f1
parente18e26e87c46806f75d219b21be8b6ff2228fc99 (diff)
Take advantage of automagical tcmalloc alignment.
-rw-r--r--indra/llmath/lloctree.h127
1 files changed, 86 insertions, 41 deletions
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index 73910ef98d..63adfa85b2 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -95,22 +95,30 @@ public:
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeListener<T> oct_listener;
+ /*void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }*/
+
LLOctreeNode( const LLVector4a& center,
const LLVector4a& size,
BaseType* parent,
- S32 octant = -1)
+ U8 octant = 255)
: mParent((oct_node*)parent),
mOctant(octant)
{
- mD = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*4);
-
- mD[CENTER] = center;
- mD[SIZE] = size;
+ mCenter = center;
+ mSize = size;
updateMinMax();
- if ((mOctant == -1) && mParent)
+ if ((mOctant == 255) && mParent)
{
- mOctant = ((oct_node*) mParent)->getOctant(mD[CENTER]);
+ mOctant = ((oct_node*) mParent)->getOctant(mCenter);
}
clearChildren();
@@ -124,30 +132,27 @@ public:
{
delete getChild(i);
}
-
- ll_aligned_free_16(mD);
}
inline const BaseType* getParent() const { return mParent; }
inline void setParent(BaseType* parent) { mParent = (oct_node*) parent; }
- inline const LLVector4a& getCenter() const { return mD[CENTER]; }
- inline const LLVector4a& getSize() const { return mD[SIZE]; }
- inline void setCenter(const LLVector4a& center) { mD[CENTER] = center; }
- inline void setSize(const LLVector4a& size) { mD[SIZE] = size; }
+ inline const LLVector4a& getCenter() const { return mCenter; }
+ inline const LLVector4a& getSize() const { return mSize; }
+ inline void setCenter(const LLVector4a& center) { mCenter = center; }
+ inline void setSize(const LLVector4a& size) { mSize = size; }
inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); }
- inline S32 getOctant() const { return mOctant; }
- inline void setOctant(S32 octant) { mOctant = octant; }
+ inline U8 getOctant() const { return mOctant; }
inline const oct_node* getOctParent() const { return (const oct_node*) getParent(); }
inline oct_node* getOctParent() { return (oct_node*) getParent(); }
- S32 getOctant(const LLVector4a& pos) const //get the octant pos is in
+ U8 getOctant(const LLVector4a& pos) const //get the octant pos is in
{
- return pos.greaterThan(mD[CENTER]).getGatheredBits() & 0x7;
+ return (U8) (pos.greaterThan(mCenter).getGatheredBits() & 0x7);
}
inline bool isInside(const LLVector4a& pos, const F32& rad) const
{
- return rad <= mD[SIZE][0]*2.f && isInside(pos);
+ return rad <= mSize[0]*2.f && isInside(pos);
}
inline bool isInside(T* data) const
@@ -157,13 +162,13 @@ public:
bool isInside(const LLVector4a& pos) const
{
- S32 gt = pos.greaterThan(mD[MAX]).getGatheredBits() & 0x7;
+ S32 gt = pos.greaterThan(mMax).getGatheredBits() & 0x7;
if (gt)
{
return false;
}
- S32 lt = pos.lessEqual(mD[MIN]).getGatheredBits() & 0x7;
+ S32 lt = pos.lessEqual(mMin).getGatheredBits() & 0x7;
if (lt)
{
return false;
@@ -174,8 +179,8 @@ public:
void updateMinMax()
{
- mD[MAX].setAdd(mD[CENTER], mD[SIZE]);
- mD[MIN].setSub(mD[CENTER], mD[SIZE]);
+ mMax.setAdd(mCenter, mSize);
+ mMin.setSub(mCenter, mSize);
}
inline oct_listener* getOctListener(U32 index)
@@ -195,7 +200,7 @@ public:
return false;
}
- F32 size = mD[SIZE][0];
+ F32 size = mSize[0];
F32 p_size = size * 2.f;
return (radius <= 0.001f && size <= 0.001f) ||
@@ -234,6 +239,29 @@ public:
void accept(tree_traveler* visitor) const { visitor->visit(this); }
void accept(oct_traveler* visitor) const { visitor->visit(this); }
+ void validateChildMap()
+ {
+ for (U32 i = 0; i < 8; i++)
+ {
+ U8 idx = mChildMap[i];
+ if (idx != 255)
+ {
+ LLOctreeNode<T>* child = mChild[idx];
+
+ if (child->getOctant() != i)
+ {
+ llerrs << "Invalid child map, bad octant data." << llendl;
+ }
+
+ if (getOctant(child->getCenter()) != child->getOctant())
+ {
+ llerrs << "Invalid child octant compared to position data." << llendl;
+ }
+ }
+ }
+ }
+
+
oct_node* getNodeAt(const LLVector4a& pos, const F32& rad)
{
LLOctreeNode<T>* node = this;
@@ -241,25 +269,19 @@ public:
if (node->isInside(pos, rad))
{
//do a quick search by octant
- S32 octant = node->getOctant(pos);
- BOOL keep_going = TRUE;
-
+ U8 octant = node->getOctant(pos);
+
//traverse the tree until we find a node that has no node
//at the appropriate octant or is smaller than the object.
//by definition, that node is the smallest node that contains
// the data
- while (keep_going && node->getSize()[0] >= rad)
+ U8 next_node = node->mChildMap[octant];
+
+ while (next_node != 255 && node->getSize()[0] >= rad)
{
- keep_going = FALSE;
- for (U32 i = 0; i < node->getChildCount() && !keep_going; i++)
- {
- if (node->getChild(i)->getOctant() == octant)
- {
- node = node->getChild(i);
- octant = node->getOctant(pos);
- keep_going = TRUE;
- }
- }
+ node = node->getChild(next_node);
+ octant = node->getOctant(pos);
+ next_node = node->mChildMap[octant];
}
}
else if (!node->contains(rad) && node->getParent())
@@ -439,6 +461,9 @@ public:
void clearChildren()
{
mChild.clear();
+
+ U32* foo = (U32*) mChildMap;
+ foo[0] = foo[1] = 0xFFFFFFFF;
}
void validate()
@@ -496,6 +521,8 @@ public:
}
#endif
+ mChildMap[child->getOctant()] = (U8) mChild.size();
+
mChild.push_back(child);
child->setParent(this);
@@ -517,6 +544,8 @@ public:
listener->handleChildRemoval(this, getChild(index));
}
+
+
if (destroy)
{
mChild[index]->destroy();
@@ -524,6 +553,15 @@ public:
}
mChild.erase(mChild.begin() + index);
+ //rebuild child map
+ U32* foo = (U32*) mChildMap;
+ foo[0] = foo[1] = 0xFFFFFFFF;
+
+ for (U32 i = 0; i < mChild.size(); ++i)
+ {
+ mChildMap[mChild[i]->getOctant()] = i;
+ }
+
checkAlive();
}
@@ -562,15 +600,20 @@ protected:
MIN = 3
} eDName;
- LLVector4a* mD;
+ LLVector4a mCenter;
+ LLVector4a mSize;
+ LLVector4a mMax;
+ LLVector4a mMin;
oct_node* mParent;
- S32 mOctant;
+ U8 mOctant;
child_list mChild;
+ U8 mChildMap[8];
+
element_list mData;
-};
+};
//just like a regular node, except it might expand on insert and compress on balance
template <class T>
@@ -613,6 +656,8 @@ public:
//destroy child
child->clearChildren();
delete child;
+
+ return false;
}
return true;
@@ -639,7 +684,7 @@ public:
const LLVector4a& v = data->getPositionGroup();
LLVector4a val;
- val.setSub(v, BaseType::mD[BaseType::CENTER]);
+ val.setSub(v, BaseType::mCenter);
val.setAbs(val);
S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7;