Browse Source

ColladaLoader2: Improved geometry parsing.

Mr.doob 9 years ago
parent
commit
2c4185e818
1 changed files with 92 additions and 25 deletions
  1. 92 25
      examples/js/loaders/ColladaLoader2.js

+ 92 - 25
examples/js/loaders/ColladaLoader2.js

@@ -42,59 +42,126 @@ THREE.ColladaLoader.prototype = {
 
 	parse: function ( text ) {
 
+		function parseFloats( text ) {
+
+			var array = [];
+			var parts = text.split( ' ' );
+
+			for ( var i = 0, l = parts.length; i < l; i ++ ) {
+				array.push( parseFloat( parts[ i ] ) );
+			}
+
+			return array;
+
+		}
+
+		function parseInts( text ) {
+
+			var array = [];
+			var parts = text.split( ' ' );
+
+			for ( var i = 0, l = parts.length; i < l; i ++ ) {
+				array.push( parseInt( parts[ i ] ) );
+			}
+
+			return array;
+
+		}
+
 		function parseGeometries( xml ) {
 
-			xml = xml.getElementsByTagName("geometry");
+			xml = xml.getElementsByTagName( 'geometry' );
 
-			var objects = [];
+			var geometries = [];
 
 			for ( var i = 0; i < xml.length; i ++ ) {
 
-				objects.push( parseMesh( xml[ i ].getElementsByTagName( 'mesh' )[ 0 ] ) );
+				geometries.push( parseGeometry( xml[ i ].getElementsByTagName( 'mesh' )[ 0 ] ) );
 
 			}
 
-			return objects;
+			return geometries;
 
 		}
 
-		function parseMesh( xml ) {
+		function parseGeometry( xml ) {
 
 			var geometry = new THREE.BufferGeometry();
 
-			var sources = xml.getElementsByTagName( 'source' );
+			// sources
 
-			for ( var i = 0; i < sources.length; i ++ ) {
+			var sources = {};
+			var sourceNodes = xml.getElementsByTagName( 'source' );
 
-				var source = sources[ i ];
-				var floats = source.getElementsByTagName( 'float_array' )[ 0 ].textContent.split( ' ' );
+			for ( var i = 0; i < sourceNodes.length; i ++ ) {
 
-				var array = [];
-				for ( var j = 0; j < floats.length; j ++ ) {
-					array.push( floats[ j ] );
-				}
-
-				geometry.addAttribute( 'position', new THREE.Float32Attribute( array, 3 ) );
+				var sourceNode = sourceNodes[ i ];
+				var array = parseFloats( sourceNode.getElementsByTagName( 'float_array' )[ 0 ].textContent );
+				sources[ sourceNode.getAttribute( 'id' ) ] = array;
 
 			}
 
+			// vertices
+
+			var verticesNode = xml.getElementsByTagName( 'vertices' )[ 0 ];
+			sources[ verticesNode.getAttribute( 'id' ) ] = sources[ verticesNode.getElementsByTagName( 'input' )[ 0 ].getAttribute( 'source' ).substring( 1 ) ];
+
+			// triangles
 
-			var triangles = xml.getElementsByTagName( 'triangles' );
+			var triangleNodes = xml.getElementsByTagName( 'triangles' );
 
-			if ( triangles === null ) return mesh;
+			if ( triangleNodes === null ) return geometry;
 
-			for ( var i = 0; i < triangles.length; i ++ ) {
+			for ( var i = 0; i < triangleNodes.length; i ++ ) {
 
-				var triangle = triangles[ i ];
+				var triangleNode = triangleNodes[ i ];
 
-				var indices = triangle.getElementsByTagName( 'p' )[ 0 ].textContent.split( ' ' );
+				// indices
+
+				var indices = parseInts( triangleNode.getElementsByTagName( 'p' )[ 0 ].textContent );
+
+				// inputs
+
+				var inputNodes = triangleNode.getElementsByTagName( 'input' );
+
+				var maxOffset = 0;
+
+				for ( var j = 0; j < inputNodes.length; j ++ ) {
+
+					var inputNode = inputNodes[ j ];
+					maxOffset = Math.max( maxOffset, parseInt( inputNode.getAttribute( 'offset' ) ) + 1 );
 
-				var array = [];
-				for ( var j = 0; j < indices.length; j ++ ) {
-					array.push( parseInt( indices[ j ] ) );
 				}
 
-				geometry.setIndex( new THREE.Uint16Attribute( array, 1 ) );
+				for ( var j = 0; j < inputNodes.length; j ++ ) {
+
+					var inputNode = inputNodes[ j ];
+
+					var source = sources[ inputNode.getAttribute( 'source' ).substring( 1 ) ];
+					var offset = parseInt( inputNode.getAttribute( 'offset' ) );
+
+					var array = [];
+
+					for ( var k = offset; k < indices.length; k += maxOffset ) {
+
+						var index = indices[ k ] * 3;
+						array.push( source[ index + 0 ], source[ index + 1 ], source[ index + 2 ] );
+
+					}
+
+					switch ( inputNode.getAttribute( 'semantic' ) ) {
+
+						case 'VERTEX':
+							geometry.addAttribute( 'position', new THREE.Float32Attribute( array, 3 ) );
+							break;
+
+						case 'NORMAL':
+							geometry.addAttribute( 'normal', new THREE.Float32Attribute( array, 3 ) );
+							break;
+
+					}
+
+				}
 
 			}
 
@@ -119,7 +186,7 @@ THREE.ColladaLoader.prototype = {
 
 		for ( var i = 0; i < geometries.length; i ++ ) {
 
-			scene.add( new THREE.Mesh( geometries[ i ] ) );
+			scene.add( new THREE.Mesh( geometries[ i ], new THREE.MeshPhongMaterial() ) );
 
 		}