x_ite 8.6.8 → 8.6.10

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 (106) hide show
  1. package/.vscode/tasks.json +1 -1
  2. package/dist/assets/components/Annotation.js +13 -13
  3. package/dist/assets/components/Annotation.min.js +1 -1
  4. package/dist/assets/components/CADGeometry.js +13 -13
  5. package/dist/assets/components/CADGeometry.min.js +1 -1
  6. package/dist/assets/components/CubeMapTexturing.js +25 -25
  7. package/dist/assets/components/CubeMapTexturing.min.js +1 -1
  8. package/dist/assets/components/DIS.js +13 -13
  9. package/dist/assets/components/DIS.min.js +1 -1
  10. package/dist/assets/components/EventUtilities.js +9 -9
  11. package/dist/assets/components/EventUtilities.min.js +1 -1
  12. package/dist/assets/components/Geometry2D.js +19 -19
  13. package/dist/assets/components/Geometry2D.min.js +1 -1
  14. package/dist/assets/components/Geospatial.js +33 -33
  15. package/dist/assets/components/Geospatial.min.js +1 -1
  16. package/dist/assets/components/HAnim.js +18 -18
  17. package/dist/assets/components/HAnim.min.js +1 -1
  18. package/dist/assets/components/KeyDeviceSensor.js +8 -8
  19. package/dist/assets/components/KeyDeviceSensor.min.js +1 -1
  20. package/dist/assets/components/Layout.js +27 -27
  21. package/dist/assets/components/Layout.min.js +1 -1
  22. package/dist/assets/components/NURBS.js +24 -24
  23. package/dist/assets/components/NURBS.min.js +1 -1
  24. package/dist/assets/components/ParticleSystems.js +25 -27
  25. package/dist/assets/components/ParticleSystems.min.js +1 -1
  26. package/dist/assets/components/Picking.js +19 -19
  27. package/dist/assets/components/Picking.min.js +1 -1
  28. package/dist/assets/components/RigidBodyPhysics.js +18 -18
  29. package/dist/assets/components/RigidBodyPhysics.min.js +1 -1
  30. package/dist/assets/components/Scripting.js +28 -28
  31. package/dist/assets/components/Scripting.min.js +1 -1
  32. package/dist/assets/components/Text.js +24 -24
  33. package/dist/assets/components/Text.min.js +1 -1
  34. package/dist/assets/components/TextureProjector.js +14 -14
  35. package/dist/assets/components/TextureProjector.min.js +1 -1
  36. package/dist/assets/components/Texturing3D.js +30 -30
  37. package/dist/assets/components/Texturing3D.min.js +1 -1
  38. package/dist/assets/components/VolumeRendering.js +19 -19
  39. package/dist/assets/components/VolumeRendering.min.js +1 -1
  40. package/dist/assets/components/X_ITE.js +9 -9
  41. package/dist/assets/components/X_ITE.min.js +1 -1
  42. package/dist/x_ite.css +1 -1
  43. package/dist/x_ite.js +907 -660
  44. package/dist/x_ite.min.js +1 -1
  45. package/dist/x_ite.zip +0 -0
  46. package/docs/_config.yml +2 -2
  47. package/docs/_posts/getting-started.md +1 -1
  48. package/docs/laboratory/gltf-sample-viewer.html +4 -4
  49. package/package.json +1 -1
  50. package/src/assets/shaders/webgl1/Pointing.fs.js +1 -1
  51. package/src/assets/shaders/webgl1/include/Fragment.glsl.js +19 -2
  52. package/src/assets/shaders/webgl1/include/Point.glsl.js +10 -2
  53. package/src/assets/shaders/webgl1/include/Texture.glsl.js +31 -1
  54. package/src/assets/shaders/webgl1/include/Vertex.glsl.js +24 -0
  55. package/src/assets/shaders/webgl2/Pointing.fs.js +1 -1
  56. package/src/assets/shaders/webgl2/include/Fragment.glsl.js +20 -1
  57. package/src/assets/shaders/webgl2/include/Point.glsl.js +12 -4
  58. package/src/assets/shaders/webgl2/include/Texture.glsl.js +17 -20
  59. package/src/assets/shaders/webgl2/include/Vertex.glsl.js +24 -0
  60. package/src/bookmarks.js +1 -1
  61. package/src/tests.js +2 -1
  62. package/src/x_ite/Browser/Core/BrowserOptions.js +3 -0
  63. package/src/x_ite/Browser/Core/BrowserTimings.js +12 -11
  64. package/src/x_ite/Browser/Core/Context.js +66 -64
  65. package/src/x_ite/Browser/Core/ContextMenu.js +0 -9
  66. package/src/x_ite/Browser/Navigation/ExamineViewer.js +1 -1
  67. package/src/x_ite/Browser/Texturing/X3DTexturingContext.js +8 -0
  68. package/src/x_ite/Browser/VERSION.js +1 -1
  69. package/src/x_ite/Browser/X3DBrowser.js +1 -1
  70. package/src/x_ite/Components/Core/X3DBindableNode.js +0 -2
  71. package/src/x_ite/Components/Core/X3DNode.js +3 -8
  72. package/src/x_ite/Components/Layering/X3DLayerNode.js +6 -2
  73. package/src/x_ite/Components/Navigation/NavigationInfo.js +1 -0
  74. package/src/x_ite/Components/Navigation/X3DViewpointNode.js +34 -21
  75. package/src/x_ite/Components/ParticleSystems/ParticleSystem.js +2 -4
  76. package/src/x_ite/Components/Rendering/X3DGeometryNode.js +5 -19
  77. package/src/x_ite/Components/Rendering/X3DLineGeometryNode.js +6 -12
  78. package/src/x_ite/Components/Rendering/X3DPointGeometryNode.js +4 -8
  79. package/src/x_ite/Components/Shaders/X3DProgrammableShaderObject.js +30 -27
  80. package/src/x_ite/Components/Shape/Material.js +4 -0
  81. package/src/x_ite/Components/Shape/PhysicalMaterial.js +4 -0
  82. package/src/x_ite/Components/Shape/TwoSidedMaterial.js +1 -0
  83. package/src/x_ite/Components/Shape/X3DMaterialNode.js +21 -19
  84. package/src/x_ite/Components/Shape/X3DOneSidedMaterialNode.js +4 -0
  85. package/src/x_ite/Components/Texturing/ImageTexture.js +80 -46
  86. package/src/x_ite/Components/Texturing/MultiTexture.js +7 -4
  87. package/src/x_ite/Components/Texturing/MultiTextureCoordinate.js +19 -16
  88. package/src/x_ite/Components/Texturing/MultiTextureTransform.js +16 -32
  89. package/src/x_ite/Components/Texturing/TextureCoordinateGenerator.js +1 -1
  90. package/src/x_ite/Components/Texturing/X3DSingleTextureCoordinateNode.js +2 -8
  91. package/src/x_ite/Components/Texturing/X3DSingleTextureTransformNode.js +2 -8
  92. package/src/x_ite/Execution/NamedNodesHandling.js +84 -0
  93. package/src/x_ite/Execution/X3DExecutionContext.js +7 -37
  94. package/src/x_ite/Execution/X3DScene.js +5 -0
  95. package/src/x_ite/InputOutput/FileLoader.js +1 -1
  96. package/src/x_ite/InputOutput/Generator.js +32 -81
  97. package/src/x_ite/Parser/GLTF2Parser.js +109 -43
  98. package/src/x_ite/Parser/OBJParser.js +42 -30
  99. package/src/x_ite/Parser/STLAParser.js +3 -0
  100. package/src/x_ite/Parser/SVGParser.js +4 -0
  101. package/src/x_ite/Rendering/X3DRenderObject.js +1 -0
  102. package/src/x_ite.html +53 -47
  103. package/x_ite.min.html +53 -47
  104. /package/docs/assets/X3D/{Michroma-Regular.ttf → teaser/Michroma-Regular.ttf} +0 -0
  105. /package/docs/assets/X3D/{peakpx.jpg → teaser/peakpx.jpg} +0 -0
  106. /package/docs/assets/X3D/{teaser.x3d → teaser/teaser.x3d} +0 -0
@@ -61,9 +61,7 @@ import DEBUG from "../DEBUG.js"
61
61
  // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html
62
62
  // https://github.com/KhronosGroup/glTF-Sample-Models
63
63
 
64
- const
65
- STEP_TIME = 1e-4, // in seconds
66
- SAMPLES_PER_SECOND = 30; // in 1/s
64
+ const SAMPLES_PER_SECOND = 30; // in 1/s
67
65
 
68
66
  function GLTF2Parser (scene)
69
67
  {
@@ -86,7 +84,7 @@ function GLTF2Parser (scene)
86
84
  this .accessors = [ ];
87
85
  this .samplers = [ ];
88
86
  this .materials = [ ];
89
- this .textureTransformNodes = new Map ();
87
+ this .textureTransformNodes = [ ];
90
88
  this .cameras = [ ];
91
89
  this .viewpoints = 0;
92
90
  this .nodes = [ ];
@@ -320,12 +318,16 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
320
318
  if (this .vectorValue (light .color, color))
321
319
  lightNode ._color = color;
322
320
 
321
+ lightNode ._global = true;
323
322
  lightNode ._intensity = this .numberValue (light .intensity, 1);
324
323
 
325
324
  lightNode .setup ();
326
325
 
327
326
  if (name)
327
+ {
328
328
  scene .addNamedNode (scene .getUniqueName (name), lightNode);
329
+ scene .addExportedNode (scene .getUniqueExportName (name), lightNode);
330
+ }
329
331
 
330
332
  return lightNode;
331
333
  },
@@ -471,7 +473,7 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
471
473
  components = Components .get (accessor .type),
472
474
  count = accessor .count || 0,
473
475
  stride = byteStride ? byteStride / TypedArray .BYTES_PER_ELEMENT : components,
474
- length = stride * count,
476
+ length = Math .min (stride * count, (bufferView .byteLength - byteOffset) / TypedArray .BYTES_PER_ELEMENT),
475
477
  array = new TypedArray (bufferView .buffer, byteOffset, length);
476
478
 
477
479
  if (stride === components)
@@ -596,7 +598,10 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
596
598
  name = this .sanitizeName (sampler .name);
597
599
 
598
600
  if (name)
601
+ {
599
602
  scene .addNamedNode (scene .getUniqueName (name), texturePropertiesNode);
603
+ scene .addExportedNode (scene .getUniqueExportName (name), texturePropertiesNode);
604
+ }
600
605
 
601
606
  // minFilter
602
607
 
@@ -694,7 +699,10 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
694
699
  name = this .sanitizeName (texture .name || image .name);
695
700
 
696
701
  if (name)
702
+ {
697
703
  scene .addNamedNode (scene .getUniqueName (name), textureNode);
704
+ scene .addExportedNode (scene .getUniqueExportName (name), textureNode);
705
+ }
698
706
 
699
707
  textureNode ._url = [image .uri];
700
708
  textureNode ._flipVertically = true;
@@ -723,13 +731,18 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
723
731
  if (material .appearanceNode)
724
732
  return material .appearanceNode;
725
733
 
726
- if (!(material .extensions instanceof Object))
727
- material .extensions = { };
734
+ const texCoordIndices = this .texCoordIndices ("", material);
735
+
736
+ this .texCoordIndex = [... texCoordIndices] .reduce (Math .max, -1);
737
+
738
+ this .textureTransformNodes = [ ];
739
+ this .texCoordMappings = new Map ();
740
+ material .texCoordMappings = this .texCoordMappings;
728
741
 
729
742
  const
730
743
  scene = this .getExecutionContext (),
731
744
  appearanceNode = scene .createNode ("Appearance", false),
732
- materialNode = this .materialObjectMaterial (material),
745
+ materialNode = this .createMaterial (material),
733
746
  name = this .sanitizeName (material .name);
734
747
 
735
748
  const emissiveFactor = new Color3 (0, 0, 0);
@@ -737,8 +750,8 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
737
750
  if (this .vectorValue (material .emissiveFactor, emissiveFactor))
738
751
  materialNode ._emissiveColor = emissiveFactor;
739
752
 
740
- materialNode ._emissiveTextureMapping = this .textureMapping (material .emissiveTexture);
741
753
  materialNode ._emissiveTexture = this .textureInfo (material .emissiveTexture);
754
+ materialNode ._emissiveTextureMapping = this .textureMapping (material .emissiveTexture);
742
755
 
743
756
  this .occlusionTextureInfo (material .occlusionTexture, materialNode);
744
757
  this .normalTextureInfo (material .normalTexture, materialNode);
@@ -746,8 +759,28 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
746
759
 
747
760
  materialNode .setup ();
748
761
 
762
+ for (const i of texCoordIndices)
763
+ {
764
+ const mapping = `TEXCOORD_${i}`;
765
+
766
+ if (this .textureTransformNodes .length)
767
+ {
768
+ const textureTransformNode = scene .createNode ("TextureTransform", false);
769
+
770
+ textureTransformNode ._mapping = mapping;
771
+ textureTransformNode .setup ();
772
+
773
+ this .textureTransformNodes .push (textureTransformNode);
774
+ }
775
+
776
+ this .texCoordMappings .set (mapping, i);
777
+ }
778
+
749
779
  if (name)
780
+ {
750
781
  scene .addNamedNode (scene .getUniqueName (name), appearanceNode);
782
+ scene .addExportedNode (scene .getUniqueExportName (name), appearanceNode);
783
+ }
751
784
 
752
785
  appearanceNode ._alphaMode = this .stringValue (material .alphaMode, "OPAQUE");
753
786
  appearanceNode ._alphaCutoff = this .numberValue (material .alphaCutoff, 0.5);
@@ -758,11 +791,24 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
758
791
 
759
792
  return material .appearanceNode = appearanceNode;
760
793
  },
761
- materialObjectMaterial: function (material)
794
+ texCoordIndices: function (key, object, indices = new Set ())
795
+ {
796
+ if (!(object instanceof Object))
797
+ return indices;
798
+
799
+ if (key .endsWith ("Texture") && !object?.extensions?.KHR_texture_transform)
800
+ indices .add (object .texCoord || 0);
801
+
802
+ for (const [key, value] of Object .entries (object))
803
+ this .texCoordIndices (key, value, indices);
804
+
805
+ return indices;
806
+ },
807
+ createMaterial: function (material)
762
808
  {
763
809
  const materials = [
764
810
  this .pbrMetallicRoughnessObject .bind (this, material .pbrMetallicRoughness),
765
- this .pbrSpecularGlossinessObject .bind (this, material .extensions .KHR_materials_pbrSpecularGlossiness),
811
+ this .pbrSpecularGlossinessObject .bind (this, material .extensions?.KHR_materials_pbrSpecularGlossiness),
766
812
  this .pbrMetallicRoughnessObject .bind (this, { }),
767
813
  ];
768
814
 
@@ -796,10 +842,10 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
796
842
  materialNode ._metallic = this .numberValue (pbrMetallicRoughness .metallicFactor, 1);
797
843
  materialNode ._roughness = this .numberValue (pbrMetallicRoughness .roughnessFactor, 1);
798
844
 
799
- materialNode ._baseTextureMapping = this .textureMapping (pbrMetallicRoughness .baseColorTexture);
800
845
  materialNode ._baseTexture = this .textureInfo (pbrMetallicRoughness .baseColorTexture);
801
- materialNode ._metallicRoughnessTextureMapping = this .textureMapping (pbrMetallicRoughness .metallicRoughnessTexture);
846
+ materialNode ._baseTextureMapping = this .textureMapping (pbrMetallicRoughness .baseColorTexture);
802
847
  materialNode ._metallicRoughnessTexture = this .textureInfo (pbrMetallicRoughness .metallicRoughnessTexture);
848
+ materialNode ._metallicRoughnessTextureMapping = this .textureMapping (pbrMetallicRoughness .metallicRoughnessTexture);
803
849
 
804
850
  return materialNode;
805
851
  },
@@ -834,30 +880,23 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
834
880
 
835
881
  materialNode ._shininess = this .numberValue (pbrSpecularGlossiness .glossinessFactor, 1);
836
882
 
837
- materialNode ._diffuseTextureMapping = this .textureMapping (pbrSpecularGlossiness .diffuseTexture);
838
883
  materialNode ._diffuseTexture = this .textureInfo (pbrSpecularGlossiness .diffuseTexture);
839
- materialNode ._specularTextureMapping = this .textureMapping (pbrSpecularGlossiness .specularGlossinessTexture);
884
+ materialNode ._diffuseTextureMapping = this .textureMapping (pbrSpecularGlossiness .diffuseTexture);
840
885
  materialNode ._specularTexture = this .textureInfo (pbrSpecularGlossiness .specularGlossinessTexture);
841
- materialNode ._shininessTextureMapping = this .textureMapping (pbrSpecularGlossiness .specularGlossinessTexture);
886
+ materialNode ._specularTextureMapping = this .textureMapping (pbrSpecularGlossiness .specularGlossinessTexture);
842
887
  materialNode ._shininessTexture = this .textureInfo (pbrSpecularGlossiness .specularGlossinessTexture);
888
+ materialNode ._shininessTextureMapping = this .textureMapping (pbrSpecularGlossiness .specularGlossinessTexture);
843
889
 
844
890
  return materialNode;
845
891
  },
846
- textureMapping: function (texture)
847
- {
848
- if (!(texture instanceof Object))
849
- return "";
850
-
851
- return "TEXCOORD_" + (texture .texCoord || 0);
852
- },
853
892
  occlusionTextureInfo: function (occlusionTexture, materialNode)
854
893
  {
855
894
  if (!(occlusionTexture instanceof Object))
856
895
  return null;
857
896
 
858
897
  materialNode ._occlusionStrength = this .numberValue (occlusionTexture .strength, 1);
859
- materialNode ._occlusionTextureMapping = this .textureMapping (occlusionTexture);
860
898
  materialNode ._occlusionTexture = this .textureInfo (occlusionTexture);
899
+ materialNode ._occlusionTextureMapping = this .textureMapping (occlusionTexture);
861
900
  },
862
901
  normalTextureInfo: function (normalTexture, materialNode)
863
902
  {
@@ -865,8 +904,8 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
865
904
  return null;
866
905
 
867
906
  materialNode ._normalScale = this .numberValue (normalTexture .scale, 1);
868
- materialNode ._normalTextureMapping = this .textureMapping (normalTexture);
869
907
  materialNode ._normalTexture = this .textureInfo (normalTexture);
908
+ materialNode ._normalTextureMapping = this .textureMapping (normalTexture);
870
909
  },
871
910
  textureInfo: function (texture)
872
911
  {
@@ -874,10 +913,19 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
874
913
  return null;
875
914
 
876
915
  if (texture .extensions instanceof Object)
877
- this .textureTransformObject (texture .extensions .KHR_texture_transform, this .textureMapping (texture));
916
+ texture .mapping = this .textureTransformObject (texture .extensions .KHR_texture_transform, texture .texCoord || 0);
917
+ else
918
+ texture .mapping = `TEXCOORD_${texture .texCoord || 0}`;
878
919
 
879
920
  return this .textureObject (this .textures [texture .index]);
880
921
  },
922
+ textureMapping: function (texture)
923
+ {
924
+ if (!(texture instanceof Object))
925
+ return "";
926
+
927
+ return texture .mapping;
928
+ },
881
929
  materialExtensions: function (extensions, materialNode)
882
930
  {
883
931
  if (!(extensions instanceof Object))
@@ -929,7 +977,7 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
929
977
 
930
978
  materialNode ._emissiveStrength = this .numberValue (KHR_materials_emissive_strength .emissiveStrength, 1);
931
979
  },
932
- textureTransformObject: function (KHR_texture_transform, mapping)
980
+ textureTransformObject: function (KHR_texture_transform, texCoord)
933
981
  {
934
982
  if (!(KHR_texture_transform instanceof Object))
935
983
  return;
@@ -939,7 +987,8 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
939
987
 
940
988
  const
941
989
  scene = this .getExecutionContext (),
942
- textureTransformNode = scene .createNode ("TextureTransformMatrix3D", false);
990
+ textureTransformNode = scene .createNode ("TextureTransformMatrix3D", false),
991
+ mapping = `TEXCOORD_${this .texCoordIndex + this .textureTransformNodes .length + 1}`;
943
992
 
944
993
  const
945
994
  translation = new Vector2 (0, 0),
@@ -959,7 +1008,10 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
959
1008
 
960
1009
  textureTransformNode .setup ();
961
1010
 
962
- this .textureTransformNodes .set (mapping, textureTransformNode);
1011
+ this .textureTransformNodes .push (textureTransformNode);
1012
+ this .texCoordMappings .set (mapping, KHR_texture_transform .texCoord ?? texCoord);
1013
+
1014
+ return mapping;
963
1015
  },
964
1016
  meshesArray: function (meshes)
965
1017
  {
@@ -987,7 +1039,10 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
987
1039
  if (name)
988
1040
  {
989
1041
  for (const shapeNode of shapeNodes)
1042
+ {
990
1043
  scene .addNamedNode (scene .getUniqueName (name), shapeNode);
1044
+ scene .addExportedNode (scene .getUniqueExportName (name), shapeNode);
1045
+ }
991
1046
  }
992
1047
 
993
1048
  return mesh .shapeNodes = shapeNodes;
@@ -1221,7 +1276,10 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
1221
1276
  // Name
1222
1277
 
1223
1278
  if (name)
1279
+ {
1224
1280
  scene .addNamedNode (scene .getUniqueName (name), viewpointNode);
1281
+ scene .addExportedNode (scene .getUniqueExportName (name), viewpointNode);
1282
+ }
1225
1283
 
1226
1284
  if (camera .name)
1227
1285
  viewpointNode ._description = camera .name;
@@ -1317,7 +1375,10 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
1317
1375
  // Name
1318
1376
 
1319
1377
  if (name)
1378
+ {
1320
1379
  scene .addNamedNode (scene .getUniqueName (name), transformNode);
1380
+ scene .addExportedNode (scene .getUniqueExportName (name), transformNode);
1381
+ }
1321
1382
 
1322
1383
  // Set transformation matrix.
1323
1384
 
@@ -1449,6 +1510,7 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
1449
1510
  const switchNode = scene .createNode ("Switch", false);
1450
1511
 
1451
1512
  scene .addNamedNode (scene .getUniqueName ("Scenes"), switchNode);
1513
+ scene .addExportedNode (scene .getUniqueExportName ("Scenes"), switchNode);
1452
1514
 
1453
1515
  // Scenes.
1454
1516
 
@@ -1487,7 +1549,10 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
1487
1549
  name = this .sanitizeName (sceneObject .name);
1488
1550
 
1489
1551
  if (name)
1552
+ {
1490
1553
  scene .addNamedNode (scene .getUniqueName (name), groupNode);
1554
+ scene .addExportedNode (scene .getUniqueExportName (name), groupNode);
1555
+ }
1491
1556
 
1492
1557
  groupNode ._children = nodes;
1493
1558
 
@@ -1518,7 +1583,7 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
1518
1583
  groupNode = scene .createNode ("Group", false);
1519
1584
 
1520
1585
  scene .addNamedNode (scene .getUniqueName ("Animations"), groupNode);
1521
- scene .addExportedNode ("Animations", groupNode);
1586
+ scene .addExportedNode (scene .getUniqueExportName ("Animations"), groupNode);
1522
1587
 
1523
1588
  groupNode ._children = animationNodes;
1524
1589
 
@@ -1547,6 +1612,8 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
1547
1612
 
1548
1613
  scene .addNamedNode (scene .getUniqueName (name || `Animation${this .animations}`), groupNode);
1549
1614
  scene .addNamedNode (scene .getUniqueName (`Timer${this .animations}`), timeSensorNode);
1615
+ scene .addExportedNode (scene .getUniqueExportName (name || `Animation${this .animations}`), groupNode);
1616
+ scene .addExportedNode (scene .getUniqueExportName (`Timer${this .animations}`), timeSensorNode);
1550
1617
 
1551
1618
  timeSensorNode ._description = animation .name || `Animation ${this .animations}`;
1552
1619
  groupNode ._children .push (timeSensorNode, ... channelNodes);
@@ -1681,11 +1748,9 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
1681
1748
  if (!+materialNode .getTextureBits ())
1682
1749
  return null;
1683
1750
 
1684
- const textureTransformNodes = [... this .textureTransformNodes .values ()]
1751
+ const textureTransformNodes = this .textureTransformNodes
1685
1752
  .sort ((a, b) => Algorithm .cmp (a ._mapping .getValue (), b ._mapping .getValue ()));
1686
1753
 
1687
- this .textureTransformNodes .clear ();
1688
-
1689
1754
  switch (textureTransformNodes .length)
1690
1755
  {
1691
1756
  case 0:
@@ -2022,7 +2087,7 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
2022
2087
  if (texCoords .textureCoordinateNode)
2023
2088
  return texCoords .textureCoordinateNode;
2024
2089
 
2025
- switch (texCoords .length)
2090
+ switch (material .texCoordMappings .size)
2026
2091
  {
2027
2092
  case 0:
2028
2093
  {
@@ -2030,12 +2095,13 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
2030
2095
  }
2031
2096
  case 1:
2032
2097
  {
2033
- return texCoords .textureCoordinateNode = this .createTextureCoordinate (texCoords [0], 0);
2098
+ return texCoords .textureCoordinateNode = [... material .texCoordMappings .entries ()]
2099
+ .map (([mapping, i]) => this .createTextureCoordinate (texCoords [i], mapping)) [0];
2034
2100
  }
2035
2101
  default:
2036
2102
  {
2037
- const textureCoordinateNodes = texCoords
2038
- .map ((texCoord, i) => this .createTextureCoordinate (texCoord, i))
2103
+ const textureCoordinateNodes = [... material .texCoordMappings .entries ()]
2104
+ .map (([mapping, i]) => this .createTextureCoordinate (texCoords [i], mapping))
2039
2105
  .filter (node => node)
2040
2106
  .sort ((a, b) => Algorithm .cmp (a ._mapping .getValue (), b ._mapping .getValue ()));
2041
2107
 
@@ -2062,19 +2128,19 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
2062
2128
  if (texCoord .type !== "VEC2")
2063
2129
  return null;
2064
2130
 
2065
- if (texCoord .textureCoordinateNode)
2066
- return texCoord .textureCoordinateNode;
2131
+ if (texCoord [mapping])
2132
+ return texCoord [mapping];
2067
2133
 
2068
2134
  const
2069
2135
  scene = this .getExecutionContext (),
2070
2136
  textureCoordinateNode = scene .createNode ("TextureCoordinate", false);
2071
2137
 
2072
- textureCoordinateNode ._mapping = "TEXCOORD_" + mapping;
2138
+ textureCoordinateNode ._mapping = mapping;
2073
2139
  textureCoordinateNode ._point = texCoord .array;
2074
2140
 
2075
2141
  textureCoordinateNode .setup ();
2076
2142
 
2077
- return texCoord .textureCoordinateNode = textureCoordinateNode;
2143
+ return texCoord [mapping] = textureCoordinateNode;
2078
2144
  },
2079
2145
  createNormal: function (normal)
2080
2146
  {
@@ -2170,7 +2236,7 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
2170
2236
  interpolatorNode ._key .push (times [0] / cycleInterval);
2171
2237
 
2172
2238
  for (let i = 1, length = times .length; i < length; ++ i)
2173
- interpolatorNode ._key .push ((times [i] - STEP_TIME) / cycleInterval, times [i] / cycleInterval);
2239
+ interpolatorNode ._key .push (times [i] / cycleInterval, times [i] / cycleInterval);
2174
2240
 
2175
2241
  // KeyValue
2176
2242
 
@@ -2244,7 +2310,7 @@ GLTF2Parser .prototype = Object .assign (Object .create (X3DParser .prototype),
2244
2310
  interpolatorNode ._key .push (times [0] / cycleInterval);
2245
2311
 
2246
2312
  for (let i = 1, length = times .length; i < length; ++ i)
2247
- interpolatorNode ._key .push ((times [i] - STEP_TIME) / cycleInterval, times [i] / cycleInterval);
2313
+ interpolatorNode ._key .push (times [i] / cycleInterval, times [i] / cycleInterval);
2248
2314
 
2249
2315
  // KeyValue
2250
2316
 
@@ -284,24 +284,30 @@ OBJParser .prototype = Object .assign (Object .create (X3DParser .prototype),
284
284
 
285
285
  parser .parse ();
286
286
 
287
- for (const [name, material] of parser .materials)
287
+ for (const [id, material] of parser .materials)
288
288
  {
289
- const nodeName = this .sanitizeName (name);
289
+ const name = this .sanitizeName (id);
290
290
 
291
- if (nodeName)
292
- scene .addNamedNode (scene .getUniqueName (nodeName), material);
291
+ if (name)
292
+ {
293
+ scene .addNamedNode (scene .getUniqueName (name), material);
294
+ scene .addExportedNode (scene .getUniqueExportName (name), material);
295
+ }
293
296
 
294
- this .materials .set (name, material);
297
+ this .materials .set (id, material);
295
298
  }
296
299
 
297
- for (const [name, texture] of parser .textures)
300
+ for (const [id, texture] of parser .textures)
298
301
  {
299
- const nodeName = this .sanitizeName (name);
302
+ const name = this .sanitizeName (id);
300
303
 
301
- if (nodeName)
302
- scene .addNamedNode (scene .getUniqueName (nodeName), texture);
304
+ if (name)
305
+ {
306
+ scene .addNamedNode (scene .getUniqueName (name), texture);
307
+ scene .addExportedNode (scene .getUniqueExportName (name), texture);
308
+ }
303
309
 
304
- this .textures .set (name, texture);
310
+ this .textures .set (id, texture);
305
311
  }
306
312
  }
307
313
  catch (error)
@@ -319,10 +325,10 @@ OBJParser .prototype = Object .assign (Object .create (X3DParser .prototype),
319
325
 
320
326
  if (Grammar .untilEndOfLine .parse (this))
321
327
  {
322
- const name = this .result [1];
328
+ const id = this .result [1];
323
329
 
324
- this .material = this .materials .get (name) || this .defaultMaterial;
325
- this .texture = this .textures .get (name);
330
+ this .material = this .materials .get (id) || this .defaultMaterial;
331
+ this .texture = this .textures .get (id);
326
332
 
327
333
  const smoothingGroup = this .smoothingGroups .get (this .group .getNodeName ());
328
334
 
@@ -346,8 +352,8 @@ OBJParser .prototype = Object .assign (Object .create (X3DParser .prototype),
346
352
  if (Grammar .untilEndOfLine .parse (this))
347
353
  {
348
354
  const
349
- scene = this .getExecutionContext (),
350
- nodeName = this .sanitizeName (this .result [1]);
355
+ scene = this .getExecutionContext (),
356
+ name = this .sanitizeName (this .result [1]);
351
357
 
352
358
  if (this .group .children .length)
353
359
  {
@@ -358,8 +364,11 @@ OBJParser .prototype = Object .assign (Object .create (X3DParser .prototype),
358
364
  scene .getRootNodes () .push (this .object);
359
365
  }
360
366
 
361
- if (nodeName)
362
- scene .addNamedNode (scene .getUniqueName (nodeName), this .object);
367
+ if (name)
368
+ {
369
+ scene .addNamedNode (scene .getUniqueName (name), this .object);
370
+ scene .addExportedNode (scene .getUniqueExportName (name), this .object);
371
+ }
363
372
  }
364
373
 
365
374
  return true;
@@ -378,10 +387,10 @@ OBJParser .prototype = Object .assign (Object .create (X3DParser .prototype),
378
387
  if (Grammar .untilEndOfLine .parse (this))
379
388
  {
380
389
  const
381
- scene = this .getExecutionContext (),
382
- name = this .result [1],
383
- nodeName = this .sanitizeName (name),
384
- group = this .groups .get (name);
390
+ scene = this .getExecutionContext (),
391
+ id = this .result [1],
392
+ name = this .sanitizeName (id),
393
+ group = this .groups .get (id);
385
394
 
386
395
  if (group)
387
396
  {
@@ -397,10 +406,13 @@ OBJParser .prototype = Object .assign (Object .create (X3DParser .prototype),
397
406
  }
398
407
  }
399
408
 
400
- this .groups .set (name, this .group);
409
+ this .groups .set (id, this .group);
401
410
 
402
- if (nodeName)
403
- scene .addNamedNode (scene .getUniqueName (nodeName), this .group);
411
+ if (name)
412
+ {
413
+ scene .addNamedNode (scene .getUniqueName (name), this .group);
414
+ scene .addExportedNode (scene .getUniqueExportName (name), this .group);
415
+ }
404
416
 
405
417
  this .smoothingGroup = 0;
406
418
  }
@@ -725,7 +737,7 @@ function MaterialParser (scene, input)
725
737
  this .materials = new Map ();
726
738
  this .textures = new Map ();
727
739
  this .color3 = new Color3 ();
728
- this .name = "";
740
+ this .id = "";
729
741
  }
730
742
 
731
743
  MaterialParser .prototype =
@@ -818,15 +830,15 @@ MaterialParser .prototype =
818
830
  {
819
831
  this .whitespacesNoLineTerminator ();
820
832
 
821
- this .name = "";
833
+ this .id = "";
822
834
 
823
835
  if (Grammar .untilEndOfLine .parse (this))
824
836
  {
825
- this .name = this .result [1];
837
+ this .id = this .result [1];
826
838
 
827
839
  this .material = this .executionContext .createNode ("Material");
828
840
 
829
- this .materials .set (this .name, this .material);
841
+ this .materials .set (this .id, this .material);
830
842
 
831
843
  return true;
832
844
  }
@@ -991,7 +1003,7 @@ MaterialParser .prototype =
991
1003
  {
992
1004
  const string = this .result [1];
993
1005
 
994
- if (string .length && this .name .length)
1006
+ if (string .length && this .id .length)
995
1007
  {
996
1008
  const paths = string .trim () .split (/\s+/);
997
1009
 
@@ -1004,7 +1016,7 @@ MaterialParser .prototype =
1004
1016
 
1005
1017
  texture .url = [path];
1006
1018
 
1007
- this .textures .set (this .name, texture);
1019
+ this .textures .set (this .id, texture);
1008
1020
  }
1009
1021
  }
1010
1022
 
@@ -208,7 +208,10 @@ STLAParser .prototype = Object .assign (Object .create (X3DParser .prototype),
208
208
  coordinate .point = this .point;
209
209
 
210
210
  if (name)
211
+ {
211
212
  scene .addNamedNode (scene .getUniqueName (name), shape);
213
+ scene .addExportedNode (scene .getUniqueExportName (name), shape);
214
+ }
212
215
 
213
216
  scene .getRootNodes () .push (shape);
214
217
 
@@ -354,6 +354,7 @@ SVGParser .prototype = Object .assign (Object .create (X3DParser .prototype),
354
354
  // Add root Transform node.
355
355
 
356
356
  scene .addNamedNode (scene .getUniqueName ("ViewBox"), this .rootTransform);
357
+ scene .addExportedNode (scene .getUniqueExportName ("ViewBox"), this .rootTransform);
357
358
  scene .getRootNodes () .push (this .rootTransform);
358
359
 
359
360
  // Optimize scene graph.
@@ -1212,7 +1213,10 @@ SVGParser .prototype = Object .assign (Object .create (X3DParser .prototype),
1212
1213
  name = this .sanitizeName (attribute);
1213
1214
 
1214
1215
  if (name)
1216
+ {
1215
1217
  scene .addNamedNode (scene .getUniqueName (name), node);
1218
+ scene .addExportedNode (scene .getUniqueExportName (name), node);
1219
+ }
1216
1220
  },
1217
1221
  viewBoxAttribute: function (attribute, defaultValue)
1218
1222
  {
@@ -670,6 +670,7 @@ X3DRenderObject .prototype =
670
670
  return {
671
671
  renderObject: this,
672
672
  transparent: transparent,
673
+ minAlpha: transparent ? 0 : 1,
673
674
  modelViewMatrix: new Float32Array (16),
674
675
  scissor: new Vector4 (0, 0, 0, 0),
675
676
  localObjects: [ ],