x_ite 8.3.3 → 8.4.1

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 (85) hide show
  1. package/dist/assets/components/Annotation.js +13 -13
  2. package/dist/assets/components/Annotation.min.js +1 -1
  3. package/dist/assets/components/CADGeometry.js +13 -13
  4. package/dist/assets/components/CADGeometry.min.js +1 -1
  5. package/dist/assets/components/CubeMapTexturing.js +25 -25
  6. package/dist/assets/components/CubeMapTexturing.min.js +1 -1
  7. package/dist/assets/components/DIS.js +13 -13
  8. package/dist/assets/components/DIS.min.js +1 -1
  9. package/dist/assets/components/EventUtilities.js +9 -9
  10. package/dist/assets/components/EventUtilities.min.js +1 -1
  11. package/dist/assets/components/Geometry2D.js +19 -19
  12. package/dist/assets/components/Geometry2D.min.js +1 -1
  13. package/dist/assets/components/Geospatial.js +33 -33
  14. package/dist/assets/components/Geospatial.min.js +1 -1
  15. package/dist/assets/components/HAnim.js +21 -19
  16. package/dist/assets/components/HAnim.min.js +1 -1
  17. package/dist/assets/components/KeyDeviceSensor.js +8 -8
  18. package/dist/assets/components/KeyDeviceSensor.min.js +1 -1
  19. package/dist/assets/components/Layout.js +27 -27
  20. package/dist/assets/components/Layout.min.js +1 -1
  21. package/dist/assets/components/NURBS.js +24 -24
  22. package/dist/assets/components/NURBS.min.js +1 -1
  23. package/dist/assets/components/ParticleSystems.js +23 -23
  24. package/dist/assets/components/ParticleSystems.min.js +1 -1
  25. package/dist/assets/components/Picking.js +19 -19
  26. package/dist/assets/components/Picking.min.js +1 -1
  27. package/dist/assets/components/RigidBodyPhysics.js +17 -17
  28. package/dist/assets/components/RigidBodyPhysics.min.js +1 -1
  29. package/dist/assets/components/Scripting.js +28 -28
  30. package/dist/assets/components/Scripting.min.js +1 -1
  31. package/dist/assets/components/Text.js +24 -24
  32. package/dist/assets/components/Text.min.js +1 -1
  33. package/dist/assets/components/TextureProjector.js +14 -14
  34. package/dist/assets/components/TextureProjector.min.js +1 -1
  35. package/dist/assets/components/Texturing3D.js +27 -27
  36. package/dist/assets/components/Texturing3D.min.js +1 -1
  37. package/dist/assets/components/VolumeRendering.js +19 -19
  38. package/dist/assets/components/VolumeRendering.min.js +1 -1
  39. package/dist/assets/components/X_ITE.js +9 -9
  40. package/dist/assets/components/X_ITE.min.js +1 -1
  41. package/dist/x_ite.css +1 -1
  42. package/dist/x_ite.js +2711 -292
  43. package/dist/x_ite.min.js +1 -1
  44. package/dist/x_ite.zip +0 -0
  45. package/docs/_config.yml +2 -2
  46. package/docs/_posts/reference/field-services-and-objects.md +24 -4
  47. package/docs/_posts/reference/prototype-services.md +24 -4
  48. package/docs/_posts/reference/scene-services.md +9 -4
  49. package/docs/_posts/what's-new.md +11 -1
  50. package/package.json +1 -1
  51. package/src/x_ite/Base/X3DInfoArray.js +26 -0
  52. package/src/x_ite/Base/X3DObject.js +1 -1
  53. package/src/x_ite/Base/X3DObjectArrayField.js +44 -0
  54. package/src/x_ite/Base/X3DTypedArrayField.js +74 -0
  55. package/src/x_ite/Browser/VERSION.js +1 -1
  56. package/src/x_ite/Components/Core/X3DNode.js +486 -23
  57. package/src/x_ite/Components/Core/X3DPrototypeInstance.js +371 -10
  58. package/src/x_ite/Components/HAnim/HAnimHumanoid.js +3 -1
  59. package/src/x_ite/Components/Rendering/X3DGeometryNode.js +6 -3
  60. package/src/x_ite/Configuration/ComponentInfo.js +32 -0
  61. package/src/x_ite/Configuration/ProfileInfo.js +4 -0
  62. package/src/x_ite/Configuration/UnitInfo.js +46 -0
  63. package/src/x_ite/Execution/X3DExecutionContext.js +54 -0
  64. package/src/x_ite/Execution/X3DExportedNode.js +52 -0
  65. package/src/x_ite/Execution/X3DImportedNode.js +164 -0
  66. package/src/x_ite/Execution/X3DScene.js +339 -0
  67. package/src/x_ite/Fields/ArrayFields.js +48 -0
  68. package/src/x_ite/Fields/SFBool.js +8 -0
  69. package/src/x_ite/Fields/SFColor.js +26 -1
  70. package/src/x_ite/Fields/SFColorRGBA.js +2 -0
  71. package/src/x_ite/Fields/SFDouble.js +10 -0
  72. package/src/x_ite/Fields/SFFloat.js +10 -0
  73. package/src/x_ite/Fields/SFImage.js +61 -1
  74. package/src/x_ite/Fields/SFInt32.js +11 -3
  75. package/src/x_ite/Fields/SFMatrixPrototypeTemplate.js +26 -1
  76. package/src/x_ite/Fields/SFNode.js +40 -25
  77. package/src/x_ite/Fields/SFRotation.js +28 -3
  78. package/src/x_ite/Fields/SFString.js +8 -0
  79. package/src/x_ite/Fields/SFTime.js +8 -0
  80. package/src/x_ite/Fields/SFVecPrototypeTemplate.js +30 -4
  81. package/src/x_ite/InputOutput/Generator.js +63 -2
  82. package/src/x_ite/Parser/JSONParser.js +1 -1
  83. package/src/x_ite/Prototype/X3DExternProtoDeclaration.js +123 -0
  84. package/src/x_ite/Prototype/X3DProtoDeclaration.js +228 -0
  85. package/src/x_ite/Routing/X3DRoute.js +67 -0
@@ -476,14 +476,7 @@ X3DPrototypeInstance .prototype = Object .assign (Object .create (X3DNode .proto
476
476
  {
477
477
  if (field .getAccessType () === X3DConstants .inputOutput && field .getReferences () .size !== 0)
478
478
  {
479
- let initializableReference = false;
480
-
481
- field .getReferences () .forEach (function (fieldReference)
482
- {
483
- initializableReference = initializableReference || fieldReference .isInitializable ();
484
- });
485
-
486
- if (!initializableReference)
479
+ if (![... field .getReferences ()] .some (reference => reference .isInitializable ()))
487
480
  mustOutputValue = !this .isDefaultValue (field);
488
481
  }
489
482
  }
@@ -607,7 +600,7 @@ X3DPrototypeInstance .prototype = Object .assign (Object .create (X3DNode .proto
607
600
  {
608
601
  const protoFields = field .getReferences ();
609
602
 
610
- protoFields .forEach (function (protoField)
603
+ for (const protoField of protoFields)
611
604
  {
612
605
  generator .string += generator .Indent ();
613
606
  generator .string += "<connect";
@@ -621,7 +614,7 @@ X3DPrototypeInstance .prototype = Object .assign (Object .create (X3DNode .proto
621
614
  generator .string += "'";
622
615
  generator .string += "/>";
623
616
  generator .string += generator .TidyBreak ();
624
- });
617
+ }
625
618
  }
626
619
 
627
620
  generator .DecIndent ();
@@ -639,6 +632,374 @@ X3DPrototypeInstance .prototype = Object .assign (Object .create (X3DNode .proto
639
632
 
640
633
  generator .LeaveScope ();
641
634
  },
635
+ toJSONStream: function (generator)
636
+ {
637
+ const sharedNode = generator .IsSharedNode (this);
638
+
639
+ generator .EnterScope ();
640
+
641
+ const name = generator .Name (this);
642
+
643
+ if (name .length)
644
+ {
645
+ if (generator .ExistsNode (this))
646
+ {
647
+ generator .string += '{';
648
+ generator .string += generator .TidySpace ();
649
+ generator .string += '"';
650
+ generator .string += "ProtoInstance";
651
+ generator .string += '"';
652
+ generator .string += ':';
653
+ generator .string += generator .TidyBreak ();
654
+ generator .string += generator .IncIndent ();
655
+ generator .string += generator .Indent ();
656
+ generator .string += '{';
657
+ generator .string += generator .TidyBreak ();
658
+ generator .string += generator .IncIndent ();
659
+
660
+ generator .string += generator .Indent ();
661
+ generator .string += '"';
662
+ generator .string += "@name";
663
+ generator .string += '"';
664
+ generator .string += ':';
665
+ generator .string += generator .TidySpace ();
666
+ generator .string += generator .JSONEncode (this .getTypeName ());
667
+ generator .string += ',';
668
+ generator .string += generator .TidyBreak ();
669
+
670
+ generator .string += generator .Indent ();
671
+ generator .string += '"';
672
+ generator .string += "@USE";
673
+ generator .string += '"';
674
+ generator .string += ':';
675
+ generator .string += generator .TidySpace ();
676
+ generator .string += generator .JSONEncode (name);
677
+ generator .string += generator .TidyBreak ();
678
+
679
+ generator .string += generator .DecIndent ();
680
+ generator .string += generator .Indent ();
681
+ generator .string += '}';
682
+ generator .string += generator .TidyBreak ();
683
+ generator .string += generator .DecIndent ();
684
+ generator .string += generator .Indent ();
685
+ generator .string += '}';
686
+
687
+ generator .LeaveScope ();
688
+ return;
689
+ }
690
+ }
691
+
692
+ // Type name
693
+
694
+ generator .string += '{';
695
+ generator .string += generator .TidySpace ();
696
+ generator .string += '"';
697
+ generator .string += "ProtoInstance";
698
+ generator .string += '"';
699
+ generator .string += ':';
700
+ generator .string += generator .TidyBreak ();
701
+ generator .string += generator .IncIndent ();
702
+ generator .string += generator .Indent ();
703
+ generator .string += '{';
704
+ generator .string += generator .TidyBreak ();
705
+ generator .string += generator .IncIndent ();
706
+
707
+
708
+ // DEF name
709
+
710
+ if (name .length)
711
+ {
712
+ generator .AddNode (this);
713
+
714
+ generator .string += generator .Indent ();
715
+ generator .string += '"';
716
+ generator .string += "@DEF";
717
+ generator .string += '"';
718
+ generator .string += ':';
719
+ generator .string += generator .TidySpace ();
720
+ generator .string += generator .JSONEncode (name);
721
+ generator .string += ',';
722
+ generator .string += generator .TidyBreak ();
723
+ }
724
+
725
+
726
+ // Type name
727
+
728
+ generator .string += generator .Indent ();
729
+ generator .string += '"';
730
+ generator .string += "@name";
731
+ generator .string += '"';
732
+ generator .string += ':';
733
+ generator .string += generator .TidySpace ();
734
+ generator .string += generator .JSONEncode (this .getTypeName ());
735
+ generator .string += ',';
736
+ generator .string += generator .TidyBreak ();
737
+
738
+
739
+ // Fields
740
+
741
+ const
742
+ fields = this .getChangedFields (),
743
+ references = [ ];
744
+
745
+ if (fields .length)
746
+ {
747
+ generator .string += generator .Indent ();
748
+ generator .string += '"';
749
+ generator .string += "fieldValue";
750
+ generator .string += '"';
751
+ generator .string += ':';
752
+ generator .string += generator .TidySpace ();
753
+ generator .string += '[';
754
+ generator .string += generator .TidyBreak ();
755
+ generator .string += generator .IncIndent ();
756
+
757
+ const outputFields = [ ];
758
+
759
+ for (const field of fields)
760
+ {
761
+ // If the field is a inputOutput and we have as reference only inputOnly or outputOnly we must output the value
762
+ // for this field.
763
+
764
+ let mustOutputValue = false;
765
+
766
+ if (generator .ExecutionContext ())
767
+ {
768
+ if (field .getAccessType () === X3DConstants .inputOutput && field .getReferences () .size !== 0)
769
+ {
770
+ if (![... field .getReferences ()] .some (reference => reference .isInitializable ()))
771
+ mustOutputValue = !this .isDefaultValue (field);
772
+ }
773
+ }
774
+
775
+ // If we have no execution context we are not in a proto and must not generate IS references the same is true
776
+ // if the node is a shared node as the node does not belong to the execution context.
777
+
778
+ if (field .getReferences () .size === 0 || !generator .ExecutionContext () || sharedNode || mustOutputValue)
779
+ {
780
+ if (mustOutputValue)
781
+ references .push (field);
782
+
783
+ outputFields .push (field);
784
+ }
785
+ else
786
+ {
787
+ references .push (field);
788
+ }
789
+ }
790
+
791
+ for (const field of outputFields)
792
+ {
793
+ switch (field .getType ())
794
+ {
795
+ case X3DConstants .SFNode:
796
+ {
797
+ generator .string += generator .Indent ();
798
+ generator .string += '{';
799
+ generator .string += generator .TidyBreak ();
800
+ generator .string += generator .IncIndent ();
801
+ generator .string += generator .Indent ();
802
+ generator .string += '"';
803
+ generator .string += "@name";
804
+ generator .string += '"';
805
+ generator .string += ':';
806
+ generator .string += generator .TidySpace ();
807
+ generator .string += generator .JSONEncode (field .getName ());
808
+ generator .string += ',';
809
+ generator .string += generator .TidyBreak ();
810
+ generator .string += generator .Indent ();
811
+ generator .string += '"';
812
+ generator .string += "-children";
813
+ generator .string += '"';
814
+ generator .string += ':';
815
+ generator .string += generator .TidySpace ();
816
+ generator .string += '[';
817
+ generator .string += generator .TidyBreak ();
818
+ generator .string += generator .IncIndent ();
819
+ generator .string += generator .Indent ();
820
+
821
+ field .toJSONStream (generator);
822
+
823
+ generator .string += generator .TidyBreak ();
824
+ generator .string += generator .DecIndent ();
825
+ generator .string += generator .Indent ();
826
+ generator .string += ']';
827
+ generator .string += generator .TidyBreak ();
828
+ generator .string += generator .DecIndent ();
829
+ generator .string += generator .Indent ();
830
+ generator .string += '}';
831
+ break;
832
+ }
833
+ case X3DConstants .MFNode:
834
+ {
835
+ generator .string += generator .Indent ();
836
+ generator .string += '{';
837
+ generator .string += generator .TidyBreak ();
838
+ generator .string += generator .IncIndent ();
839
+ generator .string += generator .Indent ();
840
+ generator .string += '"';
841
+ generator .string += "@name";
842
+ generator .string += '"';
843
+ generator .string += ':';
844
+ generator .string += generator .TidySpace ();
845
+ generator .string += generator .JSONEncode (field .getName ());
846
+ generator .string += ',';
847
+ generator .string += generator .TidyBreak ();
848
+ generator .string += generator .Indent ();
849
+ generator .string += '"';
850
+ generator .string += "-children";
851
+ generator .string += '"';
852
+ generator .string += ':';
853
+ generator .string += generator .TidySpace ();
854
+
855
+ field .toJSONStream (generator);
856
+
857
+ generator .string += generator .TidyBreak ();
858
+ generator .string += generator .DecIndent ();
859
+ generator .string += generator .Indent ();
860
+ generator .string += '}';
861
+ break;
862
+ }
863
+ default:
864
+ {
865
+ generator .string += generator .Indent ();
866
+ generator .string += '{';
867
+ generator .string += generator .TidyBreak ();
868
+ generator .string += generator .IncIndent ();
869
+ generator .string += generator .Indent ();
870
+ generator .string += '"';
871
+ generator .string += "@name";
872
+ generator .string += '"';
873
+ generator .string += ':';
874
+ generator .string += generator .TidySpace ();
875
+ generator .string += generator .JSONEncode (field .getName ());
876
+ generator .string += ',';
877
+ generator .string += generator .TidyBreak ();
878
+ generator .string += generator .Indent ();
879
+ generator .string += '"';
880
+ generator .string += "@value";
881
+ generator .string += '"';
882
+ generator .string += ':';
883
+ generator .string += generator .TidySpace ();
884
+
885
+ field .toJSONStream (generator);
886
+
887
+ generator .string += generator .TidyBreak ();
888
+ generator .string += generator .DecIndent ();
889
+ generator .string += generator .Indent ();
890
+ generator .string += '}';
891
+ break;
892
+ }
893
+ }
894
+
895
+ if (field !== outputFields .at (-1))
896
+ generator .string += ',';
897
+
898
+ generator .string += generator .TidyBreak ();
899
+ }
900
+
901
+ generator .string += generator .DecIndent ();
902
+ generator .string += generator .Indent ();
903
+ generator .string += ']';
904
+ generator .string += ',';
905
+ generator .string += generator .TidyBreak ();
906
+
907
+
908
+ // IS references
909
+
910
+ if (references .length && ! sharedNode)
911
+ {
912
+ generator .string += generator .Indent ();
913
+ generator .string += '"';
914
+ generator .string += "IS";
915
+ generator .string += '"';
916
+ generator .string += ':';
917
+ generator .string += generator .TidySpace ();
918
+ generator .string += '{';
919
+ generator .string += generator .TidyBreak ();
920
+ generator .string += generator .IncIndent ();
921
+ generator .string += generator .Indent ();
922
+ generator .string += '"';
923
+ generator .string += "connect";
924
+ generator .string += '"';
925
+ generator .string += ':';
926
+ generator .string += generator .TidySpace ();
927
+ generator .string += '[';
928
+ generator .string += generator .TidyBreak ();
929
+ generator .string += generator .IncIndent ();
930
+
931
+ for (const field of references)
932
+ {
933
+ const protoFields = [... field .getReferences ()];
934
+
935
+ for (const protoField of protoFields)
936
+ {
937
+ generator .string += generator .Indent ();
938
+ generator .string += '{';
939
+ generator .string += generator .TidyBreak ();
940
+ generator .string += generator .IncIndent ();
941
+
942
+ generator .string += generator .Indent ();
943
+ generator .string += '"';
944
+ generator .string += "@nodeField";
945
+ generator .string += '"';
946
+ generator .string += ':';
947
+ generator .string += generator .TidySpace ();
948
+ generator .string += generator .JSONEncode (field .getName ());
949
+ generator .string += ',';
950
+ generator .string += generator .TidyBreak ();
951
+
952
+ generator .string += generator .Indent ();
953
+ generator .string += '"';
954
+ generator .string += "@protoField";
955
+ generator .string += '"';
956
+ generator .string += ':';
957
+ generator .string += generator .TidySpace ();
958
+ generator .string += generator .JSONEncode (protoField .getName ());
959
+ generator .string += generator .TidyBreak ();
960
+
961
+ generator .string += generator .DecIndent ();
962
+ generator .string += generator .Indent ();
963
+ generator .string += '}';
964
+
965
+ if (field === references .at (-1) && protoField === protoFields .at (-1))
966
+ ;
967
+ else
968
+ {
969
+ generator .string += ',';
970
+ }
971
+
972
+ generator .string += generator .TidyBreak ();
973
+ }
974
+ }
975
+
976
+ generator .string += generator .DecIndent ();
977
+ generator .string += generator .Indent ();
978
+ generator .string += ']';
979
+ generator .string += generator .TidyBreak ();
980
+ generator .string += generator .DecIndent ();
981
+ generator .string += generator .Indent ();
982
+ generator .string += '}';
983
+ generator .string += ',';
984
+ generator .string += generator .TidyBreak ();
985
+ }
986
+ }
987
+
988
+ generator .string = generator .string .replace (/,(\s*)$/s, "$1");
989
+
990
+
991
+ // End
992
+
993
+ generator .string += generator .DecIndent ();
994
+ generator .string += generator .Indent ();
995
+ generator .string += '}';
996
+ generator .string += generator .TidyBreak ();
997
+ generator .string += generator .DecIndent ();
998
+ generator .string += generator .Indent ();
999
+ generator .string += '}';
1000
+
1001
+ generator .LeaveScope ();
1002
+ },
642
1003
  dispose: function ()
643
1004
  {
644
1005
  this [_protoNode] ._updateInstances .removeInterest ("construct", this);
@@ -239,7 +239,9 @@ HAnimHumanoid .prototype = Object .assign (Object .create (X3DChildNode .prototy
239
239
  renderObject .getJoints () .length = 0;
240
240
 
241
241
  this .transformNode .traverse (type, renderObject);
242
- this .skinning (type, renderObject);
242
+
243
+ if (this .isLive () .getValue ())
244
+ this .skinning (type, renderObject);
243
245
  },
244
246
  skinning: (function ()
245
247
  {
@@ -401,7 +401,8 @@ X3DGeometryNode .prototype = Object .assign (Object .create (X3DNode .prototype)
401
401
  if ((Xsize >= Ysize) && (Xsize >= Zsize))
402
402
  {
403
403
  // X size largest
404
- texCoordParams .Ssize = Xsize; texCoordParams .Sindex = 0;
404
+ texCoordParams .Ssize = Xsize;
405
+ texCoordParams .Sindex = 0;
405
406
 
406
407
  if (Ysize >= Zsize)
407
408
  texCoordParams .Tindex = 1;
@@ -411,7 +412,8 @@ X3DGeometryNode .prototype = Object .assign (Object .create (X3DNode .prototype)
411
412
  else if ((Ysize >= Xsize) && (Ysize >= Zsize))
412
413
  {
413
414
  // Y size largest
414
- texCoordParams .Ssize = Ysize; texCoordParams .Sindex = 1;
415
+ texCoordParams .Ssize = Ysize;
416
+ texCoordParams .Sindex = 1;
415
417
 
416
418
  if (Xsize >= Zsize)
417
419
  texCoordParams .Tindex = 0;
@@ -421,7 +423,8 @@ X3DGeometryNode .prototype = Object .assign (Object .create (X3DNode .prototype)
421
423
  else
422
424
  {
423
425
  // Z is the largest
424
- texCoordParams .Ssize = Zsize; texCoordParams .Sindex = 2;
426
+ texCoordParams .Ssize = Zsize;
427
+ texCoordParams .Sindex = 2;
425
428
 
426
429
  if (Xsize >= Ysize)
427
430
  texCoordParams .Tindex = 0;
@@ -90,6 +90,38 @@ ComponentInfo .prototype = Object .assign (Object .create (X3DObject .prototype)
90
90
  generator .string += "'";
91
91
  generator .string += "/>";
92
92
  },
93
+ toJSONStream: function (generator)
94
+ {
95
+ generator .string += generator .Indent ();
96
+ generator .string += '{';
97
+ generator .string += generator .TidyBreak ();
98
+ generator .string += generator .IncIndent ();
99
+
100
+ generator .string += generator .Indent ();
101
+ generator .string += '"';
102
+ generator .string += "@name";
103
+ generator .string += '"';
104
+ generator .string += ':';
105
+ generator .string += generator .TidySpace ();
106
+ generator .string += '"';
107
+ generator .string += this .name;
108
+ generator .string += '"';
109
+ generator .string += ',';
110
+ generator .string += generator .TidyBreak ();
111
+
112
+ generator .string += generator .Indent ();
113
+ generator .string += '"';
114
+ generator .string += "@level";
115
+ generator .string += '"';
116
+ generator .string += ':';
117
+ generator .string += generator .TidySpace ();
118
+ generator .string += this .level;
119
+ generator .string += generator .TidyBreak ();
120
+
121
+ generator .string += generator .DecIndent ();
122
+ generator .string += generator .Indent ();
123
+ generator .string += '}';
124
+ },
93
125
  });
94
126
 
95
127
  for (const key of Reflect .ownKeys (ComponentInfo .prototype))
@@ -72,6 +72,10 @@ ProfileInfo .prototype = Object .assign (Object .create (X3DObject .prototype),
72
72
  {
73
73
  generator .string += this .name;
74
74
  },
75
+ toJSONStream: function (generator)
76
+ {
77
+ generator .string += this .name;
78
+ },
75
79
  });
76
80
 
77
81
  for (const key of Reflect .ownKeys (ProfileInfo .prototype))
@@ -93,6 +93,52 @@ UnitInfo .prototype = Object .assign (Object .create (X3DObject .prototype),
93
93
  generator .string += "'";
94
94
  generator .string += "/>";
95
95
  },
96
+ toJSONStream: function (generator, _throw)
97
+ {
98
+ if (this .conversionFactor === 1)
99
+ throw new Error ("conversionFactor is 1");
100
+
101
+ generator .string += generator .Indent ();
102
+
103
+ generator .string += '{';
104
+ generator .string += generator .TidyBreak ();
105
+ generator .string += generator .IncIndent ();
106
+
107
+ generator .string += generator .Indent ();
108
+ generator .string += '"';
109
+ generator .string += "@category";
110
+ generator .string += '"';
111
+ generator .string += ':';
112
+ generator .string += generator .TidySpace ();
113
+ generator .string += '"';
114
+ generator .string += this .category;
115
+ generator .string += '"';
116
+ generator .string += ',';
117
+ generator .string += generator .TidyBreak ();
118
+
119
+ generator .string += generator .Indent ();
120
+ generator .string += '"';
121
+ generator .string += "@name";
122
+ generator .string += '"';
123
+ generator .string += ':';
124
+ generator .string += generator .TidySpace ();
125
+ generator .string += generator .JSONEncode (this .name);
126
+ generator .string += ',';
127
+ generator .string += generator .TidyBreak ();
128
+
129
+ generator .string += generator .Indent ();
130
+ generator .string += '"';
131
+ generator .string += "@conversionFactor";
132
+ generator .string += '"';
133
+ generator .string += ':';
134
+ generator .string += generator .TidySpace ();
135
+ generator .string += generator .DoublePrecision (this .conversionFactor);
136
+ generator .string += generator .TidyBreak ();
137
+
138
+ generator .string += generator .DecIndent ();
139
+ generator .string += generator .Indent ();
140
+ generator .string += '}';
141
+ },
96
142
  });
97
143
 
98
144
  for (const key of Reflect .ownKeys (UnitInfo .prototype))
@@ -849,6 +849,60 @@ X3DExecutionContext .prototype = Object .assign (Object .create (X3DBaseNode .pr
849
849
 
850
850
  this .getRoutes () .toXMLStream (generator);
851
851
 
852
+ generator .LeaveScope ();
853
+ generator .PopExecutionContext ();
854
+ },
855
+ toJSONStream: function (generator)
856
+ {
857
+ generator .PushExecutionContext (this);
858
+ generator .EnterScope ();
859
+ generator .ImportedNodes (this .getImportedNodes ());
860
+
861
+
862
+ // Extern proto declarations
863
+
864
+ this .getExternProtoDeclarations () .toJSONStream (generator, true);
865
+
866
+
867
+ // Proto declarations
868
+
869
+ this .getProtoDeclarations () .toJSONStream (generator, true);
870
+
871
+
872
+ // Root nodes
873
+
874
+ if (this .getRootNodes () .length)
875
+ {
876
+ for (const rootNode of this .getRootNodes ())
877
+ {
878
+ generator .string += generator .Indent ();
879
+
880
+ if (rootNode)
881
+ {
882
+ rootNode .toJSONStream (generator);
883
+ }
884
+ else
885
+ {
886
+ generator .string += generator .Indent ();
887
+ generator .string += "null";
888
+ }
889
+
890
+ generator .string += ',';
891
+ generator .string += generator .TidyBreak ();
892
+ }
893
+ }
894
+
895
+
896
+ // Imported nodes
897
+
898
+ this .getImportedNodes () .toJSONStream (generator, true);
899
+
900
+
901
+ // Routes
902
+
903
+ this .getRoutes () .toJSONStream (generator, true);
904
+
905
+
852
906
  generator .LeaveScope ();
853
907
  generator .PopExecutionContext ();
854
908
  },
@@ -109,6 +109,58 @@ X3DExportedNode .prototype = Object .assign (Object .create (X3DObject .prototyp
109
109
 
110
110
  generator .string += "/>";
111
111
  },
112
+ toJSONStream: function (generator)
113
+ {
114
+ const localName = generator .LocalName (this [_localNode]);
115
+
116
+ generator .string += generator .Indent ();
117
+ generator .string += '{';
118
+ generator .string += generator .TidySpace ();
119
+ generator .string += '"';
120
+ generator .string += "EXPORT";
121
+ generator .string += '"';
122
+ generator .string += ':';
123
+ generator .string += generator .TidyBreak ();
124
+ generator .string += generator .IncIndent ();
125
+ generator .string += generator .Indent ();
126
+ generator .string += '{';
127
+ generator .string += generator .TidyBreak ();
128
+ generator .string += generator .IncIndent ();
129
+
130
+ generator .string += generator .Indent ();
131
+ generator .string += '"';
132
+ generator .string += "@localDEF";
133
+ generator .string += '"';
134
+ generator .string += ':';
135
+ generator .string += generator .TidySpace ();
136
+ generator .string += generator .JSONEncode (localName);
137
+
138
+ if (this [_exportedName] !== localName)
139
+ {
140
+ generator .string += ',';
141
+ generator .string += generator .TidyBreak ();
142
+ generator .string += generator .Indent ();
143
+ generator .string += '"';
144
+ generator .string += "@AS";
145
+ generator .string += '"';
146
+ generator .string += ':';
147
+ generator .string += generator .TidySpace ();
148
+ generator .string += generator .JSONEncode (this [_exportedName]);
149
+ generator .string += generator .TidyBreak ();
150
+ }
151
+ else
152
+ {
153
+ generator .string += generator .TidyBreak ();
154
+ }
155
+
156
+ generator .string += generator .DecIndent ();
157
+ generator .string += generator .Indent ();
158
+ generator .string += '}';
159
+ generator .string += generator .TidyBreak ();
160
+ generator .string += generator .DecIndent ();
161
+ generator .string += generator .Indent ();
162
+ generator .string += '}';
163
+ },
112
164
  });
113
165
 
114
166
  for (const key of Reflect .ownKeys (X3DExportedNode .prototype))