@kitware/vtk.js
Version:
Visualization Toolkit for the Web
526 lines (496 loc) • 23.8 kB
JavaScript
import { mat3, mat4 } from 'gl-matrix';
import { n as newInstance$1, o as obj, c as macro } from '../../macros2.js';
import vtkBufferObject from './BufferObject.js';
import vtkHardwareSelector from './HardwareSelector.js';
import vtkProperty from '../Core/Property.js';
import vtkOpenGLPolyDataMapper from './PolyDataMapper.js';
import vtkShaderProgram from './ShaderProgram.js';
import { computeCoordShiftAndScale, computeInverseShiftAndScaleMatrix } from './CellArrayBufferObject/helpers.js';
import { registerOverride } from './ViewNodeFactory.js';
import { primTypes } from './Helper.js';
const {
vtkErrorMacro
} = macro;
const {
Representation
} = vtkProperty;
const {
ObjectType
} = vtkBufferObject;
const {
PassTypes
} = vtkHardwareSelector;
const StartEvent = {
type: 'StartEvent'
};
const EndEvent = {
type: 'EndEvent'
};
const MAT4_BYTE_SIZE = 64;
const MAT4_ELEMENT_COUNT = 16;
// ----------------------------------------------------------------------------
// vtkOpenGLSphereMapper methods
// ----------------------------------------------------------------------------
function vtkOpenGLGlyph3DMapper(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkOpenGLGlyph3DMapper');
// Capture 'parentClass' api for internal use
const superClass = {
...publicAPI
};
publicAPI.renderPiece = (ren, actor) => {
publicAPI.invokeEvent(StartEvent);
if (!model.renderable.getStatic()) {
model.renderable.update();
}
model.currentInput = model.renderable.getInputData(1);
publicAPI.invokeEvent(EndEvent);
if (!model.currentInput) {
vtkErrorMacro('No input!');
return;
}
// if there are no points then we are done
if (!model.currentInput.getPoints || !model.currentInput.getPoints().getNumberOfValues()) {
return;
}
// apply faceCulling
const gl = model.context;
if (model._openGLRenderWindow.getWebgl2()) {
model.hardwareSupport = true;
model.extension = null;
} else if (!model.extension) {
model.extension = model.context.getExtension('ANGLE_instanced_arrays');
model.hardwareSupport = !!model.extension;
}
// to test without extension support uncomment the next two lines
// model.extension = null;
// model.hardwareSupport = !!model.extension;
const backfaceCulling = actor.getProperty().getBackfaceCulling();
const frontfaceCulling = actor.getProperty().getFrontfaceCulling();
if (!backfaceCulling && !frontfaceCulling) {
model._openGLRenderWindow.disableCullFace();
} else if (frontfaceCulling) {
model._openGLRenderWindow.enableCullFace();
gl.cullFace(gl.FRONT);
} else {
model._openGLRenderWindow.enableCullFace();
gl.cullFace(gl.BACK);
}
publicAPI.renderPieceStart(ren, actor);
publicAPI.renderPieceDraw(ren, actor);
publicAPI.renderPieceFinish(ren, actor);
};
publicAPI.multiply4x4WithOffset = (out, a, b, off) => {
const a00 = a[0];
const a01 = a[1];
const a02 = a[2];
const a03 = a[3];
const a10 = a[4];
const a11 = a[5];
const a12 = a[6];
const a13 = a[7];
const a20 = a[8];
const a21 = a[9];
const a22 = a[10];
const a23 = a[11];
const a30 = a[12];
const a31 = a[13];
const a32 = a[14];
const a33 = a[15];
// Cache only the current line of the second matrix
let b0 = b[off];
let b1 = b[off + 1];
let b2 = b[off + 2];
let b3 = b[off + 3];
out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[off + 4];
b1 = b[off + 5];
b2 = b[off + 6];
b3 = b[off + 7];
out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[off + 8];
b1 = b[off + 9];
b2 = b[off + 10];
b3 = b[off + 11];
out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[off + 12];
b1 = b[off + 13];
b2 = b[off + 14];
b3 = b[off + 15];
out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
};
publicAPI.replaceShaderNormal = (shaders, ren, actor) => {
if (model.hardwareSupport) {
const lastLightComplexity = model.lastBoundBO.getReferenceByName('lastLightComplexity');
if (lastLightComplexity > 0) {
let VSSource = shaders.Vertex;
if (model.lastBoundBO.getCABO().getNormalOffset()) {
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Normal::Dec', ['attribute vec3 normalMC;', 'attribute mat3 gNormal;', 'uniform mat3 normalMatrix;', 'varying vec3 normalVCVSOutput;']).result;
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Normal::Impl', ['normalVCVSOutput = normalMatrix * gNormal * normalMC;']).result;
}
shaders.Vertex = VSSource;
}
}
superClass.replaceShaderNormal(shaders, ren, actor);
};
publicAPI.replaceShaderClip = (shaders, ren, actor) => {
if (model.hardwareSupport) {
let VSSource = shaders.Vertex;
let FSSource = shaders.Fragment;
if (model.renderable.getNumberOfClippingPlanes()) {
const numClipPlanes = model.renderable.getNumberOfClippingPlanes();
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Clip::Dec', ['uniform int numClipPlanes;', `uniform vec4 clipPlanes[${numClipPlanes}];`, `varying float clipDistancesVSOutput[${numClipPlanes}];`]).result;
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Clip::Impl', [`for (int planeNum = 0; planeNum < ${numClipPlanes}; planeNum++)`, ' {', ' if (planeNum >= numClipPlanes)', ' {', ' break;', ' }', ' vec4 gVertex = gMatrix * vertexMC;', ' clipDistancesVSOutput[planeNum] = dot(clipPlanes[planeNum], gVertex);', ' }']).result;
FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Clip::Dec', ['uniform int numClipPlanes;', `varying float clipDistancesVSOutput[${numClipPlanes}];`]).result;
FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Clip::Impl', [`for (int planeNum = 0; planeNum < ${numClipPlanes}; planeNum++)`, ' {', ' if (planeNum >= numClipPlanes)', ' {', ' break;', ' }', ' if (clipDistancesVSOutput[planeNum] < 0.0) discard;', ' }']).result;
}
shaders.Vertex = VSSource;
shaders.Fragment = FSSource;
}
superClass.replaceShaderClip(shaders, ren, actor);
};
publicAPI.replaceShaderColor = (shaders, ren, actor) => {
if (model.hardwareSupport && model.renderable.getColorArray()) {
let VSSource = shaders.Vertex;
let GSSource = shaders.Geometry;
let FSSource = shaders.Fragment;
const lastLightComplexity = model.lastBoundBO.getReferenceByName('lastLightComplexity');
// create the material/color property declarations, and VS implementation
// these are always defined
let colorDec = ['uniform float ambient;', 'uniform float diffuse;', 'uniform float specular;', 'uniform float opacityUniform; // the fragment opacity'];
// add more for specular
if (lastLightComplexity) {
colorDec = colorDec.concat(['uniform vec3 specularColorUniform;', 'uniform float specularPowerUniform;']);
}
// now handle the more complex fragment shader implementation
// the following are always defined variables. We start
// by assigning a default value from the uniform
let colorImpl = ['vec3 ambientColor;', ' vec3 diffuseColor;', ' float opacity;'];
if (lastLightComplexity) {
colorImpl = colorImpl.concat([' vec3 specularColor;', ' float specularPower;']);
}
colorImpl = colorImpl.concat([' opacity = opacityUniform;']);
if (lastLightComplexity) {
colorImpl = colorImpl.concat([' specularColor = specularColorUniform;', ' specularPower = specularPowerUniform;']);
}
if (!model.drawingEdges) {
colorDec = colorDec.concat(['varying vec4 vertexColorVSOutput;']);
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Color::Dec', ['attribute vec4 gColor;', 'varying vec4 vertexColorVSOutput;']).result;
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Color::Impl', ['vertexColorVSOutput = gColor;']).result;
GSSource = vtkShaderProgram.substitute(GSSource, '//VTK::Color::Dec', ['in vec4 vertexColorVSOutput[];', 'out vec4 vertexColorGSOutput;']).result;
GSSource = vtkShaderProgram.substitute(GSSource, '//VTK::Color::Impl', ['vertexColorGSOutput = vertexColorVSOutput[i];']).result;
colorImpl = colorImpl.concat([' diffuseColor = vertexColorVSOutput.rgb;', ' ambientColor = vertexColorVSOutput.rgb;', ' opacity = opacity*vertexColorVSOutput.a;']);
}
FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Color::Impl', colorImpl).result;
FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Color::Dec', colorDec).result;
shaders.Vertex = VSSource;
shaders.Geometry = GSSource;
shaders.Fragment = FSSource;
}
superClass.replaceShaderColor(shaders, ren, actor);
};
publicAPI.replaceShaderPositionVC = (shaders, ren, actor) => {
if (model.hardwareSupport) {
let VSSource = shaders.Vertex;
// do we need the vertex in the shader in View Coordinates
const lastLightComplexity = model.lastBoundBO.getReferenceByName('lastLightComplexity');
if (lastLightComplexity > 0) {
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::PositionVC::Impl', ['vec4 gVertexMC = gMatrix * vertexMC;', 'vertexVCVSOutput = MCVCMatrix * gVertexMC;', ' gl_Position = MCPCMatrix * gVertexMC;']).result;
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Camera::Dec', ['attribute mat4 gMatrix;', 'uniform mat4 MCPCMatrix;', 'uniform mat4 MCVCMatrix;']).result;
} else {
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Camera::Dec', ['attribute mat4 gMatrix;', 'uniform mat4 MCPCMatrix;']).result;
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::PositionVC::Impl', ['vec4 gVertexMC = gMatrix * vertexMC;', ' gl_Position = MCPCMatrix * gVertexMC;']).result;
}
shaders.Vertex = VSSource;
}
superClass.replaceShaderPositionVC(shaders, ren, actor);
};
publicAPI.replaceShaderPicking = (shaders, ren, actor) => {
if (model.hardwareSupport) {
let FSSource = shaders.Fragment;
let VSSource = shaders.Vertex;
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Picking::Dec', ['attribute vec3 mapperIndexVS;', 'varying vec3 mapperIndexVSOutput;']).result;
VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Picking::Impl', ' mapperIndexVSOutput = mapperIndexVS;').result;
shaders.Vertex = VSSource;
FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Picking::Dec', ['varying vec3 mapperIndexVSOutput;', 'uniform vec3 mapperIndex;', 'uniform int picking;']).result;
FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Picking::Impl', [' vec4 pickColor = picking == 2 ? vec4(mapperIndexVSOutput,1.0) : vec4(mapperIndex,1.0);', ' gl_FragData[0] = picking != 0 ? pickColor : gl_FragData[0];']).result;
shaders.Fragment = FSSource;
} else {
superClass.replaceShaderPicking(shaders, ren, actor);
}
};
publicAPI.updateGlyphShaderParameters = (normalMatrixUsed, mcvcMatrixUsed, cellBO, carray, garray, narray, p, selector) => {
const program = cellBO.getProgram();
if (normalMatrixUsed) {
const a = model.normalMatrix;
const b = narray;
const ofs = p * 9;
const out = model.tmpMat3;
const a00 = a[0];
const a01 = a[1];
const a02 = a[2];
const a10 = a[3];
const a11 = a[4];
const a12 = a[5];
const a20 = a[6];
const a21 = a[7];
const a22 = a[8];
const b00 = b[ofs];
const b01 = b[ofs + 1];
const b02 = b[ofs + 2];
const b10 = b[ofs + 3];
const b11 = b[ofs + 4];
const b12 = b[ofs + 5];
const b20 = b[ofs + 6];
const b21 = b[ofs + 7];
const b22 = b[ofs + 8];
out[0] = b00 * a00 + b01 * a10 + b02 * a20;
out[1] = b00 * a01 + b01 * a11 + b02 * a21;
out[2] = b00 * a02 + b01 * a12 + b02 * a22;
out[3] = b10 * a00 + b11 * a10 + b12 * a20;
out[4] = b10 * a01 + b11 * a11 + b12 * a21;
out[5] = b10 * a02 + b11 * a12 + b12 * a22;
out[6] = b20 * a00 + b21 * a10 + b22 * a20;
out[7] = b20 * a01 + b21 * a11 + b22 * a21;
out[8] = b20 * a02 + b21 * a12 + b22 * a22;
program.setUniformMatrix3x3('normalMatrix', model.tmpMat3);
}
publicAPI.multiply4x4WithOffset(model.tmpMat4, model.mcpcMatrix, garray, p * 16);
program.setUniformMatrix('MCPCMatrix', model.tmpMat4);
if (mcvcMatrixUsed) {
publicAPI.multiply4x4WithOffset(model.tmpMat4, model.mcvcMatrix, garray, p * 16);
program.setUniformMatrix('MCVCMatrix', model.tmpMat4);
}
// set color
if (carray) {
const cdata = carray.getData();
model.tmpColor[0] = cdata[p * 4] / 255.0;
model.tmpColor[1] = cdata[p * 4 + 1] / 255.0;
model.tmpColor[2] = cdata[p * 4 + 2] / 255.0;
program.setUniform3fArray('ambientColorUniform', model.tmpColor);
program.setUniform3fArray('diffuseColorUniform', model.tmpColor);
}
if (selector) {
program.setUniform3fArray('mapperIndex', selector.getPropColorValue());
}
};
publicAPI.renderPieceDraw = (ren, actor) => {
const representation = actor.getProperty().getRepresentation();
const gl = model.context;
const drawSurfaceWithEdges = actor.getProperty().getEdgeVisibility() && representation === Representation.SURFACE;
// [WMVP]C == {world, model, view, projection} coordinates
// E.g., WCPC == world to projection coordinate transformation
const keyMats = model.openGLCamera.getKeyMatrices(ren);
const actMats = model.openGLActor.getKeyMatrices();
// precompute the actor+camera mats once
mat3.multiply(model.normalMatrix, keyMats.normalMatrix, actMats.normalMatrix);
mat4.multiply(model.mcpcMatrix, keyMats.wcpc, actMats.mcwc);
mat4.multiply(model.mcvcMatrix, keyMats.wcvc, actMats.mcwc);
const garray = model.renderable.getMatrixArray();
const narray = model.renderable.getNormalArray();
const carray = model.renderable.getColorArray();
const numPts = garray.length / 16;
let compositePass = false;
if (model._openGLRenderer.getSelector()) {
if (model._openGLRenderer.getSelector().getCurrentPass() === PassTypes.COMPOSITE_INDEX_PASS) {
compositePass = true;
}
}
// for every primitive type
for (let i = model.primTypes.Start; i < model.primTypes.End; i++) {
// if there are entries
const cabo = model.primitives[i].getCABO();
if (cabo.getElementCount()) {
// are we drawing edges
model.drawingEdges = drawSurfaceWithEdges && (i === model.primTypes.TrisEdges || i === model.primTypes.TriStripsEdges);
model.lastBoundBO = model.primitives[i];
model.primitives[i].updateShaders(ren, actor, publicAPI);
const program = model.primitives[i].getProgram();
const mode = model.primitives[i].getOpenGLMode(representation);
const normalMatrixUsed = program.isUniformUsed('normalMatrix');
const mcvcMatrixUsed = program.isUniformUsed('MCVCMatrix');
if (model.hardwareSupport) {
if (model.extension) {
model.extension.drawArraysInstancedANGLE(mode, 0, cabo.getElementCount(), numPts);
} else {
gl.drawArraysInstanced(mode, 0, cabo.getElementCount(), numPts);
}
} else {
// draw the array multiple times with different cam matrix
for (let p = 0; p < numPts; ++p) {
if (compositePass) {
model._openGLRenderer.getSelector().renderCompositeIndex(p);
}
publicAPI.updateGlyphShaderParameters(normalMatrixUsed, mcvcMatrixUsed, model.primitives[i], carray, garray, narray, p, compositePass ? model._openGLRenderer.getSelector() : null);
gl.drawArrays(mode, 0, cabo.getElementCount());
}
}
}
}
};
publicAPI.setMapperShaderParameters = (cellBO, ren, actor) => {
if (cellBO.getCABO().getElementCount() && (model.glyphBOBuildTime.getMTime() > cellBO.getAttributeUpdateTime().getMTime() || cellBO.getShaderSourceTime().getMTime() > cellBO.getAttributeUpdateTime().getMTime())) {
if (cellBO.getProgram().isAttributeUsed('gMatrix')) {
if (!cellBO.getVAO().addAttributeMatrixWithDivisor(cellBO.getProgram(), model.matrixBuffer, 'gMatrix', 0, 64, model.context.FLOAT, 4, false, 1)) {
vtkErrorMacro('Error setting gMatrix in shader VAO.');
}
} else {
cellBO.getVAO().removeAttributeArray('gMatrix');
}
if (cellBO.getProgram().isAttributeUsed('gNormal')) {
if (!cellBO.getVAO().addAttributeMatrixWithDivisor(cellBO.getProgram(), model.normalBuffer, 'gNormal', 0, 36, model.context.FLOAT, 3, false, 1)) {
vtkErrorMacro('Error setting gNormal in shader VAO.');
}
} else {
cellBO.getVAO().removeAttributeArray('gNormal');
}
if (cellBO.getProgram().isAttributeUsed('gColor')) {
if (!cellBO.getVAO().addAttributeArrayWithDivisor(cellBO.getProgram(), model.colorBuffer, 'gColor', 0, 4, model.context.UNSIGNED_BYTE, 4, true, 1, false)) {
vtkErrorMacro('Error setting gColor in shader VAO.');
}
} else {
cellBO.getVAO().removeAttributeArray('gColor');
}
if (cellBO.getProgram().isAttributeUsed('mapperIndexVS')) {
if (!cellBO.getVAO().addAttributeArrayWithDivisor(cellBO.getProgram(), model.pickBuffer, 'mapperIndexVS', 0, 4, model.context.UNSIGNED_BYTE, 4, true, 1, false)) {
vtkErrorMacro('Error setting mapperIndexVS in shader VAO.');
}
} else {
cellBO.getVAO().removeAttributeArray('mapperIndexVS');
}
superClass.setMapperShaderParameters(cellBO, ren, actor);
cellBO.getAttributeUpdateTime().modified();
return;
}
superClass.setMapperShaderParameters(cellBO, ren, actor);
};
publicAPI.getNeedToRebuildBufferObjects = (ren, actor) => {
model.renderable.buildArrays();
// first do a coarse check
// Note that the actor's mtime includes it's properties mtime
const vmtime = model.VBOBuildTime.getMTime();
if (vmtime < model.renderable.getBuildTime().getMTime()) {
return true;
}
return superClass.getNeedToRebuildBufferObjects(ren, actor);
};
publicAPI.getNeedToRebuildShaders = (cellBO, ren, actor) => {
if (superClass.getNeedToRebuildShaders(cellBO, ren, actor) || cellBO.getShaderSourceTime().getMTime() < model.renderable.getMTime() || cellBO.getShaderSourceTime().getMTime() < model.currentInput.getMTime()) {
return true;
}
return false;
};
publicAPI.buildBufferObjects = (ren, actor) => {
const garray = model.renderable.getMatrixArray();
const pts = model.renderable.getInputData(0).getPoints();
const {
useShiftAndScale,
coordShift,
coordScale
} = computeCoordShiftAndScale(pts);
if (model.hardwareSupport) {
// update the buffer objects if needed
const narray = model.renderable.getNormalArray();
const carray = model.renderable.getColorArray();
if (!model.matrixBuffer) {
model.matrixBuffer = vtkBufferObject.newInstance();
model.matrixBuffer.setOpenGLRenderWindow(model._openGLRenderWindow);
model.normalBuffer = vtkBufferObject.newInstance();
model.normalBuffer.setOpenGLRenderWindow(model._openGLRenderWindow);
model.colorBuffer = vtkBufferObject.newInstance();
model.colorBuffer.setOpenGLRenderWindow(model._openGLRenderWindow);
model.pickBuffer = vtkBufferObject.newInstance();
model.pickBuffer.setOpenGLRenderWindow(model._openGLRenderWindow);
}
if (useShiftAndScale) {
const buf = garray.buffer;
const shiftScaleMat = computeInverseShiftAndScaleMatrix(coordShift, coordScale);
mat4.invert(shiftScaleMat, shiftScaleMat);
for (let ptIdx = 0; ptIdx < garray.byteLength; ptIdx += MAT4_BYTE_SIZE) {
const mat = new Float32Array(buf, ptIdx, MAT4_ELEMENT_COUNT);
mat4.multiply(mat, shiftScaleMat, mat);
}
}
if (model.renderable.getBuildTime().getMTime() > model.glyphBOBuildTime.getMTime()) {
model.matrixBuffer.upload(garray, ObjectType.ARRAY_BUFFER);
model.normalBuffer.upload(narray, ObjectType.ARRAY_BUFFER);
if (carray) {
model.colorBuffer.upload(carray.getData(), ObjectType.ARRAY_BUFFER);
} else {
model.colorBuffer.releaseGraphicsResources();
}
const numPts = garray.length / 16;
const parray = new Uint8Array(4 * numPts);
for (let i = 0; i < numPts; ++i) {
let value = i + 1;
const offset = i * 4;
parray[offset] = value % 256;
value -= parray[offset];
value /= 256;
parray[offset + 1] = value % 256;
value -= parray[offset + 1];
value /= 256;
parray[offset + 2] = value % 256;
parray[offset + 3] = 255;
}
model.pickBuffer.upload(parray, ObjectType.ARRAY_BUFFER);
model.glyphBOBuildTime.modified();
}
}
superClass.buildBufferObjects(ren, actor);
// apply shift + scale to primitives AFTER vtkOpenGLPolyDataMapper.buildBufferObjects
// so that the Glyph3DMapper gets the last say in the shift + scale
if (useShiftAndScale) {
for (let i = primTypes.Start; i < primTypes.End; i++) {
model.primitives[i].getCABO().setCoordShiftAndScale(coordShift, coordScale);
}
}
};
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
normalMatrix: null,
mcpcMatrix: null,
mcwcMatrix: null
};
// ----------------------------------------------------------------------------
function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
// Inheritance
vtkOpenGLPolyDataMapper.extend(publicAPI, model, initialValues);
model.tmpMat3 = mat3.identity(new Float64Array(9));
model.normalMatrix = mat3.identity(new Float64Array(9));
model.mcpcMatrix = mat4.identity(new Float64Array(16));
model.mcvcMatrix = mat4.identity(new Float64Array(16));
model.tmpColor = [];
model.glyphBOBuildTime = {};
obj(model.glyphBOBuildTime, {
mtime: 0
});
// Object methods
vtkOpenGLGlyph3DMapper(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = newInstance$1(extend, 'vtkOpenGLGlyph3DMapper');
// ----------------------------------------------------------------------------
var vtkGlyph3DMapper = {
newInstance,
extend
};
// Register ourself to OpenGL backend if imported
registerOverride('vtkGlyph3DMapper', newInstance);
export { vtkGlyph3DMapper as default, extend, newInstance };