Skip to content

Ammo Physics (3D Physics Extension) #1974

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

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

Brackets-Coder
Copy link
Contributor

@Brackets-Coder Brackets-Coder commented Feb 25, 2025

Ammo Physics

A work-in-progress extension based on the ammo.js physics library, which is based on the 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.

video.mp4

Task list:

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

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

  • Player Management
  • Vehicle 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.
  • I haven't made documentation, sample projects, etc. yet
  • I'm not good at graphic design so if someone wants to make a banner/thumbnail that'd be great
  • 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 Brackets-Coder marked this pull request as draft February 25, 2025 22:31
@github-actions github-actions bot added the pr: new extension Pull requests that add a new extension label Feb 25, 2025
@WAYLIVES
Copy link

WAYLIVES commented Mar 4, 2025

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

@Brackets-Coder
Copy link
Contributor Author

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 Brackets-Coder changed the title Ammo Physics Ammo Physics (3D Physics Extension) Mar 19, 2025
@Brackets-Coder
Copy link
Contributor Author

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

@WAYLIVES
Copy link

wow

@Brackets-Coder
Copy link
Contributor Author

Brackets-Coder commented Apr 2, 2025

Finally got convex hulls working 🥳 🎉

video.mp4

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

@Brackets-Coder
Copy link
Contributor Author

@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

@Xeltalliv
Copy link
Contributor

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.

@Brackets-Coder
Copy link
Contributor Author

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
Copy link
Contributor Author

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

@Brackets-Coder
Copy link
Contributor Author

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
Copy link
Contributor Author

Brackets-Coder commented Apr 10, 2025

@CubesterYT

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

@Brackets-Coder
Copy link
Contributor Author

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
Copy link
Contributor Author

Brackets-Coder commented Apr 10, 2025

Update

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

video2.mp4

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
Copy link
Contributor Author

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

@Brackets-Coder
Copy link
Contributor Author

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

@Brackets-Coder
Copy link
Contributor Author

Brackets-Coder commented Apr 10, 2025

video.mp4

@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
Copy link
Contributor Author

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.

@Xeltalliv
Copy link
Contributor

Xeltalliv commented Apr 11, 2025

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.

@Brackets-Coder
Copy link
Contributor Author

Brackets-Coder commented Apr 11, 2025

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

This comment was marked as outdated.

@Brackets-Coder
Copy link
Contributor Author

Brackets-Coder commented Apr 11, 2025

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:

video.mp4

@Brackets-Coder
Copy link
Contributor Author

Brackets-Coder commented Apr 13, 2025

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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr: new extension Pull requests that add a new extension
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants