UNPKG

cannon-es-control

Version:

A lightweight 3D physics engine written in JavaScript with control system tools

140 lines (120 loc) 5 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>cannon.js - shapes demo</title> <link rel="stylesheet" href="css/style.css" type="text/css" /> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" /> </head> <body> <script type="module"> import * as CANNON from '../dist/cannon-es-control.js' import { Demo } from './js/Demo.js' const demo = new Demo() /** * Showcase all available shapes. */ function createTetra() { const vertices = [ new CANNON.Vec3(0, 0, 0), new CANNON.Vec3(2, 0, 0), new CANNON.Vec3(0, 2, 0), new CANNON.Vec3(0, 0, 2), ] const offset = -0.35 for (let i = 0; i < vertices.length; i++) { const v = vertices[i] v.x += offset v.y += offset v.z += offset } return new CANNON.ConvexPolyhedron({ vertices, faces: [ [0, 3, 2], // -x [0, 1, 3], // -y [0, 2, 1], // -z [1, 2, 3], // +xyz ], }) } demo.addScene('All shapes', () => { const world = setupWorld(demo) const mass = 1 const size = 1 // Sphere shape const sphereShape = new CANNON.Sphere(size) const sphereBody = new CANNON.Body({ mass }) sphereBody.addShape(sphereShape) sphereBody.position.set(-size * 2, size + 1, size * 2) world.addBody(sphereBody) demo.addVisual(sphereBody) // Cylinder shape const cylinderShape = new CANNON.Cylinder(size, size, size * 2, 10) const cylinderBody = new CANNON.Body({ mass }) cylinderBody.addShape(cylinderShape) cylinderBody.position.set(size * 2, size + 1, size * 2) world.addBody(cylinderBody) demo.addVisual(cylinderBody) // Cylinder shape 2 const cylinderShape2 = new CANNON.Cylinder(size, size, size * 2, 10) const cylinderBody2 = new CANNON.Body({ mass }) cylinderBody2.addShape(cylinderShape2) cylinderBody2.position.set(size * 2, size * 4 + 1, size * 2) cylinderBody2.quaternion.setFromEuler(Math.PI / 2, Math.PI / 2, 0) world.addBody(cylinderBody2) demo.addVisual(cylinderBody2) // Box shape const boxShape = new CANNON.Box(new CANNON.Vec3(size, size, size)) const boxBody = new CANNON.Body({ mass }) boxBody.addShape(boxShape) boxBody.position.set(size * 2, size + 1, -size * 2) world.addBody(boxBody) demo.addVisual(boxBody) // Particle - not a shape but still here to show how to use it. const particle = new CANNON.Body({ mass }) particle.addShape(new CANNON.Particle()) particle.position.set(size * 2, size + 1, size * 4) world.addBody(particle) demo.addVisual(particle) // Compound const compoundBody = new CANNON.Body({ mass }) const shape = new CANNON.Box(new CANNON.Vec3(size * 0.5, size * 0.5, size * 0.5)) compoundBody.addShape(shape, new CANNON.Vec3(0, size, 0)) compoundBody.addShape(shape, new CANNON.Vec3(0, 0, 0)) compoundBody.addShape(shape, new CANNON.Vec3(0, -size, 0)) compoundBody.addShape(shape, new CANNON.Vec3(size, -size, 0)) compoundBody.position.set(size * 4, size + 1, size * 4) world.addBody(compoundBody) demo.addVisual(compoundBody) // ConvexPolyhedron tetra shape const polyhedronShape = createTetra() const polyhedronBody = new CANNON.Body({ mass }) polyhedronBody.addShape(polyhedronShape) polyhedronBody.position.set(-size * 2, size + 1, -size * 2) world.addBody(polyhedronBody) demo.addVisual(polyhedronBody) }) demo.start() function setupWorld(demo) { const world = demo.getWorld() world.gravity.set(0, -30, 0) // Max solver iterations: Use more for better force propagation, but keep in mind that it's not very computationally cheap! world.solver.iterations = 17 // Tweak contact properties. // Contact stiffness - use to make softer/harder contacts world.defaultContactMaterial.contactEquationStiffness = 1e6 // Stabilization time in number of timesteps world.defaultContactMaterial.contactEquationRelaxation = 3 // Static ground plane const groundShape = new CANNON.Plane() const groundBody = new CANNON.Body({ mass: 0 }) groundBody.addShape(groundShape) groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0) world.addBody(groundBody) demo.addVisual(groundBody) return world } </script> </body> </html>