VRMLLoader.js 23.9 KB
Newer Older
M
r59  
Mr.doob 已提交
1 2 3 4
/**
 * @author mrdoob / http://mrdoob.com/
 */

M
r72  
Mr.doob 已提交
5 6 7 8 9
THREE.VRMLLoader = function ( manager ) {

	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;

};
M
r59  
Mr.doob 已提交
10 11 12

THREE.VRMLLoader.prototype = {

M
r62  
Mr.doob 已提交
13
	constructor: THREE.VRMLLoader,
M
r59  
Mr.doob 已提交
14

M
r66  
Mr.doob 已提交
15 16 17 18 19
	// for IndexedFaceSet support
	isRecordingPoints: false,
	isRecordingFaces: false,
	points: [],
	indexes : [],
M
r63  
Mr.doob 已提交
20

M
r66  
Mr.doob 已提交
21 22 23 24 25
	// for Background support
	isRecordingAngles: false,
	isRecordingColors: false,
	angles: [],
	colors: [],
M
r63  
Mr.doob 已提交
26

M
r66  
Mr.doob 已提交
27
	recordingFieldname: null,
M
r63  
Mr.doob 已提交
28

M
r72  
Mr.doob 已提交
29
	load: function ( url, onLoad, onProgress, onError ) {
M
r59  
Mr.doob 已提交
30 31 32

		var scope = this;

M
r83  
Mr.doob 已提交
33
		var loader = new THREE.FileLoader( this.manager );
M
r72  
Mr.doob 已提交
34
		loader.load( url, function ( text ) {
M
r66  
Mr.doob 已提交
35

M
r72  
Mr.doob 已提交
36
			onLoad( scope.parse( text ) );
M
r59  
Mr.doob 已提交
37

M
r72  
Mr.doob 已提交
38
		}, onProgress, onError );
M
r59  
Mr.doob 已提交
39

M
r72  
Mr.doob 已提交
40
	},
M
r59  
Mr.doob 已提交
41

M
r72  
Mr.doob 已提交
42
	setCrossOrigin: function ( value ) {
M
r59  
Mr.doob 已提交
43

M
r72  
Mr.doob 已提交
44
		this.crossOrigin = value;
M
r59  
Mr.doob 已提交
45 46 47 48 49

	},

	parse: function ( data ) {

M
r73  
Mr.doob 已提交
50 51
		var texturePath = this.texturePath || '';

M
r74  
Mr.doob 已提交
52 53 54
		var textureLoader = new THREE.TextureLoader( this.manager );
		textureLoader.setCrossOrigin( this.crossOrigin );

M
r59  
Mr.doob 已提交
55 56 57 58 59 60 61
		var parseV1 = function ( lines, scene ) {

			console.warn( 'VRML V1.0 not supported yet' );

		};

		var parseV2 = function ( lines, scene ) {
M
r69  
Mr.doob 已提交
62

M
r66  
Mr.doob 已提交
63 64
			var defines = {};
			var float_pattern = /(\b|\-|\+)([\d\.e]+)/;
M
r73  
Mr.doob 已提交
65
			var float2_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
M
r69  
Mr.doob 已提交
66
			var float3_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
M
r66  
Mr.doob 已提交
67 68 69 70 71 72 73 74 75 76

			/**
			* Interpolates colors a and b following their relative distance
			* expressed by t.
			*
			* @param float a
			* @param float b
			* @param float t
			* @returns {Color}
			*/
M
r72  
Mr.doob 已提交
77 78
			var interpolateColors = function( a, b, t ) {

M
r69  
Mr.doob 已提交
79 80 81
				var deltaR = a.r - b.r;
				var deltaG = a.g - b.g;
				var deltaB = a.b - b.b;
M
r66  
Mr.doob 已提交
82

M
r69  
Mr.doob 已提交
83
				var c = new THREE.Color();
M
r66  
Mr.doob 已提交
84

M
r69  
Mr.doob 已提交
85 86 87
				c.r = a.r - t * deltaR;
				c.g = a.g - t * deltaG;
				c.b = a.b - t * deltaB;
M
r66  
Mr.doob 已提交
88

M
r69  
Mr.doob 已提交
89
				return c;
M
r72  
Mr.doob 已提交
90

M
r66  
Mr.doob 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
			};

			/**
			 * Vertically paints the faces interpolating between the
			 * specified colors at the specified angels. This is used for the Background
			 * node, but could be applied to other nodes with multiple faces as well.
			 *
			 * When used with the Background node, default is directionIsDown is true if
			 * interpolating the skyColor down from the Zenith. When interpolationg up from
			 * the Nadir i.e. interpolating the groundColor, the directionIsDown is false.
			 *
			 * The first angle is never specified, it is the Zenith (0 rad). Angles are specified
			 * in radians. The geometry is thought a sphere, but could be anything. The color interpolation
			 * is linear along the Y axis in any case.
			 *
			 * You must specify one more color than you have angles at the beginning of the colors array.
			 * This is the color of the Zenith (the top of the shape).
			 *
			 * @param geometry
			 * @param radius
			 * @param angles
			 * @param colors
			 * @param boolean directionIsDown Whether to work bottom up or top down.
			 */
M
r72  
Mr.doob 已提交
115
			var paintFaces = function ( geometry, radius, angles, colors, directionIsDown ) {
M
r66  
Mr.doob 已提交
116

M
r72  
Mr.doob 已提交
117
				var direction = directionIsDown ? 1 : - 1;
M
r66  
Mr.doob 已提交
118 119 120

				var faceIndices = [ 'a', 'b', 'c', 'd' ];

M
r86  
Mr.doob 已提交
121
				var coord = [], A = {}, B = {}, applyColor = false;
M
r66  
Mr.doob 已提交
122

M
r71  
Mr.doob 已提交
123
				for ( var k = 0; k < angles.length; k ++ ) {
M
r66  
Mr.doob 已提交
124 125 126

					// push the vector at which the color changes

M
r86  
Mr.doob 已提交
127 128 129 130
					var vec = {
						x: direction * ( Math.cos( angles[ k ] ) * radius ),
						y: direction * ( Math.sin( angles[ k ] ) * radius )
					};
M
r66  
Mr.doob 已提交
131 132 133 134 135 136

					coord.push( vec );

				}

				// painting the colors on the faces
M
r71  
Mr.doob 已提交
137
				for ( var i = 0; i < geometry.faces.length ; i ++ ) {
M
r66  
Mr.doob 已提交
138

M
r86  
Mr.doob 已提交
139
					var f = geometry.faces[ i ];
M
r66  
Mr.doob 已提交
140

M
r86  
Mr.doob 已提交
141
					var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
M
r66  
Mr.doob 已提交
142

M
r71  
Mr.doob 已提交
143
					for ( var j = 0; j < n; j ++ ) {
M
r66  
Mr.doob 已提交
144

M
r86  
Mr.doob 已提交
145
						var vertexIndex = f[ faceIndices[ j ] ];
M
r66  
Mr.doob 已提交
146

M
r86  
Mr.doob 已提交
147
						var p = geometry.vertices[ vertexIndex ];
M
r66  
Mr.doob 已提交
148

M
r71  
Mr.doob 已提交
149
						for ( var index = 0; index < colors.length; index ++ ) {
M
r66  
Mr.doob 已提交
150 151 152 153 154 155

							// linear interpolation between aColor and bColor, calculate proportion
							// A is previous point (angle)
							if ( index === 0 ) {

								A.x = 0;
M
r72  
Mr.doob 已提交
156
								A.y = directionIsDown ? radius : - 1 * radius;
M
r66  
Mr.doob 已提交
157 158 159

							} else {

M
r71  
Mr.doob 已提交
160 161
								A.x = coord[ index - 1 ].x;
								A.y = coord[ index - 1 ].y;
M
r66  
Mr.doob 已提交
162 163

							}
M
r63  
Mr.doob 已提交
164

M
r66  
Mr.doob 已提交
165
							// B is current point (angle)
M
r72  
Mr.doob 已提交
166
							B = coord[ index ];
M
r63  
Mr.doob 已提交
167

M
r66  
Mr.doob 已提交
168
							if ( undefined !== B ) {
M
r72  
Mr.doob 已提交
169

M
r66  
Mr.doob 已提交
170 171
								// p has to be between the points A and B which we interpolate
								applyColor = directionIsDown ? p.y <= A.y && p.y > B.y : p.y >= A.y && p.y < B.y;
M
r63  
Mr.doob 已提交
172

M
r72  
Mr.doob 已提交
173
								if ( applyColor ) {
M
r63  
Mr.doob 已提交
174

M
r86  
Mr.doob 已提交
175 176
									var aColor = colors[ index ];
									var bColor = colors[ index + 1 ];
M
r63  
Mr.doob 已提交
177

M
r66  
Mr.doob 已提交
178
									// below is simple linear interpolation
M
r86  
Mr.doob 已提交
179
									var t = Math.abs( p.y - A.y ) / ( A.y - B.y );
M
r63  
Mr.doob 已提交
180

M
r66  
Mr.doob 已提交
181
									// to make it faster, you can only calculate this if the y coord changes, the color is the same for points with the same y
M
r86  
Mr.doob 已提交
182
									var color = interpolateColors( aColor, bColor, t );
M
r63  
Mr.doob 已提交
183

M
r66  
Mr.doob 已提交
184
									f.vertexColors[ j ] = color;
M
r72  
Mr.doob 已提交
185

M
r66  
Mr.doob 已提交
186
								}
M
r63  
Mr.doob 已提交
187

M
r66  
Mr.doob 已提交
188
							} else if ( undefined === f.vertexColors[ j ] ) {
M
r72  
Mr.doob 已提交
189

M
r86  
Mr.doob 已提交
190
								var colorIndex = directionIsDown ? colors.length - 1 : 0;
M
r66  
Mr.doob 已提交
191
								f.vertexColors[ j ] = colors[ colorIndex ];
M
r63  
Mr.doob 已提交
192

M
r66  
Mr.doob 已提交
193
							}
M
r72  
Mr.doob 已提交
194

M
r66  
Mr.doob 已提交
195 196 197
						}

					}
M
r63  
Mr.doob 已提交
198

M
r66  
Mr.doob 已提交
199
				}
M
r72  
Mr.doob 已提交
200

M
r66  
Mr.doob 已提交
201 202
			};

M
Mr.doob 已提交
203 204
			var index = [];

M
r72  
Mr.doob 已提交
205
			var parseProperty = function ( node, line ) {
M
r63  
Mr.doob 已提交
206

M
r66  
Mr.doob 已提交
207
				var parts = [], part, property = {}, fieldName;
M
r63  
Mr.doob 已提交
208

M
r66  
Mr.doob 已提交
209 210 211 212 213
				/**
				 * Expression for matching relevant information, such as a name or value, but not the separators
				 * @type {RegExp}
				 */
				var regex = /[^\s,\[\]]+/g;
M
r63  
Mr.doob 已提交
214

M
Mr.doob 已提交
215
				var point, angles, colors;
M
r63  
Mr.doob 已提交
216

M
r72  
Mr.doob 已提交
217 218 219 220
				while ( null != ( part = regex.exec( line ) ) ) {

					parts.push( part[ 0 ] );

M
r66  
Mr.doob 已提交
221
				}
M
r63  
Mr.doob 已提交
222

M
r72  
Mr.doob 已提交
223
				fieldName = parts[ 0 ];
M
r66  
Mr.doob 已提交
224 225 226


				// trigger several recorders
M
r72  
Mr.doob 已提交
227
				switch ( fieldName ) {
M
r66  
Mr.doob 已提交
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
					case 'skyAngle':
					case 'groundAngle':
						this.recordingFieldname = fieldName;
						this.isRecordingAngles = true;
						this.angles = [];
						break;
					case 'skyColor':
					case 'groundColor':
						this.recordingFieldname = fieldName;
						this.isRecordingColors = true;
						this.colors = [];
						break;
					case 'point':
						this.recordingFieldname = fieldName;
						this.isRecordingPoints = true;
						this.points = [];
						break;
					case 'coordIndex':
M
r73  
Mr.doob 已提交
246
					case 'texCoordIndex':
M
r66  
Mr.doob 已提交
247 248 249 250
						this.recordingFieldname = fieldName;
						this.isRecordingFaces = true;
						this.indexes = [];
				}
M
r63  
Mr.doob 已提交
251

M
r72  
Mr.doob 已提交
252
				if ( this.isRecordingFaces ) {
M
r63  
Mr.doob 已提交
253

M
r66  
Mr.doob 已提交
254
					// the parts hold the indexes as strings
M
r72  
Mr.doob 已提交
255 256 257
					if ( parts.length > 0 ) {

						for ( var ind = 0; ind < parts.length; ind ++ ) {
M
r63  
Mr.doob 已提交
258

M
r66  
Mr.doob 已提交
259
							// the part should either be positive integer or -1
M
r72  
Mr.doob 已提交
260 261
							if ( ! /(-?\d+)/.test( parts[ ind ] ) ) {

M
r66  
Mr.doob 已提交
262
								continue;
M
r72  
Mr.doob 已提交
263

M
r66  
Mr.doob 已提交
264
							}
M
r63  
Mr.doob 已提交
265

M
r66  
Mr.doob 已提交
266
							// end of current face
M
r72  
Mr.doob 已提交
267 268 269 270 271 272
							if ( parts[ ind ] === "-1" ) {

								if ( index.length > 0 ) {

									this.indexes.push( index );

M
r66  
Mr.doob 已提交
273
								}
M
r63  
Mr.doob 已提交
274

M
r66  
Mr.doob 已提交
275 276
								// start new one
								index = [];
M
r72  
Mr.doob 已提交
277

M
r66  
Mr.doob 已提交
278
							} else {
M
r72  
Mr.doob 已提交
279 280 281

								index.push( parseInt( parts[ ind ] ) );

M
r66  
Mr.doob 已提交
282
							}
M
r72  
Mr.doob 已提交
283

M
r66  
Mr.doob 已提交
284
						}
M
r63  
Mr.doob 已提交
285

M
r66  
Mr.doob 已提交
286
					}
M
r63  
Mr.doob 已提交
287

M
r66  
Mr.doob 已提交
288
					// end
M
r72  
Mr.doob 已提交
289 290
					if ( /]/.exec( line ) ) {

M
Mr.doob 已提交
291 292 293 294 295 296 297 298 299
						if ( index.length > 0 ) {

							this.indexes.push( index );

						}

						// start new one
						index = [];

M
r66  
Mr.doob 已提交
300
						this.isRecordingFaces = false;
M
r73  
Mr.doob 已提交
301
						node[this.recordingFieldname] = this.indexes;
M
r72  
Mr.doob 已提交
302

M
r66  
Mr.doob 已提交
303
					}
M
r63  
Mr.doob 已提交
304

M
r72  
Mr.doob 已提交
305 306
				} else if ( this.isRecordingPoints ) {

M
r73  
Mr.doob 已提交
307 308
					if ( node.nodeType == 'Coordinate' )

M
r72  
Mr.doob 已提交
309
					while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
M
r63  
Mr.doob 已提交
310

M
r66  
Mr.doob 已提交
311
						point = {
M
r72  
Mr.doob 已提交
312 313 314
							x: parseFloat( parts[ 1 ] ),
							y: parseFloat( parts[ 2 ] ),
							z: parseFloat( parts[ 3 ] )
M
r66  
Mr.doob 已提交
315
						};
M
r63  
Mr.doob 已提交
316

M
r72  
Mr.doob 已提交
317 318
						this.points.push( point );

M
r66  
Mr.doob 已提交
319
					}
M
r63  
Mr.doob 已提交
320

M
r73  
Mr.doob 已提交
321 322 323 324 325 326 327 328 329 330 331 332 333
					if ( node.nodeType == 'TextureCoordinate' )

					while ( null !== ( parts = float2_pattern.exec( line ) ) ) {

						point = {
							x: parseFloat( parts[ 1 ] ),
							y: parseFloat( parts[ 2 ] )
						};

						this.points.push( point );

					}

M
r66  
Mr.doob 已提交
334
					// end
M
r72  
Mr.doob 已提交
335 336
					if ( /]/.exec( line ) ) {

M
r66  
Mr.doob 已提交
337 338
						this.isRecordingPoints = false;
						node.points = this.points;
M
r72  
Mr.doob 已提交
339

M
r66  
Mr.doob 已提交
340
					}
M
r63  
Mr.doob 已提交
341

M
r66  
Mr.doob 已提交
342
				} else if ( this.isRecordingAngles ) {
M
r63  
Mr.doob 已提交
343

M
r66  
Mr.doob 已提交
344 345
					// the parts hold the angles as strings
					if ( parts.length > 0 ) {
M
r63  
Mr.doob 已提交
346

M
r71  
Mr.doob 已提交
347
						for ( var ind = 0; ind < parts.length; ind ++ ) {
M
r63  
Mr.doob 已提交
348

M
r66  
Mr.doob 已提交
349
							// the part should be a float
M
r72  
Mr.doob 已提交
350 351
							if ( ! float_pattern.test( parts[ ind ] ) ) {

M
r66  
Mr.doob 已提交
352
								continue;
M
r72  
Mr.doob 已提交
353

M
r66  
Mr.doob 已提交
354
							}
M
r63  
Mr.doob 已提交
355

M
r72  
Mr.doob 已提交
356 357
							this.angles.push( parseFloat( parts[ ind ] ) );

M
r66  
Mr.doob 已提交
358
						}
M
r63  
Mr.doob 已提交
359

M
r66  
Mr.doob 已提交
360
					}
M
r63  
Mr.doob 已提交
361

M
r66  
Mr.doob 已提交
362
					// end
M
r72  
Mr.doob 已提交
363 364
					if ( /]/.exec( line ) ) {

M
r66  
Mr.doob 已提交
365
						this.isRecordingAngles = false;
M
r72  
Mr.doob 已提交
366 367
						node[ this.recordingFieldname ] = this.angles;

M
r66  
Mr.doob 已提交
368
					}
M
r63  
Mr.doob 已提交
369

M
r72  
Mr.doob 已提交
370
				} else if ( this.isRecordingColors ) {
M
r63  
Mr.doob 已提交
371

M
r72  
Mr.doob 已提交
372
					while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
M
r63  
Mr.doob 已提交
373

M
r86  
Mr.doob 已提交
374
						var color = {
M
r72  
Mr.doob 已提交
375 376 377
							r: parseFloat( parts[ 1 ] ),
							g: parseFloat( parts[ 2 ] ),
							b: parseFloat( parts[ 3 ] )
M
r66  
Mr.doob 已提交
378
						};
M
r63  
Mr.doob 已提交
379

M
r72  
Mr.doob 已提交
380
						this.colors.push( color );
M
r63  
Mr.doob 已提交
381

M
r66  
Mr.doob 已提交
382
					}
M
r63  
Mr.doob 已提交
383

M
r66  
Mr.doob 已提交
384
					// end
M
r72  
Mr.doob 已提交
385 386
					if ( /]/.exec( line ) ) {

M
r66  
Mr.doob 已提交
387
						this.isRecordingColors = false;
M
r72  
Mr.doob 已提交
388 389
						node[ this.recordingFieldname ] = this.colors;

M
r66  
Mr.doob 已提交
390
					}
M
r63  
Mr.doob 已提交
391

M
r72  
Mr.doob 已提交
392
				} else if ( parts[ parts.length - 1 ] !== 'NULL' && fieldName !== 'children' ) {
M
r63  
Mr.doob 已提交
393

M
r72  
Mr.doob 已提交
394
					switch ( fieldName ) {
M
r63  
Mr.doob 已提交
395

M
r66  
Mr.doob 已提交
396 397 398 399
						case 'diffuseColor':
						case 'emissiveColor':
						case 'specularColor':
						case 'color':
M
r63  
Mr.doob 已提交
400

M
r72  
Mr.doob 已提交
401 402 403
							if ( parts.length != 4 ) {

								console.warn( 'Invalid color format detected for ' + fieldName );
M
r66  
Mr.doob 已提交
404
								break;
M
r72  
Mr.doob 已提交
405

M
r66  
Mr.doob 已提交
406
							}
M
r63  
Mr.doob 已提交
407

M
r66  
Mr.doob 已提交
408
							property = {
M
r72  
Mr.doob 已提交
409 410 411 412
								r: parseFloat( parts[ 1 ] ),
								g: parseFloat( parts[ 2 ] ),
								b: parseFloat( parts[ 3 ] )
							};
M
r63  
Mr.doob 已提交
413

M
r66  
Mr.doob 已提交
414
							break;
M
r86  
Mr.doob 已提交
415

M
r83  
Mr.doob 已提交
416 417
						case 'location':
						case 'direction':
M
r66  
Mr.doob 已提交
418 419 420
						case 'translation':
						case 'scale':
						case 'size':
M
r72  
Mr.doob 已提交
421 422 423
							if ( parts.length != 4 ) {

								console.warn( 'Invalid vector format detected for ' + fieldName );
M
r66  
Mr.doob 已提交
424
								break;
M
r72  
Mr.doob 已提交
425

M
r66  
Mr.doob 已提交
426
							}
M
r63  
Mr.doob 已提交
427

M
r66  
Mr.doob 已提交
428
							property = {
M
r72  
Mr.doob 已提交
429 430 431 432
								x: parseFloat( parts[ 1 ] ),
								y: parseFloat( parts[ 2 ] ),
								z: parseFloat( parts[ 3 ] )
							};
M
r63  
Mr.doob 已提交
433

M
r66  
Mr.doob 已提交
434 435
							break;

M
r86  
Mr.doob 已提交
436
						case 'intensity':
M
r83  
Mr.doob 已提交
437
						case 'cutOffAngle':
M
r66  
Mr.doob 已提交
438 439 440 441 442 443 444
						case 'radius':
						case 'topRadius':
						case 'bottomRadius':
						case 'height':
						case 'transparency':
						case 'shininess':
						case 'ambientIntensity':
M
r72  
Mr.doob 已提交
445 446 447
							if ( parts.length != 2 ) {

								console.warn( 'Invalid single float value specification detected for ' + fieldName );
M
r66  
Mr.doob 已提交
448
								break;
M
r72  
Mr.doob 已提交
449

M
r66  
Mr.doob 已提交
450
							}
M
r63  
Mr.doob 已提交
451

M
r72  
Mr.doob 已提交
452
							property = parseFloat( parts[ 1 ] );
M
r63  
Mr.doob 已提交
453

M
r66  
Mr.doob 已提交
454
							break;
M
r63  
Mr.doob 已提交
455

M
r66  
Mr.doob 已提交
456
						case 'rotation':
M
r72  
Mr.doob 已提交
457 458 459
							if ( parts.length != 5 ) {

								console.warn( 'Invalid quaternion format detected for ' + fieldName );
M
r66  
Mr.doob 已提交
460
								break;
M
r72  
Mr.doob 已提交
461

M
r66  
Mr.doob 已提交
462
							}
M
r63  
Mr.doob 已提交
463

M
r66  
Mr.doob 已提交
464
							property = {
M
r72  
Mr.doob 已提交
465 466 467 468 469
								x: parseFloat( parts[ 1 ] ),
								y: parseFloat( parts[ 2 ] ),
								z: parseFloat( parts[ 3 ] ),
								w: parseFloat( parts[ 4 ] )
							};
M
r63  
Mr.doob 已提交
470

M
r66  
Mr.doob 已提交
471
							break;
M
r86  
Mr.doob 已提交
472

M
r83  
Mr.doob 已提交
473
						case 'on':
M
r66  
Mr.doob 已提交
474 475 476 477
						case 'ccw':
						case 'solid':
						case 'colorPerVertex':
						case 'convex':
M
r72  
Mr.doob 已提交
478 479 480
							if ( parts.length != 2 ) {

								console.warn( 'Invalid format detected for ' + fieldName );
M
r66  
Mr.doob 已提交
481
								break;
M
r72  
Mr.doob 已提交
482

M
r66  
Mr.doob 已提交
483
							}
M
r63  
Mr.doob 已提交
484

M
r72  
Mr.doob 已提交
485
							property = parts[ 1 ] === 'TRUE' ? true : false;
M
r63  
Mr.doob 已提交
486

M
r66  
Mr.doob 已提交
487 488
							break;
					}
M
r63  
Mr.doob 已提交
489

M
r72  
Mr.doob 已提交
490 491
					node[ fieldName ] = property;

M
r66  
Mr.doob 已提交
492
				}
M
r63  
Mr.doob 已提交
493

M
r66  
Mr.doob 已提交
494
				return property;
M
r72  
Mr.doob 已提交
495

M
r66  
Mr.doob 已提交
496
			};
M
r59  
Mr.doob 已提交
497 498 499 500 501

			var getTree = function ( lines ) {

				var tree = { 'string': 'Scene', children: [] };
				var current = tree;
M
r66  
Mr.doob 已提交
502 503
				var matches;
				var specification;
M
r59  
Mr.doob 已提交
504 505 506

				for ( var i = 0; i < lines.length; i ++ ) {

M
r66  
Mr.doob 已提交
507
					var comment = '';
M
r62  
Mr.doob 已提交
508

M
r59  
Mr.doob 已提交
509 510
					var line = lines[ i ];

M
r66  
Mr.doob 已提交
511 512
					// omit whitespace only lines
					if ( null !== ( result = /^\s+?$/g.exec( line ) ) ) {
M
r72  
Mr.doob 已提交
513

M
r66  
Mr.doob 已提交
514
						continue;
M
r72  
Mr.doob 已提交
515

M
r66  
Mr.doob 已提交
516
					}
M
r62  
Mr.doob 已提交
517

M
r66  
Mr.doob 已提交
518
					line = line.trim();
M
r63  
Mr.doob 已提交
519

M
r66  
Mr.doob 已提交
520
					// skip empty lines
M
r72  
Mr.doob 已提交
521 522
					if ( line === '' ) {

M
r66  
Mr.doob 已提交
523
						continue;
M
r72  
Mr.doob 已提交
524

M
r66  
Mr.doob 已提交
525
					}
M
r63  
Mr.doob 已提交
526

M
r62  
Mr.doob 已提交
527 528
					if ( /#/.exec( line ) ) {

M
r72  
Mr.doob 已提交
529
						var parts = line.split( '#' );
M
r59  
Mr.doob 已提交
530

M
r66  
Mr.doob 已提交
531
						// discard everything after the #, it is a comment
M
r72  
Mr.doob 已提交
532
						line = parts[ 0 ];
M
r59  
Mr.doob 已提交
533

M
r66  
Mr.doob 已提交
534
						// well, let's also keep the comment
M
r72  
Mr.doob 已提交
535 536
						comment = parts[ 1 ];

M
r62  
Mr.doob 已提交
537
					}
M
r63  
Mr.doob 已提交
538

M
r73  
Mr.doob 已提交
539
					if ( matches = /([^\s]*){1}(?:\s+)?{/.exec( line ) ) {
M
r59  
Mr.doob 已提交
540

M
r72  
Mr.doob 已提交
541 542 543
						// first subpattern should match the Node name

						var block = { 'nodeType' : matches[ 1 ], 'string': line, 'parent': current, 'children': [], 'comment' : comment };
M
r59  
Mr.doob 已提交
544 545 546 547
						current.children.push( block );
						current = block;

						if ( /}/.exec( line ) ) {
M
r72  
Mr.doob 已提交
548

M
r66  
Mr.doob 已提交
549 550
							// example: geometry Box { size 1 1 1 } # all on the same line
							specification = /{(.*)}/.exec( line )[ 1 ];
M
r63  
Mr.doob 已提交
551

M
r66  
Mr.doob 已提交
552
							// todo: remove once new parsing is complete?
M
r63  
Mr.doob 已提交
553 554
							block.children.push( specification );

M
r72  
Mr.doob 已提交
555
							parseProperty( current, specification );
M
r59  
Mr.doob 已提交
556 557 558 559 560 561 562 563 564 565 566

							current = current.parent;

						}

					} else if ( /}/.exec( line ) ) {

						current = current.parent;

					} else if ( line !== '' ) {

M
r72  
Mr.doob 已提交
567
						parseProperty( current, line );
M
r66  
Mr.doob 已提交
568 569
						// todo: remove once new parsing is complete? we still do not parse geometry and appearance the new way
						current.children.push( line );
M
r59  
Mr.doob 已提交
570 571 572 573 574

					}

				}

M
r66  
Mr.doob 已提交
575
				return tree;
M
r72  
Mr.doob 已提交
576 577

			};
M
r59  
Mr.doob 已提交
578 579 580 581 582 583 584 585 586

			var parseNode = function ( data, parent ) {

				// console.log( data );

				if ( typeof data === 'string' ) {

					if ( /USE/.exec( data ) ) {

M
r75  
Mr.doob 已提交
587
						var defineKey = /USE\s+?([^\s]+)/.exec( data )[ 1 ];
M
r59  
Mr.doob 已提交
588

M
r72  
Mr.doob 已提交
589 590 591 592
						if ( undefined == defines[ defineKey ] ) {

							console.warn( defineKey + ' is not defined.' );

M
r66  
Mr.doob 已提交
593
						} else {
M
r59  
Mr.doob 已提交
594

M
r66  
Mr.doob 已提交
595
							if ( /appearance/.exec( data ) && defineKey ) {
M
r59  
Mr.doob 已提交
596

M
r66  
Mr.doob 已提交
597
								parent.material = defines[ defineKey ].clone();
M
r62  
Mr.doob 已提交
598

M
r66  
Mr.doob 已提交
599
							} else if ( /geometry/.exec( data ) && defineKey ) {
M
r62  
Mr.doob 已提交
600

M
r66  
Mr.doob 已提交
601
								parent.geometry = defines[ defineKey ].clone();
M
r63  
Mr.doob 已提交
602

M
r66  
Mr.doob 已提交
603
								// the solid property is not cloned with clone(), is only needed for VRML loading, so we need to transfer it
M
r72  
Mr.doob 已提交
604 605
								if ( undefined !== defines[ defineKey ].solid && defines[ defineKey ].solid === false ) {

M
r66  
Mr.doob 已提交
606 607
									parent.geometry.solid = false;
									parent.material.side = THREE.DoubleSide;
M
r72  
Mr.doob 已提交
608

M
r66  
Mr.doob 已提交
609
								}
M
r62  
Mr.doob 已提交
610

M
r72  
Mr.doob 已提交
611
							} else if ( defineKey ) {
M
r63  
Mr.doob 已提交
612

M
r66  
Mr.doob 已提交
613 614
								var object = defines[ defineKey ].clone();
								parent.add( object );
M
r62  
Mr.doob 已提交
615

M
r66  
Mr.doob 已提交
616
							}
M
r62  
Mr.doob 已提交
617

M
r66  
Mr.doob 已提交
618
						}
M
r59  
Mr.doob 已提交
619 620 621 622 623 624 625 626 627

					}

					return;

				}

				var object = parent;

M
r83  
Mr.doob 已提交
628
				if(data.string.indexOf("AmbientLight")>-1 && data.nodeType=='PointLight'){
M
r86  
Mr.doob 已提交
629
					//wenn im Namen "AmbientLight" vorkommt und es ein PointLight ist,
M
r83  
Mr.doob 已提交
630
					//diesen Typ in 'AmbientLight' ändern
M
r86  
Mr.doob 已提交
631
					data.nodeType='AmbientLight';
M
r83  
Mr.doob 已提交
632
				}
M
r86  
Mr.doob 已提交
633 634 635 636 637 638

				var l_visible = data.on !== undefined ? data.on : true;
				var l_intensity = data.intensity !== undefined ? data.intensity : 1;
				var l_color = new THREE.Color();
				if ( data.color ) l_color.copy( data.color );

M
r83  
Mr.doob 已提交
639
				if('AmbientLight' === data.nodeType){
M
r86  
Mr.doob 已提交
640 641
					object=new THREE.AmbientLight(
								l_color.getHex(),
M
r83  
Mr.doob 已提交
642 643 644
								l_intensity
								);
					object.visible=l_visible;
M
r86  
Mr.doob 已提交
645

M
r83  
Mr.doob 已提交
646
					parent.add( object );
M
r86  
Mr.doob 已提交
647

M
r83  
Mr.doob 已提交
648 649 650
				}
				else
				if('PointLight' === data.nodeType){
M
r86  
Mr.doob 已提交
651 652
						var l_distance =0;	//0="unendlich" ...1000

M
r83  
Mr.doob 已提交
653 654 655 656
						if(data.radius!=undefined && data.radius<1000){
							//l_radius=data.radius;
							l_distance=data.radius;
						}
M
r86  
Mr.doob 已提交
657 658 659
						object=new THREE.PointLight(
								l_color.getHex(),
								l_intensity,
M
r83  
Mr.doob 已提交
660 661
								l_distance);
						object.visible=l_visible;
M
r86  
Mr.doob 已提交
662

M
r83  
Mr.doob 已提交
663 664 665
						parent.add( object );
				}
				else
M
r86  
Mr.doob 已提交
666 667 668 669 670 671 672
				if('SpotLight' === data.nodeType){
						var l_intensity=1;
						var l_distance =0;//0="unendlich"=1000
						var l_angle=Math.PI/3;
						var l_penumbra=0.0;//0..1
						var l_visible=true;

M
r83  
Mr.doob 已提交
673 674 675 676 677
						if(data.radius!=undefined && data.radius<1000){
							//l_radius=data.radius;
							l_distance=data.radius;
						}
						if(data.cutOffAngle!=undefined)l_angle=data.cutOffAngle;
M
r86  
Mr.doob 已提交
678

M
r83  
Mr.doob 已提交
679 680 681 682 683
						object = new THREE.SpotLight(
									l_color.getHex(),
									l_intensity,
									l_distance,
									l_angle,
M
r86  
Mr.doob 已提交
684
									l_penumbra
M
r83  
Mr.doob 已提交
685
									);
M
r86  
Mr.doob 已提交
686
						object.visible=l_visible;
M
r83  
Mr.doob 已提交
687 688 689 690 691 692 693
						parent.add( object );
						/*
						var lightHelper = new THREE.SpotLightHelper( object );
						parent.parent.add( lightHelper );
						lightHelper.update();
						*/
				}
M
r86  
Mr.doob 已提交
694 695
				else

M
r63  
Mr.doob 已提交
696 697
				if ( 'Transform' === data.nodeType || 'Group' === data.nodeType ) {

M
r59  
Mr.doob 已提交
698 699 700
					object = new THREE.Object3D();

					if ( /DEF/.exec( data.string ) ) {
M
r72  
Mr.doob 已提交
701

M
r75  
Mr.doob 已提交
702
						object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
M
r59  
Mr.doob 已提交
703
						defines[ object.name ] = object;
M
r72  
Mr.doob 已提交
704

M
r59  
Mr.doob 已提交
705 706
					}

M
r72  
Mr.doob 已提交
707
					if ( undefined !== data[ 'translation' ] ) {
M
r59  
Mr.doob 已提交
708

M
r66  
Mr.doob 已提交
709
						var t = data.translation;
M
r59  
Mr.doob 已提交
710

M
r72  
Mr.doob 已提交
711
						object.position.set( t.x, t.y, t.z );
M
r59  
Mr.doob 已提交
712

M
r66  
Mr.doob 已提交
713
					}
M
r59  
Mr.doob 已提交
714

M
r66  
Mr.doob 已提交
715
					if ( undefined !== data.rotation ) {
M
r59  
Mr.doob 已提交
716

M
r66  
Mr.doob 已提交
717
						var r = data.rotation;
M
r59  
Mr.doob 已提交
718

M
r66  
Mr.doob 已提交
719
						object.quaternion.setFromAxisAngle( new THREE.Vector3( r.x, r.y, r.z ), r.w );
M
r62  
Mr.doob 已提交
720

M
r66  
Mr.doob 已提交
721
					}
M
r59  
Mr.doob 已提交
722

M
r66  
Mr.doob 已提交
723
					if ( undefined !== data.scale ) {
M
r59  
Mr.doob 已提交
724

M
r66  
Mr.doob 已提交
725
						var s = data.scale;
M
r59  
Mr.doob 已提交
726

M
r66  
Mr.doob 已提交
727
						object.scale.set( s.x, s.y, s.z );
M
r59  
Mr.doob 已提交
728

M
r66  
Mr.doob 已提交
729
					}
M
r59  
Mr.doob 已提交
730 731 732

					parent.add( object );

M
r63  
Mr.doob 已提交
733
				} else if ( 'Shape' === data.nodeType ) {
M
r59  
Mr.doob 已提交
734 735 736 737

					object = new THREE.Mesh();

					if ( /DEF/.exec( data.string ) ) {
M
r63  
Mr.doob 已提交
738

M
r75  
Mr.doob 已提交
739
						object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
M
r63  
Mr.doob 已提交
740

M
r59  
Mr.doob 已提交
741
						defines[ object.name ] = object;
M
r72  
Mr.doob 已提交
742

M
r59  
Mr.doob 已提交
743 744 745 746
					}

					parent.add( object );

M
r63  
Mr.doob 已提交
747
				} else if ( 'Background' === data.nodeType ) {
M
r59  
Mr.doob 已提交
748

M
r66  
Mr.doob 已提交
749
					var segments = 20;
M
r59  
Mr.doob 已提交
750

M
r66  
Mr.doob 已提交
751
					// sky (full sphere):
M
r69  
Mr.doob 已提交
752

M
r66  
Mr.doob 已提交
753
					var radius = 2e4;
M
r59  
Mr.doob 已提交
754

M
r66  
Mr.doob 已提交
755
					var skyGeometry = new THREE.SphereGeometry( radius, segments, segments );
M
r69  
Mr.doob 已提交
756
					var skyMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide } );
M
r59  
Mr.doob 已提交
757

M
r69  
Mr.doob 已提交
758
					if ( data.skyColor.length > 1 ) {
M
r59  
Mr.doob 已提交
759

M
r69  
Mr.doob 已提交
760
						paintFaces( skyGeometry, radius, data.skyAngle, data.skyColor, true );
M
r59  
Mr.doob 已提交
761

M
r69  
Mr.doob 已提交
762
						skyMaterial.vertexColors = THREE.VertexColors
M
r59  
Mr.doob 已提交
763

M
r69  
Mr.doob 已提交
764
					} else {
M
r59  
Mr.doob 已提交
765

M
r69  
Mr.doob 已提交
766 767
						var color = data.skyColor[ 0 ];
						skyMaterial.color.setRGB( color.r, color.b, color.g );
M
r59  
Mr.doob 已提交
768

M
r69  
Mr.doob 已提交
769
					}
M
r59  
Mr.doob 已提交
770

M
r69  
Mr.doob 已提交
771
					scene.add( new THREE.Mesh( skyGeometry, skyMaterial ) );
M
r59  
Mr.doob 已提交
772

M
r66  
Mr.doob 已提交
773
					// ground (half sphere):
M
r59  
Mr.doob 已提交
774

M
r69  
Mr.doob 已提交
775
					if ( data.groundColor !== undefined ) {
M
r59  
Mr.doob 已提交
776

M
r69  
Mr.doob 已提交
777
						radius = 1.2e4;
M
r59  
Mr.doob 已提交
778

M
r69  
Mr.doob 已提交
779 780
						var groundGeometry = new THREE.SphereGeometry( radius, segments, segments, 0, 2 * Math.PI, 0.5 * Math.PI, 1.5 * Math.PI );
						var groundMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide, vertexColors: THREE.VertexColors } );
M
r59  
Mr.doob 已提交
781

M
r69  
Mr.doob 已提交
782
						paintFaces( groundGeometry, radius, data.groundAngle, data.groundColor, false );
M
r59  
Mr.doob 已提交
783

M
r69  
Mr.doob 已提交
784
						scene.add( new THREE.Mesh( groundGeometry, groundMaterial ) );
M
r59  
Mr.doob 已提交
785

M
r69  
Mr.doob 已提交
786
					}
M
r59  
Mr.doob 已提交
787

M
r63  
Mr.doob 已提交
788
				} else if ( /geometry/.exec( data.string ) ) {
M
r59  
Mr.doob 已提交
789

M
r63  
Mr.doob 已提交
790
					if ( 'Box' === data.nodeType ) {
M
r59  
Mr.doob 已提交
791

M
r66  
Mr.doob 已提交
792
						var s = data.size;
M
r59  
Mr.doob 已提交
793

M
r66  
Mr.doob 已提交
794
						parent.geometry = new THREE.BoxGeometry( s.x, s.y, s.z );
M
r59  
Mr.doob 已提交
795

M
r63  
Mr.doob 已提交
796
					} else if ( 'Cylinder' === data.nodeType ) {
M
r59  
Mr.doob 已提交
797

M
r63  
Mr.doob 已提交
798
						parent.geometry = new THREE.CylinderGeometry( data.radius, data.radius, data.height );
M
r59  
Mr.doob 已提交
799

M
r63  
Mr.doob 已提交
800
					} else if ( 'Cone' === data.nodeType ) {
M
r59  
Mr.doob 已提交
801

M
r63  
Mr.doob 已提交
802
						parent.geometry = new THREE.CylinderGeometry( data.topRadius, data.bottomRadius, data.height );
M
r59  
Mr.doob 已提交
803

M
r63  
Mr.doob 已提交
804
					} else if ( 'Sphere' === data.nodeType ) {
M
r59  
Mr.doob 已提交
805

M
r63  
Mr.doob 已提交
806
						parent.geometry = new THREE.SphereGeometry( data.radius );
M
r59  
Mr.doob 已提交
807

M
r63  
Mr.doob 已提交
808
					} else if ( 'IndexedFaceSet' === data.nodeType ) {
M
r62  
Mr.doob 已提交
809

M
r66  
Mr.doob 已提交
810
						var geometry = new THREE.Geometry();
M
r62  
Mr.doob 已提交
811

M
r73  
Mr.doob 已提交
812
						var indexes, uvIndexes, uvs;
M
r62  
Mr.doob 已提交
813

M
r71  
Mr.doob 已提交
814
						for ( var i = 0, j = data.children.length; i < j; i ++ ) {
M
r62  
Mr.doob 已提交
815

M
r66  
Mr.doob 已提交
816
							var child = data.children[ i ];
M
r62  
Mr.doob 已提交
817

M
r66  
Mr.doob 已提交
818
							var vec;
M
r62  
Mr.doob 已提交
819

M
r73  
Mr.doob 已提交
820 821 822 823 824 825 826
							if ( 'TextureCoordinate' === child.nodeType ) {

								uvs = child.points;

							}


M
r66  
Mr.doob 已提交
827
							if ( 'Coordinate' === child.nodeType ) {
M
r62  
Mr.doob 已提交
828

M
r73  
Mr.doob 已提交
829 830 831
								if ( child.points ) {

									for ( var k = 0, l = child.points.length; k < l; k ++ ) {
M
r62  
Mr.doob 已提交
832

M
r73  
Mr.doob 已提交
833
										var point = child.points[ k ];
M
r62  
Mr.doob 已提交
834

M
r73  
Mr.doob 已提交
835
										vec = new THREE.Vector3( point.x, point.y, point.z );
M
r62  
Mr.doob 已提交
836

M
r73  
Mr.doob 已提交
837 838 839
										geometry.vertices.push( vec );

									}
M
r72  
Mr.doob 已提交
840

M
r66  
Mr.doob 已提交
841
								}
M
r62  
Mr.doob 已提交
842

M
r73  
Mr.doob 已提交
843
								if ( child.string.indexOf ( 'DEF' ) > -1 ) {
M
r72  
Mr.doob 已提交
844

M
r75  
Mr.doob 已提交
845
									var name = /DEF\s+([^\s]+)/.exec( child.string )[ 1 ];
M
r72  
Mr.doob 已提交
846

M
r73  
Mr.doob 已提交
847
									defines[ name ] = geometry.vertices;
M
r62  
Mr.doob 已提交
848

M
r73  
Mr.doob 已提交
849 850 851
								}

								if ( child.string.indexOf ( 'USE' ) > -1 ) {
M
r63  
Mr.doob 已提交
852

M
r75  
Mr.doob 已提交
853
									var defineKey = /USE\s+([^\s]+)/.exec( child.string )[ 1 ];
M
r62  
Mr.doob 已提交
854

M
r73  
Mr.doob 已提交
855 856
									geometry.vertices = defines[ defineKey ];
								}
M
r62  
Mr.doob 已提交
857

M
r73  
Mr.doob 已提交
858
							}
M
r62  
Mr.doob 已提交
859

M
r73  
Mr.doob 已提交
860
						}
M
r62  
Mr.doob 已提交
861

M
r73  
Mr.doob 已提交
862
						var skip = 0;
M
r62  
Mr.doob 已提交
863

M
r73  
Mr.doob 已提交
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
						// 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 ]; 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;

								// 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 + (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 );
M
r63  
Mr.doob 已提交
906

M
r73  
Mr.doob 已提交
907
								}
M
r63  
Mr.doob 已提交
908

M
r62  
Mr.doob 已提交
909

M
r66  
Mr.doob 已提交
910
							}
M
r62  
Mr.doob 已提交
911

M
r73  
Mr.doob 已提交
912 913 914 915
						} else {

							// do not add dummy mesh to the scene
							parent.parent.remove( parent );
M
r62  
Mr.doob 已提交
916

M
r66  
Mr.doob 已提交
917
						}
M
r62  
Mr.doob 已提交
918

M
r66  
Mr.doob 已提交
919
						if ( false === data.solid ) {
M
r72  
Mr.doob 已提交
920

M
r66  
Mr.doob 已提交
921
							parent.material.side = THREE.DoubleSide;
M
r72  
Mr.doob 已提交
922

M
r66  
Mr.doob 已提交
923
						}
M
r63  
Mr.doob 已提交
924

M
r66  
Mr.doob 已提交
925 926
						// we need to store it on the geometry for use with defines
						geometry.solid = data.solid;
M
r63  
Mr.doob 已提交
927

M
r66  
Mr.doob 已提交
928 929 930
						geometry.computeFaceNormals();
						//geometry.computeVertexNormals(); // does not show
						geometry.computeBoundingSphere();
M
r62  
Mr.doob 已提交
931

M
r66  
Mr.doob 已提交
932 933
						// see if it's a define
						if ( /DEF/.exec( data.string ) ) {
M
r72  
Mr.doob 已提交
934

M
r75  
Mr.doob 已提交
935
							geometry.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
M
r66  
Mr.doob 已提交
936
							defines[ geometry.name ] = geometry;
M
r72  
Mr.doob 已提交
937

M
r66  
Mr.doob 已提交
938
						}
M
r62  
Mr.doob 已提交
939

M
r66  
Mr.doob 已提交
940
						parent.geometry = geometry;
M
r72  
Mr.doob 已提交
941

M
r59  
Mr.doob 已提交
942 943 944 945 946 947 948 949 950 951
					}

					return;

				} else if ( /appearance/.exec( data.string ) ) {

					for ( var i = 0; i < data.children.length; i ++ ) {

						var child = data.children[ i ];

M
r63  
Mr.doob 已提交
952
						if ( 'Material' === child.nodeType ) {
M
r72  
Mr.doob 已提交
953

M
r59  
Mr.doob 已提交
954 955
							var material = new THREE.MeshPhongMaterial();

M
r66  
Mr.doob 已提交
956
							if ( undefined !== child.diffuseColor ) {
M
r59  
Mr.doob 已提交
957

M
r66  
Mr.doob 已提交
958
								var d = child.diffuseColor;
M
r59  
Mr.doob 已提交
959

M
r66  
Mr.doob 已提交
960
								material.color.setRGB( d.r, d.g, d.b );
M
r59  
Mr.doob 已提交
961

M
r66  
Mr.doob 已提交
962
							}
M
r59  
Mr.doob 已提交
963

M
r66  
Mr.doob 已提交
964
							if ( undefined !== child.emissiveColor ) {
M
r59  
Mr.doob 已提交
965

M
r66  
Mr.doob 已提交
966
								var e = child.emissiveColor;
M
r59  
Mr.doob 已提交
967

M
r66  
Mr.doob 已提交
968
								material.emissive.setRGB( e.r, e.g, e.b );
M
r59  
Mr.doob 已提交
969

M
r66  
Mr.doob 已提交
970
							}
M
r59  
Mr.doob 已提交
971

M
r66  
Mr.doob 已提交
972
							if ( undefined !== child.specularColor ) {
M
r59  
Mr.doob 已提交
973

M
r66  
Mr.doob 已提交
974
								var s = child.specularColor;
M
r59  
Mr.doob 已提交
975

M
r66  
Mr.doob 已提交
976
								material.specular.setRGB( s.r, s.g, s.b );
M
r59  
Mr.doob 已提交
977

M
r66  
Mr.doob 已提交
978
							}
M
r59  
Mr.doob 已提交
979

M
r66  
Mr.doob 已提交
980
							if ( undefined !== child.transparency ) {
M
r59  
Mr.doob 已提交
981

M
r66  
Mr.doob 已提交
982
								var t = child.transparency;
M
r59  
Mr.doob 已提交
983

M
r66  
Mr.doob 已提交
984 985
								// transparency is opposite of opacity
								material.opacity = Math.abs( 1 - t );
M
r63  
Mr.doob 已提交
986

M
r66  
Mr.doob 已提交
987
								material.transparent = true;
M
r63  
Mr.doob 已提交
988

M
r66  
Mr.doob 已提交
989
							}
M
r59  
Mr.doob 已提交
990 991 992

							if ( /DEF/.exec( data.string ) ) {

M
r75  
Mr.doob 已提交
993
								material.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
M
r62  
Mr.doob 已提交
994

M
r59  
Mr.doob 已提交
995 996 997 998 999 1000
								defines[ material.name ] = material;

							}

							parent.material = material;

M
r73  
Mr.doob 已提交
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
						}

						if ( 'ImageTexture' === child.nodeType ) {

							var textureName = /"([^"]+)"/.exec(child.children[ 0 ]);

							if (textureName) {

								parent.material.name = textureName[ 1 ];

M
r74  
Mr.doob 已提交
1011
								parent.material.map = textureLoader.load( texturePath + textureName[ 1 ] );
M
r73  
Mr.doob 已提交
1012 1013

							}
M
r72  
Mr.doob 已提交
1014

M
r59  
Mr.doob 已提交
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
						}

					}

					return;

				}

				for ( var i = 0, l = data.children.length; i < l; i ++ ) {

					parseNode( data.children[ i ], object );

				}

M
r72  
Mr.doob 已提交
1029
			};
M
r59  
Mr.doob 已提交
1030 1031 1032 1033 1034 1035 1036 1037

			parseNode( getTree( lines ), scene );

		};

		var scene = new THREE.Scene();

		var lines = data.split( '\n' );
M
r63  
Mr.doob 已提交
1038

M
r73  
Mr.doob 已提交
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
		// 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 {}';
			}
		}

M
r59  
Mr.doob 已提交
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
		var header = lines.shift();

		if ( /V1.0/.exec( header ) ) {

			parseV1( lines, scene );

		} else if ( /V2.0/.exec( header ) ) {

			parseV2( lines, scene );

		}

		return scene;

	}

};