use crate::{
articulation_link::ArticulationLink, base::Base, math::*, rigid_actor::RigidActor,
rigid_dynamic::RigidDynamic, rigid_static::RigidStatic, traits::Class,
};
use std::marker::PhantomData;
#[rustfmt::skip]
use physx_sys::{
PxActor,
PxActor_getActorFlags,
PxActor_getDominanceGroup,
PxActor_getOwnerClient,
PxActor_getType,
PxActor_getWorldBounds,
PxActor_setActorFlag_mut,
PxActor_setActorFlags_mut,
PxActor_setDominanceGroup_mut,
PxActor_setOwnerClient_mut,
};
pub use physx_sys::{
PxActorFlag as ActorFlag, PxActorFlags as ActorFlags, PxActorType as ActorType,
};
impl<T> Actor for T where T: Class<PxActor> + Base {}
pub trait Actor: Class<PxActor> + Base {
fn get_type(&self) -> ActorType {
unsafe { PxActor_getType(self.as_ptr()) }
}
fn get_world_bounds(&self, inflation: f32) -> PxBounds3 {
unsafe { PxActor_getWorldBounds(self.as_ptr(), inflation).into() }
}
fn set_actor_flag(&mut self, flag: ActorFlag, value: bool) {
unsafe { PxActor_setActorFlag_mut(self.as_mut_ptr(), flag, value) }
}
fn set_actor_flags(&mut self, flags: ActorFlags) {
unsafe { PxActor_setActorFlags_mut(self.as_mut_ptr(), flags) }
}
fn get_actor_flags(&self) -> ActorFlags {
unsafe { PxActor_getActorFlags(self.as_ptr()) }
}
fn set_dominance_group(&mut self, group: u8) {
unsafe { PxActor_setDominanceGroup_mut(self.as_mut_ptr(), group) }
}
fn get_dominance_group(&self) -> u8 {
unsafe { PxActor_getDominanceGroup(self.as_ptr()) }
}
fn set_owner_client(&mut self, client: u8) {
unsafe { PxActor_setOwnerClient_mut(self.as_mut_ptr(), client) }
}
fn get_owner_client(&self) -> u8 {
unsafe { PxActor_getOwnerClient(self.as_ptr()) }
}
fn enable_visualization(&mut self, enable: bool) {
unsafe {
PxActor_setActorFlag_mut(self.as_mut_ptr(), ActorFlag::Visualization, enable);
}
}
fn enable_gravity(&mut self, enable: bool) {
unsafe {
PxActor_setActorFlag_mut(self.as_mut_ptr(), ActorFlag::DisableGravity, !enable);
}
}
}
#[repr(transparent)]
pub struct ActorMap<L, S, D>
where
L: ArticulationLink,
S: RigidStatic,
D: RigidDynamic,
{
obj: physx_sys::PxRigidActor,
phantom_user_data: PhantomData<(*const L, *const S, *const D)>,
}
unsafe impl<P, L, S, D> Class<P> for ActorMap<L, S, D>
where
physx_sys::PxRigidActor: Class<P>,
L: ArticulationLink,
S: RigidStatic,
D: RigidDynamic,
{
fn as_ptr(&self) -> *const P {
self.obj.as_ptr()
}
fn as_mut_ptr(&mut self) -> *mut P {
self.obj.as_mut_ptr()
}
}
impl<L, S, D> RigidActor for ActorMap<L, S, D>
where
L: ArticulationLink,
S: RigidStatic,
D: RigidDynamic,
{
type Shape = L::Shape;
}
impl<L, S, D> ActorMap<L, S, D>
where
L: ArticulationLink,
S: RigidStatic,
D: RigidDynamic,
{
pub fn cast_map<'a, Ret, ALFn, RSFn, RDFn>(
&'a self,
mut articulation_link_fn: ALFn,
mut rigid_static_fn: RSFn,
mut rigid_dynamic_fn: RDFn,
) -> Ret
where
ALFn: FnMut(&'a L) -> Ret,
RSFn: FnMut(&'a S) -> Ret,
RDFn: FnMut(&'a D) -> Ret,
{
match self.get_type() {
ActorType::RigidDynamic => {
rigid_dynamic_fn(unsafe { &*(self as *const _ as *const D) })
}
ActorType::RigidStatic => rigid_static_fn(unsafe { &*(self as *const _ as *const S) }),
ActorType::ArticulationLink => {
articulation_link_fn(unsafe { &*(self as *const _ as *const L) })
}
}
}
pub fn cast_map_mut<'a, Ret, ALFn, RSFn, RDFn>(
&'a mut self,
mut articulation_link_fn: ALFn,
mut rigid_static_fn: RSFn,
mut rigid_dynamic_fn: RDFn,
) -> Ret
where
ALFn: FnMut(&'a mut L) -> Ret,
RSFn: FnMut(&'a mut S) -> Ret,
RDFn: FnMut(&'a mut D) -> Ret,
{
match self.get_type() {
ActorType::RigidDynamic => {
rigid_dynamic_fn(unsafe { &mut *(self as *mut _ as *mut D) })
}
ActorType::RigidStatic => rigid_static_fn(unsafe { &mut *(self as *mut _ as *mut S) }),
ActorType::ArticulationLink => {
articulation_link_fn(unsafe { &mut *(self as *mut _ as *mut L) })
}
}
}
pub fn as_rigid_dynamic(&self) -> Option<&D> {
match self.get_type() {
ActorType::RigidDynamic => unsafe { Some(&*(self as *const _ as *const D)) },
_ => None,
}
}
pub fn as_rigid_dynamic_mut(&mut self) -> Option<&mut D> {
match self.get_type() {
ActorType::RigidDynamic => unsafe { Some(&mut *(self as *mut _ as *mut D)) },
_ => None,
}
}
pub fn as_rigid_static(&self) -> Option<&S> {
match self.get_type() {
ActorType::RigidStatic => unsafe { Some(&*(self as *const _ as *const S)) },
_ => None,
}
}
pub fn as_rigid_static_mut(&mut self) -> Option<&mut S> {
match self.get_type() {
ActorType::RigidStatic => unsafe { Some(&mut *(self as *mut _ as *mut S)) },
_ => None,
}
}
pub fn as_articulation_link(&self) -> Option<&L> {
match self.get_type() {
ActorType::ArticulationLink => unsafe { Some(&*(self as *const _ as *const L)) },
_ => None,
}
}
pub fn as_articulation_link_mut(&mut self) -> Option<&mut L> {
match self.get_type() {
ActorType::ArticulationLink => unsafe { Some(&mut *(self as *mut _ as *mut L)) },
_ => None,
}
}
}