physxx 0.3.1

Wrapper around the PhysX C++ API that aims to preserve the original API as much as possible.
Documentation
use crate::{
    AsPxJoint, AsPxRigidActor, AsPxRigidBody, PxAggregateRef, PxArticulationLinkRef,
    PxConstraintRef, PxConvexMesh, PxFixedJointRef, PxHeightField, PxJointRef, PxMaterial,
    PxRevoluteJointRef, PxRigidActorRef, PxRigidBodyRef, PxRigidDynamicRef, PxRigidStaticRef,
    PxShape,
};

pub trait AsPxBase: Sync + Send {
    fn as_base(&self) -> PxBaseRef;
}
pub trait PxBase: Sync + Send + as_any::AsAny {
    fn get_concrete_type(&self) -> u16;
    fn as_px_any(&self) -> PxAny;
    fn to_rigid_dynamic(&self) -> Option<PxRigidDynamicRef>;
    fn to_rigid_actor(&self) -> Option<PxRigidActorRef>;
    fn to_rigid_body(&self) -> Option<PxRigidBodyRef>;
    fn to_rigid_static(&self) -> Option<PxRigidStaticRef>;
    fn to_joint(&self) -> Option<PxJointRef>;
    fn to_fixed_joint(&self) -> Option<PxFixedJointRef>;
    fn to_revolute_joint(&self) -> Option<PxRevoluteJointRef>;
}
impl<T: AsPxBase + 'static> PxBase for T {
    fn get_concrete_type(&self) -> u16 {
        unsafe { physx_sys::PxBase_getConcreteType(self.as_base().0) }
    }
    fn as_px_any(&self) -> PxAny {
        PxAny::from_obj(self.as_base().0)
    }
    fn to_rigid_dynamic(&self) -> Option<PxRigidDynamicRef> {
        match self.as_px_any() {
            PxAny::PxRigidDynamic(o) => Some(o),
            _ => None,
        }
    }
    fn to_rigid_actor(&self) -> Option<PxRigidActorRef> {
        match self.as_px_any() {
            PxAny::PxRigidDynamic(o) => Some(o.as_rigid_actor()),
            PxAny::PxRigidStatic(o) => Some(o.as_rigid_actor()),
            _ => None,
        }
    }
    fn to_rigid_body(&self) -> Option<PxRigidBodyRef> {
        match self.as_px_any() {
            PxAny::PxRigidDynamic(o) => Some(o.as_rigid_body()),
            PxAny::PxArticulationLink(o) => Some(o.as_rigid_body()),
            _ => None,
        }
    }
    fn to_rigid_static(&self) -> Option<PxRigidStaticRef> {
        match self.as_px_any() {
            PxAny::PxRigidStatic(o) => Some(o),
            _ => None,
        }
    }
    fn to_joint(&self) -> Option<PxJointRef> {
        match self.as_px_any() {
            PxAny::PxFixedJoint(o) => Some(o.as_joint()),
            PxAny::PxRevoluteJoint(o) => Some(o.as_joint()),
            _ => None,
        }
    }
    fn to_fixed_joint(&self) -> Option<PxFixedJointRef> {
        match self.as_px_any() {
            PxAny::PxFixedJoint(o) => Some(o),
            _ => None,
        }
    }
    fn to_revolute_joint(&self) -> Option<PxRevoluteJointRef> {
        match self.as_px_any() {
            PxAny::PxRevoluteJoint(o) => Some(o),
            _ => None,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PxBaseRef(pub(crate) *mut physx_sys::PxBase);
impl AsPxBase for PxBaseRef {
    fn as_base(&self) -> PxBaseRef {
        PxBaseRef(self.0)
    }
}
unsafe impl Sync for PxBaseRef {}
unsafe impl Send for PxBaseRef {}

#[derive(Debug)]
pub enum PxAny {
    PxAggregate(PxAggregateRef),
    PxHeightField(PxHeightField),
    PxConvexMesh(PxConvexMesh),
    PxMaterial(PxMaterial),
    PxRigidDynamic(PxRigidDynamicRef),
    PxRigidStatic(PxRigidStaticRef),
    PxShape(PxShape),
    PxFixedJoint(PxFixedJointRef),
    PxRevoluteJoint(PxRevoluteJointRef),
    PxConstraint(PxConstraintRef),
    PxArticulationLink(PxArticulationLinkRef),
}
impl PxAny {
    pub(crate) fn from_obj(obj: *mut physx_sys::PxBase) -> Self {
        unsafe {
            match physx_sys::PxBase_getConcreteType(obj) as u32 {
                physx_sys::PxConcreteType::eAGGREGATE => {
                    PxAny::PxAggregate(PxAggregateRef(obj as _))
                }
                physx_sys::PxConcreteType::eARTICULATION => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::eARTICULATION_JOINT => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::eARTICULATION_JOINT_REDUCED_COORDINATE => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::eARTICULATION_LINK => {
                    PxAny::PxArticulationLink(PxArticulationLinkRef(obj as _))
                }
                physx_sys::PxConcreteType::eARTICULATION_REDUCED_COORDINATE => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::eBVH_STRUCTURE => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::eCONSTRAINT => {
                    PxAny::PxConstraint(PxConstraintRef(obj as _))
                }
                physx_sys::PxConcreteType::eCONVEX_MESH => {
                    PxAny::PxConvexMesh(PxConvexMesh::from_ptr(obj as _))
                }
                physx_sys::PxConcreteType::eFIRST_USER_EXTENSION => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::eFIRST_VEHICLE_EXTENSION => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::eHEIGHTFIELD => {
                    PxAny::PxHeightField(PxHeightField::from_ptr(obj as _))
                }
                physx_sys::PxConcreteType::eMATERIAL => {
                    PxAny::PxMaterial(PxMaterial::from_ptr(obj as _))
                }
                physx_sys::PxConcreteType::ePHYSX_CORE_COUNT => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::ePRUNING_STRUCTURE => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::eRIGID_DYNAMIC => {
                    PxAny::PxRigidDynamic(PxRigidDynamicRef(obj as _))
                }
                physx_sys::PxConcreteType::eRIGID_STATIC => {
                    PxAny::PxRigidStatic(PxRigidStaticRef(obj as _))
                }
                physx_sys::PxConcreteType::eSHAPE => PxAny::PxShape(PxShape::from_ptr(obj as _)),
                physx_sys::PxConcreteType::eTRIANGLE_MESH_BVH33 => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxConcreteType::eTRIANGLE_MESH_BVH34 => {
                    panic!("PhysX object type is not supported")
                }

                physx_sys::PxJointConcreteType::eCONTACT => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxJointConcreteType::eD6 => panic!("PhysX object type is not supported"),
                physx_sys::PxJointConcreteType::eDISTANCE => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxJointConcreteType::eFIXED => {
                    PxAny::PxFixedJoint(PxFixedJointRef(obj as _))
                }
                physx_sys::PxJointConcreteType::eLast => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxJointConcreteType::ePRISMATIC => {
                    panic!("PhysX object type is not supported")
                }
                physx_sys::PxJointConcreteType::eREVOLUTE => {
                    PxAny::PxRevoluteJoint(PxRevoluteJointRef(obj as _))
                }
                physx_sys::PxJointConcreteType::eSPHERICAL => {
                    panic!("PhysX object type is not supported")
                }

                _ => panic!("Unknown type"),
            }
        }
    }
}