use crate::{
actor::{Actor, ActorMap},
articulation_link::ArticulationLink,
articulation_reduced_coordinate::ArticulationReducedCoordinate,
base::Base,
bvh::Bvh,
owner::Owner,
rigid_actor::RigidActor,
rigid_dynamic::RigidDynamic,
rigid_static::RigidStatic,
traits::Class,
};
use std::{marker::PhantomData, ptr::null};
#[rustfmt::skip]
use physx_sys::{
PxAggregate_addActor_mut,
PxAggregate_addArticulation_mut,
PxAggregate_getActors,
PxAggregate_getNbActors,
PxAggregate_getSelfCollision,
PxAggregate_release_mut,
PxAggregate_removeActor_mut,
PxAggregate_removeArticulation_mut,
};
#[repr(transparent)]
pub struct PxAggregate<L, S, D, C>
where
L: ArticulationLink,
S: RigidStatic,
D: RigidDynamic,
C: ArticulationReducedCoordinate,
{
obj: physx_sys::PxAggregate,
phantom_user_data: PhantomData<(*const L, *const S, *const D, *const C)>,
}
impl<L, S, D, C> Drop for PxAggregate<L, S, D, C>
where
L: ArticulationLink,
S: RigidStatic,
D: RigidDynamic,
C: ArticulationReducedCoordinate,
{
fn drop(&mut self) {
unsafe {
PxAggregate_release_mut(self.as_mut_ptr());
}
}
}
unsafe impl<L, S, D, C> Send for PxAggregate<L, S, D, C>
where
L: ArticulationLink + Send,
S: RigidStatic + Send,
D: RigidDynamic + Send,
C: ArticulationReducedCoordinate + Send,
{
}
unsafe impl<L, S, D, C> Sync for PxAggregate<L, S, D, C>
where
L: ArticulationLink + Sync,
S: RigidStatic + Sync,
D: RigidDynamic + Sync,
C: ArticulationReducedCoordinate + Sync,
{
}
unsafe impl<P, L, S, D, C> Class<P> for PxAggregate<L, S, D, C>
where
physx_sys::PxAggregate: Class<P>,
L: ArticulationLink,
S: RigidStatic,
D: RigidDynamic,
C: ArticulationReducedCoordinate,
{
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, C> Aggregate for PxAggregate<L, S, D, C>
where
L: ArticulationLink,
S: RigidStatic,
D: RigidDynamic,
C: ArticulationReducedCoordinate,
{
type ActorMap = ActorMap<L, S, D>;
type ArticulationLink = L;
type RigidStatic = S;
type RigidDynamic = D;
type ArticulationReducedCoordinate = C;
}
pub trait Aggregate: Class<physx_sys::PxAggregate> + Base {
type ActorMap: RigidActor;
type ArticulationLink: ArticulationLink;
type RigidStatic: RigidStatic;
type RigidDynamic: RigidDynamic;
type ArticulationReducedCoordinate: ArticulationReducedCoordinate;
unsafe fn from_raw(ptr: *mut physx_sys::PxAggregate) -> Option<Owner<Self>> {
unsafe { Owner::from_raw(ptr as *mut Self) }
}
fn add_articulation_link(
&mut self,
actor: &mut Self::ArticulationLink,
bvh: Option<&Bvh>,
) -> bool {
unsafe {
PxAggregate_addActor_mut(
self.as_mut_ptr(),
actor.as_mut_ptr(),
bvh.map_or(null(), Class::as_ptr),
)
}
}
fn add_rigid_static(&mut self, actor: &mut Self::RigidStatic, bvh: Option<&Bvh>) -> bool {
unsafe {
PxAggregate_addActor_mut(
self.as_mut_ptr(),
actor.as_mut_ptr(),
bvh.map_or(null(), Class::as_ptr),
)
}
}
fn add_rigid_dynamic(&mut self, actor: &mut Self::RigidDynamic, bvh: Option<&Bvh>) -> bool {
unsafe {
PxAggregate_addActor_mut(
self.as_mut_ptr(),
actor.as_mut_ptr(),
bvh.map_or(null(), Class::as_ptr),
)
}
}
fn add_articulation(&mut self, articulation: &mut Self::ArticulationReducedCoordinate) -> bool {
unsafe { PxAggregate_addArticulation_mut(self.as_mut_ptr(), articulation.as_mut_ptr()) }
}
fn add_articulation_reduced_coordinate(
&mut self,
articulation: &mut Self::ArticulationReducedCoordinate,
) -> bool {
unsafe { PxAggregate_addArticulation_mut(self.as_mut_ptr(), articulation.as_mut_ptr()) }
}
fn get_actors(&mut self) -> Vec<&mut Self::ActorMap> {
let capacity = self.get_nb_actors();
let mut buffer: Vec<&mut Self::ActorMap> = Vec::with_capacity(capacity as usize);
unsafe {
let len = PxAggregate_getActors(
self.as_mut_ptr(),
buffer.as_mut_ptr() as *mut *mut physx_sys::PxActor,
capacity,
0,
);
buffer.set_len(len as usize);
}
buffer
}
fn get_nb_actors(&self) -> u32 {
unsafe { PxAggregate_getNbActors(self.as_ptr()) }
}
fn get_self_collision(&self) -> bool {
unsafe { PxAggregate_getSelfCollision(self.as_ptr()) }
}
fn remove_actor(&mut self, actor: &mut impl Actor) -> bool {
unsafe { PxAggregate_removeActor_mut(self.as_mut_ptr(), actor.as_mut_ptr()) }
}
fn remove_articulation(
&mut self,
articulation: &mut Self::ArticulationReducedCoordinate,
) -> bool {
unsafe { PxAggregate_removeArticulation_mut(self.as_mut_ptr(), articulation.as_mut_ptr()) }
}
}