#![warn(clippy::all)]
use super::{
articulation_link::ArticulationLink, base::Base, body::*, math::Bounds, px_type::*,
transform::*, user_data::UserData,
};
use glam::Mat4;
use physx_macros::*;
use physx_sys::{
PxArticulationBase, PxArticulationBase_createLink_mut, PxArticulationBase_getNbLinks,
PxArticulationBase_getSleepThreshold, PxArticulationBase_getSolverIterationCounts,
PxArticulationBase_getStabilizationThreshold, PxArticulationBase_getWakeCounter,
PxArticulationBase_getWorldBounds, PxArticulationBase_isSleeping,
PxArticulationBase_putToSleep_mut, PxArticulationBase_setSleepThreshold_mut,
PxArticulationBase_setSolverIterationCounts_mut,
PxArticulationBase_setStabilizationThreshold_mut, PxArticulationBase_setWakeCounter_mut,
PxArticulationBase_wakeUp_mut, PxArticulationLink, PxRigidActor, PxRigidActor_getGlobalPose,
};
use std::ptr::null_mut;
#[physx_type(inherit = "Base")]
impl ArticulationBase {
pub fn new(ptr: *mut PxArticulationBase) -> Self {
let mut _self = Self::from_ptr(ptr);
_self.allocate_user_data();
_self
}
pub fn set_solver_iteration_counts(
&mut self,
min_position_iters: u32,
min_velocity_iters: u32,
) {
unsafe {
PxArticulationBase_setSolverIterationCounts_mut(
self.get_raw_mut(),
min_position_iters,
min_velocity_iters,
);
}
}
pub fn get_solver_iteration_counts(&self) -> (u32, u32) {
unsafe {
let mut min_position_iters: u32 = 0;
let mut min_velocity_iters: u32 = 0;
PxArticulationBase_getSolverIterationCounts(
self.get_raw(),
&mut min_position_iters as *mut u32,
&mut min_velocity_iters as *mut u32,
);
(min_position_iters, min_velocity_iters)
}
}
pub fn is_sleeping(&self) -> bool {
unsafe { PxArticulationBase_isSleeping(self.get_raw()) }
}
pub fn set_sleep_threshold(&mut self, threshold: f32) {
unsafe {
PxArticulationBase_setSleepThreshold_mut(self.get_raw_mut(), threshold);
}
}
pub fn get_sleep_threshold(&self) -> f32 {
unsafe { PxArticulationBase_getSleepThreshold(self.get_raw()) }
}
pub fn set_stabilization_threshold(&mut self, threshold: f32) {
unsafe {
PxArticulationBase_setStabilizationThreshold_mut(self.get_raw_mut(), threshold);
}
}
pub fn get_stabilization_threshold(&self) -> f32 {
unsafe { PxArticulationBase_getStabilizationThreshold(self.get_raw()) }
}
pub fn set_wake_counter(&mut self, threshold: f32) {
unsafe {
PxArticulationBase_setWakeCounter_mut(self.get_raw_mut(), threshold);
}
}
pub fn get_wake_counter(&self) -> f32 {
unsafe { PxArticulationBase_getWakeCounter(self.get_raw()) }
}
pub fn wake_up(&mut self) {
unsafe {
PxArticulationBase_wakeUp_mut(self.get_raw_mut());
}
}
pub fn put_to_sleep(&mut self) {
unsafe {
PxArticulationBase_putToSleep_mut(self.get_raw_mut());
}
}
pub fn get_nb_links(&self) -> usize {
unsafe { PxArticulationBase_getNbLinks(self.get_raw()) as usize }
}
#[inline]
pub fn iter_links(&self) -> impl std::iter::Iterator<Item = &ArticulationLink> {
match self.user_data() {
UserData::ArticulationBase(data) => data.links.iter(),
_ => unimplemented!(),
}
}
#[inline]
pub fn iter_links_mut(&mut self) -> impl std::iter::Iterator<Item = &mut ArticulationLink> {
match self.user_data_mut() {
UserData::ArticulationBase(data) => data.links.iter_mut(),
_ => unimplemented!(),
}
}
#[inline]
pub fn links(&self) -> &Vec<ArticulationLink> {
match self.user_data() {
UserData::ArticulationBase(data) => &data.links,
_ => unimplemented!(),
}
}
#[inline]
pub fn links_mut(&mut self) -> &mut Vec<ArticulationLink> {
match self.user_data_mut() {
UserData::ArticulationBase(data) => &mut data.links,
_ => unimplemented!(),
}
}
pub fn create_link(
&mut self,
parent: PartHandle,
transform: Option<Mat4>,
joint_transform: Option<Mat4>,
) -> *mut PxArticulationLink {
let (parent, trans) = if parent.1 == 0 {
(null_mut(), Mat4::identity())
} else {
let parent_link = parent.1 as *mut PxArticulationLink;
(parent_link, unsafe {
px_to_gl_tf(PxRigidActor_getGlobalPose(
parent_link as *const PxRigidActor,
))
})
};
let transform = joint_transform.unwrap_or_else(Mat4::identity)
* transform.unwrap_or_else(Mat4::identity);
unsafe {
PxArticulationBase_createLink_mut(
self.get_raw_mut(),
parent,
&gl_to_px_tf(trans * transform),
)
}
}
pub fn get_world_bounds(&self, inflation: f32) -> Bounds {
unsafe { PxArticulationBase_getWorldBounds(self.get_raw(), inflation).into() }
}
pub fn add_link(&mut self, link: ArticulationLink) {
if let UserData::ArticulationBase(data) = self.user_data_mut() {
data.links.push(link)
}
}
pub fn user_data(&self) -> &UserData {
unsafe { &*((*self.ptr).userData as *const UserData) }
}
pub fn user_data_mut(&mut self) -> &mut UserData {
unsafe { &mut *((*self.ptr).userData as *mut UserData) }
}
pub(crate) fn allocate_user_data(&mut self) {
let userdata = Box::new(UserData::new_articulation_base());
unsafe {
(*self.ptr).userData = Box::into_raw(userdata) as *mut std::ffi::c_void;
}
}
}