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
/*!
Wrapper for PxBase.
 */

use crate::traits::Class;
use enumflags2::{bitflags, BitFlags};

pub(crate) use physx_sys::PxBase;

use physx_sys::{
    PxBaseFlag,
    PxBaseFlags,
    PxBase_getBaseFlags,
    PxBase_getConcreteType,
    PxBase_getConcreteTypeName,
    PxBase_isReleasable,
    PxBase_setBaseFlag_mut,
    PxBase_setBaseFlags_mut,
    //PxBase is non-instatiable, and any objects that use this dtor should call it directly
    //PxBase_release_mut,
};

/*******************************************************************************
 * Section ENUMERATIONS                                                        *
 ******************************************************************************/

#[bitflags]
#[derive(Copy, Clone, Debug)]
#[repr(u16)]
pub enum BaseFlag {
    OwnsMemory = 1,
    IsReleasable = 2,
}

impl From<BaseFlag> for PxBaseFlag::Enum {
    fn from(value: BaseFlag) -> Self {
        value as PxBaseFlag::Enum
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConcreteType {
    Undefined = 0,
    Heightfield = 1,
    ConvexMesh = 2,
    TriangleMeshBvh33 = 3,
    TriangleMeshBvh34 = 4,
    RigidDynamic = 5,
    RigidStatic = 6,
    Shape = 7,
    Material = 8,
    Constraint = 9,
    Aggregate = 10,
    Articulation = 11,
    ArticulationReducedCoordinate = 12,
    ArticulationLink = 13,
    ArticulationJoint = 14,
    ArticulationJointReducedCoordinate = 15,
    PruningStructure = 16,
    BvhStructure = 17,
    PhysxCoreCount = 18,
    FirstPhysxExtension = 256,
    FirstVehicleExtension = 512,
    FirstUserExtension = 1024,
}

impl From<u16> for ConcreteType {
    fn from(val: u16) -> Self {
        match val {
            1 => ConcreteType::Heightfield,
            2 => ConcreteType::ConvexMesh,
            3 => ConcreteType::TriangleMeshBvh33,
            4 => ConcreteType::TriangleMeshBvh34,
            5 => ConcreteType::RigidDynamic,
            6 => ConcreteType::RigidStatic,
            7 => ConcreteType::Shape,
            8 => ConcreteType::Material,
            9 => ConcreteType::Constraint,
            10 => ConcreteType::Aggregate,
            11 => ConcreteType::Articulation,
            12 => ConcreteType::ArticulationReducedCoordinate,
            13 => ConcreteType::ArticulationLink,
            14 => ConcreteType::ArticulationJoint,
            15 => ConcreteType::ArticulationJointReducedCoordinate,
            16 => ConcreteType::PruningStructure,
            17 => ConcreteType::BvhStructure,
            18 => ConcreteType::PhysxCoreCount,
            256 => ConcreteType::FirstPhysxExtension,
            512 => ConcreteType::FirstVehicleExtension,
            1024 => ConcreteType::FirstUserExtension,
            _ => ConcreteType::Undefined,
        }
    }
}

/*******************************************************************************
 * Section BASE                                                                *
 ******************************************************************************/
impl<T> Base for T where T: Class<PxBase> + Sized {}
pub trait Base: Class<PxBase> + Sized {
    /// Get the name of the real type referenced by this pointer, or None if the returned string is not valid
    fn get_concrete_type_name(&self) -> Option<&str> {
        unsafe {
            std::ffi::CStr::from_ptr(PxBase_getConcreteTypeName(self.as_ptr() as *const _) as _)
                .to_str()
                .ok()
        }
    }

    /// Returns an enumerated value identifying the type.  This may return ConcreteType::Undefined
    /// in surprising situations, notably this does not seem to work with `get_active_actors`.  Use
    /// `get_type` for actors if possible.
    fn get_concrete_type(&self) -> ConcreteType {
        unsafe { PxBase_getConcreteType(self.as_ptr()).into() }
    }

    /// Set or unset the specified flag on this object.
    fn set_base_flag(&mut self, flag: BaseFlag, value: bool) {
        unsafe {
            PxBase_setBaseFlag_mut(self.as_mut_ptr() as *mut _, flag.into(), value);
        }
    }

    /// Set the BaseFlags of this object. Note that replaces all flags currently
    /// on the object. Use `set_base_flag` to set individual flags.
    fn set_base_flags(&mut self, in_flags: BitFlags<BaseFlag>) {
        unsafe {
            PxBase_setBaseFlags_mut(
                self.as_mut_ptr() as *mut _,
                PxBaseFlags {
                    mBits: in_flags.bits(),
                },
            );
        }
    }

    /// Read the BaseFlags of this object
    fn get_base_flags(&self) -> BitFlags<BaseFlag> {
        let flags = unsafe { PxBase_getBaseFlags(self.as_ptr() as *const _) };
        unsafe { BitFlags::from_bits_unchecked(flags.mBits) }
    }

    ////////////////////////////////////////////////////////////////////////////////

    /// Returns true if this object can be released, i.e., it is not subordinate.
    fn is_releasable(&self) -> bool {
        unsafe { PxBase_isReleasable(self.as_ptr() as *const _) }
    }
}