1 /**
  2  * @author alteredq / http://alteredqualia.com/
  3  */
  4 
  5 /**@constructor*/
  6 THREE.SceneLoader = function () {
  7 
  8 	this.onLoadStart = function () {};
  9 	this.onLoadProgress = function() {};
 10 	this.onLoadComplete = function () {};
 11 
 12 	this.callbackSync = function () {};
 13 	this.callbackProgress = function () {};
 14 
 15 	this.geometryHandlerMap = {};
 16 	this.hierarchyHandlerMap = {};
 17 
 18 	this.addGeometryHandler( "ascii", THREE.JSONLoader );
 19 	this.addGeometryHandler( "binary", THREE.BinaryLoader );
 20 
 21 };
 22 
 23 THREE.SceneLoader.prototype.constructor = THREE.SceneLoader;
 24 
 25 THREE.SceneLoader.prototype.load = function ( url, callbackFinished ) {
 26 
 27 	var scope = this;
 28 
 29 	var xhr = new XMLHttpRequest();
 30 
 31 	xhr.onreadystatechange = function () {
 32 
 33 		if ( xhr.readyState === 4 ) {
 34 
 35 			if ( xhr.status === 200 || xhr.status === 0 ) {
 36 
 37 				var json = JSON.parse( xhr.responseText );
 38 				scope.parse( json, callbackFinished, url );
 39 
 40 			} else {
 41 
 42 				console.error( "THREE.SceneLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
 43 
 44 			}
 45 
 46 		}
 47 
 48 	};
 49 
 50 	xhr.open( "GET", url, true );
 51 	xhr.send( null );
 52 
 53 };
 54 
 55 THREE.SceneLoader.prototype.addGeometryHandler = function ( typeID, loaderClass ) {
 56 
 57 	this.geometryHandlerMap[ typeID ] = { "loaderClass": loaderClass };
 58 
 59 };
 60 
 61 THREE.SceneLoader.prototype.addHierarchyHandler = function ( typeID, loaderClass ) {
 62 
 63 	this.hierarchyHandlerMap[ typeID ] = { "loaderClass": loaderClass };
 64 
 65 };
 66 
 67 THREE.SceneLoader.prototype.parse = function ( json, callbackFinished, url ) {
 68 
 69 	var scope = this;
 70 
 71 	var urlBase = THREE.Loader.prototype.extractUrlBase( url );
 72 
 73 	var dg, dm, dc, df, dt,
 74 		g, m, l, d, p, r, q, s, c, t, f, tt, pp, u,
 75 		geometry, material, camera, fog,
 76 		texture, images,
 77 		light, hex, intensity,
 78 		counter_models, counter_textures,
 79 		total_models, total_textures,
 80 		result;
 81 
 82 	var target_array = [];
 83 
 84 	var data = json;
 85 
 86 	// async geometry loaders
 87 
 88 	for ( var typeID in this.geometryHandlerMap ) {
 89 
 90 		var loaderClass = this.geometryHandlerMap[ typeID ][ "loaderClass" ];
 91 		this.geometryHandlerMap[ typeID ][ "loaderObject" ] = new loaderClass();
 92 
 93 	}
 94 
 95 	// async hierachy loaders
 96 
 97 	for ( var typeID in this.hierarchyHandlerMap ) {
 98 
 99 		var loaderClass = this.hierarchyHandlerMap[ typeID ][ "loaderClass" ];
100 		this.hierarchyHandlerMap[ typeID ][ "loaderObject" ] = new loaderClass();
101 
102 	}
103 
104 	counter_models = 0;
105 	counter_textures = 0;
106 
107 	result = {
108 
109 		scene: new THREE.Scene(),
110 		geometries: {},
111 		face_materials: {},
112 		materials: {},
113 		textures: {},
114 		objects: {},
115 		cameras: {},
116 		lights: {},
117 		fogs: {},
118 		empties: {}
119 
120 	};
121 
122 	if ( data.transform ) {
123 
124 		var position = data.transform.position,
125 			rotation = data.transform.rotation,
126 			scale = data.transform.scale;
127 
128 		if ( position )
129 			result.scene.position.set( position[ 0 ], position[ 1 ], position [ 2 ] );
130 
131 		if ( rotation )
132 			result.scene.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation [ 2 ] );
133 
134 		if ( scale )
135 			result.scene.scale.set( scale[ 0 ], scale[ 1 ], scale [ 2 ] );
136 
137 		if ( position || rotation || scale ) {
138 
139 			result.scene.updateMatrix();
140 			result.scene.updateMatrixWorld();
141 
142 		}
143 
144 	}
145 
146 	function get_url( source_url, url_type ) {
147 
148 		if ( url_type == "relativeToHTML" ) {
149 
150 			return source_url;
151 
152 		} else {
153 
154 			return urlBase + "/" + source_url;
155 
156 		}
157 
158 	};
159 
160 	// toplevel loader function, delegates to handle_children
161 
162 	function handle_objects() {
163 
164 		handle_children( result.scene, data.objects );
165 
166 	}
167 
168 	// handle all the children from the loaded json and attach them to given parent
169 
170 	function handle_children( parent, children ) {
171 
172 		for ( var dd in children ) {
173 
174 			// check by id if child has already been handled,
175 			// if not, create new object
176 
177 			if ( result.objects[ dd ] === undefined ) {
178 
179 				var o = children[ dd ];
180 
181 				var object = null;
182 
183 				// meshes
184 
185 				if ( o.type && ( o.type in scope.hierarchyHandlerMap ) && o.loading === undefined ) {
186 
187 					var loaderParameters = {};
188 
189 					for ( var parType in g ) {
190 
191 						if ( parType !== "type" && parType !== "url" ) {
192 
193 							loaderParameters[ parType ] = g[ parType ];
194 
195 						}
196 
197 					}
198 
199 					material = result.materials[ o.material ];
200 
201 					o.loading = true;
202 
203 					var loader = scope.hierarchyHandlerMap[ o.type ][ "loaderObject" ];
204 
205 					// OBJLoader
206 
207 					if ( loader.addEventListener ) {
208 
209 						loader.addEventListener( 'load', create_callback_hierachy( dd, parent, material, o ) );
210 						loader.load( get_url( o.url, data.urlBaseType ) );
211 
212 					} else {
213 
214 						// ColladaLoader
215 
216 						if ( loader.options ) {
217 
218 							loader.load( get_url( o.url, data.urlBaseType ), create_callback_hierachy( dd, parent, material, o ) );
219 
220 						// UTF8Loader
221 
222 						} else {
223 
224 							loader.load( get_url( o.url, data.urlBaseType ), create_callback_hierachy( dd, parent, material, o ), loaderParameters );
225 
226 						}
227 
228 					}
229 
230 				} else if ( o.geometry !== undefined ) {
231 
232 					geometry = result.geometries[ o.geometry ];
233 
234 					// geometry already loaded
235 
236 					if ( geometry ) {
237 
238 						var needsTangents = false;
239 
240 						material = result.materials[ o.material ];
241 						needsTangents = material instanceof THREE.ShaderMaterial;
242 
243 						p = o.position;
244 						r = o.rotation;
245 						q = o.quaternion;
246 						s = o.scale;
247 						m = o.matrix;
248 
249 						// turn off quaternions, for the moment
250 
251 						q = 0;
252 
253 						// use materials from the model file
254 						// if there is no material specified in the object
255 
256 						if ( ! o.material ) {
257 
258 							material = new THREE.MeshFaceMaterial( result.face_materials[ o.geometry ] );
259 
260 						}
261 
262 						// use materials from the model file
263 						// if there is just empty face material
264 						// (must create new material as each model has its own face material)
265 
266 						if ( ( material instanceof THREE.MeshFaceMaterial ) && material.materials.length === 0 ) {
267 
268 							material = new THREE.MeshFaceMaterial( result.face_materials[ o.geometry ] );
269 
270 						}
271 
272 						if ( material instanceof THREE.MeshFaceMaterial ) {
273 
274 							for ( var i = 0; i < material.materials.length; i ++ ) {
275 
276 								needsTangents = needsTangents || ( material.materials[ i ] instanceof THREE.ShaderMaterial );
277 
278 							}
279 
280 						}
281 
282 						if ( needsTangents ) {
283 
284 							geometry.computeTangents();
285 
286 						}
287 
288 						if ( o.skin ) {
289 
290 							object = new THREE.SkinnedMesh( geometry, material );
291 
292 						} else if ( o.morph ) {
293 
294 							object = new THREE.MorphAnimMesh( geometry, material );
295 
296 							if ( o.duration !== undefined ) {
297 
298 								object.duration = o.duration;
299 
300 							}
301 
302 							if ( o.time !== undefined ) {
303 
304 								object.time = o.time;
305 
306 							}
307 
308 							if ( o.mirroredLoop !== undefined ) {
309 
310 								object.mirroredLoop = o.mirroredLoop;
311 
312 							}
313 
314 							if ( material.morphNormals ) {
315 
316 								geometry.computeMorphNormals();
317 
318 							}
319 
320 						} else {
321 
322 							object = new THREE.Mesh( geometry, material );
323 
324 						}
325 
326 						object.name = dd;
327 
328 						if ( m ) {
329 
330 							object.matrixAutoUpdate = false;
331 							object.matrix.set(
332 								m[0], m[1], m[2], m[3],
333 								m[4], m[5], m[6], m[7],
334 								m[8], m[9], m[10], m[11],
335 								m[12], m[13], m[14], m[15]
336 							);
337 
338 						} else {
339 
340 							object.position.set( p[0], p[1], p[2] );
341 
342 							if ( q ) {
343 
344 								object.quaternion.set( q[0], q[1], q[2], q[3] );
345 								object.useQuaternion = true;
346 
347 							} else {
348 
349 								object.rotation.set( r[0], r[1], r[2] );
350 
351 							}
352 
353 							object.scale.set( s[0], s[1], s[2] );
354 
355 						}
356 
357 						object.visible = o.visible;
358 						object.castShadow = o.castShadow;
359 						object.receiveShadow = o.receiveShadow;
360 
361 						parent.add( object );
362 
363 						result.objects[ dd ] = object;
364 
365 					}
366 
367 				// lights
368 
369 				} else if ( o.type === "DirectionalLight" || o.type === "PointLight" || o.type === "AmbientLight" ) {
370 
371 					hex = ( o.color !== undefined ) ? o.color : 0xffffff;
372 					intensity = ( o.intensity !== undefined ) ? o.intensity : 1;
373 
374 					if ( o.type === "DirectionalLight" ) {
375 
376 						p = o.direction;
377 
378 						light = new THREE.DirectionalLight( hex, intensity );
379 						light.position.set( p[0], p[1], p[2] );
380 
381 						if ( o.target ) {
382 
383 							target_array.push( { "object": light, "targetName" : o.target } );
384 
385 							// kill existing default target
386 							// otherwise it gets added to scene when parent gets added
387 
388 							light.target = null;
389 
390 						}
391 
392 					} else if ( o.type === "PointLight" ) {
393 
394 						p = o.position;
395 						d = o.distance;
396 
397 						light = new THREE.PointLight( hex, intensity, d );
398 						light.position.set( p[0], p[1], p[2] );
399 
400 					} else if ( o.type === "AmbientLight" ) {
401 
402 						light = new THREE.AmbientLight( hex );
403 
404 					}
405 
406 					parent.add( light );
407 
408 					light.name = dd;
409 					result.lights[ dd ] = light;
410 					result.objects[ dd ] = light;
411 
412 				// cameras
413 
414 				} else if ( o.type === "PerspectiveCamera" || o.type === "OrthographicCamera" ) {
415 
416 					if ( o.type === "PerspectiveCamera" ) {
417 
418 						camera = new THREE.PerspectiveCamera( o.fov, o.aspect, o.near, o.far );
419 
420 					} else if ( o.type === "OrthographicCamera" ) {
421 
422 						camera = new THREE.OrthographicCamera( c.left, c.right, c.top, c.bottom, c.near, c.far );
423 
424 					}
425 
426 					p = o.position;
427 					camera.position.set( p[0], p[1], p[2] );
428 					parent.add( camera );
429 
430 					camera.name = dd;
431 					result.cameras[ dd ] = camera;
432 					result.objects[ dd ] = camera;
433 
434 				// pure Object3D
435 
436 				} else {
437 
438 					p = o.position;
439 					r = o.rotation;
440 					q = o.quaternion;
441 					s = o.scale;
442 
443 					// turn off quaternions, for the moment
444 
445 					q = 0;
446 
447 					object = new THREE.Object3D();
448 					object.name = dd;
449 					object.position.set( p[0], p[1], p[2] );
450 
451 					if ( q ) {
452 
453 						object.quaternion.set( q[0], q[1], q[2], q[3] );
454 						object.useQuaternion = true;
455 
456 					} else {
457 
458 						object.rotation.set( r[0], r[1], r[2] );
459 
460 					}
461 
462 					object.scale.set( s[0], s[1], s[2] );
463 					object.visible = ( o.visible !== undefined ) ? o.visible : false;
464 
465 					parent.add( object );
466 
467 					result.objects[ dd ] = object;
468 					result.empties[ dd ] = object;
469 
470 				}
471 
472 				if ( object ) {
473 
474 					if ( o.properties !== undefined )  {
475 
476 						for ( var key in o.properties ) {
477 
478 							var value = o.properties[ key ];
479 							object.properties[ key ] = value;
480 
481 						}
482 
483 					}
484 
485 					if ( o.children !== undefined ) {
486 
487 						handle_children( object, o.children );
488 
489 					}
490 
491 				}
492 
493 			}
494 
495 		}
496 
497 	};
498 
499 	function handle_mesh( geo, mat, id ) {
500 
501 		result.geometries[ id ] = geo;
502 		result.face_materials[ id ] = mat;
503 		handle_objects();
504 
505 	};
506 
507 	function handle_hierarchy( node, id, parent, material, o ) {
508 
509 		var p = o.position;
510 		var r = o.rotation;
511 		var q = o.quaternion;
512 		var s = o.scale;
513 
514 		node.position.set( p[0], p[1], p[2] );
515 
516 		if ( q ) {
517 
518 			node.quaternion.set( q[0], q[1], q[2], q[3] );
519 			node.useQuaternion = true;
520 
521 		} else {
522 
523 			node.rotation.set( r[0], r[1], r[2] );
524 
525 		}
526 
527 		node.scale.set( s[0], s[1], s[2] );
528 
529 		if ( material ) {
530 
531 			node.traverse( function ( child )  {
532 
533 				child.material = material;
534 
535 			} );
536 
537 		}
538 
539 		parent.add( node );
540 
541 		result.objects[ id ] = node;
542 		handle_objects();
543 
544 	};
545 
546 	function create_callback_geometry( id ) {
547 
548 		return function( geo, mat ) {
549 
550 			handle_mesh( geo, mat, id );
551 
552 			counter_models -= 1;
553 
554 			scope.onLoadComplete();
555 
556 			async_callback_gate();
557 
558 		}
559 
560 	};
561 
562 	function create_callback_hierachy( id, parent, material, obj ) {
563 
564 		return function( event ) {
565 
566 			var result;
567 
568 			// loaders which use EventTarget
569 
570 			if ( event.content ) {
571 
572 				result = event.content;
573 
574 			// ColladaLoader
575 
576 			} else if ( event.dae ) {
577 
578 				result = event.scene;
579 
580 
581 			// UTF8Loader
582 
583 			} else {
584 
585 				result = event;
586 
587 			}
588 
589 			handle_hierarchy( result, id, parent, material, obj );
590 
591 			counter_models -= 1;
592 
593 			scope.onLoadComplete();
594 
595 			async_callback_gate();
596 
597 		}
598 
599 	};
600 
601 	function create_callback_embed( id ) {
602 
603 		return function( geo, mat ) {
604 
605 			result.geometries[ id ] = geo;
606 			result.face_materials[ id ] = mat;
607 
608 		}
609 
610 	};
611 
612 	function async_callback_gate() {
613 
614 		var progress = {
615 
616 			totalModels : total_models,
617 			totalTextures : total_textures,
618 			loadedModels : total_models - counter_models,
619 			loadedTextures : total_textures - counter_textures
620 
621 		};
622 
623 		scope.callbackProgress( progress, result );
624 
625 		scope.onLoadProgress();
626 
627 		if ( counter_models === 0 && counter_textures === 0 ) {
628 
629 			finalize();
630 			callbackFinished( result );
631 
632 		}
633 
634 	};
635 
636 	function finalize() {
637 
638 		// take care of targets which could be asynchronously loaded objects
639 
640 		for ( var i = 0; i < target_array.length; i ++ ) {
641 
642 			var ta = target_array[ i ];
643 
644 			var target = result.objects[ ta.targetName ];
645 
646 			if ( target ) {
647 
648 				ta.object.target = target;
649 
650 			} else {
651 
652 				// if there was error and target of specified name doesn't exist in the scene file
653 				// create instead dummy target
654 				// (target must be added to scene explicitly as parent is already added)
655 
656 				ta.object.target = new THREE.Object3D();
657 				result.scene.add( ta.object.target );
658 
659 			}
660 
661 			ta.object.target.properties.targetInverse = ta.object;
662 
663 		}
664 
665 	};
666 
667 	var callbackTexture = function ( count ) {
668 
669 		counter_textures -= count;
670 		async_callback_gate();
671 
672 		scope.onLoadComplete();
673 
674 	};
675 
676 	// must use this instead of just directly calling callbackTexture
677 	// because of closure in the calling context loop
678 
679 	var generateTextureCallback = function ( count ) {
680 
681 		return function() {
682 
683 			callbackTexture( count );
684 
685 		};
686 
687 	};
688 
689 	// first go synchronous elements
690 
691 	// fogs
692 
693 	for ( df in data.fogs ) {
694 
695 		f = data.fogs[ df ];
696 
697 		if ( f.type === "linear" ) {
698 
699 			fog = new THREE.Fog( 0x000000, f.near, f.far );
700 
701 		} else if ( f.type === "exp2" ) {
702 
703 			fog = new THREE.FogExp2( 0x000000, f.density );
704 
705 		}
706 
707 		c = f.color;
708 		fog.color.setRGB( c[0], c[1], c[2] );
709 
710 		result.fogs[ df ] = fog;
711 
712 	}
713 
714 	// now come potentially asynchronous elements
715 
716 	// geometries
717 
718 	// count how many geometries will be loaded asynchronously
719 
720 	for ( dg in data.geometries ) {
721 
722 		g = data.geometries[ dg ];
723 
724 		if ( g.type in this.geometryHandlerMap ) {
725 
726 			counter_models += 1;
727 
728 			scope.onLoadStart();
729 
730 		}
731 
732 	}
733 
734 	// count how many hierarchies will be loaded asynchronously
735 
736 	for ( var dd in data.objects ) {
737 
738 		var o = data.objects[ dd ];
739 
740 		if ( o.type && ( o.type in this.hierarchyHandlerMap ) ) {
741 
742 			counter_models += 1;
743 
744 			scope.onLoadStart();
745 
746 		}
747 
748 	}
749 
750 	total_models = counter_models;
751 
752 	for ( dg in data.geometries ) {
753 
754 		g = data.geometries[ dg ];
755 
756 		if ( g.type === "cube" ) {
757 
758 			geometry = new THREE.CubeGeometry( g.width, g.height, g.depth, g.widthSegments, g.heightSegments, g.depthSegments );
759 			result.geometries[ dg ] = geometry;
760 
761 		} else if ( g.type === "plane" ) {
762 
763 			geometry = new THREE.PlaneGeometry( g.width, g.height, g.widthSegments, g.heightSegments );
764 			result.geometries[ dg ] = geometry;
765 
766 		} else if ( g.type === "sphere" ) {
767 
768 			geometry = new THREE.SphereGeometry( g.radius, g.widthSegments, g.heightSegments );
769 			result.geometries[ dg ] = geometry;
770 
771 		} else if ( g.type === "cylinder" ) {
772 
773 			geometry = new THREE.CylinderGeometry( g.topRad, g.botRad, g.height, g.radSegs, g.heightSegs );
774 			result.geometries[ dg ] = geometry;
775 
776 		} else if ( g.type === "torus" ) {
777 
778 			geometry = new THREE.TorusGeometry( g.radius, g.tube, g.segmentsR, g.segmentsT );
779 			result.geometries[ dg ] = geometry;
780 
781 		} else if ( g.type === "icosahedron" ) {
782 
783 			geometry = new THREE.IcosahedronGeometry( g.radius, g.subdivisions );
784 			result.geometries[ dg ] = geometry;
785 
786 		} else if ( g.type in this.geometryHandlerMap ) {
787 
788 			var loaderParameters = {};
789 			for ( var parType in g ) {
790 
791 				if ( parType !== "type" && parType !== "url" ) {
792 
793 					loaderParameters[ parType ] = g[ parType ];
794 
795 				}
796 
797 			}
798 
799 			var loader = this.geometryHandlerMap[ g.type ][ "loaderObject" ];
800 			loader.load( get_url( g.url, data.urlBaseType ), create_callback_geometry( dg ), loaderParameters );
801 
802 		} else if ( g.type === "embedded" ) {
803 
804 			var modelJson = data.embeds[ g.id ],
805 				texture_path = "";
806 
807 			// pass metadata along to jsonLoader so it knows the format version
808 
809 			modelJson.metadata = data.metadata;
810 
811 			if ( modelJson ) {
812 
813 				var jsonLoader = this.geometryHandlerMap[ "ascii" ][ "loaderObject" ];
814 				jsonLoader.createModel( modelJson, create_callback_embed( dg ), texture_path );
815 
816 			}
817 
818 		}
819 
820 	}
821 
822 	// textures
823 
824 	// count how many textures will be loaded asynchronously
825 
826 	for ( dt in data.textures ) {
827 
828 		tt = data.textures[ dt ];
829 
830 		if ( tt.url instanceof Array ) {
831 
832 			counter_textures += tt.url.length;
833 
834 			for( var n = 0; n < tt.url.length; n ++ ) {
835 
836 				scope.onLoadStart();
837 
838 			}
839 
840 		} else {
841 
842 			counter_textures += 1;
843 
844 			scope.onLoadStart();
845 
846 		}
847 
848 	}
849 
850 	total_textures = counter_textures;
851 
852 	for ( dt in data.textures ) {
853 
854 		tt = data.textures[ dt ];
855 
856 		if ( tt.mapping !== undefined && THREE[ tt.mapping ] !== undefined  ) {
857 
858 			tt.mapping = new THREE[ tt.mapping ]();
859 
860 		}
861 
862 		if ( tt.url instanceof Array ) {
863 
864 			var count = tt.url.length;
865 			var url_array = [];
866 
867 			for( var i = 0; i < count; i ++ ) {
868 
869 				url_array[ i ] = get_url( tt.url[ i ], data.urlBaseType );
870 
871 			}
872 
873 			var isCompressed = url_array[ 0 ].endsWith( ".dds" );
874 
875 			if ( isCompressed ) {
876 
877 				texture = THREE.ImageUtils.loadCompressedTextureCube( url_array, tt.mapping, generateTextureCallback( count ) );
878 
879 			} else {
880 
881 				texture = THREE.ImageUtils.loadTextureCube( url_array, tt.mapping, generateTextureCallback( count ) );
882 
883 			}
884 
885 		} else {
886 
887 			var isCompressed = tt.url.toLowerCase().endsWith( ".dds" );
888 			var fullUrl = get_url( tt.url, data.urlBaseType );
889 			var textureCallback = generateTextureCallback( 1 );
890 
891 			if ( isCompressed ) {
892 
893 				texture = THREE.ImageUtils.loadCompressedTexture( fullUrl, tt.mapping, textureCallback );
894 
895 			} else {
896 
897 				texture = THREE.ImageUtils.loadTexture( fullUrl, tt.mapping, textureCallback );
898 
899 			}
900 
901 			if ( THREE[ tt.minFilter ] !== undefined )
902 				texture.minFilter = THREE[ tt.minFilter ];
903 
904 			if ( THREE[ tt.magFilter ] !== undefined )
905 				texture.magFilter = THREE[ tt.magFilter ];
906 
907 			if ( tt.anisotropy ) texture.anisotropy = tt.anisotropy;
908 
909 			if ( tt.repeat ) {
910 
911 				texture.repeat.set( tt.repeat[ 0 ], tt.repeat[ 1 ] );
912 
913 				if ( tt.repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping;
914 				if ( tt.repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping;
915 
916 			}
917 
918 			if ( tt.offset ) {
919 
920 				texture.offset.set( tt.offset[ 0 ], tt.offset[ 1 ] );
921 
922 			}
923 
924 			// handle wrap after repeat so that default repeat can be overriden
925 
926 			if ( tt.wrap ) {
927 
928 				var wrapMap = {
929 				"repeat" 	: THREE.RepeatWrapping,
930 				"mirror"	: THREE.MirroredRepeatWrapping
931 				}
932 
933 				if ( wrapMap[ tt.wrap[ 0 ] ] !== undefined ) texture.wrapS = wrapMap[ tt.wrap[ 0 ] ];
934 				if ( wrapMap[ tt.wrap[ 1 ] ] !== undefined ) texture.wrapT = wrapMap[ tt.wrap[ 1 ] ];
935 
936 			}
937 
938 		}
939 
940 		result.textures[ dt ] = texture;
941 
942 	}
943 
944 	// materials
945 
946 	for ( dm in data.materials ) {
947 
948 		m = data.materials[ dm ];
949 
950 		for ( pp in m.parameters ) {
951 
952 			if ( pp === "envMap" || pp === "map" || pp === "lightMap" || pp === "bumpMap" ) {
953 
954 				m.parameters[ pp ] = result.textures[ m.parameters[ pp ] ];
955 
956 			} else if ( pp === "shading" ) {
957 
958 				m.parameters[ pp ] = ( m.parameters[ pp ] === "flat" ) ? THREE.FlatShading : THREE.SmoothShading;
959 
960 			} else if ( pp === "side" ) {
961 
962 				if (  m.parameters[ pp ] == "double" ) {
963 
964 					m.parameters[ pp ] = THREE.DoubleSide;
965 
966 				} else if ( m.parameters[ pp ] == "back" ) {
967 
968 					m.parameters[ pp ] = THREE.BackSide;
969 
970 				} else {
971 
972 					m.parameters[ pp ] = THREE.FrontSide;
973 
974 				}
975 
976 			} else if ( pp === "blending" ) {
977 
978 				m.parameters[ pp ] = m.parameters[ pp ] in THREE ? THREE[ m.parameters[ pp ] ] : THREE.NormalBlending;
979 
980 			} else if ( pp === "combine" ) {
981 
982 				m.parameters[ pp ] = ( m.parameters[ pp ] == "MixOperation" ) ? THREE.MixOperation : THREE.MultiplyOperation;
983 
984 			} else if ( pp === "vertexColors" ) {
985 
986 				if ( m.parameters[ pp ] == "face" ) {
987 
988 					m.parameters[ pp ] = THREE.FaceColors;
989 
990 				// default to vertex colors if "vertexColors" is anything else face colors or 0 / null / false
991 
992 				} else if ( m.parameters[ pp ] )   {
993 
994 					m.parameters[ pp ] = THREE.VertexColors;
995 
996 				}
997 
998 			} else if ( pp === "wrapRGB" ) {
999 
1000 				var v3 = m.parameters[ pp ];
1001 				m.parameters[ pp ] = new THREE.Vector3( v3[ 0 ], v3[ 1 ], v3[ 2 ] );
1002 
1003 			}
1004 
1005 		}
1006 
1007 		if ( m.parameters.opacity !== undefined && m.parameters.opacity < 1.0 ) {
1008 
1009 			m.parameters.transparent = true;
1010 
1011 		}
1012 
1013 		if ( m.parameters.normalMap ) {
1014 
1015 			var shader = THREE.ShaderUtils.lib[ "normal" ];
1016 			var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
1017 
1018 			var diffuse = m.parameters.color;
1019 			var specular = m.parameters.specular;
1020 			var ambient = m.parameters.ambient;
1021 			var shininess = m.parameters.shininess;
1022 
1023 			uniforms[ "tNormal" ].value = result.textures[ m.parameters.normalMap ];
1024 
1025 			if ( m.parameters.normalScale ) {
1026 
1027 				uniforms[ "uNormalScale" ].value.set( m.parameters.normalScale[ 0 ], m.parameters.normalScale[ 1 ] );
1028 
1029 			}
1030 
1031 			if ( m.parameters.map ) {
1032 
1033 				uniforms[ "tDiffuse" ].value = m.parameters.map;
1034 				uniforms[ "enableDiffuse" ].value = true;
1035 
1036 			}
1037 
1038 			if ( m.parameters.envMap ) {
1039 
1040 				uniforms[ "tCube" ].value = m.parameters.envMap;
1041 				uniforms[ "enableReflection" ].value = true;
1042 				uniforms[ "uReflectivity" ].value = m.parameters.reflectivity;
1043 
1044 			}
1045 
1046 			if ( m.parameters.lightMap ) {
1047 
1048 				uniforms[ "tAO" ].value = m.parameters.lightMap;
1049 				uniforms[ "enableAO" ].value = true;
1050 
1051 			}
1052 
1053 			if ( m.parameters.specularMap ) {
1054 
1055 				uniforms[ "tSpecular" ].value = result.textures[ m.parameters.specularMap ];
1056 				uniforms[ "enableSpecular" ].value = true;
1057 
1058 			}
1059 
1060 			if ( m.parameters.displacementMap ) {
1061 
1062 				uniforms[ "tDisplacement" ].value = result.textures[ m.parameters.displacementMap ];
1063 				uniforms[ "enableDisplacement" ].value = true;
1064 
1065 				uniforms[ "uDisplacementBias" ].value = m.parameters.displacementBias;
1066 				uniforms[ "uDisplacementScale" ].value = m.parameters.displacementScale;
1067 
1068 			}
1069 
1070 			uniforms[ "uDiffuseColor" ].value.setHex( diffuse );
1071 			uniforms[ "uSpecularColor" ].value.setHex( specular );
1072 			uniforms[ "uAmbientColor" ].value.setHex( ambient );
1073 
1074 			uniforms[ "uShininess" ].value = shininess;
1075 
1076 			if ( m.parameters.opacity ) {
1077 
1078 				uniforms[ "uOpacity" ].value = m.parameters.opacity;
1079 
1080 			}
1081 
1082 			var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
1083 
1084 			material = new THREE.ShaderMaterial( parameters );
1085 
1086 		} else {
1087 
1088 			material = new THREE[ m.type ]( m.parameters );
1089 
1090 		}
1091 
1092 		result.materials[ dm ] = material;
1093 
1094 	}
1095 
1096 	// second pass through all materials to initialize MeshFaceMaterials
1097 	// that could be referring to other materials out of order
1098 
1099 	for ( dm in data.materials ) {
1100 
1101 		m = data.materials[ dm ];
1102 
1103 		if ( m.parameters.materials ) {
1104 
1105 			var materialArray = [];
1106 
1107 			for ( var i = 0; i < m.parameters.materials.length; i ++ ) {
1108 
1109 				var label = m.parameters.materials[ i ];
1110 				materialArray.push( result.materials[ label ] );
1111 
1112 			}
1113 
1114 			result.materials[ dm ].materials = materialArray;
1115 
1116 		}
1117 
1118 	}
1119 
1120 	// objects ( synchronous init of procedural primitives )
1121 
1122 	handle_objects();
1123 
1124 	// defaults
1125 
1126 	if ( result.cameras && data.defaults.camera ) {
1127 
1128 		result.currentCamera = result.cameras[ data.defaults.camera ];
1129 
1130 	}
1131 
1132 	if ( result.fogs && data.defaults.fog ) {
1133 
1134 		result.scene.fog = result.fogs[ data.defaults.fog ];
1135 
1136 	}
1137 
1138 	c = data.defaults.bgcolor;
1139 	result.bgColor = new THREE.Color();
1140 	result.bgColor.setRGB( c[0], c[1], c[2] );
1141 
1142 	result.bgColorAlpha = data.defaults.bgalpha;
1143 
1144 	// synchronous callback
1145 
1146 	scope.callbackSync( result );
1147 
1148 	// just in case there are no async elements
1149 
1150 	async_callback_gate();
1151 
1152 };
1153 

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