cannon-es-control
Version:
A lightweight 3D physics engine written in JavaScript with control system tools
130 lines (106 loc) • 3.96 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8" />
<title>cannon.js - Canvas interpolation example</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" />
<style>
.page-title {
color: black;
}
.page-title span {
color: #2f56e7;
}
</style>
<script type="module">
import { addTitle, addSourceButton } from './js/dom-utils.js'
addTitle()
addSourceButton()
</script>
</head>
<body>
<script type="module">
import * as CANNON from '../dist/cannon-es-control.js'
/**
* Example of interpolatedPosition and interpolatedQuaternion
* using a canvas for simplicity
*/
let ctx
let world
let sphereBody
const radius = 1
let lastCallTime = getTime()
init()
animate()
function init() {
// Init canvas
const canvas = document.createElement('canvas')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
document.body.appendChild(canvas)
ctx = canvas.getContext('2d')
ctx.lineWidth = 0.05
window.addEventListener('resize', () => {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
ctx.lineWidth = 0.05
})
// Init world
world = new CANNON.World()
// Add a circle (sphere) in the physics world
const sphereShape = new CANNON.Sphere(radius)
sphereBody = new CANNON.Body({
mass: 1,
position: new CANNON.Vec3(1, -2.5, 0),
})
sphereBody.addShape(sphereShape)
world.addBody(sphereBody)
}
function drawCircles() {
// Draw the circle at the interpolated position
ctx.beginPath()
ctx.arc(sphereBody.interpolatedPosition.x, sphereBody.interpolatedPosition.y, radius, 0, Math.PI * 2)
ctx.stroke()
// Draw the circle at the fixed step position
ctx.beginPath()
ctx.arc(sphereBody.position.x, sphereBody.position.y, radius, 0, Math.PI * 2)
ctx.stroke()
}
function render() {
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight)
ctx.save()
ctx.translate(window.innerWidth / 2, window.innerHeight / 2)
ctx.scale(50, 50)
drawCircles()
ctx.restore()
}
// Animation loop
function animate() {
requestAnimationFrame(animate)
const time = getTime()
// Compute time since last time we called the .step() method
const timeSinceLastCall = time - lastCallTime
lastCallTime = time
sphereBody.velocity.x = Math.cos(time) * 3
sphereBody.velocity.y = Math.sin(time) * 3
// Fixed time step to use for physics. We use a huge timestep of 0.5 to see what's going on.
// NOTE: For most games, fixedTimeStep=1/60 is a good choice.
const fixedTimeStep = 0.5 // seconds
// Max number of fixed physics timesteps to do in one .step(). We choose a large number to see what is going on.
// NOTE: for most games, maxSubSteps=3 is probably a good choice.
const maxSubSteps = 10
// Now step the world.
// This will do integration at a fixed time step, but compute interpolated positions
// which are stored in body.interpolatedPosition.
world.step(fixedTimeStep, timeSinceLastCall, maxSubSteps)
// Render both interpolated and fixed-step positions
render(ctx, sphereBody)
}
// Get current time, in seconds.
function getTime() {
return performance.now() / 1000
}
</script>
</body>
</html>