Support Forum G3D Web Page |
A set data structure that supports spatial queries using an axis-aligned BSP tree for speed.
More...
Classes | |
class | AxisComparator |
class | BoxIntersectionIterator |
C++ STL style iterator variable. More... | |
class | Handle |
class | Iterator |
C++ STL style iterator variable. More... | |
class | Node |
Public Member Functions | |
PointKDTree () | |
To construct a balanced tree, insert the elements and then call PointKDTree::balance(). More... | |
PointKDTree (const PointKDTree &src) | |
~PointKDTree () | |
void | balance (int valuesPerNode=40, int numMeanSplits=3) |
Rebalances the tree (slow). More... | |
Iterator | begin () const |
C++ STL style iterator method. More... | |
BoxIntersectionIterator | beginBoxIntersection (const AABox &box) const |
Iterates through the members that intersect the box More... | |
void | clear () |
Throws out all elements of the set and erases the structure of the tree. More... | |
void | clearData () |
Removes all elements of the set while maintaining the structure of the tree. More... | |
bool | contains (const T &value) |
Returns true if this object is in the set, otherwise returns false. More... | |
void | deserializeStructure (BinaryInput &bi) |
Clears the member table. More... | |
Iterator | end () const |
C++ STL style iterator method. More... | |
BoxIntersectionIterator | endBoxIntersection () const |
void | getIntersectingMembers (const Array< Plane > &plane, Array< T > &members) const |
Returns all members inside the set of planes. More... | |
void | getIntersectingMembers (const Frustum &frustum, Array< T > &members) const |
Typically used to find all visible objects inside the view frustum (see also Camera::getClipPlanes)... More... | |
void | getIntersectingMembers (const AABox &box, Array< T > &members) const |
Appends all members whose bounds intersect the box. More... | |
void | getIntersectingMembers (const Sphere &sphere, Array< T > &members) const |
void | getMembers (Array< T > &members) const |
Returns an array of all members of the set. More... | |
void | insert (const T &value) |
Inserts an object into the set if it is not already present. More... | |
void | insert (const Array< T > &valueArray) |
Inserts each elements in the array in turn. More... | |
PointKDTree & | operator= (const PointKDTree &src) |
void | remove (const T &value) |
Removes an object from the set in O(1) time. More... | |
void | serializeStructure (BinaryOutput &bo) const |
Stores the locations of the splitting planes (the structure but not the content) so that the tree can be quickly rebuilt from a previous configuration without calling balance. More... | |
size_t | size () const |
void | update (const T &value) |
If the element is in the set, it is removed. More... | |
Protected Types | |
typedef Table< T, Node *, HashFunc, EqualsFunc > | MemberTable |
Maps members to the node containing them. More... | |
Protected Member Functions | |
Node * | cloneTree (Node *src) |
Recursively clone the passed in node tree, setting pointers for members in the memberTable as appropriate. More... | |
Node * | makeNode (Array< Handle > &source, Array< Handle > &temp, int valuesPerNode, int numMeanSplits) |
Recursively subdivides the subarray. More... | |
Static Protected Member Functions | |
static AABox | computeBounds (const Array< Handle > &point) |
Returns the bounds of the sub array. More... | |
Protected Attributes | |
MemberTable | memberTable |
Node * | root |
A set data structure that supports spatial queries using an axis-aligned BSP tree for speed.
PointKDTree allows you to quickly find points in 3D that lie within a box or sphere. For large sets of objects it is much faster than testing each object for a collision. See also G3D::KDTree; this class is optimized for point sets, e.g.,for use in photon mapping and mesh processing.
Template Parameters
The template parameter T must be one for which the following functions are overloaded:
T::T(); (public constructor of no arguments)
template<> struct PositionTrait<class T> { static void getPosition(const T& v, G3D::Vector3& p);};
template <> struct HashTrait<class T> { static size_t hashCode(const T& key);};
template<> struct EqualsTrait<class T> { static bool equals(const T& a, const T& b); };
G3D provides these for the Vector2, Vector3, and Vector4 classes. If you use a custom class, or a pointer to a custom class, you will need to define those functions.
Moving Set Members
It is important that objects do not move without updating the PointKDTree. If the position of an object is about to change, PointKDTree::remove it before they change and PointKDTree::insert it again afterward. For objects where the hashCode and == operator are invariant with respect to the 3D position, you can use the PointKDTree::update method as a shortcut to insert/remove an object in one step after it has moved.
Note: Do not mutate any value once it has been inserted into PointKDTree. Values are copied interally. All PointKDTree iterators convert to pointers to constant values to reinforce this.
If you want to mutate the objects you intend to store in a PointKDTree simply insert pointers to your objects instead of the objects themselves, and ensure that the above operations are defined. (And actually, because values are copied, if your values are large you may want to insert pointers anyway, to save space and make the balance operation faster.)
Dimensions Although designed as a 3D-data structure, you can use the PointKDTree for data distributed along 2 or 1 axes by simply returning bounds that are always zero along one or more dimensions.
|
protected |
Maps members to the node containing them.
|
inline |
To construct a balanced tree, insert the elements and then call PointKDTree::balance().
|
inline |
|
inline |
|
inline |
Rebalances the tree (slow).
Call when objects have moved substantially from their original positions (which unbalances the tree and causes the spatial queries to be slow).
valuesPerNode | Maximum number of elements to put at a node. |
numMeanSplits | numMeanSplits = 0 gives a fully axis aligned BSP-tree, where the balance operation attempts to balance the tree so that every splitting plane has an equal number of left and right children (i.e. it is a median split along that axis). This tends to maximize average performance; all querries will return in the same amount of time. |
You can override this behavior by setting a number of mean (average) splits. numMeanSplits = MAX_INT creates a full oct-tree, which tends to optimize peak performance (some areas of the scene will terminate after few recursive splits) at the expense of peak performance.
|
inline |
C++ STL style iterator method.
Returns the first member.
Use preincrement (++entry) to get to the next element (iteration order is arbitrary).
Do not modify the set while iterating.
|
inline |
Iterates through the members that intersect the box
|
inline |
Throws out all elements of the set and erases the structure of the tree.
Referenced by G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::balance(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::deserializeStructure(), and G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::~PointKDTree().
|
inline |
Removes all elements of the set while maintaining the structure of the tree.
|
inlineprotected |
Recursively clone the passed in node tree, setting pointers for members in the memberTable as appropriate.
called by the assignment operator.
Referenced by G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::operator=().
|
inlinestaticprotected |
Returns the bounds of the sub array.
Used by makeNode.
Referenced by G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::makeNode().
|
inline |
Returns true if this object is in the set, otherwise returns false.
O(1) time.
Referenced by G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::insert(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::remove(), and G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::update().
|
inline |
Clears the member table.
|
inline |
C++ STL style iterator method.
Returns one after the last iterator element.
|
inline |
|
inline |
Returns all members inside the set of planes.
members | The results are appended to this array. |
|
inline |
Typically used to find all visible objects inside the view frustum (see also Camera::getClipPlanes)...
i.e. all objects not culled by frustum.
Example:
Array<Object*> visible; tree.getIntersectingMembers(camera.frustum(), visible); // ... Draw all objects in the visible array.
members | The results are appended to this array. |
|
inline |
Appends all members whose bounds intersect the box.
See also PointKDTree::beginBoxIntersection.
|
inline |
members | The results are appended to this array. |
|
inline |
Returns an array of all members of the set.
See also PointKDTree::begin.
|
inline |
Inserts an object into the set if it is not already present.
O(log n) time. Does not cause the tree to be balanced.
Referenced by G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::insert(), and G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::update().
|
inline |
Inserts each elements in the array in turn.
If the tree begins empty (no structure and no elements), this is faster than inserting each element in turn. You still need to balance the tree at the end.
|
inlineprotected |
Recursively subdivides the subarray.
The source array will be cleared after it is used
Call assignSplitBounds() on the root node after making a tree.
Referenced by G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::balance().
|
inline |
|
inline |
Removes an object from the set in O(1) time.
It is an error to remove members that are not already present. May unbalance the tree.
Removing an element never causes a node (split plane) to be removed... nodes are only changed when the tree is rebalanced. This behavior is desirable because it allows the split planes to be serialized, and then deserialized into an empty tree which can be repopulated.
|
inline |
Stores the locations of the splitting planes (the structure but not the content) so that the tree can be quickly rebuilt from a previous configuration without calling balance.
|
inline |
|
inline |
If the element is in the set, it is removed.
The element is then inserted.
This is useful when the == and hashCode methods on T are independent of the bounds. In that case, you may call update(v) to insert an element for the first time and call update(v) again every time it moves to keep the tree up to date.
|
protected |
Referenced by G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::begin(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::clear(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::clearData(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::cloneTree(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::contains(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::end(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::getMembers(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::insert(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::makeNode(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::remove(), and G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::size().
|
protected |
Referenced by G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::balance(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::beginBoxIntersection(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::clear(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::clearData(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::deserializeStructure(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::getIntersectingMembers(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::insert(), G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::operator=(), and G3D::PointKDTree< T, PositionFunc, HashFunc, EqualsFunc >::serializeStructure().