@vertexvis/viewer 0.18.0 → 0.18.1-testing.0
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/cjs/{config-ee5af2fe.js → config-ace9f5d5.js} +2 -1
- package/dist/cjs/config-ace9f5d5.js.map +1 -0
- package/dist/cjs/{controller-6914028a.js → controller-ee852f01.js} +12 -3
- package/dist/cjs/controller-ee852f01.js.map +1 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/vertex-scene-tree.cjs.entry.js +2 -2
- package/dist/cjs/vertex-viewer-measurement-precise.cjs.entry.js +1 -1
- package/dist/cjs/vertex-viewer-pin-group.cjs.entry.js +1 -1
- package/dist/cjs/vertex-viewer.cjs.entry.js +103 -35
- package/dist/cjs/vertex-viewer.cjs.entry.js.map +1 -1
- package/dist/collection/components/scene-tree/lib/controller.js +11 -2
- package/dist/collection/components/scene-tree/lib/controller.js.map +1 -1
- package/dist/collection/lib/interactions/interactionApi.js +0 -34
- package/dist/collection/lib/interactions/interactionApi.js.map +1 -1
- package/dist/collection/lib/interactions/interactionApiPerspective.js +103 -1
- package/dist/collection/lib/interactions/interactionApiPerspective.js.map +1 -1
- package/dist/collection/lib/types/interactions.js +1 -0
- package/dist/collection/lib/types/interactions.js.map +1 -1
- package/dist/custom-elements/index.js +114 -36
- package/dist/custom-elements/index.js.map +1 -1
- package/dist/esm/{config-65fd1bba.js → config-2b2e3f66.js} +2 -1
- package/dist/esm/config-2b2e3f66.js.map +1 -0
- package/dist/esm/{controller-1f6c87ab.js → controller-ea698f9b.js} +12 -3
- package/dist/esm/controller-ea698f9b.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/vertex-scene-tree.entry.js +2 -2
- package/dist/esm/vertex-viewer-measurement-precise.entry.js +1 -1
- package/dist/esm/vertex-viewer-pin-group.entry.js +1 -1
- package/dist/esm/vertex-viewer.entry.js +103 -35
- package/dist/esm/vertex-viewer.entry.js.map +1 -1
- package/dist/types/components/scene-tree/lib/controller.d.ts +1 -0
- package/dist/types/lib/interactions/interactionApi.d.ts +1 -1
- package/dist/types/lib/interactions/interactionApiPerspective.d.ts +3 -0
- package/dist/types/lib/types/interactions.d.ts +7 -0
- package/dist/viewer/index.esm.js +1 -1
- package/dist/viewer/p-0de95c4d.js +5 -0
- package/dist/viewer/p-0de95c4d.js.map +1 -0
- package/dist/viewer/{p-e2e7d01b.entry.js → p-2cca6daa.entry.js} +2 -2
- package/dist/viewer/{p-d8c70701.entry.js → p-2ce1d5a7.entry.js} +2 -2
- package/dist/viewer/{p-31c3b8d6.entry.js → p-4225576d.entry.js} +2 -2
- package/dist/viewer/p-5145f091.entry.js +5 -0
- package/dist/viewer/p-5145f091.entry.js.map +1 -0
- package/dist/viewer/{p-931247b6.js → p-bb131c4a.js} +2 -2
- package/dist/viewer/p-bb131c4a.js.map +1 -0
- package/dist/viewer/viewer.esm.js +1 -1
- package/package.json +7 -7
- package/dist/cjs/config-ee5af2fe.js.map +0 -1
- package/dist/cjs/controller-6914028a.js.map +0 -1
- package/dist/esm/config-65fd1bba.js.map +0 -1
- package/dist/esm/controller-1f6c87ab.js.map +0 -1
- package/dist/viewer/p-089d11bf.js +0 -5
- package/dist/viewer/p-089d11bf.js.map +0 -1
- package/dist/viewer/p-931247b6.js.map +0 -1
- package/dist/viewer/p-f1e718b4.entry.js +0 -5
- package/dist/viewer/p-f1e718b4.entry.js.map +0 -1
- /package/dist/viewer/{p-e2e7d01b.entry.js.map → p-2cca6daa.entry.js.map} +0 -0
- /package/dist/viewer/{p-d8c70701.entry.js.map → p-2ce1d5a7.entry.js.map} +0 -0
- /package/dist/viewer/{p-31c3b8d6.entry.js.map → p-4225576d.entry.js.map} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2023 Vertex Software LLC. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import { Point, Vector3 } from '@vertexvis/geometry';
|
|
4
|
+
import { Plane, Point, Ray, Vector3 } from '@vertexvis/geometry';
|
|
5
5
|
import { InteractionApi, } from './interactionApi';
|
|
6
|
+
const CAMERA_MIN_ZOOM_SCALAR = 0.2;
|
|
6
7
|
export class InteractionApiPerspective extends InteractionApi {
|
|
7
8
|
constructor(stream, cursors, getConfig, getScene, getFrame, getViewport, tapEmitter, doubleTapEmitter, longPressEmitter, interactionStartedEmitter, interactionFinishedEmitter) {
|
|
8
9
|
super(stream, cursors, getConfig, getScene, getFrame, getViewport, tapEmitter, doubleTapEmitter, longPressEmitter, interactionStartedEmitter, interactionFinishedEmitter);
|
|
@@ -30,6 +31,48 @@ export class InteractionApiPerspective extends InteractionApi {
|
|
|
30
31
|
return camera.moveBy(offset);
|
|
31
32
|
});
|
|
32
33
|
}
|
|
34
|
+
async zoomCameraToPoint(point, delta) {
|
|
35
|
+
return this.transformCamera(({ camera, viewport, frame, depthBuffer, boundingBox }) => {
|
|
36
|
+
const cam = frame.scene.camera;
|
|
37
|
+
const dir = cam.direction;
|
|
38
|
+
const frameCam = camera.toFrameCamera();
|
|
39
|
+
const ray = viewport.transformPointToRay(point, frame.image, frameCam);
|
|
40
|
+
if (this.zoomData == null) {
|
|
41
|
+
const fallbackPlane = Plane.fromNormalAndCoplanarPoint(dir, cam.lookAt);
|
|
42
|
+
const fallbackPt = Ray.intersectPlane(ray, fallbackPlane);
|
|
43
|
+
if (fallbackPt == null) {
|
|
44
|
+
console.warn('Cannot determine fallback point for zoom. Ray does not intersect plane.');
|
|
45
|
+
return camera;
|
|
46
|
+
}
|
|
47
|
+
const hitPt = depthBuffer != null
|
|
48
|
+
? this.getWorldPoint(point, depthBuffer, fallbackPt)
|
|
49
|
+
: fallbackPt;
|
|
50
|
+
const hitPlane = Plane.fromNormalAndCoplanarPoint(dir, hitPt);
|
|
51
|
+
this.zoomData = { hitPt, hitPlane };
|
|
52
|
+
}
|
|
53
|
+
if (this.zoomData != null) {
|
|
54
|
+
const { hitPlane } = this.zoomData;
|
|
55
|
+
const { position, distance, isPastHitPlane, keepCurrent } = this.computeZoomDistances(delta, camera, viewport, boundingBox, ray, this.zoomData);
|
|
56
|
+
if (isPastHitPlane && !keepCurrent) {
|
|
57
|
+
const viewVectorRay = Ray.create({
|
|
58
|
+
origin: position,
|
|
59
|
+
direction: Vector3.normalize(camera.viewVector),
|
|
60
|
+
});
|
|
61
|
+
return camera.update({
|
|
62
|
+
position,
|
|
63
|
+
lookAt: Ray.at(viewVectorRay, distance),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else if (!keepCurrent) {
|
|
67
|
+
return camera.update({
|
|
68
|
+
position,
|
|
69
|
+
lookAt: Plane.projectPoint(hitPlane, position),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return camera;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
33
76
|
async transformCamera(t) {
|
|
34
77
|
var _a;
|
|
35
78
|
if (this.isInteracting()) {
|
|
@@ -51,5 +94,64 @@ export class InteractionApiPerspective extends InteractionApi {
|
|
|
51
94
|
await ((_a = this.currentCamera) === null || _a === void 0 ? void 0 : _a.render());
|
|
52
95
|
}
|
|
53
96
|
}
|
|
97
|
+
computeZoomDistances(delta, camera, viewport, boundingBox, pointRay, zoomData) {
|
|
98
|
+
const config = this.getConfig();
|
|
99
|
+
const { hitPt, hitPlane } = zoomData;
|
|
100
|
+
const minDistance = config.useMinimumPerspectiveZoomDistance
|
|
101
|
+
? this.computeZoomMinimumDistance(camera, boundingBox)
|
|
102
|
+
: -1;
|
|
103
|
+
const expectedDistance = Vector3.distance(camera.position, hitPt);
|
|
104
|
+
const actualDistance = Math.max(minDistance, expectedDistance);
|
|
105
|
+
const epsilon = (6 * actualDistance * delta) / viewport.height;
|
|
106
|
+
const expectedPosition = Ray.at(pointRay, epsilon);
|
|
107
|
+
const expectedViewVector = Ray.create({
|
|
108
|
+
origin: expectedPosition,
|
|
109
|
+
direction: Vector3.normalize(camera.viewVector),
|
|
110
|
+
});
|
|
111
|
+
const expectedIntersection = Ray.intersectPlane(expectedViewVector, hitPlane);
|
|
112
|
+
if (expectedIntersection == null &&
|
|
113
|
+
config.useMinimumPerspectiveZoomDistance) {
|
|
114
|
+
const minDistanceEpsilon = (6 * minDistance * delta) / viewport.height;
|
|
115
|
+
const position = Ray.at(pointRay, minDistanceEpsilon);
|
|
116
|
+
return {
|
|
117
|
+
position,
|
|
118
|
+
distance: minDistance,
|
|
119
|
+
isPastHitPlane: true,
|
|
120
|
+
keepCurrent: false,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
else if (expectedIntersection == null) {
|
|
124
|
+
return {
|
|
125
|
+
position: camera.position,
|
|
126
|
+
distance: actualDistance,
|
|
127
|
+
isPastHitPlane: true,
|
|
128
|
+
keepCurrent: true,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
position: expectedPosition,
|
|
133
|
+
distance: actualDistance,
|
|
134
|
+
isPastHitPlane: false,
|
|
135
|
+
keepCurrent: false,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
computeZoomMinimumDistance(camera, boundingBox) {
|
|
139
|
+
const xLength = Math.abs(boundingBox.min.x) + Math.abs(boundingBox.max.x);
|
|
140
|
+
const yLength = Math.abs(boundingBox.min.y) + Math.abs(boundingBox.max.y);
|
|
141
|
+
const zLength = Math.abs(boundingBox.min.z) + Math.abs(boundingBox.max.z);
|
|
142
|
+
const maxLength = Math.max(xLength, yLength, zLength);
|
|
143
|
+
const absDotX = Math.abs(Vector3.dot(Vector3.normalize(camera.viewVector), Vector3.right()));
|
|
144
|
+
const absDotY = Math.abs(Vector3.dot(Vector3.normalize(camera.viewVector), Vector3.up()));
|
|
145
|
+
const absDotZ = Math.abs(Vector3.dot(Vector3.normalize(camera.viewVector), Vector3.back()));
|
|
146
|
+
const scaledLengthX = xLength * absDotX;
|
|
147
|
+
const scaledLengthY = yLength * absDotY;
|
|
148
|
+
const scaledLengthZ = zLength * absDotZ;
|
|
149
|
+
const relevanceLengthX = maxLength / xLength;
|
|
150
|
+
const relevanceLengthY = maxLength / yLength;
|
|
151
|
+
const relevanceLengthZ = maxLength / zLength;
|
|
152
|
+
return (((scaledLengthX + scaledLengthY + scaledLengthZ) /
|
|
153
|
+
(relevanceLengthX + relevanceLengthY + relevanceLengthZ)) *
|
|
154
|
+
CAMERA_MIN_ZOOM_SCALAR);
|
|
155
|
+
}
|
|
54
156
|
}
|
|
55
157
|
//# sourceMappingURL=interactionApiPerspective.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactionApiPerspective.js","sourceRoot":"","sources":["../../../src/lib/interactions/interactionApiPerspective.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAOrD,OAAO,EAEL,cAAc,GAGf,MAAM,kBAAkB,CAAC;AAG1B,MAAM,OAAO,yBAA0B,SAAQ,cAAc;EAC3D,YACE,MAAiB,EACjB,OAAsB,EACtB,SAAoC,EACpC,QAAuB,EACvB,QAAyC,EACzC,WAA2B,EAC3B,UAAyC,EACzC,gBAA+C,EAC/C,gBAA+C,EAC/C,yBAA6C,EAC7C,0BAA8C;IAE9C,KAAK,CACH,MAAM,EACN,OAAO,EACP,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,0BAA0B,CAC3B,CAAC;EACJ,CAAC;EAED;;;;;;KAMG;EACI,KAAK,CAAC,gBAAgB,CAAC,KAAkB;IAC9C,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;;MACnD,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;MAE7B,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;MACvC,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;MAEhC,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;MACtD,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAA,MAAM,CAAC,IAAI,mCAAI,EAAE,CAAC,CAAC;MAC9D,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;MACzD,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;MAEzD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;MACjC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;MAEpC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CACxB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,EAC7B,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAC9B,CAAC;MAEF,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;EACL,CAAC;EAEM,KAAK,CAAC,eAAe,CAC1B,CAAqC;;IAErC,IAAI,IAAI,CAAC,aAAa,EAAE,EAAE;MACxB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;MACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;MACpC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;MAC9B,MAAM,WAAW,GAAG,MAAM,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,WAAW,EAAE,CAAA,CAAC;MAE/C,IAAI,CAAC,aAAa;QAChB,IAAI,CAAC,aAAa,IAAI,IAAI,IAAI,QAAQ,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI;UAC7D,CAAC,CAAC,CAAC,CAAC;YACA,MAAM,EAAE,IAAI,CAAC,aAAkC;YAC/C,QAAQ;YACR,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;YACpB,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE;YAChC,KAAK;YACL,WAAW;WACZ,CAAC;UACJ,CAAC,CAAC,SAAS,CAAC;MAEhB,MAAM,CAAA,MAAA,IAAI,CAAC,aAAa,0CAAE,MAAM,EAAE,CAAA,CAAC;KACpC;EACH,CAAC;CACF","sourcesContent":["import { EventEmitter } from '@stencil/core';\nimport { Point, Vector3 } from '@vertexvis/geometry';\nimport { StreamApi } from '@vertexvis/stream-api';\n\nimport { ReceivedFrame } from '../..';\nimport { CursorManager } from '../cursors';\nimport { PerspectiveCamera } from '../scenes';\nimport { Viewport } from '../types';\nimport {\n CameraTransform,\n InteractionApi,\n InteractionConfigProvider,\n SceneProvider,\n} from './interactionApi';\nimport { TapEventDetails } from './tapEventDetails';\n\nexport class InteractionApiPerspective extends InteractionApi {\n public constructor(\n stream: StreamApi,\n cursors: CursorManager,\n getConfig: InteractionConfigProvider,\n getScene: SceneProvider,\n getFrame: () => ReceivedFrame | undefined,\n getViewport: () => Viewport,\n tapEmitter: EventEmitter<TapEventDetails>,\n doubleTapEmitter: EventEmitter<TapEventDetails>,\n longPressEmitter: EventEmitter<TapEventDetails>,\n interactionStartedEmitter: EventEmitter<void>,\n interactionFinishedEmitter: EventEmitter<void>\n ) {\n super(\n stream,\n cursors,\n getConfig,\n getScene,\n getFrame,\n getViewport,\n tapEmitter,\n doubleTapEmitter,\n longPressEmitter,\n interactionStartedEmitter,\n interactionFinishedEmitter\n );\n }\n\n /**\n * Performs a pan operation of the scene's camera, and requests a new image\n * for the updated scene.\n *\n * @param delta A position delta `{x, y}` in the 2D coordinate space of the\n * viewer.\n */\n public async panCameraByDelta(delta: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, viewport }) => {\n const vv = camera.viewVector;\n\n const u = Vector3.normalize(camera.up);\n const v = Vector3.normalize(vv);\n\n const throttledDelta = Point.scale(delta, 0.25, 0.25);\n const d = Vector3.magnitude(vv) * Math.tan(camera.fovY ?? 45);\n const epsilonX = (throttledDelta.x * d) / viewport.width;\n const epsilonY = (throttledDelta.y / viewport.width) * d;\n\n const xvec = Vector3.cross(u, v);\n const yvec = Vector3.cross(v, xvec);\n\n const offset = Vector3.add(\n Vector3.scale(epsilonX, xvec),\n Vector3.scale(epsilonY, yvec)\n );\n\n return camera.moveBy(offset);\n });\n }\n\n public async transformCamera(\n t: CameraTransform<PerspectiveCamera>\n ): Promise<void> {\n if (this.isInteracting()) {\n const scene = await this.getScene();\n const viewport = this.getViewport();\n const frame = this.getFrame();\n const depthBuffer = await frame?.depthBuffer();\n\n this.currentCamera =\n this.currentCamera != null && viewport != null && frame != null\n ? t({\n camera: this.currentCamera as PerspectiveCamera,\n viewport,\n scale: scene.scale(),\n boundingBox: scene.boundingBox(),\n frame,\n depthBuffer,\n })\n : undefined;\n\n await this.currentCamera?.render();\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactionApiPerspective.js","sourceRoot":"","sources":["../../../src/lib/interactions/interactionApiPerspective.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter } from '@stencil/core';\nimport { BoundingBox, Plane, Point, Ray, Vector3 } from '@vertexvis/geometry';\nimport { StreamApi } from '@vertexvis/stream-api';\n\nimport { ReceivedFrame } from '../..';\nimport { CursorManager } from '../cursors';\nimport { PerspectiveCamera } from '../scenes';\nimport { Viewport } from '../types';\nimport {\n CameraTransform,\n InteractionApi,\n InteractionConfigProvider,\n SceneProvider,\n ZoomData,\n} from './interactionApi';\nimport { TapEventDetails } from './tapEventDetails';\n\ninterface ZoomPositionData {\n position: Vector3.Vector3;\n distance: number;\n isPastHitPlane: boolean;\n keepCurrent: boolean;\n}\n\nconst CAMERA_MIN_ZOOM_SCALAR = 0.2;\n\nexport class InteractionApiPerspective extends InteractionApi {\n public constructor(\n stream: StreamApi,\n cursors: CursorManager,\n getConfig: InteractionConfigProvider,\n getScene: SceneProvider,\n getFrame: () => ReceivedFrame | undefined,\n getViewport: () => Viewport,\n tapEmitter: EventEmitter<TapEventDetails>,\n doubleTapEmitter: EventEmitter<TapEventDetails>,\n longPressEmitter: EventEmitter<TapEventDetails>,\n interactionStartedEmitter: EventEmitter<void>,\n interactionFinishedEmitter: EventEmitter<void>\n ) {\n super(\n stream,\n cursors,\n getConfig,\n getScene,\n getFrame,\n getViewport,\n tapEmitter,\n doubleTapEmitter,\n longPressEmitter,\n interactionStartedEmitter,\n interactionFinishedEmitter\n );\n }\n\n /**\n * Performs a pan operation of the scene's camera, and requests a new image\n * for the updated scene.\n *\n * @param delta A position delta `{x, y}` in the 2D coordinate space of the\n * viewer.\n */\n public async panCameraByDelta(delta: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, viewport }) => {\n const vv = camera.viewVector;\n\n const u = Vector3.normalize(camera.up);\n const v = Vector3.normalize(vv);\n\n const throttledDelta = Point.scale(delta, 0.25, 0.25);\n const d = Vector3.magnitude(vv) * Math.tan(camera.fovY ?? 45);\n const epsilonX = (throttledDelta.x * d) / viewport.width;\n const epsilonY = (throttledDelta.y / viewport.width) * d;\n\n const xvec = Vector3.cross(u, v);\n const yvec = Vector3.cross(v, xvec);\n\n const offset = Vector3.add(\n Vector3.scale(epsilonX, xvec),\n Vector3.scale(epsilonY, yvec)\n );\n\n return camera.moveBy(offset);\n });\n }\n\n public async zoomCameraToPoint(\n point: Point.Point,\n delta: number\n ): Promise<void> {\n return this.transformCamera(\n ({ camera, viewport, frame, depthBuffer, boundingBox }) => {\n const cam = frame.scene.camera;\n const dir = cam.direction;\n\n const frameCam = camera.toFrameCamera();\n const ray = viewport.transformPointToRay(point, frame.image, frameCam);\n\n if (this.zoomData == null) {\n const fallbackPlane = Plane.fromNormalAndCoplanarPoint(\n dir,\n cam.lookAt\n );\n const fallbackPt = Ray.intersectPlane(ray, fallbackPlane);\n if (fallbackPt == null) {\n console.warn(\n 'Cannot determine fallback point for zoom. Ray does not intersect plane.'\n );\n return camera;\n }\n\n const hitPt =\n depthBuffer != null\n ? this.getWorldPoint(point, depthBuffer, fallbackPt)\n : fallbackPt;\n const hitPlane = Plane.fromNormalAndCoplanarPoint(dir, hitPt);\n this.zoomData = { hitPt, hitPlane };\n }\n\n if (this.zoomData != null) {\n const { hitPlane } = this.zoomData;\n const { position, distance, isPastHitPlane, keepCurrent } =\n this.computeZoomDistances(\n delta,\n camera,\n viewport,\n boundingBox,\n ray,\n this.zoomData\n );\n\n if (isPastHitPlane && !keepCurrent) {\n const viewVectorRay = Ray.create({\n origin: position,\n direction: Vector3.normalize(camera.viewVector),\n });\n\n return camera.update({\n position,\n lookAt: Ray.at(viewVectorRay, distance),\n });\n } else if (!keepCurrent) {\n return camera.update({\n position,\n lookAt: Plane.projectPoint(hitPlane, position),\n });\n }\n }\n return camera;\n }\n );\n }\n\n public async transformCamera(\n t: CameraTransform<PerspectiveCamera>\n ): Promise<void> {\n if (this.isInteracting()) {\n const scene = await this.getScene();\n const viewport = this.getViewport();\n const frame = this.getFrame();\n const depthBuffer = await frame?.depthBuffer();\n\n this.currentCamera =\n this.currentCamera != null && viewport != null && frame != null\n ? t({\n camera: this.currentCamera as PerspectiveCamera,\n viewport,\n scale: scene.scale(),\n boundingBox: scene.boundingBox(),\n frame,\n depthBuffer,\n })\n : undefined;\n\n await this.currentCamera?.render();\n }\n }\n\n private computeZoomDistances(\n delta: number,\n camera: PerspectiveCamera,\n viewport: Viewport,\n boundingBox: BoundingBox.BoundingBox,\n pointRay: Ray.Ray,\n zoomData: ZoomData\n ): ZoomPositionData {\n const config = this.getConfig();\n const { hitPt, hitPlane } = zoomData;\n const minDistance = config.useMinimumPerspectiveZoomDistance\n ? this.computeZoomMinimumDistance(camera, boundingBox)\n : -1;\n const expectedDistance = Vector3.distance(camera.position, hitPt);\n const actualDistance = Math.max(minDistance, expectedDistance);\n const epsilon = (6 * actualDistance * delta) / viewport.height;\n\n const expectedPosition = Ray.at(pointRay, epsilon);\n const expectedViewVector = Ray.create({\n origin: expectedPosition,\n direction: Vector3.normalize(camera.viewVector),\n });\n const expectedIntersection = Ray.intersectPlane(\n expectedViewVector,\n hitPlane\n );\n\n if (\n expectedIntersection == null &&\n config.useMinimumPerspectiveZoomDistance\n ) {\n const minDistanceEpsilon = (6 * minDistance * delta) / viewport.height;\n const position = Ray.at(pointRay, minDistanceEpsilon);\n\n return {\n position,\n distance: minDistance,\n isPastHitPlane: true,\n keepCurrent: false,\n };\n } else if (expectedIntersection == null) {\n return {\n position: camera.position,\n distance: actualDistance,\n isPastHitPlane: true,\n keepCurrent: true,\n };\n }\n\n return {\n position: expectedPosition,\n distance: actualDistance,\n isPastHitPlane: false,\n keepCurrent: false,\n };\n }\n\n private computeZoomMinimumDistance(\n camera: PerspectiveCamera,\n boundingBox: BoundingBox.BoundingBox\n ): number {\n const xLength = Math.abs(boundingBox.min.x) + Math.abs(boundingBox.max.x);\n const yLength = Math.abs(boundingBox.min.y) + Math.abs(boundingBox.max.y);\n const zLength = Math.abs(boundingBox.min.z) + Math.abs(boundingBox.max.z);\n const maxLength = Math.max(xLength, yLength, zLength);\n\n const absDotX = Math.abs(\n Vector3.dot(Vector3.normalize(camera.viewVector), Vector3.right())\n );\n const absDotY = Math.abs(\n Vector3.dot(Vector3.normalize(camera.viewVector), Vector3.up())\n );\n const absDotZ = Math.abs(\n Vector3.dot(Vector3.normalize(camera.viewVector), Vector3.back())\n );\n\n const scaledLengthX = xLength * absDotX;\n const scaledLengthY = yLength * absDotY;\n const scaledLengthZ = zLength * absDotZ;\n\n const relevanceLengthX = maxLength / xLength;\n const relevanceLengthY = maxLength / yLength;\n const relevanceLengthZ = maxLength / zLength;\n\n return (\n ((scaledLengthX + scaledLengthY + scaledLengthZ) /\n (relevanceLengthX + relevanceLengthY + relevanceLengthZ)) *\n CAMERA_MIN_ZOOM_SCALAR\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactions.js","sourceRoot":"","sources":["../../../src/lib/types/interactions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"interactions.js","sourceRoot":"","sources":["../../../src/lib/types/interactions.ts"],"names":[],"mappings":"AA8BA,MAAM,CAAC,MAAM,wBAAwB,GAAsB;EACzD,oBAAoB,EAAE,CAAC;EACvB,sBAAsB,EAAE,CAAC;EACzB,gBAAgB,EAAE,EAAE;EACpB,iCAAiC,EAAE,IAAI;CACxC,CAAC","sourcesContent":["export interface InteractionConfig {\n /**\n * The amount of movement required with a fine (mouse, trackpad, etc) pointer\n * input before an interaction is considered a movement that will update the\n * camera. This threshold is always scaled up based on the device's pixel ratio.\n */\n finePointerThreshold: number;\n\n /**\n * The amount of movement required with a coarse (touch, stylus, etc) pointer\n * input before an interaction is considered a movement that will update the\n * camera. This threshold is always scaled up based on the device's pixel ratio.\n */\n coarsePointerThreshold: number;\n\n /**\n * The amount of time before a movement is considered an interaction and will\n * update the camera.\n */\n interactionDelay: number;\n\n /**\n * Whether the `zoomCameraToPoint` interaction through the `InteractionApiPerspective`\n * will enforce a minimum distance when moving the camera. When set, the camera will be\n * able to move through geometry under the cursor, rather than being restricted by the\n * point under the cursor. Defaults to `true`.\n */\n useMinimumPerspectiveZoomDistance: boolean;\n}\n\nexport const defaultInteractionConfig: InteractionConfig = {\n finePointerThreshold: 1,\n coarsePointerThreshold: 3,\n interactionDelay: 75,\n useMinimumPerspectiveZoomDistance: true,\n};\n"]}
|
|
@@ -12218,7 +12218,7 @@ class SceneTreeController {
|
|
|
12218
12218
|
this.pages = new Map();
|
|
12219
12219
|
this.activeRowRange = [0, 0];
|
|
12220
12220
|
this.metadataKeys = [];
|
|
12221
|
-
this.debugLogs =
|
|
12221
|
+
this.debugLogs = true;
|
|
12222
12222
|
/**
|
|
12223
12223
|
* A dispatcher that emits an event whenever the internal state has changed.
|
|
12224
12224
|
*/
|
|
@@ -12432,6 +12432,7 @@ class SceneTreeController {
|
|
|
12432
12432
|
? undefined
|
|
12433
12433
|
: this.state.shouldShowEmptyResults,
|
|
12434
12434
|
handshakeReceived: reset ? undefined : this.state.handshakeReceived,
|
|
12435
|
+
firstFetchComplete: reset ? undefined : this.state.firstFetchComplete,
|
|
12435
12436
|
});
|
|
12436
12437
|
}
|
|
12437
12438
|
cancel() {
|
|
@@ -12724,6 +12725,14 @@ class SceneTreeController {
|
|
|
12724
12725
|
if (msg.hasHandshake()) {
|
|
12725
12726
|
this.clearHandshakeTimer();
|
|
12726
12727
|
this.updateState(Object.assign(Object.assign({}, this.state), { handshakeReceived: true }));
|
|
12728
|
+
// Verify that we've loaded the first page of the tree when we receive
|
|
12729
|
+
// a handshake in the case that the listener was not fully registered
|
|
12730
|
+
// when a `ListChange` was sent.
|
|
12731
|
+
if (this.state.firstFetchComplete) {
|
|
12732
|
+
this.log('Scene tree did not have the first page before the handshake completed');
|
|
12733
|
+
this.invalidateAfterOffset(0);
|
|
12734
|
+
this.fetchUnloadedPagesInActiveRows();
|
|
12735
|
+
}
|
|
12727
12736
|
}
|
|
12728
12737
|
this.startIdleReconnectTimer();
|
|
12729
12738
|
const { change } = msg.toObject();
|
|
@@ -12819,7 +12828,7 @@ class SceneTreeController {
|
|
|
12819
12828
|
}
|
|
12820
12829
|
else {
|
|
12821
12830
|
this.updateState(Object.assign(Object.assign({}, this.state), { totalRows: totalRows, rows: rows, shouldShowLoading: rows.length === 0 && this.state.shouldShowLoading, shouldShowEmptyResults: this.state.filterTerm != null &&
|
|
12822
|
-
(rows.length === 0 || this.state.totalFilteredRows === 0) }));
|
|
12831
|
+
(rows.length === 0 || this.state.totalFilteredRows === 0), firstFetchComplete: true }));
|
|
12823
12832
|
}
|
|
12824
12833
|
}
|
|
12825
12834
|
}
|
|
@@ -65474,6 +65483,7 @@ const defaultInteractionConfig = {
|
|
|
65474
65483
|
finePointerThreshold: 1,
|
|
65475
65484
|
coarsePointerThreshold: 3,
|
|
65476
65485
|
interactionDelay: 75,
|
|
65486
|
+
useMinimumPerspectiveZoomDistance: true,
|
|
65477
65487
|
};
|
|
65478
65488
|
|
|
65479
65489
|
function fromUrn(urn) {
|
|
@@ -110951,40 +110961,6 @@ class InteractionApi {
|
|
|
110951
110961
|
return newCamera;
|
|
110952
110962
|
});
|
|
110953
110963
|
}
|
|
110954
|
-
async zoomCameraToPoint(point, delta) {
|
|
110955
|
-
return this.transformCamera(({ camera, viewport, frame, depthBuffer }) => {
|
|
110956
|
-
const cam = frame.scene.camera;
|
|
110957
|
-
const dir = cam.direction;
|
|
110958
|
-
const frameCam = camera.toFrameCamera();
|
|
110959
|
-
const ray$1 = viewport.transformPointToRay(point, frame.image, frameCam);
|
|
110960
|
-
if (this.zoomData == null) {
|
|
110961
|
-
const fallbackPlane = plane.fromNormalAndCoplanarPoint(dir, cam.lookAt);
|
|
110962
|
-
const fallbackPt = ray.intersectPlane(ray$1, fallbackPlane);
|
|
110963
|
-
if (fallbackPt == null) {
|
|
110964
|
-
console.warn('Cannot determine fallback point for zoom. Ray does not intersect plane.');
|
|
110965
|
-
return camera;
|
|
110966
|
-
}
|
|
110967
|
-
const hitPt = depthBuffer != null
|
|
110968
|
-
? this.getWorldPoint(point, depthBuffer, fallbackPt)
|
|
110969
|
-
: fallbackPt;
|
|
110970
|
-
const hitPlane = plane.fromNormalAndCoplanarPoint(dir, hitPt);
|
|
110971
|
-
this.zoomData = { hitPt, hitPlane };
|
|
110972
|
-
}
|
|
110973
|
-
if (this.zoomData != null) {
|
|
110974
|
-
const { hitPt, hitPlane } = this.zoomData;
|
|
110975
|
-
const distance = vector3.distance(camera.position, hitPt);
|
|
110976
|
-
const epsilon = (6 * distance * delta) / viewport.height;
|
|
110977
|
-
const position = ray.at(ray$1, epsilon);
|
|
110978
|
-
const lookAt = plane.projectPoint(hitPlane, position);
|
|
110979
|
-
const newCamera = camera.update({ position, lookAt });
|
|
110980
|
-
const newDistance = vector3.distance(position, lookAt);
|
|
110981
|
-
if (newDistance >= newCamera.near) {
|
|
110982
|
-
return newCamera;
|
|
110983
|
-
}
|
|
110984
|
-
}
|
|
110985
|
-
return camera;
|
|
110986
|
-
});
|
|
110987
|
-
}
|
|
110988
110964
|
/**
|
|
110989
110965
|
* Performs a pivot operation of the scene's camera, updating the lookAt
|
|
110990
110966
|
* while maintaining the position, and requests a new image for the
|
|
@@ -111236,6 +111212,7 @@ class InteractionApiOrthographic extends InteractionApi {
|
|
|
111236
111212
|
}
|
|
111237
111213
|
}
|
|
111238
111214
|
|
|
111215
|
+
const CAMERA_MIN_ZOOM_SCALAR = 0.2;
|
|
111239
111216
|
class InteractionApiPerspective extends InteractionApi {
|
|
111240
111217
|
constructor(stream, cursors, getConfig, getScene, getFrame, getViewport, tapEmitter, doubleTapEmitter, longPressEmitter, interactionStartedEmitter, interactionFinishedEmitter) {
|
|
111241
111218
|
super(stream, cursors, getConfig, getScene, getFrame, getViewport, tapEmitter, doubleTapEmitter, longPressEmitter, interactionStartedEmitter, interactionFinishedEmitter);
|
|
@@ -111263,6 +111240,48 @@ class InteractionApiPerspective extends InteractionApi {
|
|
|
111263
111240
|
return camera.moveBy(offset);
|
|
111264
111241
|
});
|
|
111265
111242
|
}
|
|
111243
|
+
async zoomCameraToPoint(point, delta) {
|
|
111244
|
+
return this.transformCamera(({ camera, viewport, frame, depthBuffer, boundingBox }) => {
|
|
111245
|
+
const cam = frame.scene.camera;
|
|
111246
|
+
const dir = cam.direction;
|
|
111247
|
+
const frameCam = camera.toFrameCamera();
|
|
111248
|
+
const ray$1 = viewport.transformPointToRay(point, frame.image, frameCam);
|
|
111249
|
+
if (this.zoomData == null) {
|
|
111250
|
+
const fallbackPlane = plane.fromNormalAndCoplanarPoint(dir, cam.lookAt);
|
|
111251
|
+
const fallbackPt = ray.intersectPlane(ray$1, fallbackPlane);
|
|
111252
|
+
if (fallbackPt == null) {
|
|
111253
|
+
console.warn('Cannot determine fallback point for zoom. Ray does not intersect plane.');
|
|
111254
|
+
return camera;
|
|
111255
|
+
}
|
|
111256
|
+
const hitPt = depthBuffer != null
|
|
111257
|
+
? this.getWorldPoint(point, depthBuffer, fallbackPt)
|
|
111258
|
+
: fallbackPt;
|
|
111259
|
+
const hitPlane = plane.fromNormalAndCoplanarPoint(dir, hitPt);
|
|
111260
|
+
this.zoomData = { hitPt, hitPlane };
|
|
111261
|
+
}
|
|
111262
|
+
if (this.zoomData != null) {
|
|
111263
|
+
const { hitPlane } = this.zoomData;
|
|
111264
|
+
const { position, distance, isPastHitPlane, keepCurrent } = this.computeZoomDistances(delta, camera, viewport, boundingBox, ray$1, this.zoomData);
|
|
111265
|
+
if (isPastHitPlane && !keepCurrent) {
|
|
111266
|
+
const viewVectorRay = ray.create({
|
|
111267
|
+
origin: position,
|
|
111268
|
+
direction: vector3.normalize(camera.viewVector),
|
|
111269
|
+
});
|
|
111270
|
+
return camera.update({
|
|
111271
|
+
position,
|
|
111272
|
+
lookAt: ray.at(viewVectorRay, distance),
|
|
111273
|
+
});
|
|
111274
|
+
}
|
|
111275
|
+
else if (!keepCurrent) {
|
|
111276
|
+
return camera.update({
|
|
111277
|
+
position,
|
|
111278
|
+
lookAt: plane.projectPoint(hitPlane, position),
|
|
111279
|
+
});
|
|
111280
|
+
}
|
|
111281
|
+
}
|
|
111282
|
+
return camera;
|
|
111283
|
+
});
|
|
111284
|
+
}
|
|
111266
111285
|
async transformCamera(t) {
|
|
111267
111286
|
var _a;
|
|
111268
111287
|
if (this.isInteracting()) {
|
|
@@ -111284,6 +111303,65 @@ class InteractionApiPerspective extends InteractionApi {
|
|
|
111284
111303
|
await ((_a = this.currentCamera) === null || _a === void 0 ? void 0 : _a.render());
|
|
111285
111304
|
}
|
|
111286
111305
|
}
|
|
111306
|
+
computeZoomDistances(delta, camera, viewport, boundingBox, pointRay, zoomData) {
|
|
111307
|
+
const config = this.getConfig();
|
|
111308
|
+
const { hitPt, hitPlane } = zoomData;
|
|
111309
|
+
const minDistance = config.useMinimumPerspectiveZoomDistance
|
|
111310
|
+
? this.computeZoomMinimumDistance(camera, boundingBox)
|
|
111311
|
+
: -1;
|
|
111312
|
+
const expectedDistance = vector3.distance(camera.position, hitPt);
|
|
111313
|
+
const actualDistance = Math.max(minDistance, expectedDistance);
|
|
111314
|
+
const epsilon = (6 * actualDistance * delta) / viewport.height;
|
|
111315
|
+
const expectedPosition = ray.at(pointRay, epsilon);
|
|
111316
|
+
const expectedViewVector = ray.create({
|
|
111317
|
+
origin: expectedPosition,
|
|
111318
|
+
direction: vector3.normalize(camera.viewVector),
|
|
111319
|
+
});
|
|
111320
|
+
const expectedIntersection = ray.intersectPlane(expectedViewVector, hitPlane);
|
|
111321
|
+
if (expectedIntersection == null &&
|
|
111322
|
+
config.useMinimumPerspectiveZoomDistance) {
|
|
111323
|
+
const minDistanceEpsilon = (6 * minDistance * delta) / viewport.height;
|
|
111324
|
+
const position = ray.at(pointRay, minDistanceEpsilon);
|
|
111325
|
+
return {
|
|
111326
|
+
position,
|
|
111327
|
+
distance: minDistance,
|
|
111328
|
+
isPastHitPlane: true,
|
|
111329
|
+
keepCurrent: false,
|
|
111330
|
+
};
|
|
111331
|
+
}
|
|
111332
|
+
else if (expectedIntersection == null) {
|
|
111333
|
+
return {
|
|
111334
|
+
position: camera.position,
|
|
111335
|
+
distance: actualDistance,
|
|
111336
|
+
isPastHitPlane: true,
|
|
111337
|
+
keepCurrent: true,
|
|
111338
|
+
};
|
|
111339
|
+
}
|
|
111340
|
+
return {
|
|
111341
|
+
position: expectedPosition,
|
|
111342
|
+
distance: actualDistance,
|
|
111343
|
+
isPastHitPlane: false,
|
|
111344
|
+
keepCurrent: false,
|
|
111345
|
+
};
|
|
111346
|
+
}
|
|
111347
|
+
computeZoomMinimumDistance(camera, boundingBox) {
|
|
111348
|
+
const xLength = Math.abs(boundingBox.min.x) + Math.abs(boundingBox.max.x);
|
|
111349
|
+
const yLength = Math.abs(boundingBox.min.y) + Math.abs(boundingBox.max.y);
|
|
111350
|
+
const zLength = Math.abs(boundingBox.min.z) + Math.abs(boundingBox.max.z);
|
|
111351
|
+
const maxLength = Math.max(xLength, yLength, zLength);
|
|
111352
|
+
const absDotX = Math.abs(vector3.dot(vector3.normalize(camera.viewVector), vector3.right()));
|
|
111353
|
+
const absDotY = Math.abs(vector3.dot(vector3.normalize(camera.viewVector), vector3.up()));
|
|
111354
|
+
const absDotZ = Math.abs(vector3.dot(vector3.normalize(camera.viewVector), vector3.back()));
|
|
111355
|
+
const scaledLengthX = xLength * absDotX;
|
|
111356
|
+
const scaledLengthY = yLength * absDotY;
|
|
111357
|
+
const scaledLengthZ = zLength * absDotZ;
|
|
111358
|
+
const relevanceLengthX = maxLength / xLength;
|
|
111359
|
+
const relevanceLengthY = maxLength / yLength;
|
|
111360
|
+
const relevanceLengthZ = maxLength / zLength;
|
|
111361
|
+
return (((scaledLengthX + scaledLengthY + scaledLengthZ) /
|
|
111362
|
+
(relevanceLengthX + relevanceLengthY + relevanceLengthZ)) *
|
|
111363
|
+
CAMERA_MIN_ZOOM_SCALAR);
|
|
111364
|
+
}
|
|
111287
111365
|
}
|
|
111288
111366
|
|
|
111289
111367
|
class FlyToPositionKeyInteraction {
|