cannon-es-control
Version:
A lightweight 3D physics engine written in JavaScript with control system tools
111 lines (94 loc) • 3.88 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8" />
<title>cannon.js - pile 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()
let interval
// Spheres
demo.addScene('Pile', () => {
const world = setupWorld(demo)
// Plane -x
const planeShapeXmin = new CANNON.Plane()
const planeXmin = new CANNON.Body({ mass: 0 })
planeXmin.addShape(planeShapeXmin)
planeXmin.quaternion.setFromEuler(0, Math.PI / 2, 0)
planeXmin.position.set(-5, 0, 0)
world.addBody(planeXmin)
// Plane +x
const planeShapeXmax = new CANNON.Plane()
const planeXmax = new CANNON.Body({ mass: 0 })
planeXmax.addShape(planeShapeXmax)
planeXmax.quaternion.setFromEuler(0, -Math.PI / 2, 0)
planeXmax.position.set(5, 0, 0)
world.addBody(planeXmax)
// Plane -z
const planeShapeZmin = new CANNON.Plane()
const planeZmin = new CANNON.Body({ mass: 0 })
planeZmin.addShape(planeShapeZmin)
planeZmin.quaternion.setFromEuler(0, 0, 0)
planeZmin.position.set(0, 0, -5)
world.addBody(planeZmin)
// Plane +z
const planeShapeZmax = new CANNON.Plane()
const planeZmax = new CANNON.Body({ mass: 0 })
planeZmax.addShape(planeShapeZmax)
planeZmax.quaternion.setFromEuler(0, Math.PI, 0)
planeZmax.position.set(0, 0, 5)
world.addBody(planeZmax)
const size = 1
const bodies = []
let i = 0
if (interval) clearInterval(interval)
interval = setInterval(() => {
// Sphere
i++
const sphereShape = new CANNON.Sphere(size)
const sphereBody = new CANNON.Body({
mass: 5,
position: new CANNON.Vec3(-size * 2 * Math.sin(i), size * 2 * 7, size * 2 * Math.cos(i)),
})
sphereBody.addShape(sphereShape)
world.addBody(sphereBody)
demo.addVisual(sphereBody)
bodies.push(sphereBody)
if (bodies.length > 80) {
const bodyToKill = bodies.shift()
demo.removeVisual(bodyToKill)
world.removeBody(bodyToKill)
}
}, 100)
})
demo.start()
function setupWorld(demo) {
const world = demo.getWorld()
world.gravity.set(0, -50, 0)
// Max solver iterations: Use more for better force propagation, but keep in mind that it's not very computationally cheap!
world.solver.iterations = 5
// Tweak contact properties.
// Contact stiffness - use to make softer/harder contacts
world.defaultContactMaterial.contactEquationStiffness = 5e6
// Stabilization time in number of timesteps
world.defaultContactMaterial.contactEquationRelaxation = 10
// Since we have many bodies and they don't move very much, we can use the less accurate quaternion normalization
world.quatNormalizeFast = true
world.quatNormalizeSkip = 3 // ...and we do not have to normalize every step.
// 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>