1 #include "synchronized_detail_octree.h"
9 namespace Synchronized {
24 assert( logSize <= m_height );
26 assert( ( coordinates[ 0 ] & ( ( 1u << logSize ) - 1 ) ) == 0 );
27 assert( ( coordinates[ 1 ] & ( ( 1u << logSize ) - 1 ) ) == 0 );
28 assert( ( coordinates[ 2 ] & ( ( 1u << logSize ) - 1 ) ) == 0 );
30 assert( ( coordinates[ 0 ] & ~( ( 1u << m_height ) - 1 ) ) == 0 );
31 assert( ( coordinates[ 1 ] & ~( ( 1u << m_height ) - 1 ) ) == 0 );
32 assert( ( coordinates[ 2 ] & ~( ( 1u << m_height ) - 1 ) ) == 0 );
35 m_root->FindInsert( coordinates, logSize, m_height );
38 m_root.reset(
new Node );
39 m_root->Insert( coordinates, logSize, m_height );
48 if ( m_root && ( logSize <= m_height ) )
49 success = m_root->Erase( coordinates, m_root, logSize, m_height );
65 unsigned int const Octree::Node::CountLeaves()
const {
67 unsigned int result = 0;
68 for (
unsigned int ii = 0; ii < 8; ++ii )
69 if ( m_children[ ii ] )
70 result += m_children[ ii ]->CountLeaves();
80 bool const Octree::Node::FindInsert(
82 unsigned int const logSize,
83 unsigned int const height
88 assert( logSize <= height );
89 unsigned int children = 0;
90 for (
unsigned int ii = 0; ii < 8; ++ii )
91 if ( m_children[ ii ] )
96 if ( logSize == height ) {
98 for (
unsigned int ii = 0; ii < 8; ++ii )
99 if ( m_children[ ii ] )
100 m_children[ ii ].reset();
104 else if ( logSize < height ) {
106 unsigned int index = 0;
107 if ( coordinates[ 0 ] & ( 1u << ( height - 1 ) ) )
109 if ( coordinates[ 1 ] & ( 1u << ( height - 1 ) ) )
111 if ( coordinates[ 2 ] & ( 1u << ( height - 1 ) ) )
115 if ( ! m_children[ index ] ) {
117 m_children[ index ].reset(
new Node );
118 filled = m_children[ index ]->Insert( coordinates, logSize, height - 1 );
122 filled = m_children[ index ]->FindInsert( coordinates, logSize, height - 1 );
124 if ( filled && ( children == 8 ) ) {
126 bool grandchildren =
false;
127 for (
unsigned int ii = 0; ( ! grandchildren ) && ( ii < 8 ); ++ii )
129 for (
unsigned int jj = 0; ( ! grandchildren ) && ( jj < 8 ); ++jj )
130 grandchildren |= static_cast< bool >( m_children[ ii ]->m_children[ jj ] );
132 if ( ! grandchildren ) {
134 for (
unsigned int ii = 0; ii < 8; ++ii )
135 m_children[ ii ].reset();
147 bool const Octree::Node::Insert(
149 unsigned int const logSize,
150 unsigned int const height
155 assert( logSize <= height );
156 if ( logSize < height ) {
158 unsigned int index = 0;
159 if ( coordinates[ 0 ] & ( 1u << ( height - 1 ) ) )
161 if ( coordinates[ 1 ] & ( 1u << ( height - 1 ) ) )
163 if ( coordinates[ 2 ] & ( 1u << ( height - 1 ) ) )
166 assert( ! m_children[ index ] );
167 m_children[ index ].reset(
new Node );
168 m_children[ index ]->Insert( coordinates, logSize, height - 1 );
177 bool const Octree::Node::Erase(
179 std::unique_ptr< Node >& owner,
180 unsigned int const logSize,
181 unsigned int const height
186 assert( logSize <= height );
187 unsigned int children = 0;
188 for (
unsigned int ii = 0; ii < 8; ++ii )
189 if ( m_children[ ii ] )
192 if ( logSize == height ) {
194 if ( children == 0 ) {
200 else if ( logSize < height ) {
202 if ( children == 0 ) {
204 if ( logSize + 1 == height ) {
206 for (
unsigned int ii = 1; ii < 8; ++ii )
207 m_children[ ii ].reset(
new Node );
211 for (
unsigned int ii = 0; ii < 8; ++ii )
212 m_children[ ii ].reset(
new Node );
214 result = m_children[ 0 ]->Erase( coordinates, m_children[ 0 ], logSize, height - 1 );
222 for (
unsigned int ii = 0; ii < 8; ++ii ) {
224 if ( m_children[ ii ] ) {
226 if ( m_children[ ii ]->Erase( coordinates, m_children[ ii ], logSize, height - 1 ) ) {
228 if ( ! m_children[ ii ] )
232 coordinates[ 0 ] |= ( 1u << ( height - 1 ) );
234 coordinates[ 1 ] |= ( 1u << ( height - 1 ) );
236 coordinates[ 2 ] |= ( 1u << ( height - 1 ) );