Skip to content

Instantly share code, notes, and snippets.

@edom18
Created August 15, 2013 23:51
Show Gist options
  • Save edom18/6246038 to your computer and use it in GitHub Desktop.
Save edom18/6246038 to your computer and use it in GitHub Desktop.
Cannon.js x Three.jsで3D物理演算
#WebGLで物理演算
WebGLライブラリの代表格、[Three.js](https://github.com/mrdoob/three.js/)と、
それにインスパイアされて作られた[Cannon.js](https://github.com/schteppe/cannon.js)を組み合わせて物理演算させるデモ。
Three.jsにインスパイアされただけあって、メソッド名とか使い方がかなり似ているので使いやすいです。
@import "compass/reset";
img, canvas {
vertical-align: top;
}
<script src="/assets/f/J/B/D/fJBDQ"></script>
<script src="/assets/u/4/z/N/u4zNG"></script>
(function (win, doc) {
'use strict';
var world, shape, mass, body, ground, timeStep = 1 / 60,
camera, scene, renderer, cube, plane,
cubeSize = 2;
function createCube(w, h, d) {
var geometry = new THREE.CubeGeometry(w, h, d, 10, 10);
var material = new THREE.MeshLambertMaterial({
color: 0x666666
});
var mesh = new THREE.Mesh(geometry, material);
return mesh;
}
function createPlane(w, h) {
var geometry = new THREE.PlaneGeometry(w, h);
var material = new THREE.MeshPhongMaterial({
color: 0xffffff,
specular: 0xeeeeee,
shininess: 50
});
var mesh = new THREE.Mesh(geometry, material);
return mesh;
}
function initCannon() {
world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;
world.solver.tolerance = 0.001;
var plane = new CANNON.Plane();
ground= new CANNON.RigidBody(0, plane);
ground.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
world.add(ground);
shape = new CANNON.Box(new CANNON.Vec3(cubeSize, cubeSize, cubeSize));
mass = 1;
body = new CANNON.RigidBody(mass, shape);
body.position.y = 10;
body.angularVelocity.set(0, 0, 10);
body.angularDamping = 0.1;
world.add(body);
}
function initThree() {
var w = win.innerWidth;
var h = win.innerHeight;
camera = new THREE.PerspectiveCamera(30, w / h, 1, 10000);
camera.position.set(Math.cos(Math.PI / 5) * 30, 5, Math.sin(Math.PI / 5) * 30);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x000000, 1, 200);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(w, h);
renderer.setClearColor(0x000000, 1);
renderer.shadowMapEnabled = true;
var light = new THREE.DirectionalLight(0xffffff, 2);
var amb = new THREE.AmbientLight(0x404040);
var d = 100;
light.position.set(d, d, d);
light.castShadow = true;
//light.shadowCameraVisible = true;
light.shadowMapWidth = 1024;
light.shadowMapHeight = 1024;
light.shadowCameraLeft = -d;
light.shadowCameraRight = d;
light.shadowCameraTop = d;
light.shadowCameraBottom = -d;
light.shadowCameraFar = 1000;
light.shadowCameraNear = 1;
light.shadowDarkness = 0.5;
cube = createCube(cubeSize, cubeSize, cubeSize);
cube.castShadow = true;
cube.receiveShadow = true;
plane = createPlane(300, 300);
plane.rotation.x = -Math.PI / 2;
plane.position.y = cubeSize / 2;
plane.receiveShadow = true;
scene.add(camera);
scene.add(light);
scene.add(amb);
scene.add(cube);
scene.add(plane);
doc.body.appendChild(renderer.domElement);
renderer.render(scene, camera);
}
function animate() {
requestAnimationFrame(animate);
updatePhysics();
render();
}
function updatePhysics() {
world.step(timeStep);
body.position.copy(cube.position);
body.quaternion.copy(cube.quaternion);
//ground.position.copy(plane.position);
//ground.quaternion.copy(plane.quaternion);
}
function render() {
renderer.render(scene, camera);
}
initCannon();
initThree();
animate();
}(window, document));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment