UNPKG

@thewtex/vtk.js-esm

Version:

Visualization Toolkit for the Web

264 lines (210 loc) 12.3 kB
import _defineProperty from '@babel/runtime/helpers/defineProperty'; import { ObjectType } from './BufferObject/Constants.js'; import { newInstance as newInstance$1, vtkErrorMacro as vtkErrorMacro$1 } from '../../macro.js'; import vtkBufferObject from './BufferObject.js'; import { r as radiansFromDegrees } from '../../Common/Core/Math/index.js'; import vtkShaderProgram from './ShaderProgram.js'; import vtkOpenGLPolyDataMapper from './PolyDataMapper.js'; import { v as vtkSphereMapperVS } from './glsl/vtkSphereMapperVS.glsl.js'; import { v as vtkPolyDataFS } from './glsl/vtkPolyDataFS.glsl.js'; import { registerOverride } from './ViewNodeFactory.js'; import { m as multiply } from '../../vendor/gl-matrix/esm/mat4.js'; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var vtkErrorMacro = vtkErrorMacro$1; // ---------------------------------------------------------------------------- // vtkOpenGLSphereMapper methods // ---------------------------------------------------------------------------- function vtkOpenGLSphereMapper(publicAPI, model) { // Set our className model.classHierarchy.push('vtkOpenGLSphereMapper'); // Capture 'parentClass' api for internal use var superClass = _objectSpread({}, publicAPI); publicAPI.getShaderTemplate = function (shaders, ren, actor) { shaders.Vertex = vtkSphereMapperVS; shaders.Fragment = vtkPolyDataFS; shaders.Geometry = ''; }; publicAPI.replaceShaderValues = function (shaders, ren, actor) { var VSSource = shaders.Vertex; var FSSource = shaders.Fragment; VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Camera::Dec', ['uniform mat4 VCPCMatrix;\n', 'uniform mat4 MCVCMatrix;']).result; FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::PositionVC::Dec', ['varying vec4 vertexVCVSOutput;']).result; // we create vertexVC below, so turn off the default // implementation FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::PositionVC::Impl', ['vec4 vertexVC = vertexVCVSOutput;\n']).result; // for lights kit and positional the VCPC matrix is already defined // so don't redefine it var replacement = ['uniform float invertedDepth;\n', 'uniform int cameraParallel;\n', 'varying float radiusVCVSOutput;\n', 'varying vec3 centerVCVSOutput;\n', 'uniform mat4 VCPCMatrix;\n']; FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Normal::Dec', replacement).result; var fragString = ''; if (model.context.getExtension('EXT_frag_depth')) { fragString = 'gl_FragDepthEXT = (pos.z / pos.w + 1.0) / 2.0;\n'; } if (model.openGLRenderWindow.getWebgl2()) { fragString = 'gl_FragDepth = (pos.z / pos.w + 1.0) / 2.0;\n'; } FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Depth::Impl', [// compute the eye position and unit direction ' vec3 EyePos;\n', ' vec3 EyeDir;\n', ' if (cameraParallel != 0) {\n', ' EyePos = vec3(vertexVC.x, vertexVC.y, vertexVC.z + 3.0*radiusVCVSOutput);\n', ' EyeDir = vec3(0.0,0.0,-1.0); }\n', ' else {\n', ' EyeDir = vertexVC.xyz;\n', ' EyePos = vec3(0.0,0.0,0.0);\n', ' float lengthED = length(EyeDir);\n', ' EyeDir = normalize(EyeDir);\n', // we adjust the EyePos to be closer if it is too far away // to prevent floating point precision noise ' if (lengthED > radiusVCVSOutput*3.0) {\n', ' EyePos = vertexVC.xyz - EyeDir*3.0*radiusVCVSOutput; }\n', ' }\n', // translate to Sphere center ' EyePos = EyePos - centerVCVSOutput;\n', // scale to radius 1.0 ' EyePos = EyePos/radiusVCVSOutput;\n', // find the intersection ' float b = 2.0*dot(EyePos,EyeDir);\n', ' float c = dot(EyePos,EyePos) - 1.0;\n', ' float d = b*b - 4.0*c;\n', ' vec3 normalVCVSOutput = vec3(0.0,0.0,1.0);\n', ' if (d < 0.0) { discard; }\n', ' else {\n', ' float t = (-b - invertedDepth*sqrt(d))*0.5;\n', // compute the normal, for unit sphere this is just // the intersection point ' normalVCVSOutput = invertedDepth*normalize(EyePos + t*EyeDir);\n', // compute the intersection point in VC ' vertexVC.xyz = normalVCVSOutput*radiusVCVSOutput + centerVCVSOutput;\n', ' }\n', // compute the pixel's depth // ' normalVCVSOutput = vec3(0,0,1);\n' ' vec4 pos = VCPCMatrix * vertexVC;\n', fragString]).result; // Strip out the normal line -- the normal is computed as part of the depth FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Normal::Impl', '').result; if (model.haveSeenDepthRequest) { // special depth impl FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::ZBuffer::Impl', ['if (depthRequest == 1) {', 'float computedZ = (pos.z / pos.w + 1.0) / 2.0;', 'float iz = floor(computedZ * 65535.0 + 0.1);', 'float rf = floor(iz/256.0)/255.0;', 'float gf = mod(iz,256.0)/255.0;', 'gl_FragData[0] = vec4(rf, gf, 0.0, 1.0); }']).result; } shaders.Vertex = VSSource; shaders.Fragment = FSSource; superClass.replaceShaderValues(shaders, ren, actor); }; publicAPI.setMapperShaderParameters = function (cellBO, ren, actor) { if (cellBO.getCABO().getElementCount() && (model.VBOBuildTime > cellBO.getAttributeUpdateTime().getMTime() || cellBO.getShaderSourceTime().getMTime() > cellBO.getAttributeUpdateTime().getMTime()) && cellBO.getProgram().isAttributeUsed('offsetMC')) { if (!cellBO.getVAO().addAttributeArray(cellBO.getProgram(), cellBO.getCABO(), 'offsetMC', 12, // 12:this->VBO->ColorOffset+sizeof(float) cellBO.getCABO().getStride(), model.context.FLOAT, 2, false)) { vtkErrorMacro("Error setting 'offsetMC' in shader VAO."); } } if (cellBO.getProgram().isUniformUsed('invertedDepth')) { cellBO.getProgram().setUniformf('invertedDepth', model.invert ? -1.0 : 1.0); } superClass.setMapperShaderParameters(cellBO, ren, actor); }; publicAPI.setCameraShaderParameters = function (cellBO, ren, actor) { var program = cellBO.getProgram(); var cam = ren.getActiveCamera(); var keyMats = model.openGLCamera.getKeyMatrices(ren); if (program.isUniformUsed('VCPCMatrix')) { program.setUniformMatrix('VCPCMatrix', keyMats.vcpc); } if (program.isUniformUsed('MCVCMatrix')) { if (!actor.getIsIdentity()) { var actMats = model.openGLActor.getKeyMatrices(); var tmp4 = new Float64Array(16); multiply(tmp4, keyMats.wcvc, actMats.mcwc); program.setUniformMatrix('MCVCMatrix', tmp4); } else { program.setUniformMatrix('MCVCMatrix', keyMats.wcvc); } } if (program.isUniformUsed('cameraParallel')) { cellBO.getProgram().setUniformi('cameraParallel', cam.getParallelProjection()); } }; publicAPI.getOpenGLMode = function (rep, type) { return model.context.TRIANGLES; }; publicAPI.buildBufferObjects = function (ren, actor) { var poly = model.currentInput; if (poly === null) { return; } model.renderable.mapScalars(poly, 1.0); var c = model.renderable.getColorMapColors(); var vbo = model.primitives[model.primTypes.Tris].getCABO(); var pointData = poly.getPointData(); var points = poly.getPoints(); var numPoints = points.getNumberOfPoints(); var pointArray = points.getData(); var pointSize = 5; // x,y,z,orientation1,orientation2 var scales = null; if (model.renderable.getScaleArray() != null && pointData.hasArray(model.renderable.getScaleArray())) { scales = pointData.getArray(model.renderable.getScaleArray()).getData(); } var colorData = null; var colorComponents = 0; var packedUCVBO = null; if (c) { colorComponents = c.getNumberOfComponents(); vbo.setColorOffset(0); vbo.setColorBOStride(4); colorData = c.getData(); packedUCVBO = new Uint8Array(3 * numPoints * 4); if (!vbo.getColorBO()) { vbo.setColorBO(vtkBufferObject.newInstance()); } vbo.getColorBO().setOpenGLRenderWindow(model.openGLRenderWindow); } else if (vbo.getColorBO()) { vbo.setColorBO(null); } vbo.setColorComponents(colorComponents); var packedVBO = new Float32Array(pointSize * numPoints * 3); vbo.setStride(pointSize * 4); var cos30 = Math.cos(radiansFromDegrees(30.0)); var pointIdx = 0; var colorIdx = 0; // // Generate points and point data for sides // var vboIdx = 0; var ucIdx = 0; for (var i = 0; i < numPoints; ++i) { var radius = model.renderable.getRadius(); if (scales) { radius = scales[i]; } pointIdx = i * 3; packedVBO[vboIdx++] = pointArray[pointIdx++]; packedVBO[vboIdx++] = pointArray[pointIdx++]; packedVBO[vboIdx++] = pointArray[pointIdx++]; packedVBO[vboIdx++] = -2.0 * radius * cos30; packedVBO[vboIdx++] = -radius; if (colorData) { colorIdx = i * colorComponents; packedUCVBO[ucIdx++] = colorData[colorIdx]; packedUCVBO[ucIdx++] = colorData[colorIdx + 1]; packedUCVBO[ucIdx++] = colorData[colorIdx + 2]; packedUCVBO[ucIdx++] = colorData[colorIdx + 3]; } pointIdx = i * 3; packedVBO[vboIdx++] = pointArray[pointIdx++]; packedVBO[vboIdx++] = pointArray[pointIdx++]; packedVBO[vboIdx++] = pointArray[pointIdx++]; packedVBO[vboIdx++] = 2.0 * radius * cos30; packedVBO[vboIdx++] = -radius; if (colorData) { packedUCVBO[ucIdx++] = colorData[colorIdx]; packedUCVBO[ucIdx++] = colorData[colorIdx + 1]; packedUCVBO[ucIdx++] = colorData[colorIdx + 2]; packedUCVBO[ucIdx++] = colorData[colorIdx + 3]; } pointIdx = i * 3; packedVBO[vboIdx++] = pointArray[pointIdx++]; packedVBO[vboIdx++] = pointArray[pointIdx++]; packedVBO[vboIdx++] = pointArray[pointIdx++]; packedVBO[vboIdx++] = 0.0; packedVBO[vboIdx++] = 2.0 * radius; if (colorData) { packedUCVBO[ucIdx++] = colorData[colorIdx]; packedUCVBO[ucIdx++] = colorData[colorIdx + 1]; packedUCVBO[ucIdx++] = colorData[colorIdx + 2]; packedUCVBO[ucIdx++] = colorData[colorIdx + 3]; } } vbo.setElementCount(vboIdx / pointSize); vbo.upload(packedVBO, ObjectType.ARRAY_BUFFER); if (c) { vbo.getColorBO().upload(packedUCVBO, ObjectType.ARRAY_BUFFER); } model.VBOBuildTime.modified(); }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = {}; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Inheritance vtkOpenGLPolyDataMapper.extend(publicAPI, model, initialValues); // Object methods vtkOpenGLSphereMapper(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = newInstance$1(extend, 'vtkOpenGLSphereMapper'); // ---------------------------------------------------------------------------- var vtkSphereMapper = { newInstance: newInstance, extend: extend }; // Register ourself to OpenGL backend if imported registerOverride('vtkSphereMapper', newInstance); export default vtkSphereMapper; export { extend, newInstance };