EmbarkStudios / physx-rs

🎳 Rust binding for NVIDIA PhysX 🦀
http://embark.rs
Apache License 2.0
658 stars 43 forks source link

How to get collision callback to work? #145

Open mlp1802 opened 2 years ago

mlp1802 commented 2 years ago

I'm using pure physx (physx-sys). The problem is that my "onConnect" (when bodies collides) never gets called. The filter shader is called though. Here is the scene creation.

pub fn create_scene(physics: PtrPhysics, gravity: f32) -> PtrScene {
    unsafe {
        let mut scene_desc: PS::PxSceneDesc =
            PS::PxSceneDesc_new(PS::PxPhysics_getTolerancesScale(physics));
        scene_desc.gravity = PS::PxVec3 {
            x: 0.0,
            y: gravity,
            z: 0.0,
        };

        unsafe extern "C" fn filterShader(mut s: *mut PS::FilterShaderCallbackInfo) -> u16 {
            use PS::PxPairFlag as F;
            let mut f = PS::PxPairFlags {
                mBits: (F::eCONTACT_DEFAULT | F::eNOTIFY_TOUCH_FOUND) as u16,
            }; //;;
            (*s).pairFlags = &mut f;
            (PS::PxFilterFlag::eDEFAULT) as u16
        }
        unsafe extern "C" fn onConnect(   //<--- This never gets called
            a: *mut std::ffi::c_void,
            b: *const PS::PxContactPairHeader,
            c: *const PS::PxContactPair,
            d: u32,
        ) {
            println!("Connecting!"); //but it doesn't :(
        };
        let info = PS::SimulationEventCallbackInfo {
            collision_callback: Some(onConnect),
            ..Default::default()
        };
        let simulation_event_callback = PS::create_simulation_event_callbacks(&info);
        scene_desc.simulationEventCallback = simulation_event_callback;
        let dispatcher = PS::phys_PxDefaultCpuDispatcherCreate(1, null_mut());
        scene_desc.cpuDispatcher = dispatcher as *mut PS::PxCpuDispatcher;
         PS::enable_custom_filter_shader(&mut scene_desc, shader, 1);
        let scene = PS::PxPhysics_createScene_mut(physics, &scene_desc);
        scene
    }
}

And this is how I set the filter data

pub fn set_filter_data(actor: *mut PS::PxRigidActor) {
    unsafe {
        let data = PS::PxFilterData_new_2(2, 2, 2, 2);
        let capacity = PS::PxRigidActor_getNbShapes(actor);
        let mut buffer: Vec<*mut PS::PxShape> = Vec::with_capacity(capacity as usize);
        let len =
            PS::PxRigidActor_getShapes(actor, buffer.as_mut_ptr() as *mut *mut _, capacity, 0);
        buffer.set_len(len as usize);
         for n in 0..(len as usize) {
            let shape = buffer.get(n);
            match shape {
                None => {}
                Some(ptr) => {
                    PS::PxShape_setSimulationFilterData_mut(*ptr, &data);
                }
            }
        }
    }
}

I saw the PxSimulationFilterCallback_pairFound_mut ? method but that is supposed to be overriden, not called, and how should it be overriden? I'm really at a loss, there is no crashes, it just doesn't work for some reason.

Are there perhaps some examples out there on how it works? Couldn't find any so far.

mlp1802 commented 2 years ago

Solved:
In the shader I had to do this: (*(*s).pairFlags).mBits = (F::eCONTACT_DEFAULT | F::eNOTIFY_TOUCH_FOUND) as u16;

Ps, how about a forum or similar for physx_rust?