topical media & game development
mobile-query-three-plugins-cannonjs-vendor-cannon.js-demos-convexhull.htm / htm
<DOCTYPE html>
<html>
<head>
<title>cannon.js - convex hull demo</title>
<meta charset="utf-8">
<style>* {margin:0;padding:0}</style>
</head>
<body>
<script src="../build/cannon.js"></script>
<script src="../build/cannon.demo.js"></script>
<script src="../libs/dat.gui.js"></script>
<script src="../libs/Three.js"></script>
<script src="../libs/Detector.js"></script>
<script src="../libs/Stats.js"></script>
<script>
Experiment for testing ConvexPolyhedrons.
var demo = new CANNON.Demo({ stepFrequency:120 });
function createBoxPolyhedron(size){
size = size || 1;
var boxShape = new CANNON.ConvexPolyhedron([new CANNON.Vec3(-size,-size,-size),
new CANNON.Vec3( size,-size,-size),
new CANNON.Vec3( size, size,-size),
new CANNON.Vec3(-size, size,-size),
new CANNON.Vec3(-size,-size, size),
new CANNON.Vec3( size,-size, size),
new CANNON.Vec3( size, size, size),
new CANNON.Vec3(-size, size, size)],
[[0,1,2,3], // -z
[4,5,6,7], // +z
[0,1,4,5], // -y
[2,3,6,7], // +y
[0,3,4,7], // -x
[1,2,5,6], // +x
],
[new CANNON.Vec3( 0, 0,-1),
new CANNON.Vec3( 0, 0, 1),
new CANNON.Vec3( 0,-1, 0),
new CANNON.Vec3( 0, 1, 0),
new CANNON.Vec3(-1, 0, 0),
new CANNON.Vec3( 1, 0, 0)]);
return boxShape;
}
// Various shapes
demo.addScene("various",function(){
var world = setupWorld(demo);
// ConvexPolyhedron box shape
var size = 0.5;
var hullShape = createBoxPolyhedron(size);
var mass = 10;
var boxbody = new CANNON.RigidBody(mass,hullShape);
boxbody.position.set(1,0,size+1);
world.add(boxbody);
demo.addVisual(boxbody);
// ConvexPolyhedron tetra shape
var tetraShape = new CANNON.ConvexPolyhedron([new CANNON.Vec3(0,0,0),
new CANNON.Vec3(2,0,0),
new CANNON.Vec3(0,2,0),
new CANNON.Vec3(0,0,2)],
[
[0,3,2], // -x
[0,1,3], // -y
[0,1,2], // -z
[1,3,2], // +xyz
],
[new CANNON.Vec3(-1, 0, 0),
new CANNON.Vec3( 0,-1, 0),
new CANNON.Vec3( 0, 0,-1),
new CANNON.Vec3( 1, 1, 1)]);
var tetraBody = new CANNON.RigidBody(mass,tetraShape);
tetraBody.position.set(5,-3,size+1);
world.add(tetraBody);
demo.addVisual(tetraBody);
// ConvexPolyhedron cylinder shape
var num = 20;
var verts = [];
var normals = [];
var faces = [];
var bottomface = [];
var topface = [];
var L = 1, R = 0.5;
verts.push(new CANNON.Vec3(R*Math.cos(0),
R*Math.sin(0),
-L));
bottomface.push(0);
verts.push(new CANNON.Vec3(R*Math.cos(0),
R*Math.sin(0),
L));
topface.push(1);
for(var i=0; i<num; i++){
// Bottom
var theta = 2*Math.PI/num * (i+1);
var thetaN = 2*Math.PI/num * (i+0.5);
if(i<num-1){
// Bottom
verts.push(new CANNON.Vec3(R*Math.cos(theta),
R*Math.sin(theta),
-L));
bottomface.push(2*(i+1));
// Top
verts.push(new CANNON.Vec3(R*Math.cos(theta),
R*Math.sin(theta),
L));
topface.push(2*(i+1)+1);
// Normal
normals.push(new CANNON.Vec3(Math.cos(thetaN),
Math.sin(thetaN),
0));
// Face
faces.push([2*i, 2*i+1, 2*(i+1), 2*(i+1)+1]);
} else {
faces.push([2*i, 2*i+1, 0, 1]);
// Normal
normals.push(new CANNON.Vec3(Math.cos(thetaN),
Math.sin(thetaN),
0));
}
}
faces.push(topface);
normals.push(new CANNON.Vec3(0,0,1));
faces.push(bottomface);
normals.push(new CANNON.Vec3(0,0,-1));
var cylinderShape = new CANNON.ConvexPolyhedron(verts,faces,normals);
var cylinderBody = new CANNON.RigidBody(mass,cylinderShape);
cylinderBody.position.set(0,0,size*4+1);
cylinderBody.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0),Math.PI/3);
world.add(cylinderBody);
demo.addVisual(cylinderBody);
});
// Just 1 box on a plane
demo.addScene("Hull on plane",function(){
var world = setupWorld(demo);
// ConvexPolyhedron box shape
var size = 2;
var hullShape = createBoxPolyhedron(size);
// At the moment one must provide vertices, faces and normals..
var mass = 10;
var boxbody1 = new CANNON.RigidBody(mass,hullShape);
boxbody1.position.set(0,0,size*2);
boxbody1.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0),Math.PI/4);
world.add(boxbody1);
demo.addVisual(boxbody1);
});
// Box on box tilting over
demo.addScene("Hull on hull",function(){
var world = setupWorld(demo);
// ConvexPolyhedron box shape
var size = 2;
var hullShape = createBoxPolyhedron(size);
var mass = 10;
var boxbody1 = new CANNON.RigidBody(mass,hullShape);
var boxbody2 = new CANNON.RigidBody(mass,hullShape);
boxbody1.position.set(0,0,size+1);
boxbody2.position.set(1.5,0,4*size+1);
world.add(boxbody1);
world.add(boxbody2);
demo.addVisual(boxbody1);
demo.addVisual(boxbody2);
});
// Pile of boxes
demo.addScene("Hull wall",function(){
var world = setupWorld(demo);
// ConvexPolyhedron box shape
var size = 1;
var hullShape = createBoxPolyhedron(size);
var mass = 10;
for(var i=0; i<3; i++){
for(var j=0; j<3; j++){
var boxbody = new CANNON.RigidBody(mass,hullShape);
boxbody.position.set(2*size*i+0.01,0,2*size*j + size*1.2);
world.add(boxbody);
demo.addVisual(boxbody);
}
}
});
function setupWorld(demo){
var world = demo.getWorld();
world.gravity.set(0,0,-30);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 40;
world.solver.setSpookParams(5000,7);
// ground plane
var n = new CANNON.Vec3(0,0,1);
n.normalize();
var groundShape = new CANNON.Plane(n);
var groundBody = new CANNON.RigidBody(0,groundShape);
groundBody.position.set(-10,0,0);
world.add(groundBody);
demo.addVisual(groundBody);
return world;
};
demo.start();
</script>
</body>
</html>
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.