<!doctype html>
<html lang="en">
    <head>
        <title>three.js webgl - glTF</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                font-family: Monospace;
                background-color: #EEF;
                margin: 0px;
                overflow: hidden;
            }
            
            #info {
				color: #fff;
                position: absolute;
                top: 10px;
                width: 100%;
                text-align: center;
                z-index: 100;
                display:block;
            }
            
            #container {
            	position: absolute;
            	top: 0px;
            	width:100%;
            	height:100%;
            	z-index: -1;
            }
            
            #controls {
            	position:absolute;
            	width:250px;
            	bottom:0%;
            	right:0%;
            	height:100px;
            	background-color:White;
            	opacity:.9;
            	font: 13px/1.231 "Lucida Grande", Lucida, Verdana, sans-serif;
            }

            #status {
            	position:absolute;
            	width:25%;
            	left:2%;
            	top:95%;
            	height:5%;
            	opacity:.9;
            	font: 13px/1.231 "Lucida Grande", Lucida, Verdana, sans-serif;
            }
            
            .control {
            	position:absolute;
            	margin-left:12px;
            	width:100%;
            	font-weight:bold;
            }
                        
            .controlValue {
            	position:absolute;
            	left:36%;
            	top:0%;
            }
            
            #scenes_control {
            	position:absolute;
            	top:8px;
            }

            #cameras_control {
            	position:absolute;
            	top:40px;
            }

            #animations_control {
            	position:absolute;
            	top:72px;
            }

            #info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
        </style>
    </head>

    <body>
        <div id="info">
			<a href="http://threejs.org" target="_blank">three.js</a> - 
			<a href="http://gltf.gl/" target="_blank">glTF</a> loader - 
			<br></br>
			monster by <a href="http://www.3drt.com/downloads.htm" target="_blank">3drt</a> -
			COLLADA duck by Sony
        </div>
		<div id="container">
		</div>
		<div id="status">
		</div>
		<div id="controls">
			<div class="control" id="scenes_control">
				Model
				<select class="controlValue" id="scenes_list" size="1" onchange="selectScene();" ondblclick="selectScene();">
				</select>
			</div>
			
			<div class="control" id="cameras_control">
				Camera
				<select class="controlValue" id="cameras_list" size="1" onchange="selectCamera();" ondblclick="selectCamera();">
				</select>
			</div>
			<div class="control" id="animations_control">
				Animations
				<div class="controlValue"><input type="checkbox" checked onclick="toggleAnimations();">Play</input></div>
			</div>
		</div>
        <script src="../build/three.min.js"></script>
        <script src="js/controls/OrbitControls.js"></script>
        <script src="js/loaders/gltf/glTF-parser.js"></script>
        <script src="js/loaders/gltf/glTFLoader.js"></script>
        <script src="js/loaders/gltf/glTFLoaderUtils.js"></script>
        <script src="js/loaders/gltf/glTFAnimation.js"></script>

        <script>
        	var orbitControls = null;
            var container, camera, scene, renderer, loader;

            var cameraIndex = 0;
			var cameras = [];
			var cameraNames = [];
			var defaultCamera = null;
			var gltf = null;
			
			function onload() {

				window.addEventListener( 'resize', onWindowResize, false );
            	document.addEventListener( 'keypress', 
            			function(e) { onKeyPress(e); }, false );

                buildSceneList();
                switchScene(0);
                animate();

            }

            function initScene(index) {
                container = document.getElementById( 'container' );

                scene = new THREE.Scene();

                defaultCamera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 20000 );
                
                //defaultCamera.up = new THREE.Vector3( 0, 1, 0 );
                scene.add( defaultCamera );
                camera = defaultCamera;

                var sceneInfo = sceneList[index];

                var spot1 = null;
                if (sceneInfo.addLights) {
                    
                    var ambient = new THREE.AmbientLight( 0x888888 );
                    scene.add( ambient );

                	var directionalLight = new THREE.DirectionalLight( 0xdddddd );
                	directionalLight.position.set( 0, -1, 1 ).normalize();
                	scene.add( directionalLight );
                
	                spot1   = new THREE.SpotLight( 0xffffff, 1 );
	                spot1.position.set( -100, 200, 100 );
	                spot1.target.position.set( 0, 0, 0 );

	                if (sceneInfo.shadows) {
		                
		                spot1.shadowCameraNear      = 1;
		                spot1.shadowCameraFar      = 1024;
		                spot1.castShadow            = true;
		                spot1.shadowDarkness        = 0.3;
		                spot1.shadowBias = 0.0001;
		                spot1.shadowMapWidth = 2048;
		                spot1.shadowMapHeight = 2048;
	                }
	                scene.add( spot1 );
                }
				
                // RENDERER

                renderer = new THREE.WebGLRenderer({antialias:true});
				renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );

                if (sceneInfo.shadows) {
	                renderer.shadowMapEnabled = true;
	                renderer.shadowMapSoft = true;
	        		renderer.shadowMapType = THREE.PCFSoftShadowMap;
                }
                				
                container.appendChild( renderer.domElement );

                var ground = null;
				if (sceneInfo.addGround) {
	                var groundMaterial = new THREE.MeshPhongMaterial({
	                        color: 0xFFFFFF,
	                        shading: THREE.SmoothShading,
	                    });
	                ground = new THREE.Mesh( new THREE.PlaneBufferGeometry(1024, 1024), groundMaterial);

	                if (sceneInfo.shadows) {
		                ground.receiveShadow = true;
	                }

	                if (sceneInfo.groundPos) {
		                ground.position.copy(sceneInfo.groundPos);
	                }
	                else {
		                ground.position.z = -70;
	                }
	                ground.rotation.x = -Math.PI / 2;
	                
	                scene.add(ground);
				}
				
                loader = new THREE.glTFLoader;

                var loadStartTime = Date.now();
                var status = document.getElementById("status");
                status.innerHTML = "Loading...";
                loader.load( sceneInfo.url, function(data) {

                	gltf = data;
                	
                	var object = gltf.scene;
                	
                    var loadEndTime = Date.now();

                    var loadTime = (loadEndTime - loadStartTime) / 1000;

                    status.innerHTML = "Load time: " + loadTime.toFixed(2) + " seconds.";
                    
                	if (sceneInfo.cameraPos)
                        defaultCamera.position.copy(sceneInfo.cameraPos);

                	if (sceneInfo.center) {
                        orbitControls.center.copy(sceneInfo.center);
                	}
                    
                    if (sceneInfo.objectPosition) {
                        object.position.copy(sceneInfo.objectPosition);

                        if (spot1) {
	    	                spot1.position.set(sceneInfo.objectPosition.x - 100, sceneInfo.objectPosition.y + 200, sceneInfo.objectPosition.z - 100 );
    	                	spot1.target.position.copy(sceneInfo.objectPosition);
                        }
                    }
                    
                    if (sceneInfo.objectRotation)
                        object.rotation.copy(sceneInfo.objectRotation);

                    if (sceneInfo.objectScale)
                        object.scale.copy(sceneInfo.objectScale);

                    cameraIndex = 0;
                    cameras = [];
                    cameraNames = [];
                    if (gltf.cameras && gltf.cameras.length)
                    {
                        var i, len = gltf.cameras.length;
                        for (i = 0; i < len; i++)
                        {
                            var addCamera = true;
                            var cameraName = gltf.cameras[i].parent.name;
                            if (sceneInfo.cameras && !(cameraName in sceneInfo.cameras)) {
                                    addCamera = false;
                            }

                            if (addCamera) {
                            	cameraNames.push(cameraName);
                            	cameras.push(gltf.cameras[i]);
                            }
                        }

                        updateCamerasList();
                        switchCamera(1);
                    }
                    else
                    {
                        updateCamerasList();
                        switchCamera(0);
                    }

    				if (gltf.animations && gltf.animations.length) {
    					var i, len = gltf.animations.length;
	    				for (i = 0; i < len; i++) {
	    					var animation = gltf.animations[i];
	    					animation.loop = true;
	    					// There's .3333 seconds junk at the tail of the Monster animation that
	    					// keeps it from looping cleanly. Clip it at 3 seconds
	    					if (sceneInfo.animationTime)
		    					animation.duration = sceneInfo.animationTime;
    						animation.play();
	    				}
    				}
                                       
                    scene.add( object );
                    onWindowResize();

                });

        		orbitControls = new THREE.OrbitControls(defaultCamera, renderer.domElement);
            }

			function onWindowResize() {

				defaultCamera.aspect = container.offsetWidth / container.offsetHeight;
				defaultCamera.updateProjectionMatrix();
				
				var i, len = cameras.length;
				for (i = 0; i < len; i++) // just do it for default
				{
					cameras[i].aspect = container.offsetWidth / container.offsetHeight;
					cameras[i].updateProjectionMatrix();
				}
				
				renderer.setSize( window.innerWidth, window.innerHeight );

			}

            function animate() {
                requestAnimationFrame( animate );
                THREE.glTFAnimator.update();
                if (cameraIndex == 0)
                    orbitControls.update();
                render();
            }

            function render() {

                renderer.render( scene, camera );
            }

            
			
			function onKeyPress(event) {
				var chr = String.fromCharCode(event.keyCode);
				if (chr == ' ')
				{
					index = cameraIndex + 1;
					if (index > cameras.length)
						index = 0;
					switchCamera(index);
				}
				else {
					var index = parseInt(chr);
					if (!isNaN(index)  && (index <= cameras.length)) {
						switchCamera(index);
					}
				}
			}

			var sceneList = 
				[
		             { name : "Monster", url : "./models/gltf/monster/monster.json", 
			                 cameraPos: new THREE.Vector3(30, 10, 70), 
			                 objectScale: new THREE.Vector3(0.01, 0.01, 0.01),
			                 objectPosition: new THREE.Vector3(0, 1, 0),
			                 objectRotation: new THREE.Euler(-Math.PI / 2, 0, -Math.PI / 2),
			                 animationTime: 3,
			                 addLights:true,
			                 shadows:true,
			                 addGround:true },
	                 { name : "Duck", url : "./models/gltf/duck/duck.json", 
		                 cameraPos: new THREE.Vector3(0, 30, -50),
		                 objectScale: new THREE.Vector3(0.1, 0.1, 0.1),
		                 addLights:true,
		                 addGround:true,
		                 shadows:true },
     			];

			function buildSceneList()
			{
				var elt = document.getElementById('scenes_list');
				while( elt.hasChildNodes() ){
				    elt.removeChild(elt.lastChild);
				}

				var i, len = sceneList.length;
				for (i = 0; i < len; i++)
				{
					option = document.createElement("option");
					option.text=sceneList[i].name;
					elt.add(option);
				}		
			}
			
			function switchScene(index)
			{
				cleanup();
				initScene(index);
				var elt = document.getElementById('scenes_list');
				elt.selectedIndex = index;
			}

			function selectScene()
			{
			    var select = document.getElementById("scenes_list");
			    var index = select.selectedIndex;
				if (index >= 0)
				{
					switchScene(index);
				}
			}
			
			function switchCamera(index)
			{
				cameraIndex = index;
				
				if (cameraIndex == 0) {
					camera = defaultCamera;
				}
				if (cameraIndex >= 1 && cameraIndex <= cameras.length) {
					camera = cameras[cameraIndex - 1];
				}

				var elt = document.getElementById('cameras_list');
				elt.selectedIndex = cameraIndex;				
			}
					
			function updateCamerasList() {
				var elt = document.getElementById('cameras_list');
				while( elt.hasChildNodes() ){
				    elt.removeChild(elt.lastChild);
				}

				option = document.createElement("option");
				option.text="[default]";
				elt.add(option);
				
				var i, len = cameraNames.length;
				for (i = 0; i < len; i++)
				{
					option = document.createElement("option");
					option.text=cameraNames[i];
					elt.add(option);
				}		
			}
			
			function selectCamera() {
			    var select = document.getElementById("cameras_list");
			    var index = select.selectedIndex;
				if (index >= 0)
				{
					switchCamera(index);
				}
			}

			function toggleAnimations() {
				var i, len = gltf.animations.length;
				for (i = 0; i < len; i++) {
					var animation = gltf.animations[i];
					if (animation.running) {
						animation.stop();
					}
					else {
						animation.play();
					}
				}
			}

			function cleanup() {

				if (container && renderer)
				{
					container.removeChild(renderer.domElement);
				}

				cameraIndex = 0;
				cameras = [];
				cameraNames = [];
				defaultCamera = null;
				
				if (!loader || !gltf.animations)
					return;
				
				var i, len = gltf.animations.length;
				for (i = 0; i < len; i++) {
					var animation = gltf.animations[i];
					if (animation.running) {
						animation.stop();
					}
				}
			}
			
            onload();
        </script>

    </body>
</html>