@xeokit/xeokit-sdk 2.6.41 → 2.6.43

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeokit/xeokit-sdk",
3
- "version": "2.6.41",
3
+ "version": "2.6.43",
4
4
  "description": "Web Programming Toolkit for 3D/2D BIM and AEC Graphics",
5
5
  "module": "./dist/xeokit-sdk.es.js",
6
6
  "main": "./dist/xeokit-sdk.cjs.js",
@@ -636,9 +636,8 @@ class ContextMenu {
636
636
  if (itemSubMenu) {
637
637
 
638
638
  html.push(
639
- '<li id="' + item.id + '" class="xeokit-context-menu-item">' +
639
+ '<li id="' + item.id + '" class="xeokit-context-menu-item xeokit-context-menu-submenu">' +
640
640
  actionTitle +
641
- ' [MORE]' +
642
641
  '</li>');
643
642
  if (!((groupIdx === groupLen - 1) || (j < lenj - 1))) {
644
643
  html.push(
@@ -240,6 +240,7 @@ class DistanceMeasurement extends Component {
240
240
  this._visible = false;
241
241
  this._originVisible = false;
242
242
  this._targetVisible = false;
243
+ this._useRotationAdjustment = false;
243
244
  this._wireVisible = false;
244
245
  this._axisVisible = false;
245
246
  this._xAxisVisible = false;
@@ -316,7 +317,7 @@ class DistanceMeasurement extends Component {
316
317
  this.lengthLabelEnabled = cfg.lengthLabelEnabled;
317
318
  this.labelsVisible = cfg.labelsVisible;
318
319
  this.labelsOnWires = cfg.labelsOnWires;
319
- this.useRotationAdjustment = cfg.useRotationAdjustment;
320
+ this._useRotationAdjustment = cfg.useRotationAdjustment;
320
321
 
321
322
  /**
322
323
  * @type {number[]}
@@ -378,7 +379,7 @@ class DistanceMeasurement extends Component {
378
379
  this._factors = math.transformVec3(this._axesBasis, delta);
379
380
 
380
381
  this._measurementOrientation = determineMeasurementOrientation(this._originWorld, this._targetWorld, 0);
381
- if(this._measurementOrientation === 'Vertical' && this.useRotationAdjustment){
382
+ if (this._measurementOrientation === 'Vertical' && this._useRotationAdjustment) {
382
383
  this._wp[0] = this._originWorld[0];
383
384
  this._wp[1] = this._originWorld[1];
384
385
  this._wp[2] = this._originWorld[2];
@@ -589,7 +590,7 @@ class DistanceMeasurement extends Component {
589
590
  }
590
591
 
591
592
  if (!this._zAxisLabelCulled) {
592
- if(this._measurementOrientation === 'Vertical' && this.useRotationAdjustment) {
593
+ if (this._measurementOrientation === 'Vertical' && this._useRotationAdjustment) {
593
594
  this._zAxisLabel.setPrefix("");
594
595
  this._zAxisLabel.setText(tilde + Math.abs(math.lenVec3(math.subVec3(this._targetWorld, [this._originWorld[0], this._targetWorld[1], this._originWorld[2]], distVec3)) * scale).toFixed(2) + unitAbbrev);
595
596
  }
@@ -784,6 +785,25 @@ class DistanceMeasurement extends Component {
784
785
  return this._targetVisible;
785
786
  }
786
787
 
788
+ /**
789
+ * Sets if the measurement is adjusted based on rotation
790
+ *
791
+ * @type {Boolean}
792
+ */
793
+ set useRotationAdjustment(value) {
794
+ value = value !== undefined ? Boolean(value) : this.plugin.useRotationAdjustment;
795
+ this._useRotationAdjustment = value;
796
+ }
797
+
798
+ /**
799
+ * Gets if the measurement is adjusted based on rotation
800
+ *
801
+ * @type {Boolean}
802
+ */
803
+ get useRotationAdjustment() {
804
+ return this._useRotationAdjustment;
805
+ }
806
+
787
807
  /**
788
808
  * Sets if the axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} are enabled.
789
809
  *
@@ -9,12 +9,6 @@ import {core} from "../../viewer/scene/core.js";
9
9
  class GLTFDefaultDataSource {
10
10
 
11
11
  constructor(cfg = {}) {
12
-
13
- /**
14
- * Set `true` to enable cache busting for HTTP GETs.
15
- * This is `true` by default.
16
- * @type {boolean}
17
- */
18
12
  this.cacheBuster = (cfg.cacheBuster !== false);
19
13
  }
20
14
 
@@ -339,6 +339,7 @@ class LASLoaderPlugin extends Plugin {
339
339
  }
340
340
 
341
341
  const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {
342
+ maxGeometryBatchSize: MAX_VERTICES,
342
343
  isModel: true
343
344
  }));
344
345
 
@@ -702,7 +702,13 @@ class StoreyViewsPlugin extends Plugin {
702
702
  return null;
703
703
  }
704
704
 
705
- isPositionAboveOrBelowBuilding(worldPos){
705
+ /**
706
+ * Returns whether a position is above or below a building
707
+ *
708
+ * @param {Number[]} worldPos 3D World-space position.
709
+ * @returns {String} ID of the lowest/highest story or null.
710
+ */
711
+ isPositionAboveOrBelowBuilding(worldPos) {
706
712
  const keys = Object.keys(this.storeys);
707
713
  const ids = [keys[0], keys[keys.length-1]];
708
714
  if(worldPos[1] < this.storeys[ids[0]].storeyAABB[1])
@@ -7,7 +7,7 @@ import {PhongMaterial} from "../../viewer/scene/materials/PhongMaterial.js";
7
7
  import {math} from "../../viewer/scene/math/math.js";
8
8
  import {Mesh} from "../../viewer/scene/mesh/Mesh.js";
9
9
  import {Dot} from "../lib/html/Dot.js";
10
- import {activateDraggableDots, Dot3D, transformToNode} from "../../../src/plugins/lib/ui/index.js";
10
+ import {activateDraggableDots, Dot3D, touchPointSelector, transformToNode} from "../../../src/plugins/lib/ui/index.js";
11
11
 
12
12
  const hex2rgb = function(color) {
13
13
  const rgb = idx => parseInt(color.substr(idx + 1, 2), 16) / 255;
@@ -822,14 +822,14 @@ export class DTXTrianglesLayer {
822
822
  // object colors
823
823
  textureState.texturePerObjectColorsAndFlags._textureData.set(tempUint8Array4, subPortionId * 32);
824
824
  if (this._deferredSetFlagsActive) {
825
- console.info("_subPortionSetColor defer");
825
+ //console.info("_subPortionSetColor defer");
826
826
  this._deferredSetFlagsDirty = true;
827
827
  return;
828
828
  }
829
829
  if (++this._numUpdatesInFrame >= MAX_OBJECT_UPDATES_IN_FRAME_WITHOUT_BATCHED_UPDATE) {
830
830
  this._beginDeferredFlags(); // Subsequent flags updates now deferred
831
831
  }
832
- console.info("_subPortionSetColor write through");
832
+ //console.info("_subPortionSetColor write through");
833
833
  gl.bindTexture(gl.TEXTURE_2D, textureState.texturePerObjectColorsAndFlags._texture);
834
834
  gl.texSubImage2D(
835
835
  gl.TEXTURE_2D,
@@ -5,7 +5,6 @@ import {math} from "../../../../math/math.js";
5
5
  import {RenderState} from "../../../../webgl/RenderState.js";
6
6
  import {ArrayBuf} from "../../../../webgl/ArrayBuf.js";
7
7
  import {getRenderers} from "./renderers/VBOBatchingPointsRenderers.js";
8
- import {VBOBatchingPointsBuffer} from "./VBOBatchingPointsBuffer.js";
9
8
  import {quantizePositions} from "../../../compression.js";
10
9
 
11
10
  /**
@@ -46,7 +45,58 @@ export class VBOBatchingPointsLayer {
46
45
 
47
46
  this._renderers = getRenderers(cfg.model.scene);
48
47
 
49
- this._buffer = new VBOBatchingPointsBuffer(cfg.maxGeometryBatchSize);
48
+ const maxGeometryBatchSize = cfg.maxGeometryBatchSize || 5000000;
49
+
50
+ const attribute = function() {
51
+ const portions = [ ];
52
+
53
+ return {
54
+ append: function(data, times = 1, denormalizeScale = 1.0) {
55
+ portions.push({ data: data, times: times, denormalizeScale: denormalizeScale });
56
+ },
57
+ compileBuffer: function(type) {
58
+ let len = 0;
59
+ portions.forEach(p => { len += p.times * p.data.length; });
60
+ const buf = new type(len);
61
+
62
+ let begin = 0;
63
+ portions.forEach(p => {
64
+ const data = p.data;
65
+ const dScale = p.denormalizeScale;
66
+ const subBuf = buf.subarray(begin);
67
+
68
+ if (dScale === 1.0) {
69
+ subBuf.set(data, 0);
70
+ } else {
71
+ for (let i = 0; i < data.length; ++i) {
72
+ subBuf[i] = data[i] * dScale;
73
+ }
74
+ }
75
+
76
+ let soFar = data.length;
77
+ const allDataLen = p.times * data.length;
78
+ while (soFar < allDataLen) {
79
+ const toCopy = Math.min(soFar, allDataLen - soFar);
80
+ subBuf.set(subBuf.subarray(0, toCopy), soFar);
81
+ soFar += toCopy;
82
+ }
83
+
84
+ begin += soFar;
85
+ });
86
+
87
+ return buf;
88
+ }
89
+ };
90
+ };
91
+
92
+ this._buffer = {
93
+ maxVerts: maxGeometryBatchSize,
94
+ positions: attribute(),
95
+ colors: attribute(),
96
+ pickColors: attribute(),
97
+ vertsIndex: 0
98
+ };
99
+
50
100
  this._scratchMemory = cfg.scratchMemory;
51
101
 
52
102
  this._state = new RenderState({
@@ -99,11 +149,6 @@ export class VBOBatchingPointsLayer {
99
149
  this.aabbDirty = false;
100
150
  }
101
151
  return this._aabb;
102
-
103
- /**
104
- * The type of primitives in this layer.
105
- */
106
- this.primitive = cfg.primitive;
107
152
  }
108
153
 
109
154
  /**
@@ -116,7 +161,7 @@ export class VBOBatchingPointsLayer {
116
161
  if (this._finalized) {
117
162
  throw "Already finalized";
118
163
  }
119
- return ((this._buffer.positions.length + lenPositions) < (this._buffer.maxVerts * 3));
164
+ return (this._buffer.vertsIndex + (lenPositions / 3)) <= this._buffer.maxVerts;
120
165
  }
121
166
 
122
167
  /**
@@ -141,97 +186,40 @@ export class VBOBatchingPointsLayer {
141
186
  throw "Already finalized";
142
187
  }
143
188
 
144
- const positions = cfg.positions;
145
- const positionsCompressed = cfg.positionsCompressed;
146
- const color = cfg.color;
147
- const colorsCompressed = cfg.colorsCompressed;
148
- const colors = cfg.colors;
149
- const pickColor = cfg.pickColor;
150
-
151
189
  const buffer = this._buffer;
152
- const positionsIndex = buffer.positions.length;
153
- const vertsIndex = positionsIndex / 3;
154
-
155
- let numVerts;
156
-
157
- math.expandAABB3(this._modelAABB, cfg.aabb);
158
190
 
159
- if (this._preCompressedPositionsExpected) {
160
-
161
- if (!positionsCompressed) {
162
- throw "positionsCompressed expected";
163
- }
164
-
165
- for (let i = 0, len = positionsCompressed.length; i < len; i++) {
166
- buffer.positions.push(positionsCompressed[i]);
167
- }
168
-
169
- numVerts = positionsCompressed.length / 3;
170
-
171
- } else {
172
-
173
- if (!positions) {
174
- throw "positions expected";
175
- }
191
+ const positions = this._preCompressedPositionsExpected ? cfg.positionsCompressed : cfg.positions;
192
+ if (! positions) {
193
+ throw ((this._preCompressedPositionsExpected ? "positionsCompressed" : "positions") + " expected");
194
+ }
176
195
 
177
- numVerts = positions.length / 3;
196
+ buffer.positions.append(positions);
178
197
 
179
- const lenPositions = positions.length;
180
- const positionsBase = buffer.positions.length;
198
+ const numVerts = positions.length / 3;
181
199
 
182
- for (let i = 0, len = positions.length; i < len; i++) {
183
- buffer.positions.push(positions[i]);
184
- }
185
- }
200
+ const color = cfg.color;
201
+ const colorsCompressed = cfg.colorsCompressed;
202
+ const colors = cfg.colors;
203
+ const pickColor = cfg.pickColor;
186
204
 
187
205
  if (colorsCompressed) {
188
- for (let i = 0, len = colorsCompressed.length; i < len; i++) {
189
- buffer.colors.push(colorsCompressed[i]);
190
- }
191
-
206
+ buffer.colors.append(colorsCompressed);
192
207
  } else if (colors) {
193
- for (let i = 0, len = colors.length; i < len; i++) {
194
- buffer.colors.push(colors[i] * 255);
195
- }
196
-
208
+ buffer.colors.append(colors, 1, 255.0);
197
209
  } else if (color) {
198
-
199
- const r = color[0]; // Color is pre-quantized by VBOSceneModel
200
- const g = color[1];
201
- const b = color[2];
202
- const a = 1.0;
203
-
204
- for (let i = 0; i < numVerts; i++) {
205
- buffer.colors.push(r);
206
- buffer.colors.push(g);
207
- buffer.colors.push(b);
208
- buffer.colors.push(a);
209
- }
210
+ // Color is pre-quantized by VBOSceneModel
211
+ buffer.colors.append([ color[0], color[1], color[2], 1.0 ], numVerts);
210
212
  }
211
213
 
212
- {
213
- const pickColorsBase = buffer.pickColors.length;
214
- const lenPickColors = numVerts * 4;
215
- for (let i = pickColorsBase, len = pickColorsBase + lenPickColors; i < len; i += 4) {
216
- buffer.pickColors.push(pickColor[0]);
217
- buffer.pickColors.push(pickColor[1]);
218
- buffer.pickColors.push(pickColor[2]);
219
- buffer.pickColors.push(pickColor[3]);
220
- }
221
- }
214
+ buffer.pickColors.append(pickColor.slice(0, 4), numVerts);
222
215
 
223
- if (this.model.scene.entityOffsetsEnabled) {
224
- for (let i = 0; i < numVerts; i++) {
225
- buffer.offsets.push(0);
226
- buffer.offsets.push(0);
227
- buffer.offsets.push(0);
228
- }
229
- }
216
+ math.expandAABB3(this._modelAABB, cfg.aabb);
230
217
 
231
218
  const portionId = this._portions.length / 2;
232
219
 
233
- this._portions.push(vertsIndex);
220
+ this._portions.push(this._buffer.vertsIndex);
234
221
  this._portions.push(numVerts);
222
+ this._buffer.vertsIndex += numVerts;
235
223
 
236
224
  this._numPortions++;
237
225
  this.model.numPortions++;
@@ -252,43 +240,20 @@ export class VBOBatchingPointsLayer {
252
240
  const state = this._state;
253
241
  const gl = this.model.scene.canvas.gl;
254
242
  const buffer = this._buffer;
243
+ const maybeCreateGlBuffer = (srcData, size, usage) => (srcData.length > 0) ? new ArrayBuf(gl, gl.ARRAY_BUFFER, srcData, srcData.length, size, usage) : null;
255
244
 
256
- if (buffer.positions.length > 0) {
257
- if (this._preCompressedPositionsExpected) {
258
- const positions = new Uint16Array(buffer.positions);
259
- state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, positions, buffer.positions.length, 3, gl.STATIC_DRAW);
260
- } else {
261
- const positions = new Float32Array(buffer.positions);
262
- const quantizedPositions = quantizePositions(positions, this._modelAABB, state.positionsDecodeMatrix);
263
- state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, quantizedPositions, buffer.positions.length, 3, gl.STATIC_DRAW);
264
- }
265
- }
245
+ const positions = (this._preCompressedPositionsExpected
246
+ ? buffer.positions.compileBuffer(Uint16Array)
247
+ : (quantizePositions(buffer.positions.compileBuffer(Float32Array), this._modelAABB, state.positionsDecodeMatrix)));
248
+ state.positionsBuf = maybeCreateGlBuffer(positions, 3, gl.STATIC_DRAW);
266
249
 
267
- if (buffer.colors.length > 0) {
268
- const colors = new Uint8Array(buffer.colors);
269
- let normalized = false;
270
- state.colorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, colors, buffer.colors.length, 4, gl.STATIC_DRAW, normalized);
271
- }
250
+ state.flagsBuf = maybeCreateGlBuffer(new Float32Array(this._buffer.vertsIndex), 1, gl.DYNAMIC_DRAW); // Because we build flags arrays here, get their length from the positions array
272
251
 
273
- if (buffer.positions.length > 0) { // Because we build flags arrays here, get their length from the positions array
274
- const flagsLength = buffer.positions.length / 3;
275
- const flags = new Float32Array(flagsLength);
276
- let notNormalized = false;
277
- state.flagsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, flags, flags.length, 1, gl.DYNAMIC_DRAW, notNormalized);
278
- }
252
+ state.colorsBuf = maybeCreateGlBuffer(buffer.colors.compileBuffer(Uint8Array), 4, gl.STATIC_DRAW);
279
253
 
280
- if (buffer.pickColors.length > 0) {
281
- const pickColors = new Uint8Array(buffer.pickColors);
282
- let normalized = false;
283
- state.pickColorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, pickColors, buffer.pickColors.length, 4, gl.STATIC_DRAW, normalized);
284
- }
254
+ state.pickColorsBuf = maybeCreateGlBuffer(buffer.pickColors.compileBuffer(Uint8Array), 4, gl.STATIC_DRAW);
285
255
 
286
- if (this.model.scene.entityOffsetsEnabled) {
287
- if (buffer.offsets.length > 0) {
288
- const offsets = new Float32Array(buffer.offsets);
289
- state.offsetsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, offsets, buffer.offsets.length, 3, gl.DYNAMIC_DRAW);
290
- }
291
- }
256
+ state.offsetsBuf = this.model.scene.entityOffsetsEnabled ? maybeCreateGlBuffer(new Float32Array(this._buffer.vertsIndex * 3), 3, gl.DYNAMIC_DRAW) : null;
292
257
 
293
258
  this._buffer = null;
294
259
  this._finalized = true;
@@ -103,6 +103,20 @@ export declare class DistanceMeasurement extends Component {
103
103
  */
104
104
  get targetVisible(): boolean;
105
105
 
106
+ /**
107
+ * Sets if the measurement is adjusted based on rotation
108
+ *
109
+ * @type {Boolean}
110
+ */
111
+ set useRotationAdjustment(arg: boolean);
112
+
113
+ /**
114
+ * Gets if the measurement is adjusted based on rotation
115
+ *
116
+ * @type {Boolean}
117
+ */
118
+ get useRotationAdjustment(): boolean;
119
+
106
120
  /**
107
121
  * Sets if the direct point-to-point wire between {@link DistanceMeasurement.origin} and {@link DistanceMeasurement.target} is visible.
108
122
  *
@@ -128,11 +128,11 @@ export declare class StoreyViewsPlugin extends Plugin {
128
128
 
129
129
 
130
130
  /**
131
- * Gets the ID of the storey that contains the given 3D World-space position.
132
- *.
133
- * @param {Number[]} worldPos 3D World-space position.
134
- * @returns {String} ID of the storey containing the position, or null if the position falls outside all the storeys.
135
- */
131
+ * Returns whether a position is above or below a building
132
+ *
133
+ * @param {Number[]} worldPos 3D World-space position.
134
+ * @returns {String} ID of the lowest/highest story or null.
135
+ */
136
136
  isPositionAboveOrBelowBuilding(worldPos: number[]): string;
137
137
 
138
138
  /**
@@ -1,20 +0,0 @@
1
- /**
2
- * @private
3
- */
4
- export class VBOBatchingPointsBuffer {
5
-
6
- constructor(maxGeometryBatchSize = 5000000) {
7
-
8
- if (maxGeometryBatchSize > 5000000) {
9
- maxGeometryBatchSize = 5000000;
10
- }
11
-
12
- this.maxVerts = maxGeometryBatchSize;
13
- this.maxIndices = maxGeometryBatchSize * 3; // Rough rule-of-thumb
14
- this.positions = [];
15
- this.colors = [];
16
- this.intensities = [];
17
- this.pickColors = [];
18
- this.offsets = [];
19
- }
20
- }