All Projects → notrabs → use-ammojs

notrabs / use-ammojs

Licence: MIT License
ammo.js physics for use with react-three-fiber

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to use-ammojs

ThreeStudio
3D game editor based on Three.js and Electron.
Stars: ✭ 96 (+500%)
Mutual labels:  threejs, ammojs
billiards
billiards physics
Stars: ✭ 37 (+131.25%)
Mutual labels:  threejs, physics
react-three-arjs
AR.js with react-three-fiber
Stars: ✭ 88 (+450%)
Mutual labels:  threejs, react-three-fiber
encounter
Remaking the classic C64 game in WebGL.
Stars: ✭ 45 (+181.25%)
Mutual labels:  threejs, physics
three-to-cannon
Convert a THREE.Mesh to a CANNON.Shape.
Stars: ✭ 207 (+1193.75%)
Mutual labels:  threejs, physics
cannon-es-debugger
Wireframe debugger for use with cannon-es https://github.com/react-spring/cannon-es
Stars: ✭ 69 (+331.25%)
Mutual labels:  threejs, physics
Mage
Mage is a 3D Game Engine, built on top of THREE.js. It features Unity-like scripting, AMMO.js powered physics workers, an Infernojs powered UI and a clean API. Under (very) active development.
Stars: ✭ 76 (+375%)
Mutual labels:  threejs, ammojs
Unrust
unrust - A pure rust based (webgl 2.0 / native) game engine
Stars: ✭ 341 (+2031.25%)
Mutual labels:  physics, wasm
racing-game-cljs
A 3D racing game built with ClojureScript, React and ThreeJS
Stars: ✭ 209 (+1206.25%)
Mutual labels:  threejs, react-three-fiber
bf-3
my personal site, bf.wtf version 3
Stars: ✭ 58 (+262.5%)
Mutual labels:  threejs, react-three-fiber
Webxr Physics
Adds physics to WebXR
Stars: ✭ 18 (+12.5%)
Mutual labels:  threejs, physics
imgalign
Webapplication for image stitching and aligning
Stars: ✭ 162 (+912.5%)
Mutual labels:  wasm, webworker
Aframe Physics System
Physics system for A-Frame VR, built on CANNON.js.
Stars: ✭ 371 (+2218.75%)
Mutual labels:  threejs, physics
three-js-fundamentals-r3f
Examples from the Three.js Fundamentals website recreated in react-three-fiber renderer.
Stars: ✭ 84 (+425%)
Mutual labels:  threejs, react-three-fiber
Glas
WebGL in WebAssembly with AssemblyScript
Stars: ✭ 278 (+1637.5%)
Mutual labels:  threejs, wasm
spacesvr
A standardized reality for the future of the 3D Web.
Stars: ✭ 135 (+743.75%)
Mutual labels:  threejs, react-three-fiber
EduSmart
It utilizes 3D, Augmented reality to give real-life simulations or feels of various models and make the learning process more impactful and fascinating. With an interactive live feature, students can ask the teacher their doubts instantly and also discuss.
Stars: ✭ 23 (+43.75%)
Mutual labels:  threejs, react-three-fiber
typefaces
Collection of Google fonts as typeface data for usage with three.js, react-three-fiber, and other tools.
Stars: ✭ 53 (+231.25%)
Mutual labels:  threejs, react-three-fiber
caroumesh
A React component to display 3d models in a carousel-like fashion.
Stars: ✭ 63 (+293.75%)
Mutual labels:  threejs, react-three-fiber
jitterphysics
A cross-platform, realtime physics engine for all .NET apps.
Stars: ✭ 327 (+1943.75%)
Mutual labels:  physics

npm npm npm

use-ammojs

Fast Physics hooks for use with react-three-fiber.

Achieved by running the ammo.js physics library in a web-worker. Ammo itself is a WebAssembly wrapper around the powerful Bullet Physics engine. Data is synced with SharedArrayBuffers having minimal impact on the main thread.

yarn add use-ammojs
npm i use-ammojs

Built on top of three-ammo and its related work.

Examples

API Demos

Stress Tests

⚠️ Note that the codesandbox examples do not support SharedArrayBuffers due to missing cross-origin isolation and use regular ArrayBuffers as a fallback. Currently the debug-drawer has no ArrayBuffer fallback implemented and will not render anything.

Why not use use-cannon instead?

use-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 engine, which solves these problems.

At the time of writing however use-cannon is more mature and great for most projects.

Roadmap

Main goals:

  • Create a Physics World as a React context and simulate it in a web-worker
  • Sync three objects to physics Rigid Bodies
  • Add Rigid Body support
  • Add Soft Body support
    • Volumes/Cloth from Triangle Mesh
    • Ropes
    • Support textures on Soft Bodies
    • Deformables
  • Add Constraints between Rigid Bodies
  • Add Constraints to Soft Bodies (ability to pin nodes in place or to Rigid Bodies)
  • Improve Physics API
    • Make all props reactive
    • Expose more methods trough the hook (e.g. setPosition/applyImpulse/more...)
    • Support collision callbacks
  • Add Examples to the documentation
  • Set up Benchmarks to compare cannon, ammo with ArrayBuffers and ammo with SharedArrayBuffers

Low priority goals (for unchecked tasks):

  • 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)
  • Add Raycast queries
    • One-time (async) ray-tests
    • Continuous queries trough a fixed scene component to mitigate worker latency (TODO: check if necessary)
  • Use ArrayBuffers as a fallback for missing cross-origin isolation
    • Rigid Bodies
    • Soft Bodies
    • Debug Rendering
  • Simulation managment
    • Configurable simulation speed
    • Expose performance info
      • Integrate to @react-three/drei Stats component
    • Automatically pause simulation if tab is out of focus or not rendering (as option)
  • Improve the automatic shape detection (set shapeType automatically based on the three Mesh type)
  • Raycast Vehicle API
  • Support for instanced objects
  • Support and document manual bundling of the wasm file
    • 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.

Quick Start

1. Wrap your scene in a Physics Provider

import { Physics } from "use-ammojs";

<Physics drawDebug>[...]</Physics>;

2.a Make objects physical (Rigid Bodies)

Automatically parse Shape parameters from the three Mesh (courtesy of three-to-ammo):

import { Box } from "@react-three/drei";
import { useRigidBody, ShapeType } from "use-ammojs";

function MyBox() {
  const [ref] = useRigidBody(() => ({
    mass: 1,
    position: [0, 2, 4],
    shapeType: ShapeType.BOX,
  }));

  return (
    <Box ref={ref}>
      <meshBasicMaterial attach="material" color="red" />
    </Box>
  );
}

or define Collision Shapes manually:

const [playerCapsuleRef] = useRigidBody(() => ({
  bodyType: BodyType.DYNAMIC,
  shapeType: ShapeType.CAPSULE,
  angularFactor: new Vector3(0, 0, 0),
  shapeConfig: {
    fit: ShapeFit.MANUAL,
    halfExtents: new Vector3(0.3, 0.6, 0.3),
  },
}));

or add collisions to an imported gltf scene:

useRigidBody(
  () => ({
    shapeType: ShapeType.MESH,
    bodyType: BodyType.STATIC,
  }),
  gltf.scene
);

2.a Make objects squishy (Soft Bodies)

const [ref] = useSoftBody(() => ({
  type: SoftBodyType.TRIMESH,
}));

return (
  <Sphere position={[0, 2, 7]} args={[1, 16, 16]} ref={ref}>
    <meshPhysicalMaterial attach="material" color="blue" />
  </Sphere>
);

2.c Add Constraints

TODO;

3.a Raycasts

const { rayTest } = useAmmo();

[...]

const hits = await rayTest({
  from: new Vector3(0, 5, 7),
  to: new Vector3(0, -1, 7),
  multiple: true
})

if (hits.length) {
    console.log(hits[0].object.name, hits[0].hitPosition)
}

3.b Update Motion State

const [playerRef, api] = useRigidBody(() => ({
  bodyType: BodyType.DYNAMIC,
  shapeType: ShapeType.CAPSULE,
  angularFactor: new Vector3(0, 0, 0),
  shapeConfig: {
    fit: ShapeFit.MANUAL,
    halfExtents: new Vector3(0.3, 0.6, 0.3),
  },
}));

function handleRespawn() {
  api.setPosition(new Vector3(0, 0, 0));
  api.setLinearVelocity(new Vector3(0, 0, 0));
}

Documentation

Components

<Physics />

Phyiscs Context. Use to wrap all physical objects within the same physics world.

<PhysicsStats />

Shows a stats.js panel with physics timing info. Use within a <Physics /> Context

Hooks

const { rayTest } = useAmmo();

Utility funcionts available anywhere in the <Physics /> context.

const [ref, api] = useRigidBody();
const [ref, api] = useSoftBody();

Cross-origin isolation

To use SharedArrayBuffers for better communication between the main-thread and the web-worker-thread, a cross-origin isolated environment is necessary in modern browsers. This requires sending the following HTTP headers in the response of the main html document (Learn more):

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

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

Developing locally using use-ammojs

Setting up react-scripts to work with yarn link using @craco/craco
  1. yarn add @craco/craco --dev
  2. Replace react-scripts with craco in your package.json (see @craco/craco documentation)
  3. Add craco.config.js to project root:
const path = require("path");

module.exports = {
  webpack: {
    configure: (webpackConfig) => {
      // Fix that prevents a duplicate react library being imported when using a linked yarn package
      webpackConfig.resolve.alias = {
        ...webpackConfig.resolve.alias,
        react: path.resolve("./node_modules/react"),
        "@react-three/fiber": path.resolve("./node_modules/@react-three/fiber"),
        three: path.resolve("./node_modules/three"),
      };

      return webpackConfig;
    },
  },

  // Make sure SharedArrayBuffers are available locally
  devServer: {
    headers: {
      "Cross-Origin-Embedder-Policy": "require-corp",
      "Cross-Origin-Opener-Policy": "same-origin",
    },
  },
};
  1. Run yarn link in use-ammojs root directory
  2. Run yarn link use-ammojs in your project's directory
  3. Run yarn start in use-ammojs to start the development bundler
  4. Build and run your project as usual
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].