const THREE = require('three'); /** * Texture array object for holding array of images into * texures unit that can be used by other texture primitives. * * @class * @author Alan Wu * @return {TextureArray} */ const TextureArray = function () { (require('./texture').Texture).call(this); this.isTextureArray = true; /** * Read images from an array containg src locations. * * @async * @param {Array} srcArrays - List of source location of the images. */ this.loadFromImages = async (srcArrays) => { let w = 1; let h = 1; let d = 0; if (srcArrays && srcArrays.length) { this.isLoading = true; const image = new Image(); image.crossOrigin = "Anonymous"; const canvas = document.createElement("canvas"); let length = 0; const dataStacks = new Array(srcArrays.length); for (let i = 0; i < srcArrays.length; i++) { const data = await this.imageToUint8Array(this, image, srcArrays[i], canvas); if (data && data.array) { w = data.width; h = data.height; dataStacks[d] = data.array; length += dataStacks[d].length; d++; } } const fullArray = new Uint8Array(length); length = 0; dataStacks.forEach(data => { fullArray.set(data, length); length += data.length; }); this.impl = new THREE.DataTexture2DArray(fullArray, w, h, d); this.size = { width: w, height: h, depth: d }; this.isLoading = false; this.impl.needsUpdate = true; } } /** * Get and create the material containing shaders and the textures. * The texture must be read and ready before calling this function. * * * @param {Object} options - Customise the material with the options object. * @param {String} options.fs - string of the fragment shader used for * visualisation. * @param {String} options.vs - string of the vertex shader used for * visualisation. * @param {Object} options.uniforms - Containing the data to be passed into the shaders. * @param {String} options.glslVersion - Version of glsl used for compile this shader. * */ this.getMaterial = (options) => { if (this.impl) { let material = undefined; if (options) { if (options.vs && options.fs) { let transparent = true; if (options.transparent) transparent = options.transparent; let side = THREE.FrontSide; if (options.side) side = options.side; material = new THREE.ShaderMaterial({ transparent, uniforms: options.uniforms, vertexShader: options.vs, fragmentShader: options.fs, side }); if (options.glslVersion) { material.glslVersion = options.glslVersion; } } } else { material = new THREE.MeshBasicMaterial({ color: new THREE.Color(1, 1, 1), transparent: false, opacity: 1.0, map: this.impl, side: THREE.DoubleSide }); } if (material) { material.needsUpdate = true; return material; } } } } TextureArray.prototype = Object.create((require('./texture').Texture).prototype); exports.TextureArray = TextureArray;