@inweb/viewer-three 26.7.6 → 26.8.1
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/plugins/loaders/IFCXLoader.js +1827 -881
- package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
- package/dist/plugins/loaders/IFCXLoader.min.js +1 -1
- package/dist/plugins/loaders/IFCXLoader.module.js +477 -154
- package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
- package/dist/viewer-three.js +372 -230
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +4 -2
- package/dist/viewer-three.module.js +336 -159
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/components/HighlighterComponent.d.ts +2 -2
- package/lib/Viewer/loaders/GLTFCloudDynamicLoader.d.ts +0 -2
- package/lib/Viewer/loaders/index.d.ts +1 -1
- package/package.json +5 -5
- package/plugins/loaders/IFCX/IFCXLoader.ts +4 -7
- package/plugins/loaders/IFCX/render.js +686 -181
- package/plugins/loaders/IFCXCloudLoader.ts +1 -1
- package/src/Viewer/commands/SetSelected.ts +1 -0
- package/src/Viewer/commands/index.ts +1 -1
- package/src/Viewer/components/HighlighterComponent.ts +38 -16
- package/src/Viewer/components/LightComponent.ts +17 -15
- package/src/Viewer/components/SelectionComponent.ts +1 -2
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +187 -65
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +7 -12
- package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +120 -114
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +7 -13
- package/src/Viewer/loaders/index.ts +1 -1
|
@@ -2,7 +2,7 @@ import { draggersRegistry, commandsRegistry, componentsRegistry, Loader, loaders
|
|
|
2
2
|
|
|
3
3
|
export * from "@inweb/viewer-core";
|
|
4
4
|
|
|
5
|
-
import { Line, Vector3, BufferGeometry, Float32BufferAttribute, LineBasicMaterial, Mesh, MeshBasicMaterial, DoubleSide, EventDispatcher, MOUSE, TOUCH, Spherical, Quaternion, Vector2, Plane, Object3D, Matrix4, Vector4, Raycaster, Controls, Clock, Sphere, MathUtils, Box3, Color, AmbientLight, DirectionalLight, HemisphereLight, WebGLRenderTarget, UnsignedByteType, RGBAFormat, EdgesGeometry, OrthographicCamera, CylinderGeometry, Sprite, CanvasTexture, SRGBColorSpace, SpriteMaterial, LoadingManager, LoaderUtils, TextureLoader, BufferAttribute,
|
|
5
|
+
import { Line, Vector3, BufferGeometry, Float32BufferAttribute, LineBasicMaterial, Mesh, MeshBasicMaterial, DoubleSide, EventDispatcher, MOUSE, TOUCH, Spherical, Quaternion, Vector2, Plane, Object3D, Matrix4, Vector4, Raycaster, Controls, Clock, Sphere, MathUtils, Box3, Color, AmbientLight, DirectionalLight, HemisphereLight, MeshPhongMaterial, WebGLRenderTarget, UnsignedByteType, RGBAFormat, EdgesGeometry, OrthographicCamera, CylinderGeometry, Sprite, CanvasTexture, SRGBColorSpace, SpriteMaterial, LoadingManager, LoaderUtils, TextureLoader, BufferAttribute, PointsMaterial, Material, Points, TriangleStripDrawMode, TriangleFanDrawMode, LineSegments, LineLoop, Group, NormalBlending, MeshStandardMaterial, PerspectiveCamera, Scene, WebGLRenderer, LinearToneMapping } from "three";
|
|
6
6
|
|
|
7
7
|
import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
|
|
8
8
|
|
|
@@ -1676,6 +1676,7 @@ function setSelected(viewer, handles = []) {
|
|
|
1676
1676
|
selection.clearSelection();
|
|
1677
1677
|
viewer.models.forEach((model => {
|
|
1678
1678
|
const objects = model.getObjectsByHandles(handles);
|
|
1679
|
+
model.showObjects(objects);
|
|
1679
1680
|
selection.select(objects, model);
|
|
1680
1681
|
}));
|
|
1681
1682
|
viewer.update();
|
|
@@ -1729,12 +1730,12 @@ commands.registerCommand("clearSelected", clearSelected);
|
|
|
1729
1730
|
|
|
1730
1731
|
commands.registerCommand("clearSlices", clearSlices);
|
|
1731
1732
|
|
|
1733
|
+
commands.registerCommand("collect", collect);
|
|
1734
|
+
|
|
1732
1735
|
commands.registerCommand("createPreview", createPreview);
|
|
1733
1736
|
|
|
1734
1737
|
commands.registerCommand("explode", explode);
|
|
1735
1738
|
|
|
1736
|
-
commands.registerCommand("collect", collect);
|
|
1737
|
-
|
|
1738
1739
|
commands.registerCommand("getDefaultViewPositions", getDefaultViewPositions);
|
|
1739
1740
|
|
|
1740
1741
|
commands.registerCommand("getModels", getModels);
|
|
@@ -1910,11 +1911,12 @@ class LightComponent {
|
|
|
1910
1911
|
if (this.viewer.extents.isEmpty()) return;
|
|
1911
1912
|
const extentsCenter = this.viewer.extents.getCenter(new Vector3);
|
|
1912
1913
|
const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere).radius;
|
|
1913
|
-
this.
|
|
1914
|
+
const front = (new Vector3).copy(this.viewer.camera.up).cross(new Vector3(1, 0, 0)).negate();
|
|
1915
|
+
this.directionalLight.position.copy(this.viewer.camera.up).applyAxisAngle(front, -Math.PI * 30 / 180).multiplyScalar(extentsSize * 2).add(extentsCenter);
|
|
1914
1916
|
this.directionalLight.target.position.copy(extentsCenter);
|
|
1915
|
-
this.frontLight.position.
|
|
1917
|
+
this.frontLight.position.copy(front).multiplyScalar(extentsSize * 2).add(extentsCenter);
|
|
1916
1918
|
this.frontLight.target.position.copy(extentsCenter);
|
|
1917
|
-
this.hemisphereLight.position.
|
|
1919
|
+
this.hemisphereLight.position.copy(front).multiplyScalar(extentsSize * 3).add(extentsCenter);
|
|
1918
1920
|
this.viewer.scene.add(this.ambientLight);
|
|
1919
1921
|
this.viewer.scene.add(this.directionalLight);
|
|
1920
1922
|
this.viewer.scene.add(this.frontLight);
|
|
@@ -1922,16 +1924,9 @@ class LightComponent {
|
|
|
1922
1924
|
};
|
|
1923
1925
|
this.viewer = viewer;
|
|
1924
1926
|
this.ambientLight = new AmbientLight(16777215, 1);
|
|
1925
|
-
this.viewer.scene.add(this.ambientLight);
|
|
1926
1927
|
this.directionalLight = new DirectionalLight(16777215, 1);
|
|
1927
|
-
this.directionalLight.position.set(.5, 0, .866);
|
|
1928
|
-
this.viewer.scene.add(this.directionalLight);
|
|
1929
1928
|
this.frontLight = new DirectionalLight(16777215, 1.25);
|
|
1930
|
-
this.frontLight.position.set(0, 1, 0);
|
|
1931
|
-
this.viewer.scene.add(this.frontLight);
|
|
1932
1929
|
this.hemisphereLight = new HemisphereLight(16777215, 4473924, 1.25);
|
|
1933
|
-
this.hemisphereLight.position.set(0, 0, 1);
|
|
1934
|
-
this.viewer.scene.add(this.hemisphereLight);
|
|
1935
1930
|
this.viewer.addEventListener("databasechunk", this.geometryEnd);
|
|
1936
1931
|
this.viewer.addEventListener("clear", this.geometryEnd);
|
|
1937
1932
|
}
|
|
@@ -2050,19 +2045,25 @@ class HighlighterUtils {
|
|
|
2050
2045
|
class HighlighterComponent {
|
|
2051
2046
|
constructor(viewer) {
|
|
2052
2047
|
this.geometryEnd = () => {
|
|
2053
|
-
const {facesColor: facesColor, facesTransparancy: facesTransparancy, edgesColor: edgesColor} = this.viewer.options;
|
|
2054
|
-
this.highlightMaterial = new
|
|
2048
|
+
const {facesColor: facesColor, facesTransparancy: facesTransparancy, edgesColor: edgesColor, edgesOverlap: edgesOverlap, facesOverlap: facesOverlap} = this.viewer.options;
|
|
2049
|
+
this.highlightMaterial = new MeshPhongMaterial({
|
|
2055
2050
|
color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
|
|
2056
2051
|
transparent: true,
|
|
2057
2052
|
opacity: (255 - facesTransparancy) / 255,
|
|
2058
|
-
depthTest:
|
|
2059
|
-
depthWrite:
|
|
2053
|
+
depthTest: !facesOverlap,
|
|
2054
|
+
depthWrite: !facesOverlap,
|
|
2055
|
+
specular: 2236962,
|
|
2056
|
+
shininess: 10,
|
|
2057
|
+
reflectivity: .05,
|
|
2058
|
+
polygonOffset: true,
|
|
2059
|
+
polygonOffsetFactor: 1,
|
|
2060
|
+
polygonOffsetUnits: 1
|
|
2060
2061
|
});
|
|
2061
2062
|
this.outlineMaterial = new LineMaterial({
|
|
2062
2063
|
color: new Color(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255),
|
|
2063
2064
|
linewidth: 1.5,
|
|
2064
|
-
depthTest:
|
|
2065
|
-
depthWrite:
|
|
2065
|
+
depthTest: !edgesOverlap,
|
|
2066
|
+
depthWrite: !edgesOverlap,
|
|
2066
2067
|
resolution: new Vector2(window.innerWidth, window.innerHeight)
|
|
2067
2068
|
});
|
|
2068
2069
|
this.highlightLineMaterial = new LineBasicMaterial({
|
|
@@ -2075,18 +2076,26 @@ class HighlighterComponent {
|
|
|
2075
2076
|
linewidth: 5,
|
|
2076
2077
|
transparent: true,
|
|
2077
2078
|
opacity: .8,
|
|
2078
|
-
depthTest:
|
|
2079
|
-
depthWrite:
|
|
2079
|
+
depthTest: !edgesOverlap,
|
|
2080
|
+
depthWrite: !edgesOverlap,
|
|
2080
2081
|
resolution: new Vector2(window.innerWidth, window.innerHeight)
|
|
2081
2082
|
});
|
|
2082
2083
|
};
|
|
2083
2084
|
this.optionsChange = () => {
|
|
2084
|
-
const {facesColor: facesColor, facesTransparancy: facesTransparancy, edgesColor: edgesColor} = this.viewer.options;
|
|
2085
|
+
const {facesColor: facesColor, facesTransparancy: facesTransparancy, edgesColor: edgesColor, edgesVisibility: edgesVisibility, edgesOverlap: edgesOverlap, facesOverlap: facesOverlap} = this.viewer.options;
|
|
2085
2086
|
this.highlightMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
2086
2087
|
this.highlightMaterial.opacity = (255 - facesTransparancy) / 255;
|
|
2088
|
+
this.highlightMaterial.depthTest = !facesOverlap;
|
|
2089
|
+
this.highlightMaterial.depthWrite = !facesOverlap;
|
|
2087
2090
|
this.outlineMaterial.color.setRGB(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255);
|
|
2091
|
+
this.outlineMaterial.depthTest = !edgesOverlap;
|
|
2092
|
+
this.outlineMaterial.depthWrite = !edgesOverlap;
|
|
2088
2093
|
this.highlightLineMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
2089
2094
|
this.highlightLineGlowMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
2095
|
+
this.viewer.selected.forEach((selected => {
|
|
2096
|
+
const wireframe = selected.userData.highlightWireframe;
|
|
2097
|
+
if (wireframe) wireframe.visible = edgesVisibility;
|
|
2098
|
+
}));
|
|
2090
2099
|
this.viewer.update();
|
|
2091
2100
|
};
|
|
2092
2101
|
this.viewer = viewer;
|
|
@@ -2111,6 +2120,7 @@ class HighlighterComponent {
|
|
|
2111
2120
|
this.viewer.removeEventListener("resize", this.viewerResize);
|
|
2112
2121
|
}
|
|
2113
2122
|
highlight(objects) {
|
|
2123
|
+
const {edgesVisibility: edgesVisibility} = this.viewer.options;
|
|
2114
2124
|
if (!Array.isArray(objects)) objects = [ objects ];
|
|
2115
2125
|
if (!objects.length) return;
|
|
2116
2126
|
objects.forEach((object => {
|
|
@@ -2123,20 +2133,22 @@ class HighlighterComponent {
|
|
|
2123
2133
|
wireframe.position.copy(object.position);
|
|
2124
2134
|
wireframe.rotation.copy(object.rotation);
|
|
2125
2135
|
wireframe.scale.copy(object.scale);
|
|
2136
|
+
wireframe.visible = edgesVisibility;
|
|
2126
2137
|
object.parent.add(wireframe);
|
|
2127
|
-
object.userData.
|
|
2138
|
+
object.userData.highlightWireframe = wireframe;
|
|
2128
2139
|
object.userData.originalMaterial = object.material;
|
|
2129
2140
|
object.material = this.highlightLineMaterial;
|
|
2130
2141
|
object.isHighlighted = true;
|
|
2131
2142
|
} else if (object.isMesh) {
|
|
2132
|
-
const edgesGeometry = new EdgesGeometry(object.geometry,
|
|
2143
|
+
const edgesGeometry = new EdgesGeometry(object.geometry, 60);
|
|
2133
2144
|
const lineGeometry = (new LineSegmentsGeometry).fromEdgesGeometry(edgesGeometry);
|
|
2134
2145
|
const wireframe = new Wireframe(lineGeometry, this.outlineMaterial);
|
|
2135
2146
|
wireframe.position.copy(object.position);
|
|
2136
2147
|
wireframe.rotation.copy(object.rotation);
|
|
2137
2148
|
wireframe.scale.copy(object.scale);
|
|
2149
|
+
wireframe.visible = edgesVisibility;
|
|
2138
2150
|
object.parent.add(wireframe);
|
|
2139
|
-
object.userData.
|
|
2151
|
+
object.userData.highlightWireframe = wireframe;
|
|
2140
2152
|
object.userData.originalMaterial = object.material;
|
|
2141
2153
|
object.material = this.highlightMaterial;
|
|
2142
2154
|
object.isHighlighted = true;
|
|
@@ -2150,9 +2162,9 @@ class HighlighterComponent {
|
|
|
2150
2162
|
if (!object.isHighlighted) return;
|
|
2151
2163
|
object.isHighlighted = false;
|
|
2152
2164
|
object.material = object.userData.originalMaterial;
|
|
2153
|
-
object.userData.
|
|
2165
|
+
object.userData.highlightWireframe.removeFromParent();
|
|
2154
2166
|
delete object.userData.originalMaterial;
|
|
2155
|
-
delete object.userData.
|
|
2167
|
+
delete object.userData.highlightWireframe;
|
|
2156
2168
|
}));
|
|
2157
2169
|
}
|
|
2158
2170
|
viewerResize(event) {
|
|
@@ -2176,10 +2188,10 @@ class SelectionComponent {
|
|
|
2176
2188
|
this.viewer.models.forEach((model => {
|
|
2177
2189
|
const objects = model.getVisibleObjects();
|
|
2178
2190
|
const intersects = this.getPointerIntersects(upPosition, objects);
|
|
2179
|
-
|
|
2180
|
-
...
|
|
2191
|
+
if (intersects.length > 0) intersections.push({
|
|
2192
|
+
...intersects[0],
|
|
2181
2193
|
model: model
|
|
2182
|
-
})
|
|
2194
|
+
});
|
|
2183
2195
|
}));
|
|
2184
2196
|
intersections = intersections.sort(((a, b) => a.distance - b.distance));
|
|
2185
2197
|
if (!event.shiftKey) this.clearSelection();
|
|
@@ -2249,7 +2261,6 @@ class SelectionComponent {
|
|
|
2249
2261
|
}
|
|
2250
2262
|
if (!Array.isArray(objects)) objects = [ objects ];
|
|
2251
2263
|
if (!objects.length) return;
|
|
2252
|
-
model.showObjects(objects);
|
|
2253
2264
|
model.showOriginalObjects(objects);
|
|
2254
2265
|
this.highlighter.highlight(objects);
|
|
2255
2266
|
objects.forEach((object => this.viewer.selected.push(object)));
|
|
@@ -2633,8 +2644,8 @@ class DynamicModelImpl extends ModelImpl {
|
|
|
2633
2644
|
return objects;
|
|
2634
2645
|
}
|
|
2635
2646
|
hideObjects(objects) {
|
|
2636
|
-
|
|
2637
|
-
this.gltfLoader.
|
|
2647
|
+
const handles = this.getHandlesByObjects(objects);
|
|
2648
|
+
this.gltfLoader.hideObjects(handles);
|
|
2638
2649
|
return this;
|
|
2639
2650
|
}
|
|
2640
2651
|
isolateObjects(objects) {
|
|
@@ -2643,21 +2654,20 @@ class DynamicModelImpl extends ModelImpl {
|
|
|
2643
2654
|
return this;
|
|
2644
2655
|
}
|
|
2645
2656
|
showObjects(objects) {
|
|
2646
|
-
|
|
2647
|
-
this.gltfLoader.
|
|
2657
|
+
const handles = this.getHandlesByObjects(objects);
|
|
2658
|
+
this.gltfLoader.showObjects(handles);
|
|
2648
2659
|
return this;
|
|
2649
2660
|
}
|
|
2650
2661
|
showAllObjects() {
|
|
2651
|
-
this.gltfLoader.
|
|
2652
|
-
this.gltfLoader.syncHiddenObjects();
|
|
2662
|
+
this.gltfLoader.showAllHiddenObjects();
|
|
2653
2663
|
return this;
|
|
2654
2664
|
}
|
|
2655
2665
|
showOriginalObjects(objects) {
|
|
2656
|
-
this.
|
|
2666
|
+
this.gltfLoader.showOriginalObjects(objects);
|
|
2657
2667
|
return this;
|
|
2658
2668
|
}
|
|
2659
2669
|
hideOriginalObjects(objects) {
|
|
2660
|
-
this.
|
|
2670
|
+
this.gltfLoader.hideOriginalObjects(objects);
|
|
2661
2671
|
return this;
|
|
2662
2672
|
}
|
|
2663
2673
|
}
|
|
@@ -2681,6 +2691,10 @@ const GL_CONSTANTS = {
|
|
|
2681
2691
|
TRIANGLE_FAN: 6
|
|
2682
2692
|
};
|
|
2683
2693
|
|
|
2694
|
+
const MAX_GAP = 128 * 1024;
|
|
2695
|
+
|
|
2696
|
+
const MAX_CHUNK = 30 * 1024 * 1024;
|
|
2697
|
+
|
|
2684
2698
|
class GltfStructure {
|
|
2685
2699
|
constructor(id) {
|
|
2686
2700
|
this.id = `${id}`;
|
|
@@ -2718,42 +2732,99 @@ class GltfStructure {
|
|
|
2718
2732
|
return this.json;
|
|
2719
2733
|
}
|
|
2720
2734
|
scheduleRequest(request) {
|
|
2721
|
-
this.pendingRequests.push(request);
|
|
2722
|
-
if (this.batchTimeout) {
|
|
2723
|
-
clearTimeout(this.batchTimeout);
|
|
2724
|
-
}
|
|
2725
|
-
this.batchTimeout = setTimeout((() => this.processBatch()), this.batchDelay);
|
|
2726
2735
|
return new Promise(((resolve, reject) => {
|
|
2727
|
-
|
|
2728
|
-
|
|
2736
|
+
this.pendingRequests.push({
|
|
2737
|
+
...request,
|
|
2738
|
+
_resolve: resolve,
|
|
2739
|
+
_reject: reject
|
|
2740
|
+
});
|
|
2729
2741
|
}));
|
|
2730
2742
|
}
|
|
2731
|
-
async
|
|
2732
|
-
if (this.pendingRequests.length === 0) return;
|
|
2733
|
-
const
|
|
2743
|
+
async flushBufferRequests() {
|
|
2744
|
+
if (!this.pendingRequests || this.pendingRequests.length === 0) return;
|
|
2745
|
+
const requests = [ ...this.pendingRequests ];
|
|
2734
2746
|
this.pendingRequests = [];
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2747
|
+
requests.sort(((a, b) => a.offset - b.offset));
|
|
2748
|
+
const mergedRanges = [];
|
|
2749
|
+
let current = {
|
|
2750
|
+
start: requests[0].offset,
|
|
2751
|
+
end: requests[0].offset + requests[0].length,
|
|
2752
|
+
requests: [ requests[0] ]
|
|
2753
|
+
};
|
|
2754
|
+
for (let i = 1; i < requests.length; i++) {
|
|
2755
|
+
const req = requests[i];
|
|
2756
|
+
const gap = req.offset - current.end;
|
|
2757
|
+
const newEnd = Math.max(current.end, req.offset + req.length);
|
|
2758
|
+
const projectedSize = newEnd - current.start;
|
|
2759
|
+
if (gap <= MAX_GAP && projectedSize <= MAX_CHUNK) {
|
|
2760
|
+
current.end = newEnd;
|
|
2761
|
+
current.requests.push(req);
|
|
2762
|
+
} else {
|
|
2763
|
+
mergedRanges.push(current);
|
|
2764
|
+
current = {
|
|
2765
|
+
start: req.offset,
|
|
2766
|
+
end: req.offset + req.length,
|
|
2767
|
+
requests: [ req ]
|
|
2768
|
+
};
|
|
2749
2769
|
}
|
|
2750
|
-
} catch (error) {
|
|
2751
|
-
console.error("Error processing batch:", error);
|
|
2752
|
-
currentBatch.forEach((request => request.reject(error)));
|
|
2753
2770
|
}
|
|
2754
|
-
|
|
2755
|
-
|
|
2771
|
+
mergedRanges.push(current);
|
|
2772
|
+
const finalRanges = [];
|
|
2773
|
+
for (const range of mergedRanges) {
|
|
2774
|
+
let {start: start, end: end, requests: requests} = range;
|
|
2775
|
+
while (end - start > MAX_CHUNK) {
|
|
2776
|
+
let splitIdx = 0;
|
|
2777
|
+
for (let i = 0; i < requests.length; i++) {
|
|
2778
|
+
if (requests[i].offset + requests[i].length - start > MAX_CHUNK) {
|
|
2779
|
+
break;
|
|
2780
|
+
}
|
|
2781
|
+
splitIdx = i;
|
|
2782
|
+
}
|
|
2783
|
+
const chunkRequests = requests.slice(0, splitIdx + 1);
|
|
2784
|
+
const chunkEnd = chunkRequests[chunkRequests.length - 1].offset + chunkRequests[chunkRequests.length - 1].length;
|
|
2785
|
+
finalRanges.push({
|
|
2786
|
+
start: start,
|
|
2787
|
+
end: chunkEnd,
|
|
2788
|
+
requests: chunkRequests
|
|
2789
|
+
});
|
|
2790
|
+
requests = requests.slice(splitIdx + 1);
|
|
2791
|
+
if (requests.length > 0) {
|
|
2792
|
+
start = requests[0].offset;
|
|
2793
|
+
end = requests[0].offset + requests[0].length;
|
|
2794
|
+
for (let i = 1; i < requests.length; i++) {
|
|
2795
|
+
end = Math.max(end, requests[i].offset + requests[i].length);
|
|
2796
|
+
}
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
if (requests.length > 0) {
|
|
2800
|
+
finalRanges.push({
|
|
2801
|
+
start: start,
|
|
2802
|
+
end: end,
|
|
2803
|
+
requests: requests
|
|
2804
|
+
});
|
|
2805
|
+
}
|
|
2756
2806
|
}
|
|
2807
|
+
const promises = finalRanges.map((async range => {
|
|
2808
|
+
const length = range.end - range.start;
|
|
2809
|
+
const buffer = await this.loadController.loadBinaryData([ {
|
|
2810
|
+
offset: range.start,
|
|
2811
|
+
length: length
|
|
2812
|
+
} ]);
|
|
2813
|
+
for (const req of range.requests) {
|
|
2814
|
+
const relOffset = req.offset - range.start;
|
|
2815
|
+
try {
|
|
2816
|
+
req._resolve({
|
|
2817
|
+
buffer: buffer,
|
|
2818
|
+
relOffset: relOffset,
|
|
2819
|
+
length: req.length
|
|
2820
|
+
});
|
|
2821
|
+
} catch (e) {
|
|
2822
|
+
req._reject(e);
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
}));
|
|
2826
|
+
await Promise.all(promises);
|
|
2827
|
+
this.pendingRequests = [];
|
|
2757
2828
|
}
|
|
2758
2829
|
getBufferView(byteOffset, byteLength, componentType) {
|
|
2759
2830
|
return this.scheduleRequest({
|
|
@@ -2912,62 +2983,48 @@ class GltfStructure {
|
|
|
2912
2983
|
}
|
|
2913
2984
|
await Promise.all(texturePromises);
|
|
2914
2985
|
}
|
|
2915
|
-
loadMaterials() {
|
|
2986
|
+
async loadMaterials() {
|
|
2916
2987
|
if (!this.json.materials) return this.materials;
|
|
2917
2988
|
for (let i = 0; i < this.json.materials.length; i++) {
|
|
2918
2989
|
const materialDef = this.json.materials[i];
|
|
2919
|
-
const material = this.createMaterial(materialDef);
|
|
2990
|
+
const material = await this.createMaterial(materialDef);
|
|
2991
|
+
material.name = materialDef.name;
|
|
2920
2992
|
this.materials.set(i, material);
|
|
2921
2993
|
}
|
|
2922
2994
|
return this.materials;
|
|
2923
2995
|
}
|
|
2924
2996
|
createMaterial(materialDef) {
|
|
2925
|
-
const
|
|
2997
|
+
const params = {};
|
|
2926
2998
|
if (materialDef.pbrMetallicRoughness) {
|
|
2927
2999
|
const pbr = materialDef.pbrMetallicRoughness;
|
|
2928
3000
|
if (pbr.baseColorFactor) {
|
|
2929
|
-
|
|
2930
|
-
|
|
3001
|
+
params.color = (new Color).fromArray(pbr.baseColorFactor);
|
|
3002
|
+
params.opacity = pbr.baseColorFactor[3];
|
|
3003
|
+
if (params.opacity < 1) params.transparent = true;
|
|
2931
3004
|
}
|
|
2932
3005
|
if (pbr.baseColorTexture) {
|
|
2933
|
-
|
|
2934
|
-
}
|
|
2935
|
-
if (pbr.metallicFactor !== undefined) {
|
|
2936
|
-
material.metalness = pbr.metallicFactor;
|
|
2937
|
-
}
|
|
2938
|
-
if (pbr.roughnessFactor !== undefined) {
|
|
2939
|
-
material.roughness = pbr.roughnessFactor;
|
|
2940
|
-
}
|
|
2941
|
-
if (pbr.metallicRoughnessTexture) {
|
|
2942
|
-
material.metalnessMap = this.textureCache.get(pbr.metallicRoughnessTexture.index);
|
|
2943
|
-
material.roughnessMap = material.metalnessMap;
|
|
2944
|
-
}
|
|
2945
|
-
}
|
|
2946
|
-
if (materialDef.normalTexture) {
|
|
2947
|
-
material.normalMap = this.textureCache.get(materialDef.normalTexture.index);
|
|
2948
|
-
if (materialDef.normalTexture.scale !== undefined) {
|
|
2949
|
-
material.normalScale.set(materialDef.normalTexture.scale, materialDef.normalTexture.scale);
|
|
3006
|
+
params.map = this.textureCache.get(pbr.baseColorTexture.index);
|
|
2950
3007
|
}
|
|
2951
3008
|
}
|
|
3009
|
+
params.specular = 2236962;
|
|
3010
|
+
params.shininess = 10;
|
|
3011
|
+
params.reflectivity = .05;
|
|
3012
|
+
params.polygonOffset = true;
|
|
3013
|
+
params.polygonOffsetFactor = 1;
|
|
3014
|
+
params.polygonOffsetUnits = 1;
|
|
2952
3015
|
if (materialDef.emissiveFactor) {
|
|
2953
|
-
|
|
2954
|
-
}
|
|
2955
|
-
if (materialDef.emissiveTexture) {
|
|
2956
|
-
material.emissiveMap = this.textureCache.get(materialDef.emissiveTexture.index);
|
|
3016
|
+
params.emissive = (new Color).fromArray(materialDef.emissiveFactor);
|
|
2957
3017
|
}
|
|
2958
|
-
if (materialDef.
|
|
2959
|
-
|
|
2960
|
-
if (materialDef.occlusionTexture.strength !== undefined) {
|
|
2961
|
-
material.aoMapIntensity = materialDef.occlusionTexture.strength;
|
|
2962
|
-
}
|
|
3018
|
+
if (materialDef.normalTexture) {
|
|
3019
|
+
params.normalMap = this.textureCache.get(materialDef.normalTexture.index);
|
|
2963
3020
|
}
|
|
2964
3021
|
if (materialDef.alphaMode === "BLEND") {
|
|
2965
|
-
|
|
2966
|
-
}
|
|
2967
|
-
|
|
3022
|
+
params.transparent = true;
|
|
3023
|
+
}
|
|
3024
|
+
if (materialDef.doubleSided) {
|
|
3025
|
+
params.side = DoubleSide;
|
|
2968
3026
|
}
|
|
2969
|
-
material
|
|
2970
|
-
material.name = materialDef.name;
|
|
3027
|
+
const material = new MeshPhongMaterial(params);
|
|
2971
3028
|
return material;
|
|
2972
3029
|
}
|
|
2973
3030
|
disposeMaterials() {
|
|
@@ -3212,12 +3269,17 @@ class DynamicGltfLoader {
|
|
|
3212
3269
|
this.mergedLineSegments = new Set;
|
|
3213
3270
|
this.mergedPoints = new Set;
|
|
3214
3271
|
this.isolatedObjects = [];
|
|
3215
|
-
|
|
3272
|
+
//!!window.WebGL2RenderingContext && this.renderer.getContext() instanceof WebGL2RenderingContext
|
|
3273
|
+
this.useVAO = false;
|
|
3274
|
+
this.visibleEdges = true;
|
|
3216
3275
|
this.handleToOptimizedObjects = new Map;
|
|
3217
3276
|
this.hiddenHandles = new Set;
|
|
3218
3277
|
this.newOptimizedObjects = new Set;
|
|
3219
3278
|
this.oldOptimizeObjects = new Set;
|
|
3220
3279
|
}
|
|
3280
|
+
setVisibleEdges(visible) {
|
|
3281
|
+
this.visibleEdges = visible;
|
|
3282
|
+
}
|
|
3221
3283
|
getAvailableMemory() {
|
|
3222
3284
|
let memoryLimit = 6 * 1024 * 1024 * 1024;
|
|
3223
3285
|
try {
|
|
@@ -3235,7 +3297,7 @@ class DynamicGltfLoader {
|
|
|
3235
3297
|
} catch (error) {
|
|
3236
3298
|
console.warn("Error detecting available memory:", error);
|
|
3237
3299
|
}
|
|
3238
|
-
return memoryLimit;
|
|
3300
|
+
return memoryLimit / 3;
|
|
3239
3301
|
}
|
|
3240
3302
|
getAbortController() {
|
|
3241
3303
|
return this.abortController;
|
|
@@ -3316,35 +3378,132 @@ class DynamicGltfLoader {
|
|
|
3316
3378
|
this.updateMemoryIndicator();
|
|
3317
3379
|
console.log(`Final memory usage: ${Math.round(currentMemoryUsage / (1024 * 1024))}MB`);
|
|
3318
3380
|
}
|
|
3319
|
-
async loadNode(nodeId) {
|
|
3381
|
+
async loadNode(nodeId, onLoadFinishCb) {
|
|
3320
3382
|
const node = this.nodes.get(nodeId);
|
|
3321
3383
|
if (!node || node.loaded || node.loading) return;
|
|
3322
3384
|
node.loading = true;
|
|
3323
3385
|
const meshDef = node.structure.getJson().meshes[node.meshIndex];
|
|
3324
3386
|
try {
|
|
3325
|
-
|
|
3326
|
-
|
|
3387
|
+
const bufferRequests = [];
|
|
3388
|
+
const primitiveReqMap = new Map;
|
|
3389
|
+
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
3390
|
+
const primitive = meshDef.primitives[primIdx];
|
|
3391
|
+
const reqs = [];
|
|
3392
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
3393
|
+
const accessorIndex = primitive.attributes.POSITION;
|
|
3394
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
3395
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
3396
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
3397
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
3398
|
+
const count = accessor.count;
|
|
3399
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
3400
|
+
reqs.push({
|
|
3401
|
+
offset: byteOffset,
|
|
3402
|
+
length: byteLength,
|
|
3403
|
+
componentType: accessor.componentType,
|
|
3404
|
+
accessorIndex: accessorIndex,
|
|
3405
|
+
type: "position",
|
|
3406
|
+
primIdx: primIdx
|
|
3407
|
+
});
|
|
3408
|
+
}
|
|
3409
|
+
if (primitive.attributes.NORMAL !== undefined) {
|
|
3410
|
+
const accessorIndex = primitive.attributes.NORMAL;
|
|
3411
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
3412
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
3413
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
3414
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
3415
|
+
const count = accessor.count;
|
|
3416
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
3417
|
+
reqs.push({
|
|
3418
|
+
offset: byteOffset,
|
|
3419
|
+
length: byteLength,
|
|
3420
|
+
componentType: accessor.componentType,
|
|
3421
|
+
accessorIndex: accessorIndex,
|
|
3422
|
+
type: "normal",
|
|
3423
|
+
primIdx: primIdx
|
|
3424
|
+
});
|
|
3425
|
+
}
|
|
3426
|
+
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
3427
|
+
const accessorIndex = primitive.attributes.TEXCOORD_0;
|
|
3428
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
3429
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
3430
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
3431
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
3432
|
+
const count = accessor.count;
|
|
3433
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
3434
|
+
reqs.push({
|
|
3435
|
+
offset: byteOffset,
|
|
3436
|
+
length: byteLength,
|
|
3437
|
+
componentType: accessor.componentType,
|
|
3438
|
+
accessorIndex: accessorIndex,
|
|
3439
|
+
type: "uv",
|
|
3440
|
+
primIdx: primIdx
|
|
3441
|
+
});
|
|
3442
|
+
}
|
|
3443
|
+
if (primitive.indices !== undefined) {
|
|
3444
|
+
const accessorIndex = primitive.indices;
|
|
3445
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
3446
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
3447
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
3448
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
3449
|
+
const count = accessor.count;
|
|
3450
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
3451
|
+
reqs.push({
|
|
3452
|
+
offset: byteOffset,
|
|
3453
|
+
length: byteLength,
|
|
3454
|
+
componentType: accessor.componentType,
|
|
3455
|
+
accessorIndex: accessorIndex,
|
|
3456
|
+
type: "index",
|
|
3457
|
+
primIdx: primIdx
|
|
3458
|
+
});
|
|
3459
|
+
}
|
|
3460
|
+
primitiveReqMap.set(primIdx, reqs);
|
|
3461
|
+
bufferRequests.push(...reqs);
|
|
3462
|
+
}
|
|
3463
|
+
if (bufferRequests.length === 0) {
|
|
3464
|
+
node.loaded = true;
|
|
3465
|
+
node.loading = false;
|
|
3466
|
+
return;
|
|
3467
|
+
}
|
|
3468
|
+
bufferRequests.sort(((a, b) => a.offset - b.offset));
|
|
3469
|
+
const minOffset = bufferRequests[0].offset;
|
|
3470
|
+
const maxOffset = Math.max(...bufferRequests.map((r => r.offset + r.length)));
|
|
3471
|
+
const totalLength = maxOffset - minOffset;
|
|
3472
|
+
const {buffer: buffer, relOffset: baseRelOffset} = await node.structure.scheduleRequest({
|
|
3473
|
+
offset: minOffset,
|
|
3474
|
+
length: totalLength,
|
|
3475
|
+
componentType: null
|
|
3476
|
+
});
|
|
3477
|
+
for (const req of bufferRequests) {
|
|
3478
|
+
const relOffset = req.offset - minOffset;
|
|
3479
|
+
req.data = node.structure.createTypedArray(buffer, baseRelOffset + relOffset, req.length, req.componentType);
|
|
3480
|
+
}
|
|
3481
|
+
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
3482
|
+
const primitive = meshDef.primitives[primIdx];
|
|
3327
3483
|
const geometry = new BufferGeometry;
|
|
3328
|
-
const
|
|
3329
|
-
attributes.
|
|
3484
|
+
const reqs = primitiveReqMap.get(primIdx);
|
|
3485
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
3486
|
+
const req = reqs.find((r => r.type === "position" && r.accessorIndex === primitive.attributes.POSITION));
|
|
3487
|
+
const accessor = node.structure.json.accessors[primitive.attributes.POSITION];
|
|
3488
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
3489
|
+
geometry.setAttribute("position", new BufferAttribute(req.data, components));
|
|
3490
|
+
}
|
|
3330
3491
|
if (primitive.attributes.NORMAL !== undefined) {
|
|
3331
|
-
|
|
3492
|
+
const req = reqs.find((r => r.type === "normal" && r.accessorIndex === primitive.attributes.NORMAL));
|
|
3493
|
+
const accessor = node.structure.json.accessors[primitive.attributes.NORMAL];
|
|
3494
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
3495
|
+
geometry.setAttribute("normal", new BufferAttribute(req.data, components));
|
|
3332
3496
|
}
|
|
3333
3497
|
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
3334
|
-
|
|
3498
|
+
const req = reqs.find((r => r.type === "uv" && r.accessorIndex === primitive.attributes.TEXCOORD_0));
|
|
3499
|
+
const accessor = node.structure.json.accessors[primitive.attributes.TEXCOORD_0];
|
|
3500
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
3501
|
+
geometry.setAttribute("uv", new BufferAttribute(req.data, components));
|
|
3335
3502
|
}
|
|
3336
|
-
const loadedAttributes = await Promise.all([ ...attributes.entries() ].map((async ([name, promise]) => {
|
|
3337
|
-
const attribute = await promise;
|
|
3338
|
-
return [ name, attribute ];
|
|
3339
|
-
})));
|
|
3340
|
-
loadedAttributes.forEach((([name, attribute]) => {
|
|
3341
|
-
geometry.setAttribute(name, attribute);
|
|
3342
|
-
}));
|
|
3343
3503
|
if (primitive.indices !== undefined) {
|
|
3344
|
-
const
|
|
3345
|
-
geometry.setIndex(
|
|
3504
|
+
const req = reqs.find((r => r.type === "index" && r.accessorIndex === primitive.indices));
|
|
3505
|
+
geometry.setIndex(new BufferAttribute(req.data, 1));
|
|
3346
3506
|
}
|
|
3347
|
-
this.currentPrimitiveMode = primitive.mode;
|
|
3348
3507
|
let material;
|
|
3349
3508
|
if (primitive.material !== undefined) {
|
|
3350
3509
|
material = node.structure.materials.get(primitive.material) || this.createDefaultMaterial();
|
|
@@ -3423,6 +3582,9 @@ class DynamicGltfLoader {
|
|
|
3423
3582
|
const geometrySize = this.estimateGeometrySize(node.object);
|
|
3424
3583
|
this.geometryCache.set(node.object.uuid, geometrySize);
|
|
3425
3584
|
this.currentMemoryUsage += geometrySize;
|
|
3585
|
+
if (onLoadFinishCb) {
|
|
3586
|
+
onLoadFinishCb();
|
|
3587
|
+
}
|
|
3426
3588
|
} catch (error) {
|
|
3427
3589
|
if (error.name !== "AbortError") {
|
|
3428
3590
|
console.error(`Error loading node ${nodeId}:`, error);
|
|
@@ -3520,7 +3682,7 @@ class DynamicGltfLoader {
|
|
|
3520
3682
|
const volumeB = sizeB.x * sizeB.y * sizeB.z;
|
|
3521
3683
|
return volumeB - volumeA;
|
|
3522
3684
|
}));
|
|
3523
|
-
if (!ignoreEdges) {
|
|
3685
|
+
if (!ignoreEdges && this.visibleEdges) {
|
|
3524
3686
|
this.nodesToLoad.push(...this.edgeNodes);
|
|
3525
3687
|
}
|
|
3526
3688
|
this.dispatchEvent("databasechunk", {
|
|
@@ -3628,28 +3790,12 @@ class DynamicGltfLoader {
|
|
|
3628
3790
|
async processNodes() {
|
|
3629
3791
|
const nodesToLoad = this.nodesToLoad;
|
|
3630
3792
|
let loadedCount = 0;
|
|
3793
|
+
let lastLoadedCount = 0;
|
|
3631
3794
|
const totalNodes = nodesToLoad.length;
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
for (const nodeId of batch) {
|
|
3637
|
-
if (this.abortController.signal.aborted) {
|
|
3638
|
-
throw new DOMException("Loading aborted", "AbortError");
|
|
3639
|
-
}
|
|
3640
|
-
const estimatedSize = await this.estimateNodeSize(nodeId);
|
|
3641
|
-
if (this.currentMemoryUsage + estimatedSize > this.memoryLimit) {
|
|
3642
|
-
console.log(`Memory limit reached after loading ${loadedCount} nodes`);
|
|
3643
|
-
this.dispatchEvent("geometryerror", {
|
|
3644
|
-
message: "Memory limit reached"
|
|
3645
|
-
});
|
|
3646
|
-
this.dispatchEvent("update");
|
|
3647
|
-
return loadedCount;
|
|
3648
|
-
}
|
|
3649
|
-
batchPromises.push(this.loadNode(nodeId));
|
|
3650
|
-
}
|
|
3651
|
-
await Promise.all(batchPromises);
|
|
3652
|
-
loadedCount += batch.length;
|
|
3795
|
+
const loadProgress = async () => {
|
|
3796
|
+
loadedCount++;
|
|
3797
|
+
if (loadedCount - lastLoadedCount > 1e3) {
|
|
3798
|
+
lastLoadedCount = loadedCount;
|
|
3653
3799
|
this.updateMemoryIndicator();
|
|
3654
3800
|
this.dispatchEvent("geometryprogress", {
|
|
3655
3801
|
percentage: Math.round(loadedCount / totalNodes * 100),
|
|
@@ -3665,6 +3811,28 @@ class DynamicGltfLoader {
|
|
|
3665
3811
|
setTimeout(resolve, 0);
|
|
3666
3812
|
}));
|
|
3667
3813
|
}
|
|
3814
|
+
};
|
|
3815
|
+
try {
|
|
3816
|
+
const loadOperations = [];
|
|
3817
|
+
for (const nodeId of nodesToLoad) {
|
|
3818
|
+
if (this.abortController.signal.aborted) {
|
|
3819
|
+
throw new DOMException("Loading aborted", "AbortError");
|
|
3820
|
+
}
|
|
3821
|
+
const estimatedSize = await this.estimateNodeSize(nodeId);
|
|
3822
|
+
if (this.currentMemoryUsage + estimatedSize > this.memoryLimit) {
|
|
3823
|
+
console.log(`Memory limit reached after loading ${loadedCount} nodes`);
|
|
3824
|
+
this.dispatchEvent("geometryerror", {
|
|
3825
|
+
message: "Memory limit reached"
|
|
3826
|
+
});
|
|
3827
|
+
this.dispatchEvent("update");
|
|
3828
|
+
return loadedCount;
|
|
3829
|
+
}
|
|
3830
|
+
loadOperations.push(this.loadNode(nodeId, loadProgress));
|
|
3831
|
+
}
|
|
3832
|
+
for (const structure of this.structures) {
|
|
3833
|
+
loadOperations.push(structure.flushBufferRequests());
|
|
3834
|
+
}
|
|
3835
|
+
await Promise.all(loadOperations);
|
|
3668
3836
|
this.dispatchEvent("geometryend", {
|
|
3669
3837
|
totalLoaded: loadedCount,
|
|
3670
3838
|
totalNodes: totalNodes
|
|
@@ -4468,13 +4636,29 @@ class DynamicGltfLoader {
|
|
|
4468
4636
|
}
|
|
4469
4637
|
}));
|
|
4470
4638
|
}
|
|
4639
|
+
getStructureGeometryExtent(structureId) {
|
|
4640
|
+
const extent = new Box3;
|
|
4641
|
+
for (const [nodeId, node] of this.nodes.entries()) {
|
|
4642
|
+
if (!node.geometryExtents) continue;
|
|
4643
|
+
if (!nodeId.startsWith(structureId + "_")) continue;
|
|
4644
|
+
if (node.object && this.hiddenHandles && this.hiddenHandles.has(node.object.userData.handle)) continue;
|
|
4645
|
+
const transformedBox = node.geometryExtents.clone();
|
|
4646
|
+
if (node.group && node.group.matrix) {
|
|
4647
|
+
transformedBox.applyMatrix4(node.group.matrix);
|
|
4648
|
+
if (node.group.parent && node.group.parent.matrix) {
|
|
4649
|
+
transformedBox.applyMatrix4(node.group.parent.matrix);
|
|
4650
|
+
}
|
|
4651
|
+
}
|
|
4652
|
+
extent.union(transformedBox);
|
|
4653
|
+
}
|
|
4654
|
+
return extent;
|
|
4655
|
+
}
|
|
4471
4656
|
}
|
|
4472
4657
|
|
|
4473
4658
|
class GLTFCloudDynamicLoader {
|
|
4474
4659
|
constructor(viewer) {
|
|
4475
4660
|
this.requestId = 0;
|
|
4476
4661
|
this.viewer = viewer;
|
|
4477
|
-
this.scene = new Group;
|
|
4478
4662
|
}
|
|
4479
4663
|
dispose() {
|
|
4480
4664
|
if (this.gltfLoader) this.gltfLoader.clear();
|
|
@@ -4483,21 +4667,22 @@ class GLTFCloudDynamicLoader {
|
|
|
4483
4667
|
return typeof file === "object" && typeof file.database === "string" && typeof file.downloadResource === "function" && typeof file.downloadResourceRange === "function" && /.gltf$/i.test(file.database);
|
|
4484
4668
|
}
|
|
4485
4669
|
async load(model, format, params) {
|
|
4486
|
-
|
|
4670
|
+
const scene = new Group;
|
|
4671
|
+
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
4487
4672
|
this.gltfLoader.memoryLimit = this.viewer.options.memoryLimit;
|
|
4488
4673
|
this.gltfLoader.addEventListener("databasechunk", (data => {
|
|
4489
|
-
const modelImpl = new DynamicModelImpl(
|
|
4674
|
+
const modelImpl = new DynamicModelImpl(scene);
|
|
4490
4675
|
modelImpl.loader = this;
|
|
4491
4676
|
modelImpl.gltfLoader = this.gltfLoader;
|
|
4492
4677
|
modelImpl.viewer = this.viewer;
|
|
4493
|
-
this.viewer.scene.add(
|
|
4678
|
+
this.viewer.scene.add(scene);
|
|
4494
4679
|
this.viewer.models.push(modelImpl);
|
|
4495
4680
|
this.viewer.syncOptions();
|
|
4496
4681
|
this.viewer.syncOverlay();
|
|
4497
4682
|
this.viewer.update();
|
|
4498
4683
|
this.viewer.emitEvent({
|
|
4499
4684
|
type: "databasechunk",
|
|
4500
|
-
data:
|
|
4685
|
+
data: scene,
|
|
4501
4686
|
file: model.file,
|
|
4502
4687
|
model: model
|
|
4503
4688
|
});
|
|
@@ -4511,12 +4696,6 @@ class GLTFCloudDynamicLoader {
|
|
|
4511
4696
|
model: model
|
|
4512
4697
|
});
|
|
4513
4698
|
}));
|
|
4514
|
-
this.gltfLoader.addEventListener("geometrymemory", (data => {
|
|
4515
|
-
this.viewer.emit({
|
|
4516
|
-
type: "geometryprogress",
|
|
4517
|
-
data: data
|
|
4518
|
-
});
|
|
4519
|
-
}));
|
|
4520
4699
|
this.gltfLoader.addEventListener("geometryerror", (data => {
|
|
4521
4700
|
this.viewer.emitEvent({
|
|
4522
4701
|
type: "geometryerror",
|
|
@@ -4559,9 +4738,7 @@ class GLTFCloudDynamicLoader {
|
|
|
4559
4738
|
return this;
|
|
4560
4739
|
}
|
|
4561
4740
|
cancel() {
|
|
4562
|
-
if (this.gltfLoader)
|
|
4563
|
-
this.gltfLoader.abortLoading();
|
|
4564
|
-
}
|
|
4741
|
+
if (this.gltfLoader) this.gltfLoader.abortLoading();
|
|
4565
4742
|
}
|
|
4566
4743
|
}
|
|
4567
4744
|
|