use crate::{
owner::Owner,
rigid_actor::RigidActor,
rigid_body::RigidBody,
shape::{Shape, ShapeFlag},
traits::{Class, UserData},
};
use std::{marker::PhantomData, ptr::drop_in_place};
#[rustfmt::skip]
use physx_sys::{
PxArticulationLink_getChildren,
PxArticulationLink_getInboundJointDof,
PxArticulationLink_getLinkIndex,
PxArticulationLink_getNbChildren,
PxArticulationLink_release_mut,
};
#[repr(transparent)]
pub struct PxArticulationLink<L, Geom: Shape> {
pub(crate) obj: physx_sys::PxArticulationLink,
phantom_user_data: PhantomData<(L, Geom)>,
}
unsafe impl<L, Geom: Shape> UserData for PxArticulationLink<L, Geom> {
type UserData = L;
#[inline]
fn user_data_ptr(&self) -> &*mut std::ffi::c_void {
&self.obj.userData
}
#[inline]
fn user_data_ptr_mut(&mut self) -> &mut *mut std::ffi::c_void {
&mut self.obj.userData
}
}
impl<L, Geom: Shape> Drop for PxArticulationLink<L, Geom> {
fn drop(&mut self) {
unsafe {
drop_in_place(self.get_user_data_mut() as *mut _);
PxArticulationLink_release_mut(self.as_mut_ptr());
}
}
}
unsafe impl<P, L, Geom: Shape> Class<P> for PxArticulationLink<L, Geom>
where
physx_sys::PxArticulationLink: Class<P>,
{
#[inline]
fn as_ptr(&self) -> *const P {
self.obj.as_ptr()
}
#[inline]
fn as_mut_ptr(&mut self) -> *mut P {
self.obj.as_mut_ptr()
}
}
unsafe impl<L: Send, Geom: Shape + Send> Send for PxArticulationLink<L, Geom> {}
unsafe impl<L: Sync, Geom: Shape + Sync> Sync for PxArticulationLink<L, Geom> {}
impl<L, Geom: Shape> RigidActor for PxArticulationLink<L, Geom> {
type Shape = Geom;
}
impl<L, Geom: Shape> ArticulationLink for PxArticulationLink<L, Geom> {}
pub trait ArticulationLink: Class<physx_sys::PxArticulationLink> + RigidBody + UserData {
unsafe fn from_raw(
ptr: *mut physx_sys::PxArticulationLink,
user_data: Self::UserData,
) -> Option<Owner<Self>> {
unsafe { Owner::from_raw((ptr as *mut Self).as_mut()?.init_user_data(user_data)) }
}
#[inline]
fn get_user_data(&self) -> &Self::UserData {
unsafe { UserData::get_user_data(self) }
}
#[inline]
fn get_user_data_mut(&mut self) -> &mut Self::UserData {
unsafe { UserData::get_user_data_mut(self) }
}
#[inline]
fn enable_collision(&mut self, enable: bool) {
for shape in self.get_shapes_mut() {
shape.set_flag(ShapeFlag::SimulationShape, enable);
}
}
#[inline]
fn get_link_index(&self) -> u32 {
unsafe { PxArticulationLink_getLinkIndex(self.as_ptr()) }
}
#[inline]
fn get_inbound_joint_dof(&self) -> u32 {
unsafe { PxArticulationLink_getInboundJointDof(self.as_ptr()) }
}
#[inline]
fn get_nb_children(&self) -> u32 {
unsafe { PxArticulationLink_getNbChildren(self.as_ptr()) }
}
#[inline]
fn get_children(&self) -> Vec<&Self> {
let capacity = self.get_nb_children();
let mut buffer: Vec<&Self> = Vec::with_capacity(capacity as usize);
unsafe {
let new_len = PxArticulationLink_getChildren(
self.as_ptr(),
buffer.as_mut_ptr() as *mut *mut _,
capacity,
0,
);
buffer.set_len(new_len as usize);
buffer
}
}
}