UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

148 lines (136 loc) 4.38 kB
import { m as macro } from '../../../macros2.js'; import vtkTexture from '../../../Rendering/Core/Texture.js'; import { ARRAY_TYPES, COMPONENTS, BYTES, GL_SAMPLER } from './Constants.js'; const { vtkWarningMacro, vtkErrorMacro } = macro; /** * Get GL enum from sampler parameter * @param {*} parameter The sampler parameter * @returns The GL enum */ function getGLEnumFromSamplerParameter(parameter) { const GL_TEXTURE_MAG_FILTER = 0x2800; const GL_TEXTURE_MIN_FILTER = 0x2801; const GL_TEXTURE_WRAP_S = 0x2802; const GL_TEXTURE_WRAP_T = 0x2803; const Mapping = { magFilter: GL_TEXTURE_MAG_FILTER, minFilter: GL_TEXTURE_MIN_FILTER, wrapS: GL_TEXTURE_WRAP_S, wrapT: GL_TEXTURE_WRAP_T }; return Mapping[parameter]; } function getAccessorArrayTypeAndLength(accessor, bufferView) { const ArrayType = ARRAY_TYPES[accessor.componentType]; const components = COMPONENTS[accessor.type]; const bytesPerComponent = BYTES[accessor.componentType]; const length = accessor.count * components; const byteLength = accessor.count * components * bytesPerComponent; return { ArrayType, length, byteLength }; } /** * Resolves a URL based on the original path * @param {*} url The URL to resolve * @param {*} originalPath The original path to resolve the URL against * @returns The resolved URL or an empty string if the URL is invalid */ function resolveUrl(url, originalPath) { // Invalid URL if (typeof url !== 'string' || url === '') return ''; try { // Data URI if (url.startsWith('data:')) return url; // Blob URL if (url.startsWith('blob:')) return url; // Create URL object from the original path const baseUrl = new URL(originalPath); if (!baseUrl.pathname.includes('.') && !baseUrl.pathname.endsWith('/')) { baseUrl.pathname += '/'; } // Absolute URL (http://, https://, //) if (url.startsWith('http:') || url.startsWith('https:') || url.startsWith('//')) { return new URL(url, baseUrl).href; } // Host Relative URL if (url.startsWith('/')) { return new URL(url, baseUrl).href; } // Relative URL return new URL(url, baseUrl).href; } catch (error) { vtkErrorMacro('Error resolving URL:', error); return ''; } } /** * Loads image from buffer or URI * @param {*} image * @returns */ async function loadImage(image) { if (image.bufferView) { const blob = new Blob([image.bufferView.data], { type: image.mimeType }); const bitmap = await createImageBitmap(blob, { colorSpaceConversion: 'none', imageOrientation: 'flipY' }); return bitmap; } if (image.uri) { vtkWarningMacro('Falling back to image uri', image.uri); return new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = 'Anonymous'; img.onload = () => { resolve(img); }; img.onerror = reject; img.src = image.uri; }); } return null; } /** * * @param {*} image * @param {*} sampler * @param {*} extensions * @returns */ function createVTKTextureFromGLTFTexture(image, sampler, extensions) { const texture = vtkTexture.newInstance(); // Apply sampler settings if (sampler) { if ('wrapS' in sampler && 'wrapT' in sampler || 'minFilter' in sampler && 'magFilter' in sampler) { if (sampler.wrapS === GL_SAMPLER.CLAMP_TO_EDGE || sampler.wrapT === GL_SAMPLER.CLAMP_TO_EDGE) { texture.setRepeat(false); texture.setEdgeClamp(true); } else if (sampler.wrapS === GL_SAMPLER.REPEAT || sampler.wrapT === GL_SAMPLER.REPEAT) { texture.setRepeat(true); texture.setEdgeClamp(false); } else { vtkWarningMacro('Mirrored texture wrapping is not supported!'); } const linearFilters = [GL_SAMPLER.LINEAR, GL_SAMPLER.LINEAR_MIPMAP_NEAREST, GL_SAMPLER.NEAREST_MIPMAP_LINEAR, GL_SAMPLER.LINEAR_MIPMAP_LINEAR]; if (linearFilters.includes(sampler.minFilter) || linearFilters.includes(sampler.magFilter)) { texture.setInterpolate(true); } } else { texture.setMipLevel(8); texture.setInterpolate(true); texture.setEdgeClamp(true); } } texture.setImageBitmap(image); return texture; } export { createVTKTextureFromGLTFTexture, getAccessorArrayTypeAndLength, getGLEnumFromSamplerParameter, loadImage, resolveUrl };