@kitware/vtk.js
Version:
Visualization Toolkit for the Web
120 lines (103 loc) • 4.35 kB
JavaScript
import { m as macro } from '../../macros2.js';
import vtkMouseCameraTrackballPanManipulator from './MouseCameraTrackballPanManipulator.js';
import { mat4, vec3 } from 'gl-matrix';
// ----------------------------------------------------------------------------
// Helper functions for center of rotation adjustment
// ----------------------------------------------------------------------------
/**
* Transforms a vector by the transformation delta between two matrices.
*
* @param {Object} tempObjects - Temporary matrices/vectors for computation
* @param {mat4} beforeMatrix - Matrix before transformation
* @param {mat4} afterMatrix - Matrix after transformation
* @param {Array} vector - Vector to transform [x, y, z]
* @returns {Array} Transformed vector [x, y, z]
*/
function transformVectorByTransformation(tempObjects, beforeMatrix, afterMatrix, vector) {
const {
matrixA,
matrixB,
newCenter
} = tempObjects;
// The view matrix from vtk.js is row-major, but gl-matrix expects column-major.
// We need to transpose them before use.
mat4.transpose(matrixA, beforeMatrix);
mat4.transpose(matrixB, afterMatrix);
mat4.invert(matrixB, matrixB);
// Compute delta transformation matrix
mat4.multiply(matrixA, matrixB, matrixA);
vec3.transformMat4(newCenter, vector, matrixA);
return newCenter;
}
/**
* Computes the new center of rotation based on camera movement.
* When the camera moves (pan), the center of rotation should move
* by the same transformation.
*
* @param {Object} tempObjects - Temporary matrices/vectors for computation
* @param {Object} renderer - VTK renderer
* @param {mat4} beforeCameraMatrix - Camera view matrix before movement
* @param {Array} oldCenterOfRotation - Previous center of rotation [x, y, z]
* @returns {Array} New center of rotation [x, y, z]
*/
function computeNewCenterOfRotation(tempObjects, renderer, beforeCameraMatrix, oldCenterOfRotation) {
const cam = renderer.getActiveCamera();
if (!cam || !beforeCameraMatrix) {
return oldCenterOfRotation;
}
const afterMatrixRowMajor = cam.getViewMatrix();
return transformVectorByTransformation(tempObjects, beforeCameraMatrix, afterMatrixRowMajor, oldCenterOfRotation);
}
function getCameraMatrix(renderer, tempMatrix) {
const cam = renderer.getActiveCamera();
if (cam) {
mat4.copy(tempMatrix, cam.getViewMatrix());
return tempMatrix;
}
return null;
}
function vtkMouseCameraTrackballPanManipulatorAutoCenter(publicAPI, model) {
model.classHierarchy.push('vtkMouseCameraTrackballPanManipulatorAutoCenter');
const tempCameraMatrix = mat4.create();
const tempComputeObjects = {
matrixA: mat4.create(),
matrixB: mat4.create(),
newCenter: vec3.create()
};
const superOnMouseMove = publicAPI.onMouseMove;
publicAPI.onMouseMove = (interactor, renderer, position) => {
if (!position) {
return;
}
const beforeCameraMatrix = getCameraMatrix(renderer, tempCameraMatrix);
superOnMouseMove(interactor, renderer, position);
if (beforeCameraMatrix && model.center) {
const newCenter = computeNewCenterOfRotation(tempComputeObjects, renderer, beforeCameraMatrix, model.center);
publicAPI.setCenter(newCenter);
const style = interactor.getInteractorStyle();
if (style && style.setCenterOfRotation) {
style.setCenterOfRotation(newCenter);
}
}
};
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {};
// ----------------------------------------------------------------------------
function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
// Inheritance
vtkMouseCameraTrackballPanManipulator.extend(publicAPI, model, initialValues);
// Object specific methods
vtkMouseCameraTrackballPanManipulatorAutoCenter(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = macro.newInstance(extend, 'vtkMouseCameraTrackballPanManipulatorAutoCenter');
// ----------------------------------------------------------------------------
var index = {
newInstance,
extend
};
export { index as default, extend, newInstance };