Skip to main content

oxijolt_sys/
lib.rs

1//! Unsafe bindings to [Jolt Physics] 5.6.0 through the [joltc] C wrapper.
2//!
3//! Everything here is `bindgen` output over joltc's `include/joltc.h` plus this
4//! fork's `native/joltc_ext/joltc_ext.h`, and keeps their `JPH_*` names. The output is
5//! committed under `src/bindings/`, one file per ABI family and configuration, so building
6//! needs no libclang; the `bindgen` feature generates it at build time instead. The
7//! supported targets are the registry in `build/targets.rs`; 32-bit targets are not
8//! supported. The
9//! extension adds functions in joltc's naming that are compiled into the joltc
10//! archive: a `JPH_StateRecorder`, `JPH_CharacterVirtual_SaveState` and
11//! `RestoreState`, `JPH_CharacterVirtual_ExtendedUpdate2` and
12//! `RefreshContacts2` with explicit gravity, filters and temp allocator,
13//! `JPH_VehicleConstraint_AsConstraint`, the `Constraint` base of a vehicle
14//! constraint, and for ragdolls `JPH_RagdollSettings_SetPart`, the typed
15//! `JPH_RagdollSettings_SetPartToParentSwingTwist`, `_SetPartToParentHinge` and
16//! `_SetPartToParentSixDOF`, `JPH_RagdollSettings_CalculateConstraintPriorities`,
17//! the swing-twist motor states (`JPH_SwingTwistConstraint_SetSwingMotorState`,
18//! `_GetSwingMotorState`, `_SetTwistMotorState`, `_GetTwistMotorState`), its
19//! `SetTargetOrientationBS` and `GetRotationInConstraintSpace`, and
20//! `JPH_HingeConstraint_SetTargetOrientationBS`, and materials with user data
21//! (`JPH_PhysicsMaterial_Create2`, `JPH_PhysicsMaterial_GetUserData`,
22//! `JPH_ConvexShapeSettings_SetMaterial`, `JPH_HeightFieldShapeSettings_Create2`), the
23//! sub-shape pair of a removed contact (`JPH_SubShapeIDPair_GetBody1ID` and its three siblings),
24//! a contact listener whose validate callback gets the collide result without faces
25//! (`JPH_ContactListener2_*`, `JPH_PhysicsSystem_SetContactListener2`) and a soft body contact
26//! listener (`JPH_SoftBodyContactListener_*`,
27//! `JPH_PhysicsSystem_SetSoftBodyContactListener`, `JPH_SoftBodyManifold_*`), and shapes saved
28//! to bytes with their children and materials and restored (`JPH_Shape_SaveBinaryState`,
29//! `JPH_Shape_RestoreBinaryState`, `JPH_ShapeBinaryState_*`). The safe API lives in the
30//! `oxijolt` crate.
31//!
32//! # Features
33//! - `asserts`: compile Jolt with its debug assertions. joltc's default handler prints a failed
34//!   assertion and then executes a breakpoint (`__debugbreak` on MSVC), so raw users should
35//!   install their own with `JPH_SetAssertFailureHandler` before `JPH_Init`. The handler is one
36//!   process-global joltc slot, and the `oxijolt` crate installs its own.
37//! - `double-precision`: world positions ([`Real`], `JPH_RVec3`, `JPH_RMat4`) use `f64`.
38//! - `cross-platform-deterministic`: build Jolt with its cross-platform deterministic
39//!   floating point settings (slower; same results across compilers and platforms).
40//! - `debug-renderer`: compile Jolt's debug renderer into the native libraries and bind joltc's
41//!   debug drawing functions.
42//! - `bindgen`: generate the bindings at build time with libclang instead of using the
43//!   committed ones. It does not add supported targets.
44//!
45//! # Native build and `JOLTC_LIB_DIR`
46//! By default the build script builds joltc and Jolt from the `vendor/` submodules with
47//! CMake, always in Release. Set `JOLTC_LIB_DIR` to an install prefix produced by an
48//! earlier build (`OUT_DIR/joltc`) to skip CMake: it holds `lib/` with the joltc and Jolt
49//! static libraries, `include/joltc.h`, `include/joltc_ext.h` and
50//! `oxijolt-sys-manifest.txt`. A prefix is specific
51//! to the target, the C runtime, the crate features and the pinned joltc and Jolt
52//! commits; the build script validates all of these against the manifest and refuses a
53//! mismatch.
54//!
55//! # Using the raw API
56//! joltc's own contract, as observed in its source:
57//! - Shape creators such as `JPH_BoxShape_Create` return a shape that holds **one**
58//!   reference, and `JPH_Shape_Destroy` releases one. Bodies keep their own reference, so
59//!   the creator releases its reference once it no longer needs the shape.
60//! - `JPH_PhysicsSystem_Destroy` deletes the broad-phase layer interface and both layer
61//!   filters passed in `JPH_PhysicsSystemSettings`. Do not destroy them yourself.
62//! - `JPH_Init` is guarded by a plain `bool`, and creating or destroying a physics system
63//!   writes an unsynchronised global map. Call `JPH_Init` once, and create and destroy
64//!   systems from one thread at a time.
65//! - `JPH_PhysicsSystem_Update` uses one global temp allocator. Use
66//!   `JPH_PhysicsSystem_Update2` with a per-world `JPH_TempAllocator` instead.
67//! - joltc's `JPH_CharacterVirtual_Update`, `ExtendedUpdate`, `RefreshContacts`,
68//!   `WalkStairs`, `StickToFloor` and `SetShape` use joltc's one global temp
69//!   allocator and are not thread-safe. Use `JPH_CharacterVirtual_ExtendedUpdate2`
70//!   and `JPH_CharacterVirtual_RefreshContacts2` with a per-world allocator instead.
71//! - `JPH_CharacterVirtualSettings_Init` (and `JPH_CharacterSettings_Init`) create an
72//!   empty shape and its settings on every call, each holding a reference nobody
73//!   releases. Fill the settings field by field instead.
74//! - A recorder passed to `JPH_CharacterVirtual_RestoreState` must hold a complete
75//!   stream written by `JPH_CharacterVirtual_SaveState`.
76//! - `JPH_JobSystemThreadPool_Create` maps `numThreads <= 0` to "as many as there are
77//!   hardware threads", so pass a positive worker count when the count matters.
78//! - joltc's object-layer, body and shape filters (`JPH_ObjectLayerFilter_*`,
79//!   `JPH_BodyFilter_*`, `JPH_ShapeFilter_*`) call one process-global proc table per filter
80//!   type. The `oxijolt` crate installs those tables once and owns them. Code that links
81//!   both crates must not call `JPH_*Filter_SetProcs` for these three types, and must not pass
82//!   filters it created with `JPH_*Filter_Create` to queries, because the callbacks of
83//!   `oxijolt` would receive their `userData`.
84//! - joltc's body activation and character contact listeners and the extension's contact
85//!   listener (`JPH_ContactListener2_*`) and soft body contact listener also call one
86//!   process-global proc table each. The `oxijolt` crate installs them once and owns them: code
87//!   that links both crates must not call `JPH_ContactListener2_SetProcs`,
88//!   `JPH_BodyActivationListener_SetProcs`, `JPH_CharacterContactListener_SetProcs` or
89//!   `JPH_SoftBodyContactListener_SetProcs`, nor create listeners of these types, whose
90//!   `userData` the callbacks of `oxijolt` would receive. joltc's own contact listener (`JPH_ContactListener_*`) is not used by `oxijolt`
91//!   and is free for other code.
92//! - A vehicle constraint must be registered both as a constraint
93//!   (`JPH_PhysicsSystem_AddConstraint` with `JPH_VehicleConstraint_AsConstraint`) and as a
94//!   step listener (`JPH_PhysicsSystem_AddStepListener` with
95//!   `JPH_VehicleConstraint_AsPhysicsStepListener`), and its collision tester must be set
96//!   before the first step. Remove it from both before its last reference is released
97//!   (`JPH_Constraint_Destroy` on the `AsConstraint` pointer) and before its body is
98//!   destroyed.
99//! - `JPH_VehicleEngineSettings_Init` allocates a `JPH_LinearCurve` for `normalizedTorque`
100//!   that the caller must destroy with `JPH_LinearCurve_Destroy`.
101//! - The `JPH_Wheel_GetContact*` getters are meaningful only while `JPH_Wheel_HasContact`
102//!   returns true.
103//! - `JPH_RagdollSettings_CreateRagdoll` dereferences null when the world cannot hold every
104//!   part. Check `JPH_PhysicsSystem_GetNumBodies() + parts <= JPH_PhysicsSystem_GetMaxBodies()`
105//!   first, with no body created concurrently. The skeleton must list parents before their
106//!   children.
107//! - A ragdoll destroys its bodies through its physics system when its last reference is
108//!   released: remove it from the system (`JPH_Ragdoll_RemoveFromPhysicsSystem`) before that,
109//!   and release it before the system is destroyed.
110//! - `JPH_Ragdoll_DriveToPoseUsingMotors` drives only swing-twist and hinge parts (any other
111//!   constraint is a Jolt assertion) and needs
112//!   `JPH_RagdollSettings_CalculateBodyIndexToConstraintIndex` to have run.
113//! - `JPH_RagdollSettings_SetPartToParent` handles swing-twist only and drops the constraint
114//!   base settings, the spring modes and the motor torque limits; the typed
115//!   `JPH_RagdollSettings_SetPartToParent*` functions of the extension keep every field.
116//! - A motor state other than `JPH_MotorState_Off` needs valid motor settings (Jolt
117//!   `MotorSettings::IsValid`).
118//! - These joltc functions are not bound: `JPH_RagdollSettings_DisableParentChildCollisions`,
119//!   `JPH_Ragdoll_SetPose2`, `JPH_Ragdoll_GetPose2`, `JPH_SkeletonMapper_Initialize`,
120//!   `JPH_SkeletonMapper_LockAllTranslations`, `JPH_SkeletonMapper_LockTranslations`,
121//!   `JPH_SkeletonMapper_Map` and `JPH_SkeletonMapper_MapReverse`. They reinterpret a
122//!   4-aligned `JPH_Mat4` array as Jolt's 16-aligned `Mat44`, which is undefined
123//!   behaviour for most arrays a caller can pass.
124//! - The debug drawing functions (`JPH_DebugRenderer_*`, `JPH_BodyDrawFilter_*`,
125//!   `JPH_PhysicsSystem_Draw*`, `JPH_Shape_Draw`) exist only with the `debug-renderer` feature,
126//!   which also compiles Jolt's debug renderer into the native libraries.
127//! - Jolt's `DebugRenderer` is a process singleton and joltc's `JPH_DebugRenderer_SetProcs` sets
128//!   one global proc table. With the `debug-renderer` feature of `oxijolt`, that crate
129//!   installs the table and creates a renderer during `PhysicsWorld::debug_lines`; code that
130//!   links both crates must not call `JPH_DebugRenderer_SetProcs` or keep its own
131//!   `JPH_DebugRenderer` alive.
132//!
133//! [Jolt Physics]: https://github.com/jrouwe/JoltPhysics
134//! [joltc]: https://github.com/amerkoleci/joltc
135
136mod generated;
137mod layout;
138
139pub use generated::*;
140
141/// Scalar type of world positions: `f64` with the `double-precision` feature, `f32` otherwise.
142#[cfg(feature = "double-precision")]
143pub type Real = f64;
144
145/// Scalar type of world positions: `f64` with the `double-precision` feature, `f32` otherwise.
146#[cfg(not(feature = "double-precision"))]
147pub type Real = f32;
148
149/// Whether the native library was built with Jolt's assertions (the `asserts` feature).
150pub const ASSERTS_ENABLED: bool = cfg!(feature = "asserts");
151
152/// Whether the native library was built with Jolt's cross-platform determinism (the
153/// `cross-platform-deterministic` feature).
154pub const CROSS_PLATFORM_DETERMINISTIC_ENABLED: bool =
155    cfg!(feature = "cross-platform-deterministic");
156
157/// Jolt Physics commit the native library is built from (the `vendor/JoltPhysics` submodule).
158pub const JOLT_COMMIT: &str = env!("OXIJOLT_SYS_JOLT_COMMIT");
159
160/// joltc commit the native library is built from (the `vendor/joltc` submodule).
161pub const JOLTC_COMMIT: &str = env!("OXIJOLT_SYS_JOLTC_COMMIT");
162
163/// Revision of this fork's joltc additions (`native/joltc_ext/`) in the native library. A
164/// prebuilt prefix of another revision is refused by the build script.
165pub const JOLTC_EXT_REVISION: &str = env!("OXIJOLT_SYS_JOLTC_EXT_REVISION");
166
167/// `JPH_Mat4_RotationTranslation` under the name double precision uses.
168///
169/// joltc declares the `JPH_RMat4_*` functions only for double precision; in single precision
170/// `JPH_RMat4` is `JPH_Mat4` and `JPH_RVec3` is `JPH_Vec3`, so this forwards to the `JPH_Mat4_*`
171/// function and callers name one function in both builds.
172///
173/// # Safety
174/// As for the joltc function: `result` is valid for writing one matrix, `rotation` and
175/// `translation` are valid for reading.
176#[cfg(not(feature = "double-precision"))]
177#[allow(non_snake_case)]
178pub unsafe fn JPH_RMat4_RotationTranslation(
179    result: *mut JPH_RMat4,
180    rotation: *const JPH_Quat,
181    translation: *const JPH_RVec3,
182) {
183    // SAFETY: the caller upholds the joltc function's contract, and the types are identical in
184    // single precision.
185    unsafe { JPH_Mat4_RotationTranslation(result, rotation, translation) }
186}