Select Git revision
size-data.ts
size-data.ts 5.63 KiB
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ValueCell } from '../../mol-util';
import { Vec2 } from '../../mol-math/linear-algebra';
import { TextureImage, createTextureImage } from '../../mol-gl/renderable/util';
import { LocationIterator } from '../util/location-iterator';
import { Location, NullLocation } from '../../mol-model/location';
import { SizeTheme } from '../../mol-theme/size';
import { Geometry } from './geometry';
import { decodeFloatRGB, encodeFloatRGBtoArray } from '../../mol-util/float-packing';
export type SizeType = 'uniform' | 'instance' | 'group' | 'groupInstance'
export type SizeData = {
uSize: ValueCell<number>,
tSize: ValueCell<TextureImage<Uint8Array>>,
uSizeTexDim: ValueCell<Vec2>,
dSizeType: ValueCell<string>,
}
export function createSizes(locationIt: LocationIterator, sizeTheme: SizeTheme<any>, sizeData?: SizeData): SizeData {
switch (Geometry.getGranularity(locationIt, sizeTheme.granularity)) {
case 'uniform': return createUniformSize(locationIt, sizeTheme.size, sizeData);
case 'group': return createGroupSize(locationIt, sizeTheme.size, sizeData);
case 'groupInstance': return createGroupInstanceSize(locationIt, sizeTheme.size, sizeData);
case 'instance': return createInstanceSize(locationIt, sizeTheme.size, sizeData);
}
}
export const sizeDataFactor = 100; // NOTE same factor is set in shaders
export function getMaxSize(sizeData: SizeData): number {
const type = sizeData.dSizeType.ref.value as SizeType;
switch (type) {
case 'uniform':
return sizeData.uSize.ref.value;
case 'instance':
case 'group':
case 'groupInstance':
let maxSize = 0;
const array = sizeData.tSize.ref.value.array;
for (let i = 0, il = array.length; i < il; i += 3) {
const value = decodeFloatRGB(array[i], array[i + 1], array[i + 2]);
if (maxSize < value) maxSize = value;
}
return maxSize / sizeDataFactor;
}
}
export type LocationSize = (location: Location) => number
const emptySizeTexture = { array: new Uint8Array(3), width: 1, height: 1 };
function createEmptySizeTexture() {
return {
tSize: ValueCell.create(emptySizeTexture),
uSizeTexDim: ValueCell.create(Vec2.create(1, 1))
};
}
export function createValueSize(value: number, sizeData?: SizeData): SizeData {
if (sizeData) {
ValueCell.update(sizeData.uSize, value);
ValueCell.updateIfChanged(sizeData.dSizeType, 'uniform');
return sizeData;
} else {
return {