@kitware/vtk.js
Version:
Visualization Toolkit for the Web
192 lines (173 loc) • 6.42 kB
JavaScript
import { mat4, quat } from 'gl-matrix';
import { m as macro } from '../../macros2.js';
import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js';
import { A as degreesFromRadians, r as radiansFromDegrees, a as areMatricesEqual } from '../../Common/Core/Math/index.js';
import vtkProp from './Prop.js';
const VTK_EPSILON = 1e-6;
// ----------------------------------------------------------------------------
// vtkProp3D methods
// ----------------------------------------------------------------------------
function vtkProp3D(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkProp3D');
publicAPI.addPosition = deltaXYZ => {
model.position = model.position.map((value, index) => value + deltaXYZ[index]);
publicAPI.modified();
};
publicAPI.getOrientationWXYZ = () => {
const q = quat.create();
mat4.getRotation(q, model.rotation);
const oaxis = new Float64Array(3);
const w = quat.getAxisAngle(oaxis, q);
return [degreesFromRadians(w), oaxis[0], oaxis[1], oaxis[2]];
};
publicAPI.getOrientationQuaternion = function () {
let out = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
return mat4.getRotation(out, model.rotation);
};
publicAPI.rotateX = val => {
if (val === 0.0) {
return;
}
mat4.rotateX(model.rotation, model.rotation, radiansFromDegrees(val));
publicAPI.modified();
};
publicAPI.rotateY = val => {
if (val === 0.0) {
return;
}
mat4.rotateY(model.rotation, model.rotation, radiansFromDegrees(val));
publicAPI.modified();
};
publicAPI.rotateZ = val => {
if (val === 0.0) {
return;
}
mat4.rotateZ(model.rotation, model.rotation, radiansFromDegrees(val));
publicAPI.modified();
};
publicAPI.rotateWXYZ = (degrees, x, y, z) => {
if (degrees === 0.0 || x === 0.0 && y === 0.0 && z === 0.0) {
return;
}
// convert to radians
const angle = radiansFromDegrees(degrees);
const q = quat.create();
quat.setAxisAngle(q, [x, y, z], angle);
const quatMat = new Float64Array(16);
mat4.fromQuat(quatMat, q);
mat4.multiply(model.rotation, model.rotation, quatMat);
publicAPI.modified();
};
publicAPI.rotateQuaternion = orientationQuaternion => {
if (Math.abs(orientationQuaternion[3]) >= 1 - VTK_EPSILON) {
return;
}
const oriQuatMat = mat4.fromQuat(new Float64Array(16), orientationQuaternion);
mat4.multiply(model.rotation, model.rotation, oriQuatMat);
publicAPI.modified();
};
publicAPI.setOrientation = (x, y, z) => {
if (x === model.orientation[0] && y === model.orientation[1] && z === model.orientation[2]) {
return false;
}
model.orientation = [x, y, z];
mat4.identity(model.rotation);
publicAPI.rotateZ(z);
publicAPI.rotateX(x);
publicAPI.rotateY(y);
publicAPI.modified();
return true;
};
publicAPI.setUserMatrix = matrix => {
if (areMatricesEqual(model.userMatrix, matrix)) {
return false;
}
mat4.copy(model.userMatrix, matrix);
publicAPI.modified();
return true;
};
publicAPI.getMatrix = () => {
publicAPI.computeMatrix();
return model.matrix;
};
publicAPI.computeMatrix = () => {
// check whether or not need to rebuild the matrix
if (publicAPI.getMTime() > model.matrixMTime.getMTime()) {
mat4.identity(model.matrix);
if (model.userMatrix) {
mat4.multiply(model.matrix, model.matrix, model.userMatrix);
}
mat4.translate(model.matrix, model.matrix, model.origin);
mat4.translate(model.matrix, model.matrix, model.position);
mat4.multiply(model.matrix, model.matrix, model.rotation);
mat4.scale(model.matrix, model.matrix, model.scale);
mat4.translate(model.matrix, model.matrix, [-model.origin[0], -model.origin[1], -model.origin[2]]);
mat4.transpose(model.matrix, model.matrix);
// check for identity
model.isIdentity = true;
for (let i = 0; i < 4; ++i) {
for (let j = 0; j < 4; ++j) {
if ((i === j ? 1.0 : 0.0) !== model.matrix[i + j * 4]) {
model.isIdentity = false;
}
}
}
model.matrixMTime.modified();
}
};
publicAPI.getCenter = () => vtkBoundingBox.getCenter(model.bounds);
publicAPI.getLength = () => vtkBoundingBox.getLength(model.bounds);
publicAPI.getXRange = () => vtkBoundingBox.getXRange(model.bounds);
publicAPI.getYRange = () => vtkBoundingBox.getYRange(model.bounds);
publicAPI.getZRange = () => vtkBoundingBox.getZRange(model.bounds);
publicAPI.getUserMatrix = () => model.userMatrix;
function updateIdentityFlag() {
publicAPI.computeMatrix();
}
publicAPI.onModified(updateIdentityFlag);
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
origin: [0, 0, 0],
position: [0, 0, 0],
orientation: [0, 0, 0],
rotation: null,
scale: [1, 1, 1],
bounds: [1, -1, 1, -1, 1, -1],
userMatrix: null,
userMatrixMTime: null,
cachedProp3D: null,
isIdentity: true,
matrixMTime: null
};
// ----------------------------------------------------------------------------
function extend(publicAPI, model) {
let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
Object.assign(model, DEFAULT_VALUES, initialValues);
// Inheritance
vtkProp.extend(publicAPI, model, initialValues);
model.matrixMTime = {};
macro.obj(model.matrixMTime);
// Build VTK API
macro.get(publicAPI, model, ['bounds', 'isIdentity']);
macro.getArray(publicAPI, model, ['orientation']);
macro.setGetArray(publicAPI, model, ['origin', 'position', 'scale'], 3);
// Object internal instance
model.matrix = mat4.identity(new Float64Array(16));
model.rotation = mat4.identity(new Float64Array(16));
model.userMatrix = mat4.identity(new Float64Array(16));
model.transform = null; // FIXME
// Object methods
vtkProp3D(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = macro.newInstance(extend, 'vtkProp3D');
// ----------------------------------------------------------------------------
var vtkProp3D$1 = {
newInstance,
extend
};
export { vtkProp3D$1 as default, extend, newInstance };