JSPM

  • Created
  • Published
  • Downloads 7
  • Score
    100M100P100Q40822F
  • License MIT

Fast physics hooks for use in react-three-fiber. Powered by web-workers and wasm.

Package Exports

  • use-ammojs

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (use-ammojs) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

[WIP] use-ammojs

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

Built on top of three-ammo, which runs the wasm ammo.js library in a seperate web-worker and syncs three objects using SharedArrayBuffers.

Why not use use-cannon instead?

use-cannon is great and a inspiration for this package, but it is missing features and lacks performance with many objects or large gltf imports. ammo.js is a direct wrapper around the powerful Bullet Physics engine.

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

Documentation [WIP]

0. Make sure your environment supports wasm

Add support to react-scripts (create-react-app) 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 { addBeforeLoader, loaderByName } = require("@craco/craco");

module.exports = {
  webpack: {
    configure: (webpackConfig) => {
      const wasmExtensionRegExp = /\.wasm$/;
      webpackConfig.resolve.extensions.push(".wasm");

      webpackConfig.module.rules.forEach((rule) => {
        (rule.oneOf || []).forEach((oneOf) => {
          if (oneOf.loader && oneOf.loader.indexOf("file-loader") >= 0) {
            oneOf.exclude.push(wasmExtensionRegExp);
          }
        });
      });

      const wasmLoader = {
        test: /\.wasm$/,
        type: "javascript/auto",
        loaders: ["file-loader"],
      };

      addBeforeLoader(webpackConfig, loaderByName("file-loader"), wasmLoader);

      return webpackConfig;
    },
  },
};

For local development with yarn link also add:

const path = require("path");

[...]

// Fix that prevents a duplicate react library being used 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"),
};

[...]

1. Wrap your scene in a Physics Provider

import { Physics } from "use-ammojs";

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

2. Make objects physical

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

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

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

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

or define Collision Shapes manually:

TODO

or add collisions to an imported gltf scene:

TODO

3.a Add Constraints

TODO

3.b Add Raycasts

TODO

4 Update positions