// Three.js physics World using ammo.js // Highly modified port of "ammo / instancing" from Three.js examples// https://threejs.org/examples/?q=ammo#physics_ammo_instancing
AB.backgroundMusic ('/uploads/starter/Interstellar.mp3');const UNIT =2;// unit of distance const BOXSIZE = UNIT *0.1;const FLOORSIZE = UNIT *5;const LIGHTPOS = UNIT *5;const NOBOXES =100;// initial number of boxes - we then make more const BOXTIMEOUT =200;// create new box every n milliseconds // random start positions for falling objects// x and z near origin, height y is argument: function randomPos ( y ){return(new THREE.Vector3( AB.randomFloatAtoB (-0.5*UNIT,0.5*UNIT ), y, AB.randomFloatAtoB (-0.5*UNIT,0.5*UNIT )));}// y is high or low:function randomHighPos(){return( randomPos ( AB.randomFloatAtoB (1.5*UNIT,2*UNIT )));}function randomLowPos(){return( randomPos ( AB.randomFloatAtoB (0*UNIT,2*UNIT )));}function randomColor(){return( AB.randomPick ('firebrick','teal'));}
let camera, scene, renderer;
let physics, boxes;
init();
async function init(){
physics = await AmmoPhysics();
camera =new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight,1,1000*UNIT );
camera.position.set(-UNIT, UNIT*1.5, UNIT*2);
camera.lookAt (0,0.5*UNIT,0);
scene =new THREE.Scene();
scene.background =new THREE.Color('lightblue');const dirLight =new THREE.DirectionalLight();
dirLight.position.set( LIGHTPOS, LIGHTPOS, LIGHTPOS );
scene.add( dirLight );// floorvar floorGeometry =new THREE.BoxGeometry( FLOORSIZE, FLOORSIZE, FLOORSIZE );var floorMaterial =new THREE.MeshBasicMaterial({ color:'palegoldenrod'});var floor =new THREE.Mesh( floorGeometry, floorMaterial );
floor.position.y =-2.5* UNIT;
scene.add( floor );
physics.addMesh ( floor,0);// see function addMesh in AmmoPhysics.js // addMesh ( mesh, mass = 0 )// floor has no mass - will not fall - will stay in place // boxes var boxGeometry =new THREE.BoxGeometry( BOXSIZE, BOXSIZE, BOXSIZE );var boxMaterial =new THREE.MeshLambertMaterial();
boxes =new THREE.InstancedMesh( boxGeometry, boxMaterial, NOBOXES );
scene.add( boxes );var matrix =new THREE.Matrix4();for( let i =0; i < boxes.count; i++){
matrix.setPosition ( randomLowPos());
boxes.setMatrixAt ( i, matrix );var color =new THREE.Color( randomColor());
boxes.setColorAt ( i, color );}
physics.addMesh ( boxes,1);// added with mass, so they fall // init Three.js
renderer =new THREE.WebGLRenderer({ antialias:true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.outputEncoding = THREE.sRGBEncoding;
document.body.appendChild( renderer.domElement );
createBox();
animate();}function createBox(){var boxGeometry =new THREE.BoxGeometry( BOXSIZE, BOXSIZE, BOXSIZE );var boxMaterial =new THREE.MeshLambertMaterial({ color: randomColor()});var box =new THREE.Mesh( boxGeometry, boxMaterial );
box.position.copy ( randomHighPos());// use copy to set position from a vector
scene.add( box );
physics.addMesh ( box,1);// has mass, so it falls
setTimeout ( createBox, BOXTIMEOUT );// make new box is on a different timer to animate()}function animate(){
requestAnimationFrame( animate );// original code would make a "new" box as follows:// pick one box at random and suddenly move its position to up in the air to make the "new" box// strange effect - boxes vanishing at random // var i = AB.randomIntAtoB ( 0, boxes.count -1 ); // random 0 to (boxes.count - 1)// physics.setMeshPosition ( boxes, randomPos(), i ); // see function setMeshPosition in AmmoPhysics.js
renderer.render( scene, camera );}