@inweb/viewer-three 26.9.1 → 26.9.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.
Files changed (32) hide show
  1. package/dist/plugins/components/AxesHelperComponent.js +8 -6
  2. package/dist/plugins/components/AxesHelperComponent.js.map +1 -1
  3. package/dist/plugins/components/AxesHelperComponent.min.js +1 -1
  4. package/dist/plugins/components/AxesHelperComponent.module.js +7 -5
  5. package/dist/plugins/components/AxesHelperComponent.module.js.map +1 -1
  6. package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
  7. package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
  8. package/dist/plugins/loaders/PotreeLoader.js +160 -0
  9. package/dist/plugins/loaders/PotreeLoader.js.map +1 -0
  10. package/dist/plugins/loaders/PotreeLoader.min.js +1 -0
  11. package/dist/plugins/loaders/PotreeLoader.module.js +68 -0
  12. package/dist/plugins/loaders/PotreeLoader.module.js.map +1 -0
  13. package/dist/viewer-three.js +41 -27
  14. package/dist/viewer-three.js.map +1 -1
  15. package/dist/viewer-three.min.js +2 -2
  16. package/dist/viewer-three.module.js +49 -31
  17. package/dist/viewer-three.module.js.map +1 -1
  18. package/lib/Viewer/Viewer.d.ts +3 -2
  19. package/package.json +6 -5
  20. package/plugins/components/AxesHelperComponent.ts +10 -6
  21. package/plugins/loaders/{IFCXCloudLoader.ts → IFCX/IFCXCloudLoader.ts} +1 -1
  22. package/plugins/loaders/{IFCXFileLoader.ts → IFCX/IFCXFileLoader.ts} +1 -1
  23. package/plugins/loaders/Potree/PotreeFileLoader.ts +106 -0
  24. package/plugins/loaders/Potree/PotreeModelImpl.ts +36 -0
  25. package/plugins/loaders/Potree/index.ts +28 -0
  26. package/src/Viewer/Viewer.ts +34 -10
  27. package/src/Viewer/components/ExtentsComponent.ts +1 -1
  28. package/src/Viewer/components/ResizeCanvasComponent.ts +1 -18
  29. package/src/Viewer/draggers/OrbitDragger.ts +9 -0
  30. package/src/Viewer/draggers/WalkDragger.ts +1 -0
  31. package/src/Viewer/helpers/WCSHelper.ts +3 -3
  32. /package/plugins/loaders/{IFCXLoader.ts → IFCX/index.ts} +0 -0
@@ -0,0 +1,68 @@
1
+ import { ModelImpl, Loader, loaders } from "@inweb/viewer-three";
2
+
3
+ import { Potree, PointColorType, PointSizeType, PointShape } from "potree-core";
4
+
5
+ class PotreeModelImpl extends ModelImpl {
6
+ getExtents(target) {
7
+ return target.union(this.pco.pcoGeometry.boundingBox);
8
+ }
9
+ }
10
+
11
+ class PotreeFileLoader extends Loader {
12
+ constructor(viewer) {
13
+ super();
14
+ this.updatePointClouds = () => {
15
+ const result = this.potree.updatePointClouds(this.pointClouds, this.viewer.camera, this.viewer.renderer);
16
+ if (result.exceededMaxLoadsToGPU || result.nodeLoadPromises.length > 0) this.viewer.update();
17
+ };
18
+ this.viewer = viewer;
19
+ this.potree = new Potree;
20
+ this.pointClouds = [];
21
+ this.viewer.addEventListener("render", this.updatePointClouds);
22
+ this.viewer.addEventListener("changecamera", this.updatePointClouds);
23
+ }
24
+ dispose() {
25
+ this.pointClouds.forEach((pco => pco.dispose()));
26
+ this.viewer.removeEventListener("render", this.updatePointClouds);
27
+ this.viewer.removeEventListener("changecamera", this.updatePointClouds);
28
+ }
29
+ isSupport(file, format) {
30
+ return typeof file === "string" && /(cloud.js|metadata.json)$/i.test(file);
31
+ }
32
+ async load(file, format, params = {}) {
33
+ const path = (params.path || "") + file;
34
+ const index = path.lastIndexOf("/");
35
+ const baseUrl = path.slice(0, index + 1);
36
+ const url = path.slice(index + 1);
37
+ const pco = await this.potree.loadPointCloud(url, baseUrl);
38
+ pco.material.size = 1;
39
+ pco.material.shape = 2;
40
+ pco.material.inputColorEncoding = 1;
41
+ pco.material.outputColorEncoding = 1;
42
+ pco.material.pointColorType = PointColorType.RGB;
43
+ pco.material.pointSizeType = PointSizeType.ADAPTIVE;
44
+ pco.material.shape = PointShape.CIRCLE;
45
+ if (params.position) pco.position.copy(params.position);
46
+ if (params.rotation) pco.rotation.copy(params.rotation);
47
+ if (params.scale) pco.scale.copy(params.scale);
48
+ this.pointClouds.push(pco);
49
+ const modelImpl = new PotreeModelImpl(pco);
50
+ modelImpl.loader = this;
51
+ modelImpl.viewer = this.viewer;
52
+ modelImpl.pco = pco;
53
+ this.viewer.scene.add(pco);
54
+ this.viewer.models.push(modelImpl);
55
+ this.viewer.syncOptions();
56
+ this.viewer.syncOverlay();
57
+ this.viewer.update();
58
+ this.viewer.emitEvent({
59
+ type: "databasechunk",
60
+ data: pco,
61
+ file: file
62
+ });
63
+ return this;
64
+ }
65
+ }
66
+
67
+ loaders.registerLoader("potree-file", (viewer => new PotreeFileLoader(viewer)));
68
+ //# sourceMappingURL=PotreeLoader.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PotreeLoader.module.js","sources":["../../../plugins/loaders/Potree/PotreeModelImpl.ts","../../../plugins/loaders/Potree/PotreeFileLoader.ts","../../../plugins/loaders/Potree/index.ts"],"sourcesContent":["///////////////////////////////////////////////////////////////////////////////\n// Copyright (C) 2002-2025, Open Design Alliance (the \"Alliance\").\n// All rights reserved.\n//\n// This software and its documentation and related materials are owned by\n// the Alliance. The software may only be incorporated into application\n// programs owned by members of the Alliance, subject to a signed\n// Membership Agreement and Supplemental Software License Agreement with the\n// Alliance. The structure and organization of this software are the valuable\n// trade secrets of the Alliance and its suppliers. The software is also\n// protected by copyright law and international treaty provisions. Application\n// programs incorporating this software must include the following statement\n// with their copyright notices:\n//\n// This application incorporates Open Design Alliance software pursuant to a\n// license agreement with Open Design Alliance.\n// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.\n// All rights reserved.\n//\n// By use of this software, its documentation or related materials, you\n// acknowledge and accept the above terms.\n///////////////////////////////////////////////////////////////////////////////\n\nimport { Box3 } from \"three\";\nimport { PointCloudOctree } from \"potree-core\";\nimport { ModelImpl } from \"@inweb/viewer-three\";\n\n// Potree model implementation.\n\nexport class PotreeModelImpl extends ModelImpl {\n public pco: PointCloudOctree;\n\n override getExtents(target: Box3): Box3 {\n return target.union(this.pco.pcoGeometry.boundingBox);\n }\n}\n","///////////////////////////////////////////////////////////////////////////////\n// Copyright (C) 2002-2025, Open Design Alliance (the \"Alliance\").\n// All rights reserved.\n//\n// This software and its documentation and related materials are owned by\n// the Alliance. The software may only be incorporated into application\n// programs owned by members of the Alliance, subject to a signed\n// Membership Agreement and Supplemental Software License Agreement with the\n// Alliance. The structure and organization of this software are the valuable\n// trade secrets of the Alliance and its suppliers. The software is also\n// protected by copyright law and international treaty provisions. Application\n// programs incorporating this software must include the following statement\n// with their copyright notices:\n//\n// This application incorporates Open Design Alliance software pursuant to a\n// license agreement with Open Design Alliance.\n// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.\n// All rights reserved.\n//\n// By use of this software, its documentation or related materials, you\n// acknowledge and accept the above terms.\n///////////////////////////////////////////////////////////////////////////////\n\nimport { Euler, Vector3 } from \"three\";\nimport { PointColorType, PointCloudOctree, PointSizeType, PointShape, Potree } from \"potree-core\";\nimport { Loader, Viewer } from \"@inweb/viewer-three\";\n\nimport { PotreeModelImpl } from \"./PotreeModelImpl\";\n\nexport type PotreeLoadParams = {\n path?: string;\n position?: Vector3;\n rotation?: Euler;\n scale?: Vector3;\n};\n\nexport class PotreeFileLoader extends Loader {\n public viewer: Viewer;\n public potree: Potree;\n public pointClouds: PointCloudOctree[];\n\n constructor(viewer: Viewer) {\n super();\n this.viewer = viewer;\n\n this.potree = new Potree();\n this.pointClouds = [];\n\n this.viewer.addEventListener(\"render\", this.updatePointClouds);\n this.viewer.addEventListener(\"changecamera\", this.updatePointClouds);\n }\n\n override dispose() {\n this.pointClouds.forEach((pco) => pco.dispose());\n\n this.viewer.removeEventListener(\"render\", this.updatePointClouds);\n this.viewer.removeEventListener(\"changecamera\", this.updatePointClouds);\n }\n\n override isSupport(file: any, format?: string): boolean {\n return typeof file === \"string\" && /(cloud.js|metadata.json)$/i.test(file);\n }\n\n override async load(file: any, format?: string, params: PotreeLoadParams = {}): Promise<this> {\n const path = (params.path || \"\") + file;\n const index = path.lastIndexOf(\"/\");\n const baseUrl = path.slice(0, index + 1);\n const url = path.slice(index + 1);\n\n const pco = await this.potree.loadPointCloud(url, baseUrl);\n pco.material.size = 1.0;\n pco.material.shape = 2;\n pco.material.inputColorEncoding = 1;\n pco.material.outputColorEncoding = 1;\n pco.material.pointColorType = PointColorType.RGB; // RGB | DEPTH | HEIGHT | POINT_INDEX | LOD | CLASSIFICATION\n pco.material.pointSizeType = PointSizeType.ADAPTIVE; // ADAPTIVE | FIXED\n pco.material.shape = PointShape.CIRCLE; // CIRCLE | SQUARE\n\n if (params.position) pco.position.copy(params.position);\n if (params.rotation) pco.rotation.copy(params.rotation);\n if (params.scale) pco.scale.copy(params.scale);\n\n this.pointClouds.push(pco);\n\n const modelImpl = new PotreeModelImpl(pco);\n modelImpl.loader = this;\n modelImpl.viewer = this.viewer;\n modelImpl.pco = pco;\n\n this.viewer.scene.add(pco);\n this.viewer.models.push(modelImpl);\n\n this.viewer.syncOptions();\n this.viewer.syncOverlay();\n this.viewer.update();\n\n this.viewer.emitEvent({ type: \"databasechunk\", data: pco, file });\n\n return this;\n }\n\n updatePointClouds = () => {\n const result = this.potree.updatePointClouds(this.pointClouds, this.viewer.camera, this.viewer.renderer);\n if (result.exceededMaxLoadsToGPU || result.nodeLoadPromises.length > 0) this.viewer.update();\n };\n}\n","///////////////////////////////////////////////////////////////////////////////\n// Copyright (C) 2002-2025, Open Design Alliance (the \"Alliance\").\n// All rights reserved.\n//\n// This software and its documentation and related materials are owned by\n// the Alliance. The software may only be incorporated into application\n// programs owned by members of the Alliance, subject to a signed\n// Membership Agreement and Supplemental Software License Agreement with the\n// Alliance. The structure and organization of this software are the valuable\n// trade secrets of the Alliance and its suppliers. The software is also\n// protected by copyright law and international treaty provisions. Application\n// programs incorporating this software must include the following statement\n// with their copyright notices:\n//\n// This application incorporates Open Design Alliance software pursuant to a\n// license agreement with Open Design Alliance.\n// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.\n// All rights reserved.\n//\n// By use of this software, its documentation or related materials, you\n// acknowledge and accept the above terms.\n///////////////////////////////////////////////////////////////////////////////\n\nimport { loaders } from \"@inweb/viewer-three\";\n\nimport { PotreeFileLoader } from \"./PotreeFileLoader\";\n\nloaders.registerLoader(\"potree-file\", (viewer: any) => new PotreeFileLoader(viewer));\n"],"names":["PotreeModelImpl","ModelImpl","getExtents","target","union","this","pco","pcoGeometry","boundingBox","PotreeFileLoader","Loader","constructor","viewer","super","updatePointClouds","result","potree","pointClouds","camera","renderer","exceededMaxLoadsToGPU","nodeLoadPromises","length","update","Potree","addEventListener","dispose","forEach","removeEventListener","isSupport","file","format","test","load","params","path","index","lastIndexOf","baseUrl","slice","url","loadPointCloud","material","size","shape","inputColorEncoding","outputColorEncoding","pointColorType","PointColorType","RGB","pointSizeType","PointSizeType","ADAPTIVE","PointShape","CIRCLE","position","copy","rotation","scale","push","modelImpl","loader","scene","add","models","syncOptions","syncOverlay","emitEvent","type","data","loaders","registerLoader"],"mappings":";;;;AA6BM,MAAOA,wBAAwBC;IAG1B,UAAAC,CAAWC;QAClB,OAAOA,OAAOC,MAAMC,KAAKC,IAAIC,YAAYC;;;;ACGvC,MAAOC,yBAAyBC;IAKpC,WAAAC,CAAYC;QACVC;QA2DFR,KAAiBS,oBAAG;YAClB,MAAMC,SAASV,KAAKW,OAAOF,kBAAkBT,KAAKY,aAAaZ,KAAKO,OAAOM,QAAQb,KAAKO,OAAOO;YAC/F,IAAIJ,OAAOK,yBAAyBL,OAAOM,iBAAiBC,SAAS,GAAGjB,KAAKO,OAAOW;AAAQ;QA5D5FlB,KAAKO,SAASA;QAEdP,KAAKW,SAAS,IAAIQ;QAClBnB,KAAKY,cAAc;QAEnBZ,KAAKO,OAAOa,iBAAiB,UAAUpB,KAAKS;QAC5CT,KAAKO,OAAOa,iBAAiB,gBAAgBpB,KAAKS;;IAG3C,OAAAY;QACPrB,KAAKY,YAAYU,SAASrB,OAAQA,IAAIoB;QAEtCrB,KAAKO,OAAOgB,oBAAoB,UAAUvB,KAAKS;QAC/CT,KAAKO,OAAOgB,oBAAoB,gBAAgBvB,KAAKS;;IAG9C,SAAAe,CAAUC,MAAWC;QAC5B,cAAcD,SAAS,YAAY,6BAA6BE,KAAKF;;IAG9D,UAAMG,CAAKH,MAAWC,QAAiBG,SAA2B,CAAA;QACzE,MAAMC,QAAQD,OAAOC,QAAQ,MAAML;QACnC,MAAMM,QAAQD,KAAKE,YAAY;QAC/B,MAAMC,UAAUH,KAAKI,MAAM,GAAGH,QAAQ;QACtC,MAAMI,MAAML,KAAKI,MAAMH,QAAQ;QAE/B,MAAM9B,YAAYD,KAAKW,OAAOyB,eAAeD,KAAKF;QAClDhC,IAAIoC,SAASC,OAAO;QACpBrC,IAAIoC,SAASE,QAAQ;QACrBtC,IAAIoC,SAASG,qBAAqB;QAClCvC,IAAIoC,SAASI,sBAAsB;QACnCxC,IAAIoC,SAASK,iBAAiBC,eAAeC;QAC7C3C,IAAIoC,SAASQ,gBAAgBC,cAAcC;QAC3C9C,IAAIoC,SAASE,QAAQS,WAAWC;QAEhC,IAAIpB,OAAOqB,UAAUjD,IAAIiD,SAASC,KAAKtB,OAAOqB;QAC9C,IAAIrB,OAAOuB,UAAUnD,IAAImD,SAASD,KAAKtB,OAAOuB;QAC9C,IAAIvB,OAAOwB,OAAOpD,IAAIoD,MAAMF,KAAKtB,OAAOwB;QAExCrD,KAAKY,YAAY0C,KAAKrD;QAEtB,MAAMsD,YAAY,IAAI5D,gBAAgBM;QACtCsD,UAAUC,SAASxD;QACnBuD,UAAUhD,SAASP,KAAKO;QACxBgD,UAAUtD,MAAMA;QAEhBD,KAAKO,OAAOkD,MAAMC,IAAIzD;QACtBD,KAAKO,OAAOoD,OAAOL,KAAKC;QAExBvD,KAAKO,OAAOqD;QACZ5D,KAAKO,OAAOsD;QACZ7D,KAAKO,OAAOW;QAEZlB,KAAKO,OAAOuD,UAAU;YAAEC,MAAM;YAAiBC,MAAM/D;YAAKwB;;QAE1D,OAAOzB;;;;ACvEXiE,QAAQC,eAAe,gBAAgB3D,UAAgB,IAAIH,iBAAiBG"}
@@ -80902,6 +80902,12 @@ void main() {
80902
80902
  this.viewer.target.copy(this.orbit.target);
80903
80903
  this.viewer.update();
80904
80904
  switch (this.orbit.state) {
80905
+ case STATE.ROTATE:
80906
+ case STATE.TOUCH_ROTATE:
80907
+ this.viewer.emitEvent({
80908
+ type: "orbit",
80909
+ });
80910
+ break;
80905
80911
  case STATE.PAN:
80906
80912
  case STATE.TOUCH_PAN:
80907
80913
  this.viewer.emitEvent({
@@ -80921,6 +80927,7 @@ void main() {
80921
80927
  });
80922
80928
  break;
80923
80929
  }
80930
+ this.viewer.emitEvent({ type: "changecamera" });
80924
80931
  this.changed = true;
80925
80932
  };
80926
80933
  this.stopContextMenu = (event) => {
@@ -81724,6 +81731,7 @@ void main() {
81724
81731
  };
81725
81732
  this.controlsChange = () => {
81726
81733
  this.viewer.update();
81734
+ this.viewer.emitEvent({ type: "changecamera" });
81727
81735
  };
81728
81736
  this.walkspeedChange = (event) => {
81729
81737
  this.viewer.emitEvent(event);
@@ -82805,7 +82813,7 @@ void main() {
82805
82813
  const extents = new Box3();
82806
82814
  this.viewer.models.forEach((model) => model.getExtents(extents));
82807
82815
  this.viewer.extents.copy(extents);
82808
- extents.getCenter(this.viewer.target);
82816
+ this.viewer.extents.getCenter(this.viewer.target);
82809
82817
  };
82810
82818
  this.viewer = viewer;
82811
82819
  this.viewer.addEventListener("databasechunk", this.syncExtents);
@@ -82972,21 +82980,7 @@ void main() {
82972
82980
  const { width, height } = entries[0].contentRect;
82973
82981
  if (!width || !height)
82974
82982
  return; // <- invisible viewer, or viewer with parent removed
82975
- const camera = this.viewer.camera;
82976
- const aspect = width / height;
82977
- if (camera.isPerspectiveCamera) {
82978
- camera.aspect = aspect;
82979
- camera.updateProjectionMatrix();
82980
- }
82981
- if (camera.isOrthographicCamera) {
82982
- camera.left = camera.bottom * aspect;
82983
- camera.right = camera.top * aspect;
82984
- camera.updateProjectionMatrix();
82985
- }
82986
- this.viewer.renderer.setSize(width, height, true);
82987
- this.viewer.composer.setSize(width, height);
82988
- this.viewer.update(true);
82989
- this.viewer.emitEvent({ type: "resize", width, height });
82983
+ this.viewer.setSize(width, height);
82990
82984
  };
82991
82985
  this.viewer = viewer;
82992
82986
  this.resizeObserver = new ResizeObserver(this.resizeViewer);
@@ -84466,9 +84460,9 @@ void main() {
84466
84460
  this.size = 160;
84467
84461
  this.orthoCamera = new OrthographicCamera(-2, 2, 2, -2, 0, 4);
84468
84462
  this.orthoCamera.position.set(0, 0, 2);
84469
- const matRed = new MeshBasicMaterial({ toneMapped: false, color: "#aa0000" });
84470
- const matGreen = new MeshBasicMaterial({ toneMapped: false, color: "#00aa00" });
84471
- const matBlue = new MeshBasicMaterial({ toneMapped: false, color: "#0000aa" });
84463
+ const matRed = new MeshBasicMaterial({ toneMapped: false, color: "#dd0000" });
84464
+ const matGreen = new MeshBasicMaterial({ toneMapped: false, color: "#00dd00" });
84465
+ const matBlue = new MeshBasicMaterial({ toneMapped: false, color: "#0000dd" });
84472
84466
  const spriteRed = this.getSpriteMaterial(matRed.color, "X");
84473
84467
  const spriteGreen = this.getSpriteMaterial(matGreen.color, "Y");
84474
84468
  const spriteBlue = this.getSpriteMaterial(matBlue.color, "Z");
@@ -109793,7 +109787,7 @@ void main() {
109793
109787
  this.target = new Vector3();
109794
109788
  this._activeDragger = null;
109795
109789
  this._components = [];
109796
- this.renderTime = 0;
109790
+ this._renderTime = 0;
109797
109791
  this.render = this.render.bind(this);
109798
109792
  this.update = this.update.bind(this);
109799
109793
  this._markup = new KonvaMarkup();
@@ -109857,6 +109851,7 @@ void main() {
109857
109851
  this.composer.addPass(this.fxaaPass);
109858
109852
  this.composer.addPass(this.ssaaRenderPass);
109859
109853
  this.composer.addPass(this.outputPass);
109854
+ this.composer.setSize(width, height);
109860
109855
  this.canvas = canvas;
109861
109856
  this.canvasEvents.forEach((x) => canvas.addEventListener(x, this.canvaseventlistener));
109862
109857
  this._markup.initialize(this.canvas, this.canvasEvents, this, this);
@@ -109865,8 +109860,8 @@ void main() {
109865
109860
  }
109866
109861
  this.syncOptions();
109867
109862
  this.syncOverlay();
109868
- this.renderTime = performance.now();
109869
- this.render(this.renderTime);
109863
+ this._renderTime = performance.now();
109864
+ this.render(this._renderTime);
109870
109865
  if (typeof onProgress === "function")
109871
109866
  onProgress(new ProgressEvent("progress", { lengthComputable: true, loaded: 1, total: 1 }));
109872
109867
  this.emitEvent({ type: "initializeprogress", data: 1, loaded: 1, total: 1 });
@@ -109918,8 +109913,27 @@ void main() {
109918
109913
  isInitialized() {
109919
109914
  return !!this.renderer;
109920
109915
  }
109916
+ setSize(width, height, updateStyle = true) {
109917
+ if (!this.renderer)
109918
+ return;
109919
+ const camera = this.camera;
109920
+ const aspect = width / height;
109921
+ if (camera.isPerspectiveCamera) {
109922
+ camera.aspect = aspect;
109923
+ camera.updateProjectionMatrix();
109924
+ }
109925
+ if (camera.isOrthographicCamera) {
109926
+ camera.left = camera.bottom * aspect;
109927
+ camera.right = camera.top * aspect;
109928
+ camera.updateProjectionMatrix();
109929
+ }
109930
+ this.renderer.setSize(width, height, updateStyle);
109931
+ this.composer.setSize(width, height);
109932
+ this.update(true);
109933
+ this.emitEvent({ type: "resize", width, height });
109934
+ }
109921
109935
  update(force = false) {
109922
- this.renderNeeded = true;
109936
+ this._renderNeeded = true;
109923
109937
  if (force)
109924
109938
  this.render();
109925
109939
  this.emitEvent({ type: "update", data: force });
@@ -109928,13 +109942,13 @@ void main() {
109928
109942
  var _a, _b;
109929
109943
  if (!this.renderer)
109930
109944
  return;
109931
- if (!(this.renderNeeded || force))
109945
+ if (!this._renderNeeded && !force)
109932
109946
  return;
109933
109947
  if (!time)
109934
109948
  time = performance.now();
109935
- const deltaTime = (time - this.renderTime) / 1000;
109936
- this.renderTime = time;
109937
- this.renderNeeded = false;
109949
+ const deltaTime = (time - this._renderTime) / 1000;
109950
+ this._renderTime = time;
109951
+ this._renderNeeded = false;
109938
109952
  if (this.options.antialiasing === true || this.options.antialiasing === "msaa") {
109939
109953
  this.renderer.render(this.scene, this.camera);
109940
109954
  this.renderer.render(this.helpers, this.camera);