PixelSpaceCallbackMapper

Introduction

vtkPixelSpaceCallbackMapper iterates over the points of its input dataset,
using the transforms from the active camera to compute the screen coordinates
of each point.

callback:

Set/Get the callback function the mapper will call, during the rendering
proces, with the screen coords of the points in dataset. The callback
function will have the following parameters:

// An array of 4-component arrays, in the index-order of the datasets points
coords: [
[screenx, screeny, screenz, zBufValue],
...
]

// The active camera of the renderer, in case you may need to compute alternate
// depth values for your dataset points. Using the sphere mapper in your
// application code is one example where this may be useful, so that you can
// account for that mapper's radius when doing depth checks.
camera: vtkCamera

// The aspect ratio of the render view and depthBuffer
aspect: float

// A Uint8Array of size width * height * 4, where the zbuffer values are
// encoded in the red and green components of each pixel. This will only
// be non-null after you call setUseZValues(true) on the mapper before
// rendering.
depthBuffer: Uint8Array

useZValues

Set/Get whether or not this mapper should capture the zbuffer during
rendering. Useful for allowing depth checks in the application code.

Source

index.js
import { mat4, vec3 } from 'gl-matrix';

import macro from 'vtk.js/Sources/macro';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';

// ----------------------------------------------------------------------------
// vtkPixelSpaceCallbackMapper methods
// ----------------------------------------------------------------------------

function vtkPixelSpaceCallbackMapper(publicAPI, model) {
model.classHierarchy.push('vtkPixelSpaceCallbackMapper');

if (!model.callback) {
model.callback = () => {};
}

publicAPI.invokeCallback = (
dataset,
camera,
aspect,
windowSize,
depthValues
) => {
if (!model.callback) {
return;
}

const matrix = camera.getCompositeProjectionMatrix(aspect, -1, 1);
mat4.transpose(matrix, matrix);

const dataPoints = dataset.getPoints();
const result = vec3.fromValues(0, 0, 0);
const width = windowSize.usize;
const height = windowSize.vsize;
const hw = width / 2;
const hh = height / 2;
const coords = [];

for (let pidx = 0; pidx < dataPoints.getNumberOfPoints(); pidx += 1) {
const point = dataPoints.getPoint(pidx);
result[0] = point[0];
result[1] = point[1];
result[2] = point[2];
vec3.transformMat4(result, result, matrix);
const coord = [result[0] * hw + hw, result[1] * hh + hh, result[2], 0];

if (depthValues) {
const linIdx = Math.floor(coord[1]) * width + Math.floor(coord[0]);
const idx = linIdx * 4;
const r = depthValues[idx] / 255;
const g = depthValues[idx + 1] / 255;
const z = (r * 256 + g) / 257;
coord[3] = z * 2 - 1;
}

coords.push(coord);
}

model.callback(coords, camera, aspect, depthValues, [width, height]);
};
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
callback: null,
useZValues: false,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);

// Inheritance
vtkMapper.extend(publicAPI, model, initialValues);

macro.setGet(publicAPI, model, ['callback', 'useZValues']);

// Object methods
vtkPixelSpaceCallbackMapper(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(
extend,
'vtkPixelSpaceCallbackMapper'
);

// ----------------------------------------------------------------------------

export default { newInstance, extend };