Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to attach PxSimulationEventCallback / PxSimulationEventCallback #18

Closed
aguerrieri82 opened this issue Mar 9, 2024 · 4 comments
Closed
Labels

Comments

@aguerrieri82
Copy link

There is any way to implement PxSimulationEventCallback / PxSimulationEventCallback interfaces in c# to receive events / callbaks ?

I understand is not an easy task, I tried myself to rebuild the v-tables for PxContactModifyCallback / PxSimulationEventCallback interfaces without success (nothing is called back, no exceptions).

This what i've done so far:

[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
delegate void OnContactModifyDelegate(PxContactModifyPair* pairs, uint count);

_handler = (PxContactModifyCallback*)Marshal.AllocHGlobal(sizeof(PxSimulationEventCallback));

_handler->vtable_ = (void*)Marshal.AllocHGlobal(4 * sizeof(nint));
//first qword is 0, second is a pointer to the typeinfo, following the virtual functions. 
//No idea how to recover typeinfo descriptor pointer
((nint*)_handler->vtable_)[2] = Marshal.GetFunctionPointerForDelegate((OnContactModifyDelegate)OnContactModify);
((nint*)_handler->vtable_)[3] = Marshal.GetFunctionPointerForDelegate((VoidDelegate)Distructor);
@MartinPrograms
Copy link

MartinPrograms commented May 4, 2024

I've been having the same issue, found out that the function PxSimulationFilterShader must also be set. However a variable sent to that function seems to be incorrectly set.

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate PxFilterFlags PxSimulationFilterShader(uint attributes0, PxFilterData filterData0, uint attributes1, PxFilterData filterData1, ref PxPairFlags pairFlags, IntPtr constantBlock, uint constantBlockSize);
    
static PxFilterFlags CustomFilterShader(uint attributes0, PxFilterData filterData0, uint attributes1, PxFilterData filterData1, ref PxPairFlags pairFlags, IntPtr constantBlock, uint constantBlockSize)
{
    return PxFilterFlags.Kill;
}

How the original physx version works is that you decide based on the attributes and filterdata what the PxPairFlags should be, in this case however pairFlags is a broken memory address.

Unfortunately we have to use a custom filter shader to properly assign the pairflags which if properly set calls the simulation event callback.

I have been at it for a while now, and still haven't been able to figure it out.

This is where I got the filter idea from
NVIDIA Filter

NVIDIA Sim callback

You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in the filter shader/callback (see PxSimulationFilterShader) for a pair of rigid body objects.

EDIT: The error i get with the pairflags variable is CORDBG_E_BAD_REFERENCE_VALUE

@MartinPrograms
Copy link

Potential solution?
EmbarkStudios/physx-rs#145

Would have to make this in rust however, change the default there which would be sub optimal.

@MartinPrograms
Copy link

MartinPrograms commented May 4, 2024

Found it. I have On Contact working.

(small code dump about what I did)
Creating the callbacks:

    var simcallback = new SimulationEventCallbackInfo();
        simcallback.collision_callback = (delegate* unmanaged[Cdecl]<void*, PxContactPairHeader*, PxContactPair*, uint, void>)Marshal.GetFunctionPointerForDelegate<CollisionCallback>(OnContactDelegateInstance).ToPointer();
        var callbackinfoithink = create_simulation_event_callbacks(&simcallback);
        sceneDesc.simulationEventCallback = callbackinfoithink;
        
        var thing = (delegate* unmanaged[Cdecl]<FilterShaderCallbackInfo*, PxFilterFlags>)Marshal.GetFunctionPointerForDelegate<CustomFilterShaderDelegate>(CustomFilterShaderInstance).ToPointer();
        enable_custom_filter_shader(&sceneDesc, thing, (uint)1);

And the actual callbacks:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void CustomFilterShaderDelegate(FilterShaderCallbackInfo* callbackInfo, PxFilterFlags filterFlags);
    
    static void CustomFilterShader(FilterShaderCallbackInfo* callbackInfo, PxFilterFlags filterFlags)
    {
        PxPairFlags flags = PxPairFlags.ContactDefault | PxPairFlags.NotifyTouchFound;
        
        callbackInfo->pairFlags[0] = flags;
    }
    
    public CustomFilterShaderDelegate CustomFilterShaderInstance = CustomFilterShader; // Assign the managed delegate to the unmanaged delegate instance
    
    
    
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    // public delegate*unmanaged[Cdecl]<void*, PxContactPairHeader*, PxContactPair*, uint, void> OnContactDelegate;
    public delegate void CollisionCallback(IntPtr userData, PxContactPairHeader pairHeader, PxContactPair contacts, uint flags);    

    static void OnContact(IntPtr userData, PxContactPairHeader pairHeader, PxContactPair contacts, uint flags)
    {
        // On Contact...
        // This took 7~ hours to get working.
Console.WriteLine("OnContact");
    }
    
    public CollisionCallback OnContactDelegateInstance = OnContact; // Assign the managed delegate to the unmanaged delegate instance

This is all based on the rust post from earlier, translated to C#. The 7 hours includes the hours before I found this issue.

Copy link

github-actions bot commented Nov 1, 2024

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 30 days.

@github-actions github-actions bot added the stale label Nov 1, 2024
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Dec 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants