36 releases (18 breaking)

0.19.0 Oct 11, 2023
0.18.0 Mar 3, 2023
0.17.0 Mar 3, 2023
0.16.0 Oct 20, 2022
0.4.0 Oct 31, 2019

#4 in Simulation

Download history 8/week @ 2023-12-04 9/week @ 2024-01-29 7/week @ 2024-02-05 6/week @ 2024-02-12 157/week @ 2024-02-19 54/week @ 2024-02-26 44/week @ 2024-03-04 24/week @ 2024-03-11 25/week @ 2024-03-18

147 downloads per month
Used in 2 crates

MIT/Apache

11MB
221K SLoC

C++ 203K SLoC // 0.1% comments Rust 18K SLoC // 0.0% comments C 290 SLoC // 0.4% comments Shell 8 SLoC // 0.4% comments

🎳 physx

Build Status Crates.io Docs Contributor Covenant Embark Embark

This is a work in progress 🚧

physx is intended to be an easy to use high-level wrapper for the physx-sys bindings. The goal of this is to make ownership clearer and leverage the safety of Rust.

The overall goal is to maintain a close mapping to the underlying PhysX API while improving safety and reliability of the code. This means, for example, that we do not expose the PxLoadExtensions() function but rather attach this to the Physics builder.

Please also see the repository containing an unsafe low-level binding.

Example

Basic usage

let mut physics = PhysicsFoundation::default();

let mut scene = physics.create(
    SceneDescriptor {
        gravity: PxVec3::new(0.0, 0.0, -9.81),
        ..SceneDescriptor::new(MySceneUserData::default())
    }
);

// Your physics simulation goes here

For a full example, have a look at the bouncing ball example and compare it to the raw sys example.

How it works

Wrapping a C++ API in Rust is not straightforward, and requires some extra steps to work. The first, and most basic one is creating a C wrapper over the C++ API. Using C as an intermediary allows us to leverage a stable ABI through which C++ and Rust can communicate. The physx-sys crate provides this interface.

PhysX makes significant use of inheritance, which isn't directly translatable to Rust. The class interfaces are directly translated into traits with full default implementations that are just calls to the unsafe FFI functions. These traits are bounded by their super class trait, as well as a Class<T> trait, where T is the class data struct found in physx_sys. The class interface methods all take pointers to self, and the Class<T> trait provides as_ptr and as_mut_ptr methods to retrieve *const and *mut pointers to T. Types that have a userData class member also have a UserData trait bound.

trait RigidDynamic: RigidActor + Class<physx_sys::PxRigidDynamic> + UserData {
    fn get_sleep_threshold(&self) -> f32 {
        unsafe { PxRigidDynamic_getSleepThreshold(self.as_ptr()) }
    }
    // ...
}

License

Licensed under either of

at your option.

Note that the PhysX C++ SDK has it's own BSD 3 license and depends on additional C++ third party libraries.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies