molstar
Version:
A comprehensive macromolecular library.
254 lines (253 loc) • 13.4 kB
JavaScript
"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),
};
}
}