Browse Source

Modified collada loader to add support for polygon primitives

Peter Blasco 13 years ago
parent
commit
d0f9acb5b9
1 changed files with 103 additions and 91 deletions
  1. 103 91
      src/extras/loaders/ColladaLoader.js

+ 103 - 91
src/extras/loaders/ColladaLoader.js

@@ -2195,7 +2195,8 @@ THREE.ColladaLoader = function () {
 
 				case 'polygons':
 
-					console.warn( 'polygon holes not yet supported!' );
+					this.primitives.push( ( new Polygons().parse( child ) ) );
+					break;
 
 				case 'polylist':
 
@@ -2246,7 +2247,7 @@ THREE.ColladaLoader = function () {
 
 	Mesh.prototype.handlePrimitive = function( primitive, geom ) {
 
-		var i = 0, j, k, p = primitive.p, inputs = primitive.inputs;
+		var j, k, pList = primitive.p, inputs = primitive.inputs;
 		var input, index, idx32;
 		var source, numParams;
 		var vcIndex = 0, vcount = 3, maxOffset = 0;
@@ -2268,166 +2269,170 @@ THREE.ColladaLoader = function () {
 
 		}
 
-		while ( i < p.length ) {
+		for (var pCount = 0; pCount < pList.length; ++pCount) {
+			var p = pList[pCount], i = 0;
 
-			var vs = [];
-			var ns = [];
-			var ts = {};
-			var cs = [];
+			while ( i < p.length ) {
 
-			if ( primitive.vcount ) {
+				var vs = [];
+				var ns = [];
+				var ts = {};
+				var cs = [];
 
-				vcount = primitive.vcount[ vcIndex ++ ];
+				if ( primitive.vcount ) {
 
-			}
+					vcount = primitive.vcount[ vcIndex ++ ];
 
-			for ( j = 0; j < vcount; j ++ ) {
+				}
+				else {
+					vcount = p.length / maxOffset;
+				}
 
-				for ( k = 0; k < inputs.length; k ++ ) {
 
-					input = inputs[ k ];
-					source = sources[ input.source ];
+				for ( j = 0; j < vcount; j ++ ) {
 
-					index = p[ i + ( j * maxOffset ) + input.offset ];
-					numParams = source.accessor.params.length;
-					idx32 = index * numParams;
+					for ( k = 0; k < inputs.length; k ++ ) {
 
-					switch ( input.semantic ) {
+						input = inputs[ k ];
+						source = sources[ input.source ];
 
-						case 'VERTEX':
+						index = p[ i + ( j * maxOffset ) + input.offset ];
+						numParams = source.accessor.params.length;
+						idx32 = index * numParams;
 
-							vs.push( index );
+						switch ( input.semantic ) {
 
-							break;
+							case 'VERTEX':
 
-						case 'NORMAL':
+								vs.push( index );
 
-							ns.push( getConvertedVec3( source.data, idx32 ) );
+								break;
 
-							break;
+							case 'NORMAL':
 
-						case 'TEXCOORD':
+								ns.push( getConvertedVec3( source.data, idx32 ) );
 
-							if ( ts[ input.set ] === undefined ) ts[ input.set ] = [];
-							// invert the V
-							ts[ input.set ].push( new THREE.UV( source.data[ idx32 ], 1.0 - source.data[ idx32 + 1 ] ) );
+								break;
 
-							break;
+							case 'TEXCOORD':
 
-						case 'COLOR':
+								if ( ts[ input.set ] === undefined ) ts[ input.set ] = [];
+								// invert the V
+								ts[ input.set ].push( new THREE.UV( source.data[ idx32 ], 1.0 - source.data[ idx32 + 1 ] ) );
 
-							cs.push( new THREE.Color().setRGB( source.data[ idx32 ], source.data[ idx32 + 1 ], source.data[ idx32 + 2 ] ) );
+								break;
 
-							break;
+							case 'COLOR':
 
-						default:
-							break;
+								cs.push( new THREE.Color().setRGB( source.data[ idx32 ], source.data[ idx32 + 1 ], source.data[ idx32 + 2 ] ) );
+
+								break;
+
+							default:
+								break;
+
+						}
 
 					}
 
 				}
 
-			}
 
+				var face = null, faces = [], uv, uvArr;
 
-			var face = null, faces = [], uv, uvArr;
+				if ( ns.length == 0 ) {
+					// check the vertices source
+					input = this.vertices.input.NORMAL;
 
-			if ( ns.length == 0 ) {
-				
-				// check the vertices source
-				input = this.vertices.input.NORMAL;
+					if ( input ) {
 
-				if ( input ) {
+						source = sources[ input.source ];
+						numParams = source.accessor.params.length;
 
-					source = sources[ input.source ];
-					numParams = source.accessor.params.length;
+						for ( var ndx = 0, len = vs.length; ndx < len; ndx++ ) {
 
-					for ( var ndx = 0, len = vs.length; ndx < len; ndx++ ) {
+							ns.push( getConvertedVec3( source.data, vs[ ndx ] * numParams ) );
 
-						ns.push( getConvertedVec3( source.data, vs[ ndx ] * numParams ) );
+						}
 
 					}
+					else {
+						geom.calcNormals = true;
+					}
 
 				}
-				else {
-					
-					geom.calcNormals = true;
-					
-				}
 
-			}
+				if ( vcount === 3 ) {
 
-			if ( vcount === 3 ) {
+					faces.push( new THREE.Face3( vs[0], vs[1], vs[2], ns, cs.length ? cs : new THREE.Color() ) );
 
-				faces.push( new THREE.Face3( vs[0], vs[1], vs[2], ns, cs.length ? cs : new THREE.Color() ) );
+				} else if ( vcount === 4 ) {
+					faces.push( new THREE.Face4( vs[0], vs[1], vs[2], vs[3], ns, cs.length ? cs : new THREE.Color() ) );
 
-			} else if ( vcount === 4 ) {
-				
-				faces.push( new THREE.Face4( vs[0], vs[1], vs[2], vs[3], ns, cs.length ? cs : new THREE.Color() ) );
+				} else if ( vcount > 4 && options.subdivideFaces ) {
 
-			} else if ( vcount > 4 && options.subdivideFaces ) {
+					var clr = cs.length ? cs : new THREE.Color(),
+						vec1, vec2, vec3, v1, v2, norm;
 
-				var clr = cs.length ? cs : new THREE.Color(),
-					vec1, vec2, vec3, v1, v2, norm;
+					// subdivide into multiple Face3s
+					for ( k = 1; k < vcount-1; ) {
 
-				// subdivide into multiple Face3s
-				for ( k = 1; k < vcount-1; ) {
+						// FIXME: normals don't seem to be quite right
+						faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0], ns[k++], ns[k] ],  clr ) );
 
-					// FIXME: normals don't seem to be quite right
-					faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0], ns[k++], ns[k] ],  clr ) );
+					}
 
 				}
 
-			}
+				if ( faces.length ) {
 
-			if ( faces.length ) {
+					for (var ndx = 0, len = faces.length; ndx < len; ndx++) {
 
-				for (var ndx = 0, len = faces.length; ndx < len; ndx++) {
+						face = faces[ndx];
+						face.daeMaterial = primitive.material;
+						geom.faces.push( face );
 
-					face = faces[ndx];
-					face.daeMaterial = primitive.material;
-					geom.faces.push( face );
+						for ( k = 0; k < texture_sets.length; k++ ) {
 
-					for ( k = 0; k < texture_sets.length; k++ ) {
+							uv = ts[ texture_sets[k] ];
 
-						uv = ts[ texture_sets[k] ];
+							if ( vcount > 4 ) {
 
-						if ( vcount > 4 ) {
+								// Grab the right UVs for the vertices in this face
+								uvArr = [ uv[0], uv[ndx+1], uv[ndx+2] ];
 
-							// Grab the right UVs for the vertices in this face
-							uvArr = [ uv[0], uv[ndx+1], uv[ndx+2] ];
+							} else if ( vcount === 4 ) {
 
-						} else if ( vcount === 4 ) {
+								uvArr = [ uv[0], uv[1], uv[2], uv[3] ];
 
-							uvArr = [ uv[0], uv[1], uv[2], uv[3] ];
+							} else {
 
-						} else {
+								uvArr = [ uv[0], uv[1], uv[2] ];
 
-							uvArr = [ uv[0], uv[1], uv[2] ];
+							}
 
-						}
+							if ( !geom.faceVertexUvs[k] ) {
 
-						if ( !geom.faceVertexUvs[k] ) {
+								geom.faceVertexUvs[k] = [];
 
-							geom.faceVertexUvs[k] = [];
+							}
 
-						}
+							geom.faceVertexUvs[k].push( uvArr );
 
-						geom.faceVertexUvs[k].push( uvArr );
+						}
 
 					}
 
-				}
-
-			} else {
+				} else {
 
-				console.log( 'dropped face with vcount ' + vcount + ' for geometry with id: ' + geom.id );
+					console.log( 'dropped face with vcount ' + vcount + ' for geometry with id: ' + geom.id );
 
-			}
+				}
 
-			i += maxOffset * vcount;
+				i += maxOffset * vcount;
 
-		}
+			}
+	}
 
 	};
 
@@ -2466,6 +2471,7 @@ THREE.ColladaLoader = function () {
 	Triangles.prototype.parse = function ( element ) {
 
 		this.inputs = [];
+		this.p = [];
 		this.material = element.getAttribute( 'material' );
 		this.count = _attr_as_int( element, 'count', 0 );
 
@@ -2487,7 +2493,7 @@ THREE.ColladaLoader = function () {
 
 				case 'p':
 
-					this.p = _ints( child.textContent );
+					this.p.push(_ints( child.textContent ));
 					break;
 
 				default:
@@ -2501,6 +2507,12 @@ THREE.ColladaLoader = function () {
 
 	};
 
+	function Polygons () {
+	};
+
+	Polygons.prototype = new Triangles();
+	Polygons.prototype.constructor = Polygons;
+
 	function Accessor() {
 
 		this.source = "";