UNPKG

cannon-es-control

Version:

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

157 lines (132 loc) 4.92 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>cannon.js - convex 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' /** * Experiment for testing ConvexPolyhedrons. */ const demo = new Demo() 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: vertices, faces: [ [0, 3, 2], // -x [0, 1, 3], // -y [0, 2, 1], // -z [1, 2, 3], // +xyz ], }) } function createBoxPolyhedron(size = 1) { const box = new CANNON.Box(new CANNON.Vec3(size, size, size)) return box.convexPolyhedronRepresentation } // Various shapes demo.addScene('Various', () => { const world = setupWorld(demo) const size = 0.5 const mass = 10 // ConvexPolyhedron box shape const convexShape = createBoxPolyhedron(size) const boxbody = new CANNON.Body({ mass }) boxbody.addShape(convexShape) boxbody.position.set(-1, size + 1, 0) world.addBody(boxbody) demo.addVisual(boxbody) // ConvexPolyhedron tetra shape const tetraShape = createTetra() const tetraBody = new CANNON.Body({ mass }) tetraBody.addShape(tetraShape) tetraBody.position.set(-5, size + 1, -3) world.addBody(tetraBody) demo.addVisual(tetraBody) // The Cylinder is a ConvexPolyhedron under the hood const height = 2 const radius = 0.5 const detail = 20 const cylinderShape = new CANNON.Cylinder(radius, radius, height, detail) const cylinderBody = new CANNON.Body({ mass }) cylinderBody.addShape(cylinderShape) cylinderBody.position.set(0, size * 4 + 1, 0) cylinderBody.quaternion.setFromEuler(0, 0, Math.PI / 3) world.addBody(cylinderBody) demo.addVisual(cylinderBody) }) // Box on box tilting over demo.addScene('Convex on convex', () => { const world = setupWorld(demo) const size = 2 const mass = 10 const convexShape = createBoxPolyhedron(size) // ConvexPolyhedron box shape const boxBody1 = new CANNON.Body({ mass }) boxBody1.addShape(convexShape) boxBody1.position.set(0, size + 1, 0) world.addBody(boxBody1) demo.addVisual(boxBody1) const boxBody2 = new CANNON.Body({ mass }) boxBody2.addShape(convexShape) boxBody2.position.set(-1.5, size * 4 + 1, 0) world.addBody(boxBody2) demo.addVisual(boxBody2) }) // Pile of boxes demo.addScene('Convex wall', () => { const world = setupWorld(demo) const size = 1 const mass = 10 // ConvexPolyhedron box shape const convexShape = createBoxPolyhedron(size) for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { const boxbody = new CANNON.Body({ mass }) boxbody.addShape(convexShape) boxbody.position.set(-(size * 2 * i + 0.01), size * 2 * j + size * 1.2, 0) world.addBody(boxbody) demo.addVisual(boxbody) } } }) function setupWorld(demo) { const world = demo.getWorld() world.gravity.set(0, -30, 0) // Tweak contact properties. // Contact stiffness - use to make softer/harder contacts world.defaultContactMaterial.contactEquationStiffness = 5e6 // 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) // groundBody.position.set(-10, 0, 0) world.addBody(groundBody) demo.addVisual(groundBody) return world } demo.start() </script> </body> </html>