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

Physx 5 support #43

Open
tlf30 opened this issue Nov 8, 2022 · 28 comments
Open

Physx 5 support #43

tlf30 opened this issue Nov 8, 2022 · 28 comments

Comments

@tlf30
Copy link

tlf30 commented Nov 8, 2022

Hello,
I'm going to make a huge request, apologies.
Physx 5 was finally released today. https://github.com/NVIDIA-Omniverse/PhysX

Would it be possible to create bindings for it as well?

Thanks,
Trevor

@fabmax
Copy link
Owner

fabmax commented Nov 9, 2022

Oh wow, I was waiting for PhysX 5 for years! I'm definetly going to work on this but it will probably take a while...

@tlf30
Copy link
Author

tlf30 commented Nov 9, 2022

No worries if it takes a while, Physx 5 took so long that I think we are used to waiting 😆

Perhaps topic for a different discussion, but you do an amazing job on these C++ to JNI bindings, if you get some free time (which none of us have) it would be awesome to get bindings for NVIDIA aftermath built with the VULKAN directives in place (DirectX is not usable from java so no need to support it). I have run into many situations where it would be very handy to have a way to get a GPU crash report. If you got a base repo started, I would be more than happy to contribute PRs to it and do testing.

Once you have Physx5 started, I will also be active on that. I did not want to bother with Physx4 support in my engine as I was holding out for 5, so once momentum starts on 5 I will be working on getting it integrated and can help with PRs and testing.

@fabmax
Copy link
Owner

fabmax commented Nov 10, 2022

Alright, I took a quick glimpse into the PhysX5 code and apparently the API hasn't changed too much, so the existing stuff should be rather easy to port.

A bit disappointing is that the cool new stuff (soft-bodies and particles / cloth) requires CUDA. So that part will only be usable with an Nvidia GPU.

For the aftermath stuff, I will keep that in mind but no promises when/if I will come to that 😄

@tlf30
Copy link
Author

tlf30 commented Nov 10, 2022

I personally only run NVIDIA GPUs, but I agree, many of my target end users are running many non-NVIDIA GPUs. I was especially looking forward to the particle system, but I guess I will only enable it on NVIDIA systems....

@fabmax
Copy link
Owner

fabmax commented Nov 11, 2022

Ok, the basic setup is done: https://github.com/fabmax/physx-jni/tree/physx5

For now, it's only a working Hello World. More to come in the next days...

@fabmax
Copy link
Owner

fabmax commented Nov 18, 2022

Alright, I think the PhysX 5 bindings are usable now and I merged them into main 🚀

They aren't yet complete though. Compared to the old PhysX 4 binsings, vehicles and Mac OS support are atill missing. The vehicle API has changed substantially with v5 and unfortunately isn't very Java friendly, so I have postponed this for now. Mac OS isn't an officially supported build target anymore, although it should be possible to compile the native libs for Mac anyway (later).

CUDA already works but for now only with rigid bodies. I still haven't looked into the new stuff.

So still lots of work to do but the standard stuff already works well

@tlf30
Copy link
Author

tlf30 commented Nov 18, 2022

Great, thank you much for working on this.
I'm currently traveling for work and won't have much time to test yet. I get home on the 29th and will be able to begin playing with it.

@Sm0keySa1m0n
Copy link
Contributor

Is custom geometry support on the roadmap (PxCustomGeometry)?

@fabmax
Copy link
Owner

fabmax commented Nov 24, 2022

Is custom geometry support on the roadmap (PxCustomGeometry)?

Not so far. The callbacks look quite complex but at first glance it seems doable, so maybe 😄
Any particular usecases?

@Sm0keySa1m0n
Copy link
Contributor

Is custom geometry support on the roadmap (PxCustomGeometry)?

Not so far. The callbacks look quite complex but at first glance it seems doable, so maybe 😄

Any particular usecases?

I'm building a Minecraft-like voxel game so it'll be very useful for block collision detection.

@fabmax
Copy link
Owner

fabmax commented Dec 5, 2022

Is custom geometry support on the roadmap (PxCustomGeometry)?

The latest snapshot contains bindings for PxCustomGeometry. In order to use it you need to subclass SimpleCustomGeometryCallbacksImpl and implement the required callback methods. Then, pass an instance of the callbacks to the PxCustomGeometry constructor.

It's completely untested though...

@Sm0keySa1m0n
Copy link
Contributor

Is custom geometry support on the roadmap (PxCustomGeometry)?

The latest snapshot contains bindings for PxCustomGeometry. In order to use it you need to subclass SimpleCustomGeometryCallbacksImpl and implement the required callback methods. Then, pass an instance of the callbacks to the PxCustomGeometry constructor.

It's completely untested though...

Awesome, I'll give it a go.

@fabmax
Copy link
Owner

fabmax commented Dec 5, 2022

One more thing I forgot to mention: The original C++ usePersistentContactManifold() callback method has an output float parameter breakingThreshold, which does not work in Java (because primitive types are always passed by value). As a workaround there is a member variable setPersistentContactManifold_outBreakingThreshold, which you can set when usePersistentContactManifold() is called. The value of the member is then assigned to the C++ parameter.

Here's the C++ code for that:
https://github.com/fabmax/PhysX/blob/00e0f60f615b1cc6e7e9ef7bce521ec430c4439a/physx/source/webidlbindings/src/common/WebIdlBindings.h#L284

@tlf30
Copy link
Author

tlf30 commented Feb 2, 2023

I took a quick glance and might have missed it, but I did not see anything for blast or flow yet. Are those on your list to build bindings for?

@fabmax
Copy link
Owner

fabmax commented Feb 2, 2023

Generally yes but not with particularly high priority. At least for blast, the PhysX 5 integration also seems still to be in progress (see this discussion)

Flow I haven't really checked out yet...

@zalo
Copy link

zalo commented Dec 15, 2023

@fabmax Would it be possible to add the functions for creating Tetrahedral Meshes? I wrote a GPU Simulator for PhysX-style TetMesh + Simulation Mesh pairs, but the primary thing missing is the ability to bake TetMeshes from Surface Meshes.

The functions from PxTetMakerExt.h (and optionally PxTetrahedronMeshExt.h?) would be ideal!

It would be cool to put a pretty-serious foot forward towards ubiquitous soft-body simulation in the browser 😄

@fabmax
Copy link
Owner

fabmax commented Dec 15, 2023

At first glance, I think it should be possible, but I haven't really looked into the whole soft-body stuff yet. As far as I know the PhysX soft bodies require CUDA, do you have an alternative solution for the browser?

@zalo
Copy link

zalo commented Dec 15, 2023

As far as I know the PhysX soft bodies require CUDA, do you have an alternative solution for the browser?

Yes! I’m writing one: https://zalo.github.io/TetSim/

@fabmax
Copy link
Owner

fabmax commented Dec 15, 2023

Ah nice! I will see what I can do for the tet meshes

@fabmax
Copy link
Owner

fabmax commented Dec 18, 2023

@zalo I added bindings for PxTetMakerExt and PxTetrahedronMeshExt: 3611603

They are also already included in the js version. I haven't tested them yet, so feedback is welcome 😄

@zalo
Copy link

zalo commented Dec 18, 2023

Awesome; thank you so much for setting this up! I’ll look into writing a test app asap!

@zalo
Copy link

zalo commented Dec 28, 2023

Looks like at least remeshTriangleMesh works!

image

My implementation is a bit verbose though 😅

        // Load PhysX
        const px       = await PhysX();
        let version    = px.PHYSICS_VERSION;
        let allocator  = new px.PxDefaultAllocator();
        let errorCb    = new px.PxDefaultErrorCallback();
        let foundation = px.CreateFoundation(version, allocator, errorCb);
        console.log('PhysX loaded! Version: ' + ((version >> 24) & 0xff) + '.' + ((version >> 16) & 0xff) + '.' + ((version >> 8) & 0xff));

        // Transform the test mesh to PhysX arrays
        let inputVertices  = new px.PxArray_PxVec3(sphereMesh.vertProperties.length/3);
        let inputIndices   = new px.PxArray_PxU32 (sphereMesh.triVerts.length);
        for(let i = 0; i < sphereMesh.vertProperties.length; i+=3){
            inputVertices.set(i/3, new px.PxVec3(sphereMesh.vertProperties[i], sphereMesh.vertProperties[i+1], sphereMesh.vertProperties[i+2]));
        }
        for(let i = 0; i < sphereMesh.triVerts.length; i++){
            inputIndices.set(i, sphereMesh.triVerts[i]);
        }

        // Remesh the test mesh!
        let outputVertices = new px.PxArray_PxVec3();
        let outputIndices  = new px.PxArray_PxU32 ();
        let vertexMap      = new px.PxArray_PxU32 ();
        let remesherGridResolution = 20;
        px.PxTetMaker.prototype.remeshTriangleMesh(inputVertices, inputIndices, remesherGridResolution, outputVertices, outputIndices, vertexMap);

        // Transform From PhysX back to three.js's Mesh Representation
        let triIndices = new Uint32Array(outputIndices.size());
        for(let i = 0; i < triIndices.length; i++){
            triIndices[i] = outputIndices.get(i);
        }
        let vertPositions = new Float32Array(outputVertices.size() * 3);
        for(let i = 0; i < outputVertices.size(); i++){
            let vec3 = outputVertices.get(i);
            vertPositions[i*3+0] = vec3.get_x();
            vertPositions[i*3+1] = vec3.get_y();
            vertPositions[i*3+2] = vec3.get_z();
        }
        let remeshedBufferGeo = new THREE.BufferGeometry();
        remeshedBufferGeo.setAttribute('position', new THREE.BufferAttribute(vertPositions, 3));
        remeshedBufferGeo.setIndex(new THREE.BufferAttribute(triIndices, 1));
        remeshedBufferGeo.computeVertexNormals();
        let remeshedThreeMesh = new THREE.Mesh(remeshedBufferGeo, new THREE.MeshPhysicalMaterial({ color: 0x00ff00, wireframe: true }));
        remeshedThreeMesh.position.set(2.0, 0.0, 0.0);
        this.world.scene.add(remeshedThreeMesh);

        // Clean up the PhysX Arrays
        inputVertices .__destroy__();
        inputIndices  .__destroy__();
        outputVertices.__destroy__();
        outputIndices .__destroy__();
        vertexMap     .__destroy__();

I'll look into the tetrahedralization next... putting WIP code into https://github.com/zalo/TetSim/compare/feat-physx-baking

EDIT:
It all works! Thank you!

image
Left: CAD Mesh, Middle: Remeshed + Simplified, Right: Tetrahedral Mesh

Took a fair amount of trial and error (and spelunking through the PhysX codebase for examples of constructing 'Simple'TriangleMeshes), but it appears to be working great!

@zalo
Copy link

zalo commented Dec 29, 2023

Alrighty, here's a quick Benchmark showing what the PhysX TetMesh looks like on another model, with tunable parameters: https://zalo.github.io/TetForm/

I think this was the missing piece for making a larger collection of FEM Physics Simulations; thank you again for adding this to your library!

By the way, I notice PhysX might benefit from something I've been working on the side: a faster exact convex decomposition for physics meshes...

@fabmax
Copy link
Owner

fabmax commented Dec 29, 2023

That's pretty awesome!

Convex mesh decomposition is also something I still have on my todo list. I had this one on my radar: https://github.com/kmammou/v-hacd
But I haven't dived into that topic yet.

@zalo
Copy link

zalo commented Dec 29, 2023

VHACD has the nicest build config (since it’s just a header file now 😄), but CoACD makes twice as accurate decompositions in about the same amount of time, and has a comparable license.

But, since I have Physics-based modeling/crafting on the brain, neither are quite fast enough for real-time use….

I compare them to my method here for a very concave test shape: elalish/manifold#663 (comment)

I started porting all the code/algorithms to an independent project last night, so that may bear some fruit soon…

@fabmax
Copy link
Owner

fabmax commented Dec 29, 2023

That looks promising! Although I guess for most game use-cases accuracy is not that important.

@fabmax
Copy link
Owner

fabmax commented Jan 3, 2024

Alright, I finally played around with VHACD a bit and while the accuracy is ok for me, the speed is not (at least for online mesh conversion; low-resolution stanford bunny takes ~7.5 secs when running single-threaded in native, haven't tried WASM yet, but it won't be faster...). So, if your (@zalo) voronoi approach is really that much faster I would like to give it a try once it's there 😄

What surprised me the most, is the performance of PhysX when simulating convex meshes: 500 actors, 16 meshes each and only ~3 ms per sim step

bunnies.mp4

@tlf30
Copy link
Author

tlf30 commented Jan 4, 2024

In the past when using VHACD, I have prebaked the physics mesh into my main mesh, and the loader will load both. This works fine as long as you know the mesh in advance. If using shape keys this can be problematic. I was experimenting with what it would take to use shape keys with physics meshes (in bullet), but did not get a chance to dive into it in detail.

I too am interested in a solution that is faster and can do real time mesh conversions (even at the cost of a lower accuracy).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants