💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

455 lines
11 KiB

  1. /*
  2. * Copyright (C) 2020 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_OCTREE_HPP
  20. #define ANTKEEPER_OCTREE_HPP
  21. #include <cstdint>
  22. #include <limits>
  23. #include <type_traits>
  24. #include <unordered_set>
  25. #include <stack>
  26. /**
  27. * A general purpose (hashed) linear octree. Nodes are integer identifiers and no other data is stored in the octree.
  28. *
  29. * @tparam T Integer node type. Must be 16-bit, 32-bit, or 64-bit.
  30. *
  31. * @see http://codervil.blogspot.com/2015/10/octree-node-identifiers.html
  32. * @see https://geidav.wordpress.com/2014/08/18/advanced-octrees-2-node-representations/
  33. */
  34. template <class T>
  35. class octree
  36. {
  37. private:
  38. /// Compile-time calculation of the minimum bits required to represent `n` state changes.
  39. static constexpr T ceil_log2(T n);
  40. public:
  41. static_assert(std::is_integral<T>::value, "Node type must be integral.");
  42. static_assert(sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Node type must be 16-bit, 32-bit, or 64-bit.");
  43. /// Maximum octree depth
  44. static constexpr T max_depth = (sizeof(T) == 2) ? 3 : (sizeof(T) == 4) ? 8 : 18;
  45. /// Number of bits in the node type
  46. static constexpr T node_bits = sizeof(T) * 8;
  47. /// Number of bits used to encode the depth of a node.
  48. static constexpr T depth_bits = ceil_log2(max_depth + 1);
  49. /// Number of bits used to encode the Morton code location a node.
  50. static constexpr T location_bits = (max_depth + 1) * 3;
  51. /// Integer node type.
  52. typedef T node_type;
  53. /// Root node which is always guaranteed to exist.
  54. static constexpr node_type root = 0;
  55. /**
  56. * Accesses nodes in their internal hashmap order.
  57. */
  58. struct unordered_iterator
  59. {
  60. inline unordered_iterator(const unordered_iterator& other): set_iterator(other.set_iterator) {};
  61. inline unordered_iterator& operator=(const unordered_iterator& other) { this->set_iterator = other.set_iterator; return *this; };
  62. inline unordered_iterator& operator++() { ++(this->set_iterator); return *this; };
  63. inline unordered_iterator& operator--() { --(this->set_iterator); return *this; };
  64. inline bool operator==(const unordered_iterator& other) const { return this->set_iterator == other.set_iterator; };
  65. inline bool operator!=(const unordered_iterator& other) const { return this->set_iterator != other.set_iterator; };
  66. inline const node_type& operator*() const { return *this->set_iterator; };
  67. private:
  68. friend class octree;
  69. inline explicit unordered_iterator(const typename std::unordered_set<node_type>::const_iterator& it): set_iterator(it) {};
  70. typename std::unordered_set<node_type>::const_iterator set_iterator;
  71. };
  72. /**
  73. * Accesses nodes in z-order. TODO: I think this can be done without a stack.
  74. */
  75. struct iterator
  76. {
  77. inline iterator(const iterator& other): octree(other.octree), stack(other.stack) {};
  78. inline iterator& operator=(const iterator& other) { this->octree = other.octree; this->stack = other.stack; return *this; };
  79. iterator& operator++();
  80. inline bool operator==(const iterator& other) const { return **this == *other; };
  81. inline bool operator!=(const iterator& other) const { return **this != *other; };
  82. inline const node_type& operator*() const { return stack.top(); };
  83. private:
  84. friend class octree;
  85. inline explicit iterator(const octree* octree, node_type node): octree(octree), stack({node}) {};
  86. const octree* octree;
  87. std::stack<node_type> stack;
  88. };
  89. /**
  90. * Returns the depth of a node.
  91. *
  92. * @param node Node.
  93. * @return Depth of the node.
  94. */
  95. static T depth(node_type node);
  96. /**
  97. * Returns the Morton code location of a node.
  98. *
  99. * @param node Node.
  100. * @return Morton code location of the node.
  101. */
  102. static T location(node_type node);
  103. /**
  104. * Returns the node at the given depth and location.
  105. *
  106. * @param depth Node depth.
  107. * @param location Node Morton code location.
  108. */
  109. static node_type node(T depth, T location);
  110. /**
  111. * Returns the ancestor of a node at the specified depth.
  112. *
  113. * @param node Node whose ancestor will be located.
  114. * @param depth Absolute depth of the ancestors.
  115. * @return Ancestral node.
  116. */
  117. static node_type ancestor(node_type node, T depth);
  118. /**
  119. * Returns the parent of a node.
  120. *
  121. * @param node Node.
  122. * @return Parent node.
  123. */
  124. static node_type parent(node_type node);
  125. /**
  126. * Returns the nth sibling of a node.
  127. *
  128. * @param node Node.
  129. * @param n Offset to next sibling. (Automatically wraps to 0..7)
  130. * @return Next sibling node.
  131. */
  132. static node_type sibling(node_type node, T n);
  133. /**
  134. * Returns the nth child of a node.
  135. *
  136. * @param node Parent node.
  137. * @param n Offset to the nth sibling of the first child node. (Automatically wraps to 0..7)
  138. * @return nth child node.
  139. */
  140. static node_type child(node_type node, T n);
  141. /**
  142. * Calculates the first common ancestor of two nodes.
  143. *
  144. * @param a First node.
  145. * @param b Second node.
  146. * @return First common ancestor of the two nodes.
  147. */
  148. static node_type common_ancestor(node_type a, node_type b);
  149. /// Creates an octree with a single root node.
  150. octree();
  151. /// Returns a z-order iterator to the root node.
  152. iterator begin() const;
  153. /// Returns a z-order iterator indicating the end of a traversal.
  154. iterator end() const;
  155. /// Returns an iterator to the specified node.
  156. iterator find(node_type node) const;
  157. /// Returns an unordered iterator indicating the beginning of a traversal.
  158. unordered_iterator unordered_begin() const;
  159. /// Returns an unordered iterator indicating the end of a traversal.
  160. unordered_iterator unordered_end() const;
  161. /**
  162. * Inserts a node and its siblings into the octree, creating its ancestors as necessary. Note: The root node is persistent and cannot be inserted.
  163. *
  164. * @param node Node to insert.
  165. */
  166. void insert(node_type node);
  167. /**
  168. * Erases a node along with its siblings and descendants. Note: The root node is persistent and cannot be erased.
  169. *
  170. * @param node Node to erase.
  171. */
  172. void erase(node_type node);
  173. /**
  174. * Erases all nodes except the root.
  175. */
  176. void clear();
  177. /// Returns `true` if the node exists in the octree, and `false` otherwise.
  178. bool exists(node_type node) const;
  179. /// Returns `true` if the node has no children, and `false` otherwise.
  180. bool is_leaf(node_type node) const;
  181. /// Returns the number of nodes in the octree.
  182. std::size_t size() const;
  183. private:
  184. /// Compile-time pow()
  185. static constexpr T pow(T x, T exponent);
  186. /// Count leading zeros
  187. static T clz(T x);
  188. std::unordered_set<node_type> nodes;
  189. };
  190. /**
  191. * Octree with a 16-bit node type and a maximum depth of `3`.
  192. */
  193. typedef octree<std::uint16_t> octree16;
  194. /**
  195. * Octree with a 32-bit node type and a maximum depth of `8`.
  196. */
  197. typedef octree<std::uint32_t> octree32;
  198. /**
  199. * Octree with a 64-bit node type and a maximum depth of `18`.
  200. */
  201. typedef octree<std::uint64_t> octree64;
  202. template <typename T>
  203. typename octree<T>::iterator& octree<T>::iterator::operator++()
  204. {
  205. // Get next node from top of stack
  206. node_type node = stack.top();
  207. stack.pop();
  208. // If the node has children
  209. if (!octree->is_leaf(node))
  210. {
  211. // Push first child onto the stack
  212. for (T i = 0; i < 8; ++i)
  213. stack.push(child(node, 7 - i));
  214. }
  215. if (stack.empty())
  216. stack.push(std::numeric_limits<T>::max());
  217. return *this;
  218. }
  219. template <class T>
  220. constexpr T octree<T>::ceil_log2(T n)
  221. {
  222. return (n <= 1) ? 0 : ceil_log2((n + 1) / 2) + 1;
  223. }
  224. template <class T>
  225. inline T octree<T>::depth(node_type node)
  226. {
  227. // Extract depth using a bit mask
  228. constexpr T mask = pow(2, depth_bits) - 1;
  229. return node & mask;
  230. }
  231. template <class T>
  232. inline T octree<T>::location(node_type node)
  233. {
  234. return node >> ((node_bits - 1) - depth(node) * 3);
  235. }
  236. template <class T>
  237. inline typename octree<T>::node_type octree<T>::node(T depth, T location)
  238. {
  239. return (location << ((node_bits - 1) - depth * 3)) | depth;
  240. }
  241. template <class T>
  242. inline typename octree<T>::node_type octree<T>::ancestor(node_type node, T depth)
  243. {
  244. const T mask = std::numeric_limits<T>::max() << ((node_bits - 1) - depth * 3);
  245. return (node & mask) | depth;
  246. }
  247. template <class T>
  248. inline typename octree<T>::node_type octree<T>::parent(node_type node)
  249. {
  250. return ancestor(node, depth(node) - 1);
  251. }
  252. template <class T>
  253. inline typename octree<T>::node_type octree<T>::sibling(node_type node, T n)
  254. {
  255. T depth = octree::depth(node);
  256. T location = node >> ((node_bits - 1) - depth * 3);
  257. return octree::node(depth, (location & (~0b111)) | ((location + n) & 0b111));
  258. }
  259. template <class T>
  260. inline typename octree<T>::node_type octree<T>::child(node_type node, T n)
  261. {
  262. return sibling(node + 1, n);
  263. }
  264. template <class T>
  265. inline typename octree<T>::node_type octree<T>::common_ancestor(node_type a, node_type b)
  266. {
  267. T bits = std::min<T>(depth(a), depth(b)) * 3;
  268. T marker = (T(1) << (node_bits - 1)) >> bits;
  269. T depth = clz((a ^ b) | marker) / 3;
  270. return ancestor(a, depth);
  271. }
  272. template <class T>
  273. inline octree<T>::octree():
  274. nodes({0})
  275. {}
  276. template <class T>
  277. void octree<T>::insert(node_type node)
  278. {
  279. if (exists(node))
  280. return;
  281. // Insert node
  282. nodes.emplace(node);
  283. // Insert siblings
  284. for (T i = 1; i < 8; ++i)
  285. nodes.emplace(sibling(node, i));
  286. // Insert parent as necessary
  287. node_type parent = octree::parent(node);
  288. if (!exists(parent))
  289. insert(parent);
  290. }
  291. template <class T>
  292. void octree<T>::erase(node_type node)
  293. {
  294. // Don't erase the root!
  295. if (node == root)
  296. return;
  297. for (T i = 0; i < 8; ++i)
  298. {
  299. // Erase node
  300. nodes.erase(node);
  301. // Erase descendants
  302. if (!is_leaf(node))
  303. {
  304. for (T j = 0; j < 8; ++j)
  305. erase(child(node, j));
  306. }
  307. // Go to next sibling
  308. if (i < 7)
  309. node = sibling(node, i);
  310. }
  311. }
  312. template <class T>
  313. void octree<T>::clear()
  314. {
  315. nodes = {0};
  316. }
  317. template <class T>
  318. inline bool octree<T>::exists(node_type node) const
  319. {
  320. return (nodes.find(node) != nodes.end());
  321. }
  322. template <class T>
  323. inline bool octree<T>::is_leaf(node_type node) const
  324. {
  325. return !exists(child(node, 0));
  326. }
  327. template <class T>
  328. inline std::size_t octree<T>::size() const
  329. {
  330. return nodes.size();
  331. }
  332. template <class T>
  333. typename octree<T>::iterator octree<T>::begin() const
  334. {
  335. return iterator(this, octree::root);
  336. }
  337. template <class T>
  338. typename octree<T>::iterator octree<T>::end() const
  339. {
  340. return iterator(this, std::numeric_limits<T>::max());
  341. }
  342. template <class T>
  343. typename octree<T>::iterator octree<T>::find(node_type node) const
  344. {
  345. return exists(node) ? iterator(node) : end();
  346. }
  347. template <class T>
  348. typename octree<T>::unordered_iterator octree<T>::unordered_begin() const
  349. {
  350. return unordered_iterator(nodes.begin());
  351. }
  352. template <class T>
  353. typename octree<T>::unordered_iterator octree<T>::unordered_end() const
  354. {
  355. return unordered_iterator(nodes.end());
  356. }
  357. template <class T>
  358. constexpr T octree<T>::pow(T x, T exponent)
  359. {
  360. return (exponent == 0) ? 1 : x * pow(x, exponent - 1);
  361. }
  362. template <class T>
  363. T octree<T>::clz(T x)
  364. {
  365. if (!x)
  366. return sizeof(T) * 8;
  367. #if defined(__GNU__)
  368. return __builtin_clz(x);
  369. #else
  370. T n = 0;
  371. while ((x & (T(1) << (8 * sizeof(x) - 1))) == 0)
  372. {
  373. x <<= 1;
  374. ++n;
  375. }
  376. return n;
  377. #endif
  378. }
  379. #endif // ANTKEEPER_OCTREE_HPP