cannon
Version:
A lightweight 3D physics engine written in JavaScript.
400 lines (338 loc) • 12.6 kB
HTML
<html>
<head>
<title>cannon.js - stacks demo</title>
<meta charset="utf-8">
<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 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/TrackballControls.js"></script>
<script src="../libs/Detector.js"></script>
<script src="../libs/Stats.js"></script>
<script src="../libs/smoothie.js"></script>
<script>
/**
* For debugging different kinds of stacks
*/
var demo = new CANNON.Demo();
var size = 2, mass=5;
function createTetra(){
var verts = [new CANNON.Vec3(0,0,0),
new CANNON.Vec3(2,0,0),
new CANNON.Vec3(0,2,0),
new CANNON.Vec3(0,0,2)];
var offset = -0.35;
for(var i=0; i<verts.length; i++){
var v = verts[i];
v.x += offset;
v.y += offset;
v.z += offset;
}
return new CANNON.ConvexPolyhedron(verts,
[
[0,3,2], // -x
[0,1,3], // -y
[0,2,1], // -z
[1,2,3], // +xyz
]);
}
function createBoxPolyhedron(size){
size = size || 1;
var box = new CANNON.Box(new CANNON.Vec3(size,size,size));
return box.convexPolyhedronRepresentation;
}
function createCompound(mass){
var compoundBody = new CANNON.Body({ mass: mass });
var s = size;
var shape = new CANNON.Box(new CANNON.Vec3(0.5*s,0.5*s,0.5*s));
compoundBody.addShape(shape, new CANNON.Vec3( 0, 0, s));
compoundBody.addShape(shape, new CANNON.Vec3( 0, 0, 0));
compoundBody.addShape(shape, new CANNON.Vec3( 0, 0,-s));
compoundBody.addShape(shape, new CANNON.Vec3(-s, 0,-s));
return compoundBody;
}
// Spheres
demo.addScene("sphere/sphere",function(){
var world = setupWorld(demo);
// Sphere 1
var sphereShape = new CANNON.Sphere(size);
var b1 = new CANNON.Body({ mass: 5 });
b1.addShape(sphereShape);
b1.position.set(0,0,3*size);
world.add(b1);
demo.addVisual(b1);
// Sphere 2
var b2 = new CANNON.Body({ mass: 5 });
b2.addShape(sphereShape);
b2.position.set(0,0,1*size);
world.add(b2);
demo.addVisual(b2);
});
// Sphere/plane
demo.addScene("sphere/plane",function(){
var world = setupWorld(demo);
// Sphere 1
var sphereShape = new CANNON.Sphere(size);
var b1 = new CANNON.Body({ mass: 5 });
b1.addShape(sphereShape);
b1.position.set(0, 0, 3*size);
world.add(b1);
demo.addVisual(b1);
});
// Sphere / box side
demo.addScene("sphere/box",function(){
var world = setupWorld(demo);
var boxShape = new CANNON.Box(new CANNON.Vec3(size,size,size));
var sphereShape = new CANNON.Sphere(size);
// Box
var b1 = new CANNON.Body({mass: 5});
b1.addShape(boxShape);
b1.position.set(0,0,1*size);
world.add(b1);
demo.addVisual(b1);
// Sphere
var b2 = new CANNON.Body({ mass: 5 });
b2.addShape(sphereShape);
b2.position.set(0,0,3*size);
world.add(b2);
demo.addVisual(b2);
});
demo.addScene("sphere/compound",function(){
var world = setupWorld(demo);
// Sphere
var sphereShape = new CANNON.Sphere(size*0.5);
var b = new CANNON.Body({ mass: 5 });
b.addShape(sphereShape);
b.position.set(-size, 0, 6*size);
world.add(b);
demo.addVisual(b);
var compoundBody = createCompound(mass);
compoundBody.position.set(0,0,size*3);
world.add(compoundBody);
demo.addVisual(compoundBody);
});
demo.addScene("sphere/convex",function(){
var world = setupWorld(demo);
// Sphere
var sphereShape = new CANNON.Sphere(size*0.5);
var b = new CANNON.Body({ mass: 5 });
b.addShape(sphereShape);
b.position.set(0,0,6*size);
world.add(b);
demo.addVisual(b);
var shape = createTetra();//createBoxPolyhedron(size);
var b1 = new CANNON.Body({ mass: 5 });
b1.addShape(shape);
b1.position.set(0,0,1*size);
world.add(b1);
demo.addVisual(b1);
});
demo.addScene("sphere/particle",function(){
var world = setupWorld(demo);
// Sphere
var sphereShape = new CANNON.Sphere(size*0.5);
var b = new CANNON.Body({ mass: 5 });
b.addShape(sphereShape);
b.position.set(0,0,size);
world.add(b);
demo.addVisual(b);
// Particle
var p = new CANNON.Body({ mass: 1 });
p.addShape(new CANNON.Particle());
p.position.set(0.02,0,3*size);
world.add(p);
demo.addVisual(p);
});
demo.addScene("plane/box",function(){
var world = setupWorld(demo);
var boxShape = new CANNON.Box(new CANNON.Vec3(size,size,size));
var b1 = new CANNON.Body({ mass: 5 });
b1.addShape(boxShape);
b1.position.set(0,0,1*size);
world.add(b1);
demo.addVisual(b1);
});
demo.addScene("plane/compound",function(){
var world = setupWorld(demo);
var b1 = createCompound(5);
b1.position.set(0,0,4*size);
world.add(b1);
demo.addVisual(b1);
});
demo.addScene("plane/convex",function(){
var world = setupWorld(demo);
var shape = createTetra();
var b1 = new CANNON.Body({ mass: 5 });
b1.addShape(shape);
b1.position.set(0,0,1*size);
world.add(b1);
demo.addVisual(b1);
});
demo.addScene("plane/particle",function(){
var world = setupWorld(demo);
// Particle
var p = new CANNON.Body({ mass: 1 });
p.addShape(new CANNON.Particle());
p.position.set(0.02,0,3*size);
world.add(p);
demo.addVisual(p);
});
// Boxes
demo.addScene("box/box",function(){
var world = setupWorld(demo);
// Box 1
var boxShape = new CANNON.Box(new CANNON.Vec3(size*0.5,size*0.5,size*0.5));
var b1 = new CANNON.Body({ mass: 5 });
b1.addShape(boxShape);
b1.position.set(0,0,1*size);
world.add(b1);
demo.addVisual(b1);
// Box 2
var b2 = new CANNON.Body({ mass: 5 });
b2.addShape(boxShape);
b2.position.set(size*0.5,0,3*size);
world.add(b2);
demo.addVisual(b2);
});
demo.addScene("box/compound",function(){
var world = setupWorld(demo);
var b2 = createCompound(5);
b2.position.set(size*0.5,0,2*size);
world.add(b2);
demo.addVisual(b2);
var boxShape = new CANNON.Box(new CANNON.Vec3(size*0.5,size*0.5,size*0.5));
var b1 = new CANNON.Body({ mass: 5 });
b1.addShape(boxShape);
b1.position.set(0,0,7*size);
world.add(b1);
demo.addVisual(b1);
});
demo.addScene("box/convex",function(){
var world = setupWorld(demo);
var shape = createTetra(size);
var b2 = new CANNON.Body({ mass: 5 });
b2.addShape(shape);
b2.position.set(0,0,5*size);
world.add(b2);
demo.addVisual(b2);
var boxShape = new CANNON.Box(new CANNON.Vec3(size*0.5,size*0.5,size*0.5));
var b1 = new CANNON.Body({ mass: 5 });
b1.addShape(boxShape);
b1.position.set(0,0,2*size);
world.add(b1);
demo.addVisual(b1);
});
demo.addScene("box/particle",function(){
var world = setupWorld(demo);
var boxShape = new CANNON.Box(new CANNON.Vec3(size*0.5,size*0.5,size*0.5));
var b1 = new CANNON.Body({ mass:5 });
b1.addShape(boxShape);
b1.position.set(0,0,1*size);
world.add(b1);
demo.addVisual(b1)
// Particle
var p = new CANNON.Body({ mass: 1 });
p.addShape(new CANNON.Particle());
p.position.set(0,0,3*size);
world.add(p);
demo.addVisual(p);
});
demo.addScene("compound/compound",function(){
var world = setupWorld(demo);
var b2 = createCompound(5);
b2.position.set(size*0.5,0,6*size);
world.add(b2);
demo.addVisual(b2);
var b2 = createCompound(5);
b2.position.set(size*0.5,0,2*size);
world.add(b2);
demo.addVisual(b2);
});
demo.addScene("compound/convex",function(){
var world = setupWorld(demo);
var tetraShape = createTetra();
var b1 = new CANNON.Body({ mass:5 });
b1.addShape(tetraShape);
b1.position.set(0,0,3*size);
world.add(b1);
demo.addVisual(b1);
// Box 2
var boxShape = new CANNON.Box(new CANNON.Vec3(size*0.5,size*0.5,size*0.5));
var b2 = new CANNON.Body({ mass:5 });
b2.addShape(boxShape);
b2.position.set(0,0,1*size);
world.add(b2);
demo.addVisual(b2);
});
demo.addScene("compound/particle",function(){
var world = setupWorld(demo);
var t = createCompound(5);
t.position.set(0,0,4*size);
// Particle
var p = new CANNON.Body({ mass: 1 });
p.addShape(new CANNON.Particle());
p.position.set(0,0,7*size);
world.add(t);
demo.addVisual(t);
world.add(p);
demo.addVisual(p);
});
// ConvexPolyhedron and box
demo.addScene("convex/convex",function(){
var world = setupWorld(demo);
var tetraShape = createTetra();
var b1 = new CANNON.Body({ mass:5 });
b1.addShape(tetraShape);
b1.position.set(0.1,0.1,5*size);
world.add(b1);
demo.addVisual(b1);
var tetraShape = createTetra();
var b1 = new CANNON.Body({ mass:5 });
b1.addShape(tetraShape);
b1.position.set(0,0,3*size);
world.add(b1);
demo.addVisual(b1);
});
// ConvexPolyhedron and particle
demo.addScene("convex/particle",function(){
var world = setupWorld(demo);
var tetraShape = createBoxPolyhedron(size);
var t = new CANNON.Body({ mass:5 });
t.addShape(tetraShape);
t.position.set(0,0,1*size);
t.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0),Math.PI/2);
// Particle
var p = new CANNON.Body({ mass: 1 });
p.addShape(new CANNON.Particle());
p.position.set(0,0,3*size);
world.add(t);
demo.addVisual(t);
world.add(p);
demo.addVisual(p);
});
demo.start();
function setupWorld(demo){
var world = demo.getWorld();
world.gravity.set(0,0,-10);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 20;
world.defaultContactMaterial.contactEquationStiffness = 1e7;
world.defaultContactMaterial.contactEquationRelaxation = 5;
// ground plane
var groundShape = new CANNON.Plane();
var groundBody = new CANNON.Body({ mass:0 });
groundBody.addShape(groundShape);
groundBody.position.set(0,0,-1);
//groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0),0.2);
world.add(groundBody);
demo.addVisual(groundBody);
return world;
}
</script>
</body>
</html>