UNPKG

@cornerstonejs/core

Version:
94 lines (93 loc) 4.16 kB
import macro from '@kitware/vtk.js/macros.js'; import extendedVtkCamera from './extendedVtkCamera.js'; import vtkMath from '@kitware/vtk.js/Common/Core/Math.js'; import { vec3, mat4 } from 'gl-matrix'; import { getProjectionScaleMatrix } from '../helpers/getProjectionScaleMatrix.js'; import { getNormalizedAspectRatio } from '../../utilities/getNormalizedAspectRatio.js'; const DEFAULT_VALUES = { isPerformingCoordinateTransformation: false, }; function extend(publicAPI, model, initialValues = {}) { Object.assign(model, DEFAULT_VALUES, initialValues); extendedVtkCamera.extend(publicAPI, model, initialValues); macro.setGet(publicAPI, model, ['isPerformingCoordinateTransformation']); vtkSlabCamera(publicAPI, model); } const newInstance = macro.newInstance(extend, 'vtkSlabCamera'); function vtkSlabCamera(publicAPI, model) { model.classHierarchy.push('vtkSlabCamera'); const tmpMatrix = mat4.identity(new Float64Array(16)); const tmpvec1 = new Float64Array(3); publicAPI.getProjectionMatrix = (aspect, nearz, farz) => { const result = mat4.create(); if (model.projectionMatrix) { const scale = 1 / model.physicalScale; vec3.set(tmpvec1, scale, scale, scale); mat4.copy(result, model.projectionMatrix); mat4.scale(result, result, tmpvec1); mat4.transpose(result, result); return result; } mat4.identity(tmpMatrix); let cRange0 = model.clippingRange[0]; let cRange1 = model.clippingRange[1]; if (model.isPerformingCoordinateTransformation) { cRange0 = model.distance; cRange1 = model.distance + 0.1; } const cWidth = cRange1 - cRange0; const cRange = [ cRange0 + ((nearz + 1) * cWidth) / 2.0, cRange0 + ((farz + 1) * cWidth) / 2.0, ]; if (model.parallelProjection) { const width = model.parallelScale * aspect; const height = model.parallelScale; const xmin = (model.windowCenter[0] - 1.0) * width; const xmax = (model.windowCenter[0] + 1.0) * width; const ymin = (model.windowCenter[1] - 1.0) * height; const ymax = (model.windowCenter[1] + 1.0) * height; mat4.ortho(tmpMatrix, xmin, xmax, ymin, ymax, cRange[0], cRange[1]); mat4.transpose(tmpMatrix, tmpMatrix); } else if (model.useOffAxisProjection) { throw new Error('Off-Axis projection is not supported at this time'); } else { const tmp = Math.tan(vtkMath.radiansFromDegrees(model.viewAngle) / 2.0); let width; let height; if (model.useHorizontalViewAngle === true) { width = cRange0 * tmp; height = (cRange0 * tmp) / aspect; } else { width = cRange0 * tmp * aspect; height = cRange0 * tmp; } const xmin = (model.windowCenter[0] - 1.0) * width; const xmax = (model.windowCenter[0] + 1.0) * width; const ymin = (model.windowCenter[1] - 1.0) * height; const ymax = (model.windowCenter[1] + 1.0) * height; const znear = cRange[0]; const zfar = cRange[1]; tmpMatrix[0] = (2.0 * znear) / (xmax - xmin); tmpMatrix[5] = (2.0 * znear) / (ymax - ymin); tmpMatrix[2] = (xmin + xmax) / (xmax - xmin); tmpMatrix[6] = (ymin + ymax) / (ymax - ymin); tmpMatrix[10] = -(znear + zfar) / (zfar - znear); tmpMatrix[14] = -1.0; tmpMatrix[11] = (-2.0 * znear * zfar) / (zfar - znear); tmpMatrix[15] = 0.0; } const [sx, sy] = getNormalizedAspectRatio(model.aspectRatio); if (sx !== 1.0 || sy !== 1.0) { const scaleMatrix = getProjectionScaleMatrix([sx, sy]); mat4.multiply(tmpMatrix, scaleMatrix, tmpMatrix); } mat4.copy(result, tmpMatrix); return result; }; } export default { newInstance, extend }; export { newInstance, extend };