Oolite 1.91.0.7645-241119-222d325
Loading...
Searching...
No Matches
OOOctreeBuilder Class Reference

#include <Octree.h>

+ Inheritance diagram for OOOctreeBuilder:
+ Collaboration diagram for OOOctreeBuilder:

Classes

struct  OOOctreeBuildState
 

Instance Methods

(Octree *) - buildOctreeWithRadius:
 
(void) - writeSolid
 
(void) - writeEmpty
 
(void) - beginInnerNode
 
(void) - endInnerNode
 
(OOINLINE struct OOOctreeBuildState *) - State [implementation]
 
(OOINLINE void) - SetNode [implementation]
 
(OOINLINE void) - InsertNode [implementation]
 
(id) - init [implementation]
 
(void) - dealloc [implementation]
 
(BOOL) - suppressClangStuff [implementation]
 

Class Methods

(static void) + SetNode_slow [implementation]
 

Private Attributes

int_octree
 
uint_fast32_t _nodeCount
 
uint_fast32_t _capacity
 
struct OOOctreeBuilder::OOOctreeBuildState _stateStack [kMaxOctreeDepth+1]
 
uint_fast8_t _level
 

Detailed Description

Definition at line 92 of file Octree.h.

Method Documentation

◆ beginInnerNode

- (void) beginInnerNode

Definition at line 816 of file Octree.m.

892{
893 NSAssert(_level < kMaxOctreeDepth, @"Attempt to build octree exceeding maximum depth.");
894
895 // Insert relative offset to next free space.
896 uint32_t newInsertionPoint = _nodeCount;
897 InsertNode(self, (int)_nodeCount - State(self)->insertionPoint);
898
899 /*
900 Leave space for eight nodes.
901
902 NOTE: this may leave memory uninitialized or leave _nodeCount pointing
903 past the end of the buffer. A valid sequence of eight child insertions
904 will fix both these problems by writing to all of the new slots.
905 */
906 _nodeCount += 8;
907
908 // Push state and set up new "stack frame".
909 _level++;
910 State(self)->insertionPoint = newInsertionPoint;
911 State(self)->remaining = 8;
912}
@ kMaxOctreeDepth
Definition Octree.h:88
uint_fast32_t _nodeCount
Definition Octree.h:96
OOINLINE struct OOOctreeBuildState * State(OOOctreeBuilder *self)
Definition Octree.m:794
uint_fast8_t _level
Definition Octree.h:102
OOINLINE void InsertNode(OOOctreeBuilder *self, int value)
Definition Octree.m:816

Referenced by BuildSubOctree().

+ Here is the caller graph for this function:

◆ buildOctreeWithRadius:

- (Octree *) buildOctreeWithRadius: (GLfloat) radius

Definition at line 816 of file Octree.m.

856 :(GLfloat)radius
857{
858 NSAssert(State(self)->remaining == 0 && _level == 0, @"Attempt to produce octree from an octree builder in an incomplete state.");
859
860 size_t dataSize = _nodeCount * sizeof *_octree;
861 int *resized = realloc(_octree, dataSize);
862 if (resized == NULL) resized = _octree;
863
864 /* Hand over the bytes to the data object, which will be used directly by
865 the Octree.
866 */
867 NSData *data = [NSData dataWithBytesNoCopy:resized
868 length:dataSize
869 freeWhenDone:YES];
870
871 _octree = NULL;
872 _nodeCount = 0;
873 _capacity = 0;
874
875 return [[[Octree alloc] initWithData:data radius:radius] autorelease];
876}
uint_fast32_t _capacity
Definition Octree.h:96
int * _octree
Definition Octree.h:95

◆ dealloc

- (void) dealloc
implementation

Definition at line 816 of file Octree.m.

849{
850 free(_octree);
851
852 [super dealloc];
853}

◆ endInnerNode

- (void) endInnerNode

Definition at line 816 of file Octree.m.

916{
917 NSAssert(State(self)->remaining == 0, @"Attempt to end an inner octree node with fewer than eight children.");
918 NSAssert1(_level > 0, @"Unbalanced call to %s", __FUNCTION__);
919
920 _level--;
921
922 /*
923 Check if the last eight nodes are solid. If so, we just inserted an
924 entirely solid subtree and can fold it into a single solid node. An
925 entirely solid subtree will always use the last eight nodes (any solid
926 subtrees within a child node will have been folded already), so this
927 simple approach to folding will produce an optimal result.
928
929 We could do the same for empty nodes, but OOMeshToOctreeConverter will
930 never recurse into an empty subtree.
931 */
932
933 NSAssert(_nodeCount > 8, @"After ending an inner node, there must be at least eight nodes in buffer.");
934 for (uint_fast32_t node = _nodeCount - 8; node < _nodeCount; node++)
935 {
936 if (_octree[node] != -1) return;
937 }
938
939 // If we got here, subtree is solid; fold it into a solid node.
940 _octree[State(self)->insertionPoint - 1] = -1;
941 _nodeCount -= 8;
942}

Referenced by BuildSubOctree().

+ Here is the caller graph for this function:

◆ init

- (id) init
implementation

Definition at line 816 of file Octree.m.

826{
827 if ((self = [super init]))
828 {
830 _octree = malloc(_capacity * sizeof *_octree);
831 if (_octree == NULL)
832 {
833 [self release];
834 return nil;
835 }
836
837 /*
838 We're initially inserting into the root slot, which must exist and
839 takes a single node.
840 */
841 _nodeCount = 1;
842 State(self)->remaining = 1;
843 }
844 return self;
845}
return nil
@ kMinimumBuilderCapacity
Definition Octree.m:787

◆ InsertNode

- (OOINLINE void) InsertNode (OOOctreeBuilder *) self
(int) value 
implementation

Definition at line 816 of file Octree.m.

817{
818 NSCAssert(State(self)->remaining > 0, @"Attempt to add node to a full parent in octree builder.");
819 State(self)->remaining--;
820
821 SetNode(self, State(self)->insertionPoint++, value);
822}
OOINLINE void SetNode(OOOctreeBuilder *self, uint32_t index, int value)
Definition Octree.m:802

◆ SetNode

- (OOINLINE void) SetNode (OOOctreeBuilder *) self
(uint32_t) index
(int) value 
implementation

Definition at line 802 of file Octree.m.

803{
804 if (index < self->_capacity)
805 {
806 self->_octree[index] = value;
807 }
808 else
809 {
810 SetNode_slow(self, index, value);
811 }
812}
static void SetNode_slow(OOOctreeBuilder *self, uint32_t index, int value) NO_INLINE_FUNC
Definition Octree.m:946

◆ SetNode_slow

+ (static void) SetNode_slow (OOOctreeBuilder *) self
(uint32_t) index
(int) value 
implementation

Definition at line 946 of file Octree.m.

947{
948 uint32_t newCapacity = MAX(self->_capacity * 2, (uint32_t)kMinimumBuilderCapacity);
949 newCapacity = MAX(newCapacity, index + 1);
950
951 int *newBuffer = realloc(self->_octree, newCapacity * sizeof *newBuffer);
952 if (EXPECT_NOT(newBuffer == NULL))
953 {
954 [NSException raise:NSMallocException format:@"Failed to allocate memory for octree."];
955 }
956
957 self->_octree = newBuffer;
958 self->_capacity = newCapacity;
959 self->_octree[index] = value;
960}
#define EXPECT_NOT(x)
#define MAX(A, B)
Definition OOMaths.h:114
return self

References EXPECT_NOT, kMinimumBuilderCapacity, MAX, and self.

◆ State

- (OOINLINE struct OOOctreeBuildState *) State (OOOctreeBuilder *) self
implementation

Definition at line 794 of file Octree.m.

795{
796 return &self->_stateStack[self->_level];
797}

References _level.

◆ suppressClangStuff

- (BOOL) suppressClangStuff
implementation

Definition at line 946 of file Octree.m.

968{
969 return &_stateStack && 0;
970}
struct OOOctreeBuilder::OOOctreeBuildState _stateStack[kMaxOctreeDepth+1]

◆ writeEmpty

- (void) writeEmpty

Definition at line 816 of file Octree.m.

886{
887 InsertNode(self, 0);
888}

Referenced by BuildSubOctree().

+ Here is the caller graph for this function:

◆ writeSolid

- (void) writeSolid

Definition at line 816 of file Octree.m.

880{
881 InsertNode(self, -1);
882}

Referenced by BuildSubOctree().

+ Here is the caller graph for this function:

Member Data Documentation

◆ _capacity

- (uint_fast32_t) _capacity
private

Definition at line 96 of file Octree.h.

◆ _level

- (uint_fast8_t) _level
private

Definition at line 102 of file Octree.h.

Referenced by State.

◆ _nodeCount

- (uint_fast32_t) _nodeCount
private

Definition at line 96 of file Octree.h.

◆ _octree

- (int*) _octree
private

Definition at line 95 of file Octree.h.

◆ _stateStack

- (struct OOOctreeBuildState) OOOctreeBuilder:
private

The documentation for this class was generated from the following files: