{"id":25440806,"url":"https://github.com/notrabs/use-ammojs","last_synced_at":"2025-11-01T11:30:34.489Z","repository":{"id":44689169,"uuid":"353644344","full_name":"notrabs/use-ammojs","owner":"notrabs","description":"ammo.js physics for use with react-three-fiber","archived":false,"fork":false,"pushed_at":"2024-05-01T14:07:59.000Z","size":2385,"stargazers_count":48,"open_issues_count":4,"forks_count":9,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-02-16T13:26:54.537Z","etag":null,"topics":["ammojs","physics","react","react-three-fiber","threejs","wasm","webworker"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/notrabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-01T09:24:06.000Z","updated_at":"2024-12-24T05:09:11.000Z","dependencies_parsed_at":"2022-09-12T13:41:35.032Z","dependency_job_id":null,"html_url":"https://github.com/notrabs/use-ammojs","commit_stats":null,"previous_names":[],"tags_count":56,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notrabs%2Fuse-ammojs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notrabs%2Fuse-ammojs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notrabs%2Fuse-ammojs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notrabs%2Fuse-ammojs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/notrabs","download_url":"https://codeload.github.com/notrabs/use-ammojs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239286282,"owners_count":19613689,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ammojs","physics","react","react-three-fiber","threejs","wasm","webworker"],"created_at":"2025-02-17T12:18:15.483Z","updated_at":"2025-11-01T11:30:34.457Z","avatar_url":"https://github.com/notrabs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm](https://img.shields.io/npm/v/use-ammojs?color=%23F69500)](https://www.npmjs.com/package/use-ammojs)\n[![npm](https://img.shields.io/badge/bulletphysics%20(fork)-3.17-%23F69500)](https://github.com/notrabs/ammo.js/tree/bullet_submodule)\n![npm](https://img.shields.io/npm/types/use-ammojs?label=%20)\n# use-ammojs\n\n_Fast_ Physics hooks for use with [react-three-fiber](https://github.com/pmndrs/react-three-fiber).\n\nAchieved by running the [ammo.js](https://github.com/kripken/ammo.js/) physics library in a web-worker. \nAmmo itself is a WebAssembly wrapper around the powerful [Bullet Physics](http://www.bulletphysics.org/) engine.\nData is synced with SharedArrayBuffers having minimal impact on the main thread.\n\n```\nyarn add use-ammojs\nnpm i use-ammojs\n```\n\nBuilt on top of [three-ammo](https://github.com/infinitelee/three-ammo) and its related work.\n\n## Examples\n\n#### API Demos\n\n- [Hello Physics World](https://codesandbox.io/s/oc1op?file=/src/index.js)\n- [Soft Bodies](https://codesandbox.io/s/use-ammojs-softbody-example-k59jz)\n- [Crane (Constraint)](https://codesandbox.io/s/use-ammojs-constraint-example-inhkk)\n- [Crane (Rope + Attachment)](https://codesandbox.io/s/use-ammojs-rope-example-wb9cg)\n- [Raycast](https://codesandbox.io/s/use-ammojs-raycast-example-cibin?file=/src/index.js)\n\n#### Stress Tests\n\n- [Lots of cubes](https://codesandbox.io/s/use-ammojs-lotsofcubes-f5xdz?file=/src/index.js)\n\n\u003e ⚠️ Note that the codesandbox examples do not support SharedArrayBuffers [due to missing cross-origin isolation](https://web.dev/coop-coep/) and use regular ArrayBuffers as a fallback. Currently the debug-drawer has no ArrayBuffer fallback implemented and will not render anything.\n\n## Why not use [use-cannon](https://github.com/pmndrs/use-cannon) instead?\n\nuse-cannon is great and a inspiration for this package, but it is missing features like soft-bodies and lacks performance in scenes with large triangle meshes. ammo.js is a direct wrapper around the powerful [Bullet Physics](http://www.bulletphysics.org/) engine, which solves these problems.\n\nAt the time of writing however use-cannon is more mature and great for most projects.\n\n## Roadmap\n\n#### Main goals:\n\n- [x] Create a Physics World as a React context and simulate it in a web-worker\n- [x] Sync three objects to physics Rigid Bodies\n- [x] Add Rigid Body support\n- [ ] Add [Soft Body](https://pybullet.org/Bullet/BulletFull/classbtSoftBody.html) support\n  - [x] Volumes/Cloth from Triangle Mesh\n  - [x] Ropes\n  - [ ] Support textures on Soft Bodies\n  - [ ] Deformables\n- [ ] Add Constraints between Rigid Bodies\n- [ ] Add Constraints to Soft Bodies (ability to pin nodes in place or to Rigid Bodies)\n- [ ] Improve Physics API\n  - [ ] Make _all_ props reactive\n  - [ ] Expose more methods trough the hook (e.g. setPosition/applyImpulse/[more...](https://pybullet.org/Bullet/BulletFull/classbtRigidBody.html))\n  - [ ] Support collision callbacks\n- [ ] Add Examples to the documentation\n- [ ] Set up Benchmarks to compare cannon, ammo with ArrayBuffers and ammo with SharedArrayBuffers\n\n#### Low priority goals (for unchecked tasks):\n\n- [ ] Automatic refresh rate detection and performance throttling (i.e. match the simulation rate to the requestAnimationFrame-rate and throttle performance if simulation steps take too long)\n- [ ] Add [Raycast](https://pybullet.org/Bullet/BulletFull/classbtCollisionWorld.html#aaac6675c8134f6695fecb431c72b0a6a) queries\n  - [x] One-time (async) ray-tests\n  - [ ] Continuous queries trough a fixed scene component to mitigate worker latency (TODO: check if necessary)\n- [x] Use ArrayBuffers as a fallback for missing cross-origin isolation\n  - [x] Rigid Bodies\n  - [x] Soft Bodies\n  - [ ] Debug Rendering\n- [x] Simulation managment\n  - [x] Configurable simulation speed\n  - [x] Expose performance info\n    - [ ] Integrate to @react-three/drei Stats component\n  - [ ] Automatically pause simulation if tab is out of focus or not rendering (as option)\n- [ ] Improve the automatic shape detection (set shapeType automatically based on the three Mesh type)\n- [ ] Raycast Vehicle API\n- [ ] Support for instanced objects\n- [ ] Support and document manual bundling of the wasm file\n  - Currently the wasm library is inlined with a base64 string for ease of use. Users who want to save a few bytes can serve it as a seperate file with the `application/wasm` Content-Type in their own deployment. There should be a bundle available without the inlined wasm for that use-case.\n\n## Quick Start\n\n### 1. Wrap your scene in a Physics Provider\n\n```tsx\nimport { Physics } from \"use-ammojs\";\n\n\u003cPhysics drawDebug\u003e[...]\u003c/Physics\u003e;\n```\n\n### 2.a Make objects physical (Rigid Bodies)\n\nAutomatically parse Shape parameters from the three Mesh (courtesy of [three-to-ammo](https://github.com/InfiniteLee/three-to-ammo)):\n\n```tsx\nimport { Box } from \"@react-three/drei\";\nimport { useRigidBody, ShapeType } from \"use-ammojs\";\nimport { Mesh } from \"three\";\n\nfunction MyBox() {\n  // If you need a ref with a narrower type than Object3D, provide a generic argument here\n  const [ref] = useRigidBody\u003cMesh\u003e(() =\u003e ({\n    mass: 1,\n    position: [0, 2, 4],\n    shapeType: ShapeType.BOX,\n  }));\n\n  return (\n    \u003cBox ref={ref}\u003e\n      \u003cmeshBasicMaterial attach=\"material\" color=\"red\" /\u003e\n    \u003c/Box\u003e\n  );\n}\n```\n\nor define Collision Shapes manually:\n\n```tsx\nconst [playerCapsuleRef] = useRigidBody(() =\u003e ({\n  bodyType: BodyType.DYNAMIC,\n  shapeType: ShapeType.CAPSULE,\n  angularFactor: new Vector3(0, 0, 0),\n  shapeConfig: {\n    fit: ShapeFit.MANUAL,\n    halfExtents: new Vector3(0.3, 0.6, 0.3),\n  },\n}));\n```\n\nor add collisions to an imported gltf scene:\n\n```tsx\nuseRigidBody(\n  () =\u003e ({\n    shapeType: ShapeType.MESH,\n    bodyType: BodyType.STATIC,\n  }),\n  gltf.scene\n);\n```\n\n### 2.a Make objects squishy (Soft Bodies)\n\n```tsx\nconst [ref] = useSoftBody(() =\u003e ({\n  type: SoftBodyType.TRIMESH,\n}));\n\nreturn (\n  \u003cSphere position={[0, 2, 7]} args={[1, 16, 16]} ref={ref}\u003e\n    \u003cmeshPhysicalMaterial attach=\"material\" color=\"blue\" /\u003e\n  \u003c/Sphere\u003e\n);\n```\n\n### 2.c Add Constraints\n\n```tsx\nTODO;\n```\n\n### 3.a Raycasts\n\n```tsx\nconst { rayTest } = useAmmo();\n\n[...]\n\nconst hits = await rayTest({\n  from: new Vector3(0, 5, 7),\n  to: new Vector3(0, -1, 7),\n  multiple: true\n})\n\nif (hits.length) {\n    console.log(hits[0].object.name, hits[0].hitPosition)\n}\n```\n\n### 3.b Update Motion State\n\n```tsx\nconst [playerRef, api] = useRigidBody(() =\u003e ({\n  bodyType: BodyType.DYNAMIC,\n  shapeType: ShapeType.CAPSULE,\n  angularFactor: new Vector3(0, 0, 0),\n  shapeConfig: {\n    fit: ShapeFit.MANUAL,\n    halfExtents: new Vector3(0.3, 0.6, 0.3),\n  },\n}));\n\nfunction handleRespawn() {\n  api.setPosition(new Vector3(0, 0, 0));\n  api.setLinearVelocity(new Vector3(0, 0, 0));\n}\n```\n\n## Documentation\n\n### Components\n\n```tsx\n\u003cPhysics /\u003e\n```\n\nPhyiscs Context. Use to wrap all physical objects within the same physics world.\n\n```tsx\n\u003cPhysicsStats /\u003e\n```\n\nShows a stats.js panel with physics timing info. Use within a `\u003cPhysics /\u003e` Context\n\n### Hooks\n\n```tsx\nconst { rayTest } = useAmmo();\n```\n\nUtility funcionts available anywhere in the `\u003cPhysics /\u003e` context.\n\n```tsx\nconst [ref, api] = useRigidBody();\n```\n\n```tsx\nconst [ref, api] = useSoftBody();\n```\n\n### Cross-origin isolation\n\nTo use `SharedArrayBuffers` for better communication between the main-thread and the web-worker-thread, a cross-origin isolated environment is necessary in [modern browsers](https://caniuse.com/sharedarraybuffer).\nThis requires sending the following HTTP headers in the response of the main html document ([Learn more](https://web.dev/coop-coep/)):\n\n```http request\nCross-Origin-Embedder-Policy: require-corp\nCross-Origin-Opener-Policy: same-origin\n```\n\nuse-ammojs will fallback to using `ArrayBuffers` and `postMessage()` transfers if `SharedArrayBuffers` are not available. This is not as bad as a full copy on each transfer, but it does not allow the data to be availble on both threads at the same time.\n\n### Developing locally using use-ammojs\n\n\u003cdetails\u003e \n\u003csummary\u003e Setting up react-scripts to work with yarn link using @craco/craco \u003c/summary\u003e\n\n1. `yarn add @craco/craco --dev`\n2. Replace `react-scripts` with `craco` in your `package.json` (see [@craco/craco](https://www.npmjs.com/package/@craco/craco) documentation)\n3. Add `craco.config.js` to project root:\n\n```js\nconst path = require(\"path\");\n\nmodule.exports = {\n  webpack: {\n    configure: (webpackConfig) =\u003e {\n      // Fix that prevents a duplicate react library being imported when using a linked yarn package\n      webpackConfig.resolve.alias = {\n        ...webpackConfig.resolve.alias,\n        react: path.resolve(\"./node_modules/react\"),\n        \"@react-three/fiber\": path.resolve(\"./node_modules/@react-three/fiber\"),\n        three: path.resolve(\"./node_modules/three\"),\n      };\n\n      return webpackConfig;\n    },\n  },\n\n  // Make sure SharedArrayBuffers are available locally\n  devServer: {\n    headers: {\n      \"Cross-Origin-Embedder-Policy\": \"require-corp\",\n      \"Cross-Origin-Opener-Policy\": \"same-origin\",\n    },\n  },\n};\n```\n\n\u003c/details\u003e\n\n1. Run `yarn link` in use-ammojs root directory\n2. Run `yarn link use-ammojs` in your project's directory\n3. Run `yarn start` in use-ammojs to start the development bundler\n4. Build and run your project as usual\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotrabs%2Fuse-ammojs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnotrabs%2Fuse-ammojs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotrabs%2Fuse-ammojs/lists"}