Open tlf30 opened 1 year ago
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...
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.
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 :smile:
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....
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...
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
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.
Is custom geometry support on the roadmap (PxCustomGeometry
)?
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?
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.
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...
Is custom geometry support on the roadmap (
PxCustomGeometry
)?The latest snapshot contains bindings for
PxCustomGeometry
. In order to use it you need to subclassSimpleCustomGeometryCallbacksImpl
and implement the required callback methods. Then, pass an instance of the callbacks to thePxCustomGeometry
constructor.It's completely untested though...
Awesome, I'll give it a go.
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
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?
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...
@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 π
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?
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/
Ah nice! I will see what I can do for the tet meshes
@zalo I added bindings for PxTetMakerExt
and PxTetrahedronMeshExt
: https://github.com/fabmax/physx-jni/commit/3611603f50b666e97e041a7b92322bea0fc6f4aa
They are also already included in the js version. I haven't tested them yet, so feedback is welcome :smile:
Awesome; thank you so much for setting this up! Iβll look into writing a test app asap!
Looks like at least remeshTriangleMesh
works!
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!
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!
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...
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.
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: https://github.com/elalish/manifold/pull/663#issue-2045336428
I started porting all the code/algorithms to an independent project last night, so that may bear some fruit soonβ¦
That looks promising! Although I guess for most game use-cases accuracy is not that important.
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 :smile:
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
https://github.com/fabmax/physx-jni/assets/3752161/538ee8b9-846e-4115-acb6-b9ac643ca41e
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).
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