extensions icon indicating copy to clipboard operation
extensions copied to clipboard

Ammo Physics (3D Physics Extension)

Open Brackets-Coder opened this issue 9 months ago • 87 comments

Ammo Physics

A physics extension based on the ammo.js physics library, which is a direct port of the world-renowned C++ Bullet Physics SDK.

The goal is to provide feature-complete, advanced, and performant 3D physics in a simple-to-understand manner. This extension aims to be consistent with Box2D and Simple3D.

https://github.com/user-attachments/assets/ffaa1071-dea3-4bf6-b804-900e788113a1

Task list:

  • [x] Shapes
    • [x] Boxes
    • [x] Spheres
    • [x] Cylinders
    • [x] Cones
    • [x] Capsules
    • [x] Convex Hulls
    • [x] Triangle Meshes
    • [x] Compound bodies
    • There are some others (planes, heightfields), but I don't want to support these
  • [x] Physical Materials (friction, restitution, etc.)
  • ~~[ ] Constraints (All types)~~
  • [x] Collision:
    • [x] Collision Detection
    • [x] Raycasting
    • [x] Enable/disable collision response
  • [x] Manual Impact forces (like "push with force" block in Box2D)
  • [x] Bug fixing

Things I'm considering now or for a later update:

  • Vehicle support
  • ~~Debug rendering support~~
  • ~~Soft Bodies~~

Miscellaneous Notes Mainly for Moderators:

  • ChatGPT was used to assist and enhance the making of this extension, simply because I couldn't find good quality, coherent documentation of Ammo.js, and attempting to figure out how to use it via the developer inspector isn't fun. It did not write the code for me and I am still the main author of this extension. It just helped me learn Ammo.js. Hope this doesn't cause conflicts.
  • [x] ~~I'm not good at graphic design so if someone wants to make a banner/thumbnail that'd be great~~
  • [x] ~~Still have to incorporate Scratch.Cast where necessary, right now I'm just working on functionality though~~

Put an emoji (👍, 🚀) if you like this extension

Brackets-Coder avatar Feb 25 '25 22:02 Brackets-Coder

Wow! It's very cool and useful for people like me)

WAYLIVES avatar Mar 04 '25 17:03 WAYLIVES

Wow! It's very cool and useful for people like me)

Thank you! I've been making steady progress, but it probably won't be ready for a while (which is why this is a draft).

Brackets-Coder avatar Mar 04 '25 17:03 Brackets-Coder

Added partial support compound bodies - all child shape types. Also working on convex and concave mesh support... it'll be a while.

Brackets-Coder avatar Mar 23 '25 02:03 Brackets-Coder

wow

WAYLIVES avatar Mar 23 '25 05:03 WAYLIVES

Finally got convex hulls working 🥳 🎉

https://github.com/user-attachments/assets/ad8d1814-cfd9-4ece-a145-18e206262783

Still have to optimize and bug fix everything and add more features

Brackets-Coder avatar Apr 02 '25 14:04 Brackets-Coder

@Xeltalliv

Sorry to ping you, but I've got a quick question. I'm trying to add concave triangle mesh support but I can't decide how to go about parsing vertex and face data. I want to have a block that can do vertices and/or faces directly from a list and I want another block that can do OBJ files, but then it gets tricky because I have to have use cases for handling quads and n-gons when Ammo.js requires that all faces be triangles. Does Simple3D internally manage quads and n-gons or do you triangulate the mesh before uploading? If so, how difficult would it be to implement mesh triangulation from scratch, and which methods should I use? I was considering adding various triangulation methods or having a library do it for me, but wouldn't it be easier (albeit less user-friendly) to have it only accept OBJ files that are already triangulated (can't have more than 3 vertices per face)? E.g., require that users triangulate their meshes in Blender or something like that before importing

Brackets-Coder avatar Apr 08 '25 14:04 Brackets-Coder

It's a bit complicated. Simple3D itself can have meshes represented in 3 ways: triangles, triangle strips and triangle fans. Positions of each of the vertices can either be listed directly, or be specified once per unique position and referenced multiple times from the list of indices, to share one vertex between multiple primitives. Triangles require 3 vertices per triangle. Triangle strips and fans require 3 vertices for the first triangle and only 1 vertex for each subsequent triangle, where 2 old vertices get reused. In case of triangle strip it reused 2 immediately previous vertices. In case of triangle fan it reuses 1 previous vertex and the 1st vertex. Index of 0 can be used as a separator to have multiple unconnected triangle strips/fans. image

The built-in OBJ importer doesn't use any of those modes and always just outputs a simple list of triangles pre-processed using fan triangulation algorithm. It does not handle concave n-gons.

Xeltalliv avatar Apr 08 '25 16:04 Xeltalliv

It's a bit complicated. Simple3D itself can have meshes represented in 3 ways: triangles, triangle strips and triangle fans. Positions of each of the vertices can either be listed directly, or be specified once per unique position and referenced multiple times from the list of indices, to share one vertex between multiple primitives. Triangles require 3 vertices per triangle. Triangle strips and fans require 3 vertices for the first triangle and only 1 vertex for each subsequent triangle, where 2 old vertices get reused. In case of triangle strip it reused 2 immediately previous vertices. In case of triangle fan it reuses 1 previous vertex and the 1st vertex. Index of 0 can be used as a separator to have multiple unconnected triangle strips/fans. image

The built-in OBJ importer doesn't use any of those modes and always just outputs a simple list of triangles pre-processed using fan triangulation algorithm. It does not handle concave n-gons.

I'm aware of the multiple different primitive types, that's partially why I was asking. Thanks for the help

Brackets-Coder avatar Apr 08 '25 17:04 Brackets-Coder

I'm going to have to rewrite this horrible raycasting system, which means later release date

Brackets-Coder avatar Apr 08 '25 19:04 Brackets-Coder

Progress Update

  • Rewrote the entire raycasting system to be more efficient/capable and lining up with Scratch best practices (still have to add icons)
  • Added Scratch.Cast to every block argument of every block.

@CubesterYT I know this isn't near ready for review yet... but whenever you can could you please take a quick look at the casting to make sure I did it right?

Brackets-Coder avatar Apr 10 '25 00:04 Brackets-Coder

@CubesterYT

You might want to hold off, I think I broke something in the last commit... convex hulls are clipping through bodies.

Brackets-Coder avatar Apr 10 '25 00:04 Brackets-Coder

I just removed the casting because I think that was what was causing the problems. Also don't know why my last commit passed ESLint but now it's warning me about things that should've thrown an error. I fixed those so now we should be good moving forward.

I have to add mesh support for btBvhTriangleMeshShape and btGImpactMeshShape and constraints and impulse forces. Probably should also add vehicles and some kind of player management.

Brackets-Coder avatar Apr 10 '25 02:04 Brackets-Coder

Update

Just got some form of triangle meshes partially supported: (triangle mesh on bottom, convex hull on top)

https://github.com/user-attachments/assets/94322ceb-a24e-490d-bbb2-563e84e9ce3b

Still have to clean it up, optimize and things. Only the dynamic (but slower) btGImpactMeshShape works right now, for some reason the static btBvhTriangleMeshShape doesn't work and clips through other bodies.

I have confirmed that these meshes support concave collisions, unlike convex hulls.

Right now it only supports meshes where the data is from a Scratch list like this:

-1 -1 -1
0 0 0
1 1 1
3 6 9
12 15 18
21 24 27

Where each item contains three separated coordinates and every three items corresponds to the vertices of one triangle. this means that all vertices must be in order. This means the example list above contains two triangles. There are multiple delimiter options available in the RegEx that splices this (spaces, commas, commas and spaces, and pipes). I have not yet added support for vertex indexing (e.g., the faces are determined by the items that correspond to a vertex instead of being in order) but that's planned before release. Vertex indexing will also make it easier to implement OBJ file processing, but OBJ files must be triangulated before importing into the Scratch lists as Ammo.js expects triangulated, planar meshes with no n-gons or non-manifold geometry.

I also removed the casting and fixed the convex hulls.

Task list:

  • [ ] Finish Meshes
  • [ ] Add all constraint types
  • [ ] Add impulse forces
  • [ ] Bug fix
  • [ ] Best practices
  • [ ] Optimize
  • [ ] Maybe add vehicles and player management?

Brackets-Coder avatar Apr 10 '25 17:04 Brackets-Coder

Screenshot 2025-04-10 at 1 41 14 PM I'm going to have to fix that.

Brackets-Coder avatar Apr 10 '25 17:04 Brackets-Coder

They're very glitchy and there's a lot of tunneling when two impact meshes intersect...

Brackets-Coder avatar Apr 10 '25 19:04 Brackets-Coder

https://github.com/user-attachments/assets/06356cae-f610-4c11-a2f5-070001e89d29

@Xeltalliv Since you have experience writing physics engines, do you have any idea how to fix this? I've tried various things like changing maxSubSteps, simulation framerate, project framerate, etc. but nothing works. It only occurs when one or more btGImpactMeshes intersect with each other. One mesh and one convex hull works as expected. Multiple convex hulls work as expected. I've looked at demos that showcase multiple meshes in a chain with a wrecking ball at the bottom and it works fine so I know it's not a library limitation. There are no errors in the console.

I could try using a more specialized collision algorithm but I don't want to sacrifice performance for simpler simulations.

Brackets-Coder avatar Apr 10 '25 21:04 Brackets-Coder

Also, Ammo.js seems to support wireframe debug rendering. I might want to add a layer to the canvas that can show contacts, convex hulls, velocities, etc.

Brackets-Coder avatar Apr 10 '25 21:04 Brackets-Coder

This looks like a faulty collision detection. Changing framerate, sub-steps and solver iterations is mostly useful when you have a lot of bodies interacting in a chain reaction, which isn't the case here.

I could try using a more specialized collision algorithm but I don't want to sacrifice performance for simpler simulations.

Not sure exactly what you are referring to, because there isn't much documentation, but I asked ChatGPT how to correctly use btGImpactMeshShape and it on it's own mentioned that using btGImpactCollisionAlgorithm is absolutely mandatory for it to work correctly.

Xeltalliv avatar Apr 11 '25 12:04 Xeltalliv

This looks like a faulty collision detection. Changing framerate, sub-steps and solver iterations is mostly useful when you have a lot of bodies interacting in a chain reaction, which isn't the case here.

I could try using a more specialized collision algorithm but I don't want to sacrifice performance for simpler simulations.

Not sure exactly what you are referring to, because there isn't much documentation, but I asked ChatGPT how to correctly use btGImpactMeshShape and it on it's own mentioned that using btGImpactCollisionAlgorithm::registerAlgorithm is absolutely mandatory for it to work correctly.

I'm already registering the GImpactCollisionAlgorithm, but ChatGPT suggests using a more narrow phase parent collision algorithm... I don't really think that will affect anything. Looking at the official demos, btDbvtBroadphase is being used and that's what I'm using. I could try to see if I'm registering the impact collision algorithm correctly, but I think I am:

    let dispatcher = new Ammo.btCollisionDispatcher(collisionConfig);
    Ammo.btGImpactCollisionAlgorithm.prototype.registerAlgorithm(dispatcher);

Brackets-Coder avatar Apr 11 '25 12:04 Brackets-Coder

Screenshot 2025-04-11 at 8 46 57 AM

Brackets-Coder avatar Apr 11 '25 12:04 Brackets-Coder

Now ChatGPT is telling me that I can't do anything about it and to accept the limitations, but I know for sure it's possible. There's like twelve different GImpactMeshes all interacting here:

https://github.com/user-attachments/assets/00c55cdf-77fb-4b02-90d8-66466692e838

Brackets-Coder avatar Apr 11 '25 13:04 Brackets-Coder

I think my triangle solver is faulty and ChatGPT is too dumb to help me. I suppose I'll have to figure it out myself...

Brackets-Coder avatar Apr 13 '25 17:04 Brackets-Coder

Working on manual forces (impulses, pushes, etc. like in Box2D), cleaning raycasting rewrite, fixing some collision filtering bugs when attempting to disable collision response, etc...

I'm taking a break on triangle meshes rn until I can figure out what in the world is going wrong

Brackets-Coder avatar May 28 '25 15:05 Brackets-Coder

woaaaaaaahhh this is awesome :D

Tobsterzz avatar Jun 23 '25 12:06 Tobsterzz

woaaaaaaahhh this is awesome :D

Thanks, but glitchy

Brackets-Coder avatar Jun 28 '25 13:06 Brackets-Coder

@CubesterYT how unadvisable is it to provide console warnings for user debugging in extensions? Should it be avoided entirely?

Brackets-Coder avatar Jul 20 '25 02:07 Brackets-Coder

Added push forces, still have to add torque and clear forces but those won't take long at all. Also added gravity control to bodies as well so they react independently

Brackets-Coder avatar Jul 20 '25 20:07 Brackets-Coder

Y'all I finally got triangle meshes working... it was a face indices issue. Just have to bug fix it a bit when using invalid lists... but right now alpha support works great! You can see 3 meshes interacting with concave collisions in this video:

https://github.com/user-attachments/assets/842713de-a2c9-4fbb-baca-34b38cfe27e5

Brackets-Coder avatar Jul 27 '25 12:07 Brackets-Coder

Added basic constraint support, I've tested ball constraint and fixed constraint and both seem to be somewhat working. However, I seem to have a larger issue regarding the memory management of objects when pressing the green flag, often it crashes or freezes the physics world.

Sorry for the lack of a video, but hey - they work I guess. Still have more types to add though.

Brackets-Coder avatar Jul 30 '25 02:07 Brackets-Coder

Alright that commit should be good, also includes a few other things; see commit desc

Brackets-Coder avatar Jul 30 '25 02:07 Brackets-Coder