1 /**
  2  * @author alteredq / http://alteredqualia.com/
  3  */
  4 
  5 /**@constructor*/
  6 THREE.BinaryLoader = function ( showStatus ) {
  7 
  8 	THREE.Loader.call( this, showStatus );
  9 
 10 };
 11 
 12 THREE.BinaryLoader.prototype = Object.create( THREE.Loader.prototype );
 13 
 14 // Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
 15 //  - binary models consist of two files: JS and BIN
 16 //  - parameters
 17 //		- url (required)
 18 //		- callback (required)
 19 //		- texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
 20 //		- binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
 21 
 22 THREE.BinaryLoader.prototype.load = function( url, callback, texturePath, binaryPath ) {
 23 
 24 	// todo: unify load API to for easier SceneLoader use
 25 
 26 	texturePath = texturePath && ( typeof texturePath === "string" ) ? texturePath : this.extractUrlBase( url );
 27 	binaryPath = binaryPath && ( typeof binaryPath === "string" ) ? binaryPath : this.extractUrlBase( url );
 28 
 29 	var callbackProgress = this.showProgress ? THREE.Loader.prototype.updateProgress : null;
 30 
 31 	this.onLoadStart();
 32 
 33 	// #1 load JS part via web worker
 34 
 35 	this.loadAjaxJSON( this, url, callback, texturePath, binaryPath, callbackProgress );
 36 
 37 };
 38 
 39 THREE.BinaryLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, binaryPath, callbackProgress ) {
 40 
 41 	var xhr = new XMLHttpRequest();
 42 
 43 	xhr.onreadystatechange = function () {
 44 
 45 		if ( xhr.readyState == 4 ) {
 46 
 47 			if ( xhr.status == 200 || xhr.status == 0 ) {
 48 
 49 				var json = JSON.parse( xhr.responseText );
 50 				context.loadAjaxBuffers( json, callback, binaryPath, texturePath, callbackProgress );
 51 
 52 			} else {
 53 
 54 				console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
 55 
 56 			}
 57 
 58 		}
 59 
 60 	};
 61 
 62 	xhr.open( "GET", url, true );
 63 	xhr.send( null );
 64 
 65 };
 66 
 67 THREE.BinaryLoader.prototype.loadAjaxBuffers = function ( json, callback, binaryPath, texturePath, callbackProgress ) {
 68 
 69 	var xhr = new XMLHttpRequest(),
 70 		url = binaryPath + "/" + json.buffers;
 71 
 72 	var length = 0;
 73 
 74 	xhr.onreadystatechange = function () {
 75 
 76 		if ( xhr.readyState == 4 ) {
 77 
 78 			if ( xhr.status == 200 || xhr.status == 0 ) {
 79 
 80 				var buffer = xhr.response;
 81 				if ( buffer === undefined ) buffer = ( new Uint8Array( xhr.responseBody ) ).buffer; // IEWEBGL needs this
 82 				THREE.BinaryLoader.prototype.createBinModel( buffer, callback, texturePath, json.materials );
 83 
 84 			} else {
 85 
 86 				console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
 87 
 88 			}
 89 
 90 		} else if ( xhr.readyState == 3 ) {
 91 
 92 			if ( callbackProgress ) {
 93 
 94 				if ( length == 0 ) {
 95 
 96 					length = xhr.getResponseHeader( "Content-Length" );
 97 
 98 				}
 99 
100 				callbackProgress( { total: length, loaded: xhr.responseText.length } );
101 
102 			}
103 
104 		} else if ( xhr.readyState == 2 ) {
105 
106 			length = xhr.getResponseHeader( "Content-Length" );
107 
108 		}
109 
110 	};
111 
112 	xhr.open( "GET", url, true );
113 	xhr.responseType = "arraybuffer";
114 	xhr.send( null );
115 
116 };
117 
118 // Binary AJAX parser
119 
120 THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texturePath, jsonMaterials ) {
121 
122 	var Model = function ( texturePath ) {
123 
124 		var scope = this,
125 			currentOffset = 0,
126 			md,
127 			normals = [],
128 			uvs = [],
129 			start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv,
130 			start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv,
131 			tri_size, quad_size,
132 			len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv,
133 			len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv;
134 
135 
136 		THREE.Geometry.call( this );
137 
138 		md = parseMetaData( data, currentOffset );
139 
140 		currentOffset += md.header_bytes;
141 /*
142 		md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
143 		md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT;
144 		md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
145 		md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
146 */
147 		// buffers sizes
148 
149 		tri_size =  md.vertex_index_bytes * 3 + md.material_index_bytes;
150 		quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
151 
152 		len_tri_flat      = md.ntri_flat      * ( tri_size );
153 		len_tri_smooth    = md.ntri_smooth    * ( tri_size + md.normal_index_bytes * 3 );
154 		len_tri_flat_uv   = md.ntri_flat_uv   * ( tri_size + md.uv_index_bytes * 3 );
155 		len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
156 
157 		len_quad_flat      = md.nquad_flat      * ( quad_size );
158 		len_quad_smooth    = md.nquad_smooth    * ( quad_size + md.normal_index_bytes * 4 );
159 		len_quad_flat_uv   = md.nquad_flat_uv   * ( quad_size + md.uv_index_bytes * 4 );
160 		len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 );
161 
162 		// read buffers
163 
164 		currentOffset += init_vertices( currentOffset );
165 
166 		currentOffset += init_normals( currentOffset );
167 		currentOffset += handlePadding( md.nnormals * 3 );
168 
169 		currentOffset += init_uvs( currentOffset );
170 
171 		start_tri_flat 		= currentOffset;
172 		start_tri_smooth    = start_tri_flat    + len_tri_flat    + handlePadding( md.ntri_flat * 2 );
173 		start_tri_flat_uv   = start_tri_smooth  + len_tri_smooth  + handlePadding( md.ntri_smooth * 2 );
174 		start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
175 
176 		start_quad_flat     = start_tri_smooth_uv + len_tri_smooth_uv  + handlePadding( md.ntri_smooth_uv * 2 );
177 		start_quad_smooth   = start_quad_flat     + len_quad_flat	   + handlePadding( md.nquad_flat * 2 );
178 		start_quad_flat_uv  = start_quad_smooth   + len_quad_smooth    + handlePadding( md.nquad_smooth * 2 );
179 		start_quad_smooth_uv= start_quad_flat_uv  + len_quad_flat_uv   + handlePadding( md.nquad_flat_uv * 2 );
180 
181 		// have to first process faces with uvs
182 		// so that face and uv indices match
183 
184 		init_triangles_flat_uv( start_tri_flat_uv );
185 		init_triangles_smooth_uv( start_tri_smooth_uv );
186 
187 		init_quads_flat_uv( start_quad_flat_uv );
188 		init_quads_smooth_uv( start_quad_smooth_uv );
189 
190 		// now we can process untextured faces
191 
192 		init_triangles_flat( start_tri_flat );
193 		init_triangles_smooth( start_tri_smooth );
194 
195 		init_quads_flat( start_quad_flat );
196 		init_quads_smooth( start_quad_smooth );
197 
198 		this.computeCentroids();
199 		this.computeFaceNormals();
200 
201 		function handlePadding( n ) {
202 
203 			return ( n % 4 ) ? ( 4 - n % 4 ) : 0;
204 
205 		};
206 
207 		function parseMetaData( data, offset ) {
208 
209 			var metaData = {
210 
211 				'signature'               :parseString( data, offset,  12 ),
212 				'header_bytes'            :parseUChar8( data, offset + 12 ),
213 
214 				'vertex_coordinate_bytes' :parseUChar8( data, offset + 13 ),
215 				'normal_coordinate_bytes' :parseUChar8( data, offset + 14 ),
216 				'uv_coordinate_bytes'     :parseUChar8( data, offset + 15 ),
217 
218 				'vertex_index_bytes'      :parseUChar8( data, offset + 16 ),
219 				'normal_index_bytes'      :parseUChar8( data, offset + 17 ),
220 				'uv_index_bytes'          :parseUChar8( data, offset + 18 ),
221 				'material_index_bytes'    :parseUChar8( data, offset + 19 ),
222 
223 				'nvertices'    :parseUInt32( data, offset + 20 ),
224 				'nnormals'     :parseUInt32( data, offset + 20 + 4*1 ),
225 				'nuvs'         :parseUInt32( data, offset + 20 + 4*2 ),
226 
227 				'ntri_flat'      :parseUInt32( data, offset + 20 + 4*3 ),
228 				'ntri_smooth'    :parseUInt32( data, offset + 20 + 4*4 ),
229 				'ntri_flat_uv'   :parseUInt32( data, offset + 20 + 4*5 ),
230 				'ntri_smooth_uv' :parseUInt32( data, offset + 20 + 4*6 ),
231 
232 				'nquad_flat'      :parseUInt32( data, offset + 20 + 4*7 ),
233 				'nquad_smooth'    :parseUInt32( data, offset + 20 + 4*8 ),
234 				'nquad_flat_uv'   :parseUInt32( data, offset + 20 + 4*9 ),
235 				'nquad_smooth_uv' :parseUInt32( data, offset + 20 + 4*10 )
236 
237 			};
238 /*
239 			console.log( "signature: " + metaData.signature );
240 
241 			console.log( "header_bytes: " + metaData.header_bytes );
242 			console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
243 			console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
244 			console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
245 
246 			console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
247 			console.log( "normal_index_bytes: " + metaData.normal_index_bytes );
248 			console.log( "uv_index_bytes: " + metaData.uv_index_bytes );
249 			console.log( "material_index_bytes: " + metaData.material_index_bytes );
250 
251 			console.log( "nvertices: " + metaData.nvertices );
252 			console.log( "nnormals: " + metaData.nnormals );
253 			console.log( "nuvs: " + metaData.nuvs );
254 
255 			console.log( "ntri_flat: " + metaData.ntri_flat );
256 			console.log( "ntri_smooth: " + metaData.ntri_smooth );
257 			console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
258 			console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
259 
260 			console.log( "nquad_flat: " + metaData.nquad_flat );
261 			console.log( "nquad_smooth: " + metaData.nquad_smooth );
262 			console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
263 			console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
264 
265 			var total = metaData.header_bytes
266 					  + metaData.nvertices * metaData.vertex_coordinate_bytes * 3
267 					  + metaData.nnormals * metaData.normal_coordinate_bytes * 3
268 					  + metaData.nuvs * metaData.uv_coordinate_bytes * 2
269 					  + metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes )
270 					  + metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 )
271 					  + metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 )
272 					  + metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 )
273 					  + metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes )
274 					  + metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 )
275 					  + metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 )
276 					  + metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 );
277 			console.log( "total bytes: " + total );
278 */
279 
280 			return metaData;
281 
282 		};
283 
284 		function parseString( data, offset, length ) {
285 
286 			var charArray = new Uint8Array( data, offset, length );
287 
288 			var text = "";
289 
290 			for ( var i = 0; i < length; i ++ ) {
291 
292 				text += String.fromCharCode( charArray[ offset + i ] );
293 
294 			}
295 
296 			return text;
297 
298 		};
299 
300 		function parseUChar8( data, offset ) {
301 
302 			var charArray = new Uint8Array( data, offset, 1 );
303 
304 			return charArray[ 0 ];
305 
306 		};
307 
308 		function parseUInt32( data, offset ) {
309 
310 			var intArray = new Uint32Array( data, offset, 1 );
311 
312 			return intArray[ 0 ];
313 
314 		};
315 
316 		function init_vertices( start ) {
317 
318 			var nElements = md.nvertices;
319 
320 			var coordArray = new Float32Array( data, start, nElements * 3 );
321 
322 			var i, x, y, z;
323 
324 			for( i = 0; i < nElements; i ++ ) {
325 
326 				x = coordArray[ i * 3 ];
327 				y = coordArray[ i * 3 + 1 ];
328 				z = coordArray[ i * 3 + 2 ];
329 
330 				vertex( scope, x, y, z );
331 
332 			}
333 
334 			return nElements * 3 * Float32Array.BYTES_PER_ELEMENT;
335 
336 		};
337 
338 		function init_normals( start ) {
339 
340 			var nElements = md.nnormals;
341 
342 			if ( nElements ) {
343 
344 				var normalArray = new Int8Array( data, start, nElements * 3 );
345 
346 				var i, x, y, z;
347 
348 				for( i = 0; i < nElements; i ++ ) {
349 
350 					x = normalArray[ i * 3 ];
351 					y = normalArray[ i * 3 + 1 ];
352 					z = normalArray[ i * 3 + 2 ];
353 
354 					normals.push( x/127, y/127, z/127 );
355 
356 				}
357 
358 			}
359 
360 			return nElements * 3 * Int8Array.BYTES_PER_ELEMENT;
361 
362 		};
363 
364 		function init_uvs( start ) {
365 
366 			var nElements = md.nuvs;
367 
368 			if ( nElements ) {
369 
370 				var uvArray = new Float32Array( data, start, nElements * 2 );
371 
372 				var i, u, v;
373 
374 				for( i = 0; i < nElements; i ++ ) {
375 
376 					u = uvArray[ i * 2 ];
377 					v = uvArray[ i * 2 + 1 ];
378 
379 					uvs.push( u, v );
380 
381 				}
382 
383 			}
384 
385 			return nElements * 2 * Float32Array.BYTES_PER_ELEMENT;
386 
387 		};
388 
389 		function init_uvs3( nElements, offset ) {
390 
391 			var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
392 
393 			var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements );
394 
395 			for( i = 0; i < nElements; i ++ ) {
396 
397 				uva = uvIndexBuffer[ i * 3 ];
398 				uvb = uvIndexBuffer[ i * 3 + 1 ];
399 				uvc = uvIndexBuffer[ i * 3 + 2 ];
400 
401 				u1 = uvs[ uva*2 ];
402 				v1 = uvs[ uva*2 + 1 ];
403 
404 				u2 = uvs[ uvb*2 ];
405 				v2 = uvs[ uvb*2 + 1 ];
406 
407 				u3 = uvs[ uvc*2 ];
408 				v3 = uvs[ uvc*2 + 1 ];
409 
410 				uv3( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3 );
411 
412 			}
413 
414 		};
415 
416 		function init_uvs4( nElements, offset ) {
417 
418 			var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
419 
420 			var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements );
421 
422 			for( i = 0; i < nElements; i ++ ) {
423 
424 				uva = uvIndexBuffer[ i * 4 ];
425 				uvb = uvIndexBuffer[ i * 4 + 1 ];
426 				uvc = uvIndexBuffer[ i * 4 + 2 ];
427 				uvd = uvIndexBuffer[ i * 4 + 3 ];
428 
429 				u1 = uvs[ uva*2 ];
430 				v1 = uvs[ uva*2 + 1 ];
431 
432 				u2 = uvs[ uvb*2 ];
433 				v2 = uvs[ uvb*2 + 1 ];
434 
435 				u3 = uvs[ uvc*2 ];
436 				v3 = uvs[ uvc*2 + 1 ];
437 
438 				u4 = uvs[ uvd*2 ];
439 				v4 = uvs[ uvd*2 + 1 ];
440 
441 				uv4( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3, u4, v4 );
442 
443 			}
444 
445 		};
446 
447 		function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) {
448 
449 			var i, a, b, c, m;
450 
451 			var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
452 			var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
453 
454 			for( i = 0; i < nElements; i ++ ) {
455 
456 				a = vertexIndexBuffer[ i * 3 ];
457 				b = vertexIndexBuffer[ i * 3 + 1 ];
458 				c = vertexIndexBuffer[ i * 3 + 2 ];
459 
460 				m = materialIndexBuffer[ i ];
461 
462 				f3( scope, a, b, c, m );
463 
464 			}
465 
466 		};
467 
468 		function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) {
469 
470 			var i, a, b, c, d, m;
471 
472 			var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
473 			var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
474 
475 			for( i = 0; i < nElements; i ++ ) {
476 
477 				a = vertexIndexBuffer[ i * 4 ];
478 				b = vertexIndexBuffer[ i * 4 + 1 ];
479 				c = vertexIndexBuffer[ i * 4 + 2 ];
480 				d = vertexIndexBuffer[ i * 4 + 3 ];
481 
482 				m = materialIndexBuffer[ i ];
483 
484 				f4( scope, a, b, c, d, m );
485 
486 			}
487 
488 		};
489 
490 		function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
491 
492 			var i, a, b, c, m;
493 			var na, nb, nc;
494 
495 			var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
496 			var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements );
497 			var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
498 
499 			for( i = 0; i < nElements; i ++ ) {
500 
501 				a = vertexIndexBuffer[ i * 3 ];
502 				b = vertexIndexBuffer[ i * 3 + 1 ];
503 				c = vertexIndexBuffer[ i * 3 + 2 ];
504 
505 				na = normalIndexBuffer[ i * 3 ];
506 				nb = normalIndexBuffer[ i * 3 + 1 ];
507 				nc = normalIndexBuffer[ i * 3 + 2 ];
508 
509 				m = materialIndexBuffer[ i ];
510 
511 				f3n( scope, normals, a, b, c, m, na, nb, nc );
512 
513 			}
514 
515 		};
516 
517 		function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
518 
519 			var i, a, b, c, d, m;
520 			var na, nb, nc, nd;
521 
522 			var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
523 			var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements );
524 			var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
525 
526 			for( i = 0; i < nElements; i ++ ) {
527 
528 				a = vertexIndexBuffer[ i * 4 ];
529 				b = vertexIndexBuffer[ i * 4 + 1 ];
530 				c = vertexIndexBuffer[ i * 4 + 2 ];
531 				d = vertexIndexBuffer[ i * 4 + 3 ];
532 
533 				na = normalIndexBuffer[ i * 4 ];
534 				nb = normalIndexBuffer[ i * 4 + 1 ];
535 				nc = normalIndexBuffer[ i * 4 + 2 ];
536 				nd = normalIndexBuffer[ i * 4 + 3 ];
537 
538 				m = materialIndexBuffer[ i ];
539 
540 				f4n( scope, normals, a, b, c, d, m, na, nb, nc, nd );
541 
542 			}
543 
544 		};
545 
546 		function init_triangles_flat( start ) {
547 
548 			var nElements = md.ntri_flat;
549 
550 			if ( nElements ) {
551 
552 				var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
553 				init_faces3_flat( nElements, start, offsetMaterials );
554 
555 			}
556 
557 		};
558 
559 		function init_triangles_flat_uv( start ) {
560 
561 			var nElements = md.ntri_flat_uv;
562 
563 			if ( nElements ) {
564 
565 				var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
566 				var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
567 
568 				init_faces3_flat( nElements, start, offsetMaterials );
569 				init_uvs3( nElements, offsetUvs );
570 
571 			}
572 
573 		};
574 
575 		function init_triangles_smooth( start ) {
576 
577 			var nElements = md.ntri_smooth;
578 
579 			if ( nElements ) {
580 
581 				var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
582 				var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
583 
584 				init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
585 
586 			}
587 
588 		};
589 
590 		function init_triangles_smooth_uv( start ) {
591 
592 			var nElements = md.ntri_smooth_uv;
593 
594 			if ( nElements ) {
595 
596 				var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
597 				var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
598 				var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
599 
600 				init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
601 				init_uvs3( nElements, offsetUvs );
602 
603 			}
604 
605 		};
606 
607 		function init_quads_flat( start ) {
608 
609 			var nElements = md.nquad_flat;
610 
611 			if ( nElements ) {
612 
613 				var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
614 				init_faces4_flat( nElements, start, offsetMaterials );
615 
616 			}
617 
618 		};
619 
620 		function init_quads_flat_uv( start ) {
621 
622 			var nElements = md.nquad_flat_uv;
623 
624 			if ( nElements ) {
625 
626 				var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
627 				var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
628 
629 				init_faces4_flat( nElements, start, offsetMaterials );
630 				init_uvs4( nElements, offsetUvs );
631 
632 			}
633 
634 		};
635 
636 		function init_quads_smooth( start ) {
637 
638 			var nElements = md.nquad_smooth;
639 
640 			if ( nElements ) {
641 
642 				var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
643 				var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
644 
645 				init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
646 
647 			}
648 
649 		};
650 
651 		function init_quads_smooth_uv( start ) {
652 
653 			var nElements = md.nquad_smooth_uv;
654 
655 			if ( nElements ) {
656 
657 				var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
658 				var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
659 				var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
660 
661 				init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
662 				init_uvs4( nElements, offsetUvs );
663 
664 			}
665 
666 		};
667 
668 	};
669 
670 	function vertex ( scope, x, y, z ) {
671 
672 		scope.vertices.push( new THREE.Vector3( x, y, z ) );
673 
674 	};
675 
676 	function f3 ( scope, a, b, c, mi ) {
677 
678 		scope.faces.push( new THREE.Face3( a, b, c, null, null, mi ) );
679 
680 	};
681 
682 	function f4 ( scope, a, b, c, d, mi ) {
683 
684 		scope.faces.push( new THREE.Face4( a, b, c, d, null, null, mi ) );
685 
686 	};
687 
688 	function f3n ( scope, normals, a, b, c, mi, na, nb, nc ) {
689 
690 		var nax = normals[ na*3     ],
691 			nay = normals[ na*3 + 1 ],
692 			naz = normals[ na*3 + 2 ],
693 
694 			nbx = normals[ nb*3     ],
695 			nby = normals[ nb*3 + 1 ],
696 			nbz = normals[ nb*3 + 2 ],
697 
698 			ncx = normals[ nc*3     ],
699 			ncy = normals[ nc*3 + 1 ],
700 			ncz = normals[ nc*3 + 2 ];
701 
702 		scope.faces.push( new THREE.Face3( a, b, c,
703 						  [new THREE.Vector3( nax, nay, naz ),
704 						   new THREE.Vector3( nbx, nby, nbz ),
705 						   new THREE.Vector3( ncx, ncy, ncz )],
706 						  null,
707 						  mi ) );
708 
709 	};
710 
711 	function f4n ( scope, normals, a, b, c, d, mi, na, nb, nc, nd ) {
712 
713 		var nax = normals[ na*3     ],
714 			nay = normals[ na*3 + 1 ],
715 			naz = normals[ na*3 + 2 ],
716 
717 			nbx = normals[ nb*3     ],
718 			nby = normals[ nb*3 + 1 ],
719 			nbz = normals[ nb*3 + 2 ],
720 
721 			ncx = normals[ nc*3     ],
722 			ncy = normals[ nc*3 + 1 ],
723 			ncz = normals[ nc*3 + 2 ],
724 
725 			ndx = normals[ nd*3     ],
726 			ndy = normals[ nd*3 + 1 ],
727 			ndz = normals[ nd*3 + 2 ];
728 
729 		scope.faces.push( new THREE.Face4( a, b, c, d,
730 						  [new THREE.Vector3( nax, nay, naz ),
731 						   new THREE.Vector3( nbx, nby, nbz ),
732 						   new THREE.Vector3( ncx, ncy, ncz ),
733 						   new THREE.Vector3( ndx, ndy, ndz )],
734 						  null,
735 						  mi ) );
736 
737 	};
738 
739 	function uv3 ( where, u1, v1, u2, v2, u3, v3 ) {
740 
741 		where.push( [
742 			new THREE.UV( u1, v1 ),
743 			new THREE.UV( u2, v2 ),
744 			new THREE.UV( u3, v3 )
745 		] );
746 
747 	};
748 
749 	function uv4 ( where, u1, v1, u2, v2, u3, v3, u4, v4 ) {
750 
751 		where.push( [
752 			new THREE.UV( u1, v1 ),
753 			new THREE.UV( u2, v2 ),
754 			new THREE.UV( u3, v3 ),
755 			new THREE.UV( u4, v4 )
756 		] );
757 	};
758 
759 	Model.prototype = Object.create( THREE.Geometry.prototype );
760 
761 	var geometry = new Model( texturePath );
762 	var materials = this.initMaterials( jsonMaterials, texturePath );
763 
764 	if ( this.needsTangents( materials ) ) geometry.computeTangents();
765 
766 	callback( geometry, materials );
767 
768 };
769 

nike free rn new balance hombre baratas cinturones gucci ugg rebajas cinturon gucci ray ban baratas nike cortez peuterey mujer christian louboutin madrid mbt zapatos gafas ray ban baratas mbt ofertas air max blancas mbt barcelona nike air max 90 woolrich barcelona nike mujer botas ugg gafas de sol carrera aratas air max 2016 baratas oakley baratas nike air max 2016

mbt skor nike sverige louboutin skor hollister sverige polo ralph lauren skjorta woolrich jacka dam canada goose jacka woolrich jacka ray ban rea canada goose rea michael kors rea new balance skor ralph lauren skjorta new balance rea uggs sverige lacoste rea christian louboutin skor moncler jacka nike shox barbour jacka uggs rea