use std::ffi::c_void; use num_traits::FromPrimitive; use crate::{ AsPxBase, PxBaseRef, PxGeometry, PxGeometryHolder, PxGeometryType, PxMaterial, PxPhysicsRef, PxRigidActorRef, PxTransform, PxUserData, }; bitflags! { pub struct PxShapeFlag: u8 { const SCENE_QUERY_SHAPE = physx_sys::PxShapeFlag::eSCENE_QUERY_SHAPE as u8; const SIMULATION_SHAPE = physx_sys::PxShapeFlag::eSIMULATION_SHAPE as u8; const TRIGGER_SHAPE = physx_sys::PxShapeFlag::eTRIGGER_SHAPE as u8; const VISUALIZATION = physx_sys::PxShapeFlag::eVISUALIZATION as u8; } } impl Default for PxShapeFlag { fn default() -> Self { Self::VISUALIZATION | Self::SIMULATION_SHAPE } } #[derive(Debug, PartialEq, Eq, Hash)] pub struct PxShape(pub *mut physx_sys::PxShape, pub usize); impl PxShape { pub fn new( physics: PxPhysicsRef, geometry: &dyn PxGeometry, materials: &[&PxMaterial], is_exclusive: Option, shape_flags: Option, ) -> Self { let mats = materials .iter() .map(|x| x.0) .collect::>(); Self( unsafe { physx_sys::PxPhysics_createShape_mut_1( physics.0, geometry.as_geometry_ptr(), mats.as_ptr(), materials.len() as u16, is_exclusive.unwrap_or(false), physx_sys::PxShapeFlags { mBits: shape_flags.unwrap_or_default().bits, }, ) }, 0, ) } pub(crate) fn from_ptr(ptr: *mut physx_sys::PxShape) -> Self { let mut s = Self(ptr, 0); s.acquire_reference(); s } pub(crate) fn acquire_reference(&mut self) { self.1 += 1; unsafe { physx_sys::PxShape_acquireReference_mut(self.0) } } pub fn get_geometry(&self) -> PxGeometryHolder { PxGeometryHolder(unsafe { physx_sys::PxShape_getGeometry(self.0) }) } pub fn set_geometry(&self, geometry: &dyn PxGeometry) { unsafe { physx_sys::PxShape_setGeometry_mut(self.0, geometry.as_geometry_ptr()) } } pub fn get_geometry_type(&self) -> PxGeometryType { PxGeometryType::from_i32(unsafe { physx_sys::PxShape_getGeometryType(self.0) }).unwrap() } pub fn get_local_pose(&self) -> PxTransform { PxTransform(unsafe { physx_sys::PxShape_getLocalPose(self.0) }) } pub fn set_local_pose(&self, pose: &PxTransform) { unsafe { physx_sys::PxShape_setLocalPose_mut(self.0, &pose.0 as *const physx_sys::PxTransform) } } pub fn get_global_pose(&self, actor: PxRigidActorRef) -> PxTransform { PxTransform(unsafe { physx_sys::PxShapeExt_getGlobalPose_mut(self.0, actor.0) }) } pub fn get_actor(&self) -> Option { unsafe { let p = physx_sys::PxShape_getActor(self.0); if p.is_null() { None } else { Some(PxRigidActorRef(p)) } } } pub fn get_flags(&self) -> PxShapeFlag { PxShapeFlag::from_bits(unsafe { physx_sys::PxShape_getFlags(self.0) }.mBits).unwrap() } pub fn set_flag(&self, flag: PxShapeFlag, value: bool) { unsafe { physx_sys::PxShape_setFlag_mut(self.0, flag.bits as u32, value) } } pub fn set_flags(&self, flags: PxShapeFlag) { unsafe { physx_sys::PxShape_setFlags_mut(self.0, physx_sys::PxShapeFlags { mBits: flags.bits }) } } pub fn get_contact_offset(&self) -> f32 { unsafe { physx_sys::PxShape_getContactOffset(self.0) } } pub fn set_contact_offset(&self, offset: f32) { unsafe { physx_sys::PxShape_setContactOffset_mut(self.0, offset) } } pub fn get_rest_offset(&self) -> f32 { unsafe { physx_sys::PxShape_getRestOffset(self.0) } } pub fn set_rest_offset(&self, offset: f32) { unsafe { physx_sys::PxShape_setRestOffset_mut(self.0, offset) } } } impl AsPxBase for PxShape { fn as_base(&self) -> PxBaseRef { PxBaseRef(self.0 as _) } } impl PxUserData for PxShape { fn raw_user_data_mut(&self) -> &mut *mut c_void { unsafe { &mut (*self.0).userData } } fn raw_user_data(&self) -> &*mut c_void { unsafe { &(*self.0).userData } } } impl Clone for PxShape { fn clone(&self) -> Self { Self::from_ptr(self.0) } } impl Drop for PxShape { fn drop(&mut self) { for _ in 0..self.1 { unsafe { physx_sys::PxShape_release_mut(self.0); } } } } unsafe impl Sync for PxShape {} unsafe impl Send for PxShape {}