<!DOCTYPE html>

<head>
  <script src="https://cdn.jsdelivr.net/npm/three@v0.104.0"></script>
  <script src="GLTFLoader.js"></script>
  <script src="BasisTextureLoader.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/three@v0.104.0/examples/js/controls/OrbitControls.js"></script>
  <script src="../transcoder/build/basis_transcoder.js"></script>
  <style>
    html, body { width:100%; height:100%; margin:0; padding:0; }
    canvas { display:block; }
    #panel { position: absolute; top: 10px; left: 10px; color: white; background-color:rgba(0.3, 0.3, 0.3, 0.3); padding: 0.5em; max-width: 400px;}
  </style>
</head>

<body>
  <script>
    Module.onRuntimeInitialized = () => {

      const { BasisFile, initializeBasis } = Module;

      window.BasisFile = BasisFile;

      initializeBasis();

      // Initialize three.js scene and renderer.

      const renderer = new THREE.WebGLRenderer( { antialias: true } );
      renderer.setSize( window.innerWidth, window.innerHeight );
      renderer.gammaOutput = true;
      renderer.gammaFactor = 2.2;

      const scene = new THREE.Scene();
      scene.background = new THREE.Color( 0xf0f0f0 );

      const light = new THREE.AmbientLight();
      scene.add( light );

      const light2 = new THREE.PointLight();
      scene.add( light2 );

      const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 100 );
      camera.position.set( 8, 6, 5 );
      camera.lookAt( new THREE.Vector3( 0, -2, 0 ) );

      const controls = new THREE.OrbitControls( camera, renderer.domElement );
      controls.autoRotate = true;

      // Create BasisTextureLoader and detect supported target formats.

      const basisLoader = new THREE.BasisTextureLoader();
      basisLoader.detectSupport( renderer );

      const formatName = basisLoader.etcSupported
        ? 'ETC1'
        : ( basisLoader.dxtSupported ? 'BC1' : 'PVRTC' );
      log(`Transcode to: <strong>${formatName}</strong>`);

      // Register BasisTextureLoader for .basis extension.

      THREE.Loader.Handlers.add( /\.basis$/, basisLoader );

      // Create GLTFLoader, load model, and render.

      const loader = new THREE.GLTFLoader();

      loader.load( 'assets/AgiHqSmall.gltf', ( gltf ) => {

        const model = gltf.scene;
        model.scale.set( 0.01, 0.01, 0.01 );

        scene.add( model );

        document.body.appendChild( renderer.domElement );

        animate();

      }, undefined, ( e ) => console.error( e ) );

      // Main render loop.

      function animate() {

        requestAnimationFrame( animate );
        controls.update();
        renderer.render( scene, camera );

      }

      // Support viewport resizing.

      window.addEventListener( 'resize', () => {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );

      }, false );

    }

    function log(s) {

      const div = document.createElement('div');
      div.innerHTML = s;
      document.getElementById('log').appendChild(div);

    }
  </script>
  <div id="panel">
    <strong>Basis Texture Transcoder glTF Demo</strong>
    <div id="log"></div>

  </div>
</body>

</html>