Browse Source

AMFLoader: mrdoobapproved.

Mr.doob 9 years ago
parent
commit
af0b43468a
1 changed files with 256 additions and 120 deletions
  1. 256 120
      examples/js/loaders/AMFLoader.js

+ 256 - 120
examples/js/loaders/AMFLoader.js

@@ -19,56 +19,77 @@
  *
  */
 
-THREE.AMFLoader = function( manager ) {
-	this.manager = (manager !== undefined) ? manager : THREE.DefaultLoadingManager;
+THREE.AMFLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
 };
 
 THREE.AMFLoader.prototype = {
 
 	constructor: THREE.AMFLoader,
 
-	load: function(url, onLoad, onProgress, onError) {
+	load: function ( url, onLoad, onProgress, onError ) {
+
 		var scope = this;
 
-		var loader = new THREE.XHRLoader(scope.manager);
-		loader.setCrossOrigin(this.crossOrigin);
-		loader.setResponseType('arraybuffer');
+		var loader = new THREE.XHRLoader( scope.manager );
+		loader.setCrossOrigin( this.crossOrigin );
+		loader.setResponseType( 'arraybuffer' );
+
+		loader.load( url, function( text ) {
+
+			var amfObject = scope.parse( text );
+			onLoad( amfObject );
+
+		}, onProgress, onError );
 
-		loader.load(url, function(text) {
-			var amfObject = scope.parse(text);
-			onLoad(amfObject);
-		}, onProgress, onError);
 	},
 
-	parse: function(data) {
+	parse: function ( data ) {
+
 		var amfName = "";
 		var amfAuthor = "";
 		var amfScale = 1.0;
 		var amfMaterials = {};
 		var amfObjects = {};
 
-		var xmldata = this._loadDocument(data);
+		var xmldata = this._loadDocument( data );
 
-		amfScale = this._loadDocumentScale(xmldata);
+		amfScale = this._loadDocumentScale( xmldata );
 
 		var documentchildren = xmldata.documentElement.children;
 
-		for(var i = 0; i < documentchildren.length; i++) {
-			if(documentchildren[i].nodeName === 'metadata') {
-				if(documentchildren[i].attributes['type'] !== undefined) {
-					if(documentchildren[i].attributes['type'].value === 'name') {
-						amfName = documentchildren[i].textContent;
-					} else if(documentchildren[i].attributes['type'].value === 'author') {
-						amfAuthor = documentchildren[i].textContent;
+		for ( var i = 0; i < documentchildren.length; i ++ ) {
+
+			if ( documentchildren[ i ].nodeName === 'metadata' ) {
+
+				if ( documentchildren[ i ].attributes[ 'type' ] !== undefined ) {
+
+					if ( documentchildren[ i ].attributes[ 'type' ].value === 'name' ) {
+
+						amfName = documentchildren[ i ].textContent;
+
+					} else if ( documentchildren[ i ].attributes[ 'type' ].value === 'author' ) {
+
+						amfAuthor = documentchildren[ i ].textContent;
+
 					}
+
 				}
-			} else if(documentchildren[i].nodeName === 'material') {
-				var loadedmaterial = this._loadMaterials(documentchildren[i]);
-				amfMaterials[loadedmaterial.id] = loadedmaterial.material;
-			} else if(documentchildren[i].nodeName === 'object') {
-				var loadedobject = this._loadObject(documentchildren[i]);
-				amfObjects[loadedobject.id] = loadedobject.obj;
+
+			} else if ( documentchildren[ i ].nodeName === 'material' ) {
+
+				var loadedmaterial = this._loadMaterials( documentchildren[ i ] );
+				amfMaterials[ loadedmaterial.id ] = loadedmaterial.material;
+
+			} else if ( documentchildren[ i ].nodeName === 'object' ) {
+
+				var loadedobject = this._loadObject( documentchildren[ i ] );
+				amfObjects[ loadedobject.id ] = loadedobject.obj;
+
 			}
+
 		}
 
 		var sceneobject = new THREE.Object3D();
@@ -77,108 +98,142 @@ THREE.AMFLoader.prototype = {
 		sceneobject.userData.author = amfAuthor;
 		sceneobject.userData.loader = "AMF";
 
-		var defaultmaterial = new THREE.MeshPhongMaterial({shading: THREE.FlatShading, color: 0xaaaaff});
+		var defaultmaterial = new THREE.MeshPhongMaterial( { shading: THREE.FlatShading, color: 0xaaaaff } );
+
+		for ( var objid in amfObjects ) {
 
-		for(var objid in amfObjects) {
 			var newobject = new THREE.Object3D();
 
-			for(var meshi = 0; meshi < amfObjects[objid].meshes.length; meshi++) {
-				var meshvertices = Float32Array.from(amfObjects[objid].meshes[meshi].vertices);
-				var vertices = new THREE.BufferAttribute(Float32Array.from(meshvertices), 3);
+			for ( var meshi = 0; meshi < amfObjects[ objid ].meshes.length; meshi ++ ) {
+
+				var meshvertices = Float32Array.from( amfObjects[ objid ].meshes[ meshi ].vertices );
+				var vertices = new THREE.BufferAttribute( Float32Array.from( meshvertices ), 3 );
 				var objdefaultmaterial = defaultmaterial;
 
-				if(amfObjects[objid].meshes[meshi].color) {
-					var color = amfObjects[objid].meshes[meshi].color;
+				if ( amfObjects[ objid ].meshes[ meshi ].color ) {
+
+					var color = amfObjects[ objid ].meshes[ meshi ].color;
 					objdefaultmaterial = defaultmaterial.clone();
-					objdefaultmaterial.color = new THREE.Color(color.r, color.g, color.b);
+					objdefaultmaterial.color = new THREE.Color( color.r, color.g, color.b );
+
+					if ( color.a != 1.0 ) {
 
-					if(color.a != 1.0) {
 						objdefaultmaterial.transparent = true;
 						objdefaultmaterial.opacity = color.a;
+
 					}
+
 				}
 
-				for(var voli = 0; voli < amfObjects[objid].meshes[meshi].volumes.length; voli++) {
-					var currvolume = amfObjects[objid].meshes[meshi].volumes[voli];
+				for ( var voli = 0; voli < amfObjects[ objid ].meshes[ meshi ].volumes.length; voli ++ ) {
+
+					var currvolume = amfObjects[ objid ].meshes[ meshi ].volumes[ voli ];
 					var newgeometry = new THREE.BufferGeometry();
-					var indexes = Uint32Array.from(currvolume.triangles);
-					var normals = new Uint32Array(vertices.length);
+					var indexes = Uint32Array.from( currvolume.triangles );
+					var normals = new Uint32Array( vertices.array.length );
 
 					var material = objdefaultmaterial;
 
-					newgeometry.addAttribute('position', vertices.clone() );
-					newgeometry.setIndex( new THREE.BufferAttribute(indexes, 1) );
+					newgeometry.setIndex( new THREE.BufferAttribute( indexes, 1 ) );
+					newgeometry.addAttribute( 'position', vertices.clone() );
+
+					if ( amfMaterials[ currvolume.materialid ] !== undefined ) {
+
+						material = amfMaterials[ currvolume.materialid ];
 
-					if(amfMaterials[currvolume.materialid] !== undefined) {
-						material = amfMaterials[currvolume.materialid];
 					}
 
-					newgeometry.scale(amfScale, amfScale, amfScale);
+					newgeometry.scale( amfScale, amfScale, amfScale );
 
-					var newmesh = new THREE.Mesh(newgeometry, material.clone());
+					var newmesh = new THREE.Mesh( newgeometry, material.clone() );
+
+					newobject.add( newmesh );
 
-					newobject.add(newmesh);
 				}
+
 			}
-			sceneobject.add(newobject);
+			sceneobject.add( newobject );
+
 		}
 
 		return sceneobject;
+
 	},
 
 	_loadDocument: function ( data ) {
-		var view = new DataView(data);
 
-		var magic = String.fromCharCode(view.getUint8(0), view.getUint8(1));
+		var view = new DataView( data );
 
-		if(magic === "PK") {
-			console.log("Loading Zip");
+		var magic = String.fromCharCode( view.getUint8( 0 ), view.getUint8( 1 ) );
+
+		if ( magic === "PK" ) {
+
+			console.log( "Loading Zip" );
 			var zip = null;
 			var file = null;
 
 			try {
-				zip = new JSZip(data);
-			} catch (e) {
-				if (e instanceof ReferenceError) {
-					console.log("	jszip missing and file is compressed.");
+
+				zip = new JSZip( data );
+
+			} catch ( e ) {
+
+				if ( e instanceof ReferenceError ) {
+
+					console.log( "	jszip missing and file is compressed." );
 					return null;
+
 				}
+
 			}
 
-			for(file in zip.files) {
-				if(file.toLowerCase().endsWith(".amf")) {
+			for ( file in zip.files ) {
+
+				if ( file.toLowerCase().endsWith( ".amf" ) ) {
+
 					break;
+
 				}
+
 			}
 
-			console.log("	Trying to load file asset: " + file);
-			view = new DataView(zip.file(file).asArrayBuffer());
+			console.log( "	Trying to load file asset: " + file );
+			view = new DataView( zip.file( file ).asArrayBuffer() );
+
 		}
 
-		if(TextDecoder === undefined) {
-			console.log("	TextDecoder not present.	Please use TextDecoder polyfill.");
+		if ( TextDecoder === undefined ) {
+
+			console.log( "	TextDecoder not present.	Please use TextDecoder polyfill." );
 			return null;
+
 		}
 
-		var filetext = new TextDecoder('utf-8').decode(view);
+		var filetext = new TextDecoder( 'utf-8' ).decode( view );
 
-		var xmldata = new DOMParser().parseFromString(filetext, 'application/xml');
+		var xmldata = new DOMParser().parseFromString( filetext, 'application/xml' );
 
-		if(xmldata.documentElement.nodeName.toLowerCase() !== "amf") {
-			console.log("	Error loading AMF - no AMF document found.");
+		if ( xmldata.documentElement.nodeName.toLowerCase() !== "amf" ) {
+
+			console.log( "	Error loading AMF - no AMF document found." );
 			return null;
+
 		}
 
 		return xmldata;
+
 	},
 
 	_loadDocumentScale: function ( xmldata ) {
+
 		var scale = 1.0;
 
 		var unit = 'millimeter';
 
-		if( xmldata.documentElement.attributes['unit'] !== undefined ) {
-			unit = xmldata.documentElement.attributes['unit'].value.toLowerCase();
+		if ( xmldata.documentElement.attributes[ 'unit' ] !== undefined ) {
+
+			unit = xmldata.documentElement.attributes[ 'unit' ].value.toLowerCase();
+
 		}
 
 		var scale_units = {
@@ -189,171 +244,252 @@ THREE.AMFLoader.prototype = {
 			'micron': 0.001
 		};
 
-		if(scale_units[unit] !== undefined) {
-			scale = scale_units[unit];
+		if ( scale_units[ unit ] !== undefined ) {
+
+			scale = scale_units[ unit ];
+
 		}
 
-		console.log("	Unit scale: " + scale);
+		console.log( "	Unit scale: " + scale );
 		return scale;
+
 	},
 
 	_loadMaterials: function ( node ) {
+
 		var mat = node;
 
 		var loadedmaterial = null;
 		var matname = "AMF Material";
-		var matid = mat.attributes['id'].textContent;
+		var matid = mat.attributes[ 'id' ].textContent;
 		var color;
 
-		for(var i = 0; i < mat.children.length; i++) {
-			var matchildel = mat.children[i];
+		for ( var i = 0; i < mat.children.length; i ++ ) {
+
+			var matchildel = mat.children[ i ];
+
+			if ( matchildel.nodeName === "metadata" && matchildel.attributes[ 'type' ] !== undefined ) {
+
+				if ( matchildel.attributes[ 'type' ].value === 'name' ) {
 
-			if(matchildel.nodeName === "metadata" && matchildel.attributes['type'] !== undefined) {
-				if(matchildel.attributes['type'].value === 'name') {
 					matname = matchildel.textContent;
+
 				}
-			} else if(matchildel.nodeName === 'color') {
-				color = this._loadColor(matchildel);
+
+			} else if ( matchildel.nodeName === 'color' ) {
+
+				color = this._loadColor( matchildel );
+
 			}
+
 		}
 
-		loadedmaterial = new THREE.MeshPhongMaterial({
+		loadedmaterial = new THREE.MeshPhongMaterial( {
 			shading: THREE.FlatShading,
-			color: new THREE.Color(color.r, color.g, color.b),
-			name: matname});
+			color: new THREE.Color( color.r, color.g, color.b ),
+			name: matname } );
+
+		if ( color.opacity !== 1.0 ) {
 
-		if(color.opacity !== 1.0) {
 			loadedmaterial.transparent = true;
 			loadedmaterial.opacity = color.opacity;
+
 		}
 
 		return { 'id': matid, 'material': loadedmaterial };
+
 	},
 
 	_loadColor: function ( node ) {
-		var color = {'r': 1.0, 'g': 1.0, 'b': 1.0, 'a': 1.0, opacity: 1.0};
 
-		for(var i = 0; i < node.children.length; i++) {
-			var matcolor = node.children[i];
+		var color = { 'r': 1.0, 'g': 1.0, 'b': 1.0, 'a': 1.0, opacity: 1.0 };
+
+		for ( var i = 0; i < node.children.length; i ++ ) {
+
+			var matcolor = node.children[ i ];
+
+			if ( matcolor.nodeName === 'r' ) {
 
-			if(matcolor.nodeName === 'r') {
 				color.r = matcolor.textContent;
-			} else if(matcolor.nodeName === 'g') {
+
+			} else if ( matcolor.nodeName === 'g' ) {
+
 				color.g = matcolor.textContent;
-			} else if(matcolor.nodeName === 'b') {
+
+			} else if ( matcolor.nodeName === 'b' ) {
+
 				color.b = matcolor.textContent;
-			} else if(matcolor.nodeName === 'a') {
+
+			} else if ( matcolor.nodeName === 'a' ) {
+
 				color.opacity = matcolor.textContent;
+
 			}
+
 		}
 
 		return color;
+
 	},
 
 	_loadMeshVolume: function( node ) {
+
 		var volume = { "name": "", "triangles": [], "materialid": null };
 
 		var currvolumenode = node.firstElementChild;
 
-		if(node.attributes['materialid'] !== undefined) {
-			volume.materialid = node.attributes['materialid'].nodeValue;
+		if ( node.attributes[ 'materialid' ] !== undefined ) {
+
+			volume.materialid = node.attributes[ 'materialid' ].nodeValue;
+
 		}
 
-		while( currvolumenode ) {
-			if( currvolumenode.nodeName === "metadata" ) {
-				if(currvolumenode.attributes['type'] !== undefined) {
-					if(currvolumenode.attributes['type'].value === 'name') {
+		while ( currvolumenode ) {
+
+			if ( currvolumenode.nodeName === "metadata" ) {
+
+				if ( currvolumenode.attributes[ 'type' ] !== undefined ) {
+
+					if ( currvolumenode.attributes[ 'type' ].value === 'name' ) {
+
 						volume.name = currvolumenode.textContent;
+
 					}
+
 				}
+
 			} else if ( currvolumenode.nodeName === "triangle" ) {
+
 				var trianglenode = currvolumenode.firstElementChild;
 
-				while( trianglenode ) {
-					if( trianglenode.nodeName === "v1" ||
+				while ( trianglenode ) {
+
+					if ( trianglenode.nodeName === "v1" ||
 							trianglenode.nodeName === "v2" ||
-							trianglenode.nodeName === "v3") {
-						volume.triangles.push(trianglenode.textContent);
+							trianglenode.nodeName === "v3" ) {
+
+						volume.triangles.push( trianglenode.textContent );
+
 					}
 
 					trianglenode = trianglenode.nextElementSibling;
+
 				}
+
 			}
 			currvolumenode = currvolumenode.nextElementSibling;
+
 		}
 
 		return volume;
+
 	},
 
 	_loadMeshVertices: function( node ) {
+
 		var vert_array = [];
 
 		var currverticesnode = node.firstElementChild;
 
-		while( currverticesnode ) {
+		while ( currverticesnode ) {
+
 			if ( currverticesnode.nodeName === "vertex" ) {
+
 				var vnode = currverticesnode.firstElementChild;
 
-				while( vnode ) {
-					if( vnode.nodeName === "coordinates") {
+				while ( vnode ) {
+
+					if ( vnode.nodeName === "coordinates" ) {
+
 						var coordnode = vnode.firstElementChild;
 
-						while( coordnode ) {
+						while ( coordnode ) {
 
-							if( coordnode.nodeName === "x" ||
+							if ( coordnode.nodeName === "x" ||
 									coordnode.nodeName === "y" ||
-									coordnode.nodeName === "z") {
-								vert_array.push(coordnode.textContent);
+									coordnode.nodeName === "z" ) {
+
+								vert_array.push( coordnode.textContent );
+
 							}
 
 							coordnode = coordnode.nextElementSibling;
+
 						}
+
 					}
 					vnode = vnode.nextElementSibling;
+
 				}
+
 			}
 			currverticesnode = currverticesnode.nextElementSibling;
+
 		}
 
 		return vert_array;
+
 	},
 
 	_loadObject: function ( node ) {
+
 		"use strict";
-		var objid = node.attributes['id'].textContent;
+
+		var objid = node.attributes[ 'id' ].textContent;
 		var loadedobject = { "name": "amfobject", "meshes": [] };
 
 		var currcolor = null;
 
 		var currobjnode = node.firstElementChild;
 
-		while( currobjnode ) {
-			if(currobjnode.nodeName === "metadata") {
-				if(currobjnode.attributes['type'] !== undefined) {
-					if(currobjnode.attributes['type'].value === 'name') {
+		while ( currobjnode ) {
+
+			if ( currobjnode.nodeName === "metadata" ) {
+
+				if ( currobjnode.attributes[ 'type' ] !== undefined ) {
+
+					if ( currobjnode.attributes[ 'type' ].value === 'name' ) {
+
 						loadedobject.name = currobjnode.textContent;
+
 					}
+
 				}
-			} else if(currobjnode.nodeName === "color") {
-				currcolor = this._loadColor(currobjnode);
-			} else if(currobjnode.nodeName === "mesh") {
+
+			} else if ( currobjnode.nodeName === "color" ) {
+
+				currcolor = this._loadColor( currobjnode );
+
+			} else if ( currobjnode.nodeName === "mesh" ) {
+
 				var currmeshnode = currobjnode.firstElementChild;
-				var mesh = {"vertices": [], "volumes": [], "color": currcolor };
+				var mesh = { "vertices": [], "volumes": [], "color": currcolor };
+
+				while ( currmeshnode ) {
+
+					if ( currmeshnode.nodeName === "vertices" ) {
+
+						mesh.vertices = mesh.vertices.concat( this._loadMeshVertices( currmeshnode ) );
+
+					} else if ( currmeshnode.nodeName === "volume" ) {
+
+						mesh.volumes.push( this._loadMeshVolume( currmeshnode ) );
 
-				while( currmeshnode ) {
-					if(currmeshnode.nodeName === "vertices") {
-						mesh.vertices = mesh.vertices.concat(this._loadMeshVertices(currmeshnode));
-					} else if(currmeshnode.nodeName === "volume") {
-						mesh.volumes.push(this._loadMeshVolume(currmeshnode));
 					}
+
 					currmeshnode = currmeshnode.nextElementSibling;
+
 				}
 
-				loadedobject.meshes.push(mesh);
+				loadedobject.meshes.push( mesh );
+
 			}
+
 			currobjnode = currobjnode.nextElementSibling;
+
 		}
 
 		return { 'id': objid, 'obj': loadedobject };
+
 	}
 };