@inweb/viewer-three 26.9.0 → 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.
- package/dist/plugins/components/AxesHelperComponent.js +8 -6
- package/dist/plugins/components/AxesHelperComponent.js.map +1 -1
- package/dist/plugins/components/AxesHelperComponent.min.js +1 -1
- package/dist/plugins/components/AxesHelperComponent.module.js +7 -5
- package/dist/plugins/components/AxesHelperComponent.module.js.map +1 -1
- package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
- package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
- package/dist/plugins/loaders/PotreeLoader.js +160 -0
- package/dist/plugins/loaders/PotreeLoader.js.map +1 -0
- package/dist/plugins/loaders/PotreeLoader.min.js +1 -0
- package/dist/plugins/loaders/PotreeLoader.module.js +68 -0
- package/dist/plugins/loaders/PotreeLoader.module.js.map +1 -0
- package/dist/viewer-three.js +153 -110
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +3 -3
- package/dist/viewer-three.module.js +152 -96
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/Viewer.d.ts +3 -2
- package/lib/Viewer/commands/SetDefaultViewPosition.d.ts +2 -2
- package/package.json +6 -5
- package/plugins/components/AxesHelperComponent.ts +10 -6
- package/plugins/loaders/{IFCXCloudLoader.ts → IFCX/IFCXCloudLoader.ts} +1 -1
- package/plugins/loaders/{IFCXFileLoader.ts → IFCX/IFCXFileLoader.ts} +1 -1
- package/plugins/loaders/Potree/PotreeFileLoader.ts +106 -0
- package/plugins/loaders/Potree/PotreeModelImpl.ts +36 -0
- package/plugins/loaders/Potree/index.ts +28 -0
- package/src/Viewer/Viewer.ts +39 -15
- package/src/Viewer/commands/SetDefaultViewPosition.ts +20 -16
- package/src/Viewer/commands/ZoomTo.ts +13 -13
- package/src/Viewer/components/ExtentsComponent.ts +1 -1
- package/src/Viewer/components/LightComponent.ts +8 -6
- package/src/Viewer/components/ResizeCanvasComponent.ts +1 -18
- package/src/Viewer/draggers/OrbitDragger.ts +9 -0
- package/src/Viewer/draggers/WalkDragger.ts +1 -0
- package/src/Viewer/helpers/WCSHelper.ts +3 -3
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +37 -12
- package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +32 -32
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +2 -2
- /package/plugins/loaders/{IFCXLoader.ts → IFCX/index.ts} +0 -0
package/lib/Viewer/Viewer.d.ts
CHANGED
|
@@ -38,8 +38,8 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMa
|
|
|
38
38
|
target: Vector3;
|
|
39
39
|
private _activeDragger;
|
|
40
40
|
private _components;
|
|
41
|
-
private
|
|
42
|
-
private
|
|
41
|
+
private _renderNeeded;
|
|
42
|
+
private _renderTime;
|
|
43
43
|
private _markup;
|
|
44
44
|
/**
|
|
45
45
|
* @param client - The `Client` instance that is used to load model reference files from the Open Cloud
|
|
@@ -59,6 +59,7 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMa
|
|
|
59
59
|
initialize(canvas: HTMLCanvasElement, onProgress?: (event: ProgressEvent<EventTarget>) => void): Promise<this>;
|
|
60
60
|
dispose(): this;
|
|
61
61
|
isInitialized(): boolean;
|
|
62
|
+
setSize(width: number, height: number, updateStyle?: boolean): void;
|
|
62
63
|
update(force?: boolean): void;
|
|
63
64
|
render(time?: DOMHighResTimeStamp, force?: boolean): void;
|
|
64
65
|
loadReferences(model: Model | File | Assembly): Promise<this>;
|
|
@@ -7,9 +7,9 @@ export declare const defaultViewPositions: {
|
|
|
7
7
|
right: Vector3;
|
|
8
8
|
bottom: Vector3;
|
|
9
9
|
top: Vector3;
|
|
10
|
-
|
|
10
|
+
se: Vector3;
|
|
11
11
|
sw: Vector3;
|
|
12
|
+
ne: Vector3;
|
|
12
13
|
nw: Vector3;
|
|
13
|
-
se: Vector3;
|
|
14
14
|
};
|
|
15
15
|
export declare function setDefaultViewPosition(viewer: Viewer, position: string): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inweb/viewer-three",
|
|
3
|
-
"version": "26.9.
|
|
3
|
+
"version": "26.9.2",
|
|
4
4
|
"description": "JavaScript library for rendering CAD and BIM files in a browser using Three.js",
|
|
5
5
|
"homepage": "https://cloud.opendesign.com/docs/index.html",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -35,13 +35,14 @@
|
|
|
35
35
|
"docs": "typedoc"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@inweb/client": "~26.9.
|
|
39
|
-
"@inweb/eventemitter2": "~26.9.
|
|
40
|
-
"@inweb/markup": "~26.9.
|
|
41
|
-
"@inweb/viewer-core": "~26.9.
|
|
38
|
+
"@inweb/client": "~26.9.2",
|
|
39
|
+
"@inweb/eventemitter2": "~26.9.2",
|
|
40
|
+
"@inweb/markup": "~26.9.2",
|
|
41
|
+
"@inweb/viewer-core": "~26.9.2"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/three": "^0.179.0",
|
|
45
|
+
"potree-core": "^2.0.11",
|
|
45
46
|
"three": "^0.179.1"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
@@ -32,7 +32,9 @@ class AxesHelperComponent implements IComponent {
|
|
|
32
32
|
constructor(viewer: Viewer) {
|
|
33
33
|
this.axesHelper1 = new AxesHelper();
|
|
34
34
|
this.axesHelper2 = new AxesHelper();
|
|
35
|
+
|
|
35
36
|
this.viewer = viewer;
|
|
37
|
+
this.viewer.addEventListener("initialize", this.syncHelper);
|
|
36
38
|
this.viewer.addEventListener("geometryend", this.syncHelper);
|
|
37
39
|
this.viewer.addEventListener("clear", this.syncHelper);
|
|
38
40
|
}
|
|
@@ -44,6 +46,7 @@ class AxesHelperComponent implements IComponent {
|
|
|
44
46
|
this.axesHelper2.removeFromParent();
|
|
45
47
|
this.axesHelper2.dispose();
|
|
46
48
|
|
|
49
|
+
this.viewer.removeEventListener("initialize", this.syncHelper);
|
|
47
50
|
this.viewer.removeEventListener("geometryend", this.syncHelper);
|
|
48
51
|
this.viewer.removeEventListener("clear", this.syncHelper);
|
|
49
52
|
}
|
|
@@ -55,17 +58,18 @@ class AxesHelperComponent implements IComponent {
|
|
|
55
58
|
this.axesHelper2.removeFromParent();
|
|
56
59
|
this.axesHelper2.dispose();
|
|
57
60
|
|
|
58
|
-
if (this.viewer.extents.isEmpty()) return;
|
|
59
|
-
|
|
60
61
|
const size = this.viewer.extents.getSize(new Vector3()).length();
|
|
61
62
|
const center = this.viewer.extents.getCenter(new Vector3());
|
|
62
63
|
|
|
63
|
-
this.axesHelper1 = new AxesHelper(size);
|
|
64
|
-
this.
|
|
64
|
+
this.axesHelper1 = new AxesHelper(size || 1);
|
|
65
|
+
this.axesHelper2 = new AxesHelper(size);
|
|
66
|
+
|
|
67
|
+
this.axesHelper1.position.set(0, 0, 0);
|
|
65
68
|
this.viewer.helpers.add(this.axesHelper1);
|
|
66
69
|
|
|
67
|
-
this.
|
|
68
|
-
|
|
70
|
+
if (this.viewer.extents.isEmpty()) return;
|
|
71
|
+
|
|
72
|
+
this.axesHelper2.position.copy(center);
|
|
69
73
|
this.viewer.helpers.add(this.axesHelper2);
|
|
70
74
|
};
|
|
71
75
|
}
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
24
|
import { Loader, ModelImpl, Viewer } from "@inweb/viewer-three";
|
|
25
|
-
import { parse, clear } from "./
|
|
25
|
+
import { parse, clear } from "./render.js";
|
|
26
26
|
|
|
27
27
|
export class IFCXCloudLoader extends Loader {
|
|
28
28
|
public viewer: Viewer;
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
24
|
import { GLTFLoadingManager, GLTFLoadParams, Loader, ModelImpl, Viewer } from "@inweb/viewer-three";
|
|
25
|
-
import { IFCXLoader } from "./
|
|
25
|
+
import { IFCXLoader } from "./IFCXLoader";
|
|
26
26
|
|
|
27
27
|
export class IFCXFileLoader extends Loader {
|
|
28
28
|
public viewer: Viewer;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
|
|
3
|
+
// All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This software and its documentation and related materials are owned by
|
|
6
|
+
// the Alliance. The software may only be incorporated into application
|
|
7
|
+
// programs owned by members of the Alliance, subject to a signed
|
|
8
|
+
// Membership Agreement and Supplemental Software License Agreement with the
|
|
9
|
+
// Alliance. The structure and organization of this software are the valuable
|
|
10
|
+
// trade secrets of the Alliance and its suppliers. The software is also
|
|
11
|
+
// protected by copyright law and international treaty provisions. Application
|
|
12
|
+
// programs incorporating this software must include the following statement
|
|
13
|
+
// with their copyright notices:
|
|
14
|
+
//
|
|
15
|
+
// This application incorporates Open Design Alliance software pursuant to a
|
|
16
|
+
// license agreement with Open Design Alliance.
|
|
17
|
+
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
|
|
18
|
+
// All rights reserved.
|
|
19
|
+
//
|
|
20
|
+
// By use of this software, its documentation or related materials, you
|
|
21
|
+
// acknowledge and accept the above terms.
|
|
22
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
23
|
+
|
|
24
|
+
import { Euler, Vector3 } from "three";
|
|
25
|
+
import { PointColorType, PointCloudOctree, PointSizeType, PointShape, Potree } from "potree-core";
|
|
26
|
+
import { Loader, Viewer } from "@inweb/viewer-three";
|
|
27
|
+
|
|
28
|
+
import { PotreeModelImpl } from "./PotreeModelImpl";
|
|
29
|
+
|
|
30
|
+
export type PotreeLoadParams = {
|
|
31
|
+
path?: string;
|
|
32
|
+
position?: Vector3;
|
|
33
|
+
rotation?: Euler;
|
|
34
|
+
scale?: Vector3;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export class PotreeFileLoader extends Loader {
|
|
38
|
+
public viewer: Viewer;
|
|
39
|
+
public potree: Potree;
|
|
40
|
+
public pointClouds: PointCloudOctree[];
|
|
41
|
+
|
|
42
|
+
constructor(viewer: Viewer) {
|
|
43
|
+
super();
|
|
44
|
+
this.viewer = viewer;
|
|
45
|
+
|
|
46
|
+
this.potree = new Potree();
|
|
47
|
+
this.pointClouds = [];
|
|
48
|
+
|
|
49
|
+
this.viewer.addEventListener("render", this.updatePointClouds);
|
|
50
|
+
this.viewer.addEventListener("changecamera", this.updatePointClouds);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override dispose() {
|
|
54
|
+
this.pointClouds.forEach((pco) => pco.dispose());
|
|
55
|
+
|
|
56
|
+
this.viewer.removeEventListener("render", this.updatePointClouds);
|
|
57
|
+
this.viewer.removeEventListener("changecamera", this.updatePointClouds);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override isSupport(file: any, format?: string): boolean {
|
|
61
|
+
return typeof file === "string" && /(cloud.js|metadata.json)$/i.test(file);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
override async load(file: any, format?: string, params: PotreeLoadParams = {}): Promise<this> {
|
|
65
|
+
const path = (params.path || "") + file;
|
|
66
|
+
const index = path.lastIndexOf("/");
|
|
67
|
+
const baseUrl = path.slice(0, index + 1);
|
|
68
|
+
const url = path.slice(index + 1);
|
|
69
|
+
|
|
70
|
+
const pco = await this.potree.loadPointCloud(url, baseUrl);
|
|
71
|
+
pco.material.size = 1.0;
|
|
72
|
+
pco.material.shape = 2;
|
|
73
|
+
pco.material.inputColorEncoding = 1;
|
|
74
|
+
pco.material.outputColorEncoding = 1;
|
|
75
|
+
pco.material.pointColorType = PointColorType.RGB; // RGB | DEPTH | HEIGHT | POINT_INDEX | LOD | CLASSIFICATION
|
|
76
|
+
pco.material.pointSizeType = PointSizeType.ADAPTIVE; // ADAPTIVE | FIXED
|
|
77
|
+
pco.material.shape = PointShape.CIRCLE; // CIRCLE | SQUARE
|
|
78
|
+
|
|
79
|
+
if (params.position) pco.position.copy(params.position);
|
|
80
|
+
if (params.rotation) pco.rotation.copy(params.rotation);
|
|
81
|
+
if (params.scale) pco.scale.copy(params.scale);
|
|
82
|
+
|
|
83
|
+
this.pointClouds.push(pco);
|
|
84
|
+
|
|
85
|
+
const modelImpl = new PotreeModelImpl(pco);
|
|
86
|
+
modelImpl.loader = this;
|
|
87
|
+
modelImpl.viewer = this.viewer;
|
|
88
|
+
modelImpl.pco = pco;
|
|
89
|
+
|
|
90
|
+
this.viewer.scene.add(pco);
|
|
91
|
+
this.viewer.models.push(modelImpl);
|
|
92
|
+
|
|
93
|
+
this.viewer.syncOptions();
|
|
94
|
+
this.viewer.syncOverlay();
|
|
95
|
+
this.viewer.update();
|
|
96
|
+
|
|
97
|
+
this.viewer.emitEvent({ type: "databasechunk", data: pco, file });
|
|
98
|
+
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
updatePointClouds = () => {
|
|
103
|
+
const result = this.potree.updatePointClouds(this.pointClouds, this.viewer.camera, this.viewer.renderer);
|
|
104
|
+
if (result.exceededMaxLoadsToGPU || result.nodeLoadPromises.length > 0) this.viewer.update();
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
|
|
3
|
+
// All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This software and its documentation and related materials are owned by
|
|
6
|
+
// the Alliance. The software may only be incorporated into application
|
|
7
|
+
// programs owned by members of the Alliance, subject to a signed
|
|
8
|
+
// Membership Agreement and Supplemental Software License Agreement with the
|
|
9
|
+
// Alliance. The structure and organization of this software are the valuable
|
|
10
|
+
// trade secrets of the Alliance and its suppliers. The software is also
|
|
11
|
+
// protected by copyright law and international treaty provisions. Application
|
|
12
|
+
// programs incorporating this software must include the following statement
|
|
13
|
+
// with their copyright notices:
|
|
14
|
+
//
|
|
15
|
+
// This application incorporates Open Design Alliance software pursuant to a
|
|
16
|
+
// license agreement with Open Design Alliance.
|
|
17
|
+
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
|
|
18
|
+
// All rights reserved.
|
|
19
|
+
//
|
|
20
|
+
// By use of this software, its documentation or related materials, you
|
|
21
|
+
// acknowledge and accept the above terms.
|
|
22
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
23
|
+
|
|
24
|
+
import { Box3 } from "three";
|
|
25
|
+
import { PointCloudOctree } from "potree-core";
|
|
26
|
+
import { ModelImpl } from "@inweb/viewer-three";
|
|
27
|
+
|
|
28
|
+
// Potree model implementation.
|
|
29
|
+
|
|
30
|
+
export class PotreeModelImpl extends ModelImpl {
|
|
31
|
+
public pco: PointCloudOctree;
|
|
32
|
+
|
|
33
|
+
override getExtents(target: Box3): Box3 {
|
|
34
|
+
return target.union(this.pco.pcoGeometry.boundingBox);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
|
|
3
|
+
// All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This software and its documentation and related materials are owned by
|
|
6
|
+
// the Alliance. The software may only be incorporated into application
|
|
7
|
+
// programs owned by members of the Alliance, subject to a signed
|
|
8
|
+
// Membership Agreement and Supplemental Software License Agreement with the
|
|
9
|
+
// Alliance. The structure and organization of this software are the valuable
|
|
10
|
+
// trade secrets of the Alliance and its suppliers. The software is also
|
|
11
|
+
// protected by copyright law and international treaty provisions. Application
|
|
12
|
+
// programs incorporating this software must include the following statement
|
|
13
|
+
// with their copyright notices:
|
|
14
|
+
//
|
|
15
|
+
// This application incorporates Open Design Alliance software pursuant to a
|
|
16
|
+
// license agreement with Open Design Alliance.
|
|
17
|
+
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
|
|
18
|
+
// All rights reserved.
|
|
19
|
+
//
|
|
20
|
+
// By use of this software, its documentation or related materials, you
|
|
21
|
+
// acknowledge and accept the above terms.
|
|
22
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
23
|
+
|
|
24
|
+
import { loaders } from "@inweb/viewer-three";
|
|
25
|
+
|
|
26
|
+
import { PotreeFileLoader } from "./PotreeFileLoader";
|
|
27
|
+
|
|
28
|
+
loaders.registerLoader("potree-file", (viewer: any) => new PotreeFileLoader(viewer));
|
package/src/Viewer/Viewer.ts
CHANGED
|
@@ -108,8 +108,8 @@ export class Viewer
|
|
|
108
108
|
private _activeDragger: IDragger | null;
|
|
109
109
|
private _components: IComponent[];
|
|
110
110
|
|
|
111
|
-
private
|
|
112
|
-
private
|
|
111
|
+
private _renderNeeded: boolean;
|
|
112
|
+
private _renderTime: DOMHighResTimeStamp;
|
|
113
113
|
|
|
114
114
|
private _markup: IMarkup;
|
|
115
115
|
|
|
@@ -136,7 +136,7 @@ export class Viewer
|
|
|
136
136
|
this._activeDragger = null;
|
|
137
137
|
this._components = [];
|
|
138
138
|
|
|
139
|
-
this.
|
|
139
|
+
this._renderTime = 0;
|
|
140
140
|
|
|
141
141
|
this.render = this.render.bind(this);
|
|
142
142
|
this.update = this.update.bind(this);
|
|
@@ -170,7 +170,7 @@ export class Viewer
|
|
|
170
170
|
|
|
171
171
|
this.scene = new Scene();
|
|
172
172
|
this.helpers = new Helpers();
|
|
173
|
-
this.target = new Vector3();
|
|
173
|
+
this.target = new Vector3(0, 0, 0);
|
|
174
174
|
|
|
175
175
|
const pixelRatio = window.devicePixelRatio;
|
|
176
176
|
const rect = canvas.parentElement.getBoundingClientRect();
|
|
@@ -178,7 +178,7 @@ export class Viewer
|
|
|
178
178
|
const height = rect.height || 1;
|
|
179
179
|
const aspect = width / height;
|
|
180
180
|
|
|
181
|
-
this.camera = new PerspectiveCamera(45, aspect, 0.
|
|
181
|
+
this.camera = new PerspectiveCamera(45, aspect, 0.001, 1000);
|
|
182
182
|
this.camera.up.set(0, 1, 0);
|
|
183
183
|
this.camera.position.set(0, 0, 1);
|
|
184
184
|
this.camera.lookAt(this.target);
|
|
@@ -217,6 +217,7 @@ export class Viewer
|
|
|
217
217
|
this.composer.addPass(this.fxaaPass);
|
|
218
218
|
this.composer.addPass(this.ssaaRenderPass);
|
|
219
219
|
this.composer.addPass(this.outputPass);
|
|
220
|
+
this.composer.setSize(width, height);
|
|
220
221
|
|
|
221
222
|
this.canvas = canvas;
|
|
222
223
|
this.canvasEvents.forEach((x) => canvas.addEventListener(x, this.canvaseventlistener));
|
|
@@ -230,8 +231,8 @@ export class Viewer
|
|
|
230
231
|
this.syncOptions();
|
|
231
232
|
this.syncOverlay();
|
|
232
233
|
|
|
233
|
-
this.
|
|
234
|
-
this.render(this.
|
|
234
|
+
this._renderTime = performance.now();
|
|
235
|
+
this.render(this._renderTime);
|
|
235
236
|
|
|
236
237
|
if (typeof onProgress === "function")
|
|
237
238
|
onProgress(new ProgressEvent("progress", { lengthComputable: true, loaded: 1, total: 1 }));
|
|
@@ -289,21 +290,44 @@ export class Viewer
|
|
|
289
290
|
return !!this.renderer;
|
|
290
291
|
}
|
|
291
292
|
|
|
293
|
+
setSize(width: number, height: number, updateStyle = true) {
|
|
294
|
+
if (!this.renderer) return;
|
|
295
|
+
|
|
296
|
+
const camera = this.camera as any;
|
|
297
|
+
const aspect = width / height;
|
|
298
|
+
|
|
299
|
+
if (camera.isPerspectiveCamera) {
|
|
300
|
+
camera.aspect = aspect;
|
|
301
|
+
camera.updateProjectionMatrix();
|
|
302
|
+
}
|
|
303
|
+
if (camera.isOrthographicCamera) {
|
|
304
|
+
camera.left = camera.bottom * aspect;
|
|
305
|
+
camera.right = camera.top * aspect;
|
|
306
|
+
camera.updateProjectionMatrix();
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
this.renderer.setSize(width, height, updateStyle);
|
|
310
|
+
this.composer.setSize(width, height);
|
|
311
|
+
|
|
312
|
+
this.update(true);
|
|
313
|
+
this.emitEvent({ type: "resize", width, height });
|
|
314
|
+
}
|
|
315
|
+
|
|
292
316
|
update(force = false): void {
|
|
293
|
-
this.
|
|
317
|
+
this._renderNeeded = true;
|
|
294
318
|
if (force) this.render();
|
|
295
319
|
this.emitEvent({ type: "update", data: force });
|
|
296
320
|
}
|
|
297
321
|
|
|
298
322
|
render(time?: DOMHighResTimeStamp, force = false): void {
|
|
299
323
|
if (!this.renderer) return;
|
|
300
|
-
if (!
|
|
324
|
+
if (!this._renderNeeded && !force) return;
|
|
301
325
|
|
|
302
326
|
if (!time) time = performance.now();
|
|
303
|
-
const deltaTime = (time - this.
|
|
327
|
+
const deltaTime = (time - this._renderTime) / 1000;
|
|
304
328
|
|
|
305
|
-
this.
|
|
306
|
-
this.
|
|
329
|
+
this._renderTime = time;
|
|
330
|
+
this._renderNeeded = false;
|
|
307
331
|
|
|
308
332
|
if (this.options.antialiasing === true || this.options.antialiasing === "msaa") {
|
|
309
333
|
this.renderer.render(this.scene, this.camera);
|
|
@@ -661,7 +685,7 @@ export class Viewer
|
|
|
661
685
|
camera.left = camera.bottom * aspect;
|
|
662
686
|
camera.right = camera.top * aspect;
|
|
663
687
|
camera.near = 0;
|
|
664
|
-
camera.far = extentsSize *
|
|
688
|
+
camera.far = extentsSize * 1000;
|
|
665
689
|
camera.zoom = orthogonal_camera.view_to_world_scale;
|
|
666
690
|
camera.updateProjectionMatrix();
|
|
667
691
|
|
|
@@ -686,8 +710,8 @@ export class Viewer
|
|
|
686
710
|
const camera = new PerspectiveCamera();
|
|
687
711
|
camera.fov = perspective_camera.field_of_view;
|
|
688
712
|
camera.aspect = aspect;
|
|
689
|
-
camera.near = extentsSize /
|
|
690
|
-
camera.far = extentsSize *
|
|
713
|
+
camera.near = extentsSize / 1000;
|
|
714
|
+
camera.far = extentsSize * 1000;
|
|
691
715
|
camera.updateProjectionMatrix();
|
|
692
716
|
|
|
693
717
|
camera.up.copy(getVector3FromPoint3d(perspective_camera.up_vector));
|
|
@@ -21,36 +21,40 @@
|
|
|
21
21
|
// acknowledge and accept the above terms.
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
|
-
import { Sphere, Vector3 } from "three";
|
|
24
|
+
import { Quaternion, Sphere, Vector3 } from "three";
|
|
25
25
|
import type { Viewer } from "../Viewer";
|
|
26
26
|
import { zoomTo } from "./ZoomTo";
|
|
27
27
|
|
|
28
28
|
export const defaultViewPositions = {
|
|
29
|
-
front: new Vector3(0, 0, 1),
|
|
30
|
-
back: new Vector3(0, 0,
|
|
31
|
-
left: new Vector3(
|
|
32
|
-
right: new Vector3(1, 0, 0),
|
|
29
|
+
front: new Vector3(0, 0, -1),
|
|
30
|
+
back: new Vector3(0, 0, 1),
|
|
31
|
+
left: new Vector3(1, 0, 0),
|
|
32
|
+
right: new Vector3(-1, 0, 0),
|
|
33
33
|
bottom: new Vector3(0, -1, 0),
|
|
34
34
|
top: new Vector3(0, 1, 0),
|
|
35
|
-
|
|
36
|
-
sw: new Vector3(
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
se: new Vector3(-1, 1, -1).normalize(),
|
|
36
|
+
sw: new Vector3(1, 1, -1).normalize(),
|
|
37
|
+
ne: new Vector3(-1, 1, 1).normalize(),
|
|
38
|
+
nw: new Vector3(1, 1, 1).normalize(),
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export function setDefaultViewPosition(viewer: Viewer, position: string): void {
|
|
42
|
-
const
|
|
42
|
+
const extentsCenter = viewer.extents.getCenter(new Vector3());
|
|
43
|
+
const extentsSize = viewer.extents.getBoundingSphere(new Sphere()).radius * 2;
|
|
43
44
|
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
45
|
+
const upY = new Vector3(0, 1, 0);
|
|
46
|
+
const offsetY = defaultViewPositions[position] || defaultViewPositions["sw"];
|
|
47
|
+
|
|
48
|
+
const up = new Vector3().copy(viewer.camera.up);
|
|
49
|
+
const quaternion = new Quaternion().setFromUnitVectors(upY, up);
|
|
50
|
+
const offset = new Vector3().copy(offsetY).applyQuaternion(quaternion);
|
|
47
51
|
|
|
48
52
|
const camera = viewer.camera;
|
|
49
|
-
camera.position.copy(
|
|
50
|
-
camera.lookAt(
|
|
53
|
+
camera.position.copy(offset).multiplyScalar(extentsSize).add(extentsCenter);
|
|
54
|
+
camera.lookAt(extentsCenter);
|
|
51
55
|
camera.updateMatrixWorld();
|
|
52
56
|
|
|
53
|
-
viewer.target.copy(
|
|
57
|
+
viewer.target.copy(extentsCenter);
|
|
54
58
|
|
|
55
59
|
viewer.update();
|
|
56
60
|
viewer.emit({ type: "viewposition", data: position });
|
|
@@ -27,8 +27,8 @@ import type { Viewer } from "../Viewer";
|
|
|
27
27
|
export function zoomTo(viewer: Viewer, box: Box3): void {
|
|
28
28
|
if (box.isEmpty()) return;
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
const
|
|
30
|
+
const boxCenter = box.getCenter(new Vector3());
|
|
31
|
+
const boxSize = box.getBoundingSphere(new Sphere()).radius;
|
|
32
32
|
|
|
33
33
|
const rendererSize = viewer.renderer.getSize(new Vector2());
|
|
34
34
|
const aspect = rendererSize.x / rendererSize.y;
|
|
@@ -36,30 +36,30 @@ export function zoomTo(viewer: Viewer, box: Box3): void {
|
|
|
36
36
|
const camera = viewer.camera as any;
|
|
37
37
|
|
|
38
38
|
if (camera.isPerspectiveCamera) {
|
|
39
|
-
const offset = new Vector3(0, 0, 1)
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
const offset = new Vector3(0, 0, 1)
|
|
40
|
+
.applyQuaternion(camera.quaternion)
|
|
41
|
+
.multiplyScalar(boxSize / Math.tan(MathUtils.DEG2RAD * camera.fov * 0.5));
|
|
42
42
|
|
|
43
|
-
camera.position.copy(
|
|
43
|
+
camera.position.copy(offset).add(boxCenter);
|
|
44
44
|
camera.updateMatrixWorld();
|
|
45
45
|
}
|
|
46
46
|
if (camera.isOrthographicCamera) {
|
|
47
|
-
camera.top =
|
|
48
|
-
camera.bottom = -
|
|
47
|
+
camera.top = boxSize;
|
|
48
|
+
camera.bottom = -boxSize;
|
|
49
49
|
camera.left = camera.bottom * aspect;
|
|
50
50
|
camera.right = camera.top * aspect;
|
|
51
51
|
camera.zoom = 1;
|
|
52
52
|
camera.updateProjectionMatrix();
|
|
53
53
|
|
|
54
|
-
const offset = new Vector3(0, 0, 1)
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
const offset = new Vector3(0, 0, 1)
|
|
55
|
+
.applyQuaternion(camera.quaternion)
|
|
56
|
+
.multiplyScalar(viewer.extents.getBoundingSphere(new Sphere()).radius * 3);
|
|
57
57
|
|
|
58
|
-
camera.position.copy(
|
|
58
|
+
camera.position.copy(offset).add(boxCenter);
|
|
59
59
|
camera.updateMatrixWorld();
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
viewer.target.copy(
|
|
62
|
+
viewer.target.copy(boxCenter);
|
|
63
63
|
|
|
64
64
|
viewer.update();
|
|
65
65
|
viewer.emitEvent({ type: "zoom" });
|
|
@@ -55,6 +55,6 @@ export class ExtentsComponent implements IComponent {
|
|
|
55
55
|
this.viewer.models.forEach((model) => model.getExtents(extents));
|
|
56
56
|
|
|
57
57
|
this.viewer.extents.copy(extents);
|
|
58
|
-
extents.getCenter(this.viewer.target);
|
|
58
|
+
this.viewer.extents.getCenter(this.viewer.target);
|
|
59
59
|
};
|
|
60
60
|
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// acknowledge and accept the above terms.
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
|
-
import { AmbientLight, DirectionalLight, HemisphereLight, Sphere, Vector3 } from "three";
|
|
24
|
+
import { AmbientLight, DirectionalLight, HemisphereLight, Quaternion, Sphere, Vector3 } from "three";
|
|
25
25
|
|
|
26
26
|
import { IComponent } from "@inweb/viewer-core";
|
|
27
27
|
import type { Viewer } from "../Viewer";
|
|
@@ -73,13 +73,15 @@ export class LightComponent implements IComponent {
|
|
|
73
73
|
const extentsCenter = this.viewer.extents.getCenter(new Vector3());
|
|
74
74
|
const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius;
|
|
75
75
|
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
const upY = new Vector3(0, 1, 0);
|
|
77
|
+
const frontY = new Vector3(0, 0, -1);
|
|
78
|
+
|
|
79
|
+
const up = new Vector3().copy(this.viewer.camera.up);
|
|
80
|
+
const quaternion = new Quaternion().setFromUnitVectors(upY, up);
|
|
81
|
+
const front = new Vector3().copy(frontY).applyQuaternion(quaternion).negate();
|
|
80
82
|
|
|
81
83
|
this.directionalLight.position
|
|
82
|
-
.copy(
|
|
84
|
+
.copy(up)
|
|
83
85
|
.applyAxisAngle(front, (-Math.PI * 30) / 180)
|
|
84
86
|
.multiplyScalar(extentsSize * 2)
|
|
85
87
|
.add(extentsCenter);
|
|
@@ -43,23 +43,6 @@ export class ResizeCanvasComponent implements IComponent {
|
|
|
43
43
|
|
|
44
44
|
if (!width || !height) return; // <- invisible viewer, or viewer with parent removed
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
const aspect = width / height;
|
|
48
|
-
|
|
49
|
-
if (camera.isPerspectiveCamera) {
|
|
50
|
-
camera.aspect = aspect;
|
|
51
|
-
camera.updateProjectionMatrix();
|
|
52
|
-
}
|
|
53
|
-
if (camera.isOrthographicCamera) {
|
|
54
|
-
camera.left = camera.bottom * aspect;
|
|
55
|
-
camera.right = camera.top * aspect;
|
|
56
|
-
camera.updateProjectionMatrix();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
this.viewer.renderer.setSize(width, height, true);
|
|
60
|
-
this.viewer.composer.setSize(width, height);
|
|
61
|
-
|
|
62
|
-
this.viewer.update(true);
|
|
63
|
-
this.viewer.emitEvent({ type: "resize", width, height });
|
|
46
|
+
this.viewer.setSize(width, height);
|
|
64
47
|
};
|
|
65
48
|
}
|
|
@@ -81,6 +81,13 @@ export class OrbitDragger implements IDragger {
|
|
|
81
81
|
this.viewer.update();
|
|
82
82
|
|
|
83
83
|
switch (this.orbit.state) {
|
|
84
|
+
case STATE.ROTATE:
|
|
85
|
+
case STATE.TOUCH_ROTATE:
|
|
86
|
+
this.viewer.emitEvent({
|
|
87
|
+
type: "orbit",
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
|
|
84
91
|
case STATE.PAN:
|
|
85
92
|
case STATE.TOUCH_PAN:
|
|
86
93
|
this.viewer.emitEvent({
|
|
@@ -102,6 +109,8 @@ export class OrbitDragger implements IDragger {
|
|
|
102
109
|
break;
|
|
103
110
|
}
|
|
104
111
|
|
|
112
|
+
this.viewer.emitEvent({ type: "changecamera" });
|
|
113
|
+
|
|
105
114
|
this.changed = true;
|
|
106
115
|
};
|
|
107
116
|
|
|
@@ -28,9 +28,9 @@ export class WCSHelper extends Object3D {
|
|
|
28
28
|
this.orthoCamera = new OrthographicCamera(-2, 2, 2, -2, 0, 4);
|
|
29
29
|
this.orthoCamera.position.set(0, 0, 2);
|
|
30
30
|
|
|
31
|
-
const matRed = new MeshBasicMaterial({ toneMapped: false, color: "#
|
|
32
|
-
const matGreen = new MeshBasicMaterial({ toneMapped: false, color: "#
|
|
33
|
-
const matBlue = new MeshBasicMaterial({ toneMapped: false, color: "#
|
|
31
|
+
const matRed = new MeshBasicMaterial({ toneMapped: false, color: "#dd0000" });
|
|
32
|
+
const matGreen = new MeshBasicMaterial({ toneMapped: false, color: "#00dd00" });
|
|
33
|
+
const matBlue = new MeshBasicMaterial({ toneMapped: false, color: "#0000dd" });
|
|
34
34
|
|
|
35
35
|
const spriteRed = this.getSpriteMaterial(matRed.color, "X");
|
|
36
36
|
const spriteGreen = this.getSpriteMaterial(matGreen.color, "Y");
|