@xeokit/xeokit-sdk 2.3.0-beta-19 → 2.3.0-beta-20

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.
@@ -104,7 +104,7 @@ class Item {
104
104
  * * Dynamically enable or disable items
105
105
  * * Dynamically show or hide items
106
106
  * * Supports cascading sub-menus
107
- * * Configure custom style with custom CSS (see examples above)
107
+ * * Configure custom style with CSS (see examples above)
108
108
  *
109
109
  * ## Usage
110
110
  *
@@ -1279,7 +1279,7 @@ const math = {
1279
1279
  * Returns true if the two 3-element vectors are the same.
1280
1280
  * @param v1
1281
1281
  * @param v2
1282
- * @returns {boolean}
1282
+ * @returns {Boolean}
1283
1283
  */
1284
1284
  compareVec3(v1, v2) {
1285
1285
  return (v1[0] === v2[0] && v1[1] === v2[1] && v1[2] === v2[2]);
@@ -3435,7 +3435,7 @@ const math = {
3435
3435
  * Returns true if the two 4x4 matrices are the same.
3436
3436
  * @param m1
3437
3437
  * @param m2
3438
- * @returns {boolean}
3438
+ * @returns {Boolean}
3439
3439
  */
3440
3440
  compareMat4(m1, m2) {
3441
3441
  return m1[0] === m2[0] &&
@@ -4342,7 +4342,7 @@ const math = {
4342
4342
  /** Returns true if the first AABB contains the second AABB.
4343
4343
  * @param aabb1
4344
4344
  * @param aabb2
4345
- * @returns {boolean}
4345
+ * @returns {Boolean}
4346
4346
  */
4347
4347
  containsAABB3: function (aabb1, aabb2) {
4348
4348
  const result = (
@@ -6738,7 +6738,7 @@ function isArray(value) {
6738
6738
  /**
6739
6739
  Tests if the given value is a string
6740
6740
  @param value
6741
- @returns {boolean}
6741
+ @returns {Boolean}
6742
6742
  @private
6743
6743
  */
6744
6744
  function isString(value) {
@@ -6748,7 +6748,7 @@ function isString(value) {
6748
6748
  /**
6749
6749
  Tests if the given value is a number
6750
6750
  @param value
6751
- @returns {boolean}
6751
+ @returns {Boolean}
6752
6752
  @private
6753
6753
  */
6754
6754
  function isNumeric(value) {
@@ -6758,7 +6758,7 @@ function isNumeric(value) {
6758
6758
  /**
6759
6759
  Tests if the given value is an ID
6760
6760
  @param value
6761
- @returns {boolean}
6761
+ @returns {Boolean}
6762
6762
  @private
6763
6763
  */
6764
6764
  function isID(value) {
@@ -6769,7 +6769,7 @@ function isID(value) {
6769
6769
  Tests if the given components are the same, where the components can be either IDs or instances.
6770
6770
  @param c1
6771
6771
  @param c2
6772
- @returns {boolean}
6772
+ @returns {Boolean}
6773
6773
  @private
6774
6774
  */
6775
6775
  function isSameComponent(c1, c2) {
@@ -6784,7 +6784,7 @@ function isSameComponent(c1, c2) {
6784
6784
  /**
6785
6785
  Tests if the given value is a function
6786
6786
  @param value
6787
- @returns {boolean}
6787
+ @returns {Boolean}
6788
6788
  @private
6789
6789
  */
6790
6790
  function isFunction$1(value) {
@@ -6794,7 +6794,7 @@ function isFunction$1(value) {
6794
6794
  /**
6795
6795
  Tests if the given value is a JavaScript JSON object, eg, ````{ foo: "bar" }````.
6796
6796
  @param value
6797
- @returns {boolean}
6797
+ @returns {Boolean}
6798
6798
  @private
6799
6799
  */
6800
6800
  function isObject$1(value) {
@@ -6852,7 +6852,7 @@ function applyIf(o, o2) {
6852
6852
  /**
6853
6853
  Returns true if the given map is empty.
6854
6854
  @param obj
6855
- @returns {boolean}
6855
+ @returns {Boolean}
6856
6856
  @private
6857
6857
  */
6858
6858
  function isEmptyObject$1(obj) {
@@ -9868,10 +9868,23 @@ class AngleMeasurement extends Component {
9868
9868
  return this._angle;
9869
9869
  }
9870
9870
 
9871
+ /**
9872
+ * Gets the color of the angle measurement.
9873
+ *
9874
+ * The color is an HTML string representation, eg. "#00BBFF" and "blue".
9875
+ *
9876
+ * @type {String}
9877
+ */
9871
9878
  get color() {
9872
9879
  return this._color;
9873
9880
  }
9874
9881
 
9882
+ /** Sets the color of the angle measurement.
9883
+ *
9884
+ * The color is given as an HTML string representation, eg. "#00BBFF" and "blue".
9885
+ *
9886
+ * @type {String}
9887
+ */
9875
9888
  set color(value) {
9876
9889
  this._originDot.setFillColor(value);
9877
9890
  this._cornerDot.setFillColor(value);
@@ -9886,7 +9899,7 @@ class AngleMeasurement extends Component {
9886
9899
  /**
9887
9900
  * Sets whether this AngleMeasurement is visible or not.
9888
9901
  *
9889
- * @type Boolean
9902
+ * @type {Boolean}
9890
9903
  */
9891
9904
  set visible(value) {
9892
9905
  value = value !== false;
@@ -9902,7 +9915,7 @@ class AngleMeasurement extends Component {
9902
9915
  /**
9903
9916
  * Gets whether this AngleMeasurement is visible or not.
9904
9917
  *
9905
- * @type Boolean
9918
+ * @type {Boolean}
9906
9919
  */
9907
9920
  get visible() {
9908
9921
  return this._visible;
@@ -10098,7 +10111,7 @@ class AngleMeasurementsControl extends Component {
10098
10111
 
10099
10112
  /** Gets if this AngleMeasurementsControl is currently active, where it is responding to input.
10100
10113
  *
10101
- * @returns {boolean}
10114
+ * @returns {Boolean}
10102
10115
  */
10103
10116
  get active() {
10104
10117
  return this._active;
@@ -13746,7 +13759,7 @@ class OcclusionTester {
13746
13759
  /**
13747
13760
  * Returns true if an occlusion test is needed.
13748
13761
  *
13749
- * @returns {boolean}
13762
+ * @returns {Boolean}
13750
13763
  */
13751
13764
  get needOcclusionTest() {
13752
13765
  return this._occlusionTestListDirty;
@@ -15499,7 +15512,7 @@ const Renderer = function (scene, options) {
15499
15512
 
15500
15513
  /**
15501
15514
  * Returns true if the next call to render() will draw something
15502
- * @returns {boolean}
15515
+ * @returns {Boolean}
15503
15516
  */
15504
15517
  this.needsRender = function () {
15505
15518
  return (imageDirty || drawableListDirty || stateSortDirty);
@@ -19882,7 +19895,7 @@ class Camera extends Component {
19882
19895
 
19883
19896
  /**
19884
19897
  * Gets if the World-space X-axis is "up".
19885
- * @returns {boolean}
19898
+ * @returns {Boolean}
19886
19899
  */
19887
19900
  get xUp() {
19888
19901
  return this._worldUp[0] > this._worldUp[1] && this._worldUp[0] > this._worldUp[2];
@@ -19890,7 +19903,7 @@ class Camera extends Component {
19890
19903
 
19891
19904
  /**
19892
19905
  * Gets if the World-space Y-axis is "up".
19893
- * @returns {boolean}
19906
+ * @returns {Boolean}
19894
19907
  */
19895
19908
  get yUp() {
19896
19909
  return this._worldUp[1] > this._worldUp[0] && this._worldUp[1] > this._worldUp[2];
@@ -19898,7 +19911,7 @@ class Camera extends Component {
19898
19911
 
19899
19912
  /**
19900
19913
  * Gets if the World-space Z-axis is "up".
19901
- * @returns {boolean}
19914
+ * @returns {Boolean}
19902
19915
  */
19903
19916
  get zUp() {
19904
19917
  return this._worldUp[2] > this._worldUp[0] && this._worldUp[2] > this._worldUp[1];
@@ -21294,7 +21307,7 @@ class ReadableGeometry extends Geometry {
21294
21307
 
21295
21308
  /**
21296
21309
  * @private
21297
- * @returns {boolean}
21310
+ * @returns {Boolean}
21298
21311
  */
21299
21312
  get isReadableGeometry() {
21300
21313
  return true;
@@ -24491,7 +24504,7 @@ class SAO extends Component {
24491
24504
  * Returns true if SAO is currently possible, where it is supported, enabled, and the current scene state is compatible.
24492
24505
  * Called internally by renderer logic.
24493
24506
  * @private
24494
- * @returns {boolean}
24507
+ * @returns {Boolean}
24495
24508
  */
24496
24509
  get possible() {
24497
24510
  if (!this._supported) {
@@ -25912,16 +25925,16 @@ class Scene extends Component {
25912
25925
  this.reflectionMaps = {};
25913
25926
 
25914
25927
  /**
25915
- * The {@link Bitmaps}s in this Scene, each mapped to its {@link Bitmap#id}.
25928
+ * The {@link Bitmap}s in this Scene, each mapped to its {@link Bitmap#id}.
25916
25929
  *
25917
25930
  * @type {{String:Bitmap}}
25918
25931
  */
25919
25932
  this.bitmaps = {};
25920
25933
 
25921
25934
  /**
25922
- * The {@link Line}s in this Scene, each mapped to its {@link Line#id}.
25935
+ * The {@link LineSet}s in this Scene, each mapped to its {@link LineSet#id}.
25923
25936
  *
25924
- * @type {{String:Line}}
25937
+ * @type {{String:LineSet}}
25925
25938
  */
25926
25939
  this.lineSets = {};
25927
25940
 
@@ -27846,9 +27859,24 @@ class Scene extends Component {
27846
27859
  }
27847
27860
  }
27848
27861
 
27862
+ /**
27863
+ * Texture repeat wrapping mode.
27864
+ * @type {number}
27865
+ */
27849
27866
  const RepeatWrapping = 1000;
27867
+
27868
+ /**
27869
+ * Texture clamp-to-edge wrapping mode.
27870
+ * @type {number}
27871
+ */
27850
27872
  const ClampToEdgeWrapping = 1001;
27873
+
27874
+ /**
27875
+ * Texture mirrored-repeat wrapping mode.
27876
+ * @type {number}
27877
+ */
27851
27878
  const MirroredRepeatWrapping = 1002;
27879
+
27852
27880
  const NearestFilter = 1003;
27853
27881
  const NearestMipMapNearestFilter = 1004;
27854
27882
  const NearestMipmapNearestFilter = 1004;
@@ -42390,7 +42418,7 @@ class VBOGeometry extends Geometry {
42390
42418
 
42391
42419
  /**
42392
42420
  * @private
42393
- * @returns {boolean}
42421
+ * @returns {Boolean}
42394
42422
  */
42395
42423
  get isVBOGeometry() {
42396
42424
  return true;
@@ -44439,14 +44467,14 @@ function buildTorusGeometry(cfg = {}) {
44439
44467
  *
44440
44468
  * * Creates a 3D quad containing our bitmap, located and oriented using ````pos````, ````normal```` and ````up```` vectors.
44441
44469
  * * Registered by {@link Bitmap#id} in {@link Scene#bitmaps}.
44442
- * * Created when we use {@link BCFViewpointsPlugin#setViewpoint} to load a BCF viewpoint that contains bitmaps.
44470
+ * * {@link BCFViewpointsPlugin} will save and load Bitmaps in BCF viewpoints.
44443
44471
  *
44444
44472
  * ## Usage
44445
44473
  *
44446
44474
  * In the example below, we'll load the Schependomlaan model, then use
44447
44475
  * an ````Bitmap```` to show a storey plan next to the model.
44448
44476
  *
44449
- * [<img src="http://xeokit.github.io/xeokit-sdk/assets/images/Bitmap_grid.png">](http://xeokit.github.io/xeokit-sdk/examples/#Bitmap_grid)
44477
+ * [<img src="http://xeokit.github.io/xeokit-sdk/assets/images/Bitmap_storeyPlan.png">](http://xeokit.github.io/xeokit-sdk/examples/#Bitmap_storeyPlan)
44450
44478
  *
44451
44479
  * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#Bitmap_grid)]
44452
44480
  *
@@ -44486,6 +44514,10 @@ function buildTorusGeometry(cfg = {}) {
44486
44514
  class Bitmap extends Component {
44487
44515
 
44488
44516
  /**
44517
+ * Creates a new Bitmap.
44518
+ *
44519
+ * Registers the Bitmap in {@link Scene#bitmaps}; causes Scene to fire a "bitmapCreated" event.
44520
+ *
44489
44521
  * @constructor
44490
44522
  * @param {Component} [owner] Owner component. When destroyed, the owner will destroy this ````Bitmap```` as well.
44491
44523
  * @param {*} [cfg] ````Bitmap```` configuration
@@ -44877,7 +44909,9 @@ class Bitmap extends Component {
44877
44909
  }
44878
44910
 
44879
44911
  /**
44880
- * @destroy
44912
+ * Destroys this ````Bitmap````.
44913
+ *
44914
+ * Removes the ```Bitmap```` from {@link Scene#bitmaps}; causes Scene to fire a "bitmapDestroyed" event.
44881
44915
  */
44882
44916
  destroy() {
44883
44917
  super.destroy();
@@ -44896,13 +44930,13 @@ class Bitmap extends Component {
44896
44930
  * * Creates a set of 3D line segments.
44897
44931
  * * Registered by {@link LineSet#id} in {@link Scene#lineSets}.
44898
44932
  * * Configure color using the {@link LinesMaterial} located at {@link Scene#linesMaterial}.
44899
- * * Created when we use {@link BCFViewpointsPlugin#setViewpoint} to load a BCF viewpoint that contains lines.
44933
+ * * {@link BCFViewpointsPlugin} will save and load Linesets in BCF viewpoints.
44934
+ *
44935
+ * ## Usage
44900
44936
  *
44901
44937
  * In the example below, we'll load the Schependomlaan model, then use
44902
44938
  * a ````LineSet```` to show a grid underneath the model.
44903
44939
  *
44904
- * <img src="http://xeokit.io/img/docs/Bitmap/BCF_SaveViewpoint_BitmapsAndLines.png">
44905
- *
44906
44940
  * [<img src="http://xeokit.github.io/xeokit-sdk/assets/images/LineSet_grid.png">](http://xeokit.github.io/xeokit-sdk/examples/#LineSet_grid)
44907
44941
  *
44908
44942
  * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#LineSet_grid)]
@@ -44926,8 +44960,7 @@ class Bitmap extends Component {
44926
44960
  * const model = xktLoader.load({
44927
44961
  * id: "myModel",
44928
44962
  * src: "../assets/models/xkt/v8/ifc/Schependomlaan.ifc.xkt",
44929
- *
44930
- * position: [0,1,0],
44963
+ * position: [0,1,0],
44931
44964
  * edges: true,
44932
44965
  * saoEnabled: true
44933
44966
  * });
@@ -44946,15 +44979,19 @@ class Bitmap extends Component {
44946
44979
  class LineSet extends Component {
44947
44980
 
44948
44981
  /**
44982
+ * Creates a new LineSet.
44983
+ *
44984
+ * Registers the LineSet in {@link Scene#lineSets}; causes Scene to fire a "lineSetCreated" event.
44985
+ *
44949
44986
  * @constructor
44950
44987
  * @param {Component} [owner] Owner component. When destroyed, the owner will destroy this ````LineSet```` as well.
44951
44988
  * @param {*} [cfg] ````LineSet```` configuration
44952
44989
  * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.
44953
- * @param {Number[]} cfg.positions World-space vertex positions.
44954
- * @param {Number[]} [cfg.indices] Indices
44955
- * @param {Number[]} [cfg.color=[0,0,0]] The color of this ````LineSet````.
44990
+ * @param {Number[]} cfg.positions World-space 3D vertex positions.
44991
+ * @param {Number[]} [cfg.indices] Indices to connect ````positions```` into line segments. Note that these are separate line segments, not a polyline.
44992
+ * @param {Number[]} [cfg.color=[0,0,0]] The color of this ````LineSet````. This is both emissive and diffuse.
44956
44993
  * @param {Boolean} [cfg.visible=true] Indicates whether or not this ````LineSet```` is visible.
44957
- * @param {Number} [cfg.opacity=1.0] ````LineSet````'s initial opacity factor, multiplies by the rendered fragment alpha.
44994
+ * @param {Number} [cfg.opacity=1.0] ````LineSet````'s initial opacity factor.
44958
44995
  */
44959
44996
  constructor(owner, cfg = {}) {
44960
44997
 
@@ -44994,7 +45031,7 @@ class LineSet extends Component {
44994
45031
  }
44995
45032
 
44996
45033
  /**
44997
- * Sets if this ````LineSet```` is visible or not.
45034
+ * Sets if this ````LineSet```` is visible.
44998
45035
  *
44999
45036
  * Default value is ````true````.
45000
45037
  *
@@ -45005,7 +45042,7 @@ class LineSet extends Component {
45005
45042
  }
45006
45043
 
45007
45044
  /**
45008
- * Gets if this ````LineSet```` is visible or not.
45045
+ * Gets if this ````LineSet```` is visible.
45009
45046
  *
45010
45047
  * Default value is ````true````.
45011
45048
  *
@@ -45016,7 +45053,7 @@ class LineSet extends Component {
45016
45053
  }
45017
45054
 
45018
45055
  /**
45019
- * Gets the vertex positions of the lines in this ````LineSet````.
45056
+ * Gets the 3D World-space vertex positions of the lines in this ````LineSet````.
45020
45057
  *
45021
45058
  * @returns {Number[]}
45022
45059
  */
@@ -45034,7 +45071,9 @@ class LineSet extends Component {
45034
45071
  }
45035
45072
 
45036
45073
  /**
45037
- * @destroy
45074
+ * Destroys this ````LineSet````.
45075
+ *
45076
+ * Removes the ```LineSet```` from {@link Scene#lineSets}; causes Scene to fire a "lineSetDestroyed" event.
45038
45077
  */
45039
45078
  destroy() {
45040
45079
  super.destroy();
@@ -45053,16 +45092,28 @@ const tempVec3c$6 = math.vec3();
45053
45092
  * BCF is a format for managing issues on a BIM project. This plugin's viewpoints conform to
45054
45093
  * the <a href="https://github.com/buildingSMART/BCF-API">BCF Version 2.1</a> specification.
45055
45094
  *
45095
+ * ## Supported BCF Elements
45096
+ *
45097
+ * A BCF viewpoint saves and loads the following state into a xeokit {@link Viewer}:
45098
+ *
45099
+ * * {@link Camera} position, orientation and projection
45100
+ * * {@link SectionPlane}s to slice the model
45101
+ * * {@link LineSet}s to show 3D lines
45102
+ * * {@link Bitmap}s to show images
45103
+ * * {@link Entity} visibilities and selection states
45104
+ *
45056
45105
  * ## Saving a BCF Viewpoint
45057
45106
  *
45058
45107
  * In the example below we'll create a {@link Viewer}, load an ````.XKT```` model into it using an {@link XKTLoaderPlugin},
45059
- * slice the model in half using a {@link SectionPlanesPlugin}, then use a {@link BCFViewpointsPlugin#getViewpoint}
45108
+ * slice the model in half using a {@link SectionPlanesPlugin}, create a grid ground plane using a {@link LineSet} and a 2D
45109
+ * plan view using a {@link Bitmap}, then use a {@link BCFViewpointsPlugin#getViewpoint}
45060
45110
  * to save a viewpoint to JSON, which we'll log to the JavaScript developer console.
45061
45111
  *
45062
45112
  * * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#BCF_SaveViewpoint)]
45063
45113
  *
45064
45114
  * ````javascript
45065
- * import {Viewer, XKTLoaderPlugin, SectionPlanesPlugin, BCFViewpointsPlugin} from "xeokit-sdk.es.js";
45115
+ * import {Viewer, XKTLoaderPlugin, SectionPlanesPlugin,
45116
+ * LineSet, Bitmap, buildGridGeometry, BCFViewpointsPlugin} from "xeokit-sdk.es.js";
45066
45117
  *
45067
45118
  * // Create a Viewer
45068
45119
  * const viewer = new Viewer({
@@ -45070,6 +45121,12 @@ const tempVec3c$6 = math.vec3();
45070
45121
  * transparent: true
45071
45122
  * });
45072
45123
  *
45124
+ * // Set camera position and orientation
45125
+ * viewer.scene.camera.eye = [-48.93, 54.54, 50.41];
45126
+ * viewer.scene.camera.look = [0.55, -0.61, -0.55];
45127
+ * viewer.scene.camera.up = [0, -1, 0];
45128
+ * viewer.scene.camera.perspective.fov = 60;
45129
+ *
45073
45130
  * // Add a XKTLoaderPlugin
45074
45131
  * const xktLoader = new XKTLoaderPlugin(viewer);
45075
45132
  *
@@ -45093,15 +45150,37 @@ const tempVec3c$6 = math.vec3();
45093
45150
  * dir: [0.5, 0.0, 0.5]
45094
45151
  * });
45095
45152
  *
45096
- * // When model is loaded, set camera, select some objects and capture a BCF viewpoint to the console
45153
+ * // Create a bitmap
45154
+ * const bitmap = new Bitmap(viewer.scene, {
45155
+ * src: "../assets/images/schependomlaanPlanView.png",
45156
+ * visible: true,
45157
+ * height: 24.0,
45158
+ * pos: [-15, 0, -10],
45159
+ * normal: [0, -1, 0],
45160
+ * up: [0, 0, 1],
45161
+ * collidable: false,
45162
+ * opacity: 1.0,
45163
+ * clippable: false,
45164
+ * pickable: true
45165
+ * });
45166
+ *
45167
+ * // Create a grid ground plane
45168
+ * const geometryArrays = buildGridGeometry({
45169
+ * size: 60,
45170
+ * divisions: 10
45171
+ * });
45172
+ *
45173
+ * new LineSet(viewer.scene, {
45174
+ * positions: geometryArrays.positions,
45175
+ * indices: geometryArrays.indices,
45176
+ * position: [10,0,10],
45177
+ * clippable: false
45178
+ * });
45179
+ *
45180
+ * // When model is loaded, select some objects and capture a BCF viewpoint to the console
45097
45181
  * modelNode.on("loaded", () => {
45098
45182
  *
45099
45183
  * const scene = viewer.scene;
45100
- * const camera = scene.camera;
45101
- *
45102
- * camera.eye = [-2.37, 18.97, -26.12];
45103
- * camera.look = [10.97, 5.82, -11.22];
45104
- * camera.up = [0.36, 0.83, 0.40];
45105
45184
  *
45106
45185
  * scene.setObjectsSelected([
45107
45186
  * "3b2U496P5Ebhz5FROhTwFH",
@@ -45118,6 +45197,57 @@ const tempVec3c$6 = math.vec3();
45118
45197
  * });
45119
45198
  * ````
45120
45199
  *
45200
+ * The saved BCF viewpoint would look something like below. Note that some elements are truncated for brevity.
45201
+ *
45202
+ * ````json
45203
+ * {
45204
+ * "perspective_camera": {
45205
+ * "camera_view_point": { "x": -48.93, "y": 54.54, "z": 50.41 },
45206
+ * "camera_direction": { "x": 0.55, "y": -0.61, "z": -0.55},
45207
+ * "camera_up_vector": { "x": 0.37, "y": -0.41, "z": 0.83 },
45208
+ * "field_of_view": 60.0
45209
+ * },
45210
+ * "lines": [{
45211
+ * "start_point": { "x": 1.0, "y": 1.0, "z": 1.0 },
45212
+ * "end_point": { "x": 0.0, "y": 0.0, "z": 0.0 },
45213
+ * //...(truncated)
45214
+ * }],
45215
+ * "bitmaps": [{
45216
+ * "bitmap_type": "png",
45217
+ * "bitmap_data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB9AAAAdp...", //...(truncated)
45218
+ * "location": { "x": -15, "y": 10, "z": 0 },
45219
+ * "normal": { "x": 0, "y": 0, "z": -1 },
45220
+ * "up": { "x": 0, "y": -1, "z": 0 },
45221
+ * "height": 24
45222
+ * }],
45223
+ * "clipping_planes": [{
45224
+ * "location": { "x": 0.0, "y": 0.0, "z": 0.0 },
45225
+ * "direction": { "x": 0.5, "y": 0.0, "z": 0.5 }
45226
+ * }],
45227
+ * "snapshot": {
45228
+ * "snapshot_type": "png",
45229
+ * "snapshot_data": "data:image/png;base64,......"
45230
+ * },
45231
+ * "components": {
45232
+ * "visibility": {
45233
+ * "default_visibility": false,
45234
+ * "exceptions": [{
45235
+ * "ifc_guid": "4$cshxZO9AJBebsni$z9Yk",
45236
+ * "originating_system": "xeokit.io",
45237
+ * "authoring_tool_id": "xeokit/v3.2"
45238
+ * },
45239
+ * //...
45240
+ * ]
45241
+ * },
45242
+ * "selection": [{
45243
+ * "ifc_guid": "4$cshxZO9AJBebsni$z9Yk",
45244
+ * },
45245
+ * //...
45246
+ * ]
45247
+ * }
45248
+ * }
45249
+ * ````
45250
+ *
45121
45251
  * ## Saving View Setup Hints
45122
45252
  *
45123
45253
  * BCFViewpointsPlugin can optionally save hints in the viewpoint, which indicate how to set up the view when
@@ -45161,7 +45291,7 @@ const tempVec3c$6 = math.vec3();
45161
45291
  * });
45162
45292
  * ````
45163
45293
  *
45164
- * ## Dealing With Loaded Models That Are Not in the Viewpoint
45294
+ * ## Dealing With Loaded Models that are not in the Viewpoint
45165
45295
  *
45166
45296
  * If, for example, we load model "duplex", hide some objects, then save a BCF viewpoint with
45167
45297
  * ````BCFViewpointsPlugin#getViewpoint````, then load another model, "schependomlaan", then load the viewpoint again
@@ -45270,8 +45400,7 @@ class BCFViewpointsPlugin extends Plugin {
45270
45400
  /**
45271
45401
  * Saves viewer state to a BCF viewpoint.
45272
45402
  *
45273
- * Note that xeokit's {@link Camera#look} is the **point-of-interest**, whereas the BCF ````camera_direction```` is a
45274
- * direction vector. Therefore, we save ````camera_direction```` as the vector from {@link Camera#eye} to {@link Camera#look}.
45403
+ * See ````BCFViewpointsPlugin```` class comments for more info.
45275
45404
  *
45276
45405
  * @param {*} [options] Options for getting the viewpoint.
45277
45406
  * @param {Boolean} [options.spacesVisible=false] Indicates whether ````IfcSpace```` types should be forced visible in the viewpoint.
@@ -45284,84 +45413,6 @@ class BCFViewpointsPlugin extends Plugin {
45284
45413
  * objects in the viewpoint will be visible.
45285
45414
  * @param {Boolean} [options.reverseClippingPlanes=false] When ````true````, clipping planes are reversed (https://github.com/buildingSMART/BCF-XML/issues/193)
45286
45415
  * @returns {*} BCF JSON viewpoint object
45287
- * @example
45288
- *
45289
- * const viewer = new Viewer();
45290
- *
45291
- * const bcfPlugin = new BCFPlugin(viewer, {
45292
- * //...
45293
- * });
45294
- *
45295
- * const viewpoint = bcfPlugin.getViewpoint({ // Options - see constructor
45296
- * spacesVisible: false, // Default
45297
- * spaceBoundariesVisible: false, // Default
45298
- * openingsVisible: false // Default
45299
- * });
45300
- *
45301
- * // viewpoint will resemble the following:
45302
- *
45303
- * {
45304
- * perspective_camera: {
45305
- * camera_view_point: {
45306
- * x: 0.0,
45307
- * y: 0.0,
45308
- * z: 0.0
45309
- * },
45310
- * camera_direction: {
45311
- * x: 1.0,
45312
- * y: 1.0,
45313
- * z: 2.0
45314
- * },
45315
- * camera_up_vector: {
45316
- * x: 0.0,
45317
- * y: 0.0,
45318
- * z: 1.0
45319
- * },
45320
- * field_of_view: 90.0
45321
- * },
45322
- * lineSets: [{
45323
- * start_point: {
45324
- * x: 1.0,
45325
- * y: 1.0,
45326
- * z: 1.0
45327
- * },
45328
- * end_point: {
45329
- * x: 0.0,
45330
- * y: 0.0,
45331
- * z: 0.0
45332
- * }
45333
- * }],
45334
- * clipping_planes: [{
45335
- * location: {
45336
- * x: 0.5,
45337
- * y: 0.5,
45338
- * z: 0.5
45339
- * },
45340
- * direction: {
45341
- * x: 1.0,
45342
- * y: 0.0,
45343
- * z: 0.0
45344
- * }
45345
- * }],
45346
- * bitmaps: [],
45347
- * snapshot: {
45348
- * snapshot_type: png,
45349
- * snapshot_data: "data:image/png;base64,......"
45350
- * },
45351
- * components: {
45352
- * visibility: {
45353
- * default_visibility: false,
45354
- * exceptions: [{
45355
- * ifc_guid: 4$cshxZO9AJBebsni$z9Yk,
45356
- * originating_system: xeokit.io,
45357
- * authoring_tool_id: xeokit/v1.0
45358
- * }]
45359
- * },
45360
- * selection: [{
45361
- * ifc_guid: "4$cshxZO9AJBebsni$z9Yk",
45362
- * }]
45363
- * }
45364
- * }
45365
45416
  */
45366
45417
  getViewpoint(options = {}) {
45367
45418
  const scene = this.viewer.scene;
@@ -45683,7 +45734,9 @@ class BCFViewpointsPlugin extends Plugin {
45683
45734
  });
45684
45735
  new LineSet(scene, {
45685
45736
  positions,
45686
- indices
45737
+ indices,
45738
+ clippable: false,
45739
+ collidable: true
45687
45740
  });
45688
45741
  }
45689
45742
 
@@ -45696,6 +45749,7 @@ class BCFViewpointsPlugin extends Plugin {
45696
45749
  let location = xyzObjectToArray(e.location, tempVec3a$X);
45697
45750
  let normal = xyzObjectToArray(e.normal, tempVec3b$9);
45698
45751
  let up = xyzObjectToArray(e.up, tempVec3c$6);
45752
+ let height = e.height || 1;
45699
45753
  if (!bitmap_type) {
45700
45754
  return;
45701
45755
  }
@@ -45721,7 +45775,10 @@ class BCFViewpointsPlugin extends Plugin {
45721
45775
  type: bitmap_type,
45722
45776
  pos: location,
45723
45777
  normal: normal,
45724
- up: up
45778
+ up: up,
45779
+ clippable: false,
45780
+ collidable: true,
45781
+ height
45725
45782
  });
45726
45783
  });
45727
45784
  }
@@ -46360,7 +46417,7 @@ class DistanceMeasurement extends Component {
46360
46417
  /**
46361
46418
  * Sets whether this DistanceMeasurement is visible or not.
46362
46419
  *
46363
- * @type Boolean
46420
+ * @type {Boolean}
46364
46421
  */
46365
46422
  set visible(value) {
46366
46423
  value = value !== undefined ? Boolean(value) : this.plugin.defaultVisible;
@@ -46381,7 +46438,7 @@ class DistanceMeasurement extends Component {
46381
46438
  /**
46382
46439
  * Gets whether this DistanceMeasurement is visible or not.
46383
46440
  *
46384
- * @type Boolean
46441
+ * @type {Boolean}
46385
46442
  */
46386
46443
  get visible() {
46387
46444
  return this._visible;
@@ -46562,7 +46619,7 @@ class DistanceMeasurementsControl extends Component {
46562
46619
 
46563
46620
  /** Gets if this DistanceMeasurementsControl is currently active, where it is responding to input.
46564
46621
  *
46565
- * @returns {boolean}
46622
+ * @returns {Boolean}
46566
46623
  */
46567
46624
  get active() {
46568
46625
  return this._active;
@@ -54294,7 +54351,7 @@ class TrianglesBatchingLayer {
54294
54351
  *
54295
54352
  * @param lenPositions Number of positions we'd like to create in the portion.
54296
54353
  * @param lenIndices Number of indices we'd like to create in this portion.
54297
- * @returns {boolean} True if OK to create another portion.
54354
+ * @returns {Boolean} True if OK to create another portion.
54298
54355
  */
54299
54356
  canCreatePortion(lenPositions, lenIndices) {
54300
54357
  if (this._finalized) {
@@ -63724,7 +63781,7 @@ class LinesBatchingLayer {
63724
63781
  *
63725
63782
  * @param lenPositions Number of positions we'd like to create in the portion.
63726
63783
  * @param lenIndices Number of indices we'd like to create in this portion.
63727
- * @returns {boolean} True if OK to create another portion.
63784
+ * @returns {Boolean} True if OK to create another portion.
63728
63785
  */
63729
63786
  canCreatePortion(lenPositions, lenIndices) {
63730
63787
  if (this._finalized) {
@@ -67669,7 +67726,7 @@ class PointsBatchingLayer {
67669
67726
  * Tests if there is room for another portion in this PointsBatchingLayer.
67670
67727
  *
67671
67728
  * @param lenPositions Number of positions we'd like to create in the portion.
67672
- * @returns {boolean} True if OK to create another portion.
67729
+ * @returns {Boolean} True if OK to create another portion.
67673
67730
  */
67674
67731
  canCreatePortion(lenPositions) {
67675
67732
  if (this._finalized) {
@@ -72807,6 +72864,34 @@ class SceneModel {
72807
72864
  }
72808
72865
  }
72809
72866
 
72867
+ const Cache = {
72868
+
72869
+ enabled: false,
72870
+ files: {},
72871
+
72872
+ add: function (key, file) {
72873
+ if (this.enabled === false) {
72874
+ return;
72875
+ }
72876
+ this.files[key] = file;
72877
+ },
72878
+
72879
+ get: function (key) {
72880
+ if (this.enabled === false) {
72881
+ return;
72882
+ }
72883
+ return this.files[key];
72884
+ },
72885
+
72886
+ remove: function (key) {
72887
+ delete this.files[key];
72888
+ },
72889
+
72890
+ clear: function () {
72891
+ this.files = {};
72892
+ }
72893
+ };
72894
+
72810
72895
  class LoadingManager {
72811
72896
 
72812
72897
  constructor(onLoad, onProgress, onError) {
@@ -72944,6 +73029,161 @@ class Loader {
72944
73029
  }
72945
73030
  }
72946
73031
 
73032
+ const loading = {};
73033
+
73034
+ class FileLoader extends Loader {
73035
+
73036
+ constructor(manager) {
73037
+ super(manager);
73038
+ }
73039
+
73040
+ load(url, onLoad, onProgress, onError) {
73041
+ if (url === undefined) {
73042
+ url = '';
73043
+ }
73044
+ if (this.path !== undefined) {
73045
+ url = this.path + url;
73046
+ }
73047
+ url = this.manager.resolveURL(url);
73048
+ const cached = Cache.get(url);
73049
+ if (cached !== undefined) {
73050
+ this.manager.itemStart(url);
73051
+ setTimeout(() => {
73052
+ if (onLoad) {
73053
+ onLoad(cached);
73054
+ }
73055
+ this.manager.itemEnd(url);
73056
+ }, 0);
73057
+ return cached;
73058
+ }
73059
+ if (loading[url] !== undefined) {
73060
+ loading[url].push({onLoad, onProgress, onError});
73061
+ return;
73062
+ }
73063
+ loading[url] = [];
73064
+ loading[url].push({onLoad, onProgress, onError});
73065
+ const req = new Request(url, {
73066
+ headers: new Headers(this.requestHeader),
73067
+ credentials: this.withCredentials ? 'include' : 'same-origin'
73068
+ });
73069
+ const mimeType = this.mimeType;
73070
+ const responseType = this.responseType;
73071
+ fetch(req).then(response => {
73072
+ if (response.status === 200 || response.status === 0) {
73073
+ // Some browsers return HTTP Status 0 when using non-http protocol
73074
+ // e.g. 'file://' or 'data://'. Handle as success.
73075
+ if (response.status === 0) {
73076
+ console.warn('FileLoader: HTTP Status 0 received.');
73077
+ }
73078
+ if (typeof ReadableStream === 'undefined' || response.body.getReader === undefined) {
73079
+ return response;
73080
+ }
73081
+ const callbacks = loading[url];
73082
+ const reader = response.body.getReader();
73083
+ const contentLength = response.headers.get('Content-Length');
73084
+ const total = contentLength ? parseInt(contentLength) : 0;
73085
+ const lengthComputable = total !== 0;
73086
+ let loaded = 0;
73087
+ const stream = new ReadableStream({
73088
+ start(controller) {
73089
+ readData();
73090
+
73091
+ function readData() {
73092
+ reader.read().then(({done, value}) => {
73093
+ if (done) {
73094
+ controller.close();
73095
+ } else {
73096
+ loaded += value.byteLength;
73097
+ const event = new ProgressEvent('progress', {lengthComputable, loaded, total});
73098
+ for (let i = 0, il = callbacks.length; i < il; i++) {
73099
+ const callback = callbacks[i];
73100
+ if (callback.onProgress) {
73101
+ callback.onProgress(event);
73102
+ }
73103
+ }
73104
+ controller.enqueue(value);
73105
+ readData();
73106
+ }
73107
+ });
73108
+ }
73109
+ }
73110
+ });
73111
+ return new Response(stream);
73112
+ } else {
73113
+ throw Error(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`);
73114
+ }
73115
+ }).then(response => {
73116
+ switch (responseType) {
73117
+ case 'arraybuffer':
73118
+ return response.arrayBuffer();
73119
+ case 'blob':
73120
+ return response.blob();
73121
+ case 'document':
73122
+ return response.text()
73123
+ .then(text => {
73124
+ const parser = new DOMParser();
73125
+ return parser.parseFromString(text, mimeType);
73126
+ });
73127
+ case 'json':
73128
+ return response.json();
73129
+ default:
73130
+ if (mimeType === undefined) {
73131
+ return response.text();
73132
+ } else {
73133
+ // sniff encoding
73134
+ const re = /charset="?([^;"\s]*)"?/i;
73135
+ const exec = re.exec(mimeType);
73136
+ const label = exec && exec[1] ? exec[1].toLowerCase() : undefined;
73137
+ const decoder = new TextDecoder(label);
73138
+ return response.arrayBuffer().then(ab => decoder.decode(ab));
73139
+ }
73140
+ }
73141
+ }).then(data => {
73142
+ // Add to cache only on HTTP success, so that we do not cache
73143
+ // error response bodies as proper responses to requests.
73144
+ Cache.add(url, data);
73145
+ const callbacks = loading[url];
73146
+ delete loading[url];
73147
+ for (let i = 0, il = callbacks.length; i < il; i++) {
73148
+ const callback = callbacks[i];
73149
+ if (callback.onLoad) {
73150
+ callback.onLoad(data);
73151
+ }
73152
+ }
73153
+ }).catch(err => {
73154
+ // Abort errors and other errors are handled the same
73155
+ const callbacks = loading[url];
73156
+ if (callbacks === undefined) {
73157
+ // When onLoad was called and url was deleted in `loading`
73158
+ this.manager.itemError(url);
73159
+ throw err;
73160
+
73161
+ }
73162
+ delete loading[url];
73163
+ for (let i = 0, il = callbacks.length; i < il; i++) {
73164
+ const callback = callbacks[i];
73165
+ if (callback.onError) {
73166
+ callback.onError(err);
73167
+ }
73168
+ }
73169
+ this.manager.itemError(url);
73170
+ }).finally(() => {
73171
+ this.manager.itemEnd(url);
73172
+ });
73173
+ this.manager.itemStart(url);
73174
+ }
73175
+
73176
+ setResponseType(value) {
73177
+ this.responseType = value;
73178
+ return this;
73179
+ }
73180
+
73181
+ setMimeType(value) {
73182
+ this.mimeType = value;
73183
+ return this;
73184
+ }
73185
+ }
73186
+
72947
73187
  /**
72948
73188
  * @author Deepkolos / https://github.com/deepkolos
72949
73189
  */
@@ -73018,219 +73258,6 @@ class WorkerPool$1 {
73018
73258
 
73019
73259
  }
73020
73260
 
73021
- /**
73022
- * Transcodes texture data.
73023
- *
73024
- * A {@link SceneModel} configured with an appropriate TextureTranscoder will allow us to add textures from
73025
- * transcoded buffers or files. For a concrete example, see {@link VBOSceneModel}, which can be configured with
73026
- * a {@link KTX2TextureTranscoder}, which allows us to add textures from KTX2 buffers and files.
73027
- *
73028
- * @interface
73029
- */
73030
- class TextureTranscoder {
73031
-
73032
- /**
73033
- * Transcodes texture data from transcoded buffers into a {@link Texture2D}.
73034
- *
73035
- * @param {ArrayBuffer[]} buffers Transcoded texture data. Given as an array of buffers so that we can support
73036
- * multi-image textures, such as cube maps.
73037
- * @param {*} config Transcoding options.
73038
- * @param {Texture2D} texture The texture to load.
73039
- * @returns {Promise} Resolves when the texture has loaded.
73040
- */
73041
- transcode(buffers, texture, config = {}) {
73042
- }
73043
-
73044
- /**
73045
- * Destroys this transcoder.
73046
- */
73047
- destroy() {
73048
- }
73049
- }
73050
-
73051
- const Cache = {
73052
-
73053
- enabled: false,
73054
- files: {},
73055
-
73056
- add: function (key, file) {
73057
- if (this.enabled === false) {
73058
- return;
73059
- }
73060
- this.files[key] = file;
73061
- },
73062
-
73063
- get: function (key) {
73064
- if (this.enabled === false) {
73065
- return;
73066
- }
73067
- return this.files[key];
73068
- },
73069
-
73070
- remove: function (key) {
73071
- delete this.files[key];
73072
- },
73073
-
73074
- clear: function () {
73075
- this.files = {};
73076
- }
73077
- };
73078
-
73079
- const loading = {};
73080
-
73081
- class FileLoader extends Loader {
73082
-
73083
- constructor(manager) {
73084
- super(manager);
73085
- }
73086
-
73087
- load(url, onLoad, onProgress, onError) {
73088
- if (url === undefined) {
73089
- url = '';
73090
- }
73091
- if (this.path !== undefined) {
73092
- url = this.path + url;
73093
- }
73094
- url = this.manager.resolveURL(url);
73095
- const cached = Cache.get(url);
73096
- if (cached !== undefined) {
73097
- this.manager.itemStart(url);
73098
- setTimeout(() => {
73099
- if (onLoad) {
73100
- onLoad(cached);
73101
- }
73102
- this.manager.itemEnd(url);
73103
- }, 0);
73104
- return cached;
73105
- }
73106
- if (loading[url] !== undefined) {
73107
- loading[url].push({onLoad, onProgress, onError});
73108
- return;
73109
- }
73110
- loading[url] = [];
73111
- loading[url].push({onLoad, onProgress, onError});
73112
- const req = new Request(url, {
73113
- headers: new Headers(this.requestHeader),
73114
- credentials: this.withCredentials ? 'include' : 'same-origin'
73115
- });
73116
- const mimeType = this.mimeType;
73117
- const responseType = this.responseType;
73118
- fetch(req).then(response => {
73119
- if (response.status === 200 || response.status === 0) {
73120
- // Some browsers return HTTP Status 0 when using non-http protocol
73121
- // e.g. 'file://' or 'data://'. Handle as success.
73122
- if (response.status === 0) {
73123
- console.warn('FileLoader: HTTP Status 0 received.');
73124
- }
73125
- if (typeof ReadableStream === 'undefined' || response.body.getReader === undefined) {
73126
- return response;
73127
- }
73128
- const callbacks = loading[url];
73129
- const reader = response.body.getReader();
73130
- const contentLength = response.headers.get('Content-Length');
73131
- const total = contentLength ? parseInt(contentLength) : 0;
73132
- const lengthComputable = total !== 0;
73133
- let loaded = 0;
73134
- const stream = new ReadableStream({
73135
- start(controller) {
73136
- readData();
73137
-
73138
- function readData() {
73139
- reader.read().then(({done, value}) => {
73140
- if (done) {
73141
- controller.close();
73142
- } else {
73143
- loaded += value.byteLength;
73144
- const event = new ProgressEvent('progress', {lengthComputable, loaded, total});
73145
- for (let i = 0, il = callbacks.length; i < il; i++) {
73146
- const callback = callbacks[i];
73147
- if (callback.onProgress) {
73148
- callback.onProgress(event);
73149
- }
73150
- }
73151
- controller.enqueue(value);
73152
- readData();
73153
- }
73154
- });
73155
- }
73156
- }
73157
- });
73158
- return new Response(stream);
73159
- } else {
73160
- throw Error(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`);
73161
- }
73162
- }).then(response => {
73163
- switch (responseType) {
73164
- case 'arraybuffer':
73165
- return response.arrayBuffer();
73166
- case 'blob':
73167
- return response.blob();
73168
- case 'document':
73169
- return response.text()
73170
- .then(text => {
73171
- const parser = new DOMParser();
73172
- return parser.parseFromString(text, mimeType);
73173
- });
73174
- case 'json':
73175
- return response.json();
73176
- default:
73177
- if (mimeType === undefined) {
73178
- return response.text();
73179
- } else {
73180
- // sniff encoding
73181
- const re = /charset="?([^;"\s]*)"?/i;
73182
- const exec = re.exec(mimeType);
73183
- const label = exec && exec[1] ? exec[1].toLowerCase() : undefined;
73184
- const decoder = new TextDecoder(label);
73185
- return response.arrayBuffer().then(ab => decoder.decode(ab));
73186
- }
73187
- }
73188
- }).then(data => {
73189
- // Add to cache only on HTTP success, so that we do not cache
73190
- // error response bodies as proper responses to requests.
73191
- Cache.add(url, data);
73192
- const callbacks = loading[url];
73193
- delete loading[url];
73194
- for (let i = 0, il = callbacks.length; i < il; i++) {
73195
- const callback = callbacks[i];
73196
- if (callback.onLoad) {
73197
- callback.onLoad(data);
73198
- }
73199
- }
73200
- }).catch(err => {
73201
- // Abort errors and other errors are handled the same
73202
- const callbacks = loading[url];
73203
- if (callbacks === undefined) {
73204
- // When onLoad was called and url was deleted in `loading`
73205
- this.manager.itemError(url);
73206
- throw err;
73207
-
73208
- }
73209
- delete loading[url];
73210
- for (let i = 0, il = callbacks.length; i < il; i++) {
73211
- const callback = callbacks[i];
73212
- if (callback.onError) {
73213
- callback.onError(err);
73214
- }
73215
- }
73216
- this.manager.itemError(url);
73217
- }).finally(() => {
73218
- this.manager.itemEnd(url);
73219
- });
73220
- this.manager.itemStart(url);
73221
- }
73222
-
73223
- setResponseType(value) {
73224
- this.responseType = value;
73225
- return this;
73226
- }
73227
-
73228
- setMimeType(value) {
73229
- this.mimeType = value;
73230
- return this;
73231
- }
73232
- }
73233
-
73234
73261
  const KTX2TransferSRGB = 2;
73235
73262
  const KTX2_ALPHA_PREMULTIPLIED = 1;
73236
73263
 
@@ -77114,848 +77141,6 @@ class VBOSceneModel extends Component {
77114
77141
  }
77115
77142
  }
77116
77143
 
77117
- /**
77118
- * @private
77119
- */
77120
- class GLTFSceneGraphLoader {
77121
-
77122
- constructor(cfg) { // TODO: Loading options fallbacks on loader, eg. handleGLTFNode etc
77123
- }
77124
-
77125
- load(plugin, modelNode, src, options, ok, error) {
77126
- options = options || {};
77127
- var spinner = modelNode.scene.canvas.spinner;
77128
- spinner.processes++;
77129
- loadGLTF$1(plugin, modelNode, src, options, function () {
77130
- spinner.processes--;
77131
- core.scheduleTask(function () {
77132
- modelNode.scene.fire("modelLoaded", modelNode.id); // FIXME: Assumes listeners know order of these two events
77133
- modelNode.fire("loaded", true, false);
77134
- });
77135
- if (ok) {
77136
- ok();
77137
- }
77138
- },
77139
- function (msg) {
77140
- spinner.processes--;
77141
- modelNode.error(msg);
77142
- if (error) {
77143
- error(msg);
77144
- }
77145
- modelNode.fire("error", msg);
77146
- });
77147
- }
77148
-
77149
- parse(plugin, modelNode, gltf, options, ok, error) {
77150
- options = options || {};
77151
- var spinner = modelNode.scene.canvas.spinner;
77152
- spinner.processes++;
77153
- parseGLTF$2(plugin, gltf, "", options, modelNode, function () {
77154
- spinner.processes--;
77155
- modelNode.scene.fire("modelLoaded", modelNode.id); // FIXME: Assumes listeners know order of these two events
77156
- modelNode.fire("loaded", true, false);
77157
- if (ok) {
77158
- ok();
77159
- }
77160
- },
77161
- function (msg) {
77162
- spinner.processes--;
77163
- modelNode.error(msg);
77164
- modelNode.fire("error", msg);
77165
- if (error) {
77166
- error(msg);
77167
- }
77168
- });
77169
- }
77170
- }
77171
-
77172
-
77173
- var loadGLTF$1 = (function () {
77174
- return function (plugin, modelNode, src, options, ok, error) {
77175
- plugin.dataSource.getGLTF(src, function (json) { // OK
77176
- options.basePath = getBasePath(src);
77177
- parseGLTF$2(plugin, json, src, options, modelNode, ok, error);
77178
- },
77179
- error);
77180
- };
77181
-
77182
- function getBasePath(src) {
77183
- var i = src.lastIndexOf("/");
77184
- return (i !== 0) ? src.substring(0, i + 1) : "";
77185
- }
77186
- })();
77187
-
77188
- var parseGLTF$2 = (function () {
77189
-
77190
- const WEBGL_COMPONENT_TYPES = {
77191
- 5120: Int8Array,
77192
- 5121: Uint8Array,
77193
- 5122: Int16Array,
77194
- 5123: Uint16Array,
77195
- 5125: Uint32Array,
77196
- 5126: Float32Array
77197
- };
77198
-
77199
- const WEBGL_TYPE_SIZES = {
77200
- 'SCALAR': 1,
77201
- 'VEC2': 2,
77202
- 'VEC3': 3,
77203
- 'VEC4': 4,
77204
- 'MAT2': 4,
77205
- 'MAT3': 9,
77206
- 'MAT4': 16
77207
- };
77208
-
77209
- return function (plugin, json, src, options, modelNode, ok) {
77210
- modelNode.clear();
77211
- var ctx = {
77212
- src: src,
77213
- loadBuffer: options.loadBuffer,
77214
- basePath: options.basePath,
77215
- prioritizeGLTFNode: options.prioritizeGLTFNode,
77216
- handleGLTFNode: options.handleGLTFNode,
77217
- ignoreMaterials: !!options.ignoreMaterials,
77218
- edgeThreshold: options.edgeThreshold,
77219
- readableGeometry: !!options.readableGeometry,
77220
- json: json,
77221
- scene: modelNode.scene,
77222
- plugin: plugin,
77223
- modelNode: modelNode,
77224
- modelNodeProps: {
77225
- visible: modelNode.visible,
77226
- culled: modelNode.culled,
77227
- xrayed: modelNode.xrayed,
77228
- highlighted: modelNode.highlighted,
77229
- selected: modelNode.selected,
77230
- outlined: modelNode.outlined,
77231
- clippable: modelNode.clippable,
77232
- pickable: modelNode.pickable,
77233
- collidable: modelNode.collidable,
77234
- castsShadow: modelNode.castsShadow,
77235
- receivesShadow: modelNode.receivesShadow,
77236
- colorize: modelNode.colorize,
77237
- opacity: modelNode.opacity,
77238
- edges: modelNode.edges
77239
- }
77240
- };
77241
-
77242
- modelNode.scene.loading++; // Disables (re)compilation
77243
-
77244
- loadBuffers(ctx, function () {
77245
-
77246
- loadBufferViews(ctx);
77247
- loadAccessors(ctx);
77248
- loadTextures(ctx);
77249
- loadMaterials(ctx);
77250
- loadMeshes(ctx);
77251
- loadDefaultScene(ctx);
77252
-
77253
- modelNode.scene.loading--; // Re-enables (re)compilation
77254
-
77255
- ok();
77256
- });
77257
- };
77258
-
77259
- function loadBuffers(ctx, ok) {
77260
- var buffers = ctx.json.buffers;
77261
- if (buffers) {
77262
- var numToLoad = buffers.length;
77263
- for (var i = 0, len = buffers.length; i < len; i++) {
77264
- loadBuffer(ctx, buffers[i], function () {
77265
- if (--numToLoad === 0) {
77266
- ok();
77267
- }
77268
- }, function (msg) {
77269
- ctx.plugin.error(msg);
77270
- if (--numToLoad === 0) {
77271
- ok();
77272
- }
77273
- });
77274
- }
77275
- } else {
77276
- ok();
77277
- }
77278
- }
77279
-
77280
- function loadBuffer(ctx, bufferInfo, ok, err) {
77281
- var uri = bufferInfo.uri;
77282
- if (uri) {
77283
- ctx.plugin.dataSource.getArrayBuffer(ctx.src, uri, function (data) {
77284
- bufferInfo._buffer = data;
77285
- ok();
77286
- },
77287
- err);
77288
- } else {
77289
- err('gltf/handleBuffer missing uri in ' + JSON.stringify(bufferInfo));
77290
- }
77291
- }
77292
-
77293
- function loadBufferViews(ctx) {
77294
- var bufferViewsInfo = ctx.json.bufferViews;
77295
- if (bufferViewsInfo) {
77296
- for (var i = 0, len = bufferViewsInfo.length; i < len; i++) {
77297
- loadBufferView(ctx, bufferViewsInfo[i]);
77298
- }
77299
- }
77300
- }
77301
-
77302
- function loadBufferView(ctx, bufferViewInfo) {
77303
-
77304
- var buffer = ctx.json.buffers[bufferViewInfo.buffer];
77305
-
77306
- bufferViewInfo._typedArray = null;
77307
-
77308
- var byteLength = bufferViewInfo.byteLength || 0;
77309
- var byteOffset = bufferViewInfo.byteOffset || 0;
77310
-
77311
- bufferViewInfo._buffer = buffer._buffer.slice(byteOffset, byteOffset + byteLength);
77312
- }
77313
-
77314
- function loadAccessors(ctx) {
77315
- var accessorsInfo = ctx.json.accessors;
77316
- if (accessorsInfo) {
77317
- for (var i = 0, len = accessorsInfo.length; i < len; i++) {
77318
- loadAccessor(ctx, accessorsInfo[i]);
77319
- }
77320
- }
77321
- }
77322
-
77323
- function loadAccessor(ctx, accessorInfo) {
77324
- var bufferViewInfo = ctx.json.bufferViews[accessorInfo.bufferView];
77325
- var itemSize = WEBGL_TYPE_SIZES[accessorInfo.type];
77326
- var TypedArray = WEBGL_COMPONENT_TYPES[accessorInfo.componentType];
77327
-
77328
- // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
77329
- var elementBytes = TypedArray.BYTES_PER_ELEMENT;
77330
- var itemBytes = elementBytes * itemSize;
77331
-
77332
- // The buffer is not interleaved if the stride is the item size in bytes.
77333
- if (accessorInfo.byteStride && accessorInfo.byteStride !== itemBytes) ; else {
77334
- accessorInfo._typedArray = new TypedArray(bufferViewInfo._buffer, accessorInfo.byteOffset || 0, accessorInfo.count * itemSize);
77335
- accessorInfo._itemSize = itemSize;
77336
- }
77337
- }
77338
-
77339
-
77340
- function loadTextures(ctx) {
77341
- var texturesInfo = ctx.json.textures;
77342
- if (texturesInfo) {
77343
- for (var i = 0, len = texturesInfo.length; i < len; i++) {
77344
- loadTexture(ctx, texturesInfo[i]);
77345
- }
77346
- }
77347
- }
77348
-
77349
- function loadTexture(ctx, textureInfo) {
77350
- let uri = ctx.json.images[textureInfo.source].uri;
77351
- if (uri && !uri.match(/^data:(.*?)(;base64)?,(.*)$/)) {
77352
- uri = ctx.basePath + uri;
77353
- }
77354
- textureInfo._texture = new Texture(ctx.modelNode, {
77355
- src: uri,
77356
- flipY: !!textureInfo.flipY,
77357
- //encoding: "sRGB"
77358
- encoding: "linear"
77359
- });
77360
- }
77361
-
77362
- function loadMaterials(ctx) {
77363
- var materialsInfo = ctx.json.materials;
77364
- if (materialsInfo) {
77365
- var materialInfo;
77366
- var material;
77367
- for (var i = 0, len = materialsInfo.length; i < len; i++) {
77368
- materialInfo = materialsInfo[i];
77369
- material = loadMaterial(ctx, materialInfo);
77370
- materialInfo._material = material;
77371
- }
77372
- }
77373
- }
77374
-
77375
- function loadMaterial(ctx, materialInfo) {
77376
-
77377
- var json = ctx.json;
77378
- var cfg = {};
77379
- var textureInfo;
77380
-
77381
- // Common attributes
77382
-
77383
- var normalTexture = materialInfo.normalTexture;
77384
- if (normalTexture) {
77385
- textureInfo = json.textures[normalTexture.index];
77386
- if (textureInfo) {
77387
- cfg.normalMap = textureInfo._texture;
77388
- //cfg.normalMap.encoding = "linear";
77389
- }
77390
- }
77391
-
77392
- var occlusionTexture = materialInfo.occlusionTexture;
77393
- if (occlusionTexture) {
77394
- textureInfo = json.textures[occlusionTexture.index];
77395
- if (textureInfo) {
77396
- cfg.occlusionMap = textureInfo._texture;
77397
- }
77398
- }
77399
-
77400
- var emissiveTexture = materialInfo.emissiveTexture;
77401
- if (emissiveTexture) {
77402
- textureInfo = json.textures[emissiveTexture.index];
77403
- if (textureInfo) {
77404
- cfg.emissiveMap = textureInfo._texture;
77405
- //cfg.emissiveMap.encoding = "sRGB";
77406
- }
77407
- }
77408
-
77409
- var emissiveFactor = materialInfo.emissiveFactor;
77410
- if (emissiveFactor) {
77411
- cfg.emissive = emissiveFactor;
77412
- }
77413
-
77414
- cfg.backfaces = !!materialInfo.doubleSided;
77415
-
77416
- var alphaMode = materialInfo.alphaMode;
77417
- switch (alphaMode) {
77418
- case "NORMAL_OPAQUE":
77419
- cfg.alphaMode = "opaque";
77420
- break;
77421
- case "MASK":
77422
- cfg.alphaMode = "mask";
77423
- break;
77424
- case "BLEND":
77425
- cfg.alphaMode = "blend";
77426
- break;
77427
- }
77428
-
77429
- var alphaCutoff = materialInfo.alphaCutoff;
77430
- if (alphaCutoff !== undefined) {
77431
- cfg.alphaCutoff = alphaCutoff;
77432
- }
77433
-
77434
- var extensions = materialInfo.extensions;
77435
- if (extensions) {
77436
-
77437
- // Specular PBR material
77438
-
77439
- var specularPBR = extensions["KHR_materials_pbrSpecularGlossiness"];
77440
- if (specularPBR) {
77441
-
77442
- var diffuseFactor = specularPBR.diffuseFactor;
77443
- if (diffuseFactor !== null && diffuseFactor !== undefined) {
77444
- cfg.diffuse = diffuseFactor.slice(0, 3);
77445
- cfg.alpha = diffuseFactor[3];
77446
- }
77447
-
77448
- var diffuseTexture = specularPBR.diffuseTexture;
77449
- if (diffuseTexture) {
77450
- textureInfo = json.textures[diffuseTexture.index];
77451
- if (textureInfo) {
77452
- cfg.diffuseMap = textureInfo._texture;
77453
- //cfg.diffuseMap.encoding = "sRGB";
77454
- }
77455
- }
77456
-
77457
- var specularFactor = specularPBR.specularFactor;
77458
- if (specularFactor !== null && specularFactor !== undefined) {
77459
- cfg.specular = specularFactor.slice(0, 3);
77460
- }
77461
-
77462
- var glossinessFactor = specularPBR.glossinessFactor;
77463
- if (glossinessFactor !== null && glossinessFactor !== undefined) {
77464
- cfg.glossiness = glossinessFactor;
77465
- }
77466
-
77467
- var specularGlossinessTexture = specularPBR.specularGlossinessTexture;
77468
- if (specularGlossinessTexture) {
77469
- textureInfo = json.textures[specularGlossinessTexture.index];
77470
- if (textureInfo) {
77471
- cfg.specularGlossinessMap = textureInfo._texture;
77472
- //cfg.specularGlossinessMap.encoding = "linear";
77473
- }
77474
- }
77475
-
77476
- return new SpecularMaterial(ctx.modelNode, cfg);
77477
- }
77478
-
77479
- // Common Phong, Blinn, Lambert or Constant materials
77480
-
77481
- var common = extensions["KHR_materials_common"];
77482
- if (common) {
77483
-
77484
- var technique = common.technique;
77485
- var values = common.values || {};
77486
-
77487
- var blinn = technique === "BLINN";
77488
- var phong = technique === "PHONG";
77489
- var lambert = technique === "LAMBERT";
77490
-
77491
- var shininess = values.shininess;
77492
- if ((blinn || phong) && shininess !== null && shininess !== undefined) {
77493
- cfg.shininess = shininess;
77494
- } else {
77495
- cfg.shininess = 0;
77496
- }
77497
- var texture;
77498
- var diffuse = values.diffuse;
77499
- if (diffuse && (blinn || phong || lambert)) {
77500
- if (utils.isString(diffuse)) {
77501
- texture = json.textures[diffuse];
77502
- if (texture) {
77503
- cfg.diffuseMap = texture;
77504
- // cfg.diffuseMap.encoding = "sRGB";
77505
- }
77506
- } else {
77507
- cfg.diffuse = diffuse.slice(0, 3);
77508
- }
77509
- } else {
77510
- cfg.diffuse = [0, 0, 0];
77511
- }
77512
-
77513
- var specular = values.specular;
77514
- if (specular && (blinn || phong)) {
77515
- if (utils.isString(specular)) {
77516
- texture = json.textures[specular];
77517
- if (texture) {
77518
- cfg.specularMap = texture;
77519
- }
77520
- } else {
77521
- cfg.specular = specular.slice(0, 3);
77522
- }
77523
- } else {
77524
- cfg.specular = [0, 0, 0];
77525
- }
77526
-
77527
- var emission = values.emission;
77528
- if (emission) {
77529
- if (utils.isString(emission)) {
77530
- texture = json.textures[emission];
77531
- if (texture) {
77532
- cfg.emissiveMap = texture;
77533
- }
77534
- } else {
77535
- cfg.emissive = emission.slice(0, 3);
77536
- }
77537
- } else {
77538
- cfg.emissive = [0, 0, 0];
77539
- }
77540
-
77541
- var transparency = values.transparency;
77542
- if (transparency !== null && transparency !== undefined) {
77543
- cfg.alpha = transparency;
77544
- } else {
77545
- cfg.alpha = 1.0;
77546
- }
77547
-
77548
- values.transparent;
77549
-
77550
- return new PhongMaterial(ctx.scene, cfg);
77551
- }
77552
- }
77553
-
77554
- // Metallic PBR naterial
77555
-
77556
- var metallicPBR = materialInfo.pbrMetallicRoughness;
77557
- if (metallicPBR) {
77558
-
77559
- var baseColorFactor = metallicPBR.baseColorFactor;
77560
- if (baseColorFactor) {
77561
- cfg.baseColor = baseColorFactor.slice(0, 3);
77562
- cfg.alpha = baseColorFactor[3];
77563
- }
77564
-
77565
- var colorTexture = metallicPBR.colorTexture;
77566
- if (colorTexture) {
77567
- textureInfo = json.textures[colorTexture.index];
77568
- if (textureInfo) {
77569
- cfg.baseColorMap = textureInfo._texture;
77570
- //cfg.baseColorMap.encoding = "sRGB";
77571
- }
77572
- }
77573
-
77574
- var metallicFactor = metallicPBR.metallicFactor;
77575
- if (metallicFactor !== null && metallicFactor !== undefined) {
77576
- cfg.metallic = metallicFactor;
77577
- }
77578
-
77579
- var roughnessFactor = metallicPBR.roughnessFactor;
77580
- if (roughnessFactor !== null && roughnessFactor !== undefined) {
77581
- cfg.roughness = roughnessFactor;
77582
- }
77583
-
77584
- var metallicRoughnessTexture = metallicPBR.metallicRoughnessTexture;
77585
- if (metallicRoughnessTexture) {
77586
- textureInfo = json.textures[metallicRoughnessTexture.index];
77587
- if (textureInfo) {
77588
- cfg.metallicRoughnessMap = textureInfo._texture;
77589
- // cfg.metallicRoughnessMap.encoding = "linear";
77590
- }
77591
- }
77592
-
77593
- return new MetallicMaterial(ctx.scene, cfg);
77594
- }
77595
-
77596
- // Default material
77597
-
77598
- return new PhongMaterial(ctx.scene, cfg);
77599
- }
77600
-
77601
- function loadMeshes(ctx) {
77602
- var meshes = ctx.json.meshes;
77603
- if (meshes) {
77604
- for (var i = 0, len = meshes.length; i < len; i++) {
77605
- loadMesh(ctx, meshes[i]);
77606
- }
77607
- }
77608
- }
77609
-
77610
- function loadMesh(ctx, meshInfo) {
77611
- var json = ctx.json;
77612
- var mesh = [];
77613
- var primitivesInfo = meshInfo.primitives;
77614
- var materialIndex;
77615
- var materialInfo;
77616
- var accessorInfo;
77617
- var attributes;
77618
-
77619
- if (primitivesInfo) {
77620
-
77621
- var primitiveInfo;
77622
- var indicesIndex;
77623
- var positionsIndex;
77624
- var normalsIndex;
77625
- var uv0Index;
77626
- var geometryCfg;
77627
- var meshCfg;
77628
- var geometry;
77629
-
77630
- for (var i = 0, len = primitivesInfo.length; i < len; i++) {
77631
- primitiveInfo = primitivesInfo[i];
77632
- if (primitiveInfo.mode < 4 ) {
77633
- continue;
77634
- }
77635
- geometryCfg = {
77636
- primitive: "triangles",
77637
- compressGeometry: true,
77638
- edgeThreshold: ctx.edgeThreshold
77639
- };
77640
-
77641
- indicesIndex = primitiveInfo.indices;
77642
-
77643
- if (indicesIndex !== null && indicesIndex !== undefined) {
77644
- accessorInfo = json.accessors[indicesIndex];
77645
- geometryCfg.indices = accessorInfo._typedArray;
77646
- }
77647
-
77648
- attributes = primitiveInfo.attributes;
77649
- if (!attributes) {
77650
- continue;
77651
- }
77652
-
77653
- positionsIndex = attributes.POSITION;
77654
-
77655
- if (positionsIndex !== null && positionsIndex !== undefined) {
77656
- accessorInfo = json.accessors[positionsIndex];
77657
- geometryCfg.positions = accessorInfo._typedArray;
77658
- }
77659
-
77660
- normalsIndex = attributes.NORMAL;
77661
-
77662
- if (normalsIndex !== null && normalsIndex !== undefined) {
77663
- accessorInfo = json.accessors[normalsIndex];
77664
- geometryCfg.normals = accessorInfo._typedArray;
77665
- }
77666
-
77667
- uv0Index = attributes.TEXCOORD_0;
77668
-
77669
- if (uv0Index !== null && uv0Index !== undefined) {
77670
- accessorInfo = json.accessors[uv0Index];
77671
- geometryCfg.uv = accessorInfo._typedArray;
77672
- }
77673
-
77674
- meshCfg = {};
77675
-
77676
- if (ctx.readableGeometry) {
77677
- geometry = new ReadableGeometry(ctx.modelNode, geometryCfg);
77678
- } else {
77679
- geometry = new VBOGeometry(ctx.modelNode, geometryCfg);
77680
- }
77681
-
77682
- meshCfg.geometry = geometry;
77683
-
77684
- materialIndex = primitiveInfo.material;
77685
- if (materialIndex !== null && materialIndex !== undefined) {
77686
- materialInfo = json.materials[materialIndex];
77687
- if (materialInfo) {
77688
- meshCfg.material = materialInfo._material;
77689
- }
77690
- }
77691
-
77692
- mesh.push(meshCfg);
77693
- }
77694
- }
77695
- meshInfo._mesh = mesh;
77696
- }
77697
-
77698
- function loadDefaultScene(ctx) {
77699
- var json = ctx.json;
77700
- var scene = json.scene || 0;
77701
- var defaultSceneInfo = json.scenes[scene];
77702
- if (!defaultSceneInfo) {
77703
- error(ctx, "glTF has no default scene");
77704
- return;
77705
- }
77706
- loadScene(ctx, defaultSceneInfo);
77707
- }
77708
-
77709
- function loadScene(ctx, sceneInfo) {
77710
- var nodes = sceneInfo.nodes;
77711
- if (!nodes) {
77712
- return;
77713
- }
77714
- var json = ctx.json;
77715
- var glTFNode;
77716
- for (var i = 0, len = nodes.length; i < len; i++) {
77717
- glTFNode = json.nodes[nodes[i]];
77718
- if (!glTFNode) {
77719
- error(ctx, "Node not found: " + i);
77720
- continue;
77721
- }
77722
- loadNode(ctx, glTFNode, null, null);
77723
- }
77724
- }
77725
-
77726
- function loadNode(ctx, glTFNode, matrix, parent) {
77727
-
77728
- parent = parent || ctx.modelNode;
77729
-
77730
- var createEntity;
77731
-
77732
- if (ctx.prioritizeGLTFNode) {
77733
- const priority = ctx.prioritizeGLTFNode(ctx.modelNode.id, glTFNode);
77734
- if (priority === undefined || priority === null) {
77735
- return;
77736
- }
77737
- }
77738
-
77739
- if (ctx.handleGLTFNode) {
77740
- var actions = {};
77741
- if (!ctx.handleGLTFNode(ctx.modelNode.id, glTFNode, actions)) {
77742
- return;
77743
- }
77744
- if (actions.createEntity) {
77745
- createEntity = actions.createEntity;
77746
- }
77747
- }
77748
-
77749
- const json = ctx.json;
77750
- const modelNode = ctx.modelNode;
77751
- const hasChildNodes = glTFNode.children && glTFNode.children.length > 0;
77752
-
77753
- var localMatrix;
77754
-
77755
- if (glTFNode.matrix) {
77756
- localMatrix = glTFNode.matrix;
77757
- if (matrix) {
77758
- matrix = math.mulMat4(matrix, localMatrix, math.mat4());
77759
- } else {
77760
- matrix = localMatrix;
77761
- }
77762
- }
77763
-
77764
- if (glTFNode.translation) {
77765
- localMatrix = math.translationMat4v(glTFNode.translation);
77766
- if (matrix) {
77767
- matrix = math.mulMat4(matrix, localMatrix, localMatrix);
77768
- } else {
77769
- matrix = localMatrix;
77770
- }
77771
- }
77772
-
77773
- if (glTFNode.rotation) {
77774
- localMatrix = math.quaternionToMat4(glTFNode.rotation);
77775
- if (matrix) {
77776
- matrix = math.mulMat4(matrix, localMatrix, localMatrix);
77777
- } else {
77778
- matrix = localMatrix;
77779
- }
77780
- }
77781
-
77782
- if (glTFNode.scale) {
77783
- localMatrix = math.scalingMat4v(glTFNode.scale);
77784
- if (matrix) {
77785
- matrix = math.mulMat4(matrix, localMatrix, localMatrix);
77786
- } else {
77787
- matrix = localMatrix;
77788
- }
77789
- }
77790
-
77791
- if (glTFNode.mesh !== undefined) {
77792
-
77793
- var meshInfo = json.meshes[glTFNode.mesh];
77794
-
77795
- if (meshInfo) {
77796
-
77797
- var meshesInfo = meshInfo._mesh;
77798
- var meshesInfoMesh;
77799
- var mesh;
77800
- var numMeshes = meshesInfo.length;
77801
-
77802
- if (!createEntity && numMeshes > 0 && !hasChildNodes) {
77803
-
77804
- // Case 1: Not creating object, node has meshes, node has no child nodes
77805
-
77806
- for (var i = 0, len = numMeshes; i < len; i++) {
77807
- meshesInfoMesh = meshesInfo[i];
77808
- let meshCfg = {
77809
- geometry: meshesInfoMesh.geometry,
77810
- matrix: matrix
77811
- };
77812
- utils.apply(ctx.modelNodeProps, meshCfg);
77813
- meshCfg.material = meshesInfoMesh.material;
77814
- mesh = new Mesh(modelNode, meshCfg);
77815
- parent.addChild(mesh, false); // Don't automatically inherit properties
77816
- }
77817
- return;
77818
- }
77819
-
77820
- if (createEntity && numMeshes === 1 && !hasChildNodes) {
77821
-
77822
- // Case 2: Creating object, node has one mesh, node has no child nodes
77823
-
77824
- meshesInfoMesh = meshesInfo[0];
77825
- let meshCfg = {
77826
- geometry: meshesInfoMesh.geometry,
77827
- matrix: matrix
77828
- };
77829
- utils.apply(ctx.modelNodeProps, meshCfg);
77830
- meshCfg.material = meshesInfoMesh.material;
77831
- utils.apply(createEntity, meshCfg);
77832
- mesh = new Mesh(modelNode, meshCfg);
77833
- parent.addChild(mesh, false); // Don't automatically inherit properties
77834
- return;
77835
- }
77836
-
77837
- if (createEntity && numMeshes > 0 && !hasChildNodes) {
77838
-
77839
- // Case 3: Creating object, node has meshes, node has no child nodes
77840
-
77841
- let nodeCfg = {
77842
- matrix: matrix
77843
- };
77844
- utils.apply(ctx.modelNodeProps, nodeCfg);
77845
- utils.apply(createEntity, nodeCfg);
77846
- let childNode = new Node$1(modelNode, nodeCfg);
77847
- parent.addChild(childNode, false);
77848
- for (let i = 0, len = numMeshes; i < len; i++) {
77849
- meshesInfoMesh = meshesInfo[i];
77850
- let meshCfg = {
77851
- geometry: meshesInfoMesh.geometry
77852
- };
77853
- utils.apply(ctx.modelNodeProps, meshCfg);
77854
- meshCfg.material = meshesInfoMesh.material;
77855
- utils.apply(createEntity, meshCfg);
77856
- meshCfg.id = null; // Avoid ID clash with parent Node
77857
- mesh = new Mesh(modelNode, meshCfg);
77858
- childNode.addChild(mesh, false);
77859
- }
77860
- return;
77861
- }
77862
-
77863
- if (!createEntity && numMeshes > 0 && hasChildNodes) {
77864
-
77865
- // Case 4: Not creating object, node has meshes, node has child nodes
77866
-
77867
- let nodeCfg = {
77868
- matrix: matrix
77869
- };
77870
- utils.apply(ctx.modelNodeProps, nodeCfg);
77871
- let childNode = new Node$1(modelNode, nodeCfg);
77872
- parent.addChild(childNode, false);
77873
- for (let i = 0, len = numMeshes; i < len; i++) {
77874
- meshesInfoMesh = meshesInfo[i];
77875
- let meshCfg = {
77876
- geometry: meshesInfoMesh.geometry
77877
- };
77878
- utils.apply(nodeCfg, meshCfg);
77879
- meshCfg.id = null; // Avoid ID clash with parent Node
77880
- meshCfg.matrix = null; // Node has matrix
77881
- meshCfg.material = meshesInfoMesh.material;
77882
- mesh = new Mesh(modelNode, meshCfg);
77883
- childNode.addChild(mesh, false);
77884
- }
77885
- matrix = null;
77886
- parent = childNode;
77887
- }
77888
-
77889
- if (createEntity && numMeshes === 0 && hasChildNodes) {
77890
-
77891
- // Case 5: Creating explicit object, node has meshes OR node has child nodes
77892
-
77893
- let nodeCfg = {
77894
- matrix: matrix
77895
- };
77896
- utils.apply(ctx.modelNodeProps, nodeCfg);
77897
- utils.apply(createEntity, nodeCfg);
77898
- createEntity.matrix = matrix;
77899
- let childNode = new Node$1(modelNode, nodeCfg);
77900
- parent.addChild(childNode, false); // Don't automatically inherit properties
77901
- matrix = null;
77902
- parent = childNode;
77903
- }
77904
-
77905
- if (createEntity && numMeshes > 0 || hasChildNodes) {
77906
-
77907
- // Case 6: Creating explicit object, node has meshes OR node has child nodes
77908
-
77909
- let nodeCfg = {
77910
- matrix: matrix
77911
- };
77912
- utils.apply(ctx.modelNodeProps, nodeCfg);
77913
- if (createEntity) {
77914
- utils.apply(createEntity, nodeCfg);
77915
- }
77916
- let childNode = new Node$1(modelNode, nodeCfg);
77917
- parent.addChild(childNode, false); // Don't automatically inherit properties
77918
- for (let i = 0, len = numMeshes; i < len; i++) {
77919
- meshesInfoMesh = meshesInfo[i];
77920
- let meshCfg = {
77921
- geometry: meshesInfoMesh.geometry
77922
- };
77923
- utils.apply(ctx.modelProps, meshCfg);
77924
- meshCfg.material = meshesInfoMesh.material;
77925
- if (createEntity) {
77926
- utils.apply(createEntity, meshCfg);
77927
- }
77928
- meshCfg.id = null; // Avoid ID clash with parent Node
77929
- mesh = new Mesh(modelNode, meshCfg);
77930
- childNode.addChild(mesh, false); // Don't automatically inherit properties
77931
- }
77932
- matrix = null;
77933
- parent = childNode;
77934
- }
77935
- }
77936
- }
77937
-
77938
- if (glTFNode.children) {
77939
- var children = glTFNode.children;
77940
- var childNodeInfo;
77941
- var childNodeIdx;
77942
- for (let i = 0, len = children.length; i < len; i++) {
77943
- childNodeIdx = children[i];
77944
- childNodeInfo = json.nodes[childNodeIdx];
77945
- if (!childNodeInfo) {
77946
- error(ctx, "Node not found: " + i);
77947
- continue;
77948
- }
77949
- loadNode(ctx, childNodeInfo, matrix, parent);
77950
- }
77951
- }
77952
- }
77953
-
77954
- function error(ctx, msg) {
77955
- ctx.plugin.error(msg);
77956
- }
77957
- })();
77958
-
77959
77144
  function assert$5(condition, message) {
77960
77145
  if (!condition) {
77961
77146
  throw new Error(message || 'loader assertion failed.');
@@ -85271,7 +84456,7 @@ async function parse$1(arrayBuffer, options = {}, context) {
85271
84456
  /**
85272
84457
  * @private
85273
84458
  */
85274
- class GLTFPerformanceModelLoader {
84459
+ class GLTFVBOSceneModelLoader {
85275
84460
 
85276
84461
  constructor(cfg) {
85277
84462
  }
@@ -85772,9 +84957,14 @@ const IFCObjectDefaults = {
85772
84957
  /**
85773
84958
  * {@link Viewer} plugin that loads models from [glTF](https://www.khronos.org/gltf/).
85774
84959
  *
84960
+ * * Loads all glTF formats, including embedded and binary formats.
84961
+ * * Loads physically-based materials and textures.
85775
84962
  * * Creates an {@link Entity} representing each model it loads, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.
85776
84963
  * * Creates an {@link Entity} for each object within the model, which is indicated by each glTF ````node```` that has a ````name```` attribute. Those Entities will have {@link Entity#isObject} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.
85777
84964
  * * When loading, can set the World-space position, scale and rotation of each model within World space, along with initial properties for all the model's {@link Entity}s.
84965
+ * * Not recommended for large models. For best performance with large glTF datasets, we recommend first converting them
84966
+ * to ````.xkt```` format (eg. using [convert2xkt](https://github.com/xeokit/xeokit-convert)), then loading
84967
+ * the ````.xkt```` using {@link XKTLoaderPlugin}.
85778
84968
  *
85779
84969
  * ## Metadata
85780
84970
  *
@@ -85785,23 +84975,6 @@ const IFCObjectDefaults = {
85785
84975
  * metadata, we can also provide GLTFLoaderPlugin with a custom lookup table of initial values to set on the properties of each type of {@link Entity}. By default, GLTFLoaderPlugin
85786
84976
  * uses its own map of default colors and visibilities for IFC element types.
85787
84977
  *
85788
- * ## Quality Setting
85789
- *
85790
- * By default, GLTFLoaderPlugin will load a high-performance scene representation that's optimized for low memory usage and
85791
- * optimal rendering. The high-performance representation renders large numbers of objects efficiently, using geometry
85792
- * batching and instancing, with simple Lambertian shading that ignores any textures and realistic materials in the glTF.
85793
- *
85794
- * Specifying ````performance:false```` to {@link GLTFLoaderPlugin#load} will internally load a heavier scene
85795
- * representation comprised of {@link Node}, {@link Mesh}, {@link Geometry}, {@link Material} and {@link Texture} components,
85796
- * that will exactly preserve the materials specified in the glTF. Use this when you want to load a model for a realistic preview,
85797
- * maybe using PBR etc.
85798
- *
85799
- * We tend to use the default ````performance:true```` setting for CAD and BIM models, where structure is more important that
85800
- * surface appearance.
85801
- *
85802
- * Publically, GLTFLoaderPlugin creates the same {@link Entity}s for both levels of performance. Privately, however, it implements
85803
- * {@link Entity}s using two different sets of concrete subtypes, for its two different internally-managed scene representations.
85804
- *
85805
84978
  * ## Usage
85806
84979
  *
85807
84980
  * In the example below we'll load the Schependomlaan model from a [glTF file](http://xeokit.github.io/xeokit-sdk/examples/models/gltf/schependomlaan/), along
@@ -85815,8 +84988,6 @@ const IFCObjectDefaults = {
85815
84988
  *
85816
84989
  * Read more about this example in the user guide on [Viewing BIM Models Offline](https://www.notion.so/xeokit/Viewing-an-IFC-Model-with-xeokit-c373e48bc4094ff5b6e5c5700ff580ee).
85817
84990
  *
85818
- * We're leaving ````performance: true```` since our model has many objects and we're not interested in realistic rendering.
85819
- *
85820
84991
  * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#BIMOffline_glTF_OTCConferenceCenter)]
85821
84992
  *
85822
84993
  * ````javascript
@@ -85855,8 +85026,7 @@ const IFCObjectDefaults = {
85855
85026
  * id: "myModel",
85856
85027
  * src: "./models/gltf/OTCConferenceCenter/scene.gltf",
85857
85028
  * metaModelSrc: "./models/gltf/OTCConferenceCenter/metaModel.json", // Creates a MetaModel (see below)
85858
- * edges: true,
85859
- * performance: true // Load high-performance scene representation (default is false)
85029
+ * edges: true
85860
85030
  * });
85861
85031
  *
85862
85032
  * model.on("loaded", () => {
@@ -85958,16 +85128,8 @@ class GLTFLoaderPlugin extends Plugin {
85958
85128
  constructor(viewer, cfg = {}) {
85959
85129
 
85960
85130
  super("GLTFLoader", viewer, cfg);
85961
-
85962
- /**
85963
- * @private
85964
- */
85965
- this._sceneGraphLoader = new GLTFSceneGraphLoader(this, cfg);
85966
-
85967
- /**
85968
- * @private
85969
- */
85970
- this._performanceModelLoader = new GLTFPerformanceModelLoader(this, cfg);
85131
+
85132
+ this._sceneModelLoader = new GLTFVBOSceneModelLoader(this, cfg);
85971
85133
 
85972
85134
  this.dataSource = cfg.dataSource;
85973
85135
  this.objectDefaults = cfg.objectDefaults;
@@ -86040,8 +85202,7 @@ class GLTFLoaderPlugin extends Plugin {
86040
85202
  * @param {Boolean} [params.colorTextureEnabled=true] Indicates if base color texture rendering is enabled for the model. Overridden by ````pbrEnabled````. Only works when {@link Scene#colorTextureEnabled} is also ````true````.
86041
85203
  * @param {Boolean} [params.backfaces=false] When true, allows visible backfaces, wherever specified in the glTF. When false, ignores backfaces.
86042
85204
  * @param {Number} [params.edgeThreshold=10] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.
86043
- * @param {Boolean} [params.performance=true] Set ````false```` to load all the materials and textures provided by the glTF file, otherwise leave ````true```` to load the default high-performance representation optimized for low memory usage and efficient rendering.
86044
- * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}
85205
+ * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}
86045
85206
  */
86046
85207
  load(params = {}) {
86047
85208
 
@@ -86050,20 +85211,7 @@ class GLTFLoaderPlugin extends Plugin {
86050
85211
  delete params.id;
86051
85212
  }
86052
85213
 
86053
- const performance = params.performance !== false;
86054
-
86055
- const sceneModel = performance
86056
-
86057
- // VBOSceneModel provides performance-oriented scene representation
86058
- // converting glTF materials to simple flat-shading without textures
86059
-
86060
- ? new VBOSceneModel(this.viewer.scene, utils.apply(params, {
86061
- isModel: true
86062
- }))
86063
-
86064
- // Scene Node graph supports original glTF materials
86065
-
86066
- : new Node$1(this.viewer.scene, utils.apply(params, {
85214
+ const sceneModel = new VBOSceneModel(this.viewer.scene, utils.apply(params, {
86067
85215
  isModel: true
86068
85216
  }));
86069
85217
 
@@ -86074,8 +85222,6 @@ class GLTFLoaderPlugin extends Plugin {
86074
85222
  return sceneModel; // Return new empty model
86075
85223
  }
86076
85224
 
86077
- const loader = performance ? this._performanceModelLoader : this._sceneGraphLoader;
86078
-
86079
85225
  if (params.metaModelSrc || params.metaModelData) {
86080
85226
 
86081
85227
  const objectDefaults = params.objectDefaults || this._objectDefaults || IFCObjectDefaults;
@@ -86149,9 +85295,9 @@ class GLTFLoaderPlugin extends Plugin {
86149
85295
  };
86150
85296
 
86151
85297
  if (params.src) {
86152
- loader.load(this, sceneModel, params.src, params);
85298
+ this._sceneModelLoader.load(this, sceneModel, params.src, params);
86153
85299
  } else {
86154
- loader.parse(this, sceneModel, params.gltf, params);
85300
+ this._sceneModelLoader.parse(this, sceneModel, params.gltf, params);
86155
85301
  }
86156
85302
  };
86157
85303
 
@@ -86198,9 +85344,9 @@ class GLTFLoaderPlugin extends Plugin {
86198
85344
  };
86199
85345
 
86200
85346
  if (params.src) {
86201
- loader.load(this, sceneModel, params.src, params);
85347
+ this._sceneModelLoader.load(this, sceneModel, params.src, params);
86202
85348
  } else {
86203
- loader.parse(this, sceneModel, params.gltf, params);
85349
+ this._sceneModelLoader.parse(this, sceneModel, params.gltf, params);
86204
85350
  }
86205
85351
  }
86206
85352
 
@@ -89779,6 +88925,7 @@ const tempVec3$3 = math.vec3();
89779
88925
  * this example).
89780
88926
  * * Click a plane in the overview to activate a 3D control with which you can interactively
89781
88927
  * reposition its SectionPlane in the main canvas.
88928
+ * * Use {@lin BCFViewpointsPlugin} to save and load SectionPlanes in BCF viewpoints.
89782
88929
  *
89783
88930
  * ## Usage
89784
88931
  *
@@ -89844,7 +88991,7 @@ const tempVec3$3 = math.vec3();
89844
88991
  * // Programmatically reposition one of our SectionPlanes
89845
88992
  * // This also updates its position as shown in the overview gizmo
89846
88993
  *
89847
- * mySectionPlane2.pos = [11.0, 6.-, -12];
88994
+ * mySectionPlane2.pos = [11.0, 6.0, -12];
89848
88995
  * mySectionPlane2.dir = [0.4, 0.0, 0.5];
89849
88996
  * ````
89850
88997
  */
@@ -156014,6 +155161,36 @@ class PerformanceModel extends VBOSceneModel {
156014
155161
  }
156015
155162
  }
156016
155163
 
155164
+ /**
155165
+ * Transcodes texture data.
155166
+ *
155167
+ * A {@link SceneModel} configured with an appropriate TextureTranscoder will allow us to add textures from
155168
+ * transcoded buffers or files. For a concrete example, see {@link VBOSceneModel}, which can be configured with
155169
+ * a {@link KTX2TextureTranscoder}, which allows us to add textures from KTX2 buffers and files.
155170
+ *
155171
+ * @interface
155172
+ */
155173
+ class TextureTranscoder {
155174
+
155175
+ /**
155176
+ * Transcodes texture data from transcoded buffers into a {@link Texture2D}.
155177
+ *
155178
+ * @param {ArrayBuffer[]} buffers Transcoded texture data. Given as an array of buffers so that we can support
155179
+ * multi-image textures, such as cube maps.
155180
+ * @param {*} config Transcoding options.
155181
+ * @param {Texture2D} texture The texture to load.
155182
+ * @returns {Promise} Resolves when the texture has loaded.
155183
+ */
155184
+ transcode(buffers, texture, config = {}) {
155185
+ }
155186
+
155187
+ /**
155188
+ * Destroys this transcoder.
155189
+ */
155190
+ destroy() {
155191
+ }
155192
+ }
155193
+
156017
155194
  const screenPos = math.vec4();
156018
155195
  const viewPos = math.vec4();
156019
155196
 
@@ -156258,7 +155435,7 @@ class PivotController {
156258
155435
  /**
156259
155436
  * Returns true if we are currently pivoting.
156260
155437
  *
156261
- * @returns {boolean}
155438
+ * @returns {Boolean}
156262
155439
  */
156263
155440
  getPivoting() {
156264
155441
  return this._pivoting;
@@ -161380,7 +160557,7 @@ class Configs {
161380
160557
  *
161381
160558
  * This should only be set once, before creating any Viewers.
161382
160559
  *
161383
- * @returns {boolean}
160560
+ * @returns {Boolean}
161384
160561
  */
161385
160562
  set doublePrecisionEnabled(doublePrecision) {
161386
160563
  math.setDoublePrecisionEnabled(doublePrecision);
@@ -161389,7 +160566,7 @@ class Configs {
161389
160566
  /**
161390
160567
  * Gets whether double precision mode is enabled for all Viewers.
161391
160568
  *
161392
- * @returns {boolean}
160569
+ * @returns {Boolean}
161393
160570
  */
161394
160571
  get doublePrecisionEnabled() {
161395
160572
  return math.getDoublePrecisionEnabled();
@@ -163613,9 +162790,11 @@ const tempVec3c = math.vec3();
163613
162790
  * ## Overview
163614
162791
  *
163615
162792
  * * Loads small-to-medium sized models directly from [CityJSON 1.0.0](https://www.cityjson.org/specs/1.0.0/) files.
163616
- * * Not recommended for large models. For best performance with large CityJSON datasets, we recommend using {@link XKTLoaderPlugin}.
163617
162793
  * * Loads double-precision coordinates, enabling models to be viewed at global coordinates without accuracy loss.
163618
162794
  * * Allows to set the position, scale and rotation of each model as you load it.
162795
+ * * Not recommended for large models. For best performance with large CityJSON datasets, we recommend
162796
+ * converting them to ````.xkt```` format (eg. using [convert2xkt](https://github.com/xeokit/xeokit-convert)), then loading
162797
+ * the ````.xkt```` using {@link XKTLoaderPlugin}.
163619
162798
  *
163620
162799
  * ## Limitations
163621
162800
  *