use crate::b2_collision::*;
use crate::b2_dynamic_tree::*;
use crate::b2_math::*;
use crate::private::collision::b2_broad_phase as private;
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Default, Clone, Copy, Debug)]
pub struct B2pair {
pub proxy_id_a: i32,
pub proxy_id_b: i32,
}
pub type B2broadPhasePtr<UserDataType> = Rc<RefCell<B2broadPhase<UserDataType>>>;
#[derive(Debug)]
pub struct B2broadPhase<UserDataType> {
pub(crate) m_tree: B2dynamicTree<UserDataType>,
pub(crate) m_proxy_count: i32,
pub(crate) m_move_buffer: Vec<i32>,
pub(crate) m_move_capacity: i32,
pub(crate) m_move_count: i32,
pub(crate) pairs: B2broadPhasePairs,
}
#[derive(Debug, Default)]
pub struct B2broadPhasePairs {
pub(crate) m_pair_buffer: Vec<B2pair>,
pub(crate) m_pair_capacity: i32,
pub(crate) m_pair_count: i32,
}
pub const E_NULL_PROXY: i32 = -1;
impl<UserDataType: Default + Clone> B2broadPhase<UserDataType> {
pub fn new() -> Self {
return private::b2_broad_phase_b2_broad_phase();
}
pub fn create_proxy(&mut self, aabb: B2AABB, user_data: &UserDataType) -> i32 {
return private::b2_broad_phase_create_proxy(self, aabb, user_data);
}
pub fn destroy_proxy(&mut self, proxy_id: i32) {
private::b2_broad_phase_destroy_proxy(self, proxy_id);
}
pub fn move_proxy(&mut self, proxy_id: i32, aabb: B2AABB, displacement: B2vec2) {
private::b2_broad_phase_move_proxy(self, proxy_id, aabb, displacement);
}
pub fn touch_proxy(&mut self, proxy_id: i32) {
private::b2_broad_phase_touch_proxy(self, proxy_id);
}
pub fn get_fat_aabb(&self, proxy_id: i32) -> B2AABB {
return inline::get_fat_aabb(self, proxy_id);
}
pub fn get_user_data(&self, proxy_id: i32) -> Option<UserDataType> {
return inline::get_user_data(self, proxy_id);
}
pub fn test_overlap(&self, proxy_id_a: i32, proxy_id_b: i32) -> bool {
return inline::test_overlap(self, proxy_id_a, proxy_id_b);
}
pub fn get_proxy_count(&self) -> i32 {
return inline::get_proxy_count(self);
}
pub fn update_pairs<CallbackType: AddPairTrait<UserDataType>>(
&mut self,
callback: &mut CallbackType,
) {
inline::update_pairs(self, callback);
}
pub fn query<F: QueryCallback>(&self, callback: F, aabb: B2AABB) {
inline::query(self, callback, aabb);
}
pub fn ray_cast<T: RayCastCallback>(&self, callback: T, input: &B2rayCastInput) {
inline::ray_cast(self, callback, input);
}
pub fn get_tree_height(&self) -> i32 {
return inline::get_tree_height(self);
}
pub fn get_tree_balance(&self) -> i32 {
return inline::get_tree_balance(self);
}
pub fn get_tree_quality(&self) -> f32 {
return inline::get_tree_quality(self);
}
pub fn shift_origin(&mut self, new_origin: B2vec2) {
inline::shift_origin(self, new_origin);
}
pub fn get_tree_mut(&mut self)->&mut B2dynamicTree<UserDataType>{
return &mut self.m_tree;
}
pub(crate) fn buffer_move(&mut self, proxy_id: i32) {
private::b2_broad_phase_buffer_move(self, proxy_id);
}
pub(crate) fn un_buffer_move(&mut self, proxy_id: i32) {
private::b2_broad_phase_un_buffer_move(self, proxy_id);
}
}
pub trait AddPairTrait<UserDataType> {
fn add_pair(
&mut self,
proxy_user_data_a: Option<UserDataType>,
proxy_user_data_b: Option<UserDataType>,
);
}
mod inline {
use super::*;
pub fn get_user_data<UserDataType: Default + Clone>(
self_: &B2broadPhase<UserDataType>,
proxy_id: i32,
) -> Option<UserDataType> {
return self_.m_tree.get_user_data(proxy_id);
}
pub fn test_overlap<T: Default + Clone>(
self_: &B2broadPhase<T>,
proxy_id_a: i32,
proxy_id_b: i32,
) -> bool {
let aabb_a: B2AABB = self_.m_tree.get_fat_aabb(proxy_id_a);
let aabb_b: B2AABB = self_.m_tree.get_fat_aabb(proxy_id_b);
return b2_test_overlap(aabb_a, aabb_b);
}
pub fn get_fat_aabb<T: Default + Clone>(self_: &B2broadPhase<T>, proxy_id: i32) -> B2AABB {
return self_.m_tree.get_fat_aabb(proxy_id);
}
pub fn get_proxy_count<T: Default + Clone>(self_: &B2broadPhase<T>) -> i32 {
return self_.m_proxy_count;
}
pub fn get_tree_height<T: Default + Clone>(self_: &B2broadPhase<T>) -> i32 {
return self_.m_tree.get_height();
}
pub fn get_tree_balance<T: Default + Clone>(self_: &B2broadPhase<T>) -> i32 {
return self_.m_tree.get_max_balance();
}
pub fn get_tree_quality<T: Default + Clone>(self_: &B2broadPhase<T>) -> f32 {
return self_.m_tree.get_area_ration();
}
pub fn update_pairs<T: Default + Clone, CallbackType: AddPairTrait<T>>(
self_: &mut B2broadPhase<T>,
callback: &mut CallbackType,
) {
self_.pairs.m_pair_count=0;
for i in 0..self_.m_move_count {
let m_query_proxy_id = self_.m_move_buffer[i as usize];
if m_query_proxy_id == E_NULL_PROXY {
continue;
}
let fat_aabb: B2AABB = self_.m_tree.get_fat_aabb(m_query_proxy_id);
{
let pairs = &mut self_.pairs;
let tree = &self_.m_tree;
tree.query(|proxy_id:i32|->bool{
let moved = tree.was_moved(proxy_id);
return private::b2_broad_phase_query_callback(pairs, m_query_proxy_id, proxy_id, moved);
}, fat_aabb);
}
}
for i in 0..self_.pairs.m_pair_count {
let primary_pair: B2pair = self_.pairs.m_pair_buffer[i as usize];
let user_data_a = self_.m_tree.get_user_data(primary_pair.proxy_id_a);
let user_data_b = self_.m_tree.get_user_data(primary_pair.proxy_id_b);
callback.add_pair(user_data_a, user_data_b);
}
for i in 0..self_.m_move_count {
let proxy_id: i32 = self_.m_move_buffer[i as usize];
if proxy_id == E_NULL_PROXY {
continue;
}
self_.m_tree.clear_moved(proxy_id);
}
self_.m_move_count = 0;
}
pub fn query<UserDataType: Default + Clone, F: QueryCallback>(
self_: &B2broadPhase<UserDataType>,
callback: F,
aabb: B2AABB,
) {
self_.m_tree.query(callback, aabb);
}
pub fn ray_cast<UserDataType: Default + Clone, T: RayCastCallback>(
self_: &B2broadPhase<UserDataType>,
callback: T,
input: &B2rayCastInput,
) {
self_.m_tree.ray_cast(callback, input);
}
pub fn shift_origin<UserDataType: Default + Clone>(
self_: &mut B2broadPhase<UserDataType>,
new_origin: B2vec2,
) {
self_.m_tree.shift_origin(new_origin);
}
}