@inweb/viewer-three 27.2.1 → 27.2.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.
@@ -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,22 @@
1
1
  import { Object3D, Plane, 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
5
  import { OrbitDragger } from "./OrbitDragger";
6
6
  export declare class CuttingPlaneDragger extends OrbitDragger {
7
7
  protected plane: Plane;
8
8
  protected planeCenter: Object3D;
9
- protected planeHelper: PlaneHelper;
10
- protected transform: TransformControls;
11
- constructor(viewer: Viewer, normal: Vector3, color: number);
9
+ protected planeHelper: PlaneHelper2;
10
+ protected translate: TransformControls;
11
+ protected rotate: TransformControls;
12
+ constructor(viewer: Viewer, normal: Vector3);
12
13
  dispose(): void;
13
14
  transformChange: () => void;
14
- transformDrag: (event: any) => void;
15
+ translateDrag: (event: any) => void;
16
+ rotateDrag: (event: any) => void;
15
17
  updatePlaneSize: () => void;
16
18
  updateTransformCamera: () => void;
19
+ onKeyDown: (event: KeyboardEvent) => void;
20
+ onKeyUp: (event: KeyboardEvent) => void;
17
21
  onDoubleClick: (event: PointerEvent) => void;
18
22
  }
@@ -0,0 +1,8 @@
1
+ import { Line, Mesh } from "three";
2
+ export declare class PlaneHelper2 extends Line {
3
+ size: number;
4
+ helper: Mesh;
5
+ constructor(size?: number, color?: number);
6
+ dispose(): void;
7
+ updateMatrixWorld(force: boolean): void;
8
+ }
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.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,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.2",
39
+ "@inweb/eventemitter2": "~27.2.2",
40
+ "@inweb/markup": "~27.2.2",
41
+ "@inweb/viewer-core": "~27.2.2"
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
 
@@ -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; // fraction of half-size
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,9 @@ 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
+ }
67
77
  this.raycaster = new Raycaster();
68
78
  this.raycaster.near = 0;
69
79
  this.raycaster.far = this.EYE_HEIGHT + this.FAILING_DISTANCE;
@@ -178,11 +188,39 @@ export class WalkControls extends Controls<WalkControlsEventMap> {
178
188
  if (this.moveKeys.delete(event.code)) this.update();
179
189
  };
180
190
 
191
+ private _rebuildGroundBox(center: Vector3) {
192
+ const h = this.GROUND_BOX_HALF_SIZE;
193
+ this._groundBoxCenter.copy(center);
194
+ this._groundBox.set(
195
+ new Vector3(center.x - h, center.y - h * 4, center.z - h),
196
+ new Vector3(center.x + h, center.y + h * 4, center.z + h)
197
+ );
198
+
199
+ this._activeGroundObjects = this.groundObjects.filter((obj) => {
200
+ const objectBox = this._groundObjectBoxes.get(obj);
201
+ return objectBox !== undefined && this._groundBox.intersectsBox(objectBox);
202
+ });
203
+ }
204
+
205
+ private _needsGroundBoxRebuild(pos: Vector3): boolean {
206
+ if (this._activeGroundObjects.length === 0 && this.groundObjects.length > 0) return true;
207
+ const threshold = this.GROUND_BOX_HALF_SIZE * this.GROUND_BOX_REFRESH_THRESHOLD;
208
+ return (
209
+ Math.abs(pos.x - this._groundBoxCenter.x) > threshold || Math.abs(pos.z - this._groundBoxCenter.z) > threshold
210
+ );
211
+ }
212
+
181
213
  private updateGroundFollowing() {
214
+ const pos = this.object.position;
215
+
216
+ if (this._needsGroundBoxRebuild(pos)) {
217
+ this._rebuildGroundBox(pos);
218
+ }
219
+
182
220
  this._up.copy(this.camera.up).negate();
183
- this.raycaster.set(this.object.position, this._up);
221
+ this.raycaster.set(pos, this._up);
184
222
 
185
- const intersects = this.raycaster.intersectObjects(this.groundObjects, false);
223
+ const intersects = this.raycaster.intersectObjects(this._activeGroundObjects, false);
186
224
  if (intersects.length > 0) {
187
225
  const groundY = intersects[0].point.y;
188
226
  const targetY = groundY + this.EYE_HEIGHT;
@@ -25,16 +25,17 @@ import { Object3D, Plane, 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 { PlaneHelper2 } from "../helpers/PlaneHelper2";
29
29
  import { OrbitDragger } from "./OrbitDragger";
30
30
 
31
31
  export class CuttingPlaneDragger extends OrbitDragger {
32
32
  protected plane: Plane;
33
33
  protected planeCenter: Object3D;
34
- protected planeHelper: PlaneHelper;
35
- protected transform: TransformControls;
34
+ protected planeHelper: PlaneHelper2;
35
+ protected translate: TransformControls;
36
+ protected rotate: TransformControls;
36
37
 
37
- constructor(viewer: Viewer, normal: Vector3, color: number) {
38
+ constructor(viewer: Viewer, normal: Vector3) {
38
39
  super(viewer);
39
40
 
40
41
  const extentsSize = viewer.extents.getSize(new Vector3()).length() || 1;
@@ -46,27 +47,43 @@ export class CuttingPlaneDragger extends OrbitDragger {
46
47
  if (!viewer.renderer.clippingPlanes) viewer.renderer.clippingPlanes = [];
47
48
  viewer.renderer.clippingPlanes.push(this.plane);
48
49
 
49
- this.planeHelper = new PlaneHelper(this.plane, extentsSize, color, extentsCenter);
50
- this.viewer.helpers.add(this.planeHelper);
51
-
52
50
  this.planeCenter = new Object3D();
53
51
  this.planeCenter.position.copy(extentsCenter);
52
+ this.planeCenter.quaternion.setFromUnitVectors(new Vector3(0, 0, -1), normal);
54
53
  this.viewer.helpers.add(this.planeCenter);
55
54
 
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());
55
+ this.planeHelper = new PlaneHelper2(extentsSize);
56
+ this.planeCenter.add(this.planeHelper);
57
+
58
+ this.translate = new TransformControls(viewer.camera, viewer.canvas);
59
+ this.translate.setSpace("local");
60
+ this.translate.showX = false;
61
+ this.translate.showY = false;
62
+ this.translate.showZ = true;
63
+ this.translate.attach(this.planeCenter);
64
+ this.translate.addEventListener("change", this.transformChange);
65
+ this.translate.addEventListener("dragging-changed", this.translateDrag);
66
+ this.viewer.helpers.add(this.translate.getHelper());
67
+
68
+ this.rotate = new TransformControls(viewer.camera, viewer.canvas);
69
+ this.rotate.setMode("rotate");
70
+ this.rotate.setSpace("local");
71
+ this.rotate.showX = true;
72
+ this.rotate.showY = true;
73
+ this.rotate.showZ = false;
74
+ this.rotate.attach(this.planeCenter);
75
+ this.rotate.addEventListener("change", this.transformChange);
76
+ this.rotate.addEventListener("dragging-changed", this.rotateDrag);
77
+ this.viewer.helpers.add(this.rotate.getHelper());
64
78
 
65
79
  this.viewer.addEventListener("explode", this.updatePlaneSize);
66
80
  this.viewer.addEventListener("show", this.updatePlaneSize);
67
81
  this.viewer.addEventListener("showall", this.updatePlaneSize);
68
82
  this.viewer.addEventListener("changecameramode", this.updateTransformCamera);
69
83
  this.viewer.canvas.addEventListener("dblclick", this.onDoubleClick, true);
84
+ window.addEventListener("keydown", this.onKeyDown);
85
+ window.addEventListener("keyup", this.onKeyUp);
86
+
70
87
  this.viewer.update();
71
88
  }
72
89
 
@@ -76,12 +93,20 @@ export class CuttingPlaneDragger extends OrbitDragger {
76
93
  this.viewer.removeEventListener("showall", this.updatePlaneSize);
77
94
  this.viewer.removeEventListener("changecameramode", this.updateTransformCamera);
78
95
  this.viewer.canvas.removeEventListener("dblclick", this.onDoubleClick, true);
96
+ window.removeEventListener("keydown", this.onKeyDown);
97
+ window.removeEventListener("keyup", this.onKeyUp);
98
+
99
+ this.translate.removeEventListener("change", this.transformChange);
100
+ this.translate.removeEventListener("dragging-changed", this.translateDrag);
101
+ this.translate.getHelper().removeFromParent();
102
+ this.translate.detach();
103
+ this.translate.dispose();
79
104
 
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();
105
+ this.rotate.removeEventListener("change", this.transformChange);
106
+ this.rotate.removeEventListener("dragging-changed", this.rotateDrag);
107
+ this.rotate.getHelper().removeFromParent();
108
+ this.rotate.detach();
109
+ this.rotate.dispose();
85
110
 
86
111
  this.planeHelper.removeFromParent();
87
112
  this.planeHelper.dispose();
@@ -95,12 +120,19 @@ export class CuttingPlaneDragger extends OrbitDragger {
95
120
  }
96
121
 
97
122
  transformChange = () => {
123
+ this.plane.normal.copy(new Vector3(0, 0, -1)).applyQuaternion(this.planeCenter.quaternion);
98
124
  this.plane.constant = -this.planeCenter.position.dot(this.plane.normal);
99
125
  this.viewer.update();
100
126
  };
101
127
 
102
- transformDrag = (event) => {
128
+ translateDrag = (event) => {
129
+ this.orbit.enabled = !event.value;
130
+ this.rotate.enabled = !event.value;
131
+ };
132
+
133
+ rotateDrag = (event) => {
103
134
  this.orbit.enabled = !event.value;
135
+ this.translate.enabled = !event.value;
104
136
  };
105
137
 
106
138
  updatePlaneSize = () => {
@@ -109,13 +141,22 @@ export class CuttingPlaneDragger extends OrbitDragger {
109
141
  };
110
142
 
111
143
  updateTransformCamera = () => {
112
- this.transform.camera = this.viewer.camera;
144
+ this.translate.camera = this.viewer.camera;
145
+ this.rotate.camera = this.viewer.camera;
146
+ };
147
+
148
+ onKeyDown = (event: KeyboardEvent) => {
149
+ if (event.key === "Shift") this.rotate.setRotationSnap(Math.PI / 4);
150
+ };
151
+
152
+ onKeyUp = (event: KeyboardEvent) => {
153
+ if (event.key === "Shift") this.rotate.setRotationSnap(null);
113
154
  };
114
155
 
115
156
  onDoubleClick = (event: PointerEvent) => {
116
157
  event.stopPropagation();
117
158
 
118
- this.plane.negate();
119
- this.viewer.update();
159
+ this.planeCenter.rotateOnAxis(new Vector3(0, 1, 0), Math.PI);
160
+ this.transformChange();
120
161
  };
121
162
  }
@@ -28,6 +28,6 @@ import { CuttingPlaneDragger } from "./CuttingPlaneDragger";
28
28
 
29
29
  export class CuttingPlaneXAxisDragger extends CuttingPlaneDragger {
30
30
  constructor(viewer: Viewer) {
31
- super(viewer, new Vector3(1, 0, 0), 0xff0000);
31
+ super(viewer, new Vector3(-1, 0, 0));
32
32
  }
33
33
  }
@@ -28,6 +28,6 @@ import { CuttingPlaneDragger } from "./CuttingPlaneDragger";
28
28
 
29
29
  export class CuttingPlaneYAxisDragger extends CuttingPlaneDragger {
30
30
  constructor(viewer: Viewer) {
31
- super(viewer, new Vector3(0, 1, 0), 0x00ff00);
31
+ super(viewer, new Vector3(0, -1, 0));
32
32
  }
33
33
  }
@@ -28,6 +28,6 @@ import { CuttingPlaneDragger } from "./CuttingPlaneDragger";
28
28
 
29
29
  export class CuttingPlaneZAxisDragger extends CuttingPlaneDragger {
30
30
  constructor(viewer: Viewer) {
31
- super(viewer, new Vector3(0, 0, 1), 0x0000ff);
31
+ super(viewer, new Vector3(0, 0, -1));
32
32
  }
33
33
  }
@@ -29,19 +29,13 @@ import {
29
29
  LineBasicMaterial,
30
30
  Mesh,
31
31
  MeshBasicMaterial,
32
- Object3D,
33
- Plane,
34
- Vector3,
35
32
  } from "three";
36
33
 
37
- class PlaneHelper extends Line {
38
- public plane: Plane;
34
+ export class PlaneHelper2 extends Line {
39
35
  public size: number;
40
- public offset: Vector3;
41
- public helper: Object3D;
36
+ public helper: Mesh;
42
37
 
43
- constructor(plane: Plane, size = 1, color = 0xffff00, offset: Vector3 = new Vector3()) {
44
- // const positions = [1, -1, 0, -1, 1, 0, -1, -1, 0, 1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0, 1, 1, 0];
38
+ constructor(size = 1, color = 0xc0c0c0) {
45
39
  const positions = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0, 1, 1, 0];
46
40
 
47
41
  const geometry = new BufferGeometry();
@@ -50,11 +44,9 @@ class PlaneHelper extends Line {
50
44
 
51
45
  super(geometry, new LineBasicMaterial({ color, toneMapped: false }));
52
46
 
53
- (this as any).type = "PlaneHelper";
47
+ (this as any).type = "PlaneHelper2";
54
48
 
55
- this.plane = plane;
56
49
  this.size = size;
57
- this.offset = offset;
58
50
 
59
51
  const positions2 = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0];
60
52
 
@@ -79,21 +71,12 @@ class PlaneHelper extends Line {
79
71
  dispose() {
80
72
  this.geometry.dispose();
81
73
  (this.material as any).dispose();
82
- (this.children[0] as any).geometry.dispose();
83
- (this.children[0] as any).material.dispose();
74
+ (this.helper as any).geometry.dispose();
75
+ (this.helper as any).material.dispose();
84
76
  }
85
77
 
86
78
  override updateMatrixWorld(force: boolean) {
87
- this.position.set(0, 0, 0);
88
- this.lookAt(this.plane.normal);
89
-
90
- this.position.copy(this.offset);
91
- this.translateZ(-(this.offset.dot(this.plane.normal) + this.plane.constant));
92
-
93
79
  this.scale.set(0.5 * this.size, 0.5 * this.size, 1);
94
-
95
80
  super.updateMatrixWorld(force);
96
81
  }
97
82
  }
98
-
99
- export { PlaneHelper };
@@ -1,11 +0,0 @@
1
- import { Line, Object3D, Plane, Vector3 } from "three";
2
- declare class PlaneHelper extends Line {
3
- plane: Plane;
4
- size: number;
5
- offset: Vector3;
6
- helper: Object3D;
7
- constructor(plane: Plane, size?: number, color?: number, offset?: Vector3);
8
- dispose(): void;
9
- updateMatrixWorld(force: boolean): void;
10
- }
11
- export { PlaneHelper };