1.2.3 • Published 6 months ago

p2-es v1.2.3

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

p2-es

p2-es is a 2D rigid body physics engine written in JavaScript. Features include collision detection, contacts, friction, restitution, motors, springs, advanced constraints and various shape types.

Demos | Examples | Documentation

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.

Getting Started

NPM

npm install p2-es
yarn add p2-es

CDN

You can also import the esm bundle with unpkg:

<script type="module">
    // import a specific version
    import * as p2 from 'https://www.unpkg.com/p2-es@1.1.6/dist/p2-es.js'

    // or import latest
    import * as p2 from 'https://www.unpkg.com/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.

import * as p2 from 'p2-es'

// Create a physics world, where bodies and constraints live
const world = new p2.World({
    gravity: [0, -9.82],
})

// Create an empty dynamic body
const circleBody = new p2.Body({
    mass: 5,
    position: [0, 10],
})

// Add a circle shape to the body
const circleShape = new p2.Circle({ radius: 1 })
circleBody.addShape(circleShape)

// ...and add the body to the world.
// If we don't add it to the world, it won't be simulated.
world.addBody(circleBody)

// Create an infinite ground plane body
const groundBody = new p2.Body({
    mass: 0, // Setting mass to 0 makes it static
})
const groundShape = new p2.Plane()
groundBody.addShape(groundShape)
world.addBody(groundBody)

// To animate the bodies, we must step the world forward in time, using a fixed time step size.
// The World will run substeps and interpolate automatically for us, to get smooth animation.
const fixedTimeStep = 1 / 60 // seconds
const maxSubSteps = 10 // Max sub steps to catch up with the wall clock
let lastTime = 0

// Animation loop
function animate(time) {
    requestAnimationFrame(animate)

    // Compute elapsed time since last render frame
    const deltaTime = (time - lastTime) / 1000

    // Move bodies forward in time
    world.step(fixedTimeStep, deltaTime, maxSubSteps)

    // Render the circle at the current interpolated position
    renderCircleAtPosition(circleBody.interpolatedPosition)

    lastTime = time
}

// Start the animation loop
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) {
    // Add horizontal spring force
    circleBody.force[0] -= 100 * circleBody.position[0]
})

Supported collision pairs

CirclePlaneBoxConvexParticleLineCapsuleHeightfieldRay
CircleYes--------
PlaneYes--------
BoxYesYesYes------
ConvexYesYesYesYes-----
ParticleYesYesYesYes-----
LineYesYes(todo)(todo)-----
CapsuleYesYesYesYesYes(todo)Yes--
HeightfieldYes-YesYes(todo)(todo)(todo)--
RayYesYesYesYes-YesYesYes-

Note that concave polygon shapes can be created using Body.fromPolygon.

Building

Make sure you have git, Node.js v14+ and Yarn installed

git clone https://github.com/pmndrs/p2-es.git && cd p2-es

# install deps
yarn

# build p2-es
(cd packages/p2-es && yarn build)

# build the website
yarn build

npx http-server apps/p2-es-website/dist
1.2.0

7 months ago

1.2.3

6 months ago

1.2.2

7 months ago

1.2.1

7 months ago

1.1.8

1 year ago

1.1.7

1 year ago

1.1.6

2 years ago

1.1.5

2 years ago

1.1.4

2 years ago

1.1.3

2 years ago

1.1.2

2 years ago

1.1.1

2 years ago

1.0.2

2 years ago

1.1.0

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.7.3

2 years ago

0.7.2

2 years ago

0.7.1

2 years ago