use boxdd_sys::ffi;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct Vec2 {
pub x: f32,
pub y: f32,
}
#[cfg(feature = "bytemuck")]
unsafe impl bytemuck::Zeroable for Vec2 {}
#[cfg(feature = "bytemuck")]
unsafe impl bytemuck::Pod for Vec2 {}
#[cfg(feature = "bytemuck")]
const _: () = {
assert!(core::mem::size_of::<Vec2>() == 8);
assert!(core::mem::align_of::<Vec2>() == 4);
};
impl Vec2 {
pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
pub const fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
#[inline]
pub const fn from_raw(raw: ffi::b2Vec2) -> Self {
Self { x: raw.x, y: raw.y }
}
#[inline]
pub const fn into_raw(self) -> ffi::b2Vec2 {
ffi::b2Vec2 {
x: self.x,
y: self.y,
}
}
#[inline]
pub fn is_valid(self) -> bool {
unsafe { ffi::b2IsValidVec2(self.into_raw()) }
}
}
impl From<[f32; 2]> for Vec2 {
#[inline]
fn from(a: [f32; 2]) -> Self {
Self { x: a[0], y: a[1] }
}
}
impl From<(f32, f32)> for Vec2 {
#[inline]
fn from(t: (f32, f32)) -> Self {
Self { x: t.0, y: t.1 }
}
}
#[cfg(feature = "mint")]
impl From<mint::Vector2<f32>> for Vec2 {
#[inline]
fn from(v: mint::Vector2<f32>) -> Self {
Self { x: v.x, y: v.y }
}
}
#[cfg(feature = "mint")]
impl From<mint::Point2<f32>> for Vec2 {
#[inline]
fn from(p: mint::Point2<f32>) -> Self {
Self { x: p.x, y: p.y }
}
}
#[cfg(feature = "mint")]
impl From<Vec2> for mint::Vector2<f32> {
#[inline]
fn from(v: Vec2) -> Self {
Self { x: v.x, y: v.y }
}
}
#[cfg(feature = "mint")]
impl From<Vec2> for mint::Point2<f32> {
#[inline]
fn from(v: Vec2) -> Self {
Self { x: v.x, y: v.y }
}
}
#[cfg(feature = "cgmath")]
impl From<cgmath::Vector2<f32>> for Vec2 {
#[inline]
fn from(v: cgmath::Vector2<f32>) -> Self {
Self { x: v.x, y: v.y }
}
}
#[cfg(feature = "cgmath")]
impl From<Vec2> for cgmath::Vector2<f32> {
#[inline]
fn from(v: Vec2) -> Self {
cgmath::Vector2 { x: v.x, y: v.y }
}
}
#[cfg(feature = "cgmath")]
impl From<cgmath::Point2<f32>> for Vec2 {
#[inline]
fn from(p: cgmath::Point2<f32>) -> Self {
Self { x: p.x, y: p.y }
}
}
#[cfg(feature = "cgmath")]
impl From<Vec2> for cgmath::Point2<f32> {
#[inline]
fn from(v: Vec2) -> Self {
cgmath::Point2 { x: v.x, y: v.y }
}
}
#[cfg(feature = "nalgebra")]
impl From<nalgebra::Vector2<f32>> for Vec2 {
#[inline]
fn from(v: nalgebra::Vector2<f32>) -> Self {
Self { x: v.x, y: v.y }
}
}
#[cfg(feature = "nalgebra")]
impl From<Vec2> for nalgebra::Vector2<f32> {
#[inline]
fn from(v: Vec2) -> Self {
nalgebra::Vector2::new(v.x, v.y)
}
}
#[cfg(feature = "nalgebra")]
impl From<nalgebra::Point2<f32>> for Vec2 {
#[inline]
fn from(p: nalgebra::Point2<f32>) -> Self {
Self { x: p.x, y: p.y }
}
}
#[cfg(feature = "nalgebra")]
impl From<Vec2> for nalgebra::Point2<f32> {
#[inline]
fn from(v: Vec2) -> Self {
nalgebra::Point2::new(v.x, v.y)
}
}
#[cfg(feature = "glam")]
impl From<glam::Vec2> for Vec2 {
#[inline]
fn from(v: glam::Vec2) -> Self {
Self { x: v.x, y: v.y }
}
}
#[cfg(feature = "glam")]
impl From<Vec2> for glam::Vec2 {
#[inline]
fn from(v: Vec2) -> Self {
glam::Vec2::new(v.x, v.y)
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct BodyId {
pub index1: i32,
pub world0: u16,
pub generation: u16,
}
impl BodyId {
#[inline]
pub const fn from_raw(raw: ffi::b2BodyId) -> Self {
Self {
index1: raw.index1,
world0: raw.world0,
generation: raw.generation,
}
}
#[inline]
pub const fn into_raw(self) -> ffi::b2BodyId {
ffi::b2BodyId {
index1: self.index1,
world0: self.world0,
generation: self.generation,
}
}
}
const _: () = {
assert!(core::mem::size_of::<BodyId>() == core::mem::size_of::<ffi::b2BodyId>());
assert!(core::mem::align_of::<BodyId>() == core::mem::align_of::<ffi::b2BodyId>());
};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct ShapeId {
pub index1: i32,
pub world0: u16,
pub generation: u16,
}
impl ShapeId {
#[inline]
pub const fn from_raw(raw: ffi::b2ShapeId) -> Self {
Self {
index1: raw.index1,
world0: raw.world0,
generation: raw.generation,
}
}
#[inline]
pub const fn into_raw(self) -> ffi::b2ShapeId {
ffi::b2ShapeId {
index1: self.index1,
world0: self.world0,
generation: self.generation,
}
}
}
const _: () = {
assert!(core::mem::size_of::<ShapeId>() == core::mem::size_of::<ffi::b2ShapeId>());
assert!(core::mem::align_of::<ShapeId>() == core::mem::align_of::<ffi::b2ShapeId>());
};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct JointId {
pub index1: i32,
pub world0: u16,
pub generation: u16,
}
impl JointId {
#[inline]
pub const fn from_raw(raw: ffi::b2JointId) -> Self {
Self {
index1: raw.index1,
world0: raw.world0,
generation: raw.generation,
}
}
#[inline]
pub const fn into_raw(self) -> ffi::b2JointId {
ffi::b2JointId {
index1: self.index1,
world0: self.world0,
generation: self.generation,
}
}
}
const _: () = {
assert!(core::mem::size_of::<JointId>() == core::mem::size_of::<ffi::b2JointId>());
assert!(core::mem::align_of::<JointId>() == core::mem::align_of::<ffi::b2JointId>());
};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct ChainId {
pub index1: i32,
pub world0: u16,
pub generation: u16,
}
impl ChainId {
#[inline]
pub const fn from_raw(raw: ffi::b2ChainId) -> Self {
Self {
index1: raw.index1,
world0: raw.world0,
generation: raw.generation,
}
}
#[inline]
pub const fn into_raw(self) -> ffi::b2ChainId {
ffi::b2ChainId {
index1: self.index1,
world0: self.world0,
generation: self.generation,
}
}
}
const _: () = {
assert!(core::mem::size_of::<ChainId>() == core::mem::size_of::<ffi::b2ChainId>());
assert!(core::mem::align_of::<ChainId>() == core::mem::align_of::<ffi::b2ChainId>());
};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct ContactId {
pub index1: i32,
pub world0: u16,
pub padding: i16,
pub generation: u32,
}
impl ContactId {
#[inline]
pub const fn from_raw(raw: ffi::b2ContactId) -> Self {
Self {
index1: raw.index1,
world0: raw.world0,
padding: raw.padding,
generation: raw.generation,
}
}
#[inline]
pub const fn into_raw(self) -> ffi::b2ContactId {
ffi::b2ContactId {
index1: self.index1,
world0: self.world0,
padding: self.padding,
generation: self.generation,
}
}
}
const _: () = {
assert!(core::mem::size_of::<ContactId>() == core::mem::size_of::<ffi::b2ContactId>());
assert!(core::mem::align_of::<ContactId>() == core::mem::align_of::<ffi::b2ContactId>());
};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct MassData {
pub mass: f32,
pub center: Vec2,
pub rotational_inertia: f32,
}
impl MassData {
#[inline]
pub const fn new(mass: f32, center: Vec2, rotational_inertia: f32) -> Self {
Self {
mass,
center,
rotational_inertia,
}
}
#[inline]
pub fn from_raw(raw: ffi::b2MassData) -> Self {
Self {
mass: raw.mass,
center: Vec2::from_raw(raw.center),
rotational_inertia: raw.rotationalInertia,
}
}
#[inline]
pub fn into_raw(self) -> ffi::b2MassData {
ffi::b2MassData {
mass: self.mass,
center: self.center.into_raw(),
rotationalInertia: self.rotational_inertia,
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub struct MotionLocks {
pub linear_x: bool,
pub linear_y: bool,
pub angular_z: bool,
}
impl MotionLocks {
#[inline]
pub const fn new(linear_x: bool, linear_y: bool, angular_z: bool) -> Self {
Self {
linear_x,
linear_y,
angular_z,
}
}
#[inline]
pub fn from_raw(raw: ffi::b2MotionLocks) -> Self {
Self {
linear_x: raw.linearX,
linear_y: raw.linearY,
angular_z: raw.angularZ,
}
}
#[inline]
pub fn into_raw(self) -> ffi::b2MotionLocks {
ffi::b2MotionLocks {
linearX: self.linear_x,
linearY: self.linear_y,
angularZ: self.angular_z,
}
}
}
pub const MAX_MANIFOLD_POINTS: usize = 2;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct ManifoldPoint {
pub point: Vec2,
pub anchor_a: Vec2,
pub anchor_b: Vec2,
pub separation: f32,
pub normal_impulse: f32,
pub tangent_impulse: f32,
pub total_normal_impulse: f32,
pub normal_velocity: f32,
pub id: u16,
pub persisted: bool,
}
impl ManifoldPoint {
#[inline]
pub fn from_raw(raw: ffi::b2ManifoldPoint) -> Self {
Self {
point: Vec2::from_raw(raw.point),
anchor_a: Vec2::from_raw(raw.anchorA),
anchor_b: Vec2::from_raw(raw.anchorB),
separation: raw.separation,
normal_impulse: raw.normalImpulse,
tangent_impulse: raw.tangentImpulse,
total_normal_impulse: raw.totalNormalImpulse,
normal_velocity: raw.normalVelocity,
id: raw.id,
persisted: raw.persisted,
}
}
#[inline]
pub fn into_raw(self) -> ffi::b2ManifoldPoint {
ffi::b2ManifoldPoint {
point: self.point.into_raw(),
anchorA: self.anchor_a.into_raw(),
anchorB: self.anchor_b.into_raw(),
separation: self.separation,
normalImpulse: self.normal_impulse,
tangentImpulse: self.tangent_impulse,
totalNormalImpulse: self.total_normal_impulse,
normalVelocity: self.normal_velocity,
id: self.id,
persisted: self.persisted,
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct Manifold {
pub normal: Vec2,
pub rolling_impulse: f32,
pub contact_points: [ManifoldPoint; MAX_MANIFOLD_POINTS],
pub point_count: i32,
}
impl Manifold {
#[inline]
pub fn points(&self) -> &[ManifoldPoint] {
let count = self.point_count.clamp(0, MAX_MANIFOLD_POINTS as i32) as usize;
&self.contact_points[..count]
}
#[inline]
pub fn from_raw(raw: ffi::b2Manifold) -> Self {
Self {
normal: Vec2::from_raw(raw.normal),
rolling_impulse: raw.rollingImpulse,
contact_points: raw.points.map(ManifoldPoint::from_raw),
point_count: raw.pointCount.clamp(0, MAX_MANIFOLD_POINTS as i32),
}
}
#[inline]
pub fn into_raw(self) -> ffi::b2Manifold {
ffi::b2Manifold {
normal: self.normal.into_raw(),
rollingImpulse: self.rolling_impulse,
points: self.contact_points.map(ManifoldPoint::into_raw),
pointCount: self.point_count.clamp(0, MAX_MANIFOLD_POINTS as i32),
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct ContactData {
pub contact_id: ContactId,
pub shape_id_a: ShapeId,
pub shape_id_b: ShapeId,
pub manifold: Manifold,
}
impl ContactData {
#[inline]
pub fn from_raw(raw: ffi::b2ContactData) -> Self {
Self {
contact_id: ContactId::from_raw(raw.contactId),
shape_id_a: ShapeId::from_raw(raw.shapeIdA),
shape_id_b: ShapeId::from_raw(raw.shapeIdB),
manifold: Manifold::from_raw(raw.manifold),
}
}
#[inline]
pub fn into_raw(self) -> ffi::b2ContactData {
ffi::b2ContactData {
contactId: self.contact_id.into_raw(),
shapeIdA: self.shape_id_a.into_raw(),
shapeIdB: self.shape_id_b.into_raw(),
manifold: self.manifold.into_raw(),
}
}
}
const _: () = {
assert!(core::mem::size_of::<MassData>() == core::mem::size_of::<ffi::b2MassData>());
assert!(core::mem::align_of::<MassData>() == core::mem::align_of::<ffi::b2MassData>());
assert!(core::mem::size_of::<MotionLocks>() == core::mem::size_of::<ffi::b2MotionLocks>());
assert!(core::mem::align_of::<MotionLocks>() == core::mem::align_of::<ffi::b2MotionLocks>());
assert!(core::mem::size_of::<ManifoldPoint>() == core::mem::size_of::<ffi::b2ManifoldPoint>());
assert!(
core::mem::align_of::<ManifoldPoint>() == core::mem::align_of::<ffi::b2ManifoldPoint>()
);
assert!(core::mem::size_of::<Manifold>() == core::mem::size_of::<ffi::b2Manifold>());
assert!(core::mem::align_of::<Manifold>() == core::mem::align_of::<ffi::b2Manifold>());
assert!(core::mem::size_of::<ContactData>() == core::mem::size_of::<ffi::b2ContactData>());
assert!(core::mem::align_of::<ContactData>() == core::mem::align_of::<ffi::b2ContactData>());
};