elation-engine 0.9.113 → 0.9.115

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/css/systems/render.css +5 -1
  2. package/package.json +1 -1
  3. package/scripts/assets.js +103 -20
  4. package/scripts/assetworker.js +18 -1
  5. package/scripts/external/holoplay.js +1494 -0
  6. package/scripts/external/octree.js +0 -0
  7. package/scripts/external/three/CSS3DRenderer.js +46 -43
  8. package/scripts/external/three/CubemapToEquirectangular.js +1 -1
  9. package/scripts/external/three/three-extras.js +1553 -392
  10. package/scripts/external/three/three-icosa.js +2575 -0
  11. package/scripts/external/three/three-loaders.js +925 -133
  12. package/scripts/external/three/three-postprocessing.js +3 -3
  13. package/scripts/external/three/three-r116dev.js +50930 -0
  14. package/scripts/external/three/three-spotlighttextures.js +50953 -0
  15. package/scripts/external/three/three-vrm.js +2 -2
  16. package/scripts/external/three/three-working.js +35968 -0
  17. package/scripts/external/three/three.js +38532 -24087
  18. package/scripts/external/three-mesh-bvh.js +5370 -0
  19. package/scripts/external/three-old/BVHLoader.js +406 -0
  20. package/scripts/external/three-old/ColladaLoader.js +5519 -0
  21. package/scripts/external/three-old/ColladaLoader2.js +1694 -0
  22. package/scripts/external/three-old/CubemapToEquirectangular.js +188 -0
  23. package/scripts/external/three-old/DDSLoader.js +269 -0
  24. package/scripts/external/three-old/FBXLoader-mine.js +5063 -0
  25. package/scripts/external/three-old/FBXLoader.js +5112 -0
  26. package/scripts/external/three-old/FlyControls.js +295 -0
  27. package/scripts/external/three-old/GLTF2Loader.js +2950 -0
  28. package/scripts/external/three-old/GLTFLoader.js +2213 -0
  29. package/scripts/external/three-old/JSONLoader.js +435 -0
  30. package/scripts/external/three-old/MTLLoader.js +533 -0
  31. package/scripts/external/three-old/OBJLoader-experimental.js +874 -0
  32. package/scripts/external/three-old/OBJLoader-working.js +727 -0
  33. package/scripts/external/three-old/OBJLoader.js +723 -0
  34. package/scripts/external/three-old/OBJMTLLoader.js +440 -0
  35. package/scripts/external/three-old/OrbitControls.js +592 -0
  36. package/scripts/external/three-old/PLYLoader.js +517 -0
  37. package/scripts/external/three-old/TransformControls.js +1100 -0
  38. package/scripts/external/three-old/VRMLLoader.js +1021 -0
  39. package/scripts/external/three-old/glTFLoader-combined.js +2513 -0
  40. package/scripts/external/three-old/nodethree.js +44018 -0
  41. package/scripts/external/three-old/render/BleachBypassShader.js +64 -0
  42. package/scripts/external/three-old/render/BloomPass.js +116 -0
  43. package/scripts/external/three-old/render/CSS3DRenderer.js +310 -0
  44. package/scripts/external/three-old/render/ClearPass.js +44 -0
  45. package/scripts/external/three-old/render/ConvolutionShader.js +101 -0
  46. package/scripts/external/three-old/render/CopyShader.js +46 -0
  47. package/scripts/external/three-old/render/EffectComposer.js +211 -0
  48. package/scripts/external/three-old/render/FXAAShader.js +88 -0
  49. package/scripts/external/three-old/render/FilmPass.js +60 -0
  50. package/scripts/external/three-old/render/FilmShader.js +104 -0
  51. package/scripts/external/three-old/render/ManualMSAARenderPass.js +168 -0
  52. package/scripts/external/three-old/render/MaskPass.js +97 -0
  53. package/scripts/external/three-old/render/OculusRenderPass.js +84 -0
  54. package/scripts/external/three-old/render/OculusRiftEffect.js +240 -0
  55. package/scripts/external/three-old/render/PortalRenderPass.js +166 -0
  56. package/scripts/external/three-old/render/RecordingPass.js +208 -0
  57. package/scripts/external/three-old/render/RenderPass.js +57 -0
  58. package/scripts/external/three-old/render/SSAOShader.js +259 -0
  59. package/scripts/external/three-old/render/SepiaShader.js +54 -0
  60. package/scripts/external/three-old/render/ShaderPass.js +66 -0
  61. package/scripts/external/three-old/render/VREffect.js +482 -0
  62. package/scripts/external/three-old/shimthree.js +23 -0
  63. package/scripts/external/three-old/stats.js +6 -0
  64. package/scripts/external/three-old/three-88dev.js +45004 -0
  65. package/scripts/external/three-old/three-backgroundoptimization.js +44432 -0
  66. package/scripts/external/three-old/three-updates.js +44735 -0
  67. package/scripts/external/three-old/three-working.js +44719 -0
  68. package/scripts/external/three-old/three.js +44431 -0
  69. package/scripts/external/three-old/threex.rendererstats.js +66 -0
  70. package/scripts/external/three-old/tween.js +13 -0
  71. package/scripts/external/webvr-polyfill-new.js +3497 -0
  72. package/scripts/external/webvr-polyfill-newest.js +3491 -0
  73. package/scripts/external/webvr-polyfill-old.js +6337 -0
  74. package/scripts/geometries.js +2 -2
  75. package/scripts/math.js +6 -6
  76. package/scripts/systems/admin.js +1 -1
  77. package/scripts/systems/controls.js +6 -4
  78. package/scripts/systems/physics.js +10 -10
  79. package/scripts/systems/render.js +58 -20
  80. package/scripts/systems/render2.js +38 -0
  81. package/scripts/things/camera.js +6 -1
  82. package/scripts/things/generic-trackedvectors.js +1875 -0
  83. package/scripts/things/generic.js +3 -4
  84. package/scripts/things/label2d.js +1 -1
  85. package/scripts/things/leapmotion.js +6 -6
  86. package/scripts/things/menu.js +1 -1
  87. package/scripts/things/player-bak.js +638 -0
  88. package/scripts/things/player.js +28 -10
  89. package/scripts/things/skysphere.js +1 -1
  90. package/scripts/things/terrain.js +1 -1
  91. package/scripts/things/text.js +1 -1
@@ -0,0 +1,1021 @@
1
+ /**
2
+ * @author mrdoob / http://mrdoob.com/
3
+ */
4
+
5
+ THREE.VRMLLoader = function ( manager ) {
6
+
7
+ this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
8
+
9
+ };
10
+
11
+ THREE.VRMLLoader.prototype = {
12
+
13
+ constructor: THREE.VRMLLoader,
14
+
15
+ // for IndexedFaceSet support
16
+ isRecordingPoints: false,
17
+ isRecordingFaces: false,
18
+ points: [],
19
+ indexes : [],
20
+
21
+ // for Background support
22
+ isRecordingAngles: false,
23
+ isRecordingColors: false,
24
+ angles: [],
25
+ colors: [],
26
+
27
+ recordingFieldname: null,
28
+
29
+ load: function ( url, onLoad, onProgress, onError ) {
30
+
31
+ var scope = this;
32
+
33
+ var loader = new THREE.XHRLoader( this.manager );
34
+ loader.load( url, function ( text ) {
35
+
36
+ onLoad( scope.parse( text ) );
37
+
38
+ }, onProgress, onError );
39
+
40
+ },
41
+
42
+ setCrossOrigin: function ( value ) {
43
+
44
+ this.crossOrigin = value;
45
+
46
+ },
47
+
48
+ parse: function ( data ) {
49
+
50
+ var texturePath = this.texturePath || '';
51
+
52
+ var textureLoader = new THREE.TextureLoader( this.manager );
53
+ textureLoader.setCrossOrigin( this.crossOrigin );
54
+
55
+ var parseV1 = function ( lines, scene ) {
56
+
57
+ console.warn( 'VRML V1.0 not supported yet' );
58
+
59
+ };
60
+
61
+ var parseV2 = function ( lines, scene ) {
62
+
63
+ var defines = {};
64
+ var float_pattern = /(\b|\-|\+)([\d\.e]+)/;
65
+ var float2_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
66
+ var float3_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
67
+
68
+ /**
69
+ * Interpolates colors a and b following their relative distance
70
+ * expressed by t.
71
+ *
72
+ * @param float a
73
+ * @param float b
74
+ * @param float t
75
+ * @returns {Color}
76
+ */
77
+ var interpolateColors = function( a, b, t ) {
78
+
79
+ var deltaR = a.r - b.r;
80
+ var deltaG = a.g - b.g;
81
+ var deltaB = a.b - b.b;
82
+
83
+ var c = new THREE.Color();
84
+
85
+ c.r = a.r - t * deltaR;
86
+ c.g = a.g - t * deltaG;
87
+ c.b = a.b - t * deltaB;
88
+
89
+ return c;
90
+
91
+ };
92
+
93
+ /**
94
+ * Vertically paints the faces interpolating between the
95
+ * specified colors at the specified angels. This is used for the Background
96
+ * node, but could be applied to other nodes with multiple faces as well.
97
+ *
98
+ * When used with the Background node, default is directionIsDown is true if
99
+ * interpolating the skyColor down from the Zenith. When interpolationg up from
100
+ * the Nadir i.e. interpolating the groundColor, the directionIsDown is false.
101
+ *
102
+ * The first angle is never specified, it is the Zenith (0 rad). Angles are specified
103
+ * in radians. The geometry is thought a sphere, but could be anything. The color interpolation
104
+ * is linear along the Y axis in any case.
105
+ *
106
+ * You must specify one more color than you have angles at the beginning of the colors array.
107
+ * This is the color of the Zenith (the top of the shape).
108
+ *
109
+ * @param geometry
110
+ * @param radius
111
+ * @param angles
112
+ * @param colors
113
+ * @param boolean directionIsDown Whether to work bottom up or top down.
114
+ */
115
+ var paintFaces = function ( geometry, radius, angles, colors, directionIsDown ) {
116
+
117
+ var f, n, p, vertexIndex, color;
118
+
119
+ var direction = directionIsDown ? 1 : - 1;
120
+
121
+ var faceIndices = [ 'a', 'b', 'c', 'd' ];
122
+
123
+ var coord = [ ], aColor, bColor, t = 1, A = {}, B = {}, applyColor = false, colorIndex;
124
+
125
+ for ( var k = 0; k < angles.length; k ++ ) {
126
+
127
+ var vec = { };
128
+
129
+ // push the vector at which the color changes
130
+ vec.y = direction * ( Math.cos( angles[ k ] ) * radius );
131
+
132
+ vec.x = direction * ( Math.sin( angles[ k ] ) * radius );
133
+
134
+ coord.push( vec );
135
+
136
+ }
137
+
138
+ // painting the colors on the faces
139
+ for ( var i = 0; i < geometry.faces.length ; i ++ ) {
140
+
141
+ f = geometry.faces[ i ];
142
+
143
+ n = ( f instanceof THREE.Face3 ) ? 3 : 4;
144
+
145
+ for ( var j = 0; j < n; j ++ ) {
146
+
147
+ vertexIndex = f[ faceIndices[ j ] ];
148
+
149
+ p = geometry.vertices[ vertexIndex ];
150
+
151
+ for ( var index = 0; index < colors.length; index ++ ) {
152
+
153
+ // linear interpolation between aColor and bColor, calculate proportion
154
+ // A is previous point (angle)
155
+ if ( index === 0 ) {
156
+
157
+ A.x = 0;
158
+ A.y = directionIsDown ? radius : - 1 * radius;
159
+
160
+ } else {
161
+
162
+ A.x = coord[ index - 1 ].x;
163
+ A.y = coord[ index - 1 ].y;
164
+
165
+ }
166
+
167
+ // B is current point (angle)
168
+ B = coord[ index ];
169
+
170
+ if ( undefined !== B ) {
171
+
172
+ // p has to be between the points A and B which we interpolate
173
+ applyColor = directionIsDown ? p.y <= A.y && p.y > B.y : p.y >= A.y && p.y < B.y;
174
+
175
+ if ( applyColor ) {
176
+
177
+ bColor = colors[ index + 1 ];
178
+
179
+ aColor = colors[ index ];
180
+
181
+ // below is simple linear interpolation
182
+ t = Math.abs( p.y - A.y ) / ( A.y - B.y );
183
+
184
+ // to make it faster, you can only calculate this if the y coord changes, the color is the same for points with the same y
185
+ color = interpolateColors( aColor, bColor, t );
186
+
187
+ f.vertexColors[ j ] = color;
188
+
189
+ }
190
+
191
+ } else if ( undefined === f.vertexColors[ j ] ) {
192
+
193
+ colorIndex = directionIsDown ? colors.length - 1 : 0;
194
+ f.vertexColors[ j ] = colors[ colorIndex ];
195
+
196
+ }
197
+
198
+ }
199
+
200
+ }
201
+
202
+ }
203
+
204
+ };
205
+
206
+ var index = [];
207
+
208
+ var parseProperty = function ( node, line ) {
209
+
210
+ var parts = [], part, property = {}, fieldName;
211
+
212
+ /**
213
+ * Expression for matching relevant information, such as a name or value, but not the separators
214
+ * @type {RegExp}
215
+ */
216
+ var regex = /[^\s,\[\]]+/g;
217
+
218
+ var point, angles, colors;
219
+
220
+ while ( null != ( part = regex.exec( line ) ) ) {
221
+
222
+ parts.push( part[ 0 ] );
223
+
224
+ }
225
+
226
+ fieldName = parts[ 0 ];
227
+
228
+
229
+ // trigger several recorders
230
+ switch ( fieldName ) {
231
+ case 'skyAngle':
232
+ case 'groundAngle':
233
+ this.recordingFieldname = fieldName;
234
+ this.isRecordingAngles = true;
235
+ this.angles = [];
236
+ break;
237
+ case 'skyColor':
238
+ case 'groundColor':
239
+ this.recordingFieldname = fieldName;
240
+ this.isRecordingColors = true;
241
+ this.colors = [];
242
+ break;
243
+ case 'point':
244
+ this.recordingFieldname = fieldName;
245
+ this.isRecordingPoints = true;
246
+ this.points = [];
247
+ break;
248
+ case 'coordIndex':
249
+ case 'texCoordIndex':
250
+ this.recordingFieldname = fieldName;
251
+ this.isRecordingFaces = true;
252
+ this.indexes = [];
253
+ }
254
+
255
+ if ( this.isRecordingFaces ) {
256
+
257
+ // the parts hold the indexes as strings
258
+ if ( parts.length > 0 ) {
259
+
260
+ for ( var ind = 0; ind < parts.length; ind ++ ) {
261
+
262
+ // the part should either be positive integer or -1
263
+ if ( ! /(-?\d+)/.test( parts[ ind ] ) ) {
264
+
265
+ continue;
266
+
267
+ }
268
+
269
+ // end of current face
270
+ if ( parts[ ind ] === "-1" ) {
271
+
272
+ if ( index.length > 0 ) {
273
+
274
+ this.indexes.push( index );
275
+
276
+ }
277
+
278
+ // start new one
279
+ index = [];
280
+
281
+ } else {
282
+
283
+ index.push( parseInt( parts[ ind ] ) );
284
+
285
+ }
286
+
287
+ }
288
+
289
+ }
290
+
291
+ // end
292
+ if ( /]/.exec( line ) ) {
293
+
294
+ if ( index.length > 0 ) {
295
+
296
+ this.indexes.push( index );
297
+
298
+ }
299
+
300
+ // start new one
301
+ index = [];
302
+
303
+ this.isRecordingFaces = false;
304
+ node[this.recordingFieldname] = this.indexes;
305
+
306
+ }
307
+
308
+ } else if ( this.isRecordingPoints ) {
309
+
310
+ if ( node.nodeType == 'Coordinate' )
311
+
312
+ while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
313
+
314
+ point = {
315
+ x: parseFloat( parts[ 1 ] ),
316
+ y: parseFloat( parts[ 2 ] ),
317
+ z: parseFloat( parts[ 3 ] )
318
+ };
319
+
320
+ this.points.push( point );
321
+
322
+ }
323
+
324
+ if ( node.nodeType == 'TextureCoordinate' )
325
+
326
+ while ( null !== ( parts = float2_pattern.exec( line ) ) ) {
327
+
328
+ point = {
329
+ x: parseFloat( parts[ 1 ] ),
330
+ y: parseFloat( parts[ 2 ] )
331
+ };
332
+
333
+ this.points.push( point );
334
+
335
+ }
336
+
337
+ // end
338
+ if ( /]/.exec( line ) ) {
339
+
340
+ this.isRecordingPoints = false;
341
+ node.points = this.points;
342
+
343
+ }
344
+
345
+ } else if ( this.isRecordingAngles ) {
346
+
347
+ // the parts hold the angles as strings
348
+ if ( parts.length > 0 ) {
349
+
350
+ for ( var ind = 0; ind < parts.length; ind ++ ) {
351
+
352
+ // the part should be a float
353
+ if ( ! float_pattern.test( parts[ ind ] ) ) {
354
+
355
+ continue;
356
+
357
+ }
358
+
359
+ this.angles.push( parseFloat( parts[ ind ] ) );
360
+
361
+ }
362
+
363
+ }
364
+
365
+ // end
366
+ if ( /]/.exec( line ) ) {
367
+
368
+ this.isRecordingAngles = false;
369
+ node[ this.recordingFieldname ] = this.angles;
370
+
371
+ }
372
+
373
+ } else if ( this.isRecordingColors ) {
374
+
375
+ while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
376
+
377
+ color = {
378
+ r: parseFloat( parts[ 1 ] ),
379
+ g: parseFloat( parts[ 2 ] ),
380
+ b: parseFloat( parts[ 3 ] )
381
+ };
382
+
383
+ this.colors.push( color );
384
+
385
+ }
386
+
387
+ // end
388
+ if ( /]/.exec( line ) ) {
389
+
390
+ this.isRecordingColors = false;
391
+ node[ this.recordingFieldname ] = this.colors;
392
+
393
+ }
394
+
395
+ } else if ( parts[ parts.length - 1 ] !== 'NULL' && fieldName !== 'children' ) {
396
+
397
+ switch ( fieldName ) {
398
+
399
+ case 'diffuseColor':
400
+ case 'emissiveColor':
401
+ case 'specularColor':
402
+ case 'color':
403
+
404
+ if ( parts.length != 4 ) {
405
+
406
+ console.warn( 'Invalid color format detected for ' + fieldName );
407
+ break;
408
+
409
+ }
410
+
411
+ property = {
412
+ r: parseFloat( parts[ 1 ] ),
413
+ g: parseFloat( parts[ 2 ] ),
414
+ b: parseFloat( parts[ 3 ] )
415
+ };
416
+
417
+ break;
418
+
419
+ case 'translation':
420
+ case 'scale':
421
+ case 'size':
422
+ if ( parts.length != 4 ) {
423
+
424
+ console.warn( 'Invalid vector format detected for ' + fieldName );
425
+ break;
426
+
427
+ }
428
+
429
+ property = {
430
+ x: parseFloat( parts[ 1 ] ),
431
+ y: parseFloat( parts[ 2 ] ),
432
+ z: parseFloat( parts[ 3 ] )
433
+ };
434
+
435
+ break;
436
+
437
+ case 'radius':
438
+ case 'topRadius':
439
+ case 'bottomRadius':
440
+ case 'height':
441
+ case 'transparency':
442
+ case 'shininess':
443
+ case 'ambientIntensity':
444
+ if ( parts.length != 2 ) {
445
+
446
+ console.warn( 'Invalid single float value specification detected for ' + fieldName );
447
+ break;
448
+
449
+ }
450
+
451
+ property = parseFloat( parts[ 1 ] );
452
+
453
+ break;
454
+
455
+ case 'rotation':
456
+ if ( parts.length != 5 ) {
457
+
458
+ console.warn( 'Invalid quaternion format detected for ' + fieldName );
459
+ break;
460
+
461
+ }
462
+
463
+ property = {
464
+ x: parseFloat( parts[ 1 ] ),
465
+ y: parseFloat( parts[ 2 ] ),
466
+ z: parseFloat( parts[ 3 ] ),
467
+ w: parseFloat( parts[ 4 ] )
468
+ };
469
+
470
+ break;
471
+
472
+ case 'ccw':
473
+ case 'solid':
474
+ case 'colorPerVertex':
475
+ case 'convex':
476
+ if ( parts.length != 2 ) {
477
+
478
+ console.warn( 'Invalid format detected for ' + fieldName );
479
+ break;
480
+
481
+ }
482
+
483
+ property = parts[ 1 ] === 'TRUE' ? true : false;
484
+
485
+ break;
486
+ }
487
+
488
+ node[ fieldName ] = property;
489
+
490
+ }
491
+
492
+ return property;
493
+
494
+ };
495
+
496
+ var getTree = function ( lines ) {
497
+
498
+ var tree = { 'string': 'Scene', children: [] };
499
+ var current = tree;
500
+ var matches;
501
+ var specification;
502
+
503
+ for ( var i = 0; i < lines.length; i ++ ) {
504
+
505
+ var comment = '';
506
+
507
+ var line = lines[ i ];
508
+
509
+ // omit whitespace only lines
510
+ if ( null !== ( result = /^\s+?$/g.exec( line ) ) ) {
511
+
512
+ continue;
513
+
514
+ }
515
+
516
+ line = line.trim();
517
+
518
+ // skip empty lines
519
+ if ( line === '' ) {
520
+
521
+ continue;
522
+
523
+ }
524
+
525
+ if ( /#/.exec( line ) ) {
526
+
527
+ var parts = line.split( '#' );
528
+
529
+ // discard everything after the #, it is a comment
530
+ line = parts[ 0 ];
531
+
532
+ // well, let's also keep the comment
533
+ comment = parts[ 1 ];
534
+
535
+ }
536
+
537
+ if ( matches = /([^\s]*){1}(?:\s+)?{/.exec( line ) ) {
538
+
539
+ // first subpattern should match the Node name
540
+
541
+ var block = { 'nodeType' : matches[ 1 ], 'string': line, 'parent': current, 'children': [], 'comment' : comment };
542
+ current.children.push( block );
543
+ current = block;
544
+
545
+ if ( /}/.exec( line ) ) {
546
+
547
+ // example: geometry Box { size 1 1 1 } # all on the same line
548
+ specification = /{(.*)}/.exec( line )[ 1 ];
549
+
550
+ // todo: remove once new parsing is complete?
551
+ block.children.push( specification );
552
+
553
+ parseProperty( current, specification );
554
+
555
+ current = current.parent;
556
+
557
+ }
558
+
559
+ } else if ( /}/.exec( line ) ) {
560
+
561
+ current = current.parent;
562
+
563
+ } else if ( line !== '' ) {
564
+
565
+ parseProperty( current, line );
566
+ // todo: remove once new parsing is complete? we still do not parse geometry and appearance the new way
567
+ current.children.push( line );
568
+
569
+ }
570
+
571
+ }
572
+
573
+ return tree;
574
+
575
+ };
576
+
577
+ var parseNode = function ( data, parent ) {
578
+
579
+ // console.log( data );
580
+
581
+ if ( typeof data === 'string' ) {
582
+
583
+ if ( /USE/.exec( data ) ) {
584
+
585
+ var defineKey = /USE\s+?([^\s]+)/.exec( data )[ 1 ];
586
+
587
+ if ( undefined == defines[ defineKey ] ) {
588
+
589
+ console.warn( defineKey + ' is not defined.' );
590
+
591
+ } else {
592
+
593
+ if ( /appearance/.exec( data ) && defineKey ) {
594
+
595
+ parent.material = defines[ defineKey ].clone();
596
+
597
+ } else if ( /geometry/.exec( data ) && defineKey ) {
598
+
599
+ parent.geometry = defines[ defineKey ].clone();
600
+
601
+ // the solid property is not cloned with clone(), is only needed for VRML loading, so we need to transfer it
602
+ if ( undefined !== defines[ defineKey ].solid && defines[ defineKey ].solid === false ) {
603
+
604
+ parent.geometry.solid = false;
605
+ parent.material.side = THREE.DoubleSide;
606
+
607
+ }
608
+
609
+ } else if ( defineKey ) {
610
+
611
+ var object = defines[ defineKey ].clone();
612
+ parent.add( object );
613
+
614
+ }
615
+
616
+ }
617
+
618
+ }
619
+
620
+ return;
621
+
622
+ }
623
+
624
+ var object = parent;
625
+
626
+ if ( 'Transform' === data.nodeType || 'Group' === data.nodeType ) {
627
+
628
+ object = new THREE.Object3D();
629
+
630
+ if ( /DEF/.exec( data.string ) ) {
631
+
632
+ object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
633
+ defines[ object.name ] = object;
634
+
635
+ }
636
+
637
+ if ( undefined !== data[ 'translation' ] ) {
638
+
639
+ var t = data.translation;
640
+
641
+ object.position.set( t.x, t.y, t.z );
642
+
643
+ }
644
+
645
+ if ( undefined !== data.rotation ) {
646
+
647
+ var r = data.rotation;
648
+
649
+ object.quaternion.setFromAxisAngle( new THREE.Vector3( r.x, r.y, r.z ), r.w );
650
+
651
+ }
652
+
653
+ if ( undefined !== data.scale ) {
654
+
655
+ var s = data.scale;
656
+
657
+ object.scale.set( s.x, s.y, s.z );
658
+
659
+ }
660
+
661
+ parent.add( object );
662
+
663
+ } else if ( 'Shape' === data.nodeType ) {
664
+
665
+ object = new THREE.Mesh();
666
+
667
+ if ( /DEF/.exec( data.string ) ) {
668
+
669
+ object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
670
+
671
+ defines[ object.name ] = object;
672
+
673
+ }
674
+
675
+ parent.add( object );
676
+
677
+ } else if ( 'Background' === data.nodeType ) {
678
+
679
+ var segments = 20;
680
+
681
+ // sky (full sphere):
682
+
683
+ var radius = 2e4;
684
+
685
+ var skyGeometry = new THREE.SphereGeometry( radius, segments, segments );
686
+ var skyMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide } );
687
+
688
+ if ( data.skyColor.length > 1 ) {
689
+
690
+ paintFaces( skyGeometry, radius, data.skyAngle, data.skyColor, true );
691
+
692
+ skyMaterial.vertexColors = THREE.VertexColors
693
+
694
+ } else {
695
+
696
+ var color = data.skyColor[ 0 ];
697
+ skyMaterial.color.setRGB( color.r, color.b, color.g );
698
+
699
+ }
700
+
701
+ scene.add( new THREE.Mesh( skyGeometry, skyMaterial ) );
702
+
703
+ // ground (half sphere):
704
+
705
+ if ( data.groundColor !== undefined ) {
706
+
707
+ radius = 1.2e4;
708
+
709
+ var groundGeometry = new THREE.SphereGeometry( radius, segments, segments, 0, 2 * Math.PI, 0.5 * Math.PI, 1.5 * Math.PI );
710
+ var groundMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide, vertexColors: THREE.VertexColors } );
711
+
712
+ paintFaces( groundGeometry, radius, data.groundAngle, data.groundColor, false );
713
+
714
+ scene.add( new THREE.Mesh( groundGeometry, groundMaterial ) );
715
+
716
+ }
717
+
718
+ } else if ( /geometry/.exec( data.string ) ) {
719
+
720
+ if ( 'Box' === data.nodeType ) {
721
+
722
+ var s = data.size;
723
+
724
+ parent.geometry = new THREE.BoxGeometry( s.x, s.y, s.z );
725
+
726
+ } else if ( 'Cylinder' === data.nodeType ) {
727
+
728
+ parent.geometry = new THREE.CylinderGeometry( data.radius, data.radius, data.height );
729
+
730
+ } else if ( 'Cone' === data.nodeType ) {
731
+
732
+ parent.geometry = new THREE.CylinderGeometry( data.topRadius, data.bottomRadius, data.height );
733
+
734
+ } else if ( 'Sphere' === data.nodeType ) {
735
+
736
+ parent.geometry = new THREE.SphereGeometry( data.radius );
737
+
738
+ } else if ( 'IndexedFaceSet' === data.nodeType ) {
739
+
740
+ var geometry = new THREE.Geometry();
741
+
742
+ var indexes, uvIndexes, uvs;
743
+
744
+ for ( var i = 0, j = data.children.length; i < j; i ++ ) {
745
+
746
+ var child = data.children[ i ];
747
+
748
+ var vec;
749
+
750
+ if ( 'TextureCoordinate' === child.nodeType ) {
751
+
752
+ uvs = child.points;
753
+
754
+ }
755
+
756
+
757
+ if ( 'Coordinate' === child.nodeType ) {
758
+
759
+ if ( child.points ) {
760
+
761
+ for ( var k = 0, l = child.points.length; k < l; k ++ ) {
762
+
763
+ var point = child.points[ k ];
764
+
765
+ vec = new THREE.Vector3( point.x, point.y, point.z );
766
+
767
+ geometry.vertices.push( vec );
768
+
769
+ }
770
+
771
+ }
772
+
773
+ if ( child.string.indexOf ( 'DEF' ) > -1 ) {
774
+
775
+ var name = /DEF\s+([^\s]+)/.exec( child.string )[ 1 ];
776
+
777
+ defines[ name ] = geometry.vertices;
778
+
779
+ }
780
+
781
+ if ( child.string.indexOf ( 'USE' ) > -1 ) {
782
+
783
+ var defineKey = /USE\s+([^\s]+)/.exec( child.string )[ 1 ];
784
+
785
+ geometry.vertices = defines[ defineKey ];
786
+ }
787
+
788
+ }
789
+
790
+ }
791
+
792
+ var skip = 0;
793
+
794
+ // some shapes only have vertices for use in other shapes
795
+ if ( data.coordIndex ) {
796
+
797
+ // read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html
798
+ for ( var i = 0, j = data.coordIndex.length; i < j; i ++ ) {
799
+
800
+ indexes = data.coordIndex[ i ]; if ( data.texCoordIndex ) uvIndexes = data.texCoordIndex[ i ];
801
+
802
+ // vrml support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
803
+ skip = 0;
804
+
805
+ // Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles
806
+ while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) {
807
+
808
+ var face = new THREE.Face3(
809
+ indexes[ 0 ],
810
+ indexes[ skip + (data.ccw ? 1 : 2) ],
811
+ indexes[ skip + (data.ccw ? 2 : 1) ],
812
+ null // normal, will be added later
813
+ // todo: pass in the color, if a color index is present
814
+ );
815
+
816
+ if ( uvs && uvIndexes ) {
817
+ geometry.faceVertexUvs [0].push( [
818
+ new THREE.Vector2 (
819
+ uvs[ uvIndexes[ 0 ] ].x ,
820
+ uvs[ uvIndexes[ 0 ] ].y
821
+ ) ,
822
+ new THREE.Vector2 (
823
+ uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].x ,
824
+ uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].y
825
+ ) ,
826
+ new THREE.Vector2 (
827
+ uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].x ,
828
+ uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].y
829
+ )
830
+ ] );
831
+ }
832
+
833
+ skip ++;
834
+
835
+ geometry.faces.push( face );
836
+
837
+ }
838
+
839
+
840
+ }
841
+
842
+ } else {
843
+
844
+ // do not add dummy mesh to the scene
845
+ parent.parent.remove( parent );
846
+
847
+ }
848
+
849
+ if ( false === data.solid ) {
850
+
851
+ parent.material.side = THREE.DoubleSide;
852
+
853
+ }
854
+
855
+ // we need to store it on the geometry for use with defines
856
+ geometry.solid = data.solid;
857
+
858
+ geometry.computeFaceNormals();
859
+ //geometry.computeVertexNormals(); // does not show
860
+ geometry.computeBoundingSphere();
861
+
862
+ // see if it's a define
863
+ if ( /DEF/.exec( data.string ) ) {
864
+
865
+ geometry.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
866
+ defines[ geometry.name ] = geometry;
867
+
868
+ }
869
+
870
+ parent.geometry = geometry;
871
+
872
+ }
873
+
874
+ return;
875
+
876
+ } else if ( /appearance/.exec( data.string ) ) {
877
+
878
+ for ( var i = 0; i < data.children.length; i ++ ) {
879
+
880
+ var child = data.children[ i ];
881
+
882
+ if ( 'Material' === child.nodeType ) {
883
+
884
+ var material = new THREE.MeshPhongMaterial();
885
+
886
+ if ( undefined !== child.diffuseColor ) {
887
+
888
+ var d = child.diffuseColor;
889
+
890
+ material.color.setRGB( d.r, d.g, d.b );
891
+
892
+ }
893
+
894
+ if ( undefined !== child.emissiveColor ) {
895
+
896
+ var e = child.emissiveColor;
897
+
898
+ material.emissive.setRGB( e.r, e.g, e.b );
899
+
900
+ }
901
+
902
+ if ( undefined !== child.specularColor ) {
903
+
904
+ var s = child.specularColor;
905
+
906
+ material.specular.setRGB( s.r, s.g, s.b );
907
+
908
+ }
909
+
910
+ if ( undefined !== child.transparency ) {
911
+
912
+ var t = child.transparency;
913
+
914
+ // transparency is opposite of opacity
915
+ material.opacity = Math.abs( 1 - t );
916
+
917
+ material.transparent = true;
918
+
919
+ }
920
+
921
+ if ( /DEF/.exec( data.string ) ) {
922
+
923
+ material.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
924
+
925
+ defines[ material.name ] = material;
926
+
927
+ }
928
+
929
+ parent.material = material;
930
+
931
+ }
932
+
933
+ if ( 'ImageTexture' === child.nodeType ) {
934
+
935
+ var textureName = /"([^"]+)"/.exec(child.children[ 0 ]);
936
+
937
+ if (textureName) {
938
+
939
+ parent.material.name = textureName[ 1 ];
940
+
941
+ parent.material.map = textureLoader.load( texturePath + textureName[ 1 ] );
942
+
943
+ }
944
+
945
+ }
946
+
947
+ }
948
+
949
+ return;
950
+
951
+ }
952
+
953
+ for ( var i = 0, l = data.children.length; i < l; i ++ ) {
954
+
955
+ var child = data.children[ i ];
956
+
957
+ parseNode( data.children[ i ], object );
958
+
959
+ }
960
+
961
+ };
962
+
963
+ parseNode( getTree( lines ), scene );
964
+
965
+ };
966
+
967
+ var scene = new THREE.Scene();
968
+
969
+ var lines = data.split( '\n' );
970
+
971
+ // some lines do not have breaks
972
+ for (var i = lines.length -1; i > -1; i--) {
973
+
974
+ // split lines with {..{ or {..[ - some have both
975
+ if (/{.*[{\[]/.test (lines[i])) {
976
+ var parts = lines[i].split ('{').join ('{\n').split ('\n');
977
+ parts.unshift(1);
978
+ parts.unshift(i);
979
+ lines.splice.apply(lines, parts);
980
+ } else
981
+
982
+ // split lines with ]..}
983
+ if (/\].*}/.test (lines[i])) {
984
+ var parts = lines[i].split (']').join (']\n').split ('\n');
985
+ parts.unshift(1);
986
+ parts.unshift(i);
987
+ lines.splice.apply(lines, parts);
988
+ }
989
+
990
+ // split lines with }..}
991
+ if (/}.*}/.test (lines[i])) {
992
+ var parts = lines[i].split ('}').join ('}\n').split ('\n');
993
+ parts.unshift(1);
994
+ parts.unshift(i);
995
+ lines.splice.apply(lines, parts);
996
+ }
997
+
998
+ // force the parser to create Coordinate node for empty coords
999
+ // coord USE something -> coord USE something Coordinate {}
1000
+ if((lines[i].indexOf ('coord') > -1) && (lines[i].indexOf ('[') < 0) && (lines[i].indexOf ('{') < 0)) {
1001
+ lines[i] += ' Coordinate {}';
1002
+ }
1003
+ }
1004
+
1005
+ var header = lines.shift();
1006
+
1007
+ if ( /V1.0/.exec( header ) ) {
1008
+
1009
+ parseV1( lines, scene );
1010
+
1011
+ } else if ( /V2.0/.exec( header ) ) {
1012
+
1013
+ parseV2( lines, scene );
1014
+
1015
+ }
1016
+
1017
+ return scene;
1018
+
1019
+ }
1020
+
1021
+ };