cannon
Version:
A lightweight 3D physics engine written in JavaScript.
127 lines (109 loc) • 4.55 kB
HTML
<html>
<head>
<title>cannon.js - sph 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>
var demo = new CANNON.Demo();
var nx=4, ny=4, nz=15, w=10, h=5, mass=0.01;
var walls = true;
// Test scalability - add scenes for different number of particles
demo.addScene((nx*ny*nz)+ " particles", function(){
// Create world
var world = demo.getWorld();
var sph = new CANNON.SPHSystem();
sph.density = 1;
sph.viscosity = 0.03;
sph.smoothingRadius = 1.0;
world.subsystems.push(sph);
// Tweak contact properties.
world.defaultContactMaterial.contactEquationStiffness = 1e11; // Contact stiffness - use to make softer/harder contacts
world.defaultContactMaterial.contactEquationRelaxation = 2; // Stabilization time in number of timesteps
// Max solver iterations: Use more for better force propagation, but keep in mind that it's not very computationally cheap!
world.solver.iterations = 10;
world.gravity.set(0,0,-10);
// Materials
var material = new CANNON.Material();
var material_material = new CANNON.ContactMaterial(material, material, {
friction: 0.06,
restitution: 0.0
});
world.addContactMaterial(material_material);
// ground plane
var groundShape = new CANNON.Plane();
var groundBody = new CANNON.Body({
mass: 0,
material: material
});
groundBody.addShape(groundShape);
world.add(groundBody);
demo.addVisual(groundBody);
if(walls){
// plane -x
var planeShapeXmin = new CANNON.Plane();
var planeXmin = new CANNON.Body({
mass: 0,
material: material
});
planeXmin.addShape(planeShapeXmin);
planeXmin.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0),Math.PI/2);
planeXmin.position.set(-w*0.5,0,0);
world.add(planeXmin);
// Plane +x
var planeShapeXmax = new CANNON.Plane();
var planeXmax = new CANNON.Body({ mass: 0, material: material });
planeXmax.addShape(planeShapeXmax);
planeXmax.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0),-Math.PI/2);
planeXmax.position.set(w*0.5,0,0);
world.add(planeXmax);
// Plane -y
var planeShapeYmin = new CANNON.Plane();
var planeYmin = new CANNON.Body({ mass: 0, material: material });
planeYmin.addShape(planeShapeYmin);
planeYmin.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0),-Math.PI/2);
planeYmin.position.set(0,-h*0.5,0);
world.add(planeYmin);
// Plane +y
var planeShapeYmax = new CANNON.Plane();
var planeYmax = new CANNON.Body({ mass: 0, material: material });
planeYmax.addShape(planeShapeYmax);
planeYmax.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0), Math.PI/2);
planeYmax.position.set(0,h*0.5,0);
world.add(planeYmax);
}
// Create particles
var rand = 0.1;
for(var i=0; i!==nx; i++){
for(var j=0; j!==ny; j++){
for(var k=0; k!==nz; k++){
var particle = new CANNON.Body({
mass: mass,
material: material
});
particle.addShape(new CANNON.Particle());
particle.position.set((i + (Math.random()-0.5)*rand + 0.5)*w/nx - w*0.5,
(j + (Math.random()-0.5)*rand + 0.5)*h/ny - h*0.5,
k*h/ny);
world.add(particle);
sph.add(particle);
demo.addVisual(particle);
}
}
}
});
demo.start();
</script>
</body>
</html>