@xeokit/xeokit-sdk 2.6.40 → 2.6.42
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/dist/web-ifc.wasm +0 -0
- package/dist/xeokit-sdk.cjs.js +251 -254
- package/dist/xeokit-sdk.es.js +247 -255
- package/dist/xeokit-sdk.es5.js +260 -248
- package/dist/xeokit-sdk.min.cjs.js +5 -5
- package/dist/xeokit-sdk.min.es.js +4 -4
- package/dist/xeokit-sdk.min.es5.js +3 -3
- package/package.json +1 -1
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.js +23 -3
- package/src/plugins/GLTFLoaderPlugin/GLTFDefaultDataSource.js +0 -6
- package/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js +7 -1
- package/src/plugins/TreeViewPlugin/TreeViewPlugin.js +2 -0
- package/src/plugins/ZonesPlugin/ZonesPlugin.js +0 -116
- package/src/plugins/index.js +1 -0
- package/src/plugins/lib/ui/index.js +116 -0
- package/src/viewer/scene/model/SceneModel.js +15 -1
- package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +80 -115
- package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.d.ts +14 -0
- package/types/plugins/StoreyViewsPlugin/StoreyViewsPlugin.d.ts +5 -5
- package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsBuffer.js +0 -20
package/package.json
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
|
|
@@ -702,7 +702,13 @@ class StoreyViewsPlugin extends Plugin {
|
|
|
702
702
|
return null;
|
|
703
703
|
}
|
|
704
704
|
|
|
705
|
-
|
|
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])
|
|
@@ -701,6 +701,8 @@ export class TreeViewPlugin extends Plugin {
|
|
|
701
701
|
return; // Node may not exist for the given object if (this._pruneEmptyNodes == true)
|
|
702
702
|
}
|
|
703
703
|
|
|
704
|
+
this.collapse();
|
|
705
|
+
|
|
704
706
|
const nodeId = node.nodeId;
|
|
705
707
|
|
|
706
708
|
const switchElement = this._renderService.getSwitchElement(nodeId);
|
|
@@ -408,122 +408,6 @@ const mousePointSelector = function(viewer, ray2WorldPos) {
|
|
|
408
408
|
};
|
|
409
409
|
};
|
|
410
410
|
|
|
411
|
-
const touchPointSelector = function(viewer, pointerCircle, ray2WorldPos) {
|
|
412
|
-
return function(onCancel, onChange, onCommit) {
|
|
413
|
-
const scene = viewer.scene;
|
|
414
|
-
const canvas = scene.canvas.canvas;
|
|
415
|
-
const longTouchTimeoutMs = 300;
|
|
416
|
-
const moveTolerance = 20;
|
|
417
|
-
|
|
418
|
-
const copyCanvasPos = (event, vec2) => {
|
|
419
|
-
vec2[0] = event.clientX;
|
|
420
|
-
vec2[1] = event.clientY;
|
|
421
|
-
transformToNode(canvas.ownerDocument.documentElement, canvas, vec2);
|
|
422
|
-
return vec2;
|
|
423
|
-
};
|
|
424
|
-
|
|
425
|
-
const pickWorldPos = canvasPos => {
|
|
426
|
-
const origin = math.vec3();
|
|
427
|
-
const direction = math.vec3();
|
|
428
|
-
math.canvasPosToWorldRay(canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, canvasPos, origin, direction);
|
|
429
|
-
return ray2WorldPos(origin, direction);
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
let longTouchTimeout = null;
|
|
433
|
-
const nop = () => { };
|
|
434
|
-
let onSingleTouchMove = nop;
|
|
435
|
-
let startTouchIdentifier;
|
|
436
|
-
|
|
437
|
-
const resetAction = function() {
|
|
438
|
-
pointerCircle.stop();
|
|
439
|
-
clearTimeout(longTouchTimeout);
|
|
440
|
-
viewer.cameraControl.active = true;
|
|
441
|
-
onSingleTouchMove = nop;
|
|
442
|
-
startTouchIdentifier = null;
|
|
443
|
-
};
|
|
444
|
-
|
|
445
|
-
const cleanup = function() {
|
|
446
|
-
resetAction();
|
|
447
|
-
canvas.removeEventListener("touchstart", onCanvasTouchStart);
|
|
448
|
-
canvas.removeEventListener("touchmove", onCanvasTouchMove);
|
|
449
|
-
canvas.removeEventListener("touchend", onCanvasTouchEnd);
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
const onCanvasTouchStart = function(event) {
|
|
453
|
-
const touches = event.touches;
|
|
454
|
-
|
|
455
|
-
if (touches.length !== 1)
|
|
456
|
-
{
|
|
457
|
-
resetAction();
|
|
458
|
-
onCancel();
|
|
459
|
-
}
|
|
460
|
-
else
|
|
461
|
-
{
|
|
462
|
-
const startTouch = touches[0];
|
|
463
|
-
const startCanvasPos = copyCanvasPos(startTouch, math.vec2());
|
|
464
|
-
|
|
465
|
-
const startWorldPos = pickWorldPos(startCanvasPos);
|
|
466
|
-
if (startWorldPos)
|
|
467
|
-
{
|
|
468
|
-
startTouchIdentifier = startTouch.identifier;
|
|
469
|
-
|
|
470
|
-
onSingleTouchMove = canvasPos => {
|
|
471
|
-
if (math.distVec2(startCanvasPos, canvasPos) > moveTolerance)
|
|
472
|
-
{
|
|
473
|
-
resetAction();
|
|
474
|
-
}
|
|
475
|
-
};
|
|
476
|
-
|
|
477
|
-
longTouchTimeout = setTimeout(
|
|
478
|
-
function() {
|
|
479
|
-
pointerCircle.start(startCanvasPos);
|
|
480
|
-
|
|
481
|
-
longTouchTimeout = setTimeout(
|
|
482
|
-
function() {
|
|
483
|
-
pointerCircle.stop();
|
|
484
|
-
|
|
485
|
-
viewer.cameraControl.active = false;
|
|
486
|
-
|
|
487
|
-
onSingleTouchMove = canvasPos => {
|
|
488
|
-
onChange(canvasPos, pickWorldPos(canvasPos));
|
|
489
|
-
};
|
|
490
|
-
|
|
491
|
-
onSingleTouchMove(startCanvasPos);
|
|
492
|
-
},
|
|
493
|
-
longTouchTimeoutMs);
|
|
494
|
-
},
|
|
495
|
-
250);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
};
|
|
499
|
-
canvas.addEventListener("touchstart", onCanvasTouchStart, {passive: true});
|
|
500
|
-
|
|
501
|
-
// canvas.addEventListener("touchcancel", e => console.log("touchcancel", e), {passive: true});
|
|
502
|
-
|
|
503
|
-
const onCanvasTouchMove = function(event) {
|
|
504
|
-
const touch = [...event.changedTouches].find(e => e.identifier === startTouchIdentifier);
|
|
505
|
-
if (touch)
|
|
506
|
-
{
|
|
507
|
-
onSingleTouchMove(copyCanvasPos(touch, math.vec2()));
|
|
508
|
-
}
|
|
509
|
-
};
|
|
510
|
-
canvas.addEventListener("touchmove", onCanvasTouchMove, {passive: true});
|
|
511
|
-
|
|
512
|
-
const onCanvasTouchEnd = function(event) {
|
|
513
|
-
const touch = [...event.changedTouches].find(e => e.identifier === startTouchIdentifier);
|
|
514
|
-
if (touch)
|
|
515
|
-
{
|
|
516
|
-
cleanup();
|
|
517
|
-
const canvasPos = copyCanvasPos(touch, math.vec2());
|
|
518
|
-
onCommit(canvasPos, pickWorldPos(canvasPos));
|
|
519
|
-
}
|
|
520
|
-
};
|
|
521
|
-
canvas.addEventListener("touchend", onCanvasTouchEnd, {passive: true});
|
|
522
|
-
|
|
523
|
-
return cleanup;
|
|
524
|
-
};
|
|
525
|
-
};
|
|
526
|
-
|
|
527
411
|
const planeIntersect = function(p0, n, origin, direction) {
|
|
528
412
|
const t = - (math.dotVec3(origin, n) - p0) / math.dotVec3(direction, n);
|
|
529
413
|
if (false) // (t < 0)
|
package/src/plugins/index.js
CHANGED
|
@@ -284,3 +284,119 @@ export function activateDraggableDots(cfg) {
|
|
|
284
284
|
updatePointerLens(null);
|
|
285
285
|
};
|
|
286
286
|
}
|
|
287
|
+
|
|
288
|
+
export const touchPointSelector = function(viewer, pointerCircle, ray2WorldPos) {
|
|
289
|
+
return function(onCancel, onChange, onCommit) {
|
|
290
|
+
const scene = viewer.scene;
|
|
291
|
+
const canvas = scene.canvas.canvas;
|
|
292
|
+
const longTouchTimeoutMs = 300;
|
|
293
|
+
const moveTolerance = 20;
|
|
294
|
+
|
|
295
|
+
const copyCanvasPos = (event, vec2) => {
|
|
296
|
+
vec2[0] = event.clientX;
|
|
297
|
+
vec2[1] = event.clientY;
|
|
298
|
+
transformToNode(canvas.ownerDocument.documentElement, canvas, vec2);
|
|
299
|
+
return vec2;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const pickWorldPos = canvasPos => {
|
|
303
|
+
const origin = math.vec3();
|
|
304
|
+
const direction = math.vec3();
|
|
305
|
+
math.canvasPosToWorldRay(canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, canvasPos, origin, direction);
|
|
306
|
+
return ray2WorldPos(origin, direction);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
let longTouchTimeout = null;
|
|
310
|
+
const nop = () => { };
|
|
311
|
+
let onSingleTouchMove = nop;
|
|
312
|
+
let startTouchIdentifier;
|
|
313
|
+
|
|
314
|
+
const resetAction = function() {
|
|
315
|
+
pointerCircle.stop();
|
|
316
|
+
clearTimeout(longTouchTimeout);
|
|
317
|
+
viewer.cameraControl.active = true;
|
|
318
|
+
onSingleTouchMove = nop;
|
|
319
|
+
startTouchIdentifier = null;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
const cleanup = function() {
|
|
323
|
+
resetAction();
|
|
324
|
+
canvas.removeEventListener("touchstart", onCanvasTouchStart);
|
|
325
|
+
canvas.removeEventListener("touchmove", onCanvasTouchMove);
|
|
326
|
+
canvas.removeEventListener("touchend", onCanvasTouchEnd);
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const onCanvasTouchStart = function(event) {
|
|
330
|
+
const touches = event.touches;
|
|
331
|
+
|
|
332
|
+
if (touches.length !== 1)
|
|
333
|
+
{
|
|
334
|
+
resetAction();
|
|
335
|
+
onCancel();
|
|
336
|
+
}
|
|
337
|
+
else
|
|
338
|
+
{
|
|
339
|
+
const startTouch = touches[0];
|
|
340
|
+
const startCanvasPos = copyCanvasPos(startTouch, math.vec2());
|
|
341
|
+
|
|
342
|
+
const startWorldPos = pickWorldPos(startCanvasPos);
|
|
343
|
+
if (startWorldPos)
|
|
344
|
+
{
|
|
345
|
+
startTouchIdentifier = startTouch.identifier;
|
|
346
|
+
|
|
347
|
+
onSingleTouchMove = canvasPos => {
|
|
348
|
+
if (math.distVec2(startCanvasPos, canvasPos) > moveTolerance)
|
|
349
|
+
{
|
|
350
|
+
resetAction();
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
longTouchTimeout = setTimeout(
|
|
355
|
+
function() {
|
|
356
|
+
pointerCircle.start(startCanvasPos);
|
|
357
|
+
|
|
358
|
+
longTouchTimeout = setTimeout(
|
|
359
|
+
function() {
|
|
360
|
+
pointerCircle.stop();
|
|
361
|
+
|
|
362
|
+
viewer.cameraControl.active = false;
|
|
363
|
+
|
|
364
|
+
onSingleTouchMove = canvasPos => {
|
|
365
|
+
onChange(canvasPos, pickWorldPos(canvasPos));
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
onSingleTouchMove(startCanvasPos);
|
|
369
|
+
},
|
|
370
|
+
longTouchTimeoutMs);
|
|
371
|
+
},
|
|
372
|
+
250);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
canvas.addEventListener("touchstart", onCanvasTouchStart, {passive: true});
|
|
377
|
+
|
|
378
|
+
// canvas.addEventListener("touchcancel", e => console.log("touchcancel", e), {passive: true});
|
|
379
|
+
|
|
380
|
+
const onCanvasTouchMove = function(event) {
|
|
381
|
+
const touch = [...event.changedTouches].find(e => e.identifier === startTouchIdentifier);
|
|
382
|
+
if (touch)
|
|
383
|
+
{
|
|
384
|
+
onSingleTouchMove(copyCanvasPos(touch, math.vec2()));
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
canvas.addEventListener("touchmove", onCanvasTouchMove, {passive: true});
|
|
388
|
+
|
|
389
|
+
const onCanvasTouchEnd = function(event) {
|
|
390
|
+
const touch = [...event.changedTouches].find(e => e.identifier === startTouchIdentifier);
|
|
391
|
+
if (touch)
|
|
392
|
+
{
|
|
393
|
+
cleanup();
|
|
394
|
+
const canvasPos = copyCanvasPos(touch, math.vec2());
|
|
395
|
+
onCommit(canvasPos, pickWorldPos(canvasPos));
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
canvas.addEventListener("touchend", onCanvasTouchEnd, {passive: true});
|
|
399
|
+
|
|
400
|
+
return cleanup;
|
|
401
|
+
};
|
|
402
|
+
};
|
|
@@ -2505,7 +2505,21 @@ export class SceneModel extends Component {
|
|
|
2505
2505
|
if (cfg.image) { // Ignore transcoder for Images
|
|
2506
2506
|
const image = cfg.image;
|
|
2507
2507
|
image.crossOrigin = "Anonymous";
|
|
2508
|
-
|
|
2508
|
+
if (image.compressed) {
|
|
2509
|
+
// see `parsedImage` in @loaders.gl/gltf/src/lib/parsers/parse-gltf.ts
|
|
2510
|
+
// NOTE: @loaders.gl in its current version discards potential mipmaps, leaving only a single one
|
|
2511
|
+
const data = image.data;
|
|
2512
|
+
texture.setCompressedData({
|
|
2513
|
+
mipmaps: data,
|
|
2514
|
+
props: {
|
|
2515
|
+
format: data[0].format,
|
|
2516
|
+
minFilter: minFilter,
|
|
2517
|
+
magFilter: magFilter
|
|
2518
|
+
}
|
|
2519
|
+
});
|
|
2520
|
+
} else {
|
|
2521
|
+
texture.setImage(image, {minFilter, magFilter, wrapS, wrapT, wrapR, flipY: cfg.flipY, encoding});
|
|
2522
|
+
}
|
|
2509
2523
|
} else if (cfg.src) {
|
|
2510
2524
|
const ext = cfg.src.split('.').pop();
|
|
2511
2525
|
switch (ext) { // Don't transcode recognized image file types
|
|
@@ -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
|
-
|
|
48
|
+
const maxGeometryBatchSize = Math.min(5000000, cfg.maxGeometryBatchSize || window.Infinity);
|
|
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 (
|
|
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
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
196
|
+
buffer.positions.append(positions);
|
|
178
197
|
|
|
179
|
-
|
|
180
|
-
const positionsBase = buffer.positions.length;
|
|
198
|
+
const numVerts = positions.length / 3;
|
|
181
199
|
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|
|
189
|
-
buffer.colors.push(colorsCompressed[i]);
|
|
190
|
-
}
|
|
191
|
-
|
|
206
|
+
buffer.colors.append(colorsCompressed);
|
|
192
207
|
} else if (colors) {
|
|
193
|
-
|
|
194
|
-
buffer.colors.push(colors[i] * 255);
|
|
195
|
-
}
|
|
196
|
-
|
|
208
|
+
buffer.colors.append(colors, 1, 255.0);
|
|
197
209
|
} else if (color) {
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
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
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
/**
|