UNPKG

molstar

Version:

A comprehensive macromolecular library.

164 lines (163 loc) 8.43 kB
/** * Copyright (c) 2018-2025 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { ValueCell } from '../../mol-util'; import { LocationIterator } from '../util/location-iterator'; import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { createIdentityTransform } from './transform-data'; import { ColorNames } from '../../mol-util/color/names'; import { NullLocation } from '../../mol-model/location'; import { UniformColorTheme } from '../../mol-theme/color/uniform'; import { UniformSizeTheme } from '../../mol-theme/size/uniform'; import { smoothstep } from '../../mol-math/interpolate'; import { Material } from '../../mol-util/material'; import { Clip } from '../../mol-util/clip'; import { Vec3 } from '../../mol-math/linear-algebra/3d/vec3'; import { Vec4 } from '../../mol-math/linear-algebra/3d/vec4'; export const VisualQualityInfo = { 'custom': {}, 'auto': {}, 'highest': {}, 'higher': {}, 'high': {}, 'medium': {}, 'low': {}, 'lower': {}, 'lowest': {}, }; export const VisualQualityNames = Object.keys(VisualQualityInfo); export const VisualQualityOptions = PD.arrayToOptions(VisualQualityNames); // export const ColorSmoothingParams = { smoothColors: PD.MappedStatic('auto', { auto: PD.Group({}), on: PD.Group({ resolutionFactor: PD.Numeric(2, { min: 0.5, max: 6, step: 0.1 }), sampleStride: PD.Numeric(3, { min: 1, max: 12, step: 1 }), }), off: PD.Group({}) }), }; export function hasColorSmoothingProp(props) { return !!props.smoothColors; } export function getColorSmoothingProps(smoothColors, preferSmoothing, resolution) { if ((smoothColors.name === 'on' || (smoothColors.name === 'auto' && preferSmoothing)) && resolution && resolution < 3) { let stride = 3; if (smoothColors.name === 'on') { resolution *= smoothColors.params.resolutionFactor; stride = smoothColors.params.sampleStride; } else { // https://graphtoy.com/?f1(x,t)=(2-smoothstep(0,1.1,x))*x&coords=0.7,0.6,1.8 resolution *= 2 - smoothstep(0, 1.1, resolution); resolution = Math.max(0.5, resolution); if (resolution > 1.2) stride = 2; } return { resolution, stride }; } ; } // export var BaseGeometry; (function (BaseGeometry) { BaseGeometry.MaterialCategory = { category: 'Material' }; BaseGeometry.ShadingCategory = { category: 'Shading' }; BaseGeometry.CullingLodCategory = { category: 'Culling & LOD' }; BaseGeometry.CustomQualityParamInfo = { category: 'Custom Quality', hideIf: (params) => typeof params.quality !== 'undefined' && params.quality !== 'custom' }; BaseGeometry.Params = { alpha: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }, { label: 'Opacity', isEssential: true, description: 'How opaque/transparent the representation is rendered.' }), quality: PD.Select('auto', VisualQualityOptions, { isEssential: true, description: 'Visual/rendering quality of the representation.' }), material: Material.getParam(), clip: PD.Group(Clip.Params), emissive: PD.Numeric(0, { min: 0, max: 1, step: 0.01 }), density: PD.Numeric(0.2, { min: 0, max: 1, step: 0.01 }, { description: 'Density value to estimate object thickness.' }), instanceGranularity: PD.Boolean(false, { description: 'Use instance granularity for marker, transparency, clipping, overpaint, substance data to save memory.' }), lod: PD.Vec3(Vec3(), undefined, { ...BaseGeometry.CullingLodCategory, description: 'Level of detail.', fieldLabels: { x: 'Min Distance', y: 'Max Distance', z: 'Overlap (Shader)' } }), cellSize: PD.Numeric(200, { min: 0, max: 5000, step: 100 }, { ...BaseGeometry.CullingLodCategory, description: 'Instance grid cell size.' }), batchSize: PD.Numeric(2000, { min: 0, max: 50000, step: 500 }, { ...BaseGeometry.CullingLodCategory, description: 'Instance grid batch size.' }), }; function createSimple(colorValue = ColorNames.grey, sizeValue = 1, transform) { if (!transform) transform = createIdentityTransform(); const locationIterator = LocationIterator(1, transform.instanceCount.ref.value, 1, () => NullLocation, false, () => false); const theme = { color: UniformColorTheme({}, { value: colorValue, lightness: 0, saturation: 0 }), size: UniformSizeTheme({}, { value: sizeValue }) }; return { transform, locationIterator, theme }; } BaseGeometry.createSimple = createSimple; function createValues(props, counts) { const clip = Clip.getClip(props.clip); return { alpha: ValueCell.create(props.alpha), uAlpha: ValueCell.create(props.alpha), uVertexCount: ValueCell.create(counts.vertexCount), uGroupCount: ValueCell.create(counts.groupCount), drawCount: ValueCell.create(counts.drawCount), uMetalness: ValueCell.create(props.material.metalness), uRoughness: ValueCell.create(props.material.roughness), uBumpiness: ValueCell.create(props.material.bumpiness), uEmissive: ValueCell.create(props.emissive), uDensity: ValueCell.create(props.density), dLightCount: ValueCell.create(1), dColorMarker: ValueCell.create(true), dClipObjectCount: ValueCell.create(clip.objects.count), dClipVariant: ValueCell.create(clip.variant), uClipObjectType: ValueCell.create(clip.objects.type), uClipObjectInvert: ValueCell.create(clip.objects.invert), uClipObjectPosition: ValueCell.create(clip.objects.position), uClipObjectRotation: ValueCell.create(clip.objects.rotation), uClipObjectScale: ValueCell.create(clip.objects.scale), uClipObjectTransform: ValueCell.create(clip.objects.transform), instanceGranularity: ValueCell.create(props.instanceGranularity), uLod: ValueCell.create(Vec4.create(props.lod[0], props.lod[1], props.lod[2], 0)), }; } BaseGeometry.createValues = createValues; function updateValues(values, props) { ValueCell.updateIfChanged(values.alpha, props.alpha); // `uAlpha` is set in renderable.render ValueCell.updateIfChanged(values.uMetalness, props.material.metalness); ValueCell.updateIfChanged(values.uRoughness, props.material.roughness); ValueCell.updateIfChanged(values.uBumpiness, props.material.bumpiness); ValueCell.updateIfChanged(values.uEmissive, props.emissive); ValueCell.updateIfChanged(values.uDensity, props.density); const clip = Clip.getClip(props.clip); ValueCell.updateIfChanged(values.dClipObjectCount, clip.objects.count); ValueCell.updateIfChanged(values.dClipVariant, clip.variant); ValueCell.update(values.uClipObjectType, clip.objects.type); ValueCell.update(values.uClipObjectInvert, clip.objects.invert); ValueCell.update(values.uClipObjectPosition, clip.objects.position); ValueCell.update(values.uClipObjectRotation, clip.objects.rotation); ValueCell.update(values.uClipObjectScale, clip.objects.scale); ValueCell.update(values.uClipObjectTransform, clip.objects.transform); ValueCell.updateIfChanged(values.instanceGranularity, props.instanceGranularity); ValueCell.update(values.uLod, Vec4.set(values.uLod.ref.value, props.lod[0], props.lod[1], props.lod[2], 0)); } BaseGeometry.updateValues = updateValues; function createRenderableState(props = {}) { const opaque = props.alpha === undefined ? true : props.alpha === 1; return { disposed: false, visible: true, alphaFactor: 1, pickable: true, colorOnly: false, opaque, writeDepth: opaque, }; } BaseGeometry.createRenderableState = createRenderableState; function updateRenderableState(state, props) { state.opaque = props.alpha * state.alphaFactor >= 1; state.writeDepth = state.opaque; } BaseGeometry.updateRenderableState = updateRenderableState; })(BaseGeometry || (BaseGeometry = {}));