use std::mem;
use std::ptr;
use std::ops::{Deref, DerefMut};
use wrap::*;
use common::math::Vec2;
use collision::{AABB, RayCastInput, RayCastOutput};
use collision::shapes::{MassData, ShapeType, UnknownShape};
use dynamics::world::BodyHandle;
use dynamics::body::FixtureHandle;
use user_data::{UserDataTypes, UserData, RawUserData, RawUserDataMut, InternalUserData};
#[repr(C)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct Filter {
pub category_bits: u16,
pub mask_bits: u16,
pub group_index: i16,
}
impl Filter {
pub fn new() -> Filter {
Filter {
category_bits: 0x0001,
mask_bits: 0xFFFF,
group_index: 0,
}
}
}
#[repr(C)]
#[derive(Clone)]
pub struct FixtureDef {
#[doc(hidden)]
pub shape: *const ffi::Shape,
#[doc(hidden)]
pub user_data: ffi::Any,
pub friction: f32,
pub restitution: f32,
pub density: f32,
pub is_sensor: bool,
pub filter: Filter,
}
impl FixtureDef {
pub fn new() -> FixtureDef {
FixtureDef {
shape: ptr::null(), user_data: ptr::null_mut(),
friction: 0.2,
restitution: 0.,
density: 0.,
is_sensor: false,
filter: Filter::new(),
}
}
}
pub struct MetaFixture<U: UserDataTypes> {
fixture: Fixture,
user_data: Box<InternalUserData<Fixture, U::FixtureData>>,
}
impl<U: UserDataTypes> MetaFixture<U> {
#[doc(hidden)]
pub unsafe fn new(ptr: *mut ffi::Fixture,
handle: FixtureHandle,
custom: U::FixtureData)
-> Self {
let mut f = MetaFixture {
fixture: Fixture::from_ffi(ptr),
user_data: Box::new(InternalUserData {
handle: handle,
custom: custom,
}),
};
f.mut_ptr().set_internal_user_data(&mut *f.user_data);
f
}
}
impl<U: UserDataTypes> UserData<U::FixtureData> for MetaFixture<U> {
fn user_data(&self) -> &U::FixtureData {
&self.user_data.custom
}
fn user_data_mut(&mut self) -> &mut U::FixtureData {
&mut self.user_data.custom
}
}
impl<U: UserDataTypes> Deref for MetaFixture<U> {
type Target = Fixture;
fn deref(&self) -> &Fixture {
&self.fixture
}
}
impl<U: UserDataTypes> DerefMut for MetaFixture<U> {
fn deref_mut(&mut self) -> &mut Fixture {
&mut self.fixture
}
}
wrap! { ffi::Fixture => pub Fixture }
impl Fixture {
pub fn handle(&self) -> FixtureHandle {
unsafe { self.ptr().handle() }
}
pub fn shape_type(&self) -> ShapeType {
unsafe { ffi::Fixture_get_type(self.ptr()) }
}
pub fn is_sensor(&self) -> bool {
unsafe { ffi::Fixture_is_sensor(self.ptr()) }
}
pub fn filter_data<'a>(&'a self) -> &'a Filter {
unsafe {
&*ffi::Fixture_get_filter_data(self.ptr()) }
}
pub fn body(&self) -> BodyHandle {
unsafe { ffi::Fixture_get_body_const(self.ptr()).handle() }
}
pub fn test_point(&self, point: &Vec2) -> bool {
unsafe { ffi::Fixture_test_point(self.ptr(), point) }
}
pub fn ray_cast(&self, input: &RayCastInput, child_index: i32) -> RayCastOutput {
unsafe {
let mut output = mem::zeroed();
ffi::Fixture_ray_cast(self.ptr(), &mut output, input, child_index);
output
}
}
pub fn mass_data(&self) -> MassData {
unsafe {
let mut data = mem::zeroed();
ffi::Fixture_get_mass_data(self.ptr(), &mut data);
data
}
}
pub fn density(&self) -> f32 {
unsafe { ffi::Fixture_get_density(self.ptr()) }
}
pub fn friction(&self) -> f32 {
unsafe { ffi::Fixture_get_friction(self.ptr()) }
}
pub fn restitution(&self) -> f32 {
unsafe { ffi::Fixture_get_restitution(self.ptr()) }
}
pub fn aabb<'a>(&'a self, child_index: i32) -> &'a AABB {
unsafe {
&*ffi::Fixture_get_aabb(self.ptr(), child_index) }
}
pub fn shape_mut<'a>(&'a mut self) -> WrappedRefMut<'a, UnknownShape> {
unsafe {
WrappedRefMut::new(UnknownShape::from_ffi(ffi::Fixture_get_shape(self.mut_ptr())))
}
}
pub fn shape<'a>(&'a self) -> WrappedRef<'a, UnknownShape> {
unsafe {
WrappedRef::new(UnknownShape::from_ffi(
ffi::Fixture_get_shape_const(self.ptr()) as *mut ffi::Shape
))
}
}
pub fn set_sensor(&mut self, flag: bool) {
unsafe { ffi::Fixture_set_sensor(self.mut_ptr(), flag) }
}
pub fn set_filter_data(&mut self, filter: &Filter) {
unsafe { ffi::Fixture_set_filter_data(self.mut_ptr(), filter) }
}
pub fn refilter(&mut self) {
unsafe { ffi::Fixture_refilter(self.mut_ptr()) }
}
pub fn set_density(&mut self, density: f32) {
unsafe { ffi::Fixture_set_density(self.mut_ptr(), density) }
}
pub fn set_friction(&mut self, friction: f32) {
unsafe { ffi::Fixture_set_friction(self.mut_ptr(), friction) }
}
pub fn set_restitution(&mut self, restitution: f32) {
unsafe { ffi::Fixture_set_restitution(self.mut_ptr(), restitution) }
}
pub fn dump(&mut self, child_count: i32) {
unsafe { ffi::Fixture_dump(self.mut_ptr(), child_count) }
}
}
#[doc(hidden)]
pub mod ffi {
pub use ffi::Any;
pub use collision::shapes::ffi::Shape;
pub use dynamics::body::ffi::Body;
use common::math::Vec2;
use collision::{AABB, RayCastInput, RayCastOutput};
use collision::shapes::{MassData, ShapeType};
use super::Filter;
pub enum Fixture {}
extern "C" {
pub fn Fixture_get_type(slf: *const Fixture) -> ShapeType;
pub fn Fixture_get_shape(slf: *mut Fixture) -> *mut Shape;
pub fn Fixture_get_shape_const(slf: *const Fixture) -> *const Shape;
pub fn Fixture_set_sensor(slf: *mut Fixture, flag: bool);
pub fn Fixture_is_sensor(slf: *const Fixture) -> bool;
pub fn Fixture_set_filter_data(slf: *mut Fixture, filter: *const Filter);
pub fn Fixture_get_filter_data(slf: *const Fixture) -> *const Filter;
pub fn Fixture_refilter(slf: *mut Fixture);
pub fn Fixture_get_body(slf: *mut Fixture) -> *mut Body;
pub fn Fixture_get_body_const(slf: *const Fixture) -> *const Body;
pub fn Fixture_test_point(slf: *const Fixture, p: *const Vec2) -> bool;
pub fn Fixture_ray_cast(slf: *const Fixture,
output: *mut RayCastOutput,
input: *const RayCastInput,
child_index: i32)
-> bool;
pub fn Fixture_get_mass_data(slf: *const Fixture, data: *mut MassData);
pub fn Fixture_set_density(slf: *mut Fixture, density: f32);
pub fn Fixture_get_density(slf: *const Fixture) -> f32;
pub fn Fixture_get_friction(slf: *const Fixture) -> f32;
pub fn Fixture_set_friction(slf: *mut Fixture, friction: f32);
pub fn Fixture_get_restitution(slf: *const Fixture) -> f32;
pub fn Fixture_set_restitution(slf: *mut Fixture, restitution: f32);
pub fn Fixture_get_aabb(slf: *const Fixture, child_id: i32) -> *const AABB;
pub fn Fixture_dump(slf: *mut Fixture, body_id: i32);
}
}