diff --git a/crates/jolt/Cargo.toml b/crates/jolt/Cargo.toml index c807d43..2e63287 100644 --- a/crates/jolt/Cargo.toml +++ b/crates/jolt/Cargo.toml @@ -7,3 +7,7 @@ edition = "2021" [dependencies] jolt-sys = { path = "../jolt-sys" } + +[lints.clippy] +new_without_default = { level = "allow" } +too_many_arguments = { level = "allow" } diff --git a/crates/jolt/src/body_interface.rs b/crates/jolt/src/body_interface.rs new file mode 100644 index 0000000..e41b0e1 --- /dev/null +++ b/crates/jolt/src/body_interface.rs @@ -0,0 +1,13 @@ +use jolt_sys::*; + +pub struct BodyInterface(*mut JPC_BodyInterface); + +impl BodyInterface { + pub(crate) fn new(inner: *mut JPC_BodyInterface) -> Self { + Self(inner) + } + + pub fn as_raw(&self) -> *mut JPC_BodyInterface { + self.0 + } +} diff --git a/crates/jolt/src/interfaces.rs b/crates/jolt/src/interfaces.rs new file mode 100644 index 0000000..cf5898b --- /dev/null +++ b/crates/jolt/src/interfaces.rs @@ -0,0 +1,65 @@ +use std::ffi::{c_uint, c_void}; +use std::marker::PhantomData; +use std::ptr; + +use jolt_sys::*; + +use crate::{BroadPhaseLayer, ObjectLayer}; + +pub trait IntoBroadPhaseLayerInterface { + fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface; +} + +pub trait BroadPhaseLayerInterface: Sized { + fn get_num_broad_phase_layers(&self) -> u32; + fn get_broad_phase_layer(&self, layer: ObjectLayer) -> BroadPhaseLayer; + + fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface { + type Bridge = BroadPhaseLayerInterfaceBridge; + + let fns = JPC_BroadPhaseLayerInterfaceFns { + GetNumBroadPhaseLayers: Some(Bridge::::GetNumBroadPhaseLayers as _), + GetBroadPhaseLayer: Some(Bridge::::GetBroadPhaseLayer as _), + }; + + unsafe { JPC_BroadPhaseLayerInterface_new(ptr::from_ref(self).cast::(), fns) } + } +} + +impl IntoBroadPhaseLayerInterface for *mut JPC_BroadPhaseLayerInterface { + fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface { + *self + } +} + +impl IntoBroadPhaseLayerInterface for T +where + T: BroadPhaseLayerInterface, +{ + fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface { + ::as_raw(self) + } +} + +struct BroadPhaseLayerInterfaceBridge { + _phantom: PhantomData, +} + +#[allow(non_snake_case)] +impl BroadPhaseLayerInterfaceBridge { + unsafe extern "C" fn GetNumBroadPhaseLayers(this: *const c_void) -> c_uint { + let this = this.cast::().as_ref().unwrap(); + + this.get_num_broad_phase_layers() + } + + unsafe extern "C" fn GetBroadPhaseLayer( + this: *const c_void, + layer: JPC_ObjectLayer, + ) -> JPC_BroadPhaseLayer { + let this = this.cast::().as_ref().unwrap(); + let layer = ObjectLayer(layer); + + this.get_broad_phase_layer(layer).raw() + } +} diff --git a/crates/jolt/src/lib.rs b/crates/jolt/src/lib.rs index e99acb6..2c0247c 100644 --- a/crates/jolt/src/lib.rs +++ b/crates/jolt/src/lib.rs @@ -1,11 +1,12 @@ -use std::ffi::{c_uint, c_void}; -use std::marker::PhantomData; -use std::ptr; +use jolt_sys::*; -use jolt_sys::{ - JPC_BroadPhaseLayer, JPC_BroadPhaseLayerInterface, JPC_BroadPhaseLayerInterfaceFns, - JPC_BroadPhaseLayerInterface_new, JPC_ObjectLayer, -}; +mod body_interface; +mod interfaces; +mod physics_system; + +pub use crate::body_interface::*; +pub use crate::interfaces::*; +pub use crate::physics_system::*; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ObjectLayer(JPC_ObjectLayer); @@ -32,49 +33,3 @@ impl BroadPhaseLayer { self.0 } } - -pub trait BroadPhaseLayerInterface: Sized { - fn get_num_broad_phase_layers(&self) -> u32; - fn get_broad_phase_layer(&self, layer: ObjectLayer) -> BroadPhaseLayer; - - fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface { - jpc_bpli(self) - } -} - -struct BroadPhaseLayerInterfaceBridge { - _phantom: PhantomData, -} - -#[allow(non_snake_case)] -impl BroadPhaseLayerInterfaceBridge { - unsafe extern "C" fn GetNumBroadPhaseLayers(this: *const c_void) -> c_uint { - let this = this.cast::().as_ref().unwrap(); - - this.get_num_broad_phase_layers() - } - - unsafe extern "C" fn GetBroadPhaseLayer( - this: *const c_void, - layer: JPC_ObjectLayer, - ) -> JPC_BroadPhaseLayer { - let this = this.cast::().as_ref().unwrap(); - let layer = ObjectLayer(layer); - - this.get_broad_phase_layer(layer).raw() - } -} - -fn jpc_bpli(input: &T) -> *mut JPC_BroadPhaseLayerInterface -where - T: BroadPhaseLayerInterface, -{ - type Bridge = BroadPhaseLayerInterfaceBridge; - - let fns = JPC_BroadPhaseLayerInterfaceFns { - GetNumBroadPhaseLayers: Some(Bridge::::GetNumBroadPhaseLayers as _), - GetBroadPhaseLayer: Some(Bridge::::GetBroadPhaseLayer as _), - }; - - unsafe { JPC_BroadPhaseLayerInterface_new(ptr::from_ref(input).cast::(), fns) } -} diff --git a/crates/jolt/src/physics_system.rs b/crates/jolt/src/physics_system.rs new file mode 100644 index 0000000..fb265c2 --- /dev/null +++ b/crates/jolt/src/physics_system.rs @@ -0,0 +1,53 @@ +use jolt_sys::*; + +use crate::{BodyInterface, IntoBroadPhaseLayerInterface}; + +pub struct PhysicsSystem(*mut JPC_PhysicsSystem); + +impl PhysicsSystem { + pub fn new() -> Self { + unsafe { Self(JPC_PhysicsSystem_new()) } + } + + /// # Safety + /// no + pub unsafe fn init( + &self, + max_bodies: u32, + num_body_mutexes: u32, + max_body_pairs: u32, + max_contact_constraints: u32, + broad_phase_layer_interface: impl IntoBroadPhaseLayerInterface, + object_vs_broad_phase_layer_interface: *mut JPC_ObjectVsBroadPhaseLayerFilter, + object_layer_pair_filter: *mut JPC_ObjectLayerPairFilter, + ) { + unsafe { + JPC_PhysicsSystem_Init( + self.0, + max_bodies, + num_body_mutexes, + max_body_pairs, + max_contact_constraints, + broad_phase_layer_interface.as_raw(), + object_vs_broad_phase_layer_interface, + object_layer_pair_filter, + ); + } + } + + pub fn body_interface(&self) -> BodyInterface { + unsafe { BodyInterface::new(JPC_PhysicsSystem_GetBodyInterface(self.0)) } + } + + pub fn as_raw(&self) -> *mut JPC_PhysicsSystem { + self.0 + } +} + +impl Drop for PhysicsSystem { + fn drop(&mut self) { + unsafe { + JPC_PhysicsSystem_delete(self.0); + } + } +}