Skip to content

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

This comment was marked as outdated.

@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

This comment was marked as outdated.

@Brackets-Coder

This comment was marked as outdated.

@Brackets-Coder

This comment was marked as outdated.

@Brackets-Coder

This comment was marked as outdated.

@Brackets-Coder

This comment was marked as outdated.

@Brackets-Coder

This comment was marked as outdated.

@Brackets-Coder

This comment was marked as outdated.

@Brackets-Coder

This comment was marked as outdated.

@Brackets-Coder

This comment was marked as outdated.

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

there's no freaking documentation writing constraints is a pain 😞

@Brackets-Coder
Copy link
Contributor Author

@CubesterYT I'm pretty sure this isn't possible but the best ammo.js projects use WebAssembly / Web workers to let the physics run async in the background so it doesn't hinder rendering processes, etc, also have more memory capacity.

I'm assuming this isn't possible in TW and it has to be native JS?

@Brackets-Coder
Copy link
Contributor Author

@wiktorlaskowski and @WAYLIVES might want to take a look at the placeholder banner and see if it's acceptable

@Kreerio
Copy link

Kreerio commented Sep 17, 2025

woah thats awsome

@Brackets-Coder
Copy link
Contributor Author

woah thats awsome

What the banner?

- Improves some of the comments or expands on them for self future reference
- Fixes an issue where the step simulation block would not behave correctly at 0 FPS, it now implies the screen refresh rate as Turbowarp does
@Brackets-Coder
Copy link
Contributor Author

@GarboMuffin and/or @CubesterYT

I'd like this extension to be able to support WebAssembly as it has much higher performance and much lower memory limitations.
The way I've set it up now is that a ammo.wasm.wasm file would be hosted at extensions.turbowarp.org/MasterMath/ammo.wasm.wasm

The extension would check if that file exists, if so load the WASM ammo with it, if not fall back to the default offline native JS version (at the cost of performance). This way there's no external domains and the extension should always load with some kind of Ammo.

In practice, it looks like this:
Screenshot 2025-09-18 at 8 44 10 PM

would something like this even work?

@GarboMuffin
Copy link
Member

I'll just be real with you. The likelihood that I would tolerate merging a 2MB extension is really low right now

@Brackets-Coder

This comment was marked as outdated.

@Brackets-Coder
Copy link
Contributor Author

Alternatively, I could build my own version of Ammo without the extra stuff that is much smaller than the prebuilt library, but it would probably remove things like the wireframe debug drawer which might be nice (but a lot of work and size) to implement later...

@Brackets-Coder
Copy link
Contributor Author

Alternatively, I could build my own version of Ammo without the extra stuff that is much smaller than the prebuilt library, but it would probably remove things like the wireframe debug drawer which might be nice (but a lot of work and size) to implement later...

I could probably half the file size if I did that though

@Brackets-Coder
Copy link
Contributor Author

Brackets-Coder commented Sep 19, 2025

@GarboMuffin

Hello Mr. Weber,
I made a custom build of Ammo.js with soft bodies and debug drawing disabled. I've also enabled WebAssembly and embedded it directly into the JS file, so I don't need to access extra files on the server, which probably wouldn't work anyway. I also configured the build to default at 128 MB memory limit and dynamically increase if needed. Terser minified and compressed it.

This makes it run faster, have "infinite" memory limitations (can be both good or bad, but it fixes the crashing Out of Memory issue), and the entire extension size is now only 1.2 MB (with all the blocks and stuff too). Is that good with you or should I compress further? What is the preferred size? I could probably get it a few hundred kilobytes, but that would be more aggressive and I don't think I can go further than that.

- WebAssembly Embedded into JS for higher performance and scalable memory (Fixes the Aborted: Out of Memory error)
- Remove soft bodies and debug drawer for half the size
- And something else IDK
@Brackets-Coder
Copy link
Contributor Author

!format

Copy link

The formatting bot didn't find any formatting issues. It currently only checks the extensions folder. The author or a maintainer can run terminal command 'npm run format' manually to format all files.

@Brackets-Coder
Copy link
Contributor Author

@CubesterYT since the last commit where I made a custom build of the library, format is failing even though npm run check-format passed on my local machine. Why is that?

@GarboMuffin
Copy link
Member

it's because of the prettier update pull request you merged where now your local prettier doesn't match what's on your pull request branch

that's why the pull request wasn't merged for a long time

rebase, reinstall, reformat, itll go away

@GarboMuffin
Copy link
Member

!format

prettier updates are now blocked from dependabot so that mistake won't be possible to make again

Copy link

The formatting bot didn't find any formatting issues. It currently only checks the extensions folder. The author or a maintainer can run terminal command 'npm run format' manually to format all files.

@Brackets-Coder
Copy link
Contributor Author

it's because of the prettier update pull request you merged where now your local prettier doesn't match what's on your pull request branch

that's why the pull request wasn't merged for a long time

rebase, reinstall, reformat, itll go away

Oops sorry just trying to help

@Daniel-Dami
Copy link

this extension is super cool!!

@Brackets-Coder
Copy link
Contributor Author

this extension is super cool!!

Thanks! Apparently though, it's too large, so I'll have to find some way to compress the library further

@Brackets-Coder
Copy link
Contributor Author

Brackets-Coder commented Sep 22, 2025

Previous commit reduces the file size ≈0.2 MB
The extension is now only 1MB (1020 KB, around half the original size); I don't think I can do much better than that without breaking functionality.

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.

8 participants