@xeokit/xeokit-sdk 2.2.1-beta.1 → 2.2.1-beta.2

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.
@@ -13280,533 +13280,6 @@ class Program {
13280
13280
  }
13281
13281
  }
13282
13282
 
13283
- /*
13284
- * Canvas2Image v0.1
13285
- * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com
13286
- * MIT License [http://www.opensource.org/licenses/mit-license.php]
13287
- *
13288
- * Modified by @xeolabs to permit vertical flipping, so that snapshot can be taken from WebGL frame buffers,
13289
- * which vertically flip image data as part of the way that WebGL renders textures.
13290
- */
13291
-
13292
- /**
13293
- * @private
13294
- */
13295
- const Canvas2Image = (function () {
13296
- // check if we have canvas support
13297
- const oCanvas = document.createElement("canvas"), sc = String.fromCharCode;
13298
-
13299
- // no canvas, bail out.
13300
- if (!oCanvas.getContext) {
13301
- return {
13302
- saveAsBMP: function () {
13303
- },
13304
- saveAsPNG: function () {
13305
- },
13306
- saveAsJPEG: function () {
13307
- }
13308
- }
13309
- }
13310
-
13311
- const bHasImageData = !!(oCanvas.getContext("2d").getImageData), bHasDataURL = !!(oCanvas.toDataURL),
13312
- bHasBase64 = !!(window.btoa);
13313
-
13314
- // ok, we're good
13315
- const readCanvasData = function (oCanvas) {
13316
- const iWidth = parseInt(oCanvas.width), iHeight = parseInt(oCanvas.height);
13317
- return oCanvas.getContext("2d").getImageData(0, 0, iWidth, iHeight);
13318
- };
13319
-
13320
- // base64 encodes either a string or an array of charcodes
13321
- const encodeData = function (data) {
13322
- let i, aData, strData = "";
13323
-
13324
- if (typeof data == "string") {
13325
- strData = data;
13326
- } else {
13327
- aData = data;
13328
- for (i = 0; i < aData.length; i++) {
13329
- strData += sc(aData[i]);
13330
- }
13331
- }
13332
- return btoa(strData);
13333
- };
13334
-
13335
- // creates a base64 encoded string containing BMP data takes an imagedata object as argument
13336
- const createBMP = function (oData) {
13337
- let strHeader = '';
13338
- const iWidth = oData.width;
13339
- const iHeight = oData.height;
13340
-
13341
- strHeader += 'BM';
13342
-
13343
- let iFileSize = iWidth * iHeight * 4 + 54; // total header size = 54 bytes
13344
- strHeader += sc(iFileSize % 256);
13345
- iFileSize = Math.floor(iFileSize / 256);
13346
- strHeader += sc(iFileSize % 256);
13347
- iFileSize = Math.floor(iFileSize / 256);
13348
- strHeader += sc(iFileSize % 256);
13349
- iFileSize = Math.floor(iFileSize / 256);
13350
- strHeader += sc(iFileSize % 256);
13351
-
13352
- strHeader += sc(0, 0, 0, 0, 54, 0, 0, 0); // data offset
13353
- strHeader += sc(40, 0, 0, 0); // info header size
13354
-
13355
- let iImageWidth = iWidth;
13356
- strHeader += sc(iImageWidth % 256);
13357
- iImageWidth = Math.floor(iImageWidth / 256);
13358
- strHeader += sc(iImageWidth % 256);
13359
- iImageWidth = Math.floor(iImageWidth / 256);
13360
- strHeader += sc(iImageWidth % 256);
13361
- iImageWidth = Math.floor(iImageWidth / 256);
13362
- strHeader += sc(iImageWidth % 256);
13363
-
13364
- let iImageHeight = iHeight;
13365
- strHeader += sc(iImageHeight % 256);
13366
- iImageHeight = Math.floor(iImageHeight / 256);
13367
- strHeader += sc(iImageHeight % 256);
13368
- iImageHeight = Math.floor(iImageHeight / 256);
13369
- strHeader += sc(iImageHeight % 256);
13370
- iImageHeight = Math.floor(iImageHeight / 256);
13371
- strHeader += sc(iImageHeight % 256);
13372
-
13373
- strHeader += sc(1, 0, 32, 0); // num of planes & num of bits per pixel
13374
- strHeader += sc(0, 0, 0, 0); // compression = none
13375
-
13376
- let iDataSize = iWidth * iHeight * 4;
13377
- strHeader += sc(iDataSize % 256);
13378
- iDataSize = Math.floor(iDataSize / 256);
13379
- strHeader += sc(iDataSize % 256);
13380
- iDataSize = Math.floor(iDataSize / 256);
13381
- strHeader += sc(iDataSize % 256);
13382
- iDataSize = Math.floor(iDataSize / 256);
13383
- strHeader += sc(iDataSize % 256);
13384
-
13385
- strHeader += sc(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // these bytes are not used
13386
-
13387
- const aImgData = oData.data;
13388
- let strPixelData = "";
13389
- let x;
13390
- let y = iHeight;
13391
- let iOffsetX;
13392
- let iOffsetY;
13393
- let strPixelRow;
13394
-
13395
- do {
13396
- iOffsetY = iWidth * (y - 1) * 4;
13397
- strPixelRow = "";
13398
- for (x = 0; x < iWidth; x++) {
13399
- iOffsetX = 4 * x;
13400
- strPixelRow += sc(
13401
- aImgData[iOffsetY + iOffsetX + 2], // B
13402
- aImgData[iOffsetY + iOffsetX + 1], // G
13403
- aImgData[iOffsetY + iOffsetX], // R
13404
- aImgData[iOffsetY + iOffsetX + 3] // A
13405
- );
13406
- }
13407
- strPixelData += strPixelRow;
13408
- } while (--y);
13409
-
13410
- return encodeData(strHeader + strPixelData);
13411
- };
13412
-
13413
- // sends the generated file to the client
13414
- const saveFile = function (strData) {
13415
- if (!window.open(strData)) {
13416
- document.location.href = strData;
13417
- }
13418
- };
13419
-
13420
- const makeDataURI = function (strData, strMime) {
13421
- return "data:" + strMime + ";base64," + strData;
13422
- };
13423
-
13424
- // generates a <img> object containing the imagedata
13425
- const makeImageObject = function (strSource) {
13426
- const oImgElement = document.createElement("img");
13427
- oImgElement.src = strSource;
13428
- return oImgElement;
13429
- };
13430
-
13431
- const scaleCanvas = function (oCanvas, iWidth, iHeight, flipy) {
13432
- if (iWidth && iHeight) {
13433
- const oSaveCanvas = document.createElement("canvas");
13434
- oSaveCanvas.width = iWidth;
13435
- oSaveCanvas.height = iHeight;
13436
- oSaveCanvas.style.width = iWidth + "px";
13437
- oSaveCanvas.style.height = iHeight + "px";
13438
- const oSaveCtx = oSaveCanvas.getContext("2d");
13439
- if (flipy) {
13440
- oSaveCtx.save();
13441
- oSaveCtx.scale(1.0, -1.0);
13442
- oSaveCtx.imageSmoothingEnabled = true;
13443
- oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, -iHeight);
13444
- oSaveCtx.restore();
13445
- } else {
13446
- oSaveCtx.imageSmoothingEnabled = true;
13447
- oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, iHeight);
13448
- }
13449
- return oSaveCanvas;
13450
- }
13451
- return oCanvas;
13452
- };
13453
-
13454
- return {
13455
- saveAsPNG: function (oCanvas, bReturnImg, iWidth, iHeight, flipy) {
13456
- if (!bHasDataURL) return false;
13457
- const oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight, flipy);
13458
- const strMime = "image/png";
13459
- const strData = oScaledCanvas.toDataURL(strMime);
13460
- if (bReturnImg) {
13461
- return makeImageObject(strData);
13462
- } else {
13463
- saveFile(strData);
13464
- }
13465
- return true;
13466
- },
13467
-
13468
- saveAsJPEG: function (oCanvas, bReturnImg, iWidth, iHeight, flipy) {
13469
- if (!bHasDataURL) return false;
13470
- const oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight, flipy);
13471
- const strMime = "image/jpeg";
13472
- const strData = oScaledCanvas.toDataURL(strMime);
13473
- // check if browser actually supports jpeg by looking for the mime type in the data uri. if not, return false
13474
- if (strData.indexOf(strMime) != 5) return false;
13475
- if (bReturnImg) {
13476
- return makeImageObject(strData);
13477
- } else {
13478
- saveFile(strData);
13479
- }
13480
- return true;
13481
- },
13482
-
13483
- saveAsBMP: function (oCanvas, bReturnImg, iWidth, iHeight, flipy) {
13484
- if (!(bHasDataURL && bHasImageData && bHasBase64)) return false;
13485
- const oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight, flipy);
13486
- const strMime = "image/bmp";
13487
- const oData = readCanvasData(oScaledCanvas), strImgData = createBMP(oData);
13488
- if (bReturnImg) {
13489
- return makeImageObject(makeDataURI(strImgData, strMime));
13490
- } else {
13491
- saveFile(makeDataURI(strImgData, strMime));
13492
- }
13493
- return true;
13494
- }
13495
- };
13496
- })();
13497
-
13498
- /**
13499
- * @desc Represents a WebGL render buffer.
13500
- * @private
13501
- */
13502
- class RenderBuffer {
13503
-
13504
- constructor(canvas, gl, options) {
13505
- options = options || {};
13506
- this.gl = gl;
13507
- this.allocated = false;
13508
- this.canvas = canvas;
13509
- this.buffer = null;
13510
- this.bound = false;
13511
- this.size = options.size;
13512
- this._hasDepthTexture = !!options.depthTexture;
13513
- }
13514
-
13515
- setSize(size) {
13516
- this.size = size;
13517
- }
13518
-
13519
- webglContextRestored(gl) {
13520
- this.gl = gl;
13521
- this.buffer = null;
13522
- this.allocated = false;
13523
- this.bound = false;
13524
- }
13525
-
13526
- bind() {
13527
- this._touch();
13528
- if (this.bound) {
13529
- return;
13530
- }
13531
- const gl = this.gl;
13532
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.buffer.framebuf);
13533
- this.bound = true;
13534
- }
13535
-
13536
- _touch() {
13537
-
13538
- let width;
13539
- let height;
13540
- const gl = this.gl;
13541
-
13542
- if (this.size) {
13543
- width = this.size[0];
13544
- height = this.size[1];
13545
-
13546
- } else {
13547
- width = gl.drawingBufferWidth;
13548
- height = gl.drawingBufferHeight;
13549
- }
13550
-
13551
- if (this.buffer) {
13552
-
13553
- if (this.buffer.width === width && this.buffer.height === height) {
13554
- return;
13555
-
13556
- } else {
13557
- gl.deleteTexture(this.buffer.texture);
13558
- gl.deleteFramebuffer(this.buffer.framebuf);
13559
- gl.deleteRenderbuffer(this.buffer.renderbuf);
13560
- }
13561
- }
13562
-
13563
- const colorTexture = gl.createTexture();
13564
- gl.bindTexture(gl.TEXTURE_2D, colorTexture);
13565
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
13566
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
13567
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
13568
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
13569
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
13570
-
13571
- let depthTexture;
13572
-
13573
- if (this._hasDepthTexture) {
13574
- depthTexture = gl.createTexture();
13575
- gl.bindTexture(gl.TEXTURE_2D, depthTexture);
13576
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
13577
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
13578
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
13579
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
13580
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
13581
- }
13582
-
13583
- const renderbuf = gl.createRenderbuffer();
13584
- gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuf);
13585
- gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
13586
-
13587
- const framebuf = gl.createFramebuffer();
13588
- gl.bindFramebuffer(gl.FRAMEBUFFER, framebuf);
13589
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTexture, 0);
13590
-
13591
- if (this._hasDepthTexture) {
13592
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);
13593
- } else {
13594
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuf);
13595
- }
13596
-
13597
- gl.bindTexture(gl.TEXTURE_2D, null);
13598
- gl.bindRenderbuffer(gl.RENDERBUFFER, null);
13599
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
13600
-
13601
- // Verify framebuffer is OK
13602
-
13603
- gl.bindFramebuffer(gl.FRAMEBUFFER, framebuf);
13604
- if (!gl.isFramebuffer(framebuf)) {
13605
- throw "Invalid framebuffer";
13606
- }
13607
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
13608
-
13609
- const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
13610
-
13611
- switch (status) {
13612
-
13613
- case gl.FRAMEBUFFER_COMPLETE:
13614
- break;
13615
-
13616
- case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
13617
- throw "Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
13618
-
13619
- case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
13620
- throw "Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
13621
-
13622
- case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
13623
- throw "Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
13624
-
13625
- case gl.FRAMEBUFFER_UNSUPPORTED:
13626
- throw "Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED";
13627
-
13628
- default:
13629
- throw "Incomplete framebuffer: " + status;
13630
- }
13631
-
13632
- this.buffer = {
13633
- framebuf: framebuf,
13634
- renderbuf: renderbuf,
13635
- texture: colorTexture,
13636
- depthTexture: depthTexture,
13637
- width: width,
13638
- height: height
13639
- };
13640
-
13641
- this.bound = false;
13642
- }
13643
-
13644
- clear() {
13645
- if (!this.bound) {
13646
- throw "Render buffer not bound";
13647
- }
13648
- const gl = this.gl;
13649
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
13650
- }
13651
-
13652
- read(pickX, pickY) {
13653
- const x = pickX;
13654
- const y = this.gl.drawingBufferHeight - pickY;
13655
- const pix = new Uint8Array(4);
13656
- const gl = this.gl;
13657
- gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pix);
13658
- return pix;
13659
- }
13660
-
13661
- readImage(params) {
13662
-
13663
- const gl = this.gl;
13664
- const imageDataCache = this._getImageDataCache();
13665
- const pixelData = imageDataCache.pixelData;
13666
- const canvas = imageDataCache.canvas;
13667
- const imageData = imageDataCache.imageData;
13668
- const context = imageDataCache.context;
13669
-
13670
- gl.readPixels(0, 0, this.buffer.width, this.buffer.height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);
13671
-
13672
- imageData.data.set(pixelData);
13673
- context.putImageData(imageData, 0, 0);
13674
-
13675
- const imageWidth = params.width || canvas.width;
13676
- const imageHeight = params.height || canvas.height;
13677
- const format = params.format || "jpeg";
13678
- const flipy = true; // Account for WebGL texture flipping
13679
-
13680
- let image;
13681
-
13682
- switch (format) {
13683
- case "jpeg":
13684
- image = Canvas2Image.saveAsJPEG(canvas, true, imageWidth, imageHeight, flipy);
13685
- break;
13686
- case "png":
13687
- image = Canvas2Image.saveAsPNG(canvas, true, imageWidth, imageHeight, flipy);
13688
- break;
13689
- case "bmp":
13690
- image = Canvas2Image.saveAsBMP(canvas, true, imageWidth, imageHeight, flipy);
13691
- break;
13692
- default:
13693
- console.error("Unsupported image format: '" + format + "' - supported types are 'jpeg', 'bmp' and 'png' - defaulting to 'jpeg'");
13694
- image = Canvas2Image.saveAsJPEG(canvas, true, imageWidth, imageHeight, flipy);
13695
- }
13696
-
13697
- return image.src;
13698
- }
13699
-
13700
- _getImageDataCache() {
13701
-
13702
- const bufferWidth = this.buffer.width;
13703
- const bufferHeight = this.buffer.height;
13704
-
13705
- let imageDataCache = this._imageDataCache;
13706
-
13707
- if (imageDataCache) {
13708
- if (imageDataCache.width !== bufferWidth || imageDataCache.height !== bufferHeight) {
13709
- this._imageDataCache = null;
13710
- imageDataCache = null;
13711
- }
13712
- }
13713
-
13714
- if (!imageDataCache) {
13715
-
13716
- const canvas = document.createElement('canvas');
13717
- canvas.width = bufferWidth;
13718
- canvas.height = bufferHeight;
13719
-
13720
- const context = canvas.getContext('2d');
13721
- const imageData = context.createImageData(bufferWidth, bufferHeight);
13722
-
13723
- imageDataCache = {
13724
- pixelData: new Uint8Array(bufferWidth * bufferHeight * 4),
13725
- canvas: canvas,
13726
- context: context,
13727
- imageData: imageData,
13728
- width: bufferWidth,
13729
- height: bufferHeight
13730
- };
13731
-
13732
- this._imageDataCache = imageDataCache;
13733
- }
13734
-
13735
- return imageDataCache;
13736
- }
13737
-
13738
- unbind() {
13739
- const gl = this.gl;
13740
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
13741
- this.bound = false;
13742
- }
13743
-
13744
- getTexture() {
13745
- const self = this;
13746
- return this._texture || (this._texture = {
13747
- renderBuffer: this,
13748
- bind: function (unit) {
13749
- if (self.buffer && self.buffer.texture) {
13750
- self.gl.activeTexture(self.gl["TEXTURE" + unit]);
13751
- self.gl.bindTexture(self.gl.TEXTURE_2D, self.buffer.texture);
13752
- return true;
13753
- }
13754
- return false;
13755
- },
13756
- unbind: function (unit) {
13757
- if (self.buffer && self.buffer.texture) {
13758
- self.gl.activeTexture(self.gl["TEXTURE" + unit]);
13759
- self.gl.bindTexture(self.gl.TEXTURE_2D, null);
13760
- }
13761
- }
13762
- });
13763
- }
13764
-
13765
- hasDepthTexture() {
13766
- return this._hasDepthTexture;
13767
- }
13768
-
13769
- getDepthTexture() {
13770
- if (!this._hasDepthTexture) {
13771
- return null;
13772
- }
13773
- const self = this;
13774
- return this._depthTexture || (this._dethTexture = {
13775
- renderBuffer: this,
13776
- bind: function (unit) {
13777
- if (self.buffer && self.buffer.depthTexture) {
13778
- self.gl.activeTexture(self.gl["TEXTURE" + unit]);
13779
- self.gl.bindTexture(self.gl.TEXTURE_2D, self.buffer.depthTexture);
13780
- return true;
13781
- }
13782
- return false;
13783
- },
13784
- unbind: function (unit) {
13785
- if (self.buffer && self.buffer.depthTexture) {
13786
- self.gl.activeTexture(self.gl["TEXTURE" + unit]);
13787
- self.gl.bindTexture(self.gl.TEXTURE_2D, null);
13788
- }
13789
- }
13790
- });
13791
- }
13792
-
13793
- destroy() {
13794
- if (this.allocated) {
13795
- const gl = this.gl;
13796
- gl.deleteTexture(this.buffer.texture);
13797
- gl.deleteTexture(this.buffer.depthTexture);
13798
- gl.deleteFramebuffer(this.buffer.framebuf);
13799
- gl.deleteRenderbuffer(this.buffer.renderbuf);
13800
- this.allocated = false;
13801
- this.buffer = null;
13802
- this.bound = false;
13803
- }
13804
- this._imageDataCache = null;
13805
- this._texture = null;
13806
- this._depthTexture = null;
13807
- }
13808
- }
13809
-
13810
13283
  /**
13811
13284
  * @desc Represents a WebGL ArrayBuffer.
13812
13285
  *
@@ -15252,6 +14725,533 @@ function createSampleOffsets(kernelRadius, uvIncrement) {
15252
14725
  return offsets;
15253
14726
  }
15254
14727
 
14728
+ /*
14729
+ * Canvas2Image v0.1
14730
+ * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com
14731
+ * MIT License [http://www.opensource.org/licenses/mit-license.php]
14732
+ *
14733
+ * Modified by @xeolabs to permit vertical flipping, so that snapshot can be taken from WebGL frame buffers,
14734
+ * which vertically flip image data as part of the way that WebGL renders textures.
14735
+ */
14736
+
14737
+ /**
14738
+ * @private
14739
+ */
14740
+ const Canvas2Image = (function () {
14741
+ // check if we have canvas support
14742
+ const oCanvas = document.createElement("canvas"), sc = String.fromCharCode;
14743
+
14744
+ // no canvas, bail out.
14745
+ if (!oCanvas.getContext) {
14746
+ return {
14747
+ saveAsBMP: function () {
14748
+ },
14749
+ saveAsPNG: function () {
14750
+ },
14751
+ saveAsJPEG: function () {
14752
+ }
14753
+ }
14754
+ }
14755
+
14756
+ const bHasImageData = !!(oCanvas.getContext("2d").getImageData), bHasDataURL = !!(oCanvas.toDataURL),
14757
+ bHasBase64 = !!(window.btoa);
14758
+
14759
+ // ok, we're good
14760
+ const readCanvasData = function (oCanvas) {
14761
+ const iWidth = parseInt(oCanvas.width), iHeight = parseInt(oCanvas.height);
14762
+ return oCanvas.getContext("2d").getImageData(0, 0, iWidth, iHeight);
14763
+ };
14764
+
14765
+ // base64 encodes either a string or an array of charcodes
14766
+ const encodeData = function (data) {
14767
+ let i, aData, strData = "";
14768
+
14769
+ if (typeof data == "string") {
14770
+ strData = data;
14771
+ } else {
14772
+ aData = data;
14773
+ for (i = 0; i < aData.length; i++) {
14774
+ strData += sc(aData[i]);
14775
+ }
14776
+ }
14777
+ return btoa(strData);
14778
+ };
14779
+
14780
+ // creates a base64 encoded string containing BMP data takes an imagedata object as argument
14781
+ const createBMP = function (oData) {
14782
+ let strHeader = '';
14783
+ const iWidth = oData.width;
14784
+ const iHeight = oData.height;
14785
+
14786
+ strHeader += 'BM';
14787
+
14788
+ let iFileSize = iWidth * iHeight * 4 + 54; // total header size = 54 bytes
14789
+ strHeader += sc(iFileSize % 256);
14790
+ iFileSize = Math.floor(iFileSize / 256);
14791
+ strHeader += sc(iFileSize % 256);
14792
+ iFileSize = Math.floor(iFileSize / 256);
14793
+ strHeader += sc(iFileSize % 256);
14794
+ iFileSize = Math.floor(iFileSize / 256);
14795
+ strHeader += sc(iFileSize % 256);
14796
+
14797
+ strHeader += sc(0, 0, 0, 0, 54, 0, 0, 0); // data offset
14798
+ strHeader += sc(40, 0, 0, 0); // info header size
14799
+
14800
+ let iImageWidth = iWidth;
14801
+ strHeader += sc(iImageWidth % 256);
14802
+ iImageWidth = Math.floor(iImageWidth / 256);
14803
+ strHeader += sc(iImageWidth % 256);
14804
+ iImageWidth = Math.floor(iImageWidth / 256);
14805
+ strHeader += sc(iImageWidth % 256);
14806
+ iImageWidth = Math.floor(iImageWidth / 256);
14807
+ strHeader += sc(iImageWidth % 256);
14808
+
14809
+ let iImageHeight = iHeight;
14810
+ strHeader += sc(iImageHeight % 256);
14811
+ iImageHeight = Math.floor(iImageHeight / 256);
14812
+ strHeader += sc(iImageHeight % 256);
14813
+ iImageHeight = Math.floor(iImageHeight / 256);
14814
+ strHeader += sc(iImageHeight % 256);
14815
+ iImageHeight = Math.floor(iImageHeight / 256);
14816
+ strHeader += sc(iImageHeight % 256);
14817
+
14818
+ strHeader += sc(1, 0, 32, 0); // num of planes & num of bits per pixel
14819
+ strHeader += sc(0, 0, 0, 0); // compression = none
14820
+
14821
+ let iDataSize = iWidth * iHeight * 4;
14822
+ strHeader += sc(iDataSize % 256);
14823
+ iDataSize = Math.floor(iDataSize / 256);
14824
+ strHeader += sc(iDataSize % 256);
14825
+ iDataSize = Math.floor(iDataSize / 256);
14826
+ strHeader += sc(iDataSize % 256);
14827
+ iDataSize = Math.floor(iDataSize / 256);
14828
+ strHeader += sc(iDataSize % 256);
14829
+
14830
+ strHeader += sc(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // these bytes are not used
14831
+
14832
+ const aImgData = oData.data;
14833
+ let strPixelData = "";
14834
+ let x;
14835
+ let y = iHeight;
14836
+ let iOffsetX;
14837
+ let iOffsetY;
14838
+ let strPixelRow;
14839
+
14840
+ do {
14841
+ iOffsetY = iWidth * (y - 1) * 4;
14842
+ strPixelRow = "";
14843
+ for (x = 0; x < iWidth; x++) {
14844
+ iOffsetX = 4 * x;
14845
+ strPixelRow += sc(
14846
+ aImgData[iOffsetY + iOffsetX + 2], // B
14847
+ aImgData[iOffsetY + iOffsetX + 1], // G
14848
+ aImgData[iOffsetY + iOffsetX], // R
14849
+ aImgData[iOffsetY + iOffsetX + 3] // A
14850
+ );
14851
+ }
14852
+ strPixelData += strPixelRow;
14853
+ } while (--y);
14854
+
14855
+ return encodeData(strHeader + strPixelData);
14856
+ };
14857
+
14858
+ // sends the generated file to the client
14859
+ const saveFile = function (strData) {
14860
+ if (!window.open(strData)) {
14861
+ document.location.href = strData;
14862
+ }
14863
+ };
14864
+
14865
+ const makeDataURI = function (strData, strMime) {
14866
+ return "data:" + strMime + ";base64," + strData;
14867
+ };
14868
+
14869
+ // generates a <img> object containing the imagedata
14870
+ const makeImageObject = function (strSource) {
14871
+ const oImgElement = document.createElement("img");
14872
+ oImgElement.src = strSource;
14873
+ return oImgElement;
14874
+ };
14875
+
14876
+ const scaleCanvas = function (oCanvas, iWidth, iHeight, flipy) {
14877
+ if (iWidth && iHeight) {
14878
+ const oSaveCanvas = document.createElement("canvas");
14879
+ oSaveCanvas.width = iWidth;
14880
+ oSaveCanvas.height = iHeight;
14881
+ oSaveCanvas.style.width = iWidth + "px";
14882
+ oSaveCanvas.style.height = iHeight + "px";
14883
+ const oSaveCtx = oSaveCanvas.getContext("2d");
14884
+ if (flipy) {
14885
+ oSaveCtx.save();
14886
+ oSaveCtx.scale(1.0, -1.0);
14887
+ oSaveCtx.imageSmoothingEnabled = true;
14888
+ oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, -iHeight);
14889
+ oSaveCtx.restore();
14890
+ } else {
14891
+ oSaveCtx.imageSmoothingEnabled = true;
14892
+ oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, iHeight);
14893
+ }
14894
+ return oSaveCanvas;
14895
+ }
14896
+ return oCanvas;
14897
+ };
14898
+
14899
+ return {
14900
+ saveAsPNG: function (oCanvas, bReturnImg, iWidth, iHeight, flipy) {
14901
+ if (!bHasDataURL) return false;
14902
+ const oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight, flipy);
14903
+ const strMime = "image/png";
14904
+ const strData = oScaledCanvas.toDataURL(strMime);
14905
+ if (bReturnImg) {
14906
+ return makeImageObject(strData);
14907
+ } else {
14908
+ saveFile(strData);
14909
+ }
14910
+ return true;
14911
+ },
14912
+
14913
+ saveAsJPEG: function (oCanvas, bReturnImg, iWidth, iHeight, flipy) {
14914
+ if (!bHasDataURL) return false;
14915
+ const oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight, flipy);
14916
+ const strMime = "image/jpeg";
14917
+ const strData = oScaledCanvas.toDataURL(strMime);
14918
+ // check if browser actually supports jpeg by looking for the mime type in the data uri. if not, return false
14919
+ if (strData.indexOf(strMime) != 5) return false;
14920
+ if (bReturnImg) {
14921
+ return makeImageObject(strData);
14922
+ } else {
14923
+ saveFile(strData);
14924
+ }
14925
+ return true;
14926
+ },
14927
+
14928
+ saveAsBMP: function (oCanvas, bReturnImg, iWidth, iHeight, flipy) {
14929
+ if (!(bHasDataURL && bHasImageData && bHasBase64)) return false;
14930
+ const oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight, flipy);
14931
+ const strMime = "image/bmp";
14932
+ const oData = readCanvasData(oScaledCanvas), strImgData = createBMP(oData);
14933
+ if (bReturnImg) {
14934
+ return makeImageObject(makeDataURI(strImgData, strMime));
14935
+ } else {
14936
+ saveFile(makeDataURI(strImgData, strMime));
14937
+ }
14938
+ return true;
14939
+ }
14940
+ };
14941
+ })();
14942
+
14943
+ /**
14944
+ * @desc Represents a WebGL render buffer.
14945
+ * @private
14946
+ */
14947
+ class RenderBuffer {
14948
+
14949
+ constructor(canvas, gl, options) {
14950
+ options = options || {};
14951
+ this.gl = gl;
14952
+ this.allocated = false;
14953
+ this.canvas = canvas;
14954
+ this.buffer = null;
14955
+ this.bound = false;
14956
+ this.size = options.size;
14957
+ this._hasDepthTexture = !!options.depthTexture;
14958
+ }
14959
+
14960
+ setSize(size) {
14961
+ this.size = size;
14962
+ }
14963
+
14964
+ webglContextRestored(gl) {
14965
+ this.gl = gl;
14966
+ this.buffer = null;
14967
+ this.allocated = false;
14968
+ this.bound = false;
14969
+ }
14970
+
14971
+ bind() {
14972
+ this._touch();
14973
+ if (this.bound) {
14974
+ return;
14975
+ }
14976
+ const gl = this.gl;
14977
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.buffer.framebuf);
14978
+ this.bound = true;
14979
+ }
14980
+
14981
+ _touch() {
14982
+
14983
+ let width;
14984
+ let height;
14985
+ const gl = this.gl;
14986
+
14987
+ if (this.size) {
14988
+ width = this.size[0];
14989
+ height = this.size[1];
14990
+
14991
+ } else {
14992
+ width = gl.drawingBufferWidth;
14993
+ height = gl.drawingBufferHeight;
14994
+ }
14995
+
14996
+ if (this.buffer) {
14997
+
14998
+ if (this.buffer.width === width && this.buffer.height === height) {
14999
+ return;
15000
+
15001
+ } else {
15002
+ gl.deleteTexture(this.buffer.texture);
15003
+ gl.deleteFramebuffer(this.buffer.framebuf);
15004
+ gl.deleteRenderbuffer(this.buffer.renderbuf);
15005
+ }
15006
+ }
15007
+
15008
+ const colorTexture = gl.createTexture();
15009
+ gl.bindTexture(gl.TEXTURE_2D, colorTexture);
15010
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
15011
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
15012
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
15013
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
15014
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
15015
+
15016
+ let depthTexture;
15017
+
15018
+ if (this._hasDepthTexture) {
15019
+ depthTexture = gl.createTexture();
15020
+ gl.bindTexture(gl.TEXTURE_2D, depthTexture);
15021
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
15022
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
15023
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
15024
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
15025
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
15026
+ }
15027
+
15028
+ const renderbuf = gl.createRenderbuffer();
15029
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuf);
15030
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
15031
+
15032
+ const framebuf = gl.createFramebuffer();
15033
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuf);
15034
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTexture, 0);
15035
+
15036
+ if (this._hasDepthTexture) {
15037
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);
15038
+ } else {
15039
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuf);
15040
+ }
15041
+
15042
+ gl.bindTexture(gl.TEXTURE_2D, null);
15043
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
15044
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
15045
+
15046
+ // Verify framebuffer is OK
15047
+
15048
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuf);
15049
+ if (!gl.isFramebuffer(framebuf)) {
15050
+ throw "Invalid framebuffer";
15051
+ }
15052
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
15053
+
15054
+ const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
15055
+
15056
+ switch (status) {
15057
+
15058
+ case gl.FRAMEBUFFER_COMPLETE:
15059
+ break;
15060
+
15061
+ case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
15062
+ throw "Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
15063
+
15064
+ case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
15065
+ throw "Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
15066
+
15067
+ case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
15068
+ throw "Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
15069
+
15070
+ case gl.FRAMEBUFFER_UNSUPPORTED:
15071
+ throw "Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED";
15072
+
15073
+ default:
15074
+ throw "Incomplete framebuffer: " + status;
15075
+ }
15076
+
15077
+ this.buffer = {
15078
+ framebuf: framebuf,
15079
+ renderbuf: renderbuf,
15080
+ texture: colorTexture,
15081
+ depthTexture: depthTexture,
15082
+ width: width,
15083
+ height: height
15084
+ };
15085
+
15086
+ this.bound = false;
15087
+ }
15088
+
15089
+ clear() {
15090
+ if (!this.bound) {
15091
+ throw "Render buffer not bound";
15092
+ }
15093
+ const gl = this.gl;
15094
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
15095
+ }
15096
+
15097
+ read(pickX, pickY) {
15098
+ const x = pickX;
15099
+ const y = this.gl.drawingBufferHeight - pickY;
15100
+ const pix = new Uint8Array(4);
15101
+ const gl = this.gl;
15102
+ gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pix);
15103
+ return pix;
15104
+ }
15105
+
15106
+ readImage(params) {
15107
+
15108
+ const gl = this.gl;
15109
+ const imageDataCache = this._getImageDataCache();
15110
+ const pixelData = imageDataCache.pixelData;
15111
+ const canvas = imageDataCache.canvas;
15112
+ const imageData = imageDataCache.imageData;
15113
+ const context = imageDataCache.context;
15114
+
15115
+ gl.readPixels(0, 0, this.buffer.width, this.buffer.height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);
15116
+
15117
+ imageData.data.set(pixelData);
15118
+ context.putImageData(imageData, 0, 0);
15119
+
15120
+ const imageWidth = params.width || canvas.width;
15121
+ const imageHeight = params.height || canvas.height;
15122
+ const format = params.format || "jpeg";
15123
+ const flipy = true; // Account for WebGL texture flipping
15124
+
15125
+ let image;
15126
+
15127
+ switch (format) {
15128
+ case "jpeg":
15129
+ image = Canvas2Image.saveAsJPEG(canvas, true, imageWidth, imageHeight, flipy);
15130
+ break;
15131
+ case "png":
15132
+ image = Canvas2Image.saveAsPNG(canvas, true, imageWidth, imageHeight, flipy);
15133
+ break;
15134
+ case "bmp":
15135
+ image = Canvas2Image.saveAsBMP(canvas, true, imageWidth, imageHeight, flipy);
15136
+ break;
15137
+ default:
15138
+ console.error("Unsupported image format: '" + format + "' - supported types are 'jpeg', 'bmp' and 'png' - defaulting to 'jpeg'");
15139
+ image = Canvas2Image.saveAsJPEG(canvas, true, imageWidth, imageHeight, flipy);
15140
+ }
15141
+
15142
+ return image.src;
15143
+ }
15144
+
15145
+ _getImageDataCache() {
15146
+
15147
+ const bufferWidth = this.buffer.width;
15148
+ const bufferHeight = this.buffer.height;
15149
+
15150
+ let imageDataCache = this._imageDataCache;
15151
+
15152
+ if (imageDataCache) {
15153
+ if (imageDataCache.width !== bufferWidth || imageDataCache.height !== bufferHeight) {
15154
+ this._imageDataCache = null;
15155
+ imageDataCache = null;
15156
+ }
15157
+ }
15158
+
15159
+ if (!imageDataCache) {
15160
+
15161
+ const canvas = document.createElement('canvas');
15162
+ canvas.width = bufferWidth;
15163
+ canvas.height = bufferHeight;
15164
+
15165
+ const context = canvas.getContext('2d');
15166
+ const imageData = context.createImageData(bufferWidth, bufferHeight);
15167
+
15168
+ imageDataCache = {
15169
+ pixelData: new Uint8Array(bufferWidth * bufferHeight * 4),
15170
+ canvas: canvas,
15171
+ context: context,
15172
+ imageData: imageData,
15173
+ width: bufferWidth,
15174
+ height: bufferHeight
15175
+ };
15176
+
15177
+ this._imageDataCache = imageDataCache;
15178
+ }
15179
+
15180
+ return imageDataCache;
15181
+ }
15182
+
15183
+ unbind() {
15184
+ const gl = this.gl;
15185
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
15186
+ this.bound = false;
15187
+ }
15188
+
15189
+ getTexture() {
15190
+ const self = this;
15191
+ return this._texture || (this._texture = {
15192
+ renderBuffer: this,
15193
+ bind: function (unit) {
15194
+ if (self.buffer && self.buffer.texture) {
15195
+ self.gl.activeTexture(self.gl["TEXTURE" + unit]);
15196
+ self.gl.bindTexture(self.gl.TEXTURE_2D, self.buffer.texture);
15197
+ return true;
15198
+ }
15199
+ return false;
15200
+ },
15201
+ unbind: function (unit) {
15202
+ if (self.buffer && self.buffer.texture) {
15203
+ self.gl.activeTexture(self.gl["TEXTURE" + unit]);
15204
+ self.gl.bindTexture(self.gl.TEXTURE_2D, null);
15205
+ }
15206
+ }
15207
+ });
15208
+ }
15209
+
15210
+ hasDepthTexture() {
15211
+ return this._hasDepthTexture;
15212
+ }
15213
+
15214
+ getDepthTexture() {
15215
+ if (!this._hasDepthTexture) {
15216
+ return null;
15217
+ }
15218
+ const self = this;
15219
+ return this._depthTexture || (this._dethTexture = {
15220
+ renderBuffer: this,
15221
+ bind: function (unit) {
15222
+ if (self.buffer && self.buffer.depthTexture) {
15223
+ self.gl.activeTexture(self.gl["TEXTURE" + unit]);
15224
+ self.gl.bindTexture(self.gl.TEXTURE_2D, self.buffer.depthTexture);
15225
+ return true;
15226
+ }
15227
+ return false;
15228
+ },
15229
+ unbind: function (unit) {
15230
+ if (self.buffer && self.buffer.depthTexture) {
15231
+ self.gl.activeTexture(self.gl["TEXTURE" + unit]);
15232
+ self.gl.bindTexture(self.gl.TEXTURE_2D, null);
15233
+ }
15234
+ }
15235
+ });
15236
+ }
15237
+
15238
+ destroy() {
15239
+ if (this.allocated) {
15240
+ const gl = this.gl;
15241
+ gl.deleteTexture(this.buffer.texture);
15242
+ gl.deleteTexture(this.buffer.depthTexture);
15243
+ gl.deleteFramebuffer(this.buffer.framebuf);
15244
+ gl.deleteRenderbuffer(this.buffer.renderbuf);
15245
+ this.allocated = false;
15246
+ this.buffer = null;
15247
+ this.bound = false;
15248
+ }
15249
+ this._imageDataCache = null;
15250
+ this._texture = null;
15251
+ this._depthTexture = null;
15252
+ }
15253
+ }
15254
+
15255
15255
  /**
15256
15256
  * @private
15257
15257
  */
@@ -31850,6 +31850,7 @@ function buildVertex$1(mesh) {
31850
31850
  }
31851
31851
  src.push("void main(void) {");
31852
31852
  src.push("vec4 localPosition = vec4(position, 1.0); ");
31853
+ src.push("vec4 worldPosition;");
31853
31854
  if (quantizedGeometry) {
31854
31855
  src.push("localPosition = positionsDecodeMatrix * localPosition;");
31855
31856
  }
@@ -31862,10 +31863,15 @@ function buildVertex$1(mesh) {
31862
31863
  src.push("mat4 modelViewMatrix = viewMatrix2 * modelMatrix2;");
31863
31864
  src.push("billboard(modelMatrix2);");
31864
31865
  src.push("billboard(viewMatrix2);");
31866
+ src.push("billboard(modelViewMatrix);");
31867
+ src.push("worldPosition = modelMatrix2 * localPosition;");
31868
+ src.push("worldPosition.xyz = worldPosition.xyz + offset;");
31869
+ src.push("vec4 viewPosition = modelViewMatrix * localPosition;");
31870
+ } else {
31871
+ src.push("worldPosition = modelMatrix2 * localPosition;");
31872
+ src.push("worldPosition.xyz = worldPosition.xyz + offset;");
31873
+ src.push("vec4 viewPosition = viewMatrix2 * worldPosition; ");
31865
31874
  }
31866
- src.push(" vec4 worldPosition = modelMatrix2 * localPosition;");
31867
- src.push(" worldPosition.xyz = worldPosition.xyz + offset;");
31868
- src.push(" vec4 viewPosition = viewMatrix2 * worldPosition;");
31869
31875
  if (clipping) {
31870
31876
  src.push(" vWorldPosition = worldPosition;");
31871
31877
  }
@@ -31972,7 +31978,7 @@ OcclusionRenderer.get = function (mesh) {
31972
31978
  mesh.scene.canvas.canvas.id,
31973
31979
  mesh.scene._sectionPlanesState.getHash(),
31974
31980
  mesh._geometry._state.hash,
31975
- mesh._state.hash
31981
+ mesh._state.occlusionHash
31976
31982
  ].join(";");
31977
31983
  let renderer = renderers$1[hash];
31978
31984
  if (!renderer) {
@@ -148538,7 +148544,7 @@ class Configs {
148538
148544
  }
148539
148545
 
148540
148546
  /**
148541
- * Experimental {@link Viewer} plugin that uses [web-ifc](https://github.com/tomvandig/web-ifc) to load BIM models directly from IFC files.
148547
+ * {@link Viewer} plugin that uses [web-ifc](https://github.com/tomvandig/web-ifc) to load BIM models directly from IFC files.
148542
148548
  *
148543
148549
  * <a href="https://xeokit.github.io/xeokit-sdk/examples/#BIMOffline_WebIFCLoaderPlugin_Duplex"><img src="https://xeokit.io/img/docs/WebIFCLoaderPlugin/WebIFCLoaderPlugin.png"></a>
148544
148550
  *
@@ -152108,12 +152114,7 @@ class LASLoaderPlugin extends Plugin {
152108
152114
  }
152109
152115
 
152110
152116
  const performanceModel = new PerformanceModel(this.viewer.scene, utils.apply(params, {
152111
- isModel: true,
152112
- origin: params.origin,
152113
- position: params.position,
152114
- scale: params.scale,
152115
- rotation: params.rotation,
152116
- matrix: params.matrix
152117
+ isModel: true
152117
152118
  }));
152118
152119
 
152119
152120
  if (!params.src && !params.las) {