OSDN Git Service

three.jsをThirdPartyに追加
[webglgame/webgl_framework.git] / webglFramework / Thirdparty / three.js-master / examples / js / loaders / 3MFLoader.js
1 /**
2  * @author technohippy / https://github.com/technohippy
3  */
4
5 THREE.ThreeMFLoader = function ( manager ) {
6
7         this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
8         this.availableExtensions = [];
9
10 };
11
12 THREE.ThreeMFLoader.prototype = {
13
14         constructor: THREE.ThreeMFLoader,
15
16         load: function ( url, onLoad, onProgress, onError ) {
17
18                 var scope = this;
19                 var loader = new THREE.FileLoader( scope.manager );
20                 loader.setResponseType( 'arraybuffer' );
21                 loader.load( url, function( buffer ) {
22
23                         onLoad( scope.parse( buffer ) );
24
25                 }, onProgress, onError );
26
27         },
28
29         parse: function ( data ) {
30
31                 var scope = this;
32
33                 function loadDocument( data ) {
34
35                         var zip = null;
36                         var file = null;
37
38                         var relsName;
39                         var modelPartNames = [];
40                         var printTicketPartNames = [];
41                         var texturesPartNames = [];
42                         var otherPartNames = [];
43
44                         var rels;
45                         var modelParts = {};
46                         var printTicketParts = {};
47                         var texturesParts = {};
48                         var otherParts = {};
49
50                         try {
51
52                                 zip = new JSZip( data );
53
54                         } catch ( e ) {
55
56                                 if ( e instanceof ReferenceError ) {
57
58                                         console.error( 'THREE.ThreeMFLoader: jszip missing and file is compressed.' );
59                                         return null;
60
61                                 }
62
63                         }
64
65                         for ( file in zip.files ) {
66
67                                 if ( file.match( /\.rels$/ ) ) {
68
69                                         relsName = file;
70
71                                 } else if ( file.match(/^3D\/.*\.model$/) ) {
72
73                                         modelPartNames.push( file );
74
75                                 } else if ( file.match(/^3D\/Metadata\/.*\.xml$/) ) {
76
77                                         printTicketPartNames.push( file );
78
79                                 } else if ( file.match(/^3D\/Textures\/.*/) ) {
80
81                                         texturesPartNames.push( file );
82
83                                 } else if ( file.match(/^3D\/Other\/.*/) ) {
84
85                                         otherPartNames.push( file );
86
87                                 }
88
89                         }
90
91                         var relsView = new DataView( zip.file( relsName ).asArrayBuffer() );
92                         var relsFileText = new TextDecoder( 'utf-8' ).decode( relsView );
93                         rels = parseRelsXml( relsFileText );
94
95                         for ( var i = 0; i < modelPartNames.length; i++ ) {
96
97                                 var modelPart = modelPartNames[ i ];
98                                 var view = new DataView( zip.file( modelPart ).asArrayBuffer() );
99
100                                 if ( TextDecoder === undefined ) {
101
102                                         console.error( 'THREE.ThreeMFLoader: TextDecoder not present. Please use a TextDecoder polyfill.' );
103                                         return null;
104
105                                 }
106
107                                 var fileText = new TextDecoder( 'utf-8' ).decode( view );
108                                 var xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
109
110                                 if ( xmlData.documentElement.nodeName.toLowerCase() !== 'model' ) {
111
112                                         console.error( 'THREE.ThreeMFLoader: Error loading 3MF - no 3MF document found: ', modelPart );
113
114                                 }
115
116                                 var modelNode = xmlData.querySelector( 'model' );
117                                 var extensions = {};
118
119                                 for ( var i = 0; i < modelNode.attributes.length; i++ ) {
120
121                                         var attr = modelNode.attributes[ i ];
122                                         if ( attr.name.match( /^xmlns:(.+)$/ ) ) {
123
124                                                 extensions[ attr.value ] = RegExp.$1;
125
126                                         }
127
128                                 }
129
130                                 var modelData = parseModelNode( modelNode );
131                                 modelData[ 'xml' ] = modelNode;
132
133                                 if ( 0 < Object.keys( extensions ).length ) {
134
135                                         modelData[ 'extensions' ] = extensions;
136
137                                 }
138
139                                 modelParts[ modelPart ] = modelData;
140
141                         }
142
143                         for ( var i = 0; i < texturesPartNames.length; i++ ) {
144
145                                 var texturesPartName = texturesPartNames[ i ];
146                                 texturesParts[ texturesPartName ] = zip.file( texturesPartName ).asBinary();
147
148                         }
149
150                         return {
151                                 rels: rels,
152                                 model: modelParts,
153                                 printTicket: printTicketParts,
154                                 texture: texturesParts,
155                                 other: otherParts
156                         };
157                 }
158
159                 function parseRelsXml( relsFileText ) {
160
161                         var relsXmlData = new DOMParser().parseFromString( relsFileText, 'application/xml' );
162                         var relsNode = relsXmlData.querySelector( 'Relationship' );
163                         var target = relsNode.getAttribute( 'Target' );
164                         var id = relsNode.getAttribute( 'Id' );
165                         var type = relsNode.getAttribute( 'Type' );
166
167                         return {
168                                 target: target,
169                                 id: id,
170                                 type: type
171                         };
172
173                 }
174
175                 function parseMetadataNodes( metadataNodes ) {
176
177                         var metadataData = {};
178
179                         for ( var i = 0; i < metadataNodes.length; i++ ) {
180
181                                 var metadataNode = metadataNodes[ i ];
182                                 var name = metadataNode.getAttribute('name');
183                                 var validNames = [
184                                         'Title',
185                                         'Designer',
186                                         'Description',
187                                         'Copyright',
188                                         'LicenseTerms',
189                                         'Rating',
190                                         'CreationDate',
191                                         'ModificationDate'
192                                 ];
193
194                                 if ( 0 <= validNames.indexOf( name ) ) {
195
196                                         metadataData[ name ] = metadataNode.textContent;
197
198                                 }
199
200                         }
201
202                         return metadataData;
203
204                 }
205
206                 function parseBasematerialsNode( basematerialsNode ) {
207                 }
208
209                 function parseMeshNode( meshNode, extensions ) {
210
211                         var meshData = {};
212
213                         var vertices = [];
214                         var vertexNodes = meshNode.querySelectorAll( 'vertices vertex' );
215
216                         for ( var i = 0; i < vertexNodes.length; i++ ) {
217
218                                 var vertexNode = vertexNodes[ i ];
219                                 var x = vertexNode.getAttribute( 'x' );
220                                 var y = vertexNode.getAttribute( 'y' );
221                                 var z = vertexNode.getAttribute( 'z' );
222
223                                 vertices.push( parseFloat( x ), parseFloat( y ), parseFloat( z ) );
224
225                         }
226
227                         meshData[ 'vertices' ] = new Float32Array( vertices.length );
228
229                         for ( var i = 0; i < vertices.length; i++ ) {
230
231                                 meshData[ 'vertices' ][ i ] = vertices[ i ];
232
233                         }
234
235                         var triangleProperties = [];
236                         var triangles = [];
237                         var triangleNodes = meshNode.querySelectorAll( 'triangles triangle' );
238
239                         for ( var i = 0; i < triangleNodes.length; i++ ) {
240
241                                 var triangleNode = triangleNodes[ i ];
242                                 var v1 = triangleNode.getAttribute( 'v1' );
243                                 var v2 = triangleNode.getAttribute( 'v2' );
244                                 var v3 = triangleNode.getAttribute( 'v3' );
245                                 var p1 = triangleNode.getAttribute( 'p1' );
246                                 var p2 = triangleNode.getAttribute( 'p2' );
247                                 var p3 = triangleNode.getAttribute( 'p3' );
248                                 var pid = triangleNode.getAttribute( 'pid' );
249
250                                 triangles.push( parseInt( v1, 10 ), parseInt( v2, 10 ), parseInt( v3, 10 ) );
251
252                                 var triangleProperty = {};
253
254                                 if ( p1 ) {
255
256                                         triangleProperty[ 'p1' ] = parseInt( p1, 10 );
257
258                                 }
259
260                                 if ( p2 ) {
261
262                                         triangleProperty[ 'p2' ] = parseInt( p2, 10 );
263
264                                 }
265
266                                 if ( p3 ) {
267
268                                         triangleProperty[ 'p3' ] = parseInt( p3, 10 );
269
270                                 }
271
272                                 if ( pid ) {
273
274                                         triangleProperty[ 'pid' ] = pid;
275
276                                 }
277
278                                 if ( 0 < Object.keys( triangleProperty ).length ) {
279
280                                         triangleProperties.push( triangleProperty );
281
282                                 }
283                         }
284
285                         meshData[ 'triangleProperties' ] = triangleProperties;
286                         meshData[ 'triangles' ] = new Uint32Array( triangles.length );
287
288                         for ( var i = 0; i < triangles.length; i++ ) {
289
290                                 meshData[ 'triangles' ][ i ] = triangles[ i ];
291
292                         }
293
294                         return meshData;
295
296                 }
297
298                 function parseComponentsNode( componentsNode ) {
299
300                 }
301
302                 function parseObjectNode( objectNode ) {
303
304                         var objectData = {
305                                 type: objectNode.getAttribute( 'type' )
306                         };
307
308                         var id = objectNode.getAttribute( 'id' );
309
310                         if ( id ) {
311
312                                 objectData[ 'id' ] = id;
313
314                         }
315
316                         var pid = objectNode.getAttribute( 'pid' );
317
318                         if ( pid ) {
319
320                                 objectData[ 'pid' ] = pid;
321
322                         }
323
324                         var pindex = objectNode.getAttribute( 'pindex' );
325
326                         if ( pindex ) {
327
328                                 objectData[ 'pindex' ] = pindex;
329
330                         }
331
332                         var thumbnail = objectNode.getAttribute( 'thumbnail' );
333
334                         if ( thumbnail ) {
335
336                                 objectData[ 'thumbnail' ] = thumbnail;
337
338                         }
339
340                         var partnumber = objectNode.getAttribute( 'partnumber' );
341
342                         if ( partnumber ) {
343
344                                 objectData[ 'partnumber' ] = partnumber;
345
346                         }
347
348                         var name = objectNode.getAttribute( 'name' );
349
350                         if ( name ) {
351
352                                 objectData[ 'name' ] = name;
353
354                         }
355
356                         var meshNode = objectNode.querySelector( 'mesh' );
357
358                         if ( meshNode ) {
359
360                                 objectData[ 'mesh' ] = parseMeshNode( meshNode );
361
362                         }
363
364                         var componentsNode = objectNode.querySelector( 'components' );
365
366                         if ( componentsNode ) {
367
368                                 objectData[ 'components' ] = parseComponentsNode( componentsNode );
369
370                         }
371
372                         return objectData;
373
374                 }
375
376                 function parseResourcesNode( resourcesNode ) {
377
378                         var resourcesData = {};
379                         var basematerialsNode = resourcesNode.querySelector( 'basematerials' );
380
381                         if ( basematerialsNode ) {
382
383                                 resourcesData[ 'basematerial' ] = parseBasematerialsNode( basematerialsNode );
384
385                         }
386
387                         resourcesData[ 'object' ] = {};
388                         var objectNodes = resourcesNode.querySelectorAll( 'object' );
389
390                         for ( var i = 0; i < objectNodes.length; i++ ) {
391
392                                 var objectNode = objectNodes[ i ];
393                                 var objectData = parseObjectNode( objectNode );
394                                 resourcesData[ 'object' ][ objectData[ 'id' ] ] = objectData;
395
396                         }
397
398                         return resourcesData;
399
400                 }
401
402                 function parseBuildNode( buildNode ) {
403
404                         var buildData = [];
405                         var itemNodes = buildNode.querySelectorAll( 'item' );
406
407                         for ( var i = 0; i < itemNodes.length; i++ ) {
408
409                                 var itemNode = itemNodes[ i ];
410                                 var buildItem =  {
411                                         objectid: itemNode.getAttribute( 'objectid' )
412                                 };
413                                 var transform = itemNode.getAttribute( 'transform' );
414
415                                 if ( transform ) {
416
417                                         var t = [];
418                                         transform.split( ' ' ).forEach( function( s ) {
419                                                 t.push( parseFloat( s ) );
420                                         } );
421                                         var mat4 = new THREE.Matrix4();
422                                         buildItem[ 'transform' ] = mat4.set(
423                                                 t[ 0 ], t[  3 ], t[  6 ], t[  9 ],
424                                                 t[ 1 ], t[  4 ], t[  7 ], t[ 10 ],
425                                                 t[ 2 ], t[  5 ], t[  8 ], t[ 11 ],
426                                                    0.0,     0.0,     0.0,     1.0
427                                         );
428
429                                 }
430
431                                 buildData.push( buildItem );
432
433                         }
434
435                         return buildData;
436
437                 }
438
439                 function parseModelNode( modelNode ) {
440
441                         var modelData = { unit: modelNode.getAttribute( 'unit' ) || 'millimeter' };
442                         var metadataNodes = modelNode.querySelectorAll( 'metadata' );
443
444                         if ( metadataNodes ) {
445
446                                 modelData[ 'metadata' ] = parseMetadataNodes( metadataNodes );
447
448                         }
449
450                         var resourcesNode = modelNode.querySelector( 'resources' );
451
452                         if ( resourcesNode ) {
453
454                                 modelData[ 'resources' ] = parseResourcesNode( resourcesNode );
455
456                         }
457
458                         var buildNode = modelNode.querySelector( 'build' );
459
460                         if ( buildNode ) {
461
462                                 modelData[ 'build' ] = parseBuildNode( buildNode );
463
464                         }
465
466                         return modelData;
467
468                 }
469
470                 function buildMesh( meshData, data3mf ) {
471
472                         var geometry = new THREE.BufferGeometry();
473                         geometry.setIndex( new THREE.BufferAttribute( meshData[ 'triangles' ], 1 ) );
474                         geometry.addAttribute( 'position', new THREE.BufferAttribute( meshData[ 'vertices' ], 3 ) );
475
476                         if ( meshData[ 'colors' ] ) {
477
478                                 geometry.addAttribute( 'color', new THREE.BufferAttribute( meshData[ 'colors' ], 3 ) );
479
480                         }
481
482                         geometry.computeBoundingSphere();
483
484                         var materialOpts = {
485                                 flatShading: true
486                         };
487
488                         if ( meshData[ 'colors' ] && 0 < meshData[ 'colors' ].length ) {
489
490                                 materialOpts[ 'vertexColors' ] = THREE.VertexColors;
491
492                         } else {
493
494                                 materialOpts[ 'color' ] = 0xaaaaff;
495
496                         }
497
498                         var material = new THREE.MeshPhongMaterial( materialOpts );
499                         return new THREE.Mesh( geometry, material );
500
501                 }
502
503                 function applyExtensions( extensions, meshData, modelXml, data3mf ) {
504
505                         if ( ! extensions ) {
506
507                                 return;
508
509                         }
510
511                         var availableExtensions = [];
512                         var keys = Object.keys( extensions );
513
514                         for ( var i = 0; i < keys.length; i++ ) {
515
516                                 var ns = keys[ i ];
517
518                                 for ( var j = 0; j < scope.availableExtensions.length; j++ ) {
519
520                                         var extension = scope.availableExtensions[ j ];
521
522                                         if ( extension.ns === ns ) {
523
524                                                 availableExtensions.push( extension );
525
526                                         }
527
528                                 }
529
530                         }
531
532                         for ( var i = 0; i < availableExtensions.length; i++ ) {
533
534                                 var extension = availableExtensions[ i ];
535                                 extension.apply( modelXml, extensions[ extension[ 'ns' ] ], meshData );
536
537                         }
538
539                 }
540
541                 function buildMeshes( data3mf ) {
542
543                         var modelsData = data3mf.model;
544                         var meshes = {};
545                         var modelsKeys = Object.keys( modelsData );
546
547                         for ( var i = 0; i < modelsKeys.length; i++ ) {
548
549                                 var modelsKey = modelsKeys[ i ];
550                                 var modelData = modelsData[ modelsKey ];
551                                 var modelXml = modelData[ 'xml' ];
552                                 var extensions = modelData[ 'extensions' ];
553
554                                 var objectIds = Object.keys( modelData[ 'resources' ][ 'object' ] );
555
556                                 for ( var j = 0; j < objectIds.length; j++ ) {
557
558                                         var objectId = objectIds[ j ];
559                                         var objectData = modelData[ 'resources' ][ 'object' ][ objectId ];
560                                         var meshData = objectData[ 'mesh' ];
561                                         applyExtensions( extensions, meshData, modelXml, data3mf );
562                                         meshes[ objectId ] = buildMesh( meshData, data3mf );
563
564                                 }
565
566                         }
567
568                         return meshes;
569
570                 }
571
572                 function build( meshes, refs, data3mf ) {
573
574                         var group = new THREE.Group();
575                         var buildData = data3mf.model[ refs[ 'target' ].substring( 1 ) ][ 'build' ];
576
577                         for ( var i = 0; i < buildData.length; i++ ) {
578
579                                 var buildItem = buildData[ i ];
580                                 var mesh = meshes[ buildItem[ 'objectid' ] ];
581
582                                 if ( buildItem[ 'transform' ] ) {
583
584                                         mesh.geometry.applyMatrix( buildItem[ 'transform' ] );
585
586                                 }
587
588                                 group.add( mesh );
589
590                         }
591
592                         return group;
593
594                 }
595
596                 var data3mf = loadDocument( data );
597                 var meshes = buildMeshes( data3mf );
598
599                 return build( meshes, data3mf[ 'rels' ], data3mf );
600
601         },
602
603         addExtension: function( extension ) {
604
605                 this.availableExtensions.push( extension );
606
607         }
608
609 };