1#![feature(clamp)]
2#![feature(core_intrinsics)]
3
4#[macro_use]
5extern crate lazy_static;
6
7use std::intrinsics::ctlz;
8
9pub(in crate) mod geometry;
10pub use self::geometry::{intersects, BoundingBox, Intersection, RotatedRect};
11
12#[derive(Copy, Clone)]
13struct Node<T> {
14 count: u16,
15 item: Option<(u16, T)>,
16}
17
18pub struct Tree<T> {
19 nodes: Vec<Node<T>>,
20 pub width: f32,
21 pub height: f32,
22}
23
24lazy_static! {
25 static ref LEVELS: [u16; 8] = {
26 let mut levels = [0; 8];
27 let mut i: u16 = 0;
28 for j in 1..8 {
29 let k = j - 1;
30 i += (1 << k) * (1 << k);
31 levels[j as usize] = i;
32 }
33
34 levels
35 };
36}
37
38trait BitScan {
39 fn bsr(self) -> Self;
40}
41
42impl BitScan for u8 {
43 fn bsr(self) -> Self {
44 7 - ctlz(self)
45 }
46}
47
48impl From<BoundingBox<f32>> for BoundingBox<u8> {
49 fn from(item: BoundingBox<f32>) -> Self {
50 let clamp = |x: f32| x.clamp(0.0, 255.0);
51 BoundingBox {
52 x0: clamp(item.x0.floor()) as u8,
53 y0: clamp(item.y0.floor()) as u8,
54 x1: clamp(item.x1.ceil()) as u8,
55 y1: clamp(item.y1.ceil()) as u8,
56 }
57 }
58}
59
60impl<T> Tree<T>
61where
62 T: Clone,
63{
64 pub fn new(width: f32, height: f32) -> Tree<T> {
65 let nodes: Vec<Node<T>> = Vec::with_capacity(5);
66
67 Tree {
68 nodes,
69 width,
70 height,
71 }
72 }
73
74 pub fn insert_checked(
75 &mut self,
76 item: T,
77 bbox: &BoundingBox<f32>,
78 check: Option<&Fn(&T, &T) -> bool>,
79 ) -> bool {
80 let inv_w = 256.0 / self.width;
81 let inv_h = 256.0 / self.height;
82
83 let shifted: BoundingBox<u8> = BoundingBox::new(
85 bbox.x0.max(0.0) * inv_w,
86 bbox.y0.max(0.0) * inv_h,
87 bbox.x1.min(self.width) * inv_w,
88 bbox.y1.min(self.height) * inv_h,
89 )
90 .into();
91
92 let x = shifted.x0 ^ shifted.x1;
96 let x = if x == 0 { 7 } else { 7 - x.bsr() };
97
98 let y = shifted.y0 ^ shifted.y1;
99 let y = if y == 0 { 7 } else { 7 - y.bsr() };
100
101 let level = x.min(y);
102
103 for i in (0..level + 1).rev() {
104 let length = {
105 let base = LEVELS[level as usize];
106 let index = if i == 0 {
107 base
108 } else {
109 let s = 1 << i;
110 let k: u32 = 8_u32 - i as u32;
111 let x = shifted.x0 as u8 >> k;
112 let y = shifted.y0 as u8 >> k;
113 base + y as u16 * s + x as u16
114 };
115 self.resize(index as usize)
116 };
117
118 let index = LEVELS[i as usize];
119 let mut k: usize = index as usize;
120 let count = self.nodes[k].count;
121 let mut remaining = count;
122 let mut slot = None;
123
124 for _ in 0..length {
125 match &self.nodes[k].item {
126 Some((other_index, other_item)) => {
127 if *other_index == index {
128 if let Some(f) = &check {
129 if f(&item, other_item) {
130 return false;
131 }
132 }
133
134 remaining -= 1;
135 }
136 }
137 None => {
138 if slot.is_none() {
139 slot = Some(k);
140 }
141
142 if remaining == 0 {
143 break;
144 }
145
146 ()
147 }
148 }
149
150 k += 1;
152 if k == length {
153 k = 0;
154 }
155 }
156
157 if i == 0 || check.is_none() {
158 let j = match slot {
159 Some(j) => j,
160 None => {
161 &self.nodes.push(Node {
162 count: 0,
163 item: None,
164 });
165 length
166 }
167 };
168
169 self.nodes[j].item = Some((index, item));
170 self.nodes[index as usize].count = count + 1;
171
172 return true;
173 }
174 }
175
176 false
177 }
178
179 pub fn insert_unless_intersecting(
180 &mut self,
181 item: T,
182 bbox: &BoundingBox<f32>,
183 ) -> bool
184 where
185 T: Intersection,
186 {
187 self.insert_checked(item, bbox, Some(&intersects))
188 }
189
190 pub fn insert(&mut self, item: T, bbox: &BoundingBox<f32>) {
191 self.insert_checked(item, bbox, None);
192 }
193
194 fn resize(&mut self, length: usize) -> usize {
195 let cur_length = self.nodes.len();
196 if cur_length > length {
197 return cur_length;
198 }
199
200 let mut new_length = 0;
201 for i in 0..8 {
202 let term = 2_usize.pow(2 * i);
203 new_length += term;
204 if new_length > length {
205 &self.nodes.resize(
206 new_length,
207 Node {
208 count: 0,
209 item: None,
210 },
211 );
212 break;
213 }
214 }
215
216 return new_length;
217 }
218}