@inweb/viewer-three 27.2.1 → 27.2.3

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.
@@ -19,8 +19,14 @@ export declare class WalkControls extends Controls<WalkControlsEventMap> {
19
19
  movementSpeed: number;
20
20
  multiplier: number;
21
21
  private groundFollowingSkippedFrames;
22
+ readonly GROUND_BOX_HALF_SIZE = 20;
23
+ readonly GROUND_BOX_REFRESH_THRESHOLD = 0.3;
22
24
  private raycaster;
23
25
  private groundObjects;
26
+ private _groundObjectBoxes;
27
+ private _activeGroundObjects;
28
+ private _groundBox;
29
+ private _groundBoxCenter;
24
30
  private moveKeys;
25
31
  private moveWheel;
26
32
  private moveClock;
@@ -41,6 +47,8 @@ export declare class WalkControls extends Controls<WalkControlsEventMap> {
41
47
  onWheel: (event: WheelEvent) => void;
42
48
  onKeyDown: (event: KeyboardEvent) => void;
43
49
  onKeyUp: (event: KeyboardEvent) => void;
50
+ private _rebuildGroundBox;
51
+ private _needsGroundBoxRebuild;
44
52
  private updateGroundFollowing;
45
53
  update(): void;
46
54
  rotateCamera(delta: Vector2): void;
@@ -1,18 +1,40 @@
1
- import { Object3D, Plane, Vector3 } from "three";
1
+ import { Plane, Quaternion, Vector2, Vector3 } from "three";
2
2
  import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
3
3
  import type { Viewer } from "../Viewer";
4
- import { PlaneHelper } from "../helpers/PlaneHelper";
4
+ import { PlaneHelper2 } from "../helpers/PlaneHelper2";
5
+ import { Snapper } from "../measurement/Snapper";
5
6
  import { OrbitDragger } from "./OrbitDragger";
6
7
  export declare class CuttingPlaneDragger extends OrbitDragger {
7
- protected plane: Plane;
8
- protected planeCenter: Object3D;
9
- protected planeHelper: PlaneHelper;
10
- protected transform: TransformControls;
11
- constructor(viewer: Viewer, normal: Vector3, color: number);
8
+ protected clippingPlanes: Plane[];
9
+ protected helpers: PlaneHelper2[];
10
+ protected activeHelper: PlaneHelper2;
11
+ protected snapper: Snapper;
12
+ protected downPosition: Vector2;
13
+ protected position0: Vector3;
14
+ protected quaternion0: Quaternion;
15
+ protected translate: TransformControls;
16
+ protected rotate: TransformControls;
17
+ constructor(viewer: Viewer);
12
18
  dispose(): void;
13
19
  transformChange: () => void;
14
- transformDrag: (event: any) => void;
20
+ translateDrag: (event: any) => void;
21
+ rotateDrag: (event: any) => void;
15
22
  updatePlaneSize: () => void;
16
23
  updateTransformCamera: () => void;
24
+ clearHelpers: () => void;
25
+ onKeyDown: (event: KeyboardEvent) => void;
26
+ onKeyUp: (event: KeyboardEvent) => void;
27
+ onPointerDown: (event: PointerEvent) => void;
28
+ onPointerUp: (event: PointerEvent) => void;
29
+ onPointerCancel: (event: PointerEvent) => void;
17
30
  onDoubleClick: (event: PointerEvent) => void;
31
+ private addHelper;
32
+ private setActiveHelper;
33
+ private saveState;
34
+ private reset;
35
+ addPlane(normal: Vector3): void;
36
+ addPlaneX(): void;
37
+ addPlaneY(): void;
38
+ addPlaneZ(): void;
39
+ deleteActivePlane(): void;
18
40
  }
@@ -0,0 +1,12 @@
1
+ import { Line, LineBasicMaterial, Mesh, MeshBasicMaterial, Object3D, Plane } from "three";
2
+ export declare class PlaneHelper2 extends Object3D {
3
+ plane: Plane;
4
+ size: number;
5
+ outline: Line;
6
+ mesh: Mesh;
7
+ constructor(size?: number, color?: number, opacity?: number);
8
+ dispose(): void;
9
+ updateMatrixWorld(force: boolean): void;
10
+ getLineMaterial(): LineBasicMaterial;
11
+ getMeshMaterial(): MeshBasicMaterial;
12
+ }
@@ -10,7 +10,7 @@ export declare class Snapper {
10
10
  constructor(camera: Camera, renderer: WebGLRenderer, canvas: HTMLCanvasElement);
11
11
  isMobile(): boolean;
12
12
  getMousePosition(event: MouseEvent, target: Vector2): Vector2;
13
- getPointerIntersects(mouse: Vector2, objects: Object3D[]): Array<Intersection<Object3D>>;
13
+ getPointerIntersects(mouse: Vector2, objects: Object3D[], recursive?: boolean, clip?: boolean): Array<Intersection<Object3D>>;
14
14
  getDetectRadius(point: Vector3): number;
15
15
  getSnapPoint(mouse: Vector2, objects: Object3D[]): Vector3;
16
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inweb/viewer-three",
3
- "version": "27.2.1",
3
+ "version": "27.2.3",
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,10 +35,10 @@
35
35
  "docs": "typedoc"
36
36
  },
37
37
  "dependencies": {
38
- "@inweb/client": "~27.2.1",
39
- "@inweb/eventemitter2": "~27.2.1",
40
- "@inweb/markup": "~27.2.1",
41
- "@inweb/viewer-core": "~27.2.1"
38
+ "@inweb/client": "~27.2.3",
39
+ "@inweb/eventemitter2": "~27.2.3",
40
+ "@inweb/markup": "~27.2.3",
41
+ "@inweb/viewer-core": "~27.2.3"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@streamparser/json": "^0.0.22",
@@ -542,6 +542,8 @@ export class Viewer
542
542
  if (!this.renderer) return;
543
543
 
544
544
  this._markup.clearOverlay();
545
+
546
+ this.emitEvent({ type: "clearoverlay" });
545
547
  this.update();
546
548
  }
547
549
 
@@ -549,6 +551,8 @@ export class Viewer
549
551
  if (!this.renderer) return;
550
552
 
551
553
  this.renderer.clippingPlanes = [];
554
+
555
+ this.emitEvent({ type: "clearslices" });
552
556
  this.update();
553
557
  }
554
558
 
@@ -58,7 +58,7 @@ export class SelectionComponent implements IComponent {
58
58
  };
59
59
 
60
60
  onPointerUp = (event: PointerEvent) => {
61
- if (!event.isPrimary) return;
61
+ if (!event.isPrimary || event.button !== 0) return;
62
62
 
63
63
  const upPosition = this.getMousePosition(event, new Vector2());
64
64
  if (upPosition.distanceTo(this.downPosition) !== 0) return;
@@ -21,7 +21,7 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
- import { Clock, Camera, Controls, Quaternion, Vector2, Vector3, Raycaster, Object3D, MathUtils } from "three";
24
+ import { Box3, Clock, Camera, Controls, Quaternion, Vector2, Vector3, Raycaster, Object3D, MathUtils } from "three";
25
25
 
26
26
  interface WalkControlsEventMap {
27
27
  change: { type: "change" };
@@ -41,8 +41,15 @@ export class WalkControls extends Controls<WalkControlsEventMap> {
41
41
  public multiplier = 3;
42
42
  private groundFollowingSkippedFrames = 0;
43
43
 
44
+ readonly GROUND_BOX_HALF_SIZE = 20;
45
+ readonly GROUND_BOX_REFRESH_THRESHOLD = 0.3;
46
+
44
47
  private raycaster: Raycaster;
45
48
  private groundObjects: Object3D[];
49
+ private _groundObjectBoxes = new Map<Object3D, Box3>();
50
+ private _activeGroundObjects: Object3D[] = [];
51
+ private _groundBox = new Box3();
52
+ private _groundBoxCenter = new Vector3();
46
53
 
47
54
  private moveKeys: Set<string>;
48
55
  private moveWheel = 0;
@@ -64,6 +71,12 @@ export class WalkControls extends Controls<WalkControlsEventMap> {
64
71
  this.camera = camera;
65
72
 
66
73
  this.groundObjects = groundObjects;
74
+ for (const obj of groundObjects) {
75
+ this._groundObjectBoxes.set(obj, new Box3().setFromObject(obj));
76
+ }
77
+ const pos = this.object.position;
78
+ this._rebuildGroundBox(pos);
79
+
67
80
  this.raycaster = new Raycaster();
68
81
  this.raycaster.near = 0;
69
82
  this.raycaster.far = this.EYE_HEIGHT + this.FAILING_DISTANCE;
@@ -175,14 +188,47 @@ export class WalkControls extends Controls<WalkControlsEventMap> {
175
188
  };
176
189
 
177
190
  onKeyUp = (event: KeyboardEvent) => {
178
- if (this.moveKeys.delete(event.code)) this.update();
191
+ if (this.moveKeys.delete(event.code)) {
192
+ if (this.moveKeys.size === 0) {
193
+ this._rebuildGroundBox(this.object.position);
194
+ }
195
+ this.update();
196
+ }
179
197
  };
180
198
 
199
+ private _rebuildGroundBox(center: Vector3) {
200
+ const h = this.GROUND_BOX_HALF_SIZE;
201
+ this._groundBoxCenter.copy(center);
202
+ this._groundBox.set(
203
+ new Vector3(center.x - h, center.y - h * 4, center.z - h),
204
+ new Vector3(center.x + h, center.y + h * 4, center.z + h)
205
+ );
206
+
207
+ this._activeGroundObjects = this.groundObjects.filter((obj) => {
208
+ const objectBox = this._groundObjectBoxes.get(obj);
209
+ return objectBox !== undefined && this._groundBox.intersectsBox(objectBox);
210
+ });
211
+ }
212
+
213
+ private _needsGroundBoxRebuild(pos: Vector3): boolean {
214
+ if (this._activeGroundObjects.length === 0 && this.groundObjects.length > 0) return true;
215
+ const threshold = this.GROUND_BOX_HALF_SIZE * this.GROUND_BOX_REFRESH_THRESHOLD;
216
+ return (
217
+ Math.abs(pos.x - this._groundBoxCenter.x) > threshold || Math.abs(pos.z - this._groundBoxCenter.z) > threshold
218
+ );
219
+ }
220
+
181
221
  private updateGroundFollowing() {
222
+ const pos = this.object.position;
223
+
224
+ if (this._needsGroundBoxRebuild(pos)) {
225
+ this._rebuildGroundBox(pos);
226
+ }
227
+
182
228
  this._up.copy(this.camera.up).negate();
183
- this.raycaster.set(this.object.position, this._up);
229
+ this.raycaster.set(pos, this._up);
184
230
 
185
- const intersects = this.raycaster.intersectObjects(this.groundObjects, false);
231
+ const intersects = this.raycaster.intersectObjects(this._activeGroundObjects, false);
186
232
  if (intersects.length > 0) {
187
233
  const groundY = intersects[0].point.y;
188
234
  const targetY = groundY + this.EYE_HEIGHT;
@@ -21,52 +21,77 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
- import { Object3D, Plane, Vector3 } from "three";
24
+ import { Plane, Quaternion, Vector2, Vector3 } from "three";
25
25
  import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
26
26
 
27
27
  import type { Viewer } from "../Viewer";
28
- import { PlaneHelper } from "../helpers/PlaneHelper";
28
+ import { STATE } from "../controls/OrbitControls.js";
29
+ import { PlaneHelper2 } from "../helpers/PlaneHelper2";
30
+ import { Snapper } from "../measurement/Snapper";
29
31
  import { OrbitDragger } from "./OrbitDragger";
30
32
 
31
33
  export class CuttingPlaneDragger extends OrbitDragger {
32
- protected plane: Plane;
33
- protected planeCenter: Object3D;
34
- protected planeHelper: PlaneHelper;
35
- protected transform: TransformControls;
34
+ protected clippingPlanes: Plane[];
35
+ protected helpers: PlaneHelper2[] = [];
36
+ protected activeHelper: PlaneHelper2 = null;
37
+ protected snapper: Snapper;
38
+ protected downPosition: Vector2;
39
+ protected position0: Vector3;
40
+ protected quaternion0: Quaternion;
41
+ protected translate: TransformControls;
42
+ protected rotate: TransformControls;
36
43
 
37
- constructor(viewer: Viewer, normal: Vector3, color: number) {
44
+ constructor(viewer: Viewer) {
38
45
  super(viewer);
39
46
 
47
+ if (!viewer.renderer.clippingPlanes) viewer.renderer.clippingPlanes = [];
48
+
49
+ this.clippingPlanes = viewer.renderer.clippingPlanes;
50
+ this.clippingPlanes.forEach((plane) => this.addHelper(plane));
51
+
40
52
  const extentsSize = viewer.extents.getSize(new Vector3()).length() || 1;
41
- const extentsCenter = viewer.extents.getCenter(new Vector3());
42
- const constant = -extentsCenter.dot(normal);
43
53
 
44
- this.plane = new Plane(normal, constant);
54
+ this.snapper = new Snapper(viewer.camera, viewer.renderer, viewer.canvas);
55
+ this.snapper.threshold = extentsSize / 10000;
45
56
 
46
- if (!viewer.renderer.clippingPlanes) viewer.renderer.clippingPlanes = [];
47
- viewer.renderer.clippingPlanes.push(this.plane);
57
+ this.downPosition = new Vector2();
58
+ this.position0 = new Vector3();
59
+ this.quaternion0 = new Quaternion();
48
60
 
49
- this.planeHelper = new PlaneHelper(this.plane, extentsSize, color, extentsCenter);
50
- this.viewer.helpers.add(this.planeHelper);
61
+ this.translate = new TransformControls(viewer.camera, viewer.canvas);
62
+ this.translate.setMode("translate");
63
+ this.translate.setSpace("local");
64
+ this.translate.showX = false;
65
+ this.translate.showY = false;
66
+ this.translate.showZ = true;
67
+ this.translate.addEventListener("change", this.transformChange);
68
+ this.translate.addEventListener("dragging-changed", this.translateDrag);
69
+ this.viewer.helpers.add(this.translate.getHelper());
51
70
 
52
- this.planeCenter = new Object3D();
53
- this.planeCenter.position.copy(extentsCenter);
54
- this.viewer.helpers.add(this.planeCenter);
71
+ this.rotate = new TransformControls(viewer.camera, viewer.canvas);
72
+ this.rotate.setMode("rotate");
73
+ this.rotate.setSpace("local");
74
+ this.rotate.showX = true;
75
+ this.rotate.showY = true;
76
+ this.rotate.showZ = false;
77
+ this.rotate.addEventListener("change", this.transformChange);
78
+ this.rotate.addEventListener("dragging-changed", this.rotateDrag);
79
+ this.viewer.helpers.add(this.rotate.getHelper());
55
80
 
56
- this.transform = new TransformControls(viewer.camera, viewer.canvas);
57
- this.transform.showX = !!normal.x;
58
- this.transform.showY = !!normal.y;
59
- this.transform.showZ = !!normal.z;
60
- this.transform.attach(this.planeCenter);
61
- this.transform.addEventListener("change", this.transformChange);
62
- this.transform.addEventListener("dragging-changed", this.transformDrag);
63
- this.viewer.helpers.add(this.transform.getHelper());
81
+ this.setActiveHelper(this.helpers[this.helpers.length - 1]);
64
82
 
65
83
  this.viewer.addEventListener("explode", this.updatePlaneSize);
66
84
  this.viewer.addEventListener("show", this.updatePlaneSize);
67
85
  this.viewer.addEventListener("showall", this.updatePlaneSize);
68
86
  this.viewer.addEventListener("changecameramode", this.updateTransformCamera);
87
+ this.viewer.addEventListener("clearslices", this.clearHelpers);
88
+ this.viewer.canvas.addEventListener("pointerdown", this.onPointerDown, true);
89
+ this.viewer.canvas.addEventListener("pointerup", this.onPointerUp, true);
90
+ this.viewer.canvas.addEventListener("pointercancel", this.onPointerCancel, true);
69
91
  this.viewer.canvas.addEventListener("dblclick", this.onDoubleClick, true);
92
+ window.addEventListener("keydown", this.onKeyDown);
93
+ window.addEventListener("keyup", this.onKeyUp);
94
+
70
95
  this.viewer.update();
71
96
  }
72
97
 
@@ -75,47 +100,223 @@ export class CuttingPlaneDragger extends OrbitDragger {
75
100
  this.viewer.removeEventListener("show", this.updatePlaneSize);
76
101
  this.viewer.removeEventListener("showall", this.updatePlaneSize);
77
102
  this.viewer.removeEventListener("changecameramode", this.updateTransformCamera);
103
+ this.viewer.removeEventListener("clearslices", this.clearHelpers);
104
+ this.viewer.canvas.removeEventListener("pointerdown", this.onPointerDown, true);
105
+ this.viewer.canvas.removeEventListener("pointerup", this.onPointerUp, true);
106
+ this.viewer.canvas.removeEventListener("pointercancel", this.onPointerCancel, true);
78
107
  this.viewer.canvas.removeEventListener("dblclick", this.onDoubleClick, true);
108
+ window.removeEventListener("keydown", this.onKeyDown);
109
+ window.removeEventListener("keyup", this.onKeyUp);
79
110
 
80
- this.transform.removeEventListener("change", this.transformChange);
81
- this.transform.removeEventListener("dragging-changed", this.transformDrag);
82
- this.transform.getHelper().removeFromParent();
83
- this.transform.detach();
84
- this.transform.dispose();
85
-
86
- this.planeHelper.removeFromParent();
87
- this.planeHelper.dispose();
111
+ this.translate.removeEventListener("change", this.transformChange);
112
+ this.translate.removeEventListener("dragging-changed", this.translateDrag);
113
+ this.translate.getHelper().removeFromParent();
114
+ this.translate.detach();
115
+ this.translate.dispose();
88
116
 
89
- this.planeCenter.removeFromParent();
117
+ this.rotate.removeEventListener("change", this.transformChange);
118
+ this.rotate.removeEventListener("dragging-changed", this.rotateDrag);
119
+ this.rotate.getHelper().removeFromParent();
120
+ this.rotate.detach();
121
+ this.rotate.dispose();
90
122
 
91
- // this.viewer.renderer.clippingPlanes = this.viewer.renderer.clippingPlanes.filter((plane) => plane !== this.plane);
92
- // this.viewer.update();
123
+ this.helpers.forEach((helper) => {
124
+ helper.removeFromParent();
125
+ helper.dispose();
126
+ });
127
+ this.helpers = [];
128
+ this.activeHelper = null;
93
129
 
94
130
  super.dispose();
95
131
  }
96
132
 
97
133
  transformChange = () => {
98
- this.plane.constant = -this.planeCenter.position.dot(this.plane.normal);
134
+ if (!this.activeHelper) return;
135
+
136
+ const plane = this.activeHelper.plane;
137
+ plane.normal.copy(new Vector3(0, 0, -1)).applyQuaternion(this.activeHelper.quaternion);
138
+ plane.constant = -this.activeHelper.position.dot(plane.normal);
139
+
99
140
  this.viewer.update();
141
+
142
+ this.changed = true; // <- cancel context menu
100
143
  };
101
144
 
102
- transformDrag = (event) => {
145
+ translateDrag = (event) => {
103
146
  this.orbit.enabled = !event.value;
147
+ this.rotate.enabled = !event.value;
148
+ };
149
+
150
+ rotateDrag = (event) => {
151
+ this.orbit.enabled = !event.value;
152
+ this.translate.enabled = !event.value;
104
153
  };
105
154
 
106
155
  updatePlaneSize = () => {
107
- this.planeHelper.size = this.viewer.extents.getSize(new Vector3()).length() || 1;
156
+ const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
157
+ this.helpers.forEach((planeHelper) => (planeHelper.size = extentsSize));
108
158
  this.viewer.update();
109
159
  };
110
160
 
111
161
  updateTransformCamera = () => {
112
- this.transform.camera = this.viewer.camera;
162
+ this.translate.camera = this.viewer.camera;
163
+ this.rotate.camera = this.viewer.camera;
164
+ this.snapper.camera = this.viewer.camera;
165
+ };
166
+
167
+ clearHelpers = () => {
168
+ this.setActiveHelper();
169
+
170
+ this.helpers.forEach((helper) => {
171
+ helper.removeFromParent();
172
+ helper.dispose();
173
+ });
174
+ this.helpers = [];
175
+
176
+ this.viewer.update();
177
+ };
178
+
179
+ onKeyDown = (event: KeyboardEvent) => {
180
+ if (event.key === "Shift") this.rotate.setRotationSnap(Math.PI / 4);
181
+ if (event.key === "Delete" || event.key === "Backspace") this.deleteActivePlane();
182
+ if (event.key === "Escape" && (this.translate.dragging || this.rotate.dragging)) this.reset();
183
+ };
184
+
185
+ onKeyUp = (event: KeyboardEvent) => {
186
+ if (event.key === "Shift") this.rotate.setRotationSnap(null);
187
+ };
188
+
189
+ onPointerDown = (event: PointerEvent) => {
190
+ if (event.button !== 0 || !event.isPrimary) return;
191
+
192
+ this.snapper.getMousePosition(event, this.downPosition);
193
+ this.saveState();
194
+ };
195
+
196
+ onPointerUp = (event: PointerEvent) => {
197
+ if (event.button !== 0) return;
198
+
199
+ const upPosition = this.snapper.getMousePosition(event, new Vector2());
200
+ if (upPosition.distanceTo(this.downPosition) !== 0) return;
201
+
202
+ const intersects = this.snapper.getPointerIntersects(upPosition, this.helpers, true, false);
203
+ if (intersects.length === 0) return;
204
+
205
+ this.setActiveHelper(intersects[0].object.parent as PlaneHelper2);
206
+ };
207
+
208
+ onPointerCancel = (event: PointerEvent) => {
209
+ this.viewer.canvas.dispatchEvent(new PointerEvent("pointerup", event));
113
210
  };
114
211
 
115
212
  onDoubleClick = (event: PointerEvent) => {
213
+ if (!this.activeHelper) return;
214
+
215
+ const mousePosition = this.snapper.getMousePosition(event, new Vector2());
216
+
217
+ const intersects = this.snapper.getPointerIntersects(mousePosition, [this.activeHelper], true, false);
218
+ if (intersects.length === 0) return;
219
+
220
+ this.activeHelper.rotateOnAxis(new Vector3(0, 1, 0), Math.PI);
221
+ this.transformChange();
222
+
116
223
  event.stopPropagation();
224
+ };
225
+
226
+ private addHelper(plane: Plane): PlaneHelper2 {
227
+ const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
228
+ const extentsCenter = this.viewer.extents.getCenter(new Vector3());
229
+
230
+ const helper = new PlaneHelper2(extentsSize);
231
+ helper.plane = plane;
232
+ helper.position.copy(plane.projectPoint(extentsCenter, new Vector3()));
233
+ helper.quaternion.setFromUnitVectors(new Vector3(0, 0, -1), plane.normal);
234
+
235
+ this.helpers.push(helper);
236
+ this.viewer.helpers.add(helper);
237
+
238
+ return helper;
239
+ }
240
+
241
+ private setActiveHelper(helper?: PlaneHelper2) {
242
+ if (helper === this.activeHelper) return;
243
+
244
+ if (this.activeHelper) {
245
+ this.activeHelper.getLineMaterial().color.setHex(0xf0f0f0);
246
+ this.activeHelper.getMeshMaterial().opacity = 0.15;
247
+
248
+ this.translate.detach();
249
+ this.rotate.detach();
250
+ }
251
+
252
+ this.activeHelper = helper;
253
+
254
+ if (this.activeHelper) {
255
+ this.activeHelper.getLineMaterial().color.setHex(0xd0d0d0);
256
+ this.activeHelper.getMeshMaterial().opacity = 0.3;
257
+
258
+ this.translate.attach(this.activeHelper);
259
+ this.rotate.attach(this.activeHelper);
260
+ }
117
261
 
118
- this.plane.negate();
119
262
  this.viewer.update();
120
- };
263
+ }
264
+
265
+ private saveState() {
266
+ if (!this.activeHelper) return;
267
+
268
+ this.position0.copy(this.activeHelper.position);
269
+ this.quaternion0.copy(this.activeHelper.quaternion);
270
+ }
271
+
272
+ private reset() {
273
+ if (!this.activeHelper) return;
274
+
275
+ this.translate.dragging = false;
276
+ this.rotate.dragging = false;
277
+ this.orbit.state = STATE.NONE;
278
+
279
+ this.activeHelper.position.copy(this.position0);
280
+ this.activeHelper.quaternion.copy(this.quaternion0);
281
+
282
+ this.transformChange();
283
+ }
284
+
285
+ addPlane(normal: Vector3) {
286
+ const extentsCenter = this.viewer.extents.getCenter(new Vector3());
287
+ const constant = -extentsCenter.dot(normal);
288
+
289
+ const plane = new Plane(normal, constant);
290
+ this.clippingPlanes.push(plane);
291
+
292
+ const helper = this.addHelper(plane);
293
+ this.setActiveHelper(helper);
294
+ }
295
+
296
+ addPlaneX() {
297
+ this.addPlane(new Vector3(-1, 0, 0));
298
+ }
299
+
300
+ addPlaneY() {
301
+ this.addPlane(new Vector3(0, -1, 0));
302
+ }
303
+
304
+ addPlaneZ() {
305
+ this.addPlane(new Vector3(0, 0, -1));
306
+ }
307
+
308
+ deleteActivePlane() {
309
+ if (!this.activeHelper) return;
310
+
311
+ const helper = this.activeHelper;
312
+
313
+ const index = this.clippingPlanes.indexOf(helper.plane);
314
+ if (index !== -1) this.clippingPlanes.splice(index, 1);
315
+
316
+ this.helpers = this.helpers.filter((x) => x !== helper);
317
+ helper.removeFromParent();
318
+ helper.dispose();
319
+
320
+ this.setActiveHelper(this.helpers[this.helpers.length - 1]);
321
+ }
121
322
  }
@@ -21,13 +21,12 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
- import { Vector3 } from "three";
25
-
26
24
  import type { Viewer } from "../Viewer";
27
25
  import { CuttingPlaneDragger } from "./CuttingPlaneDragger";
28
26
 
29
27
  export class CuttingPlaneXAxisDragger extends CuttingPlaneDragger {
30
28
  constructor(viewer: Viewer) {
31
- super(viewer, new Vector3(1, 0, 0), 0xff0000);
29
+ super(viewer);
30
+ this.addPlaneX();
32
31
  }
33
32
  }
@@ -21,13 +21,12 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
- import { Vector3 } from "three";
25
-
26
24
  import type { Viewer } from "../Viewer";
27
25
  import { CuttingPlaneDragger } from "./CuttingPlaneDragger";
28
26
 
29
27
  export class CuttingPlaneYAxisDragger extends CuttingPlaneDragger {
30
28
  constructor(viewer: Viewer) {
31
- super(viewer, new Vector3(0, 1, 0), 0x00ff00);
29
+ super(viewer);
30
+ this.addPlaneY();
32
31
  }
33
32
  }
@@ -21,13 +21,12 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
- import { Vector3 } from "three";
25
-
26
24
  import type { Viewer } from "../Viewer";
27
25
  import { CuttingPlaneDragger } from "./CuttingPlaneDragger";
28
26
 
29
27
  export class CuttingPlaneZAxisDragger extends CuttingPlaneDragger {
30
28
  constructor(viewer: Viewer) {
31
- super(viewer, new Vector3(0, 0, 1), 0x0000ff);
29
+ super(viewer);
30
+ this.addPlaneZ();
32
31
  }
33
32
  }
@@ -23,6 +23,7 @@
23
23
 
24
24
  import { IDraggersRegistry, draggersRegistry } from "@inweb/viewer-core";
25
25
 
26
+ import { CuttingPlaneDragger } from "./CuttingPlaneDragger";
26
27
  import { CuttingPlaneXAxisDragger } from "./CuttingPlaneXAxis";
27
28
  import { CuttingPlaneYAxisDragger } from "./CuttingPlaneYAxis";
28
29
  import { CuttingPlaneZAxisDragger } from "./CuttingPlaneZAxis";
@@ -84,6 +85,7 @@ draggers.registerDragger("Pan", (viewer) => new PanDragger(viewer));
84
85
  draggers.registerDragger("Orbit", (viewer) => new OrbitDragger(viewer));
85
86
  draggers.registerDragger("Zoom", (viewer) => new ZoomDragger(viewer));
86
87
  draggers.registerDragger("MeasureLine", (viewer) => new MeasureLineDragger(viewer));
88
+ draggers.registerDragger("CuttingPlane", (viewer) => new CuttingPlaneDragger(viewer));
87
89
  draggers.registerDragger("CuttingPlaneXAxis", (viewer) => new CuttingPlaneXAxisDragger(viewer));
88
90
  draggers.registerDragger("CuttingPlaneYAxis", (viewer) => new CuttingPlaneYAxisDragger(viewer));
89
91
  draggers.registerDragger("CuttingPlaneZAxis", (viewer) => new CuttingPlaneZAxisDragger(viewer));