@inweb/viewer-three 26.8.1 → 26.8.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 (49) hide show
  1. package/dist/plugins/components/RoomEnvironmentComponent.js +75 -40
  2. package/dist/plugins/components/RoomEnvironmentComponent.js.map +1 -1
  3. package/dist/plugins/components/RoomEnvironmentComponent.min.js +1 -1
  4. package/dist/plugins/components/StatsPanelComponent.js +1 -1
  5. package/dist/plugins/components/StatsPanelComponent.js.map +1 -1
  6. package/dist/plugins/components/StatsPanelComponent.min.js +1 -1
  7. package/dist/plugins/components/StatsPanelComponent.module.js +1 -1
  8. package/dist/plugins/components/StatsPanelComponent.module.js.map +1 -1
  9. package/dist/plugins/loaders/GLTFCloudLoader.js +225 -94
  10. package/dist/plugins/loaders/GLTFCloudLoader.js.map +1 -1
  11. package/dist/plugins/loaders/GLTFCloudLoader.min.js +1 -1
  12. package/dist/plugins/loaders/IFCXLoader.js +169 -19
  13. package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
  14. package/dist/plugins/loaders/IFCXLoader.min.js +1 -1
  15. package/dist/viewer-three.js +31141 -5500
  16. package/dist/viewer-three.js.map +1 -1
  17. package/dist/viewer-three.min.js +3 -3
  18. package/dist/viewer-three.module.js +402 -295
  19. package/dist/viewer-three.module.js.map +1 -1
  20. package/lib/Viewer/Viewer.d.ts +17 -3
  21. package/lib/Viewer/commands/SetDefaultViewPosition.d.ts +6 -6
  22. package/lib/Viewer/components/HighlighterComponent.d.ts +5 -4
  23. package/lib/Viewer/components/SelectionComponent.d.ts +1 -1
  24. package/lib/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.d.ts +3 -1
  25. package/lib/Viewer/models/IModelImpl.d.ts +27 -0
  26. package/lib/Viewer/models/ModelImpl.d.ts +27 -0
  27. package/lib/Viewer/scenes/Helpers.d.ts +7 -0
  28. package/lib/index.d.ts +2 -1
  29. package/package.json +9 -9
  30. package/plugins/components/StatsPanelComponent.ts +1 -1
  31. package/src/Viewer/Viewer.ts +124 -48
  32. package/src/Viewer/commands/SetDefaultViewPosition.ts +8 -8
  33. package/src/Viewer/components/CameraComponent.ts +20 -16
  34. package/src/Viewer/components/ExtentsComponent.ts +1 -0
  35. package/src/Viewer/components/HighlighterComponent.ts +78 -80
  36. package/src/Viewer/components/LightComponent.ts +1 -1
  37. package/src/Viewer/components/ResizeCanvasComponent.ts +1 -0
  38. package/src/Viewer/components/SelectionComponent.ts +1 -1
  39. package/src/Viewer/helpers/WCSHelper.ts +8 -5
  40. package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +33 -16
  41. package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +12 -5
  42. package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +100 -20
  43. package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +4 -2
  44. package/src/Viewer/loaders/GLTFFileLoader.ts +1 -1
  45. package/src/Viewer/models/IModelImpl.ts +67 -0
  46. package/src/Viewer/models/ModelImpl.ts +214 -0
  47. package/src/Viewer/postprocessing/SSAARenderPass.js +245 -0
  48. package/src/Viewer/scenes/Helpers.ts +42 -0
  49. package/src/index.ts +2 -1
@@ -22,7 +22,6 @@
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
24
  import {
25
- Color,
26
25
  EdgesGeometry,
27
26
  LineBasicMaterial,
28
27
  MeshPhongMaterial,
@@ -43,10 +42,10 @@ import { HighlighterUtils } from "./HighlighterUtils";
43
42
  export class HighlighterComponent implements IComponent {
44
43
  protected viewer: Viewer;
45
44
  public renderTarget: WebGLRenderTarget;
46
- public highlightMaterial: MeshPhongMaterial;
47
- public outlineMaterial: LineMaterial;
48
- public highlightLineMaterial: LineBasicMaterial;
49
- public highlightLineGlowMaterial: LineMaterial;
45
+ public facesMaterial: MeshPhongMaterial;
46
+ public edgesMaterial: LineMaterial;
47
+ public lineMaterial: LineBasicMaterial;
48
+ public lineGlowMaterial: LineMaterial;
50
49
 
51
50
  constructor(viewer: Viewer) {
52
51
  this.viewer = viewer;
@@ -81,46 +80,48 @@ export class HighlighterComponent implements IComponent {
81
80
  if (!Array.isArray(objects)) objects = [objects];
82
81
  if (!objects.length) return;
83
82
 
84
- objects.forEach((object: any) => {
85
- if (object.isHighlighted) return;
86
-
87
- if (object.isLine || object.isLineSegments) {
88
- const positions = object.geometry.attributes.position.array;
89
- const indices = object.geometry.index ? object.geometry.index.array : null;
90
- const lineGeometry = indices
91
- ? HighlighterUtils.fromIndexedLine(positions, indices)
92
- : HighlighterUtils.fromNonIndexedLine(positions, object.isLineSegments);
93
-
94
- const wireframe = new Wireframe(lineGeometry, this.highlightLineGlowMaterial);
95
- wireframe.position.copy(object.position);
96
- wireframe.rotation.copy(object.rotation);
97
- wireframe.scale.copy(object.scale);
98
- wireframe.visible = edgesVisibility;
99
-
100
- object.parent.add(wireframe);
101
- object.userData.highlightWireframe = wireframe;
102
-
103
- object.userData.originalMaterial = object.material;
104
- object.material = this.highlightLineMaterial;
105
- object.isHighlighted = true;
106
- } else if (object.isMesh) {
107
- const edgesGeometry = new EdgesGeometry(object.geometry, 60);
108
- const lineGeometry = new LineSegmentsGeometry().fromEdgesGeometry(edgesGeometry);
109
-
110
- const wireframe = new Wireframe(lineGeometry, this.outlineMaterial);
111
- wireframe.position.copy(object.position);
112
- wireframe.rotation.copy(object.rotation);
113
- wireframe.scale.copy(object.scale);
114
- wireframe.visible = edgesVisibility;
115
-
116
- object.parent.add(wireframe);
117
- object.userData.highlightWireframe = wireframe;
118
-
119
- object.userData.originalMaterial = object.material;
120
- object.material = this.highlightMaterial;
121
- object.isHighlighted = true;
122
- }
123
- });
83
+ objects
84
+ .filter((object) => !object.userData.isEdge) // <- filtering server generated edges
85
+ .forEach((object: any) => {
86
+ if (object.isHighlighted) return;
87
+
88
+ if (object.isLine || object.isLineSegments) {
89
+ const positions = object.geometry.attributes.position.array;
90
+ const indices = object.geometry.index ? object.geometry.index.array : null;
91
+ const lineGeometry = indices
92
+ ? HighlighterUtils.fromIndexedLine(positions, indices)
93
+ : HighlighterUtils.fromNonIndexedLine(positions, object.isLineSegments);
94
+
95
+ const wireframe = new Wireframe(lineGeometry, this.lineGlowMaterial);
96
+ wireframe.position.copy(object.position);
97
+ wireframe.rotation.copy(object.rotation);
98
+ wireframe.scale.copy(object.scale);
99
+ wireframe.visible = edgesVisibility;
100
+
101
+ object.parent.add(wireframe);
102
+ object.userData.highlightWireframe = wireframe;
103
+
104
+ object.userData.originalMaterial = object.material;
105
+ object.material = this.lineMaterial;
106
+ object.isHighlighted = true;
107
+ } else if (object.isMesh) {
108
+ const edgesGeometry = new EdgesGeometry(object.geometry, 89);
109
+ const lineGeometry = new LineSegmentsGeometry().fromEdgesGeometry(edgesGeometry);
110
+
111
+ const wireframe = new Wireframe(lineGeometry, this.edgesMaterial);
112
+ wireframe.position.copy(object.position);
113
+ wireframe.rotation.copy(object.rotation);
114
+ wireframe.scale.copy(object.scale);
115
+ wireframe.visible = edgesVisibility;
116
+
117
+ object.parent.add(wireframe);
118
+ object.userData.highlightWireframe = wireframe;
119
+
120
+ object.userData.originalMaterial = object.material;
121
+ object.material = this.facesMaterial;
122
+ object.isHighlighted = true;
123
+ }
124
+ });
124
125
  }
125
126
 
126
127
  unhighlight(objects: Object3D | Object3D[]) {
@@ -140,14 +141,8 @@ export class HighlighterComponent implements IComponent {
140
141
  }
141
142
 
142
143
  geometryEnd = () => {
143
- const { facesColor, facesTransparancy, edgesColor, edgesOverlap, facesOverlap } = this.viewer.options;
144
-
145
- this.highlightMaterial = new MeshPhongMaterial({
146
- color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
144
+ this.facesMaterial = new MeshPhongMaterial({
147
145
  transparent: true,
148
- opacity: (255 - facesTransparancy) / 255,
149
- depthTest: !facesOverlap,
150
- depthWrite: !facesOverlap,
151
146
  specular: 0x222222,
152
147
  shininess: 10,
153
148
  reflectivity: 0.05,
@@ -156,57 +151,60 @@ export class HighlighterComponent implements IComponent {
156
151
  polygonOffsetUnits: 1,
157
152
  });
158
153
 
159
- this.outlineMaterial = new LineMaterial({
160
- color: new Color(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255),
154
+ this.edgesMaterial = new LineMaterial({
161
155
  linewidth: 1.5,
162
- depthTest: !edgesOverlap,
163
- depthWrite: !edgesOverlap,
164
156
  resolution: new Vector2(window.innerWidth, window.innerHeight),
165
157
  });
166
158
 
167
- this.highlightLineMaterial = new LineBasicMaterial({
168
- color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
169
- depthTest: false,
170
- depthWrite: false,
159
+ this.lineMaterial = new LineBasicMaterial({
160
+ transparent: true,
161
+ depthTest: true,
162
+ depthWrite: true,
171
163
  });
172
164
 
173
- this.highlightLineGlowMaterial = new LineMaterial({
174
- color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
175
- linewidth: 5,
165
+ this.lineGlowMaterial = new LineMaterial({
166
+ linewidth: 1.5,
176
167
  transparent: true,
177
168
  opacity: 0.8,
178
- depthTest: !edgesOverlap,
179
- depthWrite: !edgesOverlap,
180
169
  resolution: new Vector2(window.innerWidth, window.innerHeight),
181
170
  });
171
+
172
+ this.syncHighlightColors();
182
173
  };
183
174
 
184
175
  optionsChange = () => {
185
- const { facesColor, facesTransparancy, edgesColor, edgesVisibility, edgesOverlap, facesOverlap } =
186
- this.viewer.options;
176
+ this.syncHighlightColors();
177
+ this.viewer.update();
178
+ };
179
+
180
+ syncHighlightColors() {
181
+ const { facesColor, facesTransparancy, facesOverlap } = this.viewer.options;
182
+ const { edgesColor, edgesVisibility, edgesOverlap } = this.viewer.options;
187
183
 
188
- this.highlightMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
189
- this.highlightMaterial.opacity = (255 - facesTransparancy) / 255;
190
- this.highlightMaterial.depthTest = !facesOverlap;
191
- this.highlightMaterial.depthWrite = !facesOverlap;
184
+ this.facesMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
185
+ this.facesMaterial.opacity = (255 - facesTransparancy) / 255;
186
+ this.facesMaterial.depthTest = !facesOverlap;
187
+ this.facesMaterial.depthWrite = !facesOverlap;
192
188
 
193
- this.outlineMaterial.color.setRGB(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255);
194
- this.outlineMaterial.depthTest = !edgesOverlap;
195
- this.outlineMaterial.depthWrite = !edgesOverlap;
189
+ this.edgesMaterial.color.setRGB(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255);
190
+ this.edgesMaterial.depthTest = !edgesOverlap;
191
+ this.edgesMaterial.depthWrite = !edgesOverlap;
196
192
 
197
- this.highlightLineMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
198
- this.highlightLineGlowMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
193
+ this.lineMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
194
+
195
+ this.lineGlowMaterial.color.setRGB(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255);
196
+ this.lineGlowMaterial.depthTest = !edgesOverlap;
197
+ this.lineGlowMaterial.depthWrite = !edgesOverlap;
199
198
 
200
199
  this.viewer.selected.forEach((selected) => {
201
200
  const wireframe = selected.userData.highlightWireframe;
202
201
  if (wireframe) wireframe.visible = edgesVisibility;
203
202
  });
204
-
205
- this.viewer.update();
206
- };
203
+ }
207
204
 
208
205
  viewerResize(event: ResizeEvent) {
209
206
  this.renderTarget?.setSize(event.width, event.height);
210
- this.outlineMaterial?.resolution.set(event.width, event.height);
207
+ this.edgesMaterial?.resolution.set(event.width, event.height);
208
+ this.lineGlowMaterial?.resolution.set(event.width, event.height);
211
209
  }
212
210
  }
@@ -36,7 +36,7 @@ export class LightComponent implements IComponent {
36
36
  constructor(viewer: Viewer) {
37
37
  this.viewer = viewer;
38
38
 
39
- this.ambientLight = new AmbientLight(0xffffff, 1.0);
39
+ this.ambientLight = new AmbientLight(0xffffff, 1.5);
40
40
  this.directionalLight = new DirectionalLight(0xffffff, 1.0);
41
41
  this.frontLight = new DirectionalLight(0xffffff, 1.25);
42
42
  this.hemisphereLight = new HemisphereLight(0xffffff, 0x444444, 1.25);
@@ -57,6 +57,7 @@ export class ResizeCanvasComponent implements IComponent {
57
57
  }
58
58
 
59
59
  this.viewer.renderer.setSize(width, height, true);
60
+ this.viewer.composer.setSize(width, height);
60
61
 
61
62
  this.viewer.update(true);
62
63
  this.viewer.emitEvent({ type: "resize", width, height });
@@ -25,7 +25,7 @@ import { Intersection, Object3D, Raycaster, Vector2 } from "three";
25
25
 
26
26
  import type { IComponent } from "@inweb/viewer-core";
27
27
  import type { Viewer } from "../Viewer";
28
- import type { IModelImpl } from "../model";
28
+ import type { IModelImpl } from "../models/IModelImpl";
29
29
  import type { HighlighterComponent } from "./HighlighterComponent";
30
30
 
31
31
  export class SelectionComponent implements IComponent {
@@ -105,15 +105,18 @@ export class WCSHelper extends Object3D {
105
105
  this.quaternion.copy(this.camera.quaternion).invert();
106
106
  this.updateMatrixWorld();
107
107
 
108
- const clippingPlanes = renderer.clippingPlanes;
109
- const viewport = renderer.getViewport(new Vector4());
108
+ const oldAutoClear = renderer.autoClear;
109
+ const oldClippingPlanes = renderer.clippingPlanes;
110
+ const oldViewport = renderer.getViewport(new Vector4());
110
111
 
111
- renderer.setViewport(this.position.x, this.position.y, this.size, this.size);
112
+ renderer.autoClear = false;
112
113
  renderer.clippingPlanes = [];
114
+ renderer.setViewport(this.position.x, this.position.y, this.size, this.size);
113
115
  renderer.clearDepth();
114
116
  renderer.render(this, this.orthoCamera);
115
117
 
116
- renderer.setViewport(viewport);
117
- renderer.clippingPlanes = clippingPlanes;
118
+ renderer.setViewport(oldViewport);
119
+ renderer.clippingPlanes = oldClippingPlanes;
120
+ renderer.autoClear = oldAutoClear;
118
121
  }
119
122
  }
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  BufferGeometry,
3
3
  PointsMaterial,
4
- Material,
5
4
  Points,
6
5
  Mesh,
7
6
  TriangleStripDrawMode,
@@ -14,7 +13,7 @@ import {
14
13
  Quaternion,
15
14
  Matrix4,
16
15
  Box3,
17
- MeshStandardMaterial,
16
+ MeshPhongMaterial,
18
17
  Color,
19
18
  MathUtils,
20
19
  PerspectiveCamera,
@@ -369,19 +368,19 @@ export class DynamicGltfLoader {
369
368
 
370
369
  let material;
371
370
  if (primitive.material !== undefined) {
372
- material = node.structure.materials.get(primitive.material) || this.createDefaultMaterial();
371
+ material = node.structure.getCachedMaterial(primitive.material, primitive.mode);
372
+
373
+ if (!material) {
374
+ const materialDef = node.structure.json.materials[primitive.material];
375
+ material = node.structure.createMaterial(materialDef, primitive.mode);
376
+ }
373
377
  } else {
374
- material = this.createDefaultMaterial();
378
+ material = this.createDefaultMaterial(primitive.mode);
375
379
  }
376
380
 
377
381
  let mesh;
378
382
  if (primitive.mode === GL_CONSTANTS.POINTS) {
379
- const pointsMaterial = new PointsMaterial();
380
- Material.prototype.copy.call(pointsMaterial, material);
381
- pointsMaterial.color.copy(material.color);
382
- pointsMaterial.map = material.map;
383
- pointsMaterial.sizeAttenuation = false;
384
- mesh = new Points(geometry, pointsMaterial);
383
+ mesh = new Points(geometry, material);
385
384
  } else if (
386
385
  primitive.mode === GL_CONSTANTS.TRIANGLES ||
387
386
  primitive.mode === GL_CONSTANTS.TRIANGLE_STRIP ||
@@ -660,6 +659,10 @@ export class DynamicGltfLoader {
660
659
  this.edgeNodes.push(uniqueNodeId);
661
660
  }
662
661
 
662
+ if (meshDef.extras && meshDef.extras.handle) {
663
+ handle = `${structure.id}_${meshDef.extras.handle}`;
664
+ }
665
+
663
666
  this.nodes.set(uniqueNodeId, {
664
667
  position: nodeGroup ? nodeGroup.position.clone() : new Vector3().setFromMatrixPosition(nodeMatrix),
665
668
  nodeIndex: nodeId,
@@ -780,12 +783,12 @@ export class DynamicGltfLoader {
780
783
  });
781
784
  }
782
785
 
783
- createDefaultMaterial() {
784
- if (this.currentPrimitiveMode === GL_CONSTANTS.POINTS) {
786
+ createDefaultMaterial(primitiveMode = undefined) {
787
+ if (primitiveMode === GL_CONSTANTS.POINTS) {
785
788
  return new PointsMaterial({
786
789
  color: new Color(0x808080),
787
790
  size: 0.05,
788
- sizeAttenuation: true,
791
+ sizeAttenuation: false,
789
792
  alphaTest: 0.5,
790
793
  transparent: true,
791
794
  vertexColors: false,
@@ -793,11 +796,25 @@ export class DynamicGltfLoader {
793
796
  depthWrite: false,
794
797
  depthTest: true,
795
798
  });
799
+ } else if (
800
+ primitiveMode === GL_CONSTANTS.LINES ||
801
+ primitiveMode === GL_CONSTANTS.LINE_STRIP ||
802
+ primitiveMode === GL_CONSTANTS.LINE_LOOP
803
+ ) {
804
+ return new LineBasicMaterial({
805
+ color: 0x808080,
806
+ linewidth: 1.0,
807
+ alphaTest: 0.1,
808
+ depthTest: true,
809
+ depthWrite: true,
810
+ transparent: true,
811
+ opacity: 1.0,
812
+ });
796
813
  } else {
797
- return new MeshStandardMaterial({
814
+ return new MeshPhongMaterial({
798
815
  color: 0x808080,
799
- metalness: 0.0,
800
- roughness: 1.0,
816
+ specular: 0x222222,
817
+ shininess: 10,
801
818
  side: DoubleSide,
802
819
  });
803
820
  }
@@ -23,13 +23,14 @@
23
23
 
24
24
  import { Box3, Object3D } from "three";
25
25
 
26
- import { ModelImpl } from "../../model";
26
+ import { ModelImpl } from "../../models/ModelImpl";
27
27
  import { DynamicGltfLoader } from "./DynamicGltfLoader.js";
28
28
 
29
29
  // Dynamic model implementation.
30
30
 
31
31
  export class DynamicModelImpl extends ModelImpl {
32
32
  public gltfLoader: DynamicGltfLoader;
33
+ public modelId: number;
33
34
 
34
35
  override getExtents(target: Box3): Box3 {
35
36
  return target.union(this.gltfLoader.getTotalGeometryExtent());
@@ -55,26 +56,32 @@ export class DynamicModelImpl extends ModelImpl {
55
56
  const handlesSet = new Set(handles);
56
57
  const objects = [];
57
58
  handlesSet.forEach((handle) => {
58
- const handles = this.gltfLoader.handleToObjects.get(handle) || [];
59
+ const handle2 = `${this.modelId}_${handle}`; // <- props fix: Dynamic Loader uses handle with structure ID prefix
60
+ const handles = this.gltfLoader.handleToObjects.get(handle2) || [];
59
61
  objects.push(...Array.from(handles));
60
62
  });
61
63
  return objects;
62
64
  }
63
65
 
66
+ override getHandlesByObjects(objects: Object3D | Object3D[]): string[] {
67
+ const handles = super.getHandlesByObjects(objects);
68
+ return handles.map((x) => x.split("_").pop()); // <- props fix: remove structure ID prefix by the Dynamic Loader
69
+ }
70
+
64
71
  override hideObjects(objects: Object3D | Object3D[]): this {
65
- const handles = this.getHandlesByObjects(objects);
72
+ const handles = super.getHandlesByObjects(objects);
66
73
  this.gltfLoader.hideObjects(handles);
67
74
  return this;
68
75
  }
69
76
 
70
77
  override isolateObjects(objects: Object3D | Object3D[]): this {
71
- const handles = this.getHandlesByObjects(objects);
78
+ const handles = super.getHandlesByObjects(objects);
72
79
  this.gltfLoader.isolateObjects(new Set(handles));
73
80
  return this;
74
81
  }
75
82
 
76
83
  override showObjects(objects: Object3D | Object3D[]): this {
77
- const handles = this.getHandlesByObjects(objects);
84
+ const handles = super.getHandlesByObjects(objects);
78
85
  this.gltfLoader.showObjects(handles);
79
86
  return this;
80
87
  }
@@ -1,4 +1,12 @@
1
- import { TextureLoader, BufferAttribute, Color, DoubleSide, MeshPhongMaterial } from "three";
1
+ import {
2
+ TextureLoader,
3
+ BufferAttribute,
4
+ Color,
5
+ DoubleSide,
6
+ MeshPhongMaterial,
7
+ PointsMaterial,
8
+ LineBasicMaterial,
9
+ } from "three";
2
10
 
3
11
  export const GL_COMPONENT_TYPES = {
4
12
  5120: Int8Array,
@@ -48,6 +56,7 @@ export class GltfStructure {
48
56
  this.textureLoader = new TextureLoader();
49
57
  this.materials = new Map();
50
58
  this.textureCache = new Map();
59
+ this.materialCache = new Map();
51
60
  }
52
61
 
53
62
  async initialize(loadController) {
@@ -346,19 +355,29 @@ export class GltfStructure {
346
355
  await Promise.all(texturePromises);
347
356
  }
348
357
 
349
- async loadMaterials() {
358
+ loadMaterials() {
350
359
  if (!this.json.materials) return this.materials;
351
360
 
352
361
  for (let i = 0; i < this.json.materials.length; i++) {
353
362
  const materialDef = this.json.materials[i];
354
- const material = await this.createMaterial(materialDef);
355
- material.name = materialDef.name;
356
- this.materials.set(i, material);
363
+
364
+ const materialCacheKey = `material_${i}`;
365
+ this.materialCache.set(materialCacheKey, {
366
+ mesh: this.createMaterial(materialDef, GL_CONSTANTS.TRIANGLES),
367
+ points: this.createMaterial(materialDef, GL_CONSTANTS.POINTS),
368
+ lines: this.createMaterial(materialDef, GL_CONSTANTS.LINES),
369
+ });
370
+
371
+ this.materialCache.get(materialCacheKey).mesh.name = materialDef.name;
372
+ this.materialCache.get(materialCacheKey).points.name = materialDef.name;
373
+ this.materialCache.get(materialCacheKey).lines.name = materialDef.name;
374
+
375
+ this.materials.set(i, this.materialCache.get(materialCacheKey).mesh);
357
376
  }
358
377
  return this.materials;
359
378
  }
360
379
 
361
- createMaterial(materialDef) {
380
+ createMaterial(materialDef, primitiveMode = undefined) {
362
381
  const params = {};
363
382
 
364
383
  if (materialDef.pbrMetallicRoughness) {
@@ -373,21 +392,10 @@ export class GltfStructure {
373
392
  }
374
393
  }
375
394
 
376
- params.specular = 0x222222;
377
- params.shininess = 10;
378
- params.reflectivity = 0.05;
379
- params.polygonOffset = true;
380
- params.polygonOffsetFactor = 1;
381
- params.polygonOffsetUnits = 1;
382
-
383
395
  if (materialDef.emissiveFactor) {
384
396
  params.emissive = new Color().fromArray(materialDef.emissiveFactor);
385
397
  }
386
398
 
387
- if (materialDef.normalTexture) {
388
- params.normalMap = this.textureCache.get(materialDef.normalTexture.index);
389
- }
390
-
391
399
  if (materialDef.alphaMode === "BLEND") {
392
400
  params.transparent = true;
393
401
  }
@@ -395,16 +403,61 @@ export class GltfStructure {
395
403
  if (materialDef.doubleSided) {
396
404
  params.side = DoubleSide;
397
405
  }
398
- const material = new MeshPhongMaterial(params);
406
+ let material;
407
+
408
+ if (primitiveMode === GL_CONSTANTS.POINTS) {
409
+ params.sizeAttenuation = false;
410
+ material = new PointsMaterial(params);
411
+ material.sizeAttenuation = false;
412
+ } else if (
413
+ primitiveMode === GL_CONSTANTS.LINES ||
414
+ primitiveMode === GL_CONSTANTS.LINE_STRIP ||
415
+ primitiveMode === GL_CONSTANTS.LINE_LOOP
416
+ ) {
417
+ material = new LineBasicMaterial(params);
418
+ } else {
419
+ params.specular = 0x222222;
420
+ params.shininess = 10;
421
+ params.reflectivity = 0.05;
422
+ params.polygonOffset = true;
423
+ params.polygonOffsetFactor = 1;
424
+ params.polygonOffsetUnits = 1;
425
+
426
+ if (materialDef.normalTexture) {
427
+ params.normalMap = this.textureCache.get(materialDef.normalTexture.index);
428
+ }
429
+
430
+ material = new MeshPhongMaterial(params);
431
+ }
432
+
399
433
  return material;
400
434
  }
401
435
 
436
+ getCachedMaterial(materialIndex, primitiveMode) {
437
+ const materialCacheKey = `material_${materialIndex}`;
438
+ const materialCache = this.materialCache.get(materialCacheKey);
439
+
440
+ if (materialCache) {
441
+ if (primitiveMode === GL_CONSTANTS.POINTS) {
442
+ return materialCache.points;
443
+ } else if (
444
+ primitiveMode === GL_CONSTANTS.LINES ||
445
+ primitiveMode === GL_CONSTANTS.LINE_STRIP ||
446
+ primitiveMode === GL_CONSTANTS.LINE_LOOP
447
+ ) {
448
+ return materialCache.lines;
449
+ } else {
450
+ return materialCache.mesh;
451
+ }
452
+ }
453
+
454
+ return null;
455
+ }
456
+
402
457
  disposeMaterials() {
403
- // Dispose all textures
404
458
  this.textureCache.forEach((texture) => texture.dispose());
405
459
  this.textureCache.clear();
406
460
 
407
- // Dispose all materials
408
461
  this.materials.forEach((material) => {
409
462
  if (material.map) material.map.dispose();
410
463
  if (material.lightMap) material.lightMap.dispose();
@@ -419,6 +472,33 @@ export class GltfStructure {
419
472
  material.dispose();
420
473
  });
421
474
  this.materials.clear();
475
+
476
+ this.materialCache.forEach((materialCache) => {
477
+ if (materialCache.mesh) {
478
+ if (materialCache.mesh.map) materialCache.mesh.map.dispose();
479
+ if (materialCache.mesh.lightMap) materialCache.mesh.lightMap.dispose();
480
+ if (materialCache.mesh.bumpMap) materialCache.mesh.bumpMap.dispose();
481
+ if (materialCache.mesh.normalMap) materialCache.mesh.normalMap.dispose();
482
+ if (materialCache.mesh.specularMap) materialCache.mesh.specularMap.dispose();
483
+ if (materialCache.mesh.envMap) materialCache.mesh.envMap.dispose();
484
+ if (materialCache.mesh.aoMap) materialCache.mesh.aoMap.dispose();
485
+ if (materialCache.mesh.metalnessMap) materialCache.mesh.metalnessMap.dispose();
486
+ if (materialCache.mesh.roughnessMap) materialCache.mesh.roughnessMap.dispose();
487
+ if (materialCache.mesh.emissiveMap) materialCache.mesh.emissiveMap.dispose();
488
+ materialCache.mesh.dispose();
489
+ }
490
+
491
+ if (materialCache.points) {
492
+ if (materialCache.points.map) materialCache.points.map.dispose();
493
+ materialCache.points.dispose();
494
+ }
495
+
496
+ if (materialCache.lines) {
497
+ if (materialCache.lines.map) materialCache.lines.map.dispose();
498
+ materialCache.lines.dispose();
499
+ }
500
+ });
501
+ this.materialCache.clear();
422
502
  }
423
503
 
424
504
  estimateNodeSize(meshIndex) {
@@ -57,12 +57,14 @@ export class GLTFCloudDynamicLoader implements ILoader {
57
57
 
58
58
  this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
59
59
  this.gltfLoader.memoryLimit = this.viewer.options.memoryLimit;
60
+ this.gltfLoader.setVisibleEdges(this.viewer.options.edgeModel);
60
61
 
61
62
  this.gltfLoader.addEventListener("databasechunk", (data) => {
62
63
  const modelImpl = new DynamicModelImpl(scene);
63
64
  modelImpl.loader = this;
64
- modelImpl.gltfLoader = this.gltfLoader;
65
65
  modelImpl.viewer = this.viewer;
66
+ modelImpl.gltfLoader = this.gltfLoader;
67
+ modelImpl.modelId = model.id;
66
68
 
67
69
  this.viewer.scene.add(scene);
68
70
  this.viewer.models.push(modelImpl);
@@ -124,7 +126,7 @@ export class GLTFCloudDynamicLoader implements ILoader {
124
126
  baseUrl: () => Promise.resolve(`${model.httpClient.serverUrl}${model.path}/`),
125
127
  };
126
128
 
127
- const structure = new GltfStructure(1);
129
+ const structure = new GltfStructure(model.id);
128
130
  await structure.initialize(loadController);
129
131
 
130
132
  await this.gltfLoader.loadStructure(structure);
@@ -26,7 +26,7 @@ import { Loader } from "@inweb/viewer-core";
26
26
 
27
27
  import { Viewer } from "../Viewer";
28
28
  import { GLTFLoadingManager, GLTFLoadParams } from "./GLTFLoadingManager";
29
- import { ModelImpl } from "../model/ModelImpl";
29
+ import { ModelImpl } from "../models/ModelImpl";
30
30
 
31
31
  export class GLTFFileLoader extends Loader {
32
32
  public viewer: Viewer;