box2d_rs/
b2_broad_phase.rs1use crate::b2_collision::*;
2use crate::b2_dynamic_tree::*;
3use crate::b2_math::*;
4use crate::private::collision::b2_broad_phase as private;
5
6use std::cell::RefCell;
7use std::rc::Rc;
8
9#[derive(Default, Clone, Copy, Debug)]
10pub struct B2pair {
11 pub proxy_id_a: i32,
12 pub proxy_id_b: i32,
13}
14
15pub type B2broadPhasePtr<UserDataType> = Rc<RefCell<B2broadPhase<UserDataType>>>;
16
17#[derive(Debug)]
21pub struct B2broadPhase<UserDataType> {
22 pub(crate) m_tree: B2dynamicTree<UserDataType>,
23
24 pub(crate) m_proxy_count: i32,
25
26 pub(crate) m_move_buffer: Vec<i32>,
27 pub(crate) m_move_capacity: i32,
28 pub(crate) m_move_count: i32,
29
30 pub(crate) pairs: B2broadPhasePairs,
31}
32
33#[derive(Debug, Default)]
35pub struct B2broadPhasePairs {
36 pub(crate) m_pair_buffer: Vec<B2pair>,
37 pub(crate) m_pair_capacity: i32,
38 pub(crate) m_pair_count: i32,
39}
40
41pub const E_NULL_PROXY: i32 = -1;
42
43impl<UserDataType: Default + Clone> B2broadPhase<UserDataType> {
44 pub fn new() -> Self {
45 return private::b2_broad_phase_b2_broad_phase();
46 }
47
48 pub fn create_proxy(&mut self, aabb: B2AABB, user_data: &UserDataType) -> i32 {
53 return private::b2_broad_phase_create_proxy(self, aabb, user_data);
54 }
55
56 pub fn destroy_proxy(&mut self, proxy_id: i32) {
58 private::b2_broad_phase_destroy_proxy(self, proxy_id);
59 }
60
61 pub fn move_proxy(&mut self, proxy_id: i32, aabb: B2AABB, displacement: B2vec2) {
64 private::b2_broad_phase_move_proxy(self, proxy_id, aabb, displacement);
65 }
66
67 pub fn touch_proxy(&mut self, proxy_id: i32) {
69 private::b2_broad_phase_touch_proxy(self, proxy_id);
70 }
71
72 pub fn get_fat_aabb(&self, proxy_id: i32) -> B2AABB {
74 return inline::get_fat_aabb(self, proxy_id);
75 }
76
77 pub fn get_user_data(&self, proxy_id: i32) -> Option<UserDataType> {
79 return inline::get_user_data(self, proxy_id);
80 }
81
82 pub fn test_overlap(&self, proxy_id_a: i32, proxy_id_b: i32) -> bool {
84 return inline::test_overlap(self, proxy_id_a, proxy_id_b);
85 }
86
87 pub fn get_proxy_count(&self) -> i32 {
89 return inline::get_proxy_count(self);
90 }
91
92 pub fn update_pairs<CallbackType: AddPairTrait<UserDataType>>(
94 &mut self,
95 callback: &mut CallbackType,
96 ) {
97 inline::update_pairs(self, callback);
98 }
99
100 pub fn query<F: QueryCallback>(&self, callback: F, aabb: B2AABB) {
103 inline::query(self, callback, aabb);
104 }
105
106 pub fn ray_cast<T: RayCastCallback>(&self, callback: T, input: &B2rayCastInput) {
114 inline::ray_cast(self, callback, input);
115 }
116
117 pub fn get_tree_height(&self) -> i32 {
119 return inline::get_tree_height(self);
120 }
121
122 pub fn get_tree_balance(&self) -> i32 {
124 return inline::get_tree_balance(self);
125 }
126
127 pub fn get_tree_quality(&self) -> f32 {
129 return inline::get_tree_quality(self);
130 }
131
132 pub fn shift_origin(&mut self, new_origin: B2vec2) {
136 inline::shift_origin(self, new_origin);
137 }
138
139 pub fn get_tree_mut(&mut self)->&mut B2dynamicTree<UserDataType>{
140 return &mut self.m_tree;
141 }
142
143 pub(crate) fn buffer_move(&mut self, proxy_id: i32) {
144 private::b2_broad_phase_buffer_move(self, proxy_id);
145 }
146
147 pub(crate) fn un_buffer_move(&mut self, proxy_id: i32) {
148 private::b2_broad_phase_un_buffer_move(self, proxy_id);
149 }
150}
151
152pub trait AddPairTrait<UserDataType> {
153 fn add_pair(
154 &mut self,
155 proxy_user_data_a: Option<UserDataType>,
156 proxy_user_data_b: Option<UserDataType>,
157 );
158}
159
160mod inline {
161 use super::*;
162
163 pub fn get_user_data<UserDataType: Default + Clone>(
164 self_: &B2broadPhase<UserDataType>,
165 proxy_id: i32,
166 ) -> Option<UserDataType> {
167 return self_.m_tree.get_user_data(proxy_id);
168 }
169
170 pub fn test_overlap<T: Default + Clone>(
171 self_: &B2broadPhase<T>,
172 proxy_id_a: i32,
173 proxy_id_b: i32,
174 ) -> bool {
175 let aabb_a: B2AABB = self_.m_tree.get_fat_aabb(proxy_id_a);
176 let aabb_b: B2AABB = self_.m_tree.get_fat_aabb(proxy_id_b);
177 return b2_test_overlap(aabb_a, aabb_b);
178 }
179
180 pub fn get_fat_aabb<T: Default + Clone>(self_: &B2broadPhase<T>, proxy_id: i32) -> B2AABB {
181 return self_.m_tree.get_fat_aabb(proxy_id);
182 }
183
184 pub fn get_proxy_count<T: Default + Clone>(self_: &B2broadPhase<T>) -> i32 {
185 return self_.m_proxy_count;
186 }
187
188 pub fn get_tree_height<T: Default + Clone>(self_: &B2broadPhase<T>) -> i32 {
189 return self_.m_tree.get_height();
190 }
191
192 pub fn get_tree_balance<T: Default + Clone>(self_: &B2broadPhase<T>) -> i32 {
193 return self_.m_tree.get_max_balance();
194 }
195
196 pub fn get_tree_quality<T: Default + Clone>(self_: &B2broadPhase<T>) -> f32 {
197 return self_.m_tree.get_area_ration();
198 }
199
200 pub fn update_pairs<T: Default + Clone, CallbackType: AddPairTrait<T>>(
201 self_: &mut B2broadPhase<T>,
202 callback: &mut CallbackType,
203 ) {
204 self_.pairs.m_pair_count=0;
206
207 for i in 0..self_.m_move_count {
209 let m_query_proxy_id = self_.m_move_buffer[i as usize];
210 if m_query_proxy_id == E_NULL_PROXY {
211 continue;
212 }
213
214 let fat_aabb: B2AABB = self_.m_tree.get_fat_aabb(m_query_proxy_id);
217 {
218 let pairs = &mut self_.pairs;
219 let tree = &self_.m_tree;
220 tree.query(|proxy_id:i32|->bool{
222 let moved = tree.was_moved(proxy_id);
223 return private::b2_broad_phase_query_callback(pairs, m_query_proxy_id, proxy_id, moved);
224 }, fat_aabb);
225 }
226 }
227
228 for i in 0..self_.pairs.m_pair_count {
230 let primary_pair: B2pair = self_.pairs.m_pair_buffer[i as usize];
231 let user_data_a = self_.m_tree.get_user_data(primary_pair.proxy_id_a);
232 let user_data_b = self_.m_tree.get_user_data(primary_pair.proxy_id_b);
233
234 callback.add_pair(user_data_a, user_data_b);
235 }
236
237 for i in 0..self_.m_move_count {
239 let proxy_id: i32 = self_.m_move_buffer[i as usize];
240 if proxy_id == E_NULL_PROXY {
241 continue;
242 }
243
244 self_.m_tree.clear_moved(proxy_id);
245 }
246
247 self_.m_move_count = 0;
249 }
250
251 pub fn query<UserDataType: Default + Clone, F: QueryCallback>(
252 self_: &B2broadPhase<UserDataType>,
253 callback: F,
254 aabb: B2AABB,
255 ) {
256 self_.m_tree.query(callback, aabb);
257 }
258
259 pub fn ray_cast<UserDataType: Default + Clone, T: RayCastCallback>(
260 self_: &B2broadPhase<UserDataType>,
261 callback: T,
262 input: &B2rayCastInput,
263 ) {
264 self_.m_tree.ray_cast(callback, input);
265 }
266
267 pub fn shift_origin<UserDataType: Default + Clone>(
268 self_: &mut B2broadPhase<UserDataType>,
269 new_origin: B2vec2,
270 ) {
271 self_.m_tree.shift_origin(new_origin);
272 }
273}