cannon-es-control
Version:
A lightweight 3D physics engine written in JavaScript with control system tools
90 lines (74 loc) • 2.99 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8" />
<title>cannon.js - tear 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'
/**
* Demo of a chain of bodies which breaks with a certain
* force threshold.
*/
const demo = new Demo()
demo.addScene('Sphere chain', () => {
const world = setupWorld(demo)
// world.solver.setSpookParams(1e20, 3)
const size = 0.45
const mass = 1
// The number of chain links
const N = 15
// The distance constraint between those links
const distance = size * 2 + 0.12
// To be able to propagate force throw the chain of N spheres, we need at least N solver iterations.
world.solver.iterations = N
const sphereShape = new CANNON.Sphere(size)
const constraints = []
let lastBody
for (let i = 0; i < N; i++) {
// First body is static (mass = 0) to support the other bodies
const sphereBody = new CANNON.Body({ mass: i === 0 ? 0 : mass })
sphereBody.addShape(sphereShape)
sphereBody.position.set(0, (N - i) * distance - 9, 0)
world.addBody(sphereBody)
demo.addVisual(sphereBody)
// Connect this body to the last one added
if (lastBody) {
const constraint = new CANNON.DistanceConstraint(sphereBody, lastBody, distance)
world.addConstraint(constraint)
constraints.push(constraint)
}
// Keep track of the last added body
lastBody = sphereBody
}
world.addEventListener('postStep', () => {
for (let i = constraints.length - 1; i >= 0; i--) {
// The multiplier is proportional to how much force that is added to the bodies by the constraint.
// If this exceeds a limit we remove the constraint.
const multiplier = Math.abs(constraints[i].equations[0].multiplier)
if (multiplier > 1000) {
world.removeConstraint(constraints[i])
}
}
})
// Throw a body on the chain to break it!
const sphereBody = new CANNON.Body({ mass: mass * 2 })
sphereBody.addShape(sphereShape)
sphereBody.position.set(-20, 3, 0)
sphereBody.velocity.x = 30
world.addBody(sphereBody)
demo.addVisual(sphereBody)
})
function setupWorld(demo) {
const world = demo.getWorld()
world.gravity.set(0, -10, 0)
return world
}
demo.start()
</script>
</body>
</html>