@vertexvis/viewer 0.23.6-canary.8 → 0.23.6-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/index-4ebe6acf.js +138 -1
- package/dist/cjs/{regl-component-b9b3e921.js → regl-component-32e37b41.js} +30 -2
- package/dist/cjs/{regl-component-b9b3e921.js.map → regl-component-32e37b41.js.map} +1 -1
- package/dist/cjs/vertex-viewer-hit-result-indicator.cjs.entry.js +1 -1
- package/dist/cjs/vertex-viewer-transform-widget.cjs.entry.js +1 -1
- package/dist/cjs/vertex-viewer.cjs.entry.js +89 -15
- package/dist/cjs/vertex-viewer.cjs.entry.js.map +1 -1
- package/dist/collection/lib/interactions/interactionApi.js +66 -8
- package/dist/collection/lib/interactions/interactionApi.js.map +1 -1
- package/dist/collection/lib/interactions/interactionApiOrthographic.js +23 -7
- package/dist/collection/lib/interactions/interactionApiOrthographic.js.map +1 -1
- package/dist/collection/lib/webgl/regl-component.js +29 -1
- package/dist/collection/lib/webgl/regl-component.js.map +1 -1
- package/dist/components/regl-component.js +29 -1
- package/dist/components/regl-component.js.map +1 -1
- package/dist/components/vertex-viewer.js +90 -16
- package/dist/components/vertex-viewer.js.map +1 -1
- package/dist/esm/index-fef00dee.js +138 -1
- package/dist/esm/{regl-component-3d0639a6.js → regl-component-76cd98b9.js} +30 -2
- package/dist/esm/{regl-component-3d0639a6.js.map → regl-component-76cd98b9.js.map} +1 -1
- package/dist/esm/vertex-viewer-hit-result-indicator.entry.js +1 -1
- package/dist/esm/vertex-viewer-transform-widget.entry.js +1 -1
- package/dist/esm/vertex-viewer.entry.js +90 -16
- package/dist/esm/vertex-viewer.entry.js.map +1 -1
- package/dist/types/lib/webgl/regl-component.d.ts +4 -0
- package/dist/viewer/{p-d7a621a2.entry.js → p-07d2b2fa.entry.js} +2 -2
- package/dist/viewer/{p-ed1460ad.js → p-75cad0f2.js} +2 -2
- package/dist/viewer/p-75cad0f2.js.map +1 -0
- package/dist/viewer/{p-96dd1ad5.entry.js → p-9c4fc8bd.entry.js} +2 -2
- package/dist/viewer/p-d2ddc770.entry.js +5 -0
- package/dist/viewer/p-d2ddc770.entry.js.map +1 -0
- package/dist/viewer/viewer.esm.js +1 -1
- package/package.json +7 -7
- package/dist/viewer/p-7e808b58.entry.js +0 -5
- package/dist/viewer/p-7e808b58.entry.js.map +0 -1
- package/dist/viewer/p-ed1460ad.js.map +0 -1
- /package/dist/viewer/{p-d7a621a2.entry.js.map → p-07d2b2fa.entry.js.map} +0 -0
- /package/dist/viewer/{p-96dd1ad5.entry.js.map → p-9c4fc8bd.entry.js.map} +0 -0
|
@@ -281,14 +281,72 @@ export class InteractionApi {
|
|
|
281
281
|
* values zoom out.
|
|
282
282
|
*/
|
|
283
283
|
async zoomCamera(delta) {
|
|
284
|
-
return this.transformCamera(({ camera, viewport }) => {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
284
|
+
return this.transformCamera(({ camera, viewport, frame, boundingBox }) => {
|
|
285
|
+
if (viewport != null && frame != null) {
|
|
286
|
+
const isPerspective = camera === null || camera === void 0 ? void 0 : camera.toFrameCamera().isPerspective();
|
|
287
|
+
if (isPerspective) {
|
|
288
|
+
const vv = camera.viewVector;
|
|
289
|
+
// Calculate the unit-less scalar determining the amount to zoom. The delta parameter
|
|
290
|
+
// is scaled by the viewport height because if the viewport is larger, then the
|
|
291
|
+
// user should have to perform a bigger action to zoom the model the same amount.
|
|
292
|
+
// Note that delta and viewport.height both have units of pixels. Further, the
|
|
293
|
+
// 3 multiplier was chosen to match the desired zoom speed.
|
|
294
|
+
const distance = Vector3.magnitude(vv);
|
|
295
|
+
const relativeDeltaToViewportHeight = 3 * distance * (delta / viewport.height);
|
|
296
|
+
// Scale the current viewVector by the scalar calculated above to determine how to adjust the camera position
|
|
297
|
+
const v = Vector3.normalize(vv);
|
|
298
|
+
const positionChange = Vector3.scale(relativeDeltaToViewportHeight, v);
|
|
299
|
+
// Calculate the new camera position
|
|
300
|
+
const position = Vector3.add(camera.position, positionChange);
|
|
301
|
+
// Update the camera with the new position
|
|
302
|
+
const newCamera = camera.update({ position });
|
|
303
|
+
return newCamera;
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
// Retrieve properties of the current camera
|
|
307
|
+
const orthographicCamera = camera;
|
|
308
|
+
const frameCam = camera.toFrameCamera();
|
|
309
|
+
const dir = frameCam.direction;
|
|
310
|
+
const ray = viewport.transformPointToRay(viewport.center, frame.image, frameCam);
|
|
311
|
+
// Calculate the unit-less scalar determining the amount to zoom. The delta parameter
|
|
312
|
+
// is scaled by the viewport height because if the viewport is larger, then the
|
|
313
|
+
// user should have to perform a bigger action to zoom the model the same amount.
|
|
314
|
+
// Note that delta and viewport.height both have units of pixels. Further, the
|
|
315
|
+
// 4 multiplier was chosen to match the desired zoom speed.
|
|
316
|
+
const relativeDeltaToViewportHeight = 4 * (delta / viewport.height);
|
|
317
|
+
// Calculate the fovHeight after performing the zoom. zoomedFovHeight has the
|
|
318
|
+
// same units of camera.fovHeight (the world units). The new fovHeight
|
|
319
|
+
// has a minimum value, which is a function of the size of the bounding box,
|
|
320
|
+
// which ensures the new fovHeight is a positive, non-zero number.
|
|
321
|
+
const minimumFovHeight = Vector3.magnitude(BoundingBox.diagonal(boundingBox)) * 1e-5;
|
|
322
|
+
const zoomedFovHeight = Math.max(minimumFovHeight, orthographicCamera.fovHeight * (1 - relativeDeltaToViewportHeight));
|
|
323
|
+
// Calculate the plane and point to zoom relative to
|
|
324
|
+
const planeToZoomRelativeTo = Plane.fromNormalAndCoplanarPoint(dir, frameCam.lookAt);
|
|
325
|
+
const pointToZoomRelativeTo = Ray.intersectPlane(ray, planeToZoomRelativeTo);
|
|
326
|
+
if (pointToZoomRelativeTo != null) {
|
|
327
|
+
// Project the current look at point onto the zoom plane
|
|
328
|
+
const projectedLookAt = Plane.projectPoint(planeToZoomRelativeTo, orthographicCamera.lookAt);
|
|
329
|
+
// Calculate the vector to determine how to adjust the camera's look at point.
|
|
330
|
+
// Ensure that the viewVector is scaled to the expected length in order to
|
|
331
|
+
// ensure other camera calculations are correct, for example, the occlusion
|
|
332
|
+
// calculations for pins.
|
|
333
|
+
const fovHeightRelativeChange = (orthographicCamera.fovHeight - zoomedFovHeight) /
|
|
334
|
+
orthographicCamera.fovHeight;
|
|
335
|
+
const lookAtChangeVector = Vector3.scale(fovHeightRelativeChange, Vector3.subtract(pointToZoomRelativeTo, projectedLookAt));
|
|
336
|
+
// Calculate the camera's new look at point
|
|
337
|
+
const updatedLookAt = Vector3.add(orthographicCamera.lookAt, lookAtChangeVector);
|
|
338
|
+
// Update the orthographic camera
|
|
339
|
+
// Note rotationPoint should match lookAt after a zoom interaction
|
|
340
|
+
const newCamera = camera.update({
|
|
341
|
+
lookAt: updatedLookAt,
|
|
342
|
+
rotationPoint: updatedLookAt,
|
|
343
|
+
fovHeight: zoomedFovHeight,
|
|
344
|
+
});
|
|
345
|
+
return newCamera;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return camera;
|
|
292
350
|
});
|
|
293
351
|
}
|
|
294
352
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactionApi.js","sourceRoot":"","sources":["../../../../../src/lib/interactions/interactionApi.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter } from '@stencil/core';\nimport { vertexvis } from '@vertexvis/frame-streaming-protos';\nimport {\n Angle,\n BoundingBox,\n Plane,\n Point,\n Ray,\n Vector3,\n} from '@vertexvis/geometry';\nimport { StreamApi } from '@vertexvis/stream-api';\nimport { Disposable } from '@vertexvis/utils';\n\nimport { ReceivedFrame } from '../..';\nimport { Cursor, CursorManager } from '../cursors';\nimport { Camera, CameraRenderOptions, Scene } from '../scenes';\nimport {\n DepthBuffer,\n EntityType,\n FrameCameraBase,\n Interactions,\n Viewport,\n} from '../types';\nimport { TapEventDetails, TapEventKeys } from './tapEventDetails';\n\nexport type SceneProvider = () => Promise<Scene>;\n\nexport type InteractionConfigProvider = () => Interactions.InteractionConfig;\n\nexport type CameraTransform<\n T extends Camera = Camera,\n R extends Camera = Camera\n> = (data: {\n camera: T;\n viewport: Viewport;\n scale: Point.Point;\n boundingBox: BoundingBox.BoundingBox;\n frame: ReceivedFrame;\n depthBuffer?: DepthBuffer;\n}) => R;\n\nexport interface PanData {\n hitPt: Vector3.Vector3;\n hitPlane: Plane.Plane;\n startingCamera: FrameCameraBase;\n}\n\nexport interface ZoomData {\n hitPt: Vector3.Vector3;\n hitPlane: Plane.Plane;\n}\n\n/**\n * The `InteractionApi` provides methods that API developers can use to modify\n * the internal state of an interaction.\n */\nexport abstract class InteractionApi<T extends Camera = Camera> {\n protected currentCamera?: Camera;\n private sceneLoadingPromise?: Promise<Scene>;\n private lastAngle: Angle.Angle | undefined;\n private worldRotationPoint?: Vector3.Vector3;\n\n protected panData?: PanData;\n protected zoomData?: ZoomData;\n\n public constructor(\n protected stream: StreamApi,\n private cursors: CursorManager,\n protected getConfig: InteractionConfigProvider,\n protected getScene: SceneProvider,\n protected getFrame: () => ReceivedFrame | undefined,\n public getViewport: () => Viewport,\n private tapEmitter: EventEmitter<TapEventDetails>,\n private doubleTapEmitter: EventEmitter<TapEventDetails>,\n private longPressEmitter: EventEmitter<TapEventDetails>,\n private interactionStartedEmitter: EventEmitter<void>,\n private interactionFinishedEmitter: EventEmitter<void>\n ) {\n this.tap = this.tap.bind(this);\n this.doubleTap = this.doubleTap.bind(this);\n this.longPress = this.longPress.bind(this);\n this.emitTapEvent = this.emitTapEvent.bind(this);\n }\n\n /**\n * Displays a cursor over the viewer with the given priority. Cursors with\n * higher priority will take precedence over cursors with lower priorities if\n * there's more than a single cursor added.\n *\n * @param cursor The cursor to add.\n * @param priority The priority of the cursor.\n * @returns A `Disposable` that can be used to remove the cursor.\n */\n public addCursor(cursor: Cursor, priority?: number): Disposable {\n return this.cursors.add(cursor, priority);\n }\n\n /**\n * Returns a 3D point in world space for the given 2D point in viewport space.\n *\n * @param point A point in 2D viewport space to transform.\n * @returns A 3D point in world space.\n */\n public async getWorldPointFromViewport(\n point: Point.Point\n ): Promise<Vector3.Vector3 | undefined> {\n const viewport = this.getViewport();\n const frame = this.getFrame();\n\n if (frame == null) {\n throw new Error('Cannot get world point. Frame is undefined.');\n }\n\n const depthBuffer = await frame.depthBuffer();\n return depthBuffer != null\n ? viewport.transformPointToWorldSpace(point, depthBuffer, 0.5)\n : undefined;\n }\n\n /**\n * Returns the entity at the given point in viewport space.\n *\n * @param point A point in viewport space.\n * @returns The entity that was found.\n */\n public async getEntityTypeAtPoint(point: Point.Point): Promise<EntityType> {\n const viewport = this.getViewport();\n const featureMap = await this.getFrame()?.featureMap();\n\n if (featureMap != null) {\n const framePt = viewport.transformPointToFrame(point, featureMap);\n return featureMap.getEntityType(framePt);\n } else {\n return EntityType.NO_GEOMETRY;\n }\n }\n\n /**\n * Generates a ray from the given point, in viewport coordinates.\n *\n * @param point A point in viewport coordinates.\n * @returns A ray representing the direction of the point in world\n * coordinates.\n */\n public getRayFromPoint(point: Point.Point): Ray.Ray {\n const viewport = this.getViewport();\n const frame = this.getFrame();\n\n if (frame != null) {\n return viewport.transformPointToRay(\n point,\n frame.image,\n frame.scene.camera\n );\n } else throw new Error('Cannot get camera. Frame is undefined.');\n }\n\n /**\n * Emits a tap event with the provided position relative to the viewer\n * canvas, along with the set of modifier keys held (if applicable).\n *\n * @param position An {x, y} coordinate marking the position of the tap.\n * @param keyDetails A set of pressed keyboard keys that you want to include\n * in the tap event.\n */\n public async tap(\n position: Point.Point,\n keyDetails: Partial<TapEventKeys> = {},\n buttons = 0\n ): Promise<void> {\n this.emitTapEvent(this.tapEmitter.emit, position, keyDetails, buttons);\n }\n\n public async doubleTap(\n position: Point.Point,\n keyDetails: Partial<TapEventKeys> = {},\n buttons = 0\n ): Promise<void> {\n this.emitTapEvent(\n this.doubleTapEmitter.emit,\n position,\n keyDetails,\n buttons\n );\n }\n\n public async longPress(\n position: Point.Point,\n keyDetails: Partial<TapEventKeys> = {},\n buttons = 0\n ): Promise<void> {\n this.emitTapEvent(\n this.longPressEmitter.emit,\n position,\n keyDetails,\n buttons\n );\n }\n\n /**\n * Marks the start of an interaction. This method must be called before\n * performing any additional interaction operations. Use `endInteraction()` to\n * mark the end of an interaction.\n */\n public async beginInteraction(): Promise<void> {\n if (!this.isInteracting()) {\n this.interactionStartedEmitter.emit();\n this.sceneLoadingPromise = this.getScene();\n this.currentCamera = (await this.sceneLoadingPromise).camera();\n this.sceneLoadingPromise = undefined;\n await this.stream.beginInteraction();\n }\n }\n\n /**\n * Invokes a function to transform the scene's camera and request a new image\n * for the updated scene.\n *\n * @param t A function to transform the camera. Function will be passed the\n * camera and scene viewport and is expected to return an updated camera.\n */\n public async transformCamera(t: CameraTransform<T>): Promise<void>;\n public async transformCamera(\n t: CameraTransform<T>,\n renderOptions?: CameraRenderOptions\n ): Promise<void>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public async transformCamera(...args: any[]): Promise<void> {\n const t = args[0];\n const renderOptions = args[1];\n\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,\n viewport,\n scale: scene.scale(),\n boundingBox: scene.boundingBox(),\n frame,\n depthBuffer,\n })\n : undefined;\n\n await this.currentCamera?.render(renderOptions);\n }\n }\n\n /**\n * Performs a twist 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 or the angle to twist the camera by around the view vector.\n */\n public async twistCamera(delta: number): Promise<void>;\n public async twistCamera(delta: Point.Point): Promise<void>;\n public async twistCamera(...args: any[]): Promise<void> {\n return this.transformCamera(({ camera, viewport }) => {\n const axis = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n\n if (args.length === 1 && typeof args[0] === 'number') {\n const angleInRadians = Angle.toRadians(-args[0]);\n return camera.rotateAroundAxis(angleInRadians, axis);\n } else if (args.length === 1) {\n const center = Point.create(viewport.width / 2, viewport.height / 2);\n const currentAngle = Angle.toDegrees(Angle.fromPoints(center, args[0]));\n const angleDelta =\n this.lastAngle != null ? currentAngle - this.lastAngle : 0;\n\n this.lastAngle = currentAngle;\n const axis = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n const angleInRadians = Angle.toRadians(-angleDelta);\n return camera.rotateAroundAxis(angleInRadians, axis);\n }\n return camera;\n });\n }\n\n /**\n * Moves the camera's position and look at to the given screen coordinate.\n *\n * If the screen coordinate intersects with an object, the camera will track\n * the hit point so the mouse position is always under the mouse.\n *\n * If the screen coordinate doesn't intersect with an object, then ???.\n *\n * @param screenPt A point in screen coordinates.\n */\n public async panCameraToScreenPoint(screenPt: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, frame, viewport, depthBuffer }) => {\n // Capture the starting state of the pan.\n if (this.panData == null) {\n const startingCamera = camera.toFrameCamera();\n const direction = startingCamera.direction;\n\n const ray = viewport.transformPointToRay(\n screenPt,\n frame.image,\n startingCamera\n );\n const fallbackPlane = Plane.fromNormalAndCoplanarPoint(\n direction,\n camera.lookAt\n );\n const fallback = Ray.intersectPlane(ray, fallbackPlane);\n if (fallback == null) {\n console.warn(\n 'Cannot determine fallback for pan. Ray does not intersect plane.'\n );\n return camera;\n }\n\n // Create a plane for the hit point that will be used to determine the\n // delta of future mouse movements to the original hit point. Fallback\n // to a plane placed at the look at point, in case there's no hit.\n const hitPt =\n depthBuffer != null\n ? this.getWorldPoint(screenPt, depthBuffer, fallback)\n : fallback;\n const hitPlane = Plane.fromNormalAndCoplanarPoint(direction, hitPt);\n\n this.panData = { hitPt, hitPlane, startingCamera };\n }\n\n if (this.panData != null) {\n const { hitPt, hitPlane, startingCamera } = this.panData;\n\n // Use a ray that originates at the screen and intersects with the hit\n // plane to determine the move distance.\n const ray = viewport.transformPointToRay(\n screenPt,\n frame.image,\n startingCamera\n );\n const movePt = Ray.intersectPlane(ray, hitPlane);\n\n if (movePt != null) {\n const delta = Vector3.subtract(hitPt, movePt);\n return camera.update(startingCamera).moveBy(delta);\n }\n }\n return camera;\n });\n }\n\n /**\n * Performs a view all operation for the scene's bounding box, and requests a\n * new image for the updated scene.\n */\n public async viewAll(): Promise<void> {\n await (await this.getScene()).camera().viewAll().render();\n }\n\n /**\n * Performs a rotate operation of the scene around the camera's look at point,\n * and requests a new image 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 rotateCamera(delta: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, viewport, boundingBox }) => {\n const upVector = Vector3.normalize(camera.up);\n const directionVector = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n const crossX = Vector3.cross(upVector, directionVector);\n const crossY = Vector3.cross(directionVector, crossX);\n\n const mouseToWorld = Vector3.normalize({\n x: delta.x * crossX.x + delta.y * crossY.x,\n y: delta.x * crossX.y + delta.y * crossY.y,\n z: delta.x * crossX.z + delta.y * crossY.z,\n });\n\n const rotationAxis = Vector3.cross(mouseToWorld, directionVector);\n\n // The 9.5 multiplier was chosen to match the desired rotation speed\n const epsilonX = (9.5 * delta.x) / viewport.width;\n const epsilonY = (9.5 * delta.y) / viewport.height;\n const angle = Math.abs(epsilonX) + Math.abs(epsilonY);\n\n return camera.rotateAroundAxis(angle, rotationAxis);\n });\n }\n\n public async rotateCameraAtPoint(\n delta: Point.Point,\n point: Point.Point\n ): Promise<void> {\n return this.transformCamera(\n ({ camera, viewport, boundingBox, depthBuffer }) => {\n if (this.worldRotationPoint == null) {\n const worldCenter = BoundingBox.center(boundingBox);\n this.worldRotationPoint =\n depthBuffer != null\n ? this.getWorldPoint(point, depthBuffer, worldCenter)\n : camera.lookAt;\n }\n\n const upVector = Vector3.normalize(camera.up);\n const vv = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n\n const crossX = Vector3.cross(upVector, vv);\n const crossY = Vector3.cross(vv, crossX);\n\n const mouseToWorld = Vector3.normalize({\n x: delta.x * crossX.x + delta.y * crossY.x,\n y: delta.x * crossX.y + delta.y * crossY.y,\n z: delta.x * crossX.z + delta.y * crossY.z,\n });\n\n const rotationAxis = Vector3.cross(mouseToWorld, vv);\n\n // The 9.5 multiplier was chosen to match the desired rotation speed\n const epsilonX = (9.5 * delta.x) / viewport.width;\n const epsilonY = (9.5 * delta.y) / viewport.height;\n const angle = Math.abs(epsilonX) + Math.abs(epsilonY);\n\n const updated = camera.rotateAroundAxisAtPoint(\n angle,\n this.worldRotationPoint,\n rotationAxis\n );\n\n return updated.update({\n // Scale the lookAt point to the same length as the distance to the\n // center of the bounding box to maintain zoom and pan behavior.\n lookAt: Vector3.add(\n Vector3.scale(\n Math.abs(camera.signedDistanceToBoundingBoxCenter()) /\n Vector3.magnitude(updated.viewVector),\n updated.viewVector\n ),\n updated.position\n ),\n });\n }\n );\n }\n\n /**\n * Performs a zoom operation of the scene's camera, and requests a new image\n * for the updated scene.\n *\n * @param delta The distance to zoom. Positive values zoom in and negative\n * values zoom out.\n */\n public async zoomCamera(delta: number): Promise<void> {\n return this.transformCamera(({ camera, viewport }) => {\n const vv = camera.viewVector;\n const v = Vector3.normalize(vv);\n\n const distance = Vector3.magnitude(vv);\n const epsilon = (3 * distance * delta) / viewport.height;\n\n const position = Vector3.add(camera.position, Vector3.scale(epsilon, v));\n const newCamera = camera.update({ position });\n return newCamera;\n });\n }\n\n /**\n * Performs a pivot operation of the scene's camera, updating the lookAt\n * while maintaining the position, and requests a new image for the\n * updated scene.\n *\n * @param degreesLocalX The angle to rotate the lookAt point around the local x-axis\n * @param degreesLocalY The angle to rotate the lookAt point around the local y-axis\n */\n public async pivotCamera(\n degreesLocalX: number,\n degreesLocalY: number\n ): Promise<void> {\n return this.transformCamera(({ camera }) => {\n const { position, up, lookAt } = camera;\n const normalizedUp = Vector3.normalize(up);\n const normalizedViewVector = Vector3.normalize(camera.viewVector);\n const xVector = Vector3.cross(normalizedUp, normalizedViewVector);\n const yVector = Vector3.cross(normalizedViewVector, xVector);\n\n const updatedLookAtX = Vector3.rotateAboutAxis(\n Angle.toRadians(degreesLocalX),\n lookAt,\n xVector,\n position\n );\n const updatedLookAtY = Vector3.rotateAboutAxis(\n Angle.toRadians(degreesLocalY),\n updatedLookAtX,\n yVector,\n position\n );\n\n return camera.update({ ...camera, lookAt: updatedLookAtY });\n });\n }\n\n /**\n * Marks the end of an interaction.\n */\n public async endInteraction(): Promise<void> {\n await this.sceneLoadingPromise;\n\n if (this.isInteracting()) {\n this.currentCamera = undefined;\n this.worldRotationPoint = undefined;\n this.panData = undefined;\n this.zoomData = undefined;\n this.resetLastAngle();\n\n this.interactionFinishedEmitter.emit();\n await this.stream.endInteraction();\n }\n }\n\n /**\n * resets the last recorded angle for a twist op\n */\n public resetLastAngle(): void {\n this.lastAngle = undefined;\n }\n\n /**\n * Indicates if the API is in an interacting state.\n */\n public isInteracting(): boolean {\n return this.currentCamera != null;\n }\n\n /**\n * Returns the pixel threshold that should be used to detect\n * movement based on the type of pointer input being coarse or fine.\n * This threshold is based on the configured `coarsePointerThreshold`\n * or the `finePointerThreshold` respectively.\n *\n * @param isTouch - Whether the event is a touch or not, if false or\n * undefined, a media query will be used to determine pointer type\n * @returns The pixel threshold.\n */\n public pixelThreshold(isTouch?: boolean): number {\n const pixelThreshold = this.isCoarseInputDevice(isTouch)\n ? this.getConfig().coarsePointerThreshold\n : this.getConfig().finePointerThreshold;\n\n return pixelThreshold * window.devicePixelRatio;\n }\n\n /**\n * Performs a hit test at the given point and returns a list of hit results\n * indicating any scene items that exist at the given point.\n *\n * @param pt A point, in viewport coordinates.\n * @returns A promise that resolves with the list of hit results.\n */\n public async hitItems(\n pt: Point.Point\n ): Promise<vertexvis.protobuf.stream.IHit[]> {\n const res = await (await this.getScene()).raycaster().hitItems(pt);\n return res?.hits ?? [];\n }\n\n private emitTapEvent(\n emit: (details: TapEventDetails) => void,\n position: Point.Point,\n keyDetails: Partial<TapEventKeys> = {},\n buttons = 0\n ): void {\n const {\n altKey = false,\n ctrlKey = false,\n metaKey = false,\n shiftKey = false,\n } = keyDetails;\n emit({\n position,\n altKey,\n ctrlKey,\n metaKey,\n shiftKey,\n buttons,\n });\n }\n\n private isCoarseInputDevice(isTouch?: boolean): boolean {\n return isTouch || window.matchMedia('(pointer: coarse)').matches;\n }\n\n protected getWorldPoint(\n point: Point.Point,\n depthBuffer: DepthBuffer,\n fallbackPoint: Vector3.Vector3\n ): Vector3.Vector3 {\n const viewport = this.getViewport();\n const framePt = viewport.transformPointToFrame(point, depthBuffer);\n const hasDepth = depthBuffer.hitTest(framePt);\n return hasDepth\n ? viewport.transformPointToWorldSpace(point, depthBuffer)\n : fallbackPoint;\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 abstract panCameraByDelta(delta: Point.Point): Promise<void>;\n\n public abstract zoomCameraToPoint(\n point: Point.Point,\n delta: number\n ): Promise<void>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactionApi.js","sourceRoot":"","sources":["../../../../../src/lib/interactions/interactionApi.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter } from '@stencil/core';\nimport { vertexvis } from '@vertexvis/frame-streaming-protos';\nimport {\n Angle,\n BoundingBox,\n Plane,\n Point,\n Ray,\n Vector3,\n} from '@vertexvis/geometry';\nimport { StreamApi } from '@vertexvis/stream-api';\nimport { Disposable } from '@vertexvis/utils';\n\nimport { ReceivedFrame } from '../..';\nimport { Cursor, CursorManager } from '../cursors';\nimport {\n Camera,\n CameraRenderOptions,\n OrthographicCamera,\n Scene,\n} from '../scenes';\nimport {\n DepthBuffer,\n EntityType,\n FrameCameraBase,\n Interactions,\n Viewport,\n} from '../types';\nimport { TapEventDetails, TapEventKeys } from './tapEventDetails';\n\nexport type SceneProvider = () => Promise<Scene>;\n\nexport type InteractionConfigProvider = () => Interactions.InteractionConfig;\n\nexport type CameraTransform<\n T extends Camera = Camera,\n R extends Camera = Camera\n> = (data: {\n camera: T;\n viewport: Viewport;\n scale: Point.Point;\n boundingBox: BoundingBox.BoundingBox;\n frame: ReceivedFrame;\n depthBuffer?: DepthBuffer;\n}) => R;\n\nexport interface PanData {\n hitPt: Vector3.Vector3;\n hitPlane: Plane.Plane;\n startingCamera: FrameCameraBase;\n}\n\nexport interface ZoomData {\n hitPt: Vector3.Vector3;\n hitPlane: Plane.Plane;\n}\n\n/**\n * The `InteractionApi` provides methods that API developers can use to modify\n * the internal state of an interaction.\n */\nexport abstract class InteractionApi<T extends Camera = Camera> {\n protected currentCamera?: Camera;\n private sceneLoadingPromise?: Promise<Scene>;\n private lastAngle: Angle.Angle | undefined;\n private worldRotationPoint?: Vector3.Vector3;\n\n protected panData?: PanData;\n protected zoomData?: ZoomData;\n\n public constructor(\n protected stream: StreamApi,\n private cursors: CursorManager,\n protected getConfig: InteractionConfigProvider,\n protected getScene: SceneProvider,\n protected getFrame: () => ReceivedFrame | undefined,\n public getViewport: () => Viewport,\n private tapEmitter: EventEmitter<TapEventDetails>,\n private doubleTapEmitter: EventEmitter<TapEventDetails>,\n private longPressEmitter: EventEmitter<TapEventDetails>,\n private interactionStartedEmitter: EventEmitter<void>,\n private interactionFinishedEmitter: EventEmitter<void>\n ) {\n this.tap = this.tap.bind(this);\n this.doubleTap = this.doubleTap.bind(this);\n this.longPress = this.longPress.bind(this);\n this.emitTapEvent = this.emitTapEvent.bind(this);\n }\n\n /**\n * Displays a cursor over the viewer with the given priority. Cursors with\n * higher priority will take precedence over cursors with lower priorities if\n * there's more than a single cursor added.\n *\n * @param cursor The cursor to add.\n * @param priority The priority of the cursor.\n * @returns A `Disposable` that can be used to remove the cursor.\n */\n public addCursor(cursor: Cursor, priority?: number): Disposable {\n return this.cursors.add(cursor, priority);\n }\n\n /**\n * Returns a 3D point in world space for the given 2D point in viewport space.\n *\n * @param point A point in 2D viewport space to transform.\n * @returns A 3D point in world space.\n */\n public async getWorldPointFromViewport(\n point: Point.Point\n ): Promise<Vector3.Vector3 | undefined> {\n const viewport = this.getViewport();\n const frame = this.getFrame();\n\n if (frame == null) {\n throw new Error('Cannot get world point. Frame is undefined.');\n }\n\n const depthBuffer = await frame.depthBuffer();\n return depthBuffer != null\n ? viewport.transformPointToWorldSpace(point, depthBuffer, 0.5)\n : undefined;\n }\n\n /**\n * Returns the entity at the given point in viewport space.\n *\n * @param point A point in viewport space.\n * @returns The entity that was found.\n */\n public async getEntityTypeAtPoint(point: Point.Point): Promise<EntityType> {\n const viewport = this.getViewport();\n const featureMap = await this.getFrame()?.featureMap();\n\n if (featureMap != null) {\n const framePt = viewport.transformPointToFrame(point, featureMap);\n return featureMap.getEntityType(framePt);\n } else {\n return EntityType.NO_GEOMETRY;\n }\n }\n\n /**\n * Generates a ray from the given point, in viewport coordinates.\n *\n * @param point A point in viewport coordinates.\n * @returns A ray representing the direction of the point in world\n * coordinates.\n */\n public getRayFromPoint(point: Point.Point): Ray.Ray {\n const viewport = this.getViewport();\n const frame = this.getFrame();\n\n if (frame != null) {\n return viewport.transformPointToRay(\n point,\n frame.image,\n frame.scene.camera\n );\n } else throw new Error('Cannot get camera. Frame is undefined.');\n }\n\n /**\n * Emits a tap event with the provided position relative to the viewer\n * canvas, along with the set of modifier keys held (if applicable).\n *\n * @param position An {x, y} coordinate marking the position of the tap.\n * @param keyDetails A set of pressed keyboard keys that you want to include\n * in the tap event.\n */\n public async tap(\n position: Point.Point,\n keyDetails: Partial<TapEventKeys> = {},\n buttons = 0\n ): Promise<void> {\n this.emitTapEvent(this.tapEmitter.emit, position, keyDetails, buttons);\n }\n\n public async doubleTap(\n position: Point.Point,\n keyDetails: Partial<TapEventKeys> = {},\n buttons = 0\n ): Promise<void> {\n this.emitTapEvent(\n this.doubleTapEmitter.emit,\n position,\n keyDetails,\n buttons\n );\n }\n\n public async longPress(\n position: Point.Point,\n keyDetails: Partial<TapEventKeys> = {},\n buttons = 0\n ): Promise<void> {\n this.emitTapEvent(\n this.longPressEmitter.emit,\n position,\n keyDetails,\n buttons\n );\n }\n\n /**\n * Marks the start of an interaction. This method must be called before\n * performing any additional interaction operations. Use `endInteraction()` to\n * mark the end of an interaction.\n */\n public async beginInteraction(): Promise<void> {\n if (!this.isInteracting()) {\n this.interactionStartedEmitter.emit();\n this.sceneLoadingPromise = this.getScene();\n this.currentCamera = (await this.sceneLoadingPromise).camera();\n this.sceneLoadingPromise = undefined;\n await this.stream.beginInteraction();\n }\n }\n\n /**\n * Invokes a function to transform the scene's camera and request a new image\n * for the updated scene.\n *\n * @param t A function to transform the camera. Function will be passed the\n * camera and scene viewport and is expected to return an updated camera.\n */\n public async transformCamera(t: CameraTransform<T>): Promise<void>;\n public async transformCamera(\n t: CameraTransform<T>,\n renderOptions?: CameraRenderOptions\n ): Promise<void>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public async transformCamera(...args: any[]): Promise<void> {\n const t = args[0];\n const renderOptions = args[1];\n\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,\n viewport,\n scale: scene.scale(),\n boundingBox: scene.boundingBox(),\n frame,\n depthBuffer,\n })\n : undefined;\n\n await this.currentCamera?.render(renderOptions);\n }\n }\n\n /**\n * Performs a twist 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 or the angle to twist the camera by around the view vector.\n */\n public async twistCamera(delta: number): Promise<void>;\n public async twistCamera(delta: Point.Point): Promise<void>;\n public async twistCamera(...args: any[]): Promise<void> {\n return this.transformCamera(({ camera, viewport }) => {\n const axis = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n\n if (args.length === 1 && typeof args[0] === 'number') {\n const angleInRadians = Angle.toRadians(-args[0]);\n return camera.rotateAroundAxis(angleInRadians, axis);\n } else if (args.length === 1) {\n const center = Point.create(viewport.width / 2, viewport.height / 2);\n const currentAngle = Angle.toDegrees(Angle.fromPoints(center, args[0]));\n const angleDelta =\n this.lastAngle != null ? currentAngle - this.lastAngle : 0;\n\n this.lastAngle = currentAngle;\n const axis = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n const angleInRadians = Angle.toRadians(-angleDelta);\n return camera.rotateAroundAxis(angleInRadians, axis);\n }\n return camera;\n });\n }\n\n /**\n * Moves the camera's position and look at to the given screen coordinate.\n *\n * If the screen coordinate intersects with an object, the camera will track\n * the hit point so the mouse position is always under the mouse.\n *\n * If the screen coordinate doesn't intersect with an object, then ???.\n *\n * @param screenPt A point in screen coordinates.\n */\n public async panCameraToScreenPoint(screenPt: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, frame, viewport, depthBuffer }) => {\n // Capture the starting state of the pan.\n if (this.panData == null) {\n const startingCamera = camera.toFrameCamera();\n const direction = startingCamera.direction;\n\n const ray = viewport.transformPointToRay(\n screenPt,\n frame.image,\n startingCamera\n );\n const fallbackPlane = Plane.fromNormalAndCoplanarPoint(\n direction,\n camera.lookAt\n );\n const fallback = Ray.intersectPlane(ray, fallbackPlane);\n if (fallback == null) {\n console.warn(\n 'Cannot determine fallback for pan. Ray does not intersect plane.'\n );\n return camera;\n }\n\n // Create a plane for the hit point that will be used to determine the\n // delta of future mouse movements to the original hit point. Fallback\n // to a plane placed at the look at point, in case there's no hit.\n const hitPt =\n depthBuffer != null\n ? this.getWorldPoint(screenPt, depthBuffer, fallback)\n : fallback;\n const hitPlane = Plane.fromNormalAndCoplanarPoint(direction, hitPt);\n\n this.panData = { hitPt, hitPlane, startingCamera };\n }\n\n if (this.panData != null) {\n const { hitPt, hitPlane, startingCamera } = this.panData;\n\n // Use a ray that originates at the screen and intersects with the hit\n // plane to determine the move distance.\n const ray = viewport.transformPointToRay(\n screenPt,\n frame.image,\n startingCamera\n );\n const movePt = Ray.intersectPlane(ray, hitPlane);\n\n if (movePt != null) {\n const delta = Vector3.subtract(hitPt, movePt);\n return camera.update(startingCamera).moveBy(delta);\n }\n }\n return camera;\n });\n }\n\n /**\n * Performs a view all operation for the scene's bounding box, and requests a\n * new image for the updated scene.\n */\n public async viewAll(): Promise<void> {\n await (await this.getScene()).camera().viewAll().render();\n }\n\n /**\n * Performs a rotate operation of the scene around the camera's look at point,\n * and requests a new image 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 rotateCamera(delta: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, viewport, boundingBox }) => {\n const upVector = Vector3.normalize(camera.up);\n const directionVector = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n const crossX = Vector3.cross(upVector, directionVector);\n const crossY = Vector3.cross(directionVector, crossX);\n\n const mouseToWorld = Vector3.normalize({\n x: delta.x * crossX.x + delta.y * crossY.x,\n y: delta.x * crossX.y + delta.y * crossY.y,\n z: delta.x * crossX.z + delta.y * crossY.z,\n });\n\n const rotationAxis = Vector3.cross(mouseToWorld, directionVector);\n\n // The 9.5 multiplier was chosen to match the desired rotation speed\n const epsilonX = (9.5 * delta.x) / viewport.width;\n const epsilonY = (9.5 * delta.y) / viewport.height;\n const angle = Math.abs(epsilonX) + Math.abs(epsilonY);\n\n return camera.rotateAroundAxis(angle, rotationAxis);\n });\n }\n\n public async rotateCameraAtPoint(\n delta: Point.Point,\n point: Point.Point\n ): Promise<void> {\n return this.transformCamera(\n ({ camera, viewport, boundingBox, depthBuffer }) => {\n if (this.worldRotationPoint == null) {\n const worldCenter = BoundingBox.center(boundingBox);\n this.worldRotationPoint =\n depthBuffer != null\n ? this.getWorldPoint(point, depthBuffer, worldCenter)\n : camera.lookAt;\n }\n\n const upVector = Vector3.normalize(camera.up);\n const vv = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n\n const crossX = Vector3.cross(upVector, vv);\n const crossY = Vector3.cross(vv, crossX);\n\n const mouseToWorld = Vector3.normalize({\n x: delta.x * crossX.x + delta.y * crossY.x,\n y: delta.x * crossX.y + delta.y * crossY.y,\n z: delta.x * crossX.z + delta.y * crossY.z,\n });\n\n const rotationAxis = Vector3.cross(mouseToWorld, vv);\n\n // The 9.5 multiplier was chosen to match the desired rotation speed\n const epsilonX = (9.5 * delta.x) / viewport.width;\n const epsilonY = (9.5 * delta.y) / viewport.height;\n const angle = Math.abs(epsilonX) + Math.abs(epsilonY);\n\n const updated = camera.rotateAroundAxisAtPoint(\n angle,\n this.worldRotationPoint,\n rotationAxis\n );\n\n return updated.update({\n // Scale the lookAt point to the same length as the distance to the\n // center of the bounding box to maintain zoom and pan behavior.\n lookAt: Vector3.add(\n Vector3.scale(\n Math.abs(camera.signedDistanceToBoundingBoxCenter()) /\n Vector3.magnitude(updated.viewVector),\n updated.viewVector\n ),\n updated.position\n ),\n });\n }\n );\n }\n\n /**\n * Performs a zoom operation of the scene's camera, and requests a new image\n * for the updated scene.\n *\n * @param delta The distance to zoom. Positive values zoom in and negative\n * values zoom out.\n */\n public async zoomCamera(delta: number): Promise<void> {\n return this.transformCamera(({ camera, viewport, frame, boundingBox }) => {\n if (viewport != null && frame != null) {\n const isPerspective = camera?.toFrameCamera().isPerspective();\n\n if (isPerspective) {\n const vv = camera.viewVector;\n\n // Calculate the unit-less scalar determining the amount to zoom. The delta parameter\n // is scaled by the viewport height because if the viewport is larger, then the\n // user should have to perform a bigger action to zoom the model the same amount.\n // Note that delta and viewport.height both have units of pixels. Further, the\n // 3 multiplier was chosen to match the desired zoom speed.\n const distance = Vector3.magnitude(vv);\n const relativeDeltaToViewportHeight =\n 3 * distance * (delta / viewport.height);\n\n // Scale the current viewVector by the scalar calculated above to determine how to adjust the camera position\n const v = Vector3.normalize(vv);\n const positionChange = Vector3.scale(\n relativeDeltaToViewportHeight,\n v\n );\n\n // Calculate the new camera position\n const position = Vector3.add(camera.position, positionChange);\n\n // Update the camera with the new position\n const newCamera = camera.update({ position });\n return newCamera;\n } else {\n // Retrieve properties of the current camera\n const orthographicCamera = camera as unknown as OrthographicCamera;\n const frameCam = camera.toFrameCamera();\n const dir = frameCam.direction;\n const ray = viewport.transformPointToRay(\n viewport.center,\n frame.image,\n frameCam\n );\n\n // Calculate the unit-less scalar determining the amount to zoom. The delta parameter\n // is scaled by the viewport height because if the viewport is larger, then the\n // user should have to perform a bigger action to zoom the model the same amount.\n // Note that delta and viewport.height both have units of pixels. Further, the\n // 4 multiplier was chosen to match the desired zoom speed.\n const relativeDeltaToViewportHeight = 4 * (delta / viewport.height);\n\n // Calculate the fovHeight after performing the zoom. zoomedFovHeight has the\n // same units of camera.fovHeight (the world units). The new fovHeight\n // has a minimum value, which is a function of the size of the bounding box,\n // which ensures the new fovHeight is a positive, non-zero number.\n const minimumFovHeight =\n Vector3.magnitude(BoundingBox.diagonal(boundingBox)) * 1e-5;\n const zoomedFovHeight = Math.max(\n minimumFovHeight,\n orthographicCamera.fovHeight * (1 - relativeDeltaToViewportHeight)\n );\n\n // Calculate the plane and point to zoom relative to\n const planeToZoomRelativeTo = Plane.fromNormalAndCoplanarPoint(\n dir,\n frameCam.lookAt\n );\n const pointToZoomRelativeTo = Ray.intersectPlane(\n ray,\n planeToZoomRelativeTo\n );\n\n if (pointToZoomRelativeTo != null) {\n // Project the current look at point onto the zoom plane\n const projectedLookAt = Plane.projectPoint(\n planeToZoomRelativeTo,\n orthographicCamera.lookAt\n );\n\n // Calculate the vector to determine how to adjust the camera's look at point.\n // Ensure that the viewVector is scaled to the expected length in order to\n // ensure other camera calculations are correct, for example, the occlusion\n // calculations for pins.\n const fovHeightRelativeChange =\n (orthographicCamera.fovHeight - zoomedFovHeight) /\n orthographicCamera.fovHeight;\n const lookAtChangeVector = Vector3.scale(\n fovHeightRelativeChange,\n Vector3.subtract(pointToZoomRelativeTo, projectedLookAt)\n );\n\n // Calculate the camera's new look at point\n const updatedLookAt = Vector3.add(\n orthographicCamera.lookAt,\n lookAtChangeVector\n );\n\n // Update the orthographic camera\n // Note rotationPoint should match lookAt after a zoom interaction\n const newCamera = camera.update({\n lookAt: updatedLookAt,\n rotationPoint: updatedLookAt,\n fovHeight: zoomedFovHeight,\n });\n return newCamera;\n }\n }\n }\n\n return camera;\n });\n }\n\n /**\n * Performs a pivot operation of the scene's camera, updating the lookAt\n * while maintaining the position, and requests a new image for the\n * updated scene.\n *\n * @param degreesLocalX The angle to rotate the lookAt point around the local x-axis\n * @param degreesLocalY The angle to rotate the lookAt point around the local y-axis\n */\n public async pivotCamera(\n degreesLocalX: number,\n degreesLocalY: number\n ): Promise<void> {\n return this.transformCamera(({ camera }) => {\n const { position, up, lookAt } = camera;\n const normalizedUp = Vector3.normalize(up);\n const normalizedViewVector = Vector3.normalize(camera.viewVector);\n const xVector = Vector3.cross(normalizedUp, normalizedViewVector);\n const yVector = Vector3.cross(normalizedViewVector, xVector);\n\n const updatedLookAtX = Vector3.rotateAboutAxis(\n Angle.toRadians(degreesLocalX),\n lookAt,\n xVector,\n position\n );\n const updatedLookAtY = Vector3.rotateAboutAxis(\n Angle.toRadians(degreesLocalY),\n updatedLookAtX,\n yVector,\n position\n );\n\n return camera.update({ ...camera, lookAt: updatedLookAtY });\n });\n }\n\n /**\n * Marks the end of an interaction.\n */\n public async endInteraction(): Promise<void> {\n await this.sceneLoadingPromise;\n\n if (this.isInteracting()) {\n this.currentCamera = undefined;\n this.worldRotationPoint = undefined;\n this.panData = undefined;\n this.zoomData = undefined;\n this.resetLastAngle();\n\n this.interactionFinishedEmitter.emit();\n await this.stream.endInteraction();\n }\n }\n\n /**\n * resets the last recorded angle for a twist op\n */\n public resetLastAngle(): void {\n this.lastAngle = undefined;\n }\n\n /**\n * Indicates if the API is in an interacting state.\n */\n public isInteracting(): boolean {\n return this.currentCamera != null;\n }\n\n /**\n * Returns the pixel threshold that should be used to detect\n * movement based on the type of pointer input being coarse or fine.\n * This threshold is based on the configured `coarsePointerThreshold`\n * or the `finePointerThreshold` respectively.\n *\n * @param isTouch - Whether the event is a touch or not, if false or\n * undefined, a media query will be used to determine pointer type\n * @returns The pixel threshold.\n */\n public pixelThreshold(isTouch?: boolean): number {\n const pixelThreshold = this.isCoarseInputDevice(isTouch)\n ? this.getConfig().coarsePointerThreshold\n : this.getConfig().finePointerThreshold;\n\n return pixelThreshold * window.devicePixelRatio;\n }\n\n /**\n * Performs a hit test at the given point and returns a list of hit results\n * indicating any scene items that exist at the given point.\n *\n * @param pt A point, in viewport coordinates.\n * @returns A promise that resolves with the list of hit results.\n */\n public async hitItems(\n pt: Point.Point\n ): Promise<vertexvis.protobuf.stream.IHit[]> {\n const res = await (await this.getScene()).raycaster().hitItems(pt);\n return res?.hits ?? [];\n }\n\n private emitTapEvent(\n emit: (details: TapEventDetails) => void,\n position: Point.Point,\n keyDetails: Partial<TapEventKeys> = {},\n buttons = 0\n ): void {\n const {\n altKey = false,\n ctrlKey = false,\n metaKey = false,\n shiftKey = false,\n } = keyDetails;\n emit({\n position,\n altKey,\n ctrlKey,\n metaKey,\n shiftKey,\n buttons,\n });\n }\n\n private isCoarseInputDevice(isTouch?: boolean): boolean {\n return isTouch || window.matchMedia('(pointer: coarse)').matches;\n }\n\n protected getWorldPoint(\n point: Point.Point,\n depthBuffer: DepthBuffer,\n fallbackPoint: Vector3.Vector3\n ): Vector3.Vector3 {\n const viewport = this.getViewport();\n const framePt = viewport.transformPointToFrame(point, depthBuffer);\n const hasDepth = depthBuffer.hitTest(framePt);\n return hasDepth\n ? viewport.transformPointToWorldSpace(point, depthBuffer)\n : fallbackPoint;\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 abstract panCameraByDelta(delta: Point.Point): Promise<void>;\n\n public abstract zoomCameraToPoint(\n point: Point.Point,\n delta: number\n ): Promise<void>;\n}\n"]}
|
|
@@ -116,17 +116,33 @@ export class InteractionApiOrthographic extends InteractionApi {
|
|
|
116
116
|
}
|
|
117
117
|
if (this.orthographicZoomData != null) {
|
|
118
118
|
const { hitPt, hitPlane } = this.orthographicZoomData;
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
// Calculate the unit-less scalar determining the amount to zoom. The delta parameter
|
|
120
|
+
// is scaled by the viewport height because if the viewport is larger, then the
|
|
121
|
+
// user should have to perform a bigger action to zoom the model the same amount.
|
|
122
|
+
// Note that delta and viewport.height both have units of pixels. Further, the
|
|
123
|
+
// 4 multiplier was chosen to match the desired zoom speed.
|
|
124
|
+
const relativeDeltaToViewportHeight = 4 * (delta / viewport.height);
|
|
125
|
+
// Calculate the fovHeight after performing the zoom. zoomedFovHeight has the
|
|
126
|
+
// same units of camera.fovHeight (the world units). The new fovHeight
|
|
127
|
+
// has a minimum value, which is a function of the size of the bounding box,
|
|
128
|
+
// which ensures the new fovHeight is a positive, non-zero number.
|
|
129
|
+
const minimumFovHeight = Vector3.magnitude(BoundingBox.diagonal(boundingBox)) * 1e-5;
|
|
130
|
+
const zoomedFovHeight = Math.max(minimumFovHeight, camera.fovHeight * (1 - relativeDeltaToViewportHeight));
|
|
131
|
+
// Calculate the vector to determine how to adjust the camera's look at point.
|
|
132
|
+
// Ensure that the viewVector is scaled to the expected length in order to
|
|
133
|
+
// ensure other camera calculations are correct, for example, the occlusion
|
|
134
|
+
// calculations for pins.
|
|
122
135
|
const projectedLookAt = Plane.projectPoint(hitPlane, camera.lookAt);
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
136
|
+
const fovHeightRelativeChange = (camera.fovHeight - zoomedFovHeight) / camera.fovHeight;
|
|
137
|
+
const lookAtChangeVector = Vector3.scale(fovHeightRelativeChange, Vector3.subtract(hitPt, projectedLookAt));
|
|
138
|
+
// Calculate the camera's new look at point
|
|
139
|
+
const updatedLookAt = Vector3.add(camera.lookAt, lookAtChangeVector);
|
|
140
|
+
// Return the updated camera
|
|
141
|
+
// Note rotationPoint should match lookAt after a zoom interaction
|
|
126
142
|
return camera.update({
|
|
127
143
|
lookAt: updatedLookAt,
|
|
128
144
|
rotationPoint: updatedLookAt,
|
|
129
|
-
fovHeight:
|
|
145
|
+
fovHeight: zoomedFovHeight,
|
|
130
146
|
});
|
|
131
147
|
}
|
|
132
148
|
return camera;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactionApiOrthographic.js","sourceRoot":"","sources":["../../../../../src/lib/interactions/interactionApiOrthographic.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 { updateLookAtRelativeToBoundingBoxCenter } from '../rendering/vectors';\nimport { OrthographicCamera } from '../scenes';\nimport { DepthBuffer, Viewport } from '../types';\nimport { ZoomData } from './interactionApi';\nimport {\n InteractionApi,\n InteractionConfigProvider,\n SceneProvider,\n} from './interactionApi';\nimport { TapEventDetails } from './tapEventDetails';\n\ninterface OrthographicZoomData extends ZoomData {\n startingScreenPt: Point.Point;\n}\n\nexport class InteractionApiOrthographic extends InteractionApi<OrthographicCamera> {\n private orthographicZoomData?: OrthographicZoomData;\n\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 * Returns a 3D point in world space for the given 2D point in viewport space.\n *\n * @param point A point in 2D viewport space to transform.\n * @returns A 3D point in world space.\n */\n public async getWorldPointFromViewport(\n point: Point.Point\n ): Promise<Vector3.Vector3 | undefined> {\n const viewport = this.getViewport();\n const frame = this.getFrame();\n\n if (frame == null) {\n throw new Error('Cannot get world point. Frame is undefined.');\n }\n\n const depthBuffer = await frame.depthBuffer();\n return depthBuffer != null\n ? viewport.transformPointToWorldSpace(point, depthBuffer, 0.5)\n : undefined;\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 viewVector = camera.viewVector;\n const normalizedUpVector = Vector3.normalize(camera.up);\n const normalizedViewVector = Vector3.normalize(viewVector);\n\n const throttledDelta = Point.scale(delta, 0.5, 0.5);\n const d = Vector3.magnitude(viewVector);\n const epsilonX = (throttledDelta.x * d) / viewport.width;\n const epsilonY = (throttledDelta.y * d) / viewport.height;\n\n const xvec = Vector3.cross(normalizedUpVector, normalizedViewVector);\n const yvec = Vector3.cross(normalizedViewVector, xvec);\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 /**\n * Moves the camera's position and look at to the given screen coordinate.\n *\n * If the screen coordinate intersects with an object, the camera will track\n * the hit point so the mouse position is always under the mouse.\n *\n * If the screen coordinate doesn't intersect with an object, then ???.\n *\n * @param screenPt A point in screen coordinates.\n */\n public async panCameraToScreenPoint(screenPt: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, frame, viewport, boundingBox }) => {\n // Capture the starting state of the pan.\n if (this.panData == null) {\n const startingCamera = camera.toFrameCamera();\n const direction = startingCamera.direction;\n\n const ray = viewport.transformPointToRay(\n screenPt,\n frame.image,\n startingCamera\n );\n const hitPlane = Plane.fromNormalAndCoplanarPoint(\n direction,\n camera.lookAt\n );\n const hitPt = Ray.intersectPlane(ray, hitPlane);\n if (hitPt == null) {\n console.warn(\n 'Cannot determine fallback for pan. Ray does not intersect plane.'\n );\n return camera;\n }\n\n this.panData = { hitPt, hitPlane, startingCamera };\n }\n\n if (this.panData != null) {\n const { hitPt, hitPlane, startingCamera } = this.panData;\n\n // Use a ray that originates at the screen and intersects with the hit\n // plane to determine the move distance.\n const ray = viewport.transformPointToRay(\n screenPt,\n frame.image,\n startingCamera\n );\n const movePt = Ray.intersectPlane(ray, hitPlane);\n\n if (movePt != null) {\n const delta = Vector3.subtract(hitPt, movePt);\n\n // rotationPoint should match lookAt after a pan interaction\n const updatedLookAt = Vector3.add(startingCamera.lookAt, delta);\n return camera.update({\n lookAt: updatedLookAt,\n rotationPoint: updatedLookAt,\n });\n }\n }\n return camera;\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 if (\n this.orthographicZoomData == null ||\n Point.distance(point, this.orthographicZoomData.startingScreenPt) > 2\n ) {\n const frameCam = camera.toFrameCamera();\n const dir = frameCam.direction;\n const ray = viewport.transformPointToRay(\n point,\n frame.image,\n frameCam\n );\n\n const fallbackPlane = Plane.fromNormalAndCoplanarPoint(\n dir,\n frameCam.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.orthographicZoomData = {\n hitPt,\n hitPlane,\n startingScreenPt: point,\n };\n }\n\n if (this.orthographicZoomData != null) {\n const { hitPt, hitPlane } = this.orthographicZoomData;\n\n // The 4 multiplier was chosen to match the desired zoom speed\n const relativeDelta =\n 4 * (camera.fovHeight / viewport.height) * delta;\n const fovHeight = Math.max(1, camera.fovHeight - relativeDelta);\n const projectedLookAt = Plane.projectPoint(hitPlane, camera.lookAt);\n const diff = Vector3.scale(\n (camera.fovHeight - fovHeight) / camera.fovHeight,\n Vector3.subtract(hitPt, projectedLookAt)\n );\n\n // rotationPoint should match lookAt after a zoom interaction\n const updatedLookAt = Vector3.add(camera.lookAt, diff);\n return camera.update({\n lookAt: updatedLookAt,\n rotationPoint: updatedLookAt,\n fovHeight: Math.max(1, camera.fovHeight - relativeDelta),\n });\n }\n return camera;\n }\n );\n }\n\n /**\n * Performs a rotate operation of the scene around the camera's look at point,\n * and requests a new image 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 rotateCamera(delta: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, viewport, boundingBox }) => {\n const upVector = Vector3.normalize(camera.up);\n const directionVector = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n\n const crossX = Vector3.cross(upVector, directionVector);\n const crossY = Vector3.cross(directionVector, crossX);\n\n const mouseToWorld = Vector3.normalize({\n x: delta.x * crossX.x + delta.y * crossY.x,\n y: delta.x * crossX.y + delta.y * crossY.y,\n z: delta.x * crossX.z + delta.y * crossY.z,\n });\n\n const rotationAxisDirection = Vector3.cross(\n mouseToWorld,\n directionVector\n );\n\n // The 9.5 multiplier was chosen to match the desired rotation speed\n const epsilonX = (9.5 * delta.x) / viewport.width;\n const epsilonY = (9.5 * delta.y) / viewport.height;\n const angle = Math.abs(epsilonX) + Math.abs(epsilonY);\n\n const rotationPoint =\n camera.rotationPoint != null && camera.rotationPoint?.x != null\n ? camera.rotationPoint\n : camera.lookAt;\n const updated = camera.rotateAroundAxisAtPoint(\n angle,\n rotationPoint,\n rotationAxisDirection\n );\n\n // Update the lookAt point to take the center of the model into account\n // This change helps ensure that the lookAt point is consistent between\n // the SDK and back-end system such that the calculated depth buffer is correct.\n const newLookAt = updateLookAtRelativeToBoundingBoxCenter(\n updated.lookAt,\n updated.viewVector,\n BoundingBox.center(boundingBox)\n );\n\n // Update only the lookAt point. The rotationPoint should remain\n // constant until a different type of interaction is performed.\n return updated.update({\n lookAt: newLookAt,\n });\n });\n }\n\n protected getWorldPoint(\n point: Point.Point,\n depthBuffer: DepthBuffer,\n fallbackPoint: Vector3.Vector3\n ): Vector3.Vector3 {\n const viewport = this.getViewport();\n const framePt = viewport.transformPointToFrame(point, depthBuffer);\n const hasDepth = depthBuffer.hitTest(framePt);\n return hasDepth\n ? viewport.transformPointToWorldSpace(point, depthBuffer)\n : fallbackPoint;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactionApiOrthographic.js","sourceRoot":"","sources":["../../../../../src/lib/interactions/interactionApiOrthographic.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAK9E,OAAO,EAAE,uCAAuC,EAAE,MAAM,sBAAsB,CAAC;AAI/E,OAAO,EACL,cAAc,GAGf,MAAM,kBAAkB,CAAC;AAO1B,MAAM,OAAO,0BAA2B,SAAQ,cAAkC;EAGhF,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;;;;;KAKG;EACI,KAAK,CAAC,yBAAyB,CACpC,KAAkB;IAElB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;IAE9B,IAAI,KAAK,IAAI,IAAI,EAAE;MACjB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;KAChE;IAED,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,WAAW,IAAI,IAAI;MACxB,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,CAAC;MAC9D,CAAC,CAAC,SAAS,CAAC;EAChB,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,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;MACrC,MAAM,kBAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;MACxD,MAAM,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;MAE3D,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;MACpD,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;MACxC,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;MACzD,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;MAE1D,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC;MACrE,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;MACvD,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;EAED;;;;;;;;;KASG;EACI,KAAK,CAAC,sBAAsB,CAAC,QAAqB;IACvD,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE;MACvE,yCAAyC;MACzC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE;QACxB,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QAC9C,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC;QAE3C,MAAM,GAAG,GAAG,QAAQ,CAAC,mBAAmB,CACtC,QAAQ,EACR,KAAK,CAAC,KAAK,EACX,cAAc,CACf,CAAC;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,0BAA0B,CAC/C,SAAS,EACT,MAAM,CAAC,MAAM,CACd,CAAC;QACF,MAAM,KAAK,GAAG,GAAG,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAChD,IAAI,KAAK,IAAI,IAAI,EAAE;UACjB,OAAO,CAAC,IAAI,CACV,kEAAkE,CACnE,CAAC;UACF,OAAO,MAAM,CAAC;SACf;QAED,IAAI,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;OACpD;MAED,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE;QACxB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAEzD,sEAAsE;QACtE,wCAAwC;QACxC,MAAM,GAAG,GAAG,QAAQ,CAAC,mBAAmB,CACtC,QAAQ,EACR,KAAK,CAAC,KAAK,EACX,cAAc,CACf,CAAC;QACF,MAAM,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAEjD,IAAI,MAAM,IAAI,IAAI,EAAE;UAClB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;UAE9C,4DAA4D;UAC5D,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;UAChE,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,MAAM,EAAE,aAAa;YACrB,aAAa,EAAE,aAAa;WAC7B,CAAC,CAAC;SACJ;OACF;MACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;EACL,CAAC;EAEM,KAAK,CAAC,iBAAiB,CAC5B,KAAkB,EAClB,KAAa;IAEb,OAAO,IAAI,CAAC,eAAe,CACzB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;MACxD,IACE,IAAI,CAAC,oBAAoB,IAAI,IAAI;QACjC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,GAAG,CAAC,EACrE;QACA,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,mBAAmB,CACtC,KAAK,EACL,KAAK,CAAC,KAAK,EACX,QAAQ,CACT,CAAC;QAEF,MAAM,aAAa,GAAG,KAAK,CAAC,0BAA0B,CACpD,GAAG,EACH,QAAQ,CAAC,MAAM,CAChB,CAAC;QACF,MAAM,UAAU,GAAG,GAAG,CAAC,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC1D,IAAI,UAAU,IAAI,IAAI,EAAE;UACtB,OAAO,CAAC,IAAI,CACV,yEAAyE,CAC1E,CAAC;UACF,OAAO,MAAM,CAAC;SACf;QAED,MAAM,KAAK,GACT,WAAW,IAAI,IAAI;UACjB,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,CAAC;UACpD,CAAC,CAAC,UAAU,CAAC;QACjB,MAAM,QAAQ,GAAG,KAAK,CAAC,0BAA0B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9D,IAAI,CAAC,oBAAoB,GAAG;UAC1B,KAAK;UACL,QAAQ;UACR,gBAAgB,EAAE,KAAK;SACxB,CAAC;OACH;MAED,IAAI,IAAI,CAAC,oBAAoB,IAAI,IAAI,EAAE;QACrC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAC;QAEtD,qFAAqF;QACrF,+EAA+E;QAC/E,iFAAiF;QACjF,8EAA8E;QAC9E,2DAA2D;QAC3D,MAAM,6BAA6B,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEpE,6EAA6E;QAC7E,sEAAsE;QACtE,4EAA4E;QAC5E,kEAAkE;QAClE,MAAM,gBAAgB,GACpB,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC;QAC9D,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAC9B,gBAAgB,EAChB,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,6BAA6B,CAAC,CACvD,CAAC;QAEF,8EAA8E;QAC9E,0EAA0E;QAC1E,2EAA2E;QAC3E,yBAAyB;QACzB,MAAM,eAAe,GAAG,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACpE,MAAM,uBAAuB,GAC3B,CAAC,MAAM,CAAC,SAAS,GAAG,eAAe,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC;QAC1D,MAAM,kBAAkB,GAAG,OAAO,CAAC,KAAK,CACtC,uBAAuB,EACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,CACzC,CAAC;QAEF,2CAA2C;QAC3C,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;QAErE,4BAA4B;QAC5B,kEAAkE;QAClE,OAAO,MAAM,CAAC,MAAM,CAAC;UACnB,MAAM,EAAE,aAAa;UACrB,aAAa,EAAE,aAAa;UAC5B,SAAS,EAAE,eAAe;SAC3B,CAAC,CAAC;OACJ;MACD,OAAO,MAAM,CAAC;IAChB,CAAC,CACF,CAAC;EACJ,CAAC;EAED;;;;;;KAMG;EACI,KAAK,CAAC,YAAY,CAAC,KAAkB;IAC1C,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE;;MAChE,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;MAC9C,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,CACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CACjD,CAAC;MAEF,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;MACxD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;MAEtD,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC;QACrC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QAC1C,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QAC1C,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;OAC3C,CAAC,CAAC;MAEH,MAAM,qBAAqB,GAAG,OAAO,CAAC,KAAK,CACzC,YAAY,EACZ,eAAe,CAChB,CAAC;MAEF,oEAAoE;MACpE,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;MAClD,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;MACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;MAEtD,MAAM,aAAa,GACjB,MAAM,CAAC,aAAa,IAAI,IAAI,IAAI,CAAA,MAAA,MAAM,CAAC,aAAa,0CAAE,CAAC,KAAI,IAAI;QAC7D,CAAC,CAAC,MAAM,CAAC,aAAa;QACtB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;MACpB,MAAM,OAAO,GAAG,MAAM,CAAC,uBAAuB,CAC5C,KAAK,EACL,aAAa,EACb,qBAAqB,CACtB,CAAC;MAEF,uEAAuE;MACvE,uEAAuE;MACvE,gFAAgF;MAChF,MAAM,SAAS,GAAG,uCAAuC,CACvD,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,UAAU,EAClB,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAChC,CAAC;MAEF,gEAAgE;MAChE,+DAA+D;MAC/D,OAAO,OAAO,CAAC,MAAM,CAAC;QACpB,MAAM,EAAE,SAAS;OAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;EACL,CAAC;EAES,aAAa,CACrB,KAAkB,EAClB,WAAwB,EACxB,aAA8B;IAE9B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,qBAAqB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,QAAQ;MACb,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC,KAAK,EAAE,WAAW,CAAC;MACzD,CAAC,CAAC,aAAa,CAAC;EACpB,CAAC;CACF","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 { updateLookAtRelativeToBoundingBoxCenter } from '../rendering/vectors';\nimport { OrthographicCamera } from '../scenes';\nimport { DepthBuffer, Viewport } from '../types';\nimport { ZoomData } from './interactionApi';\nimport {\n InteractionApi,\n InteractionConfigProvider,\n SceneProvider,\n} from './interactionApi';\nimport { TapEventDetails } from './tapEventDetails';\n\ninterface OrthographicZoomData extends ZoomData {\n startingScreenPt: Point.Point;\n}\n\nexport class InteractionApiOrthographic extends InteractionApi<OrthographicCamera> {\n private orthographicZoomData?: OrthographicZoomData;\n\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 * Returns a 3D point in world space for the given 2D point in viewport space.\n *\n * @param point A point in 2D viewport space to transform.\n * @returns A 3D point in world space.\n */\n public async getWorldPointFromViewport(\n point: Point.Point\n ): Promise<Vector3.Vector3 | undefined> {\n const viewport = this.getViewport();\n const frame = this.getFrame();\n\n if (frame == null) {\n throw new Error('Cannot get world point. Frame is undefined.');\n }\n\n const depthBuffer = await frame.depthBuffer();\n return depthBuffer != null\n ? viewport.transformPointToWorldSpace(point, depthBuffer, 0.5)\n : undefined;\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 viewVector = camera.viewVector;\n const normalizedUpVector = Vector3.normalize(camera.up);\n const normalizedViewVector = Vector3.normalize(viewVector);\n\n const throttledDelta = Point.scale(delta, 0.5, 0.5);\n const d = Vector3.magnitude(viewVector);\n const epsilonX = (throttledDelta.x * d) / viewport.width;\n const epsilonY = (throttledDelta.y * d) / viewport.height;\n\n const xvec = Vector3.cross(normalizedUpVector, normalizedViewVector);\n const yvec = Vector3.cross(normalizedViewVector, xvec);\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 /**\n * Moves the camera's position and look at to the given screen coordinate.\n *\n * If the screen coordinate intersects with an object, the camera will track\n * the hit point so the mouse position is always under the mouse.\n *\n * If the screen coordinate doesn't intersect with an object, then ???.\n *\n * @param screenPt A point in screen coordinates.\n */\n public async panCameraToScreenPoint(screenPt: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, frame, viewport, boundingBox }) => {\n // Capture the starting state of the pan.\n if (this.panData == null) {\n const startingCamera = camera.toFrameCamera();\n const direction = startingCamera.direction;\n\n const ray = viewport.transformPointToRay(\n screenPt,\n frame.image,\n startingCamera\n );\n const hitPlane = Plane.fromNormalAndCoplanarPoint(\n direction,\n camera.lookAt\n );\n const hitPt = Ray.intersectPlane(ray, hitPlane);\n if (hitPt == null) {\n console.warn(\n 'Cannot determine fallback for pan. Ray does not intersect plane.'\n );\n return camera;\n }\n\n this.panData = { hitPt, hitPlane, startingCamera };\n }\n\n if (this.panData != null) {\n const { hitPt, hitPlane, startingCamera } = this.panData;\n\n // Use a ray that originates at the screen and intersects with the hit\n // plane to determine the move distance.\n const ray = viewport.transformPointToRay(\n screenPt,\n frame.image,\n startingCamera\n );\n const movePt = Ray.intersectPlane(ray, hitPlane);\n\n if (movePt != null) {\n const delta = Vector3.subtract(hitPt, movePt);\n\n // rotationPoint should match lookAt after a pan interaction\n const updatedLookAt = Vector3.add(startingCamera.lookAt, delta);\n return camera.update({\n lookAt: updatedLookAt,\n rotationPoint: updatedLookAt,\n });\n }\n }\n return camera;\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 if (\n this.orthographicZoomData == null ||\n Point.distance(point, this.orthographicZoomData.startingScreenPt) > 2\n ) {\n const frameCam = camera.toFrameCamera();\n const dir = frameCam.direction;\n const ray = viewport.transformPointToRay(\n point,\n frame.image,\n frameCam\n );\n\n const fallbackPlane = Plane.fromNormalAndCoplanarPoint(\n dir,\n frameCam.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.orthographicZoomData = {\n hitPt,\n hitPlane,\n startingScreenPt: point,\n };\n }\n\n if (this.orthographicZoomData != null) {\n const { hitPt, hitPlane } = this.orthographicZoomData;\n\n // Calculate the unit-less scalar determining the amount to zoom. The delta parameter\n // is scaled by the viewport height because if the viewport is larger, then the\n // user should have to perform a bigger action to zoom the model the same amount.\n // Note that delta and viewport.height both have units of pixels. Further, the\n // 4 multiplier was chosen to match the desired zoom speed.\n const relativeDeltaToViewportHeight = 4 * (delta / viewport.height);\n\n // Calculate the fovHeight after performing the zoom. zoomedFovHeight has the\n // same units of camera.fovHeight (the world units). The new fovHeight\n // has a minimum value, which is a function of the size of the bounding box,\n // which ensures the new fovHeight is a positive, non-zero number.\n const minimumFovHeight =\n Vector3.magnitude(BoundingBox.diagonal(boundingBox)) * 1e-5;\n const zoomedFovHeight = Math.max(\n minimumFovHeight,\n camera.fovHeight * (1 - relativeDeltaToViewportHeight)\n );\n\n // Calculate the vector to determine how to adjust the camera's look at point.\n // Ensure that the viewVector is scaled to the expected length in order to\n // ensure other camera calculations are correct, for example, the occlusion\n // calculations for pins.\n const projectedLookAt = Plane.projectPoint(hitPlane, camera.lookAt);\n const fovHeightRelativeChange =\n (camera.fovHeight - zoomedFovHeight) / camera.fovHeight;\n const lookAtChangeVector = Vector3.scale(\n fovHeightRelativeChange,\n Vector3.subtract(hitPt, projectedLookAt)\n );\n\n // Calculate the camera's new look at point\n const updatedLookAt = Vector3.add(camera.lookAt, lookAtChangeVector);\n\n // Return the updated camera\n // Note rotationPoint should match lookAt after a zoom interaction\n return camera.update({\n lookAt: updatedLookAt,\n rotationPoint: updatedLookAt,\n fovHeight: zoomedFovHeight,\n });\n }\n return camera;\n }\n );\n }\n\n /**\n * Performs a rotate operation of the scene around the camera's look at point,\n * and requests a new image 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 rotateCamera(delta: Point.Point): Promise<void> {\n return this.transformCamera(({ camera, viewport, boundingBox }) => {\n const upVector = Vector3.normalize(camera.up);\n const directionVector = Vector3.normalize(\n Vector3.subtract(camera.lookAt, camera.position)\n );\n\n const crossX = Vector3.cross(upVector, directionVector);\n const crossY = Vector3.cross(directionVector, crossX);\n\n const mouseToWorld = Vector3.normalize({\n x: delta.x * crossX.x + delta.y * crossY.x,\n y: delta.x * crossX.y + delta.y * crossY.y,\n z: delta.x * crossX.z + delta.y * crossY.z,\n });\n\n const rotationAxisDirection = Vector3.cross(\n mouseToWorld,\n directionVector\n );\n\n // The 9.5 multiplier was chosen to match the desired rotation speed\n const epsilonX = (9.5 * delta.x) / viewport.width;\n const epsilonY = (9.5 * delta.y) / viewport.height;\n const angle = Math.abs(epsilonX) + Math.abs(epsilonY);\n\n const rotationPoint =\n camera.rotationPoint != null && camera.rotationPoint?.x != null\n ? camera.rotationPoint\n : camera.lookAt;\n const updated = camera.rotateAroundAxisAtPoint(\n angle,\n rotationPoint,\n rotationAxisDirection\n );\n\n // Update the lookAt point to take the center of the model into account\n // This change helps ensure that the lookAt point is consistent between\n // the SDK and back-end system such that the calculated depth buffer is correct.\n const newLookAt = updateLookAtRelativeToBoundingBoxCenter(\n updated.lookAt,\n updated.viewVector,\n BoundingBox.center(boundingBox)\n );\n\n // Update only the lookAt point. The rotationPoint should remain\n // constant until a different type of interaction is performed.\n return updated.update({\n lookAt: newLookAt,\n });\n });\n }\n\n protected getWorldPoint(\n point: Point.Point,\n depthBuffer: DepthBuffer,\n fallbackPoint: Vector3.Vector3\n ): Vector3.Vector3 {\n const viewport = this.getViewport();\n const framePt = viewport.transformPointToFrame(point, depthBuffer);\n const hasDepth = depthBuffer.hitTest(framePt);\n return hasDepth\n ? viewport.transformPointToWorldSpace(point, depthBuffer)\n : fallbackPoint;\n }\n}\n"]}
|
|
@@ -13,6 +13,22 @@ export const DEFAULT_PERSPECTIVE_MESH_SCALAR = 0.005;
|
|
|
13
13
|
// This attempts to keep the widget approximately the same
|
|
14
14
|
// size as zooming occurs.
|
|
15
15
|
export const DEFAULT_ORTHOGRAPHIC_MESH_SCALAR = 0.00625;
|
|
16
|
+
// Scalar that is used to increase the relative triangle size
|
|
17
|
+
// in viewers with a small area. This attempts to keep the widget
|
|
18
|
+
// approximately the same size for all viewing window sizes.
|
|
19
|
+
export const TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_NUMERATOR = 1580000;
|
|
20
|
+
// Scalar that is used to increase the relative triangle size
|
|
21
|
+
// in viewers with a small area. This attempts to keep the widget
|
|
22
|
+
// approximately the same size for all viewing window sizes.
|
|
23
|
+
export const TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_DENOMINATOR = 520000;
|
|
24
|
+
// Scalar that is used to increase the relative triangle size
|
|
25
|
+
// in viewers with a small height. This attempts to keep the widget
|
|
26
|
+
// approximately the same size for all viewing window sizes.
|
|
27
|
+
export const TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_NUMERATOR = 950;
|
|
28
|
+
// Scalar that is used to increase the relative triangle size
|
|
29
|
+
// in viewers with a small height. This attempts to keep the widget
|
|
30
|
+
// approximately the same size for all viewing window sizes.
|
|
31
|
+
export const TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_DENOMINATOR = 45;
|
|
16
32
|
export class ReglComponent {
|
|
17
33
|
constructor(canvasElement) {
|
|
18
34
|
this.canvasElement = canvasElement;
|
|
@@ -75,9 +91,21 @@ export class ReglComponent {
|
|
|
75
91
|
.reverse();
|
|
76
92
|
}
|
|
77
93
|
computeTriangleSize(position, frame) {
|
|
78
|
-
|
|
94
|
+
const baseTriangleSize = frame.scene.camera.isOrthographic()
|
|
79
95
|
? frame.scene.camera.fovHeight * DEFAULT_ORTHOGRAPHIC_MESH_SCALAR
|
|
80
96
|
: Vector3.magnitude(Vector3.subtract(position, frame.scene.camera.position)) * DEFAULT_PERSPECTIVE_MESH_SCALAR;
|
|
97
|
+
// Increase the triangle size for small viewers
|
|
98
|
+
const canvasArea = this.canvasElement.height * this.canvasElement.width;
|
|
99
|
+
const canvasAreaAdjustment = TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_NUMERATOR /
|
|
100
|
+
(canvasArea + TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_DENOMINATOR);
|
|
101
|
+
// Increase the triangle size for viewers with a small height and large width
|
|
102
|
+
const canvasHeightAdjustment = this.canvasElement.height < 650
|
|
103
|
+
? TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_NUMERATOR /
|
|
104
|
+
(this.canvasElement.height +
|
|
105
|
+
TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_DENOMINATOR)
|
|
106
|
+
: 1;
|
|
107
|
+
const sizeAdjustment = Math.max(canvasAreaAdjustment, canvasHeightAdjustment, 1);
|
|
108
|
+
return baseTriangleSize * sizeAdjustment;
|
|
81
109
|
}
|
|
82
110
|
}
|
|
83
111
|
//# sourceMappingURL=regl-component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"regl-component.js","sourceRoot":"","sources":["../../../../../src/lib/webgl/regl-component.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"regl-component.js","sourceRoot":"","sources":["../../../../../src/lib/webgl/regl-component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Vector3 } from '@vertexvis/geometry';\nimport { Disposable } from '@vertexvis/utils';\nimport regl from 'regl';\n\nimport { Drawable } from '../transforms/drawable';\nimport { Frame, Viewport } from '../types';\n\n// Scalar that is used in combination with a perspective camera's\n// components to determine the relative size of the meshes.\n// This attempts to keep the widget approximately the same\n// size as zooming occurs.\nexport const DEFAULT_PERSPECTIVE_MESH_SCALAR = 0.005;\n\n// Scalar that is used in combination with an orthographic camera's\n// components to determine the relative size of the meshes.\n// This attempts to keep the widget approximately the same\n// size as zooming occurs.\nexport const DEFAULT_ORTHOGRAPHIC_MESH_SCALAR = 0.00625;\n\n// Scalar that is used to increase the relative triangle size\n// in viewers with a small area. This attempts to keep the widget\n// approximately the same size for all viewing window sizes.\nexport const TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_NUMERATOR = 1580000;\n\n// Scalar that is used to increase the relative triangle size\n// in viewers with a small area. This attempts to keep the widget\n// approximately the same size for all viewing window sizes.\nexport const TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_DENOMINATOR = 520000;\n\n// Scalar that is used to increase the relative triangle size\n// in viewers with a small height. This attempts to keep the widget\n// approximately the same size for all viewing window sizes.\nexport const TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_NUMERATOR = 950;\n\n// Scalar that is used to increase the relative triangle size\n// in viewers with a small height. This attempts to keep the widget\n// approximately the same size for all viewing window sizes.\nexport const TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_DENOMINATOR = 45;\n\nexport abstract class ReglComponent implements Disposable {\n protected reglCommand?: regl.Regl;\n protected reglFrameDisposable?: regl.Cancellable;\n\n protected availableElements: Drawable[] = [];\n protected drawableElements: Drawable[] = [];\n\n protected frame?: Frame;\n protected viewport: Viewport;\n\n public constructor(protected canvasElement: HTMLCanvasElement) {\n this.viewport = new Viewport(canvasElement.width, canvasElement.height);\n }\n\n public dispose(): void {\n this.reglFrameDisposable?.cancel();\n }\n\n public updateFrame(frame: Frame, redraw = true): void {\n this.frame = frame;\n\n if (redraw) {\n this.updateAndDraw();\n }\n }\n\n public updateDimensions(canvasElement: HTMLCanvasElement): void {\n this.viewport = new Viewport(canvasElement.width, canvasElement.height);\n\n this.createOrUpdateElements();\n }\n\n public updateAndDraw(): void {\n if (this.frame != null && this.hasData()) {\n this.createOrUpdateElements();\n this.sortMeshes(this.frame, ...this.availableElements);\n this.draw();\n }\n }\n\n /**\n * @internal - visible for testing\n */\n public getDrawableElements(): Drawable[] {\n return this.drawableElements;\n }\n\n protected draw(): void {\n if (this.reglFrameDisposable == null) {\n this.reglFrameDisposable = this.reglCommand?.frame(() => {\n this.drawableElements.forEach((el) =>\n el?.draw({\n fill: el.fillColor,\n opacity: !!el.disabled ? 0.2 : 1,\n })\n );\n });\n }\n }\n\n protected clear(): void {\n this.reglCommand?.clear({\n color: [0, 0, 0, 0],\n });\n }\n\n protected sortMeshes(\n frame: Frame,\n ...drawableElements: Array<Drawable | undefined>\n ): void {\n const compare = (d1: Drawable, d2: Drawable): number =>\n d1.points.shortestDistanceFrom(frame.scene.camera.position) -\n d2.points.shortestDistanceFrom(frame.scene.camera.position);\n\n // Reverse sorted elements to draw the closest element last.\n // This causes it to appear above any other element.\n this.drawableElements = (\n drawableElements.filter((el) => el != null) as Drawable[]\n )\n .filter((el) => el.points.valid)\n .sort(compare)\n .reverse();\n }\n\n protected computeTriangleSize(\n position: Vector3.Vector3,\n frame: Frame\n ): number {\n const baseTriangleSize = frame.scene.camera.isOrthographic()\n ? frame.scene.camera.fovHeight * DEFAULT_ORTHOGRAPHIC_MESH_SCALAR\n : Vector3.magnitude(\n Vector3.subtract(position, frame.scene.camera.position)\n ) * DEFAULT_PERSPECTIVE_MESH_SCALAR;\n\n // Increase the triangle size for small viewers\n const canvasArea = this.canvasElement.height * this.canvasElement.width;\n const canvasAreaAdjustment =\n TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_NUMERATOR /\n (canvasArea + TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_DENOMINATOR);\n\n // Increase the triangle size for viewers with a small height and large width\n const canvasHeightAdjustment =\n this.canvasElement.height < 650\n ? TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_NUMERATOR /\n (this.canvasElement.height +\n TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_DENOMINATOR)\n : 1;\n\n const sizeAdjustment = Math.max(\n canvasAreaAdjustment,\n canvasHeightAdjustment,\n 1\n );\n\n return baseTriangleSize * sizeAdjustment;\n }\n\n protected abstract createOrUpdateElements(): void;\n\n protected abstract hasData(): boolean;\n}\n"]}
|
|
@@ -12509,6 +12509,22 @@ const DEFAULT_PERSPECTIVE_MESH_SCALAR = 0.005;
|
|
|
12509
12509
|
// This attempts to keep the widget approximately the same
|
|
12510
12510
|
// size as zooming occurs.
|
|
12511
12511
|
const DEFAULT_ORTHOGRAPHIC_MESH_SCALAR = 0.00625;
|
|
12512
|
+
// Scalar that is used to increase the relative triangle size
|
|
12513
|
+
// in viewers with a small area. This attempts to keep the widget
|
|
12514
|
+
// approximately the same size for all viewing window sizes.
|
|
12515
|
+
const TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_NUMERATOR = 1580000;
|
|
12516
|
+
// Scalar that is used to increase the relative triangle size
|
|
12517
|
+
// in viewers with a small area. This attempts to keep the widget
|
|
12518
|
+
// approximately the same size for all viewing window sizes.
|
|
12519
|
+
const TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_DENOMINATOR = 520000;
|
|
12520
|
+
// Scalar that is used to increase the relative triangle size
|
|
12521
|
+
// in viewers with a small height. This attempts to keep the widget
|
|
12522
|
+
// approximately the same size for all viewing window sizes.
|
|
12523
|
+
const TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_NUMERATOR = 950;
|
|
12524
|
+
// Scalar that is used to increase the relative triangle size
|
|
12525
|
+
// in viewers with a small height. This attempts to keep the widget
|
|
12526
|
+
// approximately the same size for all viewing window sizes.
|
|
12527
|
+
const TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_DENOMINATOR = 45;
|
|
12512
12528
|
class ReglComponent {
|
|
12513
12529
|
constructor(canvasElement) {
|
|
12514
12530
|
this.canvasElement = canvasElement;
|
|
@@ -12571,9 +12587,21 @@ class ReglComponent {
|
|
|
12571
12587
|
.reverse();
|
|
12572
12588
|
}
|
|
12573
12589
|
computeTriangleSize(position, frame) {
|
|
12574
|
-
|
|
12590
|
+
const baseTriangleSize = frame.scene.camera.isOrthographic()
|
|
12575
12591
|
? frame.scene.camera.fovHeight * DEFAULT_ORTHOGRAPHIC_MESH_SCALAR
|
|
12576
12592
|
: vector3.magnitude(vector3.subtract(position, frame.scene.camera.position)) * DEFAULT_PERSPECTIVE_MESH_SCALAR;
|
|
12593
|
+
// Increase the triangle size for small viewers
|
|
12594
|
+
const canvasArea = this.canvasElement.height * this.canvasElement.width;
|
|
12595
|
+
const canvasAreaAdjustment = TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_NUMERATOR /
|
|
12596
|
+
(canvasArea + TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_DENOMINATOR);
|
|
12597
|
+
// Increase the triangle size for viewers with a small height and large width
|
|
12598
|
+
const canvasHeightAdjustment = this.canvasElement.height < 650
|
|
12599
|
+
? TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_NUMERATOR /
|
|
12600
|
+
(this.canvasElement.height +
|
|
12601
|
+
TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_DENOMINATOR)
|
|
12602
|
+
: 1;
|
|
12603
|
+
const sizeAdjustment = Math.max(canvasAreaAdjustment, canvasHeightAdjustment, 1);
|
|
12604
|
+
return baseTriangleSize * sizeAdjustment;
|
|
12577
12605
|
}
|
|
12578
12606
|
}
|
|
12579
12607
|
|