source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/mrdoob-three.js-4862f5f/src/loaders/SceneLoader.js@ 28897

Last change on this file since 28897 was 28897, checked in by davidb, 10 years ago

GUI front-end to server base plus web page content

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