1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#![allow(non_upper_case_globals)]
#[macro_use]
extern crate bitflags;
extern crate num_derive;
use std::ptr::null_mut;

mod actor;
pub mod articulation;
pub mod articulation_reduced_coordinate;
mod base;
mod character_controller;
mod cooking;
mod geometry;
mod height_field;
mod joints;
mod mesh;
mod pvd;
mod raycast;
mod scene;
mod serialization;
mod shape;
pub mod sweep;
mod transform;
mod user_data;

pub use actor::*;
pub use articulation::*;
pub use base::*;
pub use character_controller::*;
pub use cooking::*;
pub use geometry::*;
pub use height_field::*;
pub use joints::*;
pub use mesh::*;
pub use physx_sys as sys;
pub use pvd::*;
pub use raycast::*;
pub use scene::*;
pub use serialization::*;
pub use shape::*;
pub use transform::*;
pub use user_data::*;

#[derive(Clone, Copy)]
pub struct PxFoundationRef(*mut physx_sys::PxFoundation);
impl PxFoundationRef {
    pub fn new() -> Self {
        unsafe { Self(physx_sys::physx_create_foundation()) }
    }
    pub fn get() -> Self {
        unsafe { Self(physx_sys::PxPhysics_getFoundation_mut(PxPhysicsRef::get().0)) }
    }
    pub fn release(self) {
        unsafe { physx_sys::PxFoundation_release_mut(self.0) }
    }
}
unsafe impl Sync for PxFoundationRef {}
unsafe impl Send for PxFoundationRef {}

pub const PX_PHYSICS_VERSION: u32 = physx_sys::version(4, 1, 1);

#[derive(Clone, Copy)]
pub struct PxPhysicsRef(*mut physx_sys::PxPhysics);
impl PxPhysicsRef {
    pub fn new(foundation: &PxFoundationRef) -> Self {
        Self(unsafe {
            physx_sys::phys_PxCreatePhysics(PX_PHYSICS_VERSION, foundation.0, &physx_sys::PxTolerancesScale_new(), true, null_mut())
        })
    }
    pub fn new_with_pvd(foundation: &PxFoundationRef, pvd: &PxPvdRef) -> Self {
        Self(unsafe { physx_sys::phys_PxCreatePhysics(PX_PHYSICS_VERSION, foundation.0, &physx_sys::PxTolerancesScale_new(), true, pvd.0) })
    }
    pub fn get() -> Self {
        Self(unsafe { physx_sys::phys_PxGetPhysics() })
    }
    fn get_physics_insertion_callback(&self) -> *mut physx_sys::PxPhysicsInsertionCallback {
        unsafe { physx_sys::PxPhysics_getPhysicsInsertionCallback_mut(self.0) }
    }
    fn get_tolerances_scale(&self) -> *const physx_sys::PxTolerancesScale {
        unsafe { physx_sys::PxPhysics_getTolerancesScale(self.0) }
    }
    pub fn release(self) {
        unsafe {
            physx_sys::PxPhysics_release_mut(self.0);
        }
    }
}
unsafe impl Sync for PxPhysicsRef {}
unsafe impl Send for PxPhysicsRef {}

pub fn px_init_extensions(physics: &PxPhysicsRef, pvd: &PxPvdRef) {
    assert!(unsafe { physx_sys::phys_PxInitExtensions(physics.0, pvd.0) })
}

#[derive(Clone, Copy)]
pub struct PxDefaultCpuDispatcherRef(*mut physx_sys::PxDefaultCpuDispatcher);
impl PxDefaultCpuDispatcherRef {
    pub fn new(num_threads: u32) -> Self {
        Self(unsafe { physx_sys::phys_PxDefaultCpuDispatcherCreate(num_threads, null_mut()) })
    }
    pub fn release(self) {
        unsafe { physx_sys::PxDefaultCpuDispatcher_release_mut(self.0) }
    }
}
unsafe impl Sync for PxDefaultCpuDispatcherRef {}
unsafe impl Send for PxDefaultCpuDispatcherRef {}

#[derive(Debug)]
pub struct PxMaterial(*mut physx_sys::PxMaterial);
impl PxMaterial {
    pub fn new(physics: PxPhysicsRef, static_friction: f32, dynamic_friction: f32, restitution: f32) -> Self {
        Self(unsafe { physx_sys::PxPhysics_createMaterial_mut(physics.0, static_friction, dynamic_friction, restitution) })
    }
    pub(crate) fn from_ptr(ptr: *mut physx_sys::PxMaterial) -> Self {
        let mut s = Self(ptr);
        s.acquire_reference();
        s
    }
    pub(crate) fn acquire_reference(&mut self) {
        unsafe { physx_sys::PxMaterial_acquireReference_mut(self.0) }
    }
}
impl AsPxBase for PxMaterial {
    fn as_base(&self) -> PxBaseRef {
        PxBaseRef(self.0 as _)
    }
}
impl Drop for PxMaterial {
    fn drop(&mut self) {
        unsafe { physx_sys::PxMaterial_release_mut(self.0) }
    }
}
impl Clone for PxMaterial {
    fn clone(&self) -> Self {
        Self::from_ptr(self.0)
    }
}
unsafe impl Sync for PxMaterial {}
unsafe impl Send for PxMaterial {}

#[derive(Debug, Clone, Copy)]
pub struct PxAggregateRef(*mut physx_sys::PxAggregate);
impl PxAggregateRef {
    pub fn new(physics: &PxPhysicsRef, max_size: u32, self_collisions: bool) -> Self {
        Self(unsafe { physx_sys::PxPhysics_createAggregate_mut(physics.0, max_size, self_collisions) })
    }
    pub fn add_actor(&mut self, actor: &dyn AsPxActor) -> bool {
        unsafe { physx_sys::PxAggregate_addActor_mut(self.0, actor.as_actor().0, null_mut()) }
    }
    pub fn get_nb_actors(&self) -> u32 {
        unsafe { physx_sys::PxAggregate_getNbActors(self.0) }
    }
    pub fn get_max_nb_actors(&self) -> u32 {
        unsafe { physx_sys::PxAggregate_getMaxNbActors(self.0) }
    }
    pub fn release(&mut self) {
        unsafe { physx_sys::PxAggregate_release_mut(self.0) }
    }
}
impl AsPxBase for PxAggregateRef {
    fn as_base(&self) -> PxBaseRef {
        PxBaseRef(self.0 as _)
    }
}
unsafe impl Sync for PxAggregateRef {}
unsafe impl Send for PxAggregateRef {}

pub trait PxReferenceCounted {
    fn get_reference_count(&self) -> u32;
}