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