UNPKG

molstar

Version:

A comprehensive macromolecular library.

254 lines (253 loc) 13.4 kB
"use strict"; /** * Copyright (c) 2018-2025 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author David Sehnal <david.sehnal@gmail.com> * @author Gianluca Tomasello <giagitom@gmail.com> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.createColors = createColors; exports.createValueColor = createValueColor; exports.createTextureColor = createTextureColor; exports.createGridColor = createGridColor; const mol_util_1 = require("../../mol-util"); const util_1 = require("../../mol-gl/renderable/util"); const color_1 = require("../../mol-util/color"); const linear_algebra_1 = require("../../mol-math/linear-algebra"); const location_1 = require("../../mol-model/location"); const texture_1 = require("../../mol-gl/webgl/texture"); function createColors(locationIt, positionIt, colorTheme, colorData) { var _a; const data = _createColors(locationIt, positionIt, colorTheme, colorData); if (colorTheme.palette) { mol_util_1.ValueCell.updateIfChanged(data.dUsePalette, true); const [min, max] = colorTheme.palette.domain || [0, 1]; mol_util_1.ValueCell.update(data.uPaletteDomain, linear_algebra_1.Vec2.set(data.uPaletteDomain.ref.value, min, max)); mol_util_1.ValueCell.update(data.uPaletteDefault, color_1.Color.toVec3Normalized(data.uPaletteDefault.ref.value, (_a = colorTheme.palette.defaultColor) !== null && _a !== void 0 ? _a : (0, color_1.Color)(0xCCCCCC))); updatePaletteTexture(colorTheme.palette, data.tPalette); } else { mol_util_1.ValueCell.updateIfChanged(data.dUsePalette, false); } return data; } function _createColors(locationIt, positionIt, colorTheme, colorData) { switch (colorTheme.granularity) { case 'uniform': return createUniformColor(locationIt, colorTheme.color, colorData); case 'instance': return locationIt.nonInstanceable ? createGroupColor(locationIt, colorTheme.color, colorData) : createInstanceColor(locationIt, colorTheme.color, colorData); case 'group': return createGroupColor(locationIt, colorTheme.color, colorData); case 'groupInstance': return createGroupInstanceColor(locationIt, colorTheme.color, colorData); case 'vertex': return createVertexColor(positionIt, colorTheme.color, colorData); case 'vertexInstance': return createVertexInstanceColor(positionIt, colorTheme.color, colorData); case 'volume': return createGridColor(colorTheme.grid, 'volume', colorData); case 'volumeInstance': return createGridColor(colorTheme.grid, 'volumeInstance', colorData); case 'direct': return createDirectColor(colorData); } } function updatePaletteTexture(palette, cell) { let isSynced = true; const texture = cell.ref.value; if (palette.colors.length !== texture.width || texture.filter !== palette.filter) { isSynced = false; } else { const data = texture.array; let o = 0; for (const c of palette.colors) { const [r, g, b] = color_1.Color.toRgb(c); if (data[o++] !== r || data[o++] !== g || data[o++] !== b) { isSynced = false; break; } } } if (isSynced) return; const array = new Uint8Array(palette.colors.length * 3); let o = 0; for (const c of palette.colors) { const [r, g, b] = color_1.Color.toRgb(c); array[o++] = r; array[o++] = g; array[o++] = b; } mol_util_1.ValueCell.update(cell, { array, height: 1, width: palette.colors.length, filter: palette.filter }); } // function createValueColor(value, colorData) { if (colorData) { mol_util_1.ValueCell.update(colorData.uColor, color_1.Color.toVec3Normalized(colorData.uColor.ref.value, value)); mol_util_1.ValueCell.updateIfChanged(colorData.dColorType, 'uniform'); return colorData; } else { return { uColor: mol_util_1.ValueCell.create(color_1.Color.toVec3Normalized((0, linear_algebra_1.Vec3)(), value)), tColor: mol_util_1.ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), tColorGrid: mol_util_1.ValueCell.create((0, texture_1.createNullTexture)()), uPaletteDomain: mol_util_1.ValueCell.create(linear_algebra_1.Vec2.create(0, 1)), uPaletteDefault: mol_util_1.ValueCell.create((0, linear_algebra_1.Vec3)()), tPalette: mol_util_1.ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), uColorTexDim: mol_util_1.ValueCell.create(linear_algebra_1.Vec2.create(1, 1)), uColorGridDim: mol_util_1.ValueCell.create(linear_algebra_1.Vec3.create(1, 1, 1)), uColorGridTransform: mol_util_1.ValueCell.create(linear_algebra_1.Vec4.create(0, 0, 0, 1)), dColorType: mol_util_1.ValueCell.create('uniform'), dUsePalette: mol_util_1.ValueCell.create(false), }; } } /** Creates color uniform */ function createUniformColor(locationIt, color, colorData) { return createValueColor(color(location_1.NullLocation, false), colorData); } // function createTextureColor(colors, type, colorData) { if (colorData) { mol_util_1.ValueCell.update(colorData.tColor, colors); mol_util_1.ValueCell.update(colorData.uColorTexDim, linear_algebra_1.Vec2.create(colors.width, colors.height)); mol_util_1.ValueCell.updateIfChanged(colorData.dColorType, type); return colorData; } else { return { uColor: mol_util_1.ValueCell.create((0, linear_algebra_1.Vec3)()), tColor: mol_util_1.ValueCell.create(colors), tColorGrid: mol_util_1.ValueCell.create((0, texture_1.createNullTexture)()), uPaletteDomain: mol_util_1.ValueCell.create(linear_algebra_1.Vec2.create(0, 1)), uPaletteDefault: mol_util_1.ValueCell.create((0, linear_algebra_1.Vec3)()), tPalette: mol_util_1.ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), uColorTexDim: mol_util_1.ValueCell.create(linear_algebra_1.Vec2.create(colors.width, colors.height)), uColorGridDim: mol_util_1.ValueCell.create(linear_algebra_1.Vec3.create(1, 1, 1)), uColorGridTransform: mol_util_1.ValueCell.create(linear_algebra_1.Vec4.create(0, 0, 0, 1)), dColorType: mol_util_1.ValueCell.create(type), dUsePalette: mol_util_1.ValueCell.create(false), }; } } /** Creates color texture with color for each instance */ function createInstanceColor(locationIt, color, colorData) { const { instanceCount } = locationIt; const colors = (0, util_1.createTextureImage)(Math.max(1, instanceCount), 3, Uint8Array, colorData && colorData.tColor.ref.value.array); locationIt.reset(); while (locationIt.hasNext) { const { location, isSecondary, instanceIndex } = locationIt.move(); color_1.Color.toArray(color(location, isSecondary), colors.array, instanceIndex * 3); locationIt.skipInstance(); } return createTextureColor(colors, 'instance', colorData); } /** Creates color texture with color for each group (i.e. shared across instances) */ function createGroupColor(locationIt, color, colorData) { const { groupCount, hasLocation2 } = locationIt; const colors = (0, util_1.createTextureImage)(Math.max(1, groupCount * (hasLocation2 ? 2 : 1)), 3, Uint8Array, colorData && colorData.tColor.ref.value.array); locationIt.reset(); const indexMultiplier = hasLocation2 ? 6 : 3; while (locationIt.hasNext && !locationIt.isNextNewInstance) { const { location, location2, isSecondary, groupIndex } = locationIt.move(); color_1.Color.toArray(color(location, isSecondary), colors.array, groupIndex * indexMultiplier); if (hasLocation2) color_1.Color.toArray(color(location2, isSecondary), colors.array, groupIndex * indexMultiplier + 3); } return createTextureColor(colors, 'group', colorData); } /** Creates color texture with color for each group in each instance */ function createGroupInstanceColor(locationIt, color, colorData) { const { groupCount, instanceCount, hasLocation2 } = locationIt; const count = instanceCount * groupCount * (hasLocation2 ? 2 : 1); const colors = (0, util_1.createTextureImage)(Math.max(1, count), 3, Uint8Array, colorData && colorData.tColor.ref.value.array); locationIt.reset(); const indexMultiplier = hasLocation2 ? 6 : 3; while (locationIt.hasNext) { const { location, location2, isSecondary, index } = locationIt.move(); color_1.Color.toArray(color(location, isSecondary), colors.array, index * indexMultiplier); if (hasLocation2) color_1.Color.toArray(color(location2, isSecondary), colors.array, index * indexMultiplier + 3); } return createTextureColor(colors, 'groupInstance', colorData); } /** Creates color texture with color for each vertex (i.e. shared across instances) */ function createVertexColor(locationIt, color, colorData) { const { groupCount, stride } = locationIt; const colors = (0, util_1.createTextureImage)(Math.max(1, groupCount), 3, Uint8Array, colorData && colorData.tColor.ref.value.array); locationIt.reset(); locationIt.voidInstances(); while (locationIt.hasNext && !locationIt.isNextNewInstance) { const { location, isSecondary, groupIndex } = locationIt.move(); const c = color(location, isSecondary); for (let i = 0; i < stride; ++i) { color_1.Color.toArray(c, colors.array, (groupIndex + i) * 3); } } return createTextureColor(colors, 'vertex', colorData); } /** Creates color texture with color for each vertex in each instance */ function createVertexInstanceColor(locationIt, color, colorData) { const { groupCount, instanceCount, stride } = locationIt; const count = instanceCount * groupCount; const colors = (0, util_1.createTextureImage)(Math.max(1, count), 3, Uint8Array, colorData && colorData.tColor.ref.value.array); locationIt.reset(); while (locationIt.hasNext) { const { location, isSecondary, index } = locationIt.move(); const c = color(location, isSecondary); for (let i = 0; i < stride; ++i) { color_1.Color.toArray(c, colors.array, (index + i) * 3); } } return createTextureColor(colors, 'vertexInstance', colorData); } // function createGridColor(grid, type, colorData) { const { colors, dimension, transform } = grid; const width = colors.getWidth(); const height = colors.getHeight(); if (colorData) { mol_util_1.ValueCell.update(colorData.tColorGrid, colors); mol_util_1.ValueCell.update(colorData.uColorTexDim, linear_algebra_1.Vec2.create(width, height)); mol_util_1.ValueCell.update(colorData.uColorGridDim, linear_algebra_1.Vec3.clone(dimension)); mol_util_1.ValueCell.update(colorData.uColorGridTransform, linear_algebra_1.Vec4.clone(transform)); mol_util_1.ValueCell.updateIfChanged(colorData.dColorType, type); return colorData; } else { return { uColor: mol_util_1.ValueCell.create((0, linear_algebra_1.Vec3)()), tColor: mol_util_1.ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), tColorGrid: mol_util_1.ValueCell.create(colors), uPaletteDomain: mol_util_1.ValueCell.create(linear_algebra_1.Vec2.create(0, 1)), uPaletteDefault: mol_util_1.ValueCell.create((0, linear_algebra_1.Vec3)()), tPalette: mol_util_1.ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), uColorTexDim: mol_util_1.ValueCell.create(linear_algebra_1.Vec2.create(width, height)), uColorGridDim: mol_util_1.ValueCell.create(linear_algebra_1.Vec3.clone(dimension)), uColorGridTransform: mol_util_1.ValueCell.create(linear_algebra_1.Vec4.clone(transform)), dColorType: mol_util_1.ValueCell.create(type), dUsePalette: mol_util_1.ValueCell.create(false), }; } } // /** Creates direct color */ function createDirectColor(colorData) { if (colorData) { mol_util_1.ValueCell.updateIfChanged(colorData.dColorType, 'direct'); return colorData; } else { return { uColor: mol_util_1.ValueCell.create((0, linear_algebra_1.Vec3)()), tColor: mol_util_1.ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), tColorGrid: mol_util_1.ValueCell.create((0, texture_1.createNullTexture)()), uPaletteDomain: mol_util_1.ValueCell.create(linear_algebra_1.Vec2.create(0, 1)), uPaletteDefault: mol_util_1.ValueCell.create((0, linear_algebra_1.Vec3)()), tPalette: mol_util_1.ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), uColorTexDim: mol_util_1.ValueCell.create(linear_algebra_1.Vec2.create(1, 1)), uColorGridDim: mol_util_1.ValueCell.create(linear_algebra_1.Vec3.create(1, 1, 1)), uColorGridTransform: mol_util_1.ValueCell.create(linear_algebra_1.Vec4.create(0, 0, 0, 1)), dColorType: mol_util_1.ValueCell.create('direct'), dUsePalette: mol_util_1.ValueCell.create(false), }; } }