I translated an example from the the first tutorial to Cannon-ES:
Instruction:
- Install Rollup:
npm i -D rollup
- Use this command to debug:
rollup -cmw
- To release install UglifyJS:
npm i uglify-js -g
and use this command rollup -c
, and next: uglifyjs public/js/bundle.js -o public/js/bundle.min.js
rollup.config.js
export default {
input: "./src/client/main.js",
output: {
file: "public/js/bundle.js"
}
}
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,
body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script async src="https://unpkg.com/es-module-shims@1.5.5/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.141.0/build/three.module.js",
"collada-loader": "https://unpkg.com/three@0.141.0/examples/jsm/loaders/ColladaLoader.js",
"orbit-controls": "https://unpkg.com/three@0.141.0/examples/jsm/controls/OrbitControls.js",
"cannon-es": "https://cdn.jsdelivr.net/npm/cannon-es@0.19.0/dist/cannon-es.js"
}
}
</script>
<script type="module" src="js/bundle.js"></script>
</body>
</html>
src/client/main.js
import * as THREE from "three";
import { OrbitControls } from "orbit-controls";
import * as CANNON from "cannon-es";
let scene;
const world = new CANNON.World({ gravity: new CANNON.Vec3(0, -10, 0) });
const rigidBodies = [];
function init()
{
initScene();
createGround();
createBox({ x: 0, y: 5, z: 0.5 });
createBox({ x: 0.5, y: 2, z: 0 });
}
init();
function createGround()
{
const pos = { x: 0, y: 0, z: 0 };
const scale = { x: 50, y: 2, z: 50 };
const quat = { x: 0, y: 0, z: 0, w: 1 };
const mass = 0;
// Three.js section
const ground = new THREE.Mesh(
new THREE.BoxBufferGeometry(),
new THREE.MeshPhongMaterial({ color: 0xa0afa4 }));
ground.position.set(pos.x, pos.y, pos.z);
ground.scale.set(scale.x, scale.y, scale.z);
ground.receiveShadow = true;
scene.add(ground);
// Cannon-ES section
const colShape = new CANNON.Box(new CANNON.Vec3(scale.x / 2, scale.y / 2, scale.z / 2));
const body = new CANNON.Body({ mass: mass });
body.position.set(pos.x, pos.y, pos.z);
body.quaternion.set(quat.x, quat.y, quat.z, quat.w);
body.addShape(colShape);
world.addBody(body);
}
function createBox(pos)
{
const scale = { x: 1, y: 1, z: 1 };
const quat = { x: 0, y: 0, z: 0, w: 1 };
const mass = 10;
// Three.js section
const box = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshPhongMaterial({ color: 0xe77732 }));
scene.add(box);
box.position.set(pos.x, pos.y, pos.z);
box.scale.set(scale.x, scale.y, scale.z);
box.castShadow = true;
box.receiveShadow = true;
scene.add(box);
// Cannon-ES section
const colShape = new CANNON.Box(new CANNON.Vec3(scale.x / 2, scale.y / 2, scale.z / 2));
const body = new CANNON.Body({ mass: mass });
body.position.set(pos.x, pos.y, pos.z);
body.quaternion.set(quat.x, quat.y, quat.z, quat.w);
body.addShape(colShape);
world.addBody(body);
box.userData.physicsBody = body;
rigidBodies.push(box);
}
function updatePhysics()
{
world.fixedStep();
for (let i = 0; i < rigidBodies.length; i++)
{
let objThree = rigidBodies[i];
let objCannon = objThree.userData.physicsBody;
objThree.position.copy(objCannon.position);
objThree.quaternion.copy(objCannon.quaternion);
}
}
function initScene()
{
// Create the scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xbfd1e5);
// Add hemisphere light
let hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.1);
hemiLight.color.setHSL(0.6, 0.6, 0.6);
hemiLight.groundColor.setHSL(0.1, 1, 0.4);
hemiLight.position.set(0, 50, 0);
scene.add(hemiLight);
// Add directional light
let dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.color.setHSL(0.1, 1, 0.95);
dirLight.position.set(-1, 1.75, 1);
dirLight.position.multiplyScalar(100);
scene.add(dirLight);
dirLight.castShadow = true;
dirLight.shadow.mapSize.width = 2048;
dirLight.shadow.mapSize.height = 2048;
let d = 50;
dirLight.shadow.camera.left = -d;
dirLight.shadow.camera.right = d;
dirLight.shadow.camera.top = d;
dirLight.shadow.camera.bottom = -d;
dirLight.shadow.camera.far = 13500;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor(0xbfd1e5);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMap.enabled = true;
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.set(2, 4, 7);
const orbitControls = new OrbitControls(camera, renderer.domElement);
orbitControls.target = new THREE.Vector3(0, 0, 0);
(function anim()
{
requestAnimationFrame(anim);
orbitControls.update();
updatePhysics();
renderer.render(scene, camera);
})();
window.onresize =
() =>
{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
};
}