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

Please expose btTriangleIndexVertexArray #398

Open
arcman7 opened this issue May 3, 2022 · 12 comments
Open

Please expose btTriangleIndexVertexArray #398

arcman7 opened this issue May 3, 2022 · 12 comments

Comments

@arcman7
Copy link

arcman7 commented May 3, 2022

If I'm understanding everything correctly, this would allow us to pass in massive buffers that are filled with vertex data. This would unlock using massive open world maps with ammo js! As of now, I run out of memory well before all the the individual calls to btTriangleMesh.addTriangle(triPoints[0], triPoints[1], triPoints[2]); ever finishes for a model with 200k + vertices; and yet at the same time I'm allowed to load in a heightmap with 1480 x 1480 subdivisions passing in the data via Ammo._malloc? It seems to me ammo js would be perfectly capable of handling this if only it were exposed.

@willeastcott
Copy link
Contributor

Yeah, PlayCanvas calls addTriangle here. For large environments, this can be very slow. It'd be great to have a faster mechanism for specifying the collision mesh geometry.

@DennisSmolek
Copy link

You don't want to do this...

A heightmap is essentially a Plane so much easier on the memory. See:
https://rapier.rs/docs/user_guides/rust/colliders/#heightfields

You should try and use the smallest, most efficient method for the collision detection.
There are a lot of ways to do this but realize when you test you'll have to run a collision test over EVERY triangle in the mesh vs EACH object you want to compare.

For many player objects, they use their own raycasters and dont rely on the physics engine for all sorts of reasons:
https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/CharacterControllers.html

If you cant do this, use a subdivision method like quad trees or better yet use BVH.

This would let you do a smaller pass and maybe do a test against the specific triangles if you need to..

Something like VHCAD would work https://github.com/kmammou/v-hacd
This Lib by Don McCurdy shows a method to create a shape for Cannon.js

BTW Rapier has a JS version and we're working on getting the VHCAD WASM wired up as well (not in rapier JS yet)

Will be over at https://github.com/pmndrs/react-three-rapier

The docs for Ammo and bullet really surprise me with how popular they are

@arcman7
Copy link
Author

arcman7 commented Jun 15, 2022

Something like VHCAD would work https://github.com/kmammou/v-hacd
This Lib by Don McCurdy shows a method to create a shape for Cannon.js

This is awesome. Thank you so much!

BTW Rapier has a JS version and we're working on getting the VHCAD WASM wired up as well (not in rapier JS yet)
Will be over at https://github.com/pmndrs/react-three-rapier

This looks really exciting and I'd love to get a sense of performance benchmarks against ammo.js. Ultimately I would love to be able to use a babylon.js integration with rapier once the WASM api is up and running or if the performance gains against ammo.js are already there and it makes sense for me to start making the switch.

The docs for Ammo and bullet really surprise me with how popular they are

It's been a nightmare for me. But it's paid off more or less.

@arcman7
Copy link
Author

arcman7 commented Jul 2, 2022

@DennisSmolek Can we revisit this

You don't want to do this...

Even if I don't want to do this for the world terrain mesh, exposing this interface would still speedup adding smaller but still detailed meshes into the ammo js physics world. Having to instantiate an instance of btPoint three times for each triangle still produces an incredible amount of overhead. In fact, I think it's this method of adding points to Ammo js that causes of a lot of the memory issues I've seen.

Correct me if I'm wrong, but adding large amounts of vertices in one function call momentarily raises the memory usage of ammo by a significant amount, but once the object has been fully passed in, the memory is released. If this is the case, then JS developers really could be getting more use out of Ammo js since it's the initial overhead that causes the OOM error in most cases, not the actual large count of vertices once it's been loaded.

@MackeyK24
Copy link
Contributor

MackeyK24 commented Aug 7, 2022

you mean implementing the whole class btTriangleIndexVertexArray

I dunno about this one cause i dont know for sure how to implement all the constructor properties in ammo.idl

and more importantly how to pass them from javascript.

@arcman7
Copy link
Author

arcman7 commented Aug 7, 2022

you mean implementing the whole class btTriangleIndexVertexArray

I dunno about this one cause i dont know for sure how to implement all the constructor properties in ammo.idl

and more importantly how to pass them from javascript.

So it's not a matter of just exposing it in the idl?

@MackeyK24
Copy link
Contributor

MackeyK24 commented Aug 7, 2022

Mainly it is just exposing it the in ammo.idl but how you pass the pointers to the data is the thing.

I am going play with this for a bit... lets at least get the idl setup then we can fart around with how to wrap the pointers to the data for Ammo.js

@arcman7
Copy link
Author

arcman7 commented Aug 7, 2022

Mainly it is just exposing it the in ammo.idl but how you pass the pointers to the data is the thing.

I am going play with this for a bit... lets at least get the idl setup then we can fart around with how to wrap the pointers to the data for Ammo.js

Sounds good - I'll reference to one your prs that made similar changes to the ammo.idl file

@DennisSmolek
Copy link

Even if I don't want to do this for the world terrain mesh, exposing this interface would still speedup adding smaller but still detailed meshes into the ammo js physics world.

So this makes sense and I’m honestly not sure regarding the function call itself, but I’ve made INSANE calls with things over the years so I’m not worried there.

my concern and warning was against your ultimate use case with using a mesh with that many faces as a collidable object..

(AFAIK) The standard way to run the test is at least one ray per face scanning the universe, and as this is JS it’s sequential, and if it’s a standard loop object and not a ground plane, it’s going to blow stuff up.

I’ll use rapiers docs because they explain an alternative a bit better: https://rapier.rs/docs/user_guides/rust/colliders/#compound-shapes

@arcman7
Copy link
Author

arcman7 commented Aug 7, 2022

Mainly it is just exposing it the in ammo.idl but how you pass the pointers to the data is the thing.

I figured we'd just copy what's being done with the btHeightfieldTerrainShape:

  const ammoVertexData = Ammo._malloc(
    4 * numberOfRows * numberOfCols
  )

This might mean making slight modifications to the btTriangleIndexVertexArray class. I'll take a look in a few days.

@arcman7
Copy link
Author

arcman7 commented Aug 7, 2022

@DennisSmolek

I’ll use rapiers docs because they explain an alternative a bit better: https://rapier.rs/docs/user_guides/rust/colliders/#compound-shapes

This will automatically create a compound shape composed of multiple convex meshes obtained from the approximate convex decomposition of the triangle mesh (or polyline in 2D) using the VHACD algorithm.

Okay that's awesome. I tried to use the VHACD algo as a plugin with blender and had no success. I gave up after reading that people were not getting any sort of stable results from the VHACD algo. At least with the implementation they were using.

Recently I went into blender just to split apart a model into a bunch of individual convex hulls, because creating a convexhull with the original monolith model would not result in the correct shape. Its a tree, and each branch and each twig had to be split into its own set of vertices. Does Rapiers ColliderBuilder::convex_decomposition(vertices, indices) solve this for me?

Would using this on a large terrain mesh produce an approximate shrink-wrapped mesh as well? I don't think I would use it this way, but I'm wondering what are the limits of it's usage?

@arcman7
Copy link
Author

arcman7 commented Feb 4, 2023

If I'm understanding everything correctly, this would allow us to pass in massive buffers that are filled with vertex data. This would unlock using massive open world maps with ammo js! As of now, I run out of memory well before all the the individual calls to btTriangleMesh.addTriangle(triPoints[0], triPoints[1], triPoints[2]); ever finishes for a model with 200k + vertices; and yet at the same time I'm allowed to load in a heightmap with 1480 x 1480 subdivisions passing in the data via Ammo._malloc? It seems to me ammo js would be perfectly capable of handling this if only it were exposed.

Something has changed in the Ammo.js build that Babylon.js uses, for whatever reason now I can load in a triangle mesh shape with over 500k vertices no problem, just takes 10 20 minutes to load lol.

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