makc пре 9 година
родитељ
комит
a6e269a281
1 измењених фајлова са 118 додато и 13 уклоњено
  1. 118 13
      examples/js/loaders/VRMLLoader.js

+ 118 - 13
examples/js/loaders/VRMLLoader.js

@@ -44,10 +44,14 @@ THREE.VRMLLoader.prototype = {
 
 		this.crossOrigin = value;
 
+		THREE.ImageUtils.crossOrigin = value;
+
 	},
 
 	parse: function ( data ) {
 
+		var texturePath = this.texturePath || '';
+
 		var parseV1 = function ( lines, scene ) {
 
 			console.warn( 'VRML V1.0 not supported yet' );
@@ -58,6 +62,7 @@ THREE.VRMLLoader.prototype = {
 
 			var defines = {};
 			var float_pattern = /(\b|\-|\+)([\d\.e]+)/;
+			var float2_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
 			var float3_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
 
 			/**
@@ -239,10 +244,10 @@ THREE.VRMLLoader.prototype = {
 						this.points = [];
 						break;
 					case 'coordIndex':
+					case 'texCoordIndex':
 						this.recordingFieldname = fieldName;
 						this.isRecordingFaces = true;
 						this.indexes = [];
-						break;
 				}
 
 				if ( this.isRecordingFaces ) {
@@ -287,12 +292,14 @@ THREE.VRMLLoader.prototype = {
 					if ( /]/.exec( line ) ) {
 
 						this.isRecordingFaces = false;
-						node.coordIndex = this.indexes;
+						node[this.recordingFieldname] = this.indexes;
 
 					}
 
 				} else if ( this.isRecordingPoints ) {
 
+					if ( node.nodeType == 'Coordinate' )
+
 					while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
 
 						point = {
@@ -305,6 +312,19 @@ THREE.VRMLLoader.prototype = {
 
 					}
 
+					if ( node.nodeType == 'TextureCoordinate' )
+
+					while ( null !== ( parts = float2_pattern.exec( line ) ) ) {
+
+						point = {
+							x: parseFloat( parts[ 1 ] ),
+							y: parseFloat( parts[ 2 ] )
+						};
+
+						this.points.push( point );
+
+					}
+
 					// end
 					if ( /]/.exec( line ) ) {
 
@@ -505,7 +525,7 @@ THREE.VRMLLoader.prototype = {
 
 					}
 
-					if ( matches = /([^\s]*){1}\s?{/.exec( line ) ) {
+					if ( matches = /([^\s]*){1}(?:\s+)?{/.exec( line ) ) {
 
 						// first subpattern should match the Node name
 
@@ -637,7 +657,7 @@ THREE.VRMLLoader.prototype = {
 
 					if ( /DEF/.exec( data.string ) ) {
 
-						object.name = /DEF (\w+)/.exec( data.string )[ 1 ];
+						object.name = /DEF\s+(\w+)/.exec( data.string )[ 1 ];
 
 						defines[ object.name ] = object;
 
@@ -710,7 +730,7 @@ THREE.VRMLLoader.prototype = {
 
 						var geometry = new THREE.Geometry();
 
-						var indexes;
+						var indexes, uvIndexes, uvs;
 
 						for ( var i = 0, j = data.children.length; i < j; i ++ ) {
 
@@ -718,8 +738,17 @@ THREE.VRMLLoader.prototype = {
 
 							var vec;
 
+							if ( 'TextureCoordinate' === child.nodeType ) {
+
+								uvs = child.points;
+
+							}
+
+
 							if ( 'Coordinate' === child.nodeType ) {
 
+								if ( child.points )
+
 								for ( var k = 0, l = child.points.length; k < l; k ++ ) {
 
 									var point = child.points[ k ];
@@ -730,7 +759,20 @@ THREE.VRMLLoader.prototype = {
 
 								}
 
-								break;
+								if ( child.string.indexOf ( 'DEF' ) > -1 ) {
+
+									var name = /DEF\s+(\w+)/.exec( child.string )[ 1 ];
+
+									defines[ name ] = geometry.vertices;
+
+								}
+
+								if ( child.string.indexOf ( 'USE' ) > -1 ) {
+
+									var defineKey = /USE\s+(\w+)/.exec( child.string )[ 1 ];
+
+									geometry.vertices = defines[ defineKey ];
+								}
 
 							}
 
@@ -738,27 +780,45 @@ THREE.VRMLLoader.prototype = {
 
 						var skip = 0;
 
+						// some shapes only have vertices for use in other shapes
+						if ( data.coordIndex )
+
 						// read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html
 						for ( var i = 0, j = data.coordIndex.length; i < j; i ++ ) {
 
-							indexes = data.coordIndex[ i ];
+							indexes = data.coordIndex[ i ]; if ( data.texCoordIndex ) uvIndexes = data.texCoordIndex[ i ];
 
 							// vrml support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
 							skip = 0;
 
-							// todo: this is the time to check if the faces are ordered ccw or not (cw)
-
 							// Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles
 							while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) {
 
 								var face = new THREE.Face3(
 									indexes[ 0 ],
-									indexes[ skip + 1 ],
-									indexes[ skip + 2 ],
+									indexes[ skip + data.ccw ? 1 : 2 ],
+									indexes[ skip + data.ccw ? 2 : 1 ],
 									null // normal, will be added later
 									// todo: pass in the color, if a color index is present
 								);
 
+								if ( uvs && uvIndexes ) {
+									geometry.faceVertexUvs [0].push( [
+										new THREE.Vector2 (
+											uvs[ uvIndexes[ 0 ] ].x ,
+											uvs[ uvIndexes[ 0 ] ].y
+										) ,
+										new THREE.Vector2 (
+											uvs[ uvIndexes[ skip + data.ccw ? 1 : 2 ] ].x ,
+											uvs[ uvIndexes[ skip + data.ccw ? 1 : 2 ] ].y
+										) ,
+										new THREE.Vector2 (
+											uvs[ uvIndexes[ skip + data.ccw ? 2 : 1 ] ].x ,
+											uvs[ uvIndexes[ skip + data.ccw ? 2 : 1 ] ].y
+										)
+									] );
+								}
+
 								skip ++;
 
 								geometry.faces.push( face );
@@ -850,8 +910,19 @@ THREE.VRMLLoader.prototype = {
 
 							parent.material = material;
 
-							// material found, stop looping
-							break;
+						}
+
+						if ( 'ImageTexture' === child.nodeType ) {
+
+							var textureName = /"([^"]+)"/.exec(child.children[ 0 ]);
+
+							if (textureName) {
+
+								parent.material.name = textureName[ 1 ];
+
+								parent.material.map = THREE.ImageUtils.loadTexture (texturePath + textureName[ 1 ]);
+
+							}
 
 						}
 
@@ -879,6 +950,40 @@ THREE.VRMLLoader.prototype = {
 
 		var lines = data.split( '\n' );
 
+		// some lines do not have breaks
+		for (var i = lines.length -1; i > -1; i--) {
+
+			// split lines with {..{ or {..[ - some have both
+			if (/{.*[{\[]/.test (lines[i])) {
+				var parts = lines[i].split ('{').join ('{\n').split ('\n');
+				parts.unshift(1);
+				parts.unshift(i);
+				lines.splice.apply(lines, parts);
+			} else
+
+			// split lines with ]..}
+			if (/\].*}/.test (lines[i])) {
+				var parts = lines[i].split (']').join (']\n').split ('\n');
+				parts.unshift(1);
+				parts.unshift(i);
+				lines.splice.apply(lines, parts);
+			}
+
+			// split lines with }..}
+			if (/}.*}/.test (lines[i])) {
+				var parts = lines[i].split ('}').join ('}\n').split ('\n');
+				parts.unshift(1);
+				parts.unshift(i);
+				lines.splice.apply(lines, parts);
+			}
+
+			// force the parser to create Coordinate node for empty coords
+			// coord USE something -> coord USE something Coordinate {}
+			if((lines[i].indexOf ('coord') > -1) && (lines[i].indexOf ('[') < 0) && (lines[i].indexOf ('{') < 0)) {
+				lines[i] += ' Coordinate {}';
+			}
+		}
+
 		var header = lines.shift();
 
 		if ( /V1.0/.exec( header ) ) {