p2-es
This is a maintained fork of p2.js, originally created by Stefan Hedman @schteppe.
It is a type-safe flatbundle (esm and cjs) which allows for tree shaking and usage in modern environments.
If you're using three.js in a React environment with react-three-fiber, check out use-p2! It's a wrapper around p2-es that runs in a web worker.
2D rigid body physics engine written in JavaScript. Includes collision detection, contacts, friction, restitution, motors, springs, advanced constraints and various shape types.
Demos | Examples | Documentation
Getting Started
Usage with NPM
yarn add p2-es
CDN
You can also import the esm bundle with unpkg:
<script type="module">
import * as p2 from 'https://www.unpkg.com/browse/p2-es@1.0.0/dist/p2-es.js';
import * as p2 from 'https://www.unpkg.com/browse/p2-es/dist/p2-es.js';
</script>
If you would like to use ordinary Array
instead of Float32Array
, define P2_ARRAY_TYPE
globally before loading the library.
<script type="text/javascript">
P2_ARRAY_TYPE = Array
</script>
<script type="module">
import * as p2 from 'p2-es.js'
</script>
Sample code
The following example uses the World, Circle, Body and Plane classes to set up a simple physics scene with a ball on a plane.
var world = new p2.World({
gravity: [0, -9.82],
})
var circleBody = new p2.Body({
mass: 5,
position: [0, 10],
})
var circleShape = new p2.Circle({ radius: 1 })
circleBody.addShape(circleShape)
world.addBody(circleBody)
var groundBody = new p2.Body({
mass: 0,
})
var groundShape = new p2.Plane()
groundBody.addShape(groundShape)
world.addBody(groundBody)
var fixedTimeStep = 1 / 60
var maxSubSteps = 10
var lastTime
function animate(time) {
requestAnimationFrame(animate)
var deltaTime = lastTime ? (time - lastTime) / 1000 : 0
world.step(fixedTimeStep, deltaTime, maxSubSteps)
renderCircleAtPosition(circleBody.interpolatedPosition)
lastTime = time
}
requestAnimationFrame(animate)
To interact with bodies, you need to do it after each internal step. Simply attach a "postStep" listener to the world, and make sure to use body.position
here - body.interpolatedPosition
is only for rendering.
world.on('postStep', function (event) {
circleBody.force[0] -= 100 * circleBody.position[0]
})
Supported collision pairs
| Circle | Plane | Box | Convex | Particle | Line | Capsule | Heightfield | Ray |
---|
Circle | Yes | - | - | - | - | - | - | - | - |
Plane | Yes | - | - | - | - | - | - | - | - |
Box | Yes | Yes | Yes | - | - | - | - | - | - |
Convex | Yes | Yes | Yes | Yes | - | - | - | - | - |
Particle | Yes | Yes | Yes | Yes | - | - | - | - | - |
Line | Yes | Yes | (todo) | (todo) | - | - | - | - | - |
Capsule | Yes | Yes | Yes | Yes | Yes | (todo) | Yes | - | - |
Heightfield | Yes | - | Yes | Yes | (todo) | (todo) | (todo) | - | - |
Ray | Yes | Yes | Yes | Yes | - | Yes | Yes | Yes | - |
Note that concave polygon shapes can be created using Body.fromPolygon.
How to build
Make sure you have git, Node.js and Yarn installed
git clone https://github.com/pmndrs/p2-es.git;
cd p2-es;
yarn install
yarn build
yarn generate-docs
yarn serve
Release process
- Bump version number.
- Build and commit files in
dist/
and docs/
. - Tag the commit with the version number e.g. vX.Y.Z
- Add release notes to github
- Publish to NPM
TODO