Browse Source

Support drag-and-drop for EXR files

WestLangley 5 years ago
parent
commit
8fb08bae8d
1 changed files with 86 additions and 35 deletions
  1. 86 35
      examples/webgl_materials_matcap.html

+ 86 - 35
examples/webgl_materials_matcap.html

@@ -10,7 +10,7 @@
 	<body>
 		<div id="info">
 			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl materials matcap<br />
-			Drag-and-drop alternate MatCap image files<br/>
+			Drag-and-drop JPG, PNG, or EXR MatCap image files<br/>
 		</div>
 
 		<script type="module">
@@ -20,6 +20,7 @@
 			import { GUI } from './jsm/libs/dat.gui.module.js';
 			import { OrbitControls } from './jsm/controls/OrbitControls.js';
 			import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
+			import { EXRLoader } from './jsm/loaders/EXRLoader.js';
 
 			var mesh, renderer, scene, camera;
 
@@ -51,12 +52,13 @@
 
 				// camera
 				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 );
-				camera.position.set( 0, 0, 12 );
+				camera.position.set( 0, 0, 13 );
 
 				// controls
 				var controls = new OrbitControls( camera, renderer.domElement );
 				controls.addEventListener( 'change', render );
 				controls.enableZoom = false;
+				controls.enablePan = false;
 
 				// manager
 				var manager = new THREE.LoadingManager( render );
@@ -109,21 +111,6 @@
 				// drag 'n drop
 				initDragAndDrop();
 
-				// corner div
-				var div = document.createElement( 'div' );
-				div.style.position = 'absolute';
-				div.style.top = '10px';
-				div.style.left = '10px';
-				document.body.appendChild( div );
-
-				image = document.createElement( 'img' );
-				image.style.width = '128px';
-				image.style.height = '128px';
-				image.style.display = 'block';
-				image.style.margin = '0 0 10px 0';
-				image.src = 'textures/matcaps/matcap-porcelain-white.jpg';
-				div.appendChild( image );
-
 				window.addEventListener( 'resize', onWindowResize, false );
 
 			}
@@ -146,10 +133,10 @@
 			}
 
 			//
-
 			// drag and drop anywhere in document
+			//
 
-			function imgCallback( event ) {
+			function updateMatcap( texture ) {
 
 				if ( mesh.material.matcap ) {
 
@@ -157,44 +144,108 @@
 
 				}
 
-				mesh.material.matcap = new THREE.Texture( event.target );
-				mesh.material.matcap.needsUpdate = true;
+				mesh.material.matcap = texture;
 
-				mesh.material.matcap.encoding = THREE.sRGBEncoding; // assume it is sRGB
-				mesh.material.needsUpdate = true;
+				texture.needsUpdate = true;
 
-				image.src = mesh.material.matcap.image.src; // corner div
+				mesh.material.needsUpdate = true; // because the encoding can change
 
 				render();
 
 			}
 
-			function initDragAndDrop() {
+			function handleJPG( event ) { // PNG, too
 
-				document.addEventListener( 'dragover', function ( event ) {
+				function imgCallback( event ) {
 
-					event.preventDefault();
-					event.dataTransfer.dropEffect = 'copy';
+					var texture = new THREE.Texture( event.target );
 
-				}, false );
+					texture.encoding = THREE.sRGBEncoding;
 
-				document.addEventListener( 'drop', function ( event ) {
+					updateMatcap( texture );
 
-					event.preventDefault();
+				}
+
+				var img = new Image();
+
+				img.onload = imgCallback;
+
+				img.src = event.target.result;
+
+			}
+
+			function handleEXR( event ) {
+
+				var contents = event.target.result;
+
+				var loader = new EXRLoader();
+
+				var texData = loader.parse( contents );
+
+				var texture = new THREE.DataTexture();
+
+				texture.image.width = texData.width;
+				texture.image.height = texData.height;
+				texture.image.data = texData.data;
+
+				texture.format = texData.format;
+				texture.type = texData.type;
+
+				texture.generateMipmaps = false;
+				texture.magFilter = THREE.LinearFilter;
+				texture.minFilter = THREE.LinearFilter;
+
+				updateMatcap( texture );
+
+			}
+
+			function loadFile( file ) {
+
+				var filename = file.name;
+				var extension = filename.split( '.' ).pop().toLowerCase();
+
+				if ( extension === 'exr' ) {
 
 					var reader = new FileReader();
 
 					reader.addEventListener( 'load', function ( event ) {
 
-						var img = new Image();
+						handleEXR( event );
+
+					}, false );
+
+					reader.readAsArrayBuffer( file );
+
+				} else { // 'jpg', 'png'
+
+					var reader = new FileReader();
 
-						img.onload = imgCallback;
+					reader.addEventListener( 'load', function ( event ) {
 
-						img.src = event.currentTarget.result;
+						handleJPG( event );
 
 					}, false );
 
-					reader.readAsDataURL( event.dataTransfer.files[ 0 ] );
+					reader.readAsDataURL( file );
+
+				}
+
+			}
+
+			function initDragAndDrop() {
+
+				document.addEventListener( 'dragover', function ( event ) {
+
+					event.preventDefault();
+					event.dataTransfer.dropEffect = 'copy';
+
+				}, false );
+
+				document.addEventListener( 'drop', function ( event ) {
+
+					event.preventDefault();
+
+					loadFile( event.dataTransfer.files[ 0 ] );
 
 				}, false );