use std::borrow::Cow;
use std::ffi::CStr;
use bevy::prelude::*;
use physx::traits::Class;
use physx_sys::{
PxActor_setName_mut,
PxArticulationReducedCoordinate_setName_mut,
PxShape_setName_mut,
};
use crate::prelude::{Scene, *};
#[derive(Resource)]
pub struct NameFormatter(pub fn(Entity, Option<&Name>) -> Cow<'static, CStr>);
#[derive(Component)]
struct PxName(Cow<'static, CStr>);
pub struct NamePlugin;
impl Plugin for NamePlugin {
fn build(&self, app: &mut App) {
app.add_systems(
PhysicsSchedule,
name_sync
.after(crate::systems::scene_simulate)
.run_if(resource_exists::<NameFormatter>)
.in_set(PhysicsSet::Simulate),
);
}
}
fn name_sync(
mut commands: Commands,
mut scene: ResMut<Scene>,
mut handles: Query<
(
Entity,
Option<&Name>,
Option<&PxName>,
Option<&mut ArticulationLinkHandle>,
Option<&mut ArticulationRootHandle>,
Option<&mut RigidDynamicHandle>,
Option<&mut RigidStaticHandle>,
Option<&mut ShapeHandle>,
),
Or<(
Added<ArticulationLinkHandle>,
Added<ArticulationRootHandle>,
Added<RigidDynamicHandle>,
Added<RigidStaticHandle>,
Added<ShapeHandle>,
// changing name doesn't affect PVD,
// as only first name sent to it is displayed
//Changed<Name>,
)>,
>,
fmt: Res<NameFormatter>,
) {
for (entity, bevy_name, existing_name, hlink, hroot, hdyn, hstat, hshape) in handles.iter_mut() {
if hlink.is_none() && hroot.is_none() && hdyn.is_none() && hstat.is_none() && hshape.is_none() {
continue;
}
let name = existing_name.map(|x| x.0.as_ptr()).unwrap_or_else(|| {
let name = fmt.0(entity, bevy_name);
let ptr = name.as_ptr();
commands.entity(entity).insert(PxName(name));
ptr
});
if let Some(mut h) = hroot {
let mut h = h.get_mut(&mut scene);
unsafe { PxArticulationReducedCoordinate_setName_mut(h.as_mut_ptr(), name) };
}
if let Some(mut h) = hlink {
let mut h = h.get_mut(&mut scene);
unsafe { PxActor_setName_mut(h.as_mut_ptr(), name) };
}
if let Some(mut h) = hdyn {
let mut h = h.get_mut(&mut scene);
unsafe { PxActor_setName_mut(h.as_mut_ptr(), name) };
}
if let Some(mut h) = hstat {
let mut h = h.get_mut(&mut scene);
unsafe { PxActor_setName_mut(h.as_mut_ptr(), name) };
}
if let Some(mut h) = hshape {
let mut h = h.get_mut(&mut scene);
unsafe { PxShape_setName_mut(h.as_mut_ptr(), name) };
}
}
}