Code viewer for World: Ammo physics modified

// 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 );

        // floor
        
            var 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 );
	}