UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

134 lines (113 loc) 5.18 kB
import { vec3, mat4 } from 'gl-matrix'; import { m as macro } from '../../macros2.js'; import vtkCompositeCameraManipulator from './CompositeCameraManipulator.js'; import vtkCompositeMouseManipulator from './CompositeMouseManipulator.js'; import { r as radiansFromDegrees, j as cross } from '../../Common/Core/Math/index.js'; // ---------------------------------------------------------------------------- // vtkMouseCameraAxisRotateManipulator methods // ---------------------------------------------------------------------------- function vtkMouseCameraAxisRotateManipulator(publicAPI, model) { // Set our className model.classHierarchy.push('vtkMouseCameraAxisRotateManipulator'); const negCameraDir = new Float64Array(3); const newCamPos = new Float64Array(3); const newFp = new Float64Array(3); const newViewUp = new Float64Array(3); const trans = new Float64Array(16); const rotation = new Float64Array(16); const v2 = new Float64Array(3); const centerNeg = new Float64Array(3); const negRotationAxis = new Float64Array(3); publicAPI.onButtonDown = (interactor, renderer, position) => { model.previousPosition = position; }; publicAPI.onMouseMove = (interactor, renderer, position) => { if (!position) { return; } const camera = renderer.getActiveCamera(); const cameraPos = camera.getPosition(); const cameraFp = camera.getFocalPoint(); const cameraViewUp = camera.getViewUp(); const cameraDirection = camera.getDirectionOfProjection(); vec3.negate(negCameraDir, cameraDirection); mat4.identity(trans); mat4.identity(rotation); const { center, rotationFactor, rotationAxis } = model; vec3.negate(negRotationAxis, rotationAxis); const dx = model.previousPosition.x - position.x; const dy = model.previousPosition.y - position.y; const size = interactor.getView().getViewportSize(renderer); // Azimuth const azimuthDelta = radiansFromDegrees(360.0 * dx / size[0] * rotationFactor); mat4.rotate(rotation, rotation, azimuthDelta, rotationAxis); // Elevation cross(cameraDirection, cameraViewUp, v2); let elevationDelta = radiansFromDegrees(-360.0 * dy / size[1] * rotationFactor); // angle of camera to rotation axis on the positive or negative half, // relative to the origin. const angleToPosHalf = Math.acos(vec3.dot(negCameraDir, rotationAxis)); const angleToNegHalf = Math.acos(vec3.dot(negCameraDir, negRotationAxis)); // whether camera is in positive half of the rotation axis or neg half const inPosHalf = angleToPosHalf <= angleToNegHalf; const elevationToAxis = Math.min(angleToPosHalf, angleToNegHalf); if (model.useHalfAxis && !inPosHalf) { elevationDelta = Math.PI / 2 - angleToPosHalf; } else if (inPosHalf && elevationToAxis + elevationDelta < 0) { elevationDelta = -elevationToAxis; // } else if (!inPosHalf && elevationToAxis - elevationDelta < 0) { } else if (!inPosHalf && angleToPosHalf + elevationDelta > Math.PI) { elevationDelta = elevationToAxis; } mat4.rotate(rotation, rotation, elevationDelta, v2); // Translate from origin mat4.translate(trans, trans, center); // apply rotation mat4.multiply(trans, trans, rotation); // Translate to origin vec3.negate(centerNeg, center); mat4.translate(trans, trans, centerNeg); // Apply transformation to camera position, focal point, and view up vec3.transformMat4(newCamPos, cameraPos, trans); vec3.transformMat4(newFp, cameraFp, trans); vec3.transformMat4(newViewUp, cameraViewUp, rotation); camera.setPosition(newCamPos[0], newCamPos[1], newCamPos[2]); camera.setFocalPoint(newFp[0], newFp[1], newFp[2]); camera.setViewUp(newViewUp); renderer.resetCameraClippingRange(); if (interactor.getLightFollowCamera()) { renderer.updateLightsGeometryToFollowCamera(); } model.previousPosition = position; }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- const DEFAULT_VALUES = { rotationAxis: [0, 0, 1], useHalfAxis: true }; // ---------------------------------------------------------------------------- function extend(publicAPI, model, initialValues = {}) { Object.assign(model, DEFAULT_VALUES, initialValues); // Inheritance macro.obj(publicAPI, model); macro.setGet(publicAPI, model, ['rotationAxis', 'useHalfAxis']); vtkCompositeMouseManipulator.extend(publicAPI, model, initialValues); vtkCompositeCameraManipulator.extend(publicAPI, model, initialValues); // Object specific methods vtkMouseCameraAxisRotateManipulator(publicAPI, model); } // ---------------------------------------------------------------------------- const newInstance = macro.newInstance(extend, 'vtkMouseCameraAxisRotateManipulator'); // ---------------------------------------------------------------------------- var vtkMouseCameraAxisRotateManipulator$1 = { newInstance, extend }; export { vtkMouseCameraAxisRotateManipulator$1 as default, extend, newInstance };