@kitware/vtk.js
Version:
Visualization Toolkit for the Web
134 lines (113 loc) • 5.18 kB
JavaScript
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 };