Sfoglia il codice sorgente

ColladaLoader2: Refactored vertex input parser.

Mr.doob 9 anni fa
parent
commit
0a17f0ef94
1 ha cambiato i file con 145 aggiunte e 118 eliminazioni
  1. 145 118
      examples/js/loaders/ColladaLoader2.js

+ 145 - 118
examples/js/loaders/ColladaLoader2.js

@@ -793,33 +793,45 @@ THREE.ColladaLoader.prototype = {
 
 		// geometry
 
-		function parseSource( xml ) {
+		function parseGeometry( xml ) {
 
 			var data = {
-				array: [],
-				stride: 3
+				name: xml.getAttribute( 'name' ),
+				sources: {},
+				vertices: {},
+				primitives: []
 			};
 
-			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
+			var mesh = getElementsByTagName( xml, 'mesh' )[ 0 ];
 
-				var child = xml.childNodes[ i ];
+			for ( var i = 0; i < mesh.childNodes.length; i ++ ) {
+
+				var child = mesh.childNodes[ i ];
 
 				if ( child.nodeType !== 1 ) continue;
 
+				var id = child.getAttribute( 'id' );
+
 				switch ( child.nodeName ) {
 
-					case 'float_array':
-						data.array = parseFloats( child.textContent );
+					case 'source':
+						data.sources[ id ] = parseGeometrySource( child );
 						break;
 
-					case 'technique_common':
-						var accessor = getElementsByTagName( child, 'accessor' )[ 0 ];
-
-						if ( accessor !== undefined ) {
+					case 'vertices':
+						// data.sources[ id ] = data.sources[ parseId( getElementsByTagName( child, 'input' )[ 0 ].getAttribute( 'source' ) ) ];
+						data.vertices = parseGeometryVertices( child );
+						break;
 
-							data.stride = parseInt( accessor.getAttribute( 'stride' ) );
+					case 'polygons':
+						console.log( 'ColladaLoader: Unsupported primitive type: ', child.nodeName );
+						break;
 
-						}
+					case 'lines':
+					case 'linestrips':
+					case 'polylist':
+					case 'triangles':
+						data.primitives.push( parseGeometryPrimitive( child ) );
 						break;
 
 					default:
@@ -829,47 +841,37 @@ THREE.ColladaLoader.prototype = {
 
 			}
 
-			return data;
+			library.geometries[ xml.getAttribute( 'id' ) ] = data;
 
 		}
 
-		function parseGeometry( xml ) {
+		function parseGeometrySource( xml ) {
 
 			var data = {
-				name: xml.getAttribute( 'name' ),
-				sources: {},
-				primitives: []
+				array: [],
+				stride: 3
 			};
 
-			var mesh = getElementsByTagName( xml, 'mesh' )[ 0 ];
-
-			for ( var i = 0; i < mesh.childNodes.length; i ++ ) {
+			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
 
-				var child = mesh.childNodes[ i ];
+				var child = xml.childNodes[ i ];
 
 				if ( child.nodeType !== 1 ) continue;
 
-				var id = child.getAttribute( 'id' );
-
 				switch ( child.nodeName ) {
 
-					case 'source':
-						data.sources[ id ] = parseSource( child );
+					case 'float_array':
+						data.array = parseFloats( child.textContent );
 						break;
 
-					case 'vertices':
-						data.sources[ id ] = data.sources[ parseId( getElementsByTagName( child, 'input' )[ 0 ].getAttribute( 'source' ) ) ];
-						break;
+					case 'technique_common':
+						var accessor = getElementsByTagName( child, 'accessor' )[ 0 ];
 
-					case 'polygons':
-						console.log( 'ColladaLoader: Unsupported primitive type: ', child.nodeName );
-						break;
+						if ( accessor !== undefined ) {
 
-					case 'lines':
-					case 'linestrips':
-					case 'polylist':
-					case 'triangles':
-						data.primitives.push( parseGeometryPrimitive( child ) );
+							data.stride = parseInt( accessor.getAttribute( 'stride' ) );
+
+						}
 						break;
 
 					default:
@@ -879,7 +881,25 @@ THREE.ColladaLoader.prototype = {
 
 			}
 
-			library.geometries[ xml.getAttribute( 'id' ) ] = data;
+			return data;
+
+		}
+
+		function parseGeometryVertices( xml ) {
+
+			var data = {};
+
+			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				data[ child.getAttribute( 'semantic' ) ] = parseId( child.getAttribute( 'source' ) );
+
+			}
+
+			return data;
 
 		}
 
@@ -932,6 +952,7 @@ THREE.ColladaLoader.prototype = {
 			var group = {};
 
 			var sources = data.sources;
+			var vertices = data.vertices;
 			var primitives = data.primitives;
 
 			if ( primitives.length === 0 ) return group;
@@ -939,149 +960,155 @@ THREE.ColladaLoader.prototype = {
 			for ( var p = 0; p < primitives.length; p ++ ) {
 
 				var primitive = primitives[ p ];
-
 				var inputs = primitive.inputs;
-				var stride = primitive.stride;
-				var vcount = primitive.vcount;
-
-				var indices = primitive.p;
-
-				var maxcount = 0;
 
 				var geometry = new THREE.BufferGeometry();
+
 				if ( data.name ) geometry.name = data.name;
 
 				for ( var name in inputs ) {
 
 					var input = inputs[ name ];
 
-					var source = sources[ input.id ];
-					var sourceArray = source.array;
-					var sourceStride = source.stride;
+					switch ( name )	{
 
-					var offset = input.offset;
+						case 'VERTEX':
+							for ( var key in vertices ) {
 
-					var array = [];
+								geometry.addAttribute( key.toLowerCase(), buildGeometryAttribute( primitive, sources[ vertices[ key ] ], input.offset ) );
 
-					function pushVector( i ) {
+							}
+							break;
 
-						var index = indices[ i + offset ] * sourceStride;
+						case 'NORMAL':
+							geometry.addAttribute( 'normal', buildGeometryAttribute( primitive, sources[ input.id ], input.offset ) );
+							break;
 
-						/*
-						if ( asset.upAxis === 'Z_UP' ) {
+						case 'COLOR':
+							geometry.addAttribute( 'color', buildGeometryAttribute( primitive, sources[ input.id ], input.offset ) );
+							break;
 
-							array.push( sourceArray[ index + 0 ], sourceArray[ index + 2 ], - sourceArray[ index + 1 ] );
+						case 'TEXCOORD':
+							geometry.addAttribute( 'uv', buildGeometryAttribute( primitive, sources[ input.id ], input.offset ) );
+							break;
 
-						} else {
+					}
 
-							array.push( sourceArray[ index + 0 ], sourceArray[ index + 1 ], sourceArray[ index + 2 ] );
+				}
 
-						}
-						*/
+				var object;
 
-						array.push( sourceArray[ index + 0 ], sourceArray[ index + 1 ], sourceArray[ index + 2 ] );
+				switch ( primitive.type ) {
 
+					case 'lines':
+						object = new THREE.LineSegments( geometry, DEFAULT_LINEMATERIAL );
+						break;
 
-					}
+					case 'linestrips':
+						object = new THREE.Line( geometry, DEFAULT_LINEMATERIAL );
+						break;
 
-					if ( primitive.vcount !== undefined ) {
+					case 'triangles':
+					case 'polylist':
+						object = new THREE.Mesh( geometry, DEFAULT_MESHMATERIAL );
+						break;
 
-						var index = 0;
+				}
 
-						for ( var i = 0, l = vcount.length; i < l; i ++ ) {
+				group[ primitive.material ] = object;
 
-							var count = vcount[ i ];
+			}
 
-							if ( count === 4 ) {
+			return group;
 
-								var a = index + stride * 0;
-								var b = index + stride * 1;
-								var c = index + stride * 2;
-								var d = index + stride * 3;
+		}
 
-								pushVector( a ); pushVector( b ); pushVector( d );
-								pushVector( b ); pushVector( c ); pushVector( d );
+		function buildGeometryAttribute( primitive, source, offset ) {
 
-							} else if ( count === 3 ) {
+			var indices = primitive.p;
+			var stride = primitive.stride;
+			var vcount = primitive.vcount;
 
-								var a = index + stride * 0;
-								var b = index + stride * 1;
-								var c = index + stride * 2;
+			function pushVector( i ) {
 
-								pushVector( a ); pushVector( b ); pushVector( c );
+				var index = indices[ i + offset ] * sourceStride;
 
-							} else {
+				/*
+				if ( asset.upAxis === 'Z_UP' ) {
 
-								maxcount = Math.max( maxcount, count );
+					array.push( sourceArray[ index + 0 ], sourceArray[ index + 2 ], - sourceArray[ index + 1 ] );
 
-							}
+				} else {
 
-							index += stride * count;
+					array.push( sourceArray[ index + 0 ], sourceArray[ index + 1 ], sourceArray[ index + 2 ] );
 
-						}
+				}
+				*/
 
-					} else {
+				array.push( sourceArray[ index + 0 ], sourceArray[ index + 1 ], sourceArray[ index + 2 ] );
 
-						for ( var i = 0, l = indices.length; i < l; i += stride ) {
+			}
 
-							pushVector( i );
+			var maxcount = 0;
 
-						}
+			var sourceArray = source.array;
+			var sourceStride = source.stride;
 
-					}
+			var array = [];
 
-					switch ( name )	{
+			if ( primitive.vcount !== undefined ) {
 
-						case 'VERTEX':
-							geometry.addAttribute( 'position', new THREE.Float32Attribute( array, 3 ) );
-							break;
+				var index = 0;
 
-						case 'COLOR':
-							geometry.addAttribute( 'color', new THREE.Float32Attribute( array, 3 ) );
-							break;
+				for ( var i = 0, l = vcount.length; i < l; i ++ ) {
 
-						case 'NORMAL':
-							geometry.addAttribute( 'normal', new THREE.Float32Attribute( array, 3 ) );
-							break;
+					var count = vcount[ i ];
 
-						case 'TEXCOORD':
-							geometry.addAttribute( 'uv', new THREE.Float32Attribute( array, stride ) );
-							break;
+					if ( count === 4 ) {
+
+						var a = index + stride * 0;
+						var b = index + stride * 1;
+						var c = index + stride * 2;
+						var d = index + stride * 3;
+
+						pushVector( a ); pushVector( b ); pushVector( d );
+						pushVector( b ); pushVector( c ); pushVector( d );
+
+					} else if ( count === 3 ) {
+
+						var a = index + stride * 0;
+						var b = index + stride * 1;
+						var c = index + stride * 2;
+
+						pushVector( a ); pushVector( b ); pushVector( c );
+
+					} else {
+
+						maxcount = Math.max( maxcount, count );
 
 					}
 
+					index += stride * count;
+
 				}
 
 				if ( maxcount > 0 ) {
 
-					console.log( 'ColladaLoader: Geometry', data.id, 'has faces with more than 4 vertices.' );
+					console.log( 'ColladaLoader: Geometry has faces with more than 4 vertices.' );
 
 				}
 
-				var object;
-
-				switch ( primitive.type ) {
-
-					case 'lines':
-						object = new THREE.LineSegments( geometry, DEFAULT_LINEMATERIAL );
-						break;
+			} else {
 
-					case 'linestrips':
-						object = new THREE.Line( geometry, DEFAULT_LINEMATERIAL );
-						break;
+				for ( var i = 0, l = indices.length; i < l; i += stride ) {
 
-					case 'triangles':
-					case 'polylist':
-						object = new THREE.Mesh( geometry, DEFAULT_MESHMATERIAL );
-						break;
+					pushVector( i );
 
 				}
 
-				group[ primitive.material ] = object;
-
 			}
 
-			return group;
+			return new THREE.Float32Attribute( array, sourceStride );
 
 		}