physxCAPI/physxCDLL/physxCallback.hpp
2023-08-11 10:55:58 +08:00

634 lines
26 KiB
C++
Raw Permalink Blame History

#include "PxPhysicsAPI.h"
#include "physxABIStruct.hpp"
//
//
extern "C"
{
struct FilterShaderCallbackInfo
{
physx::PxFilterObjectAttributes attributes0;
physx::PxFilterObjectAttributes attributes1;
physx::PxFilterData filterData0;
physx::PxFilterData filterData1;
physx::PxPairFlags* pairFlags;
const void* constantBlock;
physx::PxU32 constantBlockSize;
};
typedef void (*CollisionCallback)(void*, physx::PxContactPairHeader const*, physx::PxContactPair const*, physx::PxU32);
typedef physx::PxU16(*SimulationShaderFilter)(FilterShaderCallbackInfo*);
struct FilterCallbackData {
SimulationShaderFilter filter;
bool call_default_filter_shader_first;
};
physx::PxFilterFlags FilterShaderTrampoline(physx::PxFilterObjectAttributes attributes0,
physx::PxFilterData filterData0,
physx::PxFilterObjectAttributes attributes1,
physx::PxFilterData filterData1,
physx::PxPairFlags& pairFlags,
const void* constantBlock,
physx::PxU32 constantBlockSize)
{
const FilterCallbackData* data = static_cast<const FilterCallbackData*>(constantBlock);
if (data->call_default_filter_shader_first) {
// Let the default handler set the pair flags, but ignore the collision filtering
PxDefaultSimulationFilterShader(attributes0, filterData0, attributes1, filterData1, pairFlags, constantBlock,
constantBlockSize);
}
// Get the filter shader from the constant block
SimulationShaderFilter shaderfilter = data->filter;
// This is a bit expensive since we're putting things on the stack but with LTO this should optimize OK,
// and I was having issues with corrupted values when passing by value
FilterShaderCallbackInfo info{ attributes0, attributes1, filterData0, filterData1, &pairFlags, nullptr, 0 };
// We return a u16 since PxFilterFlags is a complex type and C++ wants it to be returned on the stack,
// but Rust thinks it's simple due to the codegen and wants to return it in EAX.
return physx::PxFilterFlags{ shaderfilter(&info) };
}
using PairFoundCallback = physx::PxFilterFlags(*)(physx::PxU64, physx::PxFilterObjectAttributes, physx::PxFilterData, const physx::PxActor*, const physx::PxShape*,
physx::PxFilterObjectAttributes, physx::PxFilterData, const physx::PxActor*, const physx::PxShape*, physx::PxPairFlags&);
using PairLostCallback = void (*)(physx::PxU64, physx::PxFilterObjectAttributes, physx::PxFilterData, physx::PxFilterObjectAttributes, physx::PxFilterData, bool);
using StatusChangeCallback = bool (*)(physx::PxU64&, physx::PxPairFlags&, physx::PxFilterFlags&);
struct SimuliationFilterCallBackInfo {
// Callback for pairFound
PairFoundCallback pairFoundCallback = nullptr;
PairLostCallback pairLostCallback = nullptr;
StatusChangeCallback statusChangeCallback = nullptr;
};
//
//
class SimulationFilterCallBackTrampoline : public physx::PxSimulationFilterCallback
{
public:
SimulationFilterCallBackTrampoline(const SimuliationFilterCallBackInfo* callbacks) : mCallbacks(*callbacks) {}
// Collisions
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ܴ<EFBFBD><DCB4><EFBFBD>bug
physx::PxFilterFlags pairFound(physx::PxU64 pairID,
physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, const physx::PxActor* a0, const physx::PxShape* s0,
physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1, const physx::PxActor* a1, const physx::PxShape* s1,
physx::PxPairFlags& pairFlags) override
{
if (mCallbacks.pairFoundCallback) {
return mCallbacks.pairFoundCallback(pairID,
attributes0, filterData0, a0, s0,
attributes1, filterData1, a1, s1,
pairFlags);
}
}
// Triggers
void pairLost(physx::PxU64 pairID,
physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0,
physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1,
bool objectRemoved) override
{
if (mCallbacks.pairLostCallback) {
mCallbacks.pairLostCallback(pairID, attributes0, filterData0,
attributes1, filterData1, objectRemoved);
}
}
// Constraint breaks
bool statusChange(physx::PxU64& pairID, physx::PxPairFlags& pairFlags, physx::PxFilterFlags& filterFlags) override
{
if (mCallbacks.statusChangeCallback) {
return mCallbacks.statusChangeCallback(pairID, pairFlags, filterFlags);
}
}
SimuliationFilterCallBackInfo mCallbacks;
};
//
//
//
using CollisionCallback = void (*)(void*, physx::PxContactPairHeader const*, physx::PxContactPair const*, physx::PxU32);
using TriggerCallback = void (*)(void*, physx::PxTriggerPair const*, physx::PxU32);
using ConstraintBreakCallback = void (*)(void*, physx::PxConstraintInfo const*, physx::PxU32);
using WakeSleepCallback = void (*)(void*, physx::PxActor** const, physx::PxU32, bool);
using AdvanceCallback = void (*)(void*, const physx::PxRigidBody* const*, const physx::PxTransform* const, physx::PxU32);
//
//
struct SimulationEventCallbackInfo {
// Callback for collision events.
CollisionCallback collisionCallback = nullptr;
void* collisionUserData = nullptr;
// Callback for trigger shape events (an object entered or left a trigger shape).
TriggerCallback triggerCallback = nullptr;
void* triggerUserData = nullptr;
// Callback for when a constraint breaks (such as a joint with a force limit)
ConstraintBreakCallback constraintBreakCallback = nullptr;
void* constraintBreakUserData = nullptr;
// Callback for when an object falls asleep or is awoken.
WakeSleepCallback wakeSleepCallback = nullptr;
void* wakeSleepUserData = nullptr;
// Callback to get the next pose early for objects (if flagged with eENABLE_POSE_INTEGRATION_PREVIEW).
AdvanceCallback advanceCallback = nullptr;
void* advanceUserData = nullptr;
};
//
//
//
class SimulationEventTrampoline : public physx::PxSimulationEventCallback
{
public:
SimulationEventTrampoline(const SimulationEventCallbackInfo* callbacks) : mCallbacks(*callbacks) {}
// Collisions
void onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) override {
if (mCallbacks.collisionCallback) {
mCallbacks.collisionCallback(mCallbacks.collisionUserData, &pairHeader, pairs, nbPairs);
}
}
// Triggers
void onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count) override {
if (mCallbacks.triggerCallback) {
mCallbacks.triggerCallback(mCallbacks.triggerUserData, pairs, count);
}
}
// Constraint breaks
void onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count) override {
if (mCallbacks.constraintBreakCallback) {
mCallbacks.constraintBreakCallback(mCallbacks.constraintBreakUserData, constraints, count);
}
}
// Wake/Sleep (combined for convenience)
void onWake(physx::PxActor** actors, physx::PxU32 count) override {
if (mCallbacks.wakeSleepCallback) {
mCallbacks.wakeSleepCallback(mCallbacks.wakeSleepUserData, actors, count, true);
}
}
void onSleep(physx::PxActor** actors, physx::PxU32 count) override {
if (mCallbacks.wakeSleepCallback) {
mCallbacks.wakeSleepCallback(mCallbacks.wakeSleepUserData, actors, count, false);
}
}
// Advance
void onAdvance(const physx::PxRigidBody* const* bodyBuffer, const physx::PxTransform* poseBuffer, const physx::PxU32 count) override {
if (mCallbacks.advanceCallback) {
mCallbacks.advanceCallback(mCallbacks.advanceUserData, bodyBuffer, poseBuffer, count);
}
}
SimulationEventCallbackInfo mCallbacks;
};
//
class RaycastFilterCallback : public physx::PxQueryFilterCallback
{
public:
explicit RaycastFilterCallback(physx::PxRigidActor* actor) : mActor(actor) {}
physx::PxRigidActor* mActor;
virtual physx::PxQueryHitType::Enum preFilter(const physx::PxFilterData&, const physx::PxShape* shape,
const physx::PxRigidActor* actor, physx::PxHitFlags&)
{
if (mActor == actor)
{
return physx::PxQueryHitType::eNONE;
}
else
{
return physx::PxQueryHitType::eBLOCK;
}
}
virtual physx::PxQueryHitType::Enum postFilter(const physx::PxFilterData& filterData, const physx::PxQueryHit& hit, const physx::PxShape* shape,
const physx::PxRigidActor* actor)
{
return physx::PxQueryHitType::eNONE;
}
};
// TODO: Shouldn't we rename this to PreFilterCallback?
typedef uint32_t(*RaycastHitCallback)(const physx::PxRigidActor* actor, const physx::PxFilterData* filterData, const physx::PxShape* shape, uint32_t hitFlags, const void* userData);
typedef uint32_t(*PostFilterCallback)(const physx::PxFilterData* filterData, const physx::PxQueryHit* hit, const void* userData);
physx::PxQueryHitType::Enum sanitize_hit_type(uint32_t hit_type) {
switch (hit_type) {
case physx::PxQueryHitType::eNONE:
case physx::PxQueryHitType::eTOUCH:
case physx::PxQueryHitType::eBLOCK: return (physx::PxQueryHitType::Enum)hit_type;
default: return physx::PxQueryHitType::eNONE;
}
}
//
class RaycastFilterTrampoline : public physx::PxQueryFilterCallback
{
public:
RaycastFilterTrampoline(RaycastHitCallback callback, const void* userdata)
: mCallback(callback), mUserData(userdata) {}
RaycastHitCallback mCallback;
const void* mUserData;
virtual physx::PxQueryHitType::Enum preFilter(const physx::PxFilterData& filterData, const physx::PxShape* shape, const physx::PxRigidActor* actor, physx::PxHitFlags& hitFlags)
{
return sanitize_hit_type(mCallback(actor, &filterData, shape, (uint32_t)hitFlags, mUserData));
}
virtual physx::PxQueryHitType::Enum postFilter(const physx::PxFilterData& filterData, const physx::PxQueryHit& hit,
const physx::PxShape* shape, const physx::PxRigidActor* actor)
{
return physx::PxQueryHitType::eNONE;
}
//virtual physx::PxQueryHitType::Enum postFilter(const physx::PxFilterData&, const physx::PxQueryHit&)
//{
// return physx::PxQueryHitType::eNONE;
//}
};
//
//
class RaycastFilterPrePostTrampoline : public physx::PxQueryFilterCallback
{
public:
RaycastFilterPrePostTrampoline(RaycastHitCallback preFilter, PostFilterCallback postFilter, const void* userdata)
: mPreFilter(preFilter), mPostFilter(postFilter), mUserData(userdata) {}
RaycastHitCallback mPreFilter;
PostFilterCallback mPostFilter;
const void* mUserData;
virtual physx::PxQueryHitType::Enum preFilter(const physx::PxFilterData& filterData, const physx::PxShape* shape, const physx::PxRigidActor* actor, physx::PxHitFlags& hitFlags)
{
return sanitize_hit_type(mPreFilter(actor, &filterData, shape, (uint32_t)hitFlags, mUserData));
}
//<2F><>Ҫ<EFBFBD><D2AA><EFBFBD>¹<EFBFBD>ע<EFBFBD><D7A2>
virtual physx::PxQueryHitType::Enum postFilter(const physx::PxFilterData& filterData, const physx::PxQueryHit& hit,
const physx::PxShape* shape, const physx::PxRigidActor* actor)
{
return sanitize_hit_type(mPostFilter(&filterData, &hit, mUserData));
}
//virtual physx::PxQueryHitType::Enum postFilter(const physx::PxFilterData& filterData, const physx::PxQueryHit& hit)
//{
// return sanitize_hit_type(mPostFilter(&filterData, &hit, mUserData));
//}
};
//
typedef physx::PxAgain(*RaycastHitProcessTouchesCallback)(const physx::PxRaycastHit* buffer, physx::PxU32 nbHits, void* userdata);
typedef physx::PxAgain(*SweepHitProcessTouchesCallback)(const physx::PxSweepHit* buffer, physx::PxU32 nbHits, void* userdata);
typedef physx::PxAgain(*OverlapHitProcessTouchesCallback)(const physx::PxOverlapHit* buffer, physx::PxU32 nbHits, void* userdata);
typedef void (*HitFinalizeQueryCallback)(void* userdata);
//
class RaycastHitCallbackTrampoline : public physx::PxRaycastCallback
{
public:
RaycastHitCallbackTrampoline(
RaycastHitProcessTouchesCallback processTouchesCallback,
HitFinalizeQueryCallback finalizeQueryCallback,
physx::PxRaycastHit* touchesBuffer,
physx::PxU32 numTouches,
void* userdata)
: physx::PxRaycastCallback(touchesBuffer, numTouches),
mProcessTouchesCallback(processTouchesCallback),
mFinalizeQueryCallback(finalizeQueryCallback),
mUserData(userdata) {}
RaycastHitProcessTouchesCallback mProcessTouchesCallback;
HitFinalizeQueryCallback mFinalizeQueryCallback;
void* mUserData;
physx::PxAgain processTouches(const physx::PxRaycastHit* buffer, physx::PxU32 nbHits) override
{
return mProcessTouchesCallback(buffer, nbHits, mUserData);
}
void finalizeQuery() override
{
mFinalizeQueryCallback(mUserData);
}
};
//
class SweepHitCallbackTrampoline : public physx::PxSweepCallback
{
public:
SweepHitCallbackTrampoline(
SweepHitProcessTouchesCallback processTouchesCallback,
HitFinalizeQueryCallback finalizeQueryCallback,
physx::PxSweepHit* touchesBuffer,
physx::PxU32 numTouches,
void* userdata)
: physx::PxSweepCallback(touchesBuffer, numTouches),
mProcessTouchesCallback(processTouchesCallback),
mFinalizeQueryCallback(finalizeQueryCallback),
mUserData(userdata) {}
SweepHitProcessTouchesCallback mProcessTouchesCallback;
HitFinalizeQueryCallback mFinalizeQueryCallback;
void* mUserData;
physx::PxAgain processTouches(const physx::PxSweepHit* buffer, physx::PxU32 nbHits) override
{
return mProcessTouchesCallback(buffer, nbHits, mUserData);
}
void finalizeQuery() override
{
mFinalizeQueryCallback(mUserData);
}
};
//
class OverlapHitCallbackTrampoline : public physx::PxOverlapCallback
{
public:
OverlapHitCallbackTrampoline(
OverlapHitProcessTouchesCallback processTouchesCallback,
HitFinalizeQueryCallback finalizeQueryCallback,
physx::PxOverlapHit* touchesBuffer,
physx::PxU32 numTouches,
void* userdata)
: physx::PxOverlapCallback(touchesBuffer, numTouches),
mProcessTouchesCallback(processTouchesCallback),
mFinalizeQueryCallback(finalizeQueryCallback),
mUserData(userdata) {}
OverlapHitProcessTouchesCallback mProcessTouchesCallback;
HitFinalizeQueryCallback mFinalizeQueryCallback;
void* mUserData;
physx::PxAgain processTouches(const physx::PxOverlapHit* buffer, physx::PxU32 nbHits) override
{
return mProcessTouchesCallback(buffer, nbHits, mUserData);
}
void finalizeQuery() override
{
mFinalizeQueryCallback(mUserData);
}
};
typedef void* (*AllocCallback)(uint64_t size, const char* typeName, const char* filename, int line, void* userdata);
typedef void (*DeallocCallback)(void* ptr, void* userdata);
class CustomAllocatorTrampoline : public physx::PxAllocatorCallback {
public:
CustomAllocatorTrampoline(AllocCallback allocCb, DeallocCallback deallocCb, void* userdata)
: mAllocCallback(allocCb), mDeallocCallback(deallocCb), mUserData(userdata) {}
void* allocate(size_t size, const char* typeName, const char* filename, int line)
{
return mAllocCallback((uint64_t)size, typeName, filename, line, mUserData);
}
virtual void deallocate(void* ptr)
{
mDeallocCallback(ptr, mUserData);
}
private:
AllocCallback mAllocCallback;
DeallocCallback mDeallocCallback;
public:
void* mUserData;
};
typedef void* (*ZoneStartCallback)(const char* typeName, bool detached, uint64_t context, void* userdata);
typedef void (*ZoneEndCallback)(void* profilerData, const char* typeName, bool detached, uint64_t context, void* userdata);
class CustomProfilerTrampoline : public physx::PxProfilerCallback {
public:
CustomProfilerTrampoline(ZoneStartCallback startCb, ZoneEndCallback endCb, void* userdata)
: mStartCallback(startCb), mEndCallback(endCb), mUserData(userdata) {
}
virtual void* zoneStart(const char* eventName, bool detached, uint64_t contextId) override
{
return mStartCallback(eventName, detached, contextId, mUserData);
}
virtual void zoneEnd(void* profilerData, const char* eventName, bool detached, uint64_t contextId) override
{
return mEndCallback(profilerData, eventName, detached, contextId, mUserData);
}
private:
ZoneStartCallback mStartCallback;
ZoneEndCallback mEndCallback;
public:
void* mUserData;
};
using ErrorCallback = void (*)(int code, const char* message, const char* file, int line, void* userdata);
class ErrorTrampoline : public physx::PxErrorCallback {
public:
ErrorTrampoline(ErrorCallback errorCb, void* userdata)
: mErrorCallback(errorCb), mUserdata(userdata)
{}
void reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line) override {
mErrorCallback(code, message, file, line, mUserdata);
}
private:
ErrorCallback mErrorCallback = nullptr;
void* mUserdata = nullptr;
};
//using AssertHandler = void (*)(const char* expr, const char* file, int line, bool* should_ignore, void* userdata);
//class AssertTrampoline : public physx::PxAssertHandler {
//public:
// AssertTrampoline(AssertHandler onAssert, void* userdata)
// : mAssertHandler(onAssert), mUserdata(userdata)
// {}
//
// virtual void operator()(const char* exp, const char* file, int line, bool& ignore) override final {
// mAssertHandler(exp, file, line, &ignore, mUserdata);
// }
//
//private:
// AssertHandler mAssertHandler = nullptr;
// void* mUserdata = nullptr;
//};
// fixme[tolsson]: this might be iffy on Windows with DLLs if we have multiple packages
// linking against the raw interface
//physx::PxErrorCallback* get_default_error_callback()
//{
// return &gErrorCallback;
//}
physx::PxPhysics* physx_create_physics(physx::PxFoundation* foundation)
{
return PxCreatePhysics(PX_PHYSICS_VERSION, *foundation, physx::PxTolerancesScale(), true, nullptr, nullptr);
}
physx::PxQueryFilterCallback* create_raycast_filter_callback(physx::PxRigidActor* actor_to_ignore)
{
return new RaycastFilterCallback(actor_to_ignore);
}
physx::PxQueryFilterCallback* create_raycast_filter_callback_func(RaycastHitCallback callback, void* userData)
{
return new RaycastFilterTrampoline(callback, userData);
}
physx::PxQueryFilterCallback* create_pre_and_post_raycast_filter_callback_func(RaycastHitCallback preFilter, PostFilterCallback postFilter, void* userData)
{
return new RaycastFilterPrePostTrampoline(preFilter, postFilter, userData);
}
physx::PxRaycastCallback* create_raycast_callback(
RaycastHitProcessTouchesCallback process_touches_callback,
HitFinalizeQueryCallback finalize_query_callback,
physx::PxRaycastHit* touchesBuffer,
physx::PxU32 numTouches,
void* userdata
) {
return new RaycastHitCallbackTrampoline(
process_touches_callback, finalize_query_callback, touchesBuffer, numTouches, userdata);
}
void delete_raycast_callback(physx::PxRaycastCallback* callback)
{
delete callback;
}
void delete_sweep_callback(physx::PxSweepCallback* callback)
{
delete callback;
}
void delete_overlap_callback(physx::PxOverlapCallback* callback)
{
delete callback;
}
physx::PxSweepCallback* create_sweep_callback(
SweepHitProcessTouchesCallback process_touches_callback,
HitFinalizeQueryCallback finalize_query_callback,
physx::PxSweepHit* touchesBuffer,
physx::PxU32 numTouches,
void* userdata
) {
return new SweepHitCallbackTrampoline(
process_touches_callback, finalize_query_callback, touchesBuffer, numTouches, userdata
);
}
physx::PxOverlapCallback* create_overlap_callback(
OverlapHitProcessTouchesCallback process_touches_callback,
HitFinalizeQueryCallback finalize_query_callback,
physx::PxOverlapHit* touchesBuffer,
physx::PxU32 numTouches,
void* userdata
) {
return new OverlapHitCallbackTrampoline(
process_touches_callback, finalize_query_callback, touchesBuffer, numTouches, userdata
);
}
physx::PxAllocatorCallback* create_alloc_callback(
AllocCallback alloc_callback,
DeallocCallback dealloc_callback,
void* userdata
) {
return new CustomAllocatorTrampoline(alloc_callback, dealloc_callback, userdata);
}
void* get_alloc_callback_user_data(physx::PxAllocatorCallback* allocator) {
CustomAllocatorTrampoline* trampoline = static_cast<CustomAllocatorTrampoline*>(allocator);
return trampoline->mUserData;
}
physx::PxProfilerCallback* create_profiler_callback(
ZoneStartCallback zone_start_callback,
ZoneEndCallback zone_end_callback,
void* userdata
) {
return new CustomProfilerTrampoline(zone_start_callback, zone_end_callback, userdata);
}
physx::PxErrorCallback* create_error_callback(
ErrorCallback error_callback,
void* userdata
) {
return new ErrorTrampoline(error_callback, userdata);
}
//physx::PxAssertHandler* create_assert_handler( AssertHandler on_assert,void* userdata )
//{
// return new AssertTrampoline(on_assert, userdata);
//}
void* get_default_simulation_filter_shader()
{
return (void*)physx::PxDefaultSimulationFilterShader;
}
physx::PxSimulationFilterCallback* create_simulation_filter_callbacks(const SimuliationFilterCallBackInfo* callbacks)
{
SimulationFilterCallBackTrampoline* trampoline = new SimulationFilterCallBackTrampoline(callbacks);
return static_cast<physx::PxSimulationFilterCallback*>(trampoline);
}
void destroy_simulation_filter_callbacks(physx::PxSimulationFilterCallback* callback)
{
SimulationFilterCallBackTrampoline* trampoline = static_cast<SimulationFilterCallBackTrampoline*>(callback);
delete trampoline;
}
physx::PxSimulationEventCallback* create_simulation_event_callbacks(const SimulationEventCallbackInfo* callbacks)
{
SimulationEventTrampoline* trampoline = new SimulationEventTrampoline(callbacks);
return static_cast<physx::PxSimulationEventCallback*>(trampoline);
}
SimulationEventCallbackInfo* get_simulation_event_info(physx::PxSimulationEventCallback* callback)
{
SimulationEventTrampoline* trampoline = static_cast<SimulationEventTrampoline*>(callback);
return &trampoline->mCallbacks;
}
void destroy_simulation_event_callbacks(physx::PxSimulationEventCallback* callback)
{
SimulationEventTrampoline* trampoline = static_cast<SimulationEventTrampoline*>(callback);
delete trampoline;
}
void enable_custom_filter_shader(physx::PxSceneDesc* desc, SimulationShaderFilter filter, uint32_t call_default_filter_shader_first)
{
/* Note: This is a workaround to PhysX copying the filter data */
static FilterCallbackData filterShaderData = {
filter,
call_default_filter_shader_first != 0
};
desc->filterShader = FilterShaderTrampoline;
// printf("Setting pointer to %p\n", filter);
desc->filterShaderData = (void*)&filterShaderData;
desc->filterShaderDataSize = sizeof(FilterCallbackData);
}
//// Not generated, used only for testing and examples!
//void PxAssertHandler_opCall_mut(physx_PxErrorCallback_Pod* self__pod, char const* expr, char const* file, int32_t line, bool* ignore) {
// physx::PxAssertHandler* self_ = reinterpret_cast<physx::PxAssertHandler*>(self__pod);
// (*self_)(expr, file, line, *ignore);
//};
}