topical media & game development
mobile-query-three-plugins-cannonjs-vendor-cannon.js-demos-constraints.htm / htm
<DOCTYPE html>
<html>
<head>
<title>cannon.js - constraints 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>
var demo = new CANNON.Demo({paused:false});
// Particle cloth on sphere
demo.addScene("cloth on sphere",function(){
var world = setupWorld(demo);
world.solver.setSpookParams(1000,2);
world.solver.iterations = 20;
var dist = 0.2;
var mass = 0.5;
var Nrows = 15, Ncols = 15;
var bodies = {}; // bodies["i j"] => particle
for(var i=0; i<Ncols; i++){
for(var j=0; j<Nrows; j++){
// Create a new body
var body = new CANNON.Particle(mass);
body.position.set((i-Ncols*0.5)*dist,(j-Nrows*0.5)*dist,5);
bodies[i+" "+j] = body;
world.add(body);
demo.addVisual(body);
}
}
function connect(i1,j1,i2,j2){
world.addConstraint(new CANNON.DistanceConstraint(bodies[i1+" "+j1],bodies[i2+" "+j2],dist));
}
for(var i=0; i<Ncols; i++){
for(var j=0; j<Nrows; j++){
if(i<Ncols-1) connect(i,j,i+1,j);
if(j<Nrows-1) connect(i,j,i,j+1);
}
}
var sphere = new CANNON.Sphere(1.5);
var body = new CANNON.RigidBody(0,sphere);
body.position.set(0,0,3.5);
world.add(body);
demo.addVisual(body);
});
demo.addScene("links",function(){
var world = setupWorld(demo);
world.gravity.set(0,-5,-20);
world.solver.setSpookParams(150,5);
var size = 1;
var boxShape = new CANNON.Box(new CANNON.Vec3(size,size*0.1,size));
var mass = 0;
var space = 0.1*size;
var N=5, last;
for(var i=0; i<N; i++){
var boxbody = new CANNON.RigidBody(mass,boxShape);
boxbody.position.set(0,0,(N-i)*(size*2+2*space) + size*2+space);
boxbody.linearDamping=0.01;
boxbody.angularDamping=0.01;
world.add(boxbody);
demo.addVisual(boxbody);
if(i!=0){
// Connect this body to the last one
var c1 = new CANNON.PointToPointConstraint(boxbody,new CANNON.Vec3(-size,0,size+space),last,new CANNON.Vec3(-size,0,-size-space));
var c2 = new CANNON.PointToPointConstraint(boxbody,new CANNON.Vec3(size,0,size+space),last,new CANNON.Vec3(size,0,-size-space));
world.addConstraint(c1);
world.addConstraint(c2);
} else {
mass=0.3;
}
last = boxbody;
}
});
demo.addScene("Sphere pendulum",function(){
var world = setupWorld(demo);
var size = 1;
var sphereShape = new CANNON.Sphere(size);
var mass = 1;
var spherebody = new CANNON.RigidBody(mass,sphereShape);
spherebody.position.set(0,0,size*3);
spherebody.velocity.set(10,0,0);
spherebody.linearDamping=0;
spherebody.angularDamping=0;
world.add(spherebody);
demo.addVisual(spherebody);
var spherebody2 = new CANNON.RigidBody(0,sphereShape);
spherebody2.position.set(0,0,size*7);
world.add(spherebody2);
demo.addVisual(spherebody2);
// Connect this body to the last one
var c = new CANNON.PointToPointConstraint(spherebody,new CANNON.Vec3(0,0,size*2),spherebody2,new CANNON.Vec3(0,0,-size*2));
world.addConstraint(c);
});
// Sphere chain
demo.addScene("Sphere chain",function(){
var size = 0.5;
var dist = size*2+2;
var world = setupWorld(demo);
world.solver.setSpookParams(1000,2);
var sphereShape = new CANNON.Sphere(size);
var mass = 1;
var lastBody = null;
var N = 10;
for(var i=0; i<N; i++){
// Create a new body
var spherebody = new CANNON.RigidBody(i===0 ? 0 :mass,sphereShape);
spherebody.position.set(0,0,(N-i)*dist);
spherebody.velocity.x = i;
world.add(spherebody);
demo.addVisual(spherebody);
// Connect this body to the last one
var c;
if(lastBody!==null){
c = new CANNON.DistanceConstraint(spherebody,lastBody,dist);
} else {
c = new CANNON.DistanceConstraint(spherebody,
new CANNON.Vec3(0,0,N*dist),
0);
}
world.addConstraint(c);
lastBody = spherebody;
}
});
// Particle cloth
demo.addScene("Particle cloth",function(){
var world = setupWorld(demo);
world.solver.setSpookParams(1000,2);
world.solver.iterations = 50;
var dist = 0.2;
var mass = 0.5;
var Nrows = 10, Ncols = 15;
var bodies = {}; // bodies["i j"] => particle
for(var i=0; i<Ncols; i++){
for(var j=0; j<Nrows; j++){
// Create a new body
var body = new CANNON.Particle(j==Nrows-1 ? 0 : mass);
body.position.set(i*dist,0,j*dist+5);
body.velocity.set(0, 3*(Math.sin(i*0.1)+Math.sin(j*0.1)),0);
bodies[i+" "+j] = body;
world.add(body);
demo.addVisual(body);
}
}
function connect(i1,j1,i2,j2){
world.addConstraint(new CANNON.DistanceConstraint(bodies[i1+" "+j1],bodies[i2+" "+j2],dist));
}
for(var i=0; i<Ncols; i++){
for(var j=0; j<Nrows; j++){
if(i<Ncols-1) connect(i,j,i+1,j);
if(j<Nrows-1) connect(i,j,i,j+1);
}
}
});
// Particle 3d object
demo.addScene("3D cloth structure",function(){
var world = setupWorld(demo);
world.solver.setSpookParams(5000,2);
world.solver.iterations = 10;
var dist = 1;
var mass = 1;
var Nx = 6, Ny = 3, Nz = 3;
var bodies = {}; // bodies["i j k"] => particle
for(var i=0; i<Nx; i++){
for(var j=0; j<Ny; j++){
for(var k=0; k<Nz; k++){
// Create a new body
var body = new CANNON.Particle(mass);
body.position.set(i*dist,j*dist, k*dist + Nz*dist*0.3+1);
body.velocity.set(0, 30*(Math.sin(i*0.1)+Math.sin(j*0.1)),0);
bodies[i+" "+j+" "+k] = body;
world.add(body);
demo.addVisual(body);
}
}
}
function connect(i1,j1,k1,i2,j2,k2,len){
world.addConstraint(new CANNON.DistanceConstraint(bodies[i1+" "+j1+" "+k1],bodies[i2+" "+j2+" "+k2],len));
}
for(var i=0; i<Nx; i++){
for(var j=0; j<Ny; j++){
for(var k=0; k<Nz; k++){
// normal directions
if(i<Nx-1) connect(i,j,k, i+1,j,k, dist);
if(j<Ny-1) connect(i,j,k, i,j+1,k, dist);
if(k<Nz-1) connect(i,j,k, i,j,k+1, dist);
// Diagonals
if(i<Nx-1 && j<Ny-1 && k<Nz-1){
// 3d diagonals
connect(i,j,k, i+1,j+1,k+1, Math.sqrt(3)*dist);
connect(i+1,j,k, i,j+1,k+1, Math.sqrt(3)*dist);
connect(i,j+1,k, i+1,j,k+1, Math.sqrt(3)*dist);
connect(i,j,k+1, i+1,j+1,k, Math.sqrt(3)*dist);
}
// 2d diagonals
if(i<Nx-1 && j<Ny-1){
connect(i+1,j,k, i,j+1,k, Math.sqrt(2)*dist);
connect(i,j+1,k, i+1,j,k, Math.sqrt(2)*dist);
}
if(i<Nx-1 && k<Nz-1){
connect(i+1,j,k, i,j,k+1, Math.sqrt(2)*dist);
connect(i,j,k+1, i+1,j,k, Math.sqrt(2)*dist);
}
if(j<Ny-1 && k<Nz-1){
connect(i,j+1,k, i,j,k+1, Math.sqrt(2)*dist);
connect(i,j,k+1, i,j+1,k, Math.sqrt(2)*dist);
}
}
}
}
});
function setupWorld(demo){
// Create world
var world = demo.getWorld();
world.gravity.set(0,0,-40);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;
// ground plane
var groundShape = new CANNON.Plane();
var groundBody = new CANNON.RigidBody(0,groundShape);
groundBody.position.set(0,0,1);
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.