use bevy::prelude::*;
use physx::prelude::*;
use physx_sys::{PxErrorCode, PxTolerancesScale};
use crate::types::*;
struct ErrorCallback;
impl physx::physics::ErrorCallback for ErrorCallback {
fn report_error(&self, code: PxErrorCode, message: &str, file: &str, line: u32) {
bevy::log::error!(target: "bevy_mod_physx", "[{file:}:{line:}] {code:40}: {message:}", code=code as i32);
}
}
#[derive(Resource, Deref, DerefMut)]
pub struct Physics(PhysicsFoundation<physx::foundation::DefaultAllocator, PxShape>);
impl Physics {
pub fn new(foundation_desc: &FoundationDescriptor) -> Self {
let mut builder = physx::physics::PhysicsFoundationBuilder::default();
builder.enable_visual_debugger(foundation_desc.visual_debugger);
builder.with_extensions(foundation_desc.extensions);
builder.set_pvd_port(foundation_desc.visual_debugger_port);
if let Some(host) = foundation_desc.visual_debugger_host.as_ref() {
builder.set_pvd_host(host);
}
builder.set_length_tolerance(foundation_desc.tolerances.length);
builder.set_speed_tolerance(foundation_desc.tolerances.speed);
builder.with_error_callback(ErrorCallback);
let physics = builder.build();
if physics.is_none() && foundation_desc.visual_debugger {
let mut without_debugger = foundation_desc.clone();
without_debugger.visual_debugger = false;
return Self::new(&without_debugger);
}
let physics = physics.expect("building PhysX foundation failed");
Self(physics)
}
}
#[derive(Clone)]
pub struct FoundationDescriptor {
pub extensions: bool,
pub tolerances: PxTolerancesScale,
pub visual_debugger: bool,
pub visual_debugger_port: i32,
pub visual_debugger_host: Option<String>,
}
impl Default for FoundationDescriptor {
fn default() -> Self {
Self {
extensions: true,
tolerances: PxTolerancesScale { length: 1., speed: 10. },
visual_debugger: false,
visual_debugger_port: 5425,
visual_debugger_host: None,
}
}
}