Game of Ur 0.3.3
This is a computer adaptation of Game of Ur, written in C++ mainly using SDL and OpenGL.
|
A single node of an octree, representing a single octant of the 8 that make up its parent region. More...
#include <spatial_query_octree.hpp>
Public Types | |
enum | OctantSpecifier : Octant { RIGHT =0x1 , TOP =0x2 , FRONT =0x4 } |
Mask values which, when applied to the octant value, tell you which sub-region of the parent region this node represents. | |
enum | AddressMasks : Address { DEPTH_MASK = -(1ull << kDepthBitOffset) , ROUTE_MASK = ~(-(1ull << knRouteBits)) } |
Mask values for retrieving the different sections of an Address. | |
using | Octant = uint8_t |
A number representing the portion of the parent region represented by this node. | |
using | Depth = uint8_t |
The depth of this node relative to the overall octree; the number of hops to go from this node up to the root node of the tree. | |
using | Address = uint64_t |
The full address of this node, where every three bits right-to-left represent the octant in the hierarchy to select in order to reach it, and the leftmost bits represent the depth at which it is found. | |
Public Member Functions | |
std::vector< std::pair< EntityID, AxisAlignedBounds > > | findAllMemberEntities () const |
Retrieves all entities in this octant and its descendants. | |
std::vector< std::pair< EntityID, AxisAlignedBounds > > | findEntitiesOverlapping (const AxisAlignedBounds &searchBounds) const |
Retrieves all entities that intersect with the region described by searchBounds. | |
std::vector< std::pair< EntityID, AxisAlignedBounds > > | findEntitiesOverlapping (const Ray &searchRay) const |
Retrieves all entities that intersect with the ray described by searchRay. | |
uint8_t | getChildCount () const |
Gets the number of active child octants this octant has. | |
Address | getAddress () const |
Gets the address value for this node. | |
AxisAlignedBounds | getWorldBounds () const |
Retrieves the AABB representing the region this node covers. | |
Address | insertEntity (EntityID entityID, const AxisAlignedBounds &entityWorldBounds) |
Adds an entity to this node or its subtree, per its configuration and the bounds of the object. | |
std::shared_ptr< OctreeNode > | removeEntity (EntityID entityID, Address entityAddressHint=kNoAddress) |
Removes an entity situated at a node at some address (or on a descendant node). | |
std::shared_ptr< OctreeNode > | getNode (Address octantAddress) |
Gets a descendant of this node (or this node itself) by its address. | |
std::shared_ptr< OctreeNode > | nextNodeInAddress (Address octantAddress) |
Gets the child node corresponding to the next node in the argument's route section relative to the this node. | |
std::shared_ptr< OctreeNode > | getSmallestNodeContaining (const AxisAlignedBounds &entityWorldBounds) |
Gets the node whose region just encompasses the bounds provided as input. | |
std::shared_ptr< OctreeNode > | findCandidateRoot () |
Gets the smallest node, this node or a descendant, whose region encompasses all entities remaining in the Octree. | |
Address | getBaseRoute (Address address) const |
Gets the route section of the address up to the current node's depth. | |
Depth | getDepth () const |
The depth of this node relative to the root of the Octree it is a part of. | |
Octant | getOctant () const |
Gets the octant value of this node relative to its parent. | |
Octant | nextOctant (Address address) const |
Fetches the octant of the next node in the route section of the argument address. | |
void | shrinkTreeAndBecomeRoot () |
Trims the addresses of this node and its children (and consequently their entities) such that this node is the root. | |
Static Public Member Functions | |
static Address | MakeAddress (Octant childOctant, Address parentAddress) |
Prepends the address of a child octant to the address of its parent in order to make the child's address. | |
static Depth | GetDepth (Address address) |
Gets the depth value of a node based on its address. | |
static Octant | ToGrowthDirection (Octant octant) |
Maps an octant to its corresponding growth direction. | |
static Octant | ToOctant (Octant growthDirection) |
Converts a growth direction to its corresponding octant. | |
static Octant | GetOctant (Address address) |
Returns the 3 bits representing just this node's octant value, relative to its own parent. | |
static Address | GetBaseRouteMask (Depth baseDepth) |
Gets a bit mask covering the first 3*depth bits based on a given depth value. | |
static Address | GetBaseRoute (Address address, Depth baseDepth) |
Gets the value of the route section of an address up to some specified depth. | |
static Octant | GetOctantAt (Address address, Depth depth) |
Gets the octant corresponding to a specific depth within an address. | |
static Address | GrowAddress (Address address, Address rootAddress) |
Adds root-address' route to address' route. | |
static Address | ShrinkAddress (Address address, Depth depthRemoved) |
Shrinks an address according to the depth removed. | |
static bool | SharesBranch (Address one, Address two) |
Tests whether two nodes are present on the same branch of an octree (or in other words, whether one is the descendant or ancestor of the other). | |
static std::shared_ptr< OctreeNode > | CreateRootNode (uint8_t subdivisionThreshold, AxisAlignedBounds boundRegion) |
Produces a node for the root of an octree that encloses the region to be divided. | |
static std::shared_ptr< OctreeNode > | GrowTreeAndCreateRoot (std::shared_ptr< OctreeNode > oldRoot, const AxisAlignedBounds ®ionToCover) |
Expands an octree such that it encloses a previously unmapped region, and creates a node to be used as the new root node for the octree. | |
Static Public Attributes | |
static constexpr uint8_t | knDepthBits { 5 } |
The number of bits on the left hand side of a node address giving the depth of this node. | |
static constexpr uint8_t | kDepthBitOffset { sizeof(Address)*8 - knDepthBits } |
(Computed) The number of bits by which to shift the address right in order to retrieve the depth value of the node. | |
static constexpr uint8_t | knRouteBits { (kDepthBitOffset/3) * 3} |
The number of bits of the address, starting from the right, representing the route to follow in the Octree hierarchy in order to reach this node. | |
static constexpr Depth | kMaxDepthInclusive |
The total depth representable given the value range of the depth-section of the address, and the space available in the route-section. | |
static constexpr Address | kNoAddress { 0x0 } |
A special value reserved for the absence of an address, as in the root node of the Octree. | |
Private Member Functions | |
OctreeNode (Address octantAddress, uint8_t subdivisionThreshold, AxisAlignedBounds worldBounds, std::shared_ptr< OctreeNode > parent) | |
Constructs a new OctreeNode. | |
Private Attributes | |
Address | mAddress { 0x0 } |
The address of this node, where kNoAddress is the address of the root node of an octree. | |
uint8_t | mSubdivisionThreshold { 40 } |
The number of member entities a node (or its descendant) may have, beyond which the node's subdivision should be attempted. | |
AxisAlignedBounds | mWorldBounds {} |
The region, as an AABB, encompassed by this node. | |
std::weak_ptr< OctreeNode > | mParent {} |
The parent of this node, which this node is an octant of. | |
std::array< std::shared_ptr< OctreeNode >, 8 > | mChildren {} |
An array of up to 8 child nodes maintained by this node, where each index corresponds to one possible value of an Octant. | |
std::map< EntityID, AxisAlignedBounds > | mEntities {} |
The member entities of this node. | |
A single node of an octree, representing a single octant of the 8 that make up its parent region.
using ToyMaker::OctreeNode::Octant = uint8_t |
A number representing the portion of the parent region represented by this node.
|
inlineprivate |
Constructs a new OctreeNode.
octantAddress | The address this node is initialized with. |
subdivisionThreshold | The number of member entities a node may have beyond which its subdivision should be attempted. |
worldBounds | The total region (as an AABB) to be enclosed by this node. |
parent | A reference to the parent of this node. |
|
static |
Produces a node for the root of an octree that encloses the region to be divided.
subdivisionThreshold | The number of objects on a single node beyond which a subdivision of the node should be attempted. |
boundRegion | The region containing all of the axis aligned bounds to be enclosed by this octree. |
std::vector< std::pair< EntityID, AxisAlignedBounds > > OctreeNode::findAllMemberEntities | ( | ) | const |
Retrieves all entities in this octant and its descendants.
Available query methods
std::shared_ptr< OctreeNode > OctreeNode::findCandidateRoot | ( | ) |
std::vector< std::pair< EntityID, AxisAlignedBounds > > OctreeNode::findEntitiesOverlapping | ( | const AxisAlignedBounds & | searchBounds | ) | const |
Retrieves all entities that intersect with the region described by searchBounds.
searchBounds | The region whose entities we would like to fetch. |
std::vector< std::pair< EntityID, AxisAlignedBounds > > OctreeNode::findEntitiesOverlapping | ( | const Ray & | searchRay | ) | const |
Retrieves all entities that intersect with the ray described by searchRay.
searchRay | The ray whose intersecting objects we would like to fetch. |
|
inline |
Gets the address value for this node.
|
static |
Gets the value of the route section of an address up to some specified depth.
address | The address whose route (up to baseDepth) we want to obtain. |
baseDepth | The depth up to which we want the route for. |
OctreeNode::Address OctreeNode::getBaseRoute | ( | Address | address | ) | const |
Gets the route section of the address up to the current node's depth.
address | The address whose base route is being retrieved. |
|
static |
Gets a bit mask covering the first 3*depth bits based on a given depth value.
baseDepth | The depth up to which we want the route bits for. |
uint8_t OctreeNode::getChildCount | ( | ) | const |
Gets the number of active child octants this octant has.
|
static |
Gets the depth value of a node based on its address.
address | The address of the node. |
OctreeNode::Depth OctreeNode::getDepth | ( | ) | const |
std::shared_ptr< OctreeNode > OctreeNode::getNode | ( | Address | octantAddress | ) |
Gets a descendant of this node (or this node itself) by its address.
octantAddress | The octree address of the node being fetched. |
|
static |
Returns the 3 bits representing just this node's octant value, relative to its own parent.
address | The address of the node whose octant value we want. |
OctreeNode::Octant OctreeNode::getOctant | ( | ) | const |
Gets the octant value of this node relative to its parent.
|
static |
Gets the octant corresponding to a specific depth within an address.
address | The address in which the octant is present (as part of its route) |
depth | The depth of the octant being retrieved. |
std::shared_ptr< OctreeNode > OctreeNode::getSmallestNodeContaining | ( | const AxisAlignedBounds & | entityWorldBounds | ) |
Gets the node whose region just encompasses the bounds provided as input.
The region of the node retrieved is such that any sub-region would at most overlap, but not enclose, the argument bounds.
entityWorldBounds | The bounds which the node retrieved should just envelop. |
|
inline |
Retrieves the AABB representing the region this node covers.
|
static |
Adds root-address' route to address' route.
The depth of the root address is added to the old address (the first argument) in order to produce that node or object's new address.
This is used when the octree has grown to enclose a larger region, and its previous nodes must be recomputed relative to the new root of the octree.
address | The (previous) address of an octant or object. |
rootAddress | The address from the new root of the octree to the old root (or its leaf-most ancestor). |
|
static |
Expands an octree such that it encloses a previously unmapped region, and creates a node to be used as the new root node for the octree.
oldRoot | The root node prior to the addition of an object falling outside its bounds. |
regionToCover | The region enclosing both the old octree as well as any new objects added falling outside of it. |
OctreeNode::Address OctreeNode::insertEntity | ( | EntityID | entityID, |
const AxisAlignedBounds & | entityWorldBounds ) |
Adds an entity to this node or its subtree, per its configuration and the bounds of the object.
entityID | The ID of the object being added. |
entityWorldBounds | The AABB of the entity. |
|
static |
Prepends the address of a child octant to the address of its parent in order to make the child's address.
childOctant | The octant of the parent that the child will represent. |
parentAddress | The (presumably valid) address of the parent. |
std::shared_ptr< OctreeNode > OctreeNode::nextNodeInAddress | ( | Address | octantAddress | ) |
Gets the child node corresponding to the next node in the argument's route section relative to the this node.
octantAddress | The address of the node being looked for. |
OctreeNode::Octant OctreeNode::nextOctant | ( | Address | address | ) | const |
Fetches the octant of the next node in the route section of the argument address.
address | The address to a node or an entity contained by it. |
std::shared_ptr< OctreeNode > OctreeNode::removeEntity | ( | EntityID | entityID, |
Address | entityAddressHint = kNoAddress ) |
Removes an entity situated at a node at some address (or on a descendant node).
entityID | The ID of the entity being removevd. |
entityAddressHint | The address of the node (or that node's ancestor) at which the entity is present. |
Tests whether two nodes are present on the same branch of an octree (or in other words, whether one is the descendant or ancestor of the other).
one | The address of the first node. |
two | The address of the second node. |
true | Both addresses correspond to nodes or objects on the same branch of the octree; |
false | The addresses diverge, and are not on the same branch of the octree; |
|
static |
Shrinks an address according to the depth removed.
This is used when, after the removal of an object, octree nodes higher up in the tree are no longer required. A node that was previously a descendant node is promoted to the root node of the octree, and all addresses are changed accordingly.
address | The (previous) address of a node or object, now being shrunk. |
depthRemoved | The depth being removed from the address. |
|
static |
Maps an octant to its corresponding growth direction.
The growth-directions are the directions in which each dimension of this octant would need to be doubled in order to convert it into its own parent region, per its octant value.
This method isn't really used, but is present for symmetry with ToOctant()
octant | The octant being converted into a "growth direction". |
|
static |
Converts a growth direction to its corresponding octant.
The growth direction tells you in which direction an octant's dimensions should be doubled in order to become its parent. Conversely, the direction of the subdivision of the enlarged region gives you the octant value for the original sub-region.
This is mainly used when the area to be encapsulated by the octree has expanded, say when an object is added which is outside of the Octree's currently enclosed region.
Once all the growth steps (a series of growth directions from the old root of the octree) have been computed, this operation produces the octant value for the node corresponding to each step.
growthDirection | The direction in which a smaller node was doubled in order to produce the larget one. |
|
staticconstexpr |
(Computed) The number of bits by which to shift the address right in order to retrieve the depth value of the node.
|
staticconstexpr |
The total depth representable given the value range of the depth-section of the address, and the space available in the route-section.
|
private |
An array of up to 8 child nodes maintained by this node, where each index corresponds to one possible value of an Octant.