Code viewer for World: Port of flying birds
// Port of flying birds from discoverthreejs.com
// "Final code from Ch 1.7 of Discover three.js" 
// https://codesandbox.io/s/github/looeee/discoverthree.com-examples/tree/master/1-first-steps/7-load-models?from-embed
 
 
const startRadius       = 150;                  // distance from centre we start the camera at
const maxRadius         = startRadius * 20;     // maximum distance from camera we render things 

// can load skybox of other user:
 const SKYBOX_ARRAY = [										 
                "/uploads/starter/dawnmountain-xpos.png",
                "/uploads/starter/dawnmountain-xneg.png",
                "/uploads/starter/dawnmountain-ypos.png",
                "/uploads/starter/dawnmountain-yneg.png",
                "/uploads/starter/dawnmountain-zpos.png",
                "/uploads/starter/dawnmountain-zneg.png"
                ];


const mixers = [];
const clock = new THREE.Clock();

// AB customisations
// Select text and "Code Help" to see what these mean:

ABHandler.MAXCAMERAPOS      = maxRadius;
ABWorld.drawCameraControls  = false;  
AB.drawRunControls          = false;    



	
	AB.world.newRun = function()
	{
	    //      ABWorld.renderer = new THREE.WebGLRenderer ( { antialias: true } );     
	    // custom renderer args - uncomment if need this - otherwise init3d makes the renderer 
	    
        var color    = new THREE.Color ();                          // renderer color is not used - there is a skybox
	    ABWorld.init3d ( startRadius, maxRadius, color );            
	    
	    initLights();    
	    loadModels(); 
	    
	    // skybox: 
        ABWorld.scene.background = new THREE.CubeTextureLoader().load ( SKYBOX_ARRAY );
	};



	AB.world.nextStep = function()		 
	{
	    const delta = clock.getDelta();
        mixers.forEach( ( mixer ) => { mixer.update( delta ); } );
	};




function loadModels() 
{
  const loader = new THREE.GLTFLoader();

  const onLoad = ( gltf, position ) => 
  {
    const model = gltf.scene.children[ 0 ];
    model.position.copy( position );

    const animation = gltf.animations[ 0 ];

    const mixer = new THREE.AnimationMixer( model );
    mixers.push( mixer );

    const action = mixer.clipAction( animation );
    action.play();

    ABWorld.scene.add( model );
  };

  const parrotPosition      = new THREE.Vector3 ( 0,     0,   50 );
  const flamingoPosition    = new THREE.Vector3 ( 150,   0, -200 );
  const storkPosition       = new THREE.Vector3 ( 0,   -50, -200 );

 // can load 3D models of other user:
  loader.load ( '/uploads/humphrys/Parrot.glb',   gltf => onLoad ( gltf, parrotPosition )   );
  loader.load ( '/uploads/humphrys/Flamingo.glb', gltf => onLoad ( gltf, flamingoPosition ) );
  loader.load ( '/uploads/humphrys/Stork.glb',    gltf => onLoad ( gltf, storkPosition )    );
  
}



function initLights() 
// the lights are needed to show up models
{
  const ambientLight = new THREE.AmbientLight( 0xffffff, 1 );
  ABWorld.scene.add( ambientLight );

  const frontLight = new THREE.DirectionalLight( 0xffffff, 1 );
  frontLight.position.set( 10, 10, 10 );

  const backLight = new THREE.DirectionalLight( 0xffffff, 1 );
  backLight.position.set( -10, 10, -10 );

  ABWorld.scene.add( frontLight, backLight );
}



// background music 
// can load music of other user:

 const MUSICFILE = '/uploads/test/StarCommander1.wav';
 AB.backgroundMusic ( MUSICFILE );