/ examples / bno055_webgl_demo / static / js / OBJLoader.js
OBJLoader.js
  1  /**
  2   * @author mrdoob / http://mrdoob.com/
  3   */
  4  
  5  THREE.OBJLoader = function ( manager ) {
  6  
  7  	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
  8  
  9  };
 10  
 11  THREE.OBJLoader.prototype = {
 12  
 13  	constructor: THREE.OBJLoader,
 14  
 15  	load: function ( url, onLoad, onProgress, onError ) {
 16  
 17  		var scope = this;
 18  
 19  		var loader = new THREE.XHRLoader( scope.manager );
 20  		loader.setCrossOrigin( this.crossOrigin );
 21  		loader.load( url, function ( text ) {
 22  
 23  			onLoad( scope.parse( text ) );
 24  
 25  		}, onProgress, onError );
 26  
 27  	},
 28  
 29  	parse: function ( text ) {
 30  
 31  		console.time( 'OBJLoader' );
 32  
 33  		var object, objects = [];
 34  		var geometry, material;
 35  
 36  		function parseVertexIndex( value ) {
 37  
 38  			var index = parseInt( value );
 39  
 40  			return ( index >= 0 ? index - 1 : index + vertices.length / 3 ) * 3;
 41  
 42  		}
 43  
 44  		function parseNormalIndex( value ) {
 45  
 46  			var index = parseInt( value );
 47  
 48  			return ( index >= 0 ? index - 1 : index + normals.length / 3 ) * 3;
 49  
 50  		}
 51  
 52  		function parseUVIndex( value ) {
 53  
 54  			var index = parseInt( value );
 55  
 56  			return ( index >= 0 ? index - 1 : index + uvs.length / 2 ) * 2;
 57  
 58  		}
 59  
 60  		function addVertex( a, b, c ) {
 61  
 62  			geometry.vertices.push(
 63  				vertices[ a ], vertices[ a + 1 ], vertices[ a + 2 ],
 64  				vertices[ b ], vertices[ b + 1 ], vertices[ b + 2 ],
 65  				vertices[ c ], vertices[ c + 1 ], vertices[ c + 2 ]
 66  			);
 67  
 68  		}
 69  
 70  		function addNormal( a, b, c ) {
 71  
 72  			geometry.normals.push(
 73  				normals[ a ], normals[ a + 1 ], normals[ a + 2 ],
 74  				normals[ b ], normals[ b + 1 ], normals[ b + 2 ],
 75  				normals[ c ], normals[ c + 1 ], normals[ c + 2 ]
 76  			);
 77  
 78  		}
 79  
 80  		function addUV( a, b, c ) {
 81  
 82  			geometry.uvs.push(
 83  				uvs[ a ], uvs[ a + 1 ],
 84  				uvs[ b ], uvs[ b + 1 ],
 85  				uvs[ c ], uvs[ c + 1 ]
 86  			);
 87  
 88  		}
 89  
 90  		function addFace( a, b, c, d,  ua, ub, uc, ud, na, nb, nc, nd ) {
 91  
 92  			var ia = parseVertexIndex( a );
 93  			var ib = parseVertexIndex( b );
 94  			var ic = parseVertexIndex( c );
 95  			var id;
 96  
 97  			if ( d === undefined ) {
 98  
 99  				addVertex( ia, ib, ic );
100  
101  			} else {
102  
103  				id = parseVertexIndex( d );
104  
105  				addVertex( ia, ib, id );
106  				addVertex( ib, ic, id );
107  
108  			}
109  
110  			if ( ua !== undefined ) {
111  
112  				ia = parseUVIndex( ua );
113  				ib = parseUVIndex( ub );
114  				ic = parseUVIndex( uc );
115  
116  				if ( d === undefined ) {
117  
118  					addUV( ia, ib, ic );
119  
120  				} else {
121  
122  					id = parseUVIndex( ud );
123  
124  					addUV( ia, ib, id );
125  					addUV( ib, ic, id );
126  
127  				}
128  
129  			}
130  
131  			if ( na !== undefined ) {
132  
133  				ia = parseNormalIndex( na );
134  				ib = parseNormalIndex( nb );
135  				ic = parseNormalIndex( nc );
136  
137  				if ( d === undefined ) {
138  
139  					addNormal( ia, ib, ic );
140  
141  				} else {
142  
143  					id = parseNormalIndex( nd );
144  
145  					addNormal( ia, ib, id );
146  					addNormal( ib, ic, id );
147  
148  				}
149  
150  			}
151  
152  		}
153  
154  		// create mesh if no objects in text
155  
156  		if ( /^o /gm.test( text ) === false ) {
157  
158  			geometry = {
159  				vertices: [],
160  				normals: [],
161  				uvs: []
162  			};
163  
164  			material = {
165  				name: ''
166  			};
167  
168  			object = {
169  				name: '',
170  				geometry: geometry,
171  				material: material
172  			};
173  
174  			objects.push( object );
175  
176  		}
177  
178  		var vertices = [];
179  		var normals = [];
180  		var uvs = [];
181  
182  		// v float float float
183  
184  		var vertex_pattern = /v( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/;
185  
186  		// vn float float float
187  
188  		var normal_pattern = /vn( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/;
189  
190  		// vt float float
191  
192  		var uv_pattern = /vt( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/;
193  
194  		// f vertex vertex vertex ...
195  
196  		var face_pattern1 = /f( +-?\d+)( +-?\d+)( +-?\d+)( +-?\d+)?/;
197  
198  		// f vertex/uv vertex/uv vertex/uv ...
199  
200  		var face_pattern2 = /f( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))?/;
201  
202  		// f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
203  
204  		var face_pattern3 = /f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?/;
205  
206  		// f vertex//normal vertex//normal vertex//normal ...
207  
208  		var face_pattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/
209  
210  		//
211  
212  		var lines = text.split( '\n' );
213  
214  		for ( var i = 0; i < lines.length; i ++ ) {
215  
216  			var line = lines[ i ];
217  			line = line.trim();
218  
219  			var result;
220  
221  			if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
222  
223  				continue;
224  
225  			} else if ( ( result = vertex_pattern.exec( line ) ) !== null ) {
226  
227  				// ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
228  
229  				vertices.push(
230  					parseFloat( result[ 1 ] ),
231  					parseFloat( result[ 2 ] ),
232  					parseFloat( result[ 3 ] )
233  				);
234  
235  			} else if ( ( result = normal_pattern.exec( line ) ) !== null ) {
236  
237  				// ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
238  
239  				normals.push(
240  					parseFloat( result[ 1 ] ),
241  					parseFloat( result[ 2 ] ),
242  					parseFloat( result[ 3 ] )
243  				);
244  
245  			} else if ( ( result = uv_pattern.exec( line ) ) !== null ) {
246  
247  				// ["vt 0.1 0.2", "0.1", "0.2"]
248  
249  				uvs.push(
250  					parseFloat( result[ 1 ] ),
251  					parseFloat( result[ 2 ] )
252  				);
253  
254  			} else if ( ( result = face_pattern1.exec( line ) ) !== null ) {
255  
256  				// ["f 1 2 3", "1", "2", "3", undefined]
257  
258  				addFace(
259  					result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ]
260  				);
261  
262  			} else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
263  
264  				// ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
265  
266  				addFace(
267  					result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
268  					result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
269  				);
270  
271  			} else if ( ( result = face_pattern3.exec( line ) ) !== null ) {
272  
273  				// ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
274  
275  				addFace(
276  					result[ 2 ], result[ 6 ], result[ 10 ], result[ 14 ],
277  					result[ 3 ], result[ 7 ], result[ 11 ], result[ 15 ],
278  					result[ 4 ], result[ 8 ], result[ 12 ], result[ 16 ]
279  				);
280  
281  			} else if ( ( result = face_pattern4.exec( line ) ) !== null ) {
282  
283  				// ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
284  
285  				addFace(
286  					result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
287  					undefined, undefined, undefined, undefined,
288  					result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
289  				);
290  
291  			} else if ( /^o /.test( line ) ) {
292  
293  				geometry = {
294  					vertices: [],
295  					normals: [],
296  					uvs: []
297  				};
298  
299  				material = {
300  					name: ''
301  				};
302  
303  				object = {
304  					name: line.substring( 2 ).trim(),
305  					geometry: geometry,
306  					material: material
307  				};
308  
309  				objects.push( object )
310  
311  			} else if ( /^g /.test( line ) ) {
312  
313  				// group
314  
315  			} else if ( /^usemtl /.test( line ) ) {
316  
317  				// material
318  
319  				material.name = line.substring( 7 ).trim();
320  
321  			} else if ( /^mtllib /.test( line ) ) {
322  
323  				// mtl file
324  
325  			} else if ( /^s /.test( line ) ) {
326  
327  				// smooth shading
328  
329  			} else {
330  
331  				// console.log( "THREE.OBJLoader: Unhandled line " + line );
332  
333  			}
334  
335  		}
336  
337  		var container = new THREE.Object3D();
338  
339  		for ( var i = 0, l = objects.length; i < l; i ++ ) {
340  
341  			object = objects[ i ];
342  			geometry = object.geometry;
343  
344  			var buffergeometry = new THREE.BufferGeometry();
345  
346  			buffergeometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( geometry.vertices ), 3 ) );
347  
348  			if ( geometry.normals.length > 0 ) {
349  				buffergeometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( geometry.normals ), 3 ) );
350  			}
351  
352  			if ( geometry.uvs.length > 0 ) {
353  				buffergeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( geometry.uvs ), 2 ) );
354  			}
355  
356  			material = new THREE.MeshLambertMaterial();
357  			material.name = object.material.name;
358  
359  			var mesh = new THREE.Mesh( buffergeometry, material );
360  			mesh.name = object.name;
361  
362  			container.add( mesh );
363  
364  		}
365  
366  		console.timeEnd( 'OBJLoader' );
367  
368  		return container;
369  
370  	}
371  
372  };