@xeokit/xeokit-sdk 2.6.54 → 2.6.57
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/xeokit-sdk.cjs.js +1414 -1786
- package/dist/xeokit-sdk.es.js +1412 -1787
- package/dist/xeokit-sdk.es5.js +732 -725
- package/dist/xeokit-sdk.min.cjs.js +5 -5
- package/dist/xeokit-sdk.min.es.js +5 -5
- package/dist/xeokit-sdk.min.es5.js +4 -4
- package/package.json +1 -1
- package/src/plugins/AngleMeasurementsPlugin/AngleMeasurement.js +155 -415
- package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +1 -1
- package/src/plugins/AnnotationsPlugin/Annotation.js +7 -5
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.js +236 -750
- package/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js +51 -0
- package/src/plugins/TreeViewPlugin/RenderService.js +2 -1
- package/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js +5 -1
- package/src/plugins/ZonesPlugin/ZonesPlugin.js +15 -79
- package/src/plugins/lib/html/Dot.js +14 -41
- package/src/plugins/lib/html/Label.js +10 -37
- package/src/plugins/lib/html/MenuEvent.js +74 -0
- package/src/plugins/lib/html/Wire.js +20 -47
- package/src/plugins/lib/ui/index.js +370 -12
- package/src/viewer/Viewer.js +9 -0
- package/src/viewer/index.js +1 -0
- package/src/viewer/scene/CameraControl/CameraControl.js +38 -0
- package/src/viewer/scene/CameraControl/lib/CameraUpdater.js +5 -4
- package/src/viewer/scene/CameraControl/lib/handlers/KeyboardPanRotateDollyHandler.js +0 -8
- package/src/viewer/scene/CameraControl/lib/handlers/MousePanRotateDollyHandler.js +1 -2
- package/src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js +2 -1
- package/src/viewer/scene/marker/Marker.js +20 -23
- package/src/viewer/scene/model/SceneModelEntity.js +5 -0
- package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +1 -1
- package/src/viewer/utils/index.js +1 -0
- package/src/viewer/utils/os.js +8 -1
- package/types/viewer/scene/CameraControl/CameraControl.d.ts +23 -0
- package/types/viewer/scene/models/PerformanceModel/index.d.ts +0 -1
- package/types/viewer/scene/models/SceneModel.d.ts +0 -3
- package/types/viewer/scene/models/SceneModelEntity.d.ts +6 -0
- package/types/viewer/scene/nodes/Node.d.ts +1 -1
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import {Dot} from "../html/Dot.js";
|
|
2
|
+
import {Label} from "../html/Label.js";
|
|
3
|
+
import {Wire} from "../html/Wire.js";
|
|
2
4
|
import {math} from "../../../viewer/scene/math/math.js";
|
|
3
5
|
import {Marker} from "../../../viewer/scene/marker/Marker.js";
|
|
4
6
|
|
|
7
|
+
const tmpVec2a = math.vec2();
|
|
8
|
+
const tmpVec2b = math.vec2();
|
|
9
|
+
const tmpVec2c = math.vec2();
|
|
10
|
+
const tmpVec2d = math.vec2();
|
|
11
|
+
const tmpVec3a = math.vec3();
|
|
12
|
+
const tmpVec3b = math.vec3();
|
|
13
|
+
const tmpVec4a = math.vec4();
|
|
14
|
+
const tmpVec4b = math.vec4();
|
|
15
|
+
const tmpVec4c = math.vec4();
|
|
16
|
+
const tmpVec4d = math.vec4();
|
|
17
|
+
|
|
5
18
|
const nop = () => { };
|
|
6
19
|
|
|
7
20
|
export function transformToNode(from, to, vec) {
|
|
@@ -11,10 +24,124 @@ export function transformToNode(from, to, vec) {
|
|
|
11
24
|
vec[1] += fromRec.top - toRec.top;
|
|
12
25
|
};
|
|
13
26
|
|
|
27
|
+
const toClipSpace = (camera, worldPos, p) => {
|
|
28
|
+
// to homogeneous coords
|
|
29
|
+
p.set(worldPos);
|
|
30
|
+
p[3] = 1;
|
|
31
|
+
|
|
32
|
+
// to clip space
|
|
33
|
+
math.mulMat4v4(camera.viewMatrix, p, p);
|
|
34
|
+
math.mulMat4v4(camera.projMatrix, p, p);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const toCanvasSpace = (canvas, parentElement, ndc, p) => {
|
|
38
|
+
p[0] = (1 + ndc[0]) * 0.5 * canvas.offsetWidth;
|
|
39
|
+
p[1] = (1 - ndc[1]) * 0.5 * canvas.offsetHeight;
|
|
40
|
+
transformToNode(canvas, parentElement, p);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const clipSegment = (scene, parentElement, start, end, canvasStart, canvasEnd) => {
|
|
44
|
+
const camera = scene.camera;
|
|
45
|
+
const canvas = scene.canvas.canvas;
|
|
46
|
+
|
|
47
|
+
if (math.distVec3(start, end) < 0.001) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const delta = math.subVec3(end, start, tmpVec3a);
|
|
52
|
+
let s_min = 0.0;
|
|
53
|
+
let s_max = 1.0;
|
|
54
|
+
|
|
55
|
+
for (let plane of scene._sectionPlanesState.sectionPlanes) {
|
|
56
|
+
const endDot = math.dotVec3(plane.dir, math.subVec3(plane.pos, end, tmpVec3b));
|
|
57
|
+
const startDot = math.dotVec3(plane.dir, math.subVec3(plane.pos, start, tmpVec3b));
|
|
58
|
+
|
|
59
|
+
if ((startDot > 0) && (endDot > 0)) {
|
|
60
|
+
return false;
|
|
61
|
+
} else if ((startDot > 0) || (endDot > 0)) {
|
|
62
|
+
const denom = math.dotVec3(plane.dir, delta);
|
|
63
|
+
if (Math.abs(denom) >= 1e-6) {
|
|
64
|
+
const ratio = math.dotVec3(plane.dir, tmpVec3b) / denom;
|
|
65
|
+
if (startDot > 0) {
|
|
66
|
+
s_min = Math.max(s_min, ratio);
|
|
67
|
+
} else {
|
|
68
|
+
s_max = Math.min(s_max, ratio);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const p0 = tmpVec4a;
|
|
75
|
+
const p1 = tmpVec4b;
|
|
76
|
+
toClipSpace(camera, (s_min > 0) ? math.addVec3(start, math.mulVec3Scalar(delta, s_min, tmpVec3b), tmpVec3b) : start, p0);
|
|
77
|
+
toClipSpace(camera, (s_max < 1) ? math.addVec3(start, math.mulVec3Scalar(delta, s_max, tmpVec3b), tmpVec3b) : end, p1);
|
|
78
|
+
|
|
79
|
+
const p0Behind = ((p0[2] / p0[3]) < -1) || (p0[3] < 0);
|
|
80
|
+
const p1Behind = ((p1[2] / p1[3]) < -1) || (p1[3] < 0);
|
|
81
|
+
if (p0Behind && p1Behind) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const t = (p0[3] + p0[2]) / ((p0[3] + p0[2]) - (p1[3] + p1[2]));
|
|
86
|
+
|
|
87
|
+
if ((t > 0) && (t < 1)) { //p0Behind || p1Behind) {
|
|
88
|
+
// Find the intersection of a segment with the near plane in clip space, if it exists."""
|
|
89
|
+
// Calculate the interpolation factor t where the line segment crosses the near plane
|
|
90
|
+
const delta = math.subVec4(p1, p0, tmpVec4c);
|
|
91
|
+
math.mulVec4Scalar(delta, t, delta);
|
|
92
|
+
math.addVec4(p0, delta, p0Behind ? p0 : p1);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// normalize clip space coords
|
|
96
|
+
math.mulVec4Scalar(p0, 1.0 / p0[3]);
|
|
97
|
+
math.mulVec4Scalar(p1, 1.0 / p1[3]);
|
|
98
|
+
|
|
99
|
+
let t_min = 0.0;
|
|
100
|
+
let t_max = 1.0;
|
|
101
|
+
|
|
102
|
+
// If either point is outside the view frustum, clip the line segment
|
|
103
|
+
|
|
104
|
+
for (let i = 0; i < 2; ++i) {
|
|
105
|
+
const denom = p1[i] - p0[i];
|
|
106
|
+
|
|
107
|
+
const l = (-p0[3] - p0[i]) / denom;
|
|
108
|
+
const r = ( p0[3] - p0[i]) / denom;
|
|
109
|
+
|
|
110
|
+
if (denom > 0) {
|
|
111
|
+
t_min = Math.max(t_min, l);
|
|
112
|
+
t_max = Math.min(t_max, r);
|
|
113
|
+
} else {
|
|
114
|
+
t_min = Math.max(t_min, r);
|
|
115
|
+
t_max = Math.min(t_max, l);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (t_min >= t_max) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Calculate the clipped start and end points
|
|
124
|
+
const ndcDelta = math.subVec4(p1, p0, tmpVec4c);
|
|
125
|
+
math.addVec4(p0, math.mulVec4Scalar(ndcDelta, t_max, tmpVec4d), p1);
|
|
126
|
+
math.addVec4(p0, math.mulVec4Scalar(ndcDelta, t_min, tmpVec4d), p0);
|
|
127
|
+
|
|
128
|
+
math.mulVec4Scalar(p0, 1 / p0[3]);
|
|
129
|
+
math.mulVec4Scalar(p1, 1 / p1[3]);
|
|
130
|
+
|
|
131
|
+
toCanvasSpace(canvas, parentElement, p0, canvasStart);
|
|
132
|
+
toCanvasSpace(canvas, parentElement, p1, canvasEnd);
|
|
133
|
+
|
|
134
|
+
return true;
|
|
135
|
+
};
|
|
136
|
+
|
|
14
137
|
export class Dot3D extends Marker {
|
|
15
138
|
constructor(scene, markerCfg, parentElement, cfg = {}) {
|
|
139
|
+
const camera = scene.camera;
|
|
140
|
+
|
|
16
141
|
super(scene, markerCfg);
|
|
17
142
|
|
|
143
|
+
this.__visible = true; // "__" to not interfere with Marker::_visible
|
|
144
|
+
|
|
18
145
|
const handler = (cfgEvent, componentEvent) => {
|
|
19
146
|
return event => {
|
|
20
147
|
if (cfgEvent) {
|
|
@@ -24,6 +151,7 @@ export class Dot3D extends Marker {
|
|
|
24
151
|
};
|
|
25
152
|
};
|
|
26
153
|
this._dot = new Dot(parentElement, {
|
|
154
|
+
borderColor: cfg.borderColor,
|
|
27
155
|
fillColor: cfg.fillColor,
|
|
28
156
|
zIndex: cfg.zIndex,
|
|
29
157
|
onMouseOver: handler(cfg.onMouseOver, "mouseover"),
|
|
@@ -38,19 +166,62 @@ export class Dot3D extends Marker {
|
|
|
38
166
|
onContextMenu: handler(cfg.onContextMenu, "contextmenu")
|
|
39
167
|
});
|
|
40
168
|
|
|
169
|
+
const toClipSpace = (worldPos, p) => {
|
|
170
|
+
// to homogeneous coords
|
|
171
|
+
p.set(worldPos);
|
|
172
|
+
p[3] = 1;
|
|
173
|
+
|
|
174
|
+
// to clip space
|
|
175
|
+
math.mulMat4v4(camera.viewMatrix, p, p);
|
|
176
|
+
math.mulMat4v4(camera.projMatrix, p, p);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const toCanvasSpace = ndc => {
|
|
180
|
+
const canvas = scene.canvas.canvas;
|
|
181
|
+
ndc[0] = (1 + ndc[0]) * 0.5 * canvas.offsetWidth;
|
|
182
|
+
ndc[1] = (1 - ndc[1]) * 0.5 * canvas.offsetHeight;
|
|
183
|
+
transformToNode(canvas, parentElement, ndc);
|
|
184
|
+
};
|
|
185
|
+
|
|
41
186
|
const updateDotPos = () => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
187
|
+
if (! this.__visible) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const p0 = tmpVec4c;
|
|
191
|
+
toClipSpace(this.worldPos, p0);
|
|
192
|
+
math.mulVec3Scalar(p0, 1.0 / p0[3]);
|
|
193
|
+
|
|
194
|
+
const outsideFrustum = ((p0[3] < 0)
|
|
195
|
+
||
|
|
196
|
+
(p0[0] < -1) || (p0[0] > 1)
|
|
197
|
+
||
|
|
198
|
+
(p0[1] < -1) || (p0[1] > 1)
|
|
199
|
+
||
|
|
200
|
+
(p0[2] < -1) || (p0[2] > 1));
|
|
201
|
+
const culled = outsideFrustum || scene._sectionPlanesState.sectionPlanes.some(
|
|
202
|
+
plane => (math.dotVec3(plane.dir, math.subVec3(plane.pos, this.worldPos, tmpVec3a)) > 0));
|
|
203
|
+
|
|
204
|
+
this._dot.setCulled(culled);
|
|
205
|
+
if (!culled) {
|
|
206
|
+
toCanvasSpace(p0);
|
|
207
|
+
this._dot.setPos(p0[0], p0[1]);
|
|
208
|
+
}
|
|
45
209
|
};
|
|
46
210
|
|
|
47
211
|
this.on("worldPos", updateDotPos);
|
|
48
212
|
|
|
49
|
-
const onViewMatrix =
|
|
50
|
-
const onProjMatrix =
|
|
213
|
+
const onViewMatrix = camera.on("viewMatrix", updateDotPos);
|
|
214
|
+
const onProjMatrix = camera.on("projMatrix", updateDotPos);
|
|
215
|
+
const onCanvasBnd = scene.canvas.on("boundary", updateDotPos);
|
|
216
|
+
const planesUpdate = scene.on("sectionPlaneUpdated", updateDotPos);
|
|
217
|
+
|
|
218
|
+
this._updatePosition = updateDotPos;
|
|
219
|
+
|
|
51
220
|
this._cleanup = () => {
|
|
52
|
-
|
|
53
|
-
|
|
221
|
+
camera.off(onViewMatrix);
|
|
222
|
+
camera.off(onProjMatrix);
|
|
223
|
+
scene.canvas.off(onCanvasBnd);
|
|
224
|
+
scene.off(planesUpdate);
|
|
54
225
|
this._dot.destroy();
|
|
55
226
|
};
|
|
56
227
|
}
|
|
@@ -59,14 +230,14 @@ export class Dot3D extends Marker {
|
|
|
59
230
|
this._dot.setClickable(value);
|
|
60
231
|
}
|
|
61
232
|
|
|
62
|
-
setCulled(value) {
|
|
63
|
-
this._dot.setCulled(value);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
233
|
setFillColor(value) {
|
|
67
234
|
this._dot.setFillColor(value);
|
|
68
235
|
}
|
|
69
236
|
|
|
237
|
+
setBorderColor(value) {
|
|
238
|
+
this._dot.setBorderColor(value);
|
|
239
|
+
}
|
|
240
|
+
|
|
70
241
|
setHighlighted(value) {
|
|
71
242
|
this._dot.setHighlighted(value);
|
|
72
243
|
}
|
|
@@ -76,7 +247,11 @@ export class Dot3D extends Marker {
|
|
|
76
247
|
}
|
|
77
248
|
|
|
78
249
|
setVisible(value) {
|
|
79
|
-
this.
|
|
250
|
+
if (this.__visible != value) {
|
|
251
|
+
this.__visible = value;
|
|
252
|
+
this._updatePosition();
|
|
253
|
+
this._dot.setVisible(value);
|
|
254
|
+
}
|
|
80
255
|
}
|
|
81
256
|
|
|
82
257
|
destroy() {
|
|
@@ -86,6 +261,189 @@ export class Dot3D extends Marker {
|
|
|
86
261
|
|
|
87
262
|
}
|
|
88
263
|
|
|
264
|
+
export class Label3D {
|
|
265
|
+
constructor(scene, parentElement, cfg) {
|
|
266
|
+
const camera = scene.camera;
|
|
267
|
+
|
|
268
|
+
this._label = new Label(parentElement, cfg);
|
|
269
|
+
this._start = math.vec3();
|
|
270
|
+
this._mid = math.vec3();
|
|
271
|
+
this._end = math.vec3();
|
|
272
|
+
this._yOff = 0;
|
|
273
|
+
this._betweenWires = false;
|
|
274
|
+
this.__visible = true;
|
|
275
|
+
|
|
276
|
+
const setPosOnWire = (p0, p1, yOff) => {
|
|
277
|
+
p0[0] += p1[0];
|
|
278
|
+
p0[1] += p1[1];
|
|
279
|
+
math.mulVec2Scalar(p0, .5);
|
|
280
|
+
this._label.setPos(p0[0], p0[1] + yOff);
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
this._updatePositions = () => {
|
|
284
|
+
if (! this.__visible) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (this._betweenWires) {
|
|
288
|
+
const visibleA = clipSegment(scene, parentElement, this._start, this._mid, tmpVec2a, tmpVec2b);
|
|
289
|
+
const visibleB = clipSegment(scene, parentElement, this._end, this._mid, tmpVec2c, tmpVec2d);
|
|
290
|
+
this._label.setCulled(! (visibleA || visibleB));
|
|
291
|
+
if (visibleA && visibleB) {
|
|
292
|
+
tmpVec2b[0] += tmpVec2d[0];
|
|
293
|
+
tmpVec2b[1] += tmpVec2d[1];
|
|
294
|
+
math.mulVec2Scalar(tmpVec2b, .5);
|
|
295
|
+
|
|
296
|
+
tmpVec2b[0] += tmpVec2a[0] + tmpVec2c[0];
|
|
297
|
+
tmpVec2b[1] += tmpVec2a[1] + tmpVec2c[1];
|
|
298
|
+
math.mulVec2Scalar(tmpVec2b, 1/3);
|
|
299
|
+
this._label.setPos(tmpVec2b[0], tmpVec2b[1]);
|
|
300
|
+
} else if (visibleA) {
|
|
301
|
+
setPosOnWire(tmpVec2a, tmpVec2b, 0);
|
|
302
|
+
} else if (visibleB) {
|
|
303
|
+
setPosOnWire(tmpVec2c, tmpVec2d, 0);
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
const visible = (clipSegment(scene, parentElement, this._start, this._end, tmpVec2a, tmpVec2b)
|
|
307
|
+
&&
|
|
308
|
+
(math.distVec2(tmpVec2a, tmpVec2b) >= this._labelMinAxisLength));
|
|
309
|
+
this._label.setCulled(!visible);
|
|
310
|
+
if (visible) {
|
|
311
|
+
setPosOnWire(tmpVec2a, tmpVec2b, this._yOff);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
const onViewMatrix = camera.on("viewMatrix", this._updatePositions);
|
|
317
|
+
const onProjMatrix = camera.on("projMatrix", this._updatePositions);
|
|
318
|
+
const onCanvasBnd = scene.canvas.on("boundary", this._updatePositions);
|
|
319
|
+
const planesUpdate = scene.on("sectionPlaneUpdated", this._updatePositions);
|
|
320
|
+
|
|
321
|
+
this._cleanup = () => {
|
|
322
|
+
camera.off(onViewMatrix);
|
|
323
|
+
camera.off(onProjMatrix);
|
|
324
|
+
scene.canvas.off(onCanvasBnd);
|
|
325
|
+
scene.off(planesUpdate);
|
|
326
|
+
this._label.destroy();
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
setPosOnWire(p0, p1, yOff, labelMinAxisLength) {
|
|
331
|
+
this._start.set(p0);
|
|
332
|
+
this._end.set(p1);
|
|
333
|
+
this._yOff = yOff;
|
|
334
|
+
this._labelMinAxisLength = labelMinAxisLength;
|
|
335
|
+
this._betweenWires = false;
|
|
336
|
+
this._updatePositions();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
setPosBetween(p0, p1, p2) {
|
|
340
|
+
this._start.set(p0);
|
|
341
|
+
this._mid.set(p1);
|
|
342
|
+
this._end.set(p2);
|
|
343
|
+
this._betweenWires = true;
|
|
344
|
+
this._updatePositions();
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
setFillColor(value) {
|
|
348
|
+
this._label.setFillColor(value);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
setHighlighted(value) {
|
|
352
|
+
this._label.setHighlighted(value);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
setText(value) {
|
|
356
|
+
this._label.setText(value);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
setClickable(value) {
|
|
360
|
+
this._label.setClickable(value);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
setVisible(value) {
|
|
364
|
+
if (this.__visible != value) {
|
|
365
|
+
this.__visible = value;
|
|
366
|
+
this._updatePositions();
|
|
367
|
+
this._label.setVisible(value);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
destroy() {
|
|
372
|
+
this._cleanup();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export class Wire3D {
|
|
378
|
+
constructor(scene, parentElement, cfg) {
|
|
379
|
+
const camera = scene.camera;
|
|
380
|
+
|
|
381
|
+
this._wire = new Wire(parentElement, cfg);
|
|
382
|
+
this._start = math.vec3();
|
|
383
|
+
this._end = math.vec3();
|
|
384
|
+
this.__visible = true;
|
|
385
|
+
|
|
386
|
+
this._updatePositions = () => {
|
|
387
|
+
if (! this.__visible) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const visible = clipSegment(scene, parentElement, this._start, this._end, tmpVec2a, tmpVec2b);
|
|
391
|
+
this._wire.setCulled(! visible);
|
|
392
|
+
if (visible) {
|
|
393
|
+
this._wire.setStartAndEnd(tmpVec2a[0], tmpVec2a[1], tmpVec2b[0], tmpVec2b[1]);
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
const onViewMatrix = camera.on("viewMatrix", this._updatePositions);
|
|
398
|
+
const onProjMatrix = camera.on("projMatrix", this._updatePositions);
|
|
399
|
+
const onCanvasBnd = scene.canvas.on("boundary", this._updatePositions);
|
|
400
|
+
const planesUpdate = scene.on("sectionPlaneUpdated", this._updatePositions);
|
|
401
|
+
|
|
402
|
+
this._cleanup = () => {
|
|
403
|
+
camera.off(onViewMatrix);
|
|
404
|
+
camera.off(onProjMatrix);
|
|
405
|
+
scene.canvas.off(onCanvasBnd);
|
|
406
|
+
scene.off(planesUpdate);
|
|
407
|
+
this._wire.destroy();
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
setEnds(start, end) {
|
|
412
|
+
this._start.set(start);
|
|
413
|
+
this._end.set(end);
|
|
414
|
+
this._updatePositions();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
setClickable(value) {
|
|
418
|
+
this._wire.setClickable(value);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
setColor(value) {
|
|
422
|
+
this._wire.setColor(value);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
setHighlighted(value) {
|
|
426
|
+
this._wire.setHighlighted(value);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
setOpacity(value) {
|
|
430
|
+
this._wire.setOpacity(value);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
setVisible(value) {
|
|
434
|
+
if (this.__visible != value) {
|
|
435
|
+
this.__visible = value;
|
|
436
|
+
this._updatePositions();
|
|
437
|
+
this._wire.setVisible(value);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
destroy() {
|
|
442
|
+
this._cleanup();
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
}
|
|
446
|
+
|
|
89
447
|
export function activateDraggableDot(dot, cfg) {
|
|
90
448
|
const extractCFG = function(propName, defaultValue) {
|
|
91
449
|
if (propName in cfg) {
|
package/src/viewer/Viewer.js
CHANGED
|
@@ -491,6 +491,12 @@ class Viewer {
|
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
493
|
|
|
494
|
+
// Added to fix label's text offset in an html2canvas capture (See XEOK-151)
|
|
495
|
+
// based on https://github.com/niklasvh/html2canvas/issues/2775#issuecomment-1316356991
|
|
496
|
+
const style = document.createElement('style');
|
|
497
|
+
document.head.appendChild(style);
|
|
498
|
+
style.sheet?.insertRule('body > div:last-child img { display: inline-block; }');
|
|
499
|
+
|
|
494
500
|
for (let i = 0, len = pluginContainerElements.length; i < len; i++) {
|
|
495
501
|
const containerElement = pluginContainerElements[i];
|
|
496
502
|
await html2canvas(containerElement, {
|
|
@@ -503,6 +509,9 @@ class Viewer {
|
|
|
503
509
|
// (implemented to compensate XCD-153 issue)
|
|
504
510
|
snapshotCanvas.getContext("2d").resetTransform();
|
|
505
511
|
}
|
|
512
|
+
|
|
513
|
+
style.remove();
|
|
514
|
+
|
|
506
515
|
if (!params.includeGizmos) {
|
|
507
516
|
this.sendToPlugins("snapshotFinished");
|
|
508
517
|
}
|
package/src/viewer/index.js
CHANGED
|
@@ -820,6 +820,13 @@ class CameraControl extends Component {
|
|
|
820
820
|
new KeyboardPanRotateDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates)
|
|
821
821
|
];
|
|
822
822
|
|
|
823
|
+
this._cursors = {
|
|
824
|
+
dollyForward: "zoom-in",
|
|
825
|
+
dollyBackward: "zoom-out",
|
|
826
|
+
rotate: 'grabbing',
|
|
827
|
+
pan: 'move',
|
|
828
|
+
}
|
|
829
|
+
|
|
823
830
|
// Applies scheduled updates to the Camera on each Scene "tick" event
|
|
824
831
|
|
|
825
832
|
this._cameraUpdater = new CameraUpdater(this.scene, this._controllers, this._configs, this._states, this._updates);
|
|
@@ -1181,6 +1188,37 @@ class CameraControl extends Component {
|
|
|
1181
1188
|
this._configs.pointerEnabled = !!value;
|
|
1182
1189
|
}
|
|
1183
1190
|
|
|
1191
|
+
/**
|
|
1192
|
+
* Sets the cursor to be used when a particular action is being performed.
|
|
1193
|
+
*
|
|
1194
|
+
* Accepted actions are:
|
|
1195
|
+
*
|
|
1196
|
+
* * "dollyForward" - when the camera is dollying in the forward direction
|
|
1197
|
+
* * "dollyBackward" - when the camera is dollying in the backward direction
|
|
1198
|
+
* * "pan" - when the camera is being panned
|
|
1199
|
+
* * "rotate" - when the camera is being rotated
|
|
1200
|
+
*
|
|
1201
|
+
* @param {String} action
|
|
1202
|
+
* @param {String} style
|
|
1203
|
+
*/
|
|
1204
|
+
setCursorStyle(action, style) {
|
|
1205
|
+
if (Object.prototype.hasOwnProperty.call(this._cursors, action)) {
|
|
1206
|
+
this._cursors = { ...this._cursors, [action]: style };
|
|
1207
|
+
}
|
|
1208
|
+
else
|
|
1209
|
+
console.warn(`Action '${action}' is not valid for cursor styles.`);
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/**
|
|
1213
|
+
* Gets the current style for a particular action.
|
|
1214
|
+
*
|
|
1215
|
+
* @param {String} action To get the style for
|
|
1216
|
+
* @returns {String} style set on the cursor for action
|
|
1217
|
+
*/
|
|
1218
|
+
getCursorStyle(action) {
|
|
1219
|
+
return this._cursors[action] || null;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1184
1222
|
_reset() {
|
|
1185
1223
|
for (let i = 0, len = this._handlers.length; i < len; i++) {
|
|
1186
1224
|
const handler = this._handlers[i];
|
|
@@ -18,6 +18,7 @@ class CameraUpdater {
|
|
|
18
18
|
const pickController = controllers.pickController;
|
|
19
19
|
const pivotController = controllers.pivotController;
|
|
20
20
|
const panController = controllers.panController;
|
|
21
|
+
const cameraControl = controllers.cameraControl;
|
|
21
22
|
|
|
22
23
|
let countDown = SCALE_DOLLY_EACH_FRAME; // Decrements on each tick
|
|
23
24
|
let dollyDistFactor = 1.0; // Calculated when countDown is zero
|
|
@@ -142,7 +143,7 @@ class CameraUpdater {
|
|
|
142
143
|
updates.rotateDeltaX *= configs.rotationInertia;
|
|
143
144
|
updates.rotateDeltaY *= configs.rotationInertia;
|
|
144
145
|
|
|
145
|
-
cursorType =
|
|
146
|
+
cursorType = cameraControl._cursors.rotate;
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
//----------------------------------------------------------------------------------------------------------
|
|
@@ -208,7 +209,7 @@ class CameraUpdater {
|
|
|
208
209
|
camera.pan(vec);
|
|
209
210
|
}
|
|
210
211
|
|
|
211
|
-
cursorType =
|
|
212
|
+
cursorType = cameraControl._cursors.pan;
|
|
212
213
|
}
|
|
213
214
|
|
|
214
215
|
updates.panDeltaX *= configs.panInertia;
|
|
@@ -222,9 +223,9 @@ class CameraUpdater {
|
|
|
222
223
|
if (dollyDeltaForDist !== 0) {
|
|
223
224
|
|
|
224
225
|
if (dollyDeltaForDist < 0) {
|
|
225
|
-
cursorType =
|
|
226
|
+
cursorType = cameraControl._cursors.dollyForward;
|
|
226
227
|
} else {
|
|
227
|
-
cursorType =
|
|
228
|
+
cursorType = cameraControl._cursors.dollyBackward;
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
if (configs.firstPerson) {
|
|
@@ -26,10 +26,6 @@ class KeyboardPanRotateDollyHandler {
|
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
28
|
keyDownMap[keyCode] = true;
|
|
29
|
-
|
|
30
|
-
if (keyCode === input.KEY_SHIFT) {
|
|
31
|
-
canvas.style.cursor = "move";
|
|
32
|
-
}
|
|
33
29
|
});
|
|
34
30
|
|
|
35
31
|
this._onSceneKeyUp = input.on("keyup", (keyCode) => {
|
|
@@ -38,10 +34,6 @@ class KeyboardPanRotateDollyHandler {
|
|
|
38
34
|
}
|
|
39
35
|
keyDownMap[keyCode] = false;
|
|
40
36
|
|
|
41
|
-
if (keyCode === input.KEY_SHIFT) {
|
|
42
|
-
canvas.style.cursor = null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
37
|
if (controllers.pivotController.getPivoting()) {
|
|
46
38
|
controllers.pivotController.endPivot()
|
|
47
39
|
}
|
|
@@ -78,7 +78,6 @@ class MousePanRotateDollyHandler {
|
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
function setMousedownState(pick = true) {
|
|
81
|
-
canvas.style.cursor = "move";
|
|
82
81
|
setMousedownPositions();
|
|
83
82
|
if (pick) {
|
|
84
83
|
setMousedownPick();
|
|
@@ -109,7 +108,7 @@ class MousePanRotateDollyHandler {
|
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
function isPanning() {
|
|
112
|
-
return cameraControl._isKeyDownForAction(cameraControl.MOUSE_PAN, keyDown);
|
|
111
|
+
return configs.planView || cameraControl._isKeyDownForAction(cameraControl.MOUSE_PAN, keyDown);
|
|
113
112
|
}
|
|
114
113
|
|
|
115
114
|
function isRotating() {
|
|
@@ -119,7 +119,8 @@ class TouchPanRotateAndDollyHandler {
|
|
|
119
119
|
|
|
120
120
|
canvas.addEventListener("touchend", this._canvasTouchEndHandler = () => {
|
|
121
121
|
if (pivotController.getPivoting()) {
|
|
122
|
-
pivotController.endPivot()
|
|
122
|
+
pivotController.endPivot();
|
|
123
|
+
pivotController.hidePivot();
|
|
123
124
|
}
|
|
124
125
|
firstDragDeltaX = 0;
|
|
125
126
|
firstDragDeltaY = 0;
|
|
@@ -191,28 +191,13 @@ class Marker extends Component {
|
|
|
191
191
|
* @type {Entity}
|
|
192
192
|
*/
|
|
193
193
|
set entity(entity) {
|
|
194
|
-
if (this._entity) {
|
|
195
|
-
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
if (this._onEntityDestroyed !== null) {
|
|
199
|
-
if (this._entity.model) {
|
|
200
|
-
this._entity.model.off(this._onEntityDestroyed);
|
|
201
|
-
} else {
|
|
202
|
-
this._entity.off(this._onEntityDestroyed);
|
|
203
|
-
}
|
|
204
|
-
this._onEntityDestroyed = null;
|
|
205
|
-
}
|
|
206
|
-
if (this._onEntityModelDestroyed !== null) {
|
|
207
|
-
if (this._entity.model) {
|
|
208
|
-
this._entity.model.off(this._onEntityModelDestroyed);
|
|
209
|
-
}
|
|
210
|
-
this._onEntityModelDestroyed = null;
|
|
211
|
-
}
|
|
194
|
+
if (this._entity === entity) {
|
|
195
|
+
return;
|
|
212
196
|
}
|
|
197
|
+
this._cleanupDestroyedHandlers();
|
|
213
198
|
this._entity = entity;
|
|
214
199
|
if (this._entity) {
|
|
215
|
-
if (this._entity
|
|
200
|
+
if (this._entity.isSceneModelEntity) {
|
|
216
201
|
this._onEntityModelDestroyed = this._entity.model.on("destroyed", () => { // SceneModelEntity does not fire events, and cannot exist beyond its VBOSceneModel
|
|
217
202
|
this._entity = null; // Marker now may become visible, if it was synched to invisible Entity
|
|
218
203
|
this._onEntityModelDestroyed = null;
|
|
@@ -374,16 +359,28 @@ class Marker extends Component {
|
|
|
374
359
|
this.fire("destroyed", true);
|
|
375
360
|
this.scene.camera.off(this._onCameraViewMatrix);
|
|
376
361
|
this.scene.camera.off(this._onCameraProjMatrix);
|
|
362
|
+
this._cleanupDestroyedHandlers();
|
|
363
|
+
this._renderer.removeMarker(this);
|
|
364
|
+
super.destroy();
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
_cleanupDestroyedHandlers() {
|
|
377
368
|
if (this._entity) {
|
|
378
369
|
if (this._onEntityDestroyed !== null) {
|
|
379
|
-
this._entity.model
|
|
370
|
+
if (this._entity.model) {
|
|
371
|
+
this._entity.model.off(this._onEntityDestroyed);
|
|
372
|
+
} else {
|
|
373
|
+
this._entity.off(this._onEntityDestroyed);
|
|
374
|
+
}
|
|
375
|
+
this._onEntityDestroyed = null;
|
|
380
376
|
}
|
|
381
377
|
if (this._onEntityModelDestroyed !== null) {
|
|
382
|
-
this._entity.model
|
|
378
|
+
if (this._entity.model) {
|
|
379
|
+
this._entity.model.off(this._onEntityModelDestroyed);
|
|
380
|
+
}
|
|
381
|
+
this._onEntityModelDestroyed = null;
|
|
383
382
|
}
|
|
384
383
|
}
|
|
385
|
-
this._renderer.removeMarker(this);
|
|
386
|
-
super.destroy();
|
|
387
384
|
}
|
|
388
385
|
}
|
|
389
386
|
|