diff --git a/src/mol-geo/geometry/direct-volume/direct-volume.ts b/src/mol-geo/geometry/direct-volume/direct-volume.ts index 3d53792792404f20ae8e093d836f2a271b01133a..76458adaa367d96f27246924f0b2fa11821fe7a3 100644 --- a/src/mol-geo/geometry/direct-volume/direct-volume.ts +++ b/src/mol-geo/geometry/direct-volume/direct-volume.ts @@ -8,8 +8,8 @@ import { RuntimeContext } from 'mol-task' import { ValueCell } from 'mol-util' import { Sphere3D, Box3D } from 'mol-math/geometry' import { paramDefaultValues, RangeParam, SelectParam, TextParam } from 'mol-view/parameter'; -import { DirectVolume2dValues, DirectVolumeBaseValues, DirectVolume3dValues } from 'mol-gl/renderable/direct-volume'; -import { Vec3, Vec2, Mat4 } from 'mol-math/linear-algebra'; +import { DirectVolumeValues } from 'mol-gl/renderable/direct-volume'; +import { Vec3, Mat4 } from 'mol-math/linear-algebra'; import { Box } from '../../primitive/box'; import { getControlPointsFromString, createTransferFunctionTexture } from './transfer-function'; import { Texture } from 'mol-gl/webgl/texture'; @@ -22,7 +22,10 @@ import { Geometry } from '../geometry'; const VolumeBox = Box() const RenderModeOptions = [['isosurface', 'Isosurface'], ['volume', 'Volume']] as [string, string][] -interface DirectVolumeBase { +export interface DirectVolume { + readonly kind: 'direct-volume', + readonly gridTexture: ValueCell<Texture>, + readonly gridTextureDim: ValueCell<Vec3>, readonly gridDimension: ValueCell<Vec3>, readonly bboxSize: ValueCell<Vec3> readonly bboxMin: ValueCell<Vec3> @@ -33,74 +36,12 @@ interface DirectVolumeBase { boundingSphere?: Sphere3D } -const BaseParams = { - ...Geometry.Params, - isoValueAbsolute: RangeParam('Iso Value Absolute', '', 0.22, -1, 1, 0.01), - isoValueRelative: RangeParam('Iso Value Relative', '', 2, -10, 10, 0.1), - renderMode: SelectParam('Render Mode', '', 'isosurface', RenderModeOptions), - controlPoints: TextParam('Control Points', '', '0.19:0.1, 0.2:0.5, 0.21:0.1, 0.4:0.3'), -} -const DefaultBaseProps = paramDefaultValues(BaseParams) -type BaseProps = typeof DefaultBaseProps - -async function createBaseValues(ctx: RuntimeContext, directVolume: DirectVolumeBase, transform: TransformData, locationIt: LocationIterator, props: BaseProps): Promise<DirectVolumeBaseValues> { - const { instanceCount, groupCount } = locationIt - const color = await createColors(ctx, locationIt, props) - const marker = createMarkers(instanceCount * groupCount) - - const counts = { drawCount: VolumeBox.indices.length, groupCount, instanceCount } - - const { bboxSize, bboxMin, bboxMax, gridDimension, transform: gridTransform } = directVolume - - const controlPoints = getControlPointsFromString(props.controlPoints) - const transferTex = createTransferFunctionTexture(controlPoints) - - const maxSteps = Math.ceil(Vec3.magnitude(gridDimension.ref.value)) * 2 - - return { - ...color, - ...marker, - ...transform, - ...Geometry.createValues(props, counts), - - aPosition: ValueCell.create(VolumeBox.vertices as Float32Array), - elements: ValueCell.create(VolumeBox.indices as Uint32Array), - - uIsoValue: ValueCell.create(props.isoValueAbsolute), - uBboxMin: bboxMin, - uBboxMax: bboxMax, - uBboxSize: bboxSize, - dMaxSteps: ValueCell.create(maxSteps), - uTransform: gridTransform, - uGridDim: gridDimension, - dRenderMode: ValueCell.create(props.renderMode), - tTransferTex: transferTex, - } -} - -function updateBaseValues(values: DirectVolumeBaseValues, props: BaseProps) { - ValueCell.updateIfChanged(values.uIsoValue, props.isoValueAbsolute) - ValueCell.updateIfChanged(values.uAlpha, props.alpha) - ValueCell.updateIfChanged(values.dUseFog, props.useFog) - ValueCell.updateIfChanged(values.dRenderMode, props.renderMode) - - const controlPoints = getControlPointsFromString(props.controlPoints) - createTransferFunctionTexture(controlPoints, values.tTransferTex) -} - -// 2d - -export interface DirectVolume2d extends DirectVolumeBase { - readonly kind: 'direct-volume-2d', - readonly gridTexture: ValueCell<Texture>, - readonly gridTextureDim: ValueCell<Vec2>, -} - -export namespace DirectVolume2d { - export function create(bbox: Box3D, gridDimension: Vec3, transform: Mat4, texture: Texture, directVolume?: DirectVolume2d): DirectVolume2d { +export namespace DirectVolume { + export function create(bbox: Box3D, gridDimension: Vec3, transform: Mat4, texture: Texture, directVolume?: DirectVolume): DirectVolume { + const { width, height, depth } = texture if (directVolume) { ValueCell.update(directVolume.gridDimension, gridDimension) - ValueCell.update(directVolume.gridTextureDim, Vec2.set(directVolume.gridTextureDim.ref.value, texture.width, texture.height)) + ValueCell.update(directVolume.gridTextureDim, Vec3.set(directVolume.gridTextureDim.ref.value, width, height, depth)) ValueCell.update(directVolume.bboxMin, bbox.min) ValueCell.update(directVolume.bboxMax, bbox.max) ValueCell.update(directVolume.bboxSize, Vec3.sub(directVolume.bboxSize.ref.value, bbox.max, bbox.min)) @@ -108,10 +49,10 @@ export namespace DirectVolume2d { return directVolume } else { return { - kind: 'direct-volume-2d' as 'direct-volume-2d', + kind: 'direct-volume', gridDimension: ValueCell.create(gridDimension), gridTexture: ValueCell.create(texture), - gridTextureDim: ValueCell.create(Vec2.create(texture.width, texture.height)), + gridTextureDim: ValueCell.create(Vec3.create(width, height, depth)), bboxMin: ValueCell.create(bbox.min), bboxMax: ValueCell.create(bbox.max), bboxSize: ValueCell.create(Vec3.sub(Vec3.zero(), bbox.max, bbox.min)), @@ -120,78 +61,68 @@ export namespace DirectVolume2d { } } - export function createEmpty(directVolume?: DirectVolume2d): DirectVolume2d { - return {} as DirectVolume2d // TODO + export function createEmpty(directVolume?: DirectVolume): DirectVolume { + return {} as DirectVolume // TODO } - export const Params = BaseParams + export const Params = { + ...Geometry.Params, + isoValueAbsolute: RangeParam('Iso Value Absolute', '', 0.22, -1, 1, 0.01), + isoValueRelative: RangeParam('Iso Value Relative', '', 2, -10, 10, 0.1), + renderMode: SelectParam('Render Mode', '', 'isosurface', RenderModeOptions), + controlPoints: TextParam('Control Points', '', '0.19:0.1, 0.2:0.5, 0.21:0.1, 0.4:0.3'), + } export const DefaultProps = paramDefaultValues(Params) export type Props = typeof DefaultProps - export async function createValues(ctx: RuntimeContext, directVolume: DirectVolume2d, transform: TransformData, locationIt: LocationIterator, props: Props): Promise<DirectVolume2dValues> { + export async function createValues(ctx: RuntimeContext, directVolume: DirectVolume, transform: TransformData, locationIt: LocationIterator, props: Props): Promise<DirectVolumeValues> { const { gridTexture, gridTextureDim } = directVolume - return { - ...await createBaseValues(ctx, directVolume, transform, locationIt, props), - dGridTexType: ValueCell.create('2d'), - uGridTexDim: gridTextureDim, - tGridTex: gridTexture, - } - } - - export function updateValues(values: DirectVolume2dValues, props: Props) { - updateBaseValues(values, props) - } -} - -// 3d + const { instanceCount, groupCount } = locationIt + const color = await createColors(ctx, locationIt, props) + const marker = createMarkers(instanceCount * groupCount) -export interface DirectVolume3d extends DirectVolumeBase { - readonly kind: 'direct-volume-3d', - readonly gridTexture: ValueCell<Texture>, -} - -export namespace DirectVolume3d { - export function create(bbox: Box3D, gridDimension: Vec3, transform: Mat4, texture: Texture, directVolume?: DirectVolume3d): DirectVolume3d { - if (directVolume) { - ValueCell.update(directVolume.gridDimension, gridDimension) - ValueCell.update(directVolume.bboxMin, bbox.min) - ValueCell.update(directVolume.bboxMax, bbox.max) - ValueCell.update(directVolume.bboxSize, Vec3.sub(directVolume.bboxSize.ref.value, bbox.max, bbox.min)) - ValueCell.update(directVolume.transform, transform) - return directVolume - } else { - return { - kind: 'direct-volume-3d' as 'direct-volume-3d', - gridDimension: ValueCell.create(gridDimension), - gridTexture: ValueCell.create(texture), - bboxMin: ValueCell.create(bbox.min), - bboxMax: ValueCell.create(bbox.max), - bboxSize: ValueCell.create(Vec3.sub(Vec3.zero(), bbox.max, bbox.min)), - transform: ValueCell.create(transform), - } - } - } + const counts = { drawCount: VolumeBox.indices.length, groupCount, instanceCount } - export function createEmpty(directVolume?: DirectVolume3d): DirectVolume3d { - return {} as DirectVolume3d // TODO - } + const { bboxSize, bboxMin, bboxMax, gridDimension, transform: gridTransform } = directVolume - export const Params = BaseParams - export const DefaultProps = paramDefaultValues(Params) - export type Props = typeof DefaultProps + const controlPoints = getControlPointsFromString(props.controlPoints) + const transferTex = createTransferFunctionTexture(controlPoints) - export async function createValues(ctx: RuntimeContext, directVolume: DirectVolume3d, transform: TransformData, locationIt: LocationIterator, props: Props): Promise<DirectVolume3dValues> { - const { gridTexture } = directVolume + const maxSteps = Math.ceil(Vec3.magnitude(gridDimension.ref.value)) * 2 return { - ...await createBaseValues(ctx, directVolume, transform, locationIt, props), - dGridTexType: ValueCell.create('3d'), + ...color, + ...marker, + ...transform, + ...Geometry.createValues(props, counts), + + aPosition: ValueCell.create(VolumeBox.vertices as Float32Array), + elements: ValueCell.create(VolumeBox.indices as Uint32Array), + + uIsoValue: ValueCell.create(props.isoValueAbsolute), + uBboxMin: bboxMin, + uBboxMax: bboxMax, + uBboxSize: bboxSize, + dMaxSteps: ValueCell.create(maxSteps), + uTransform: gridTransform, + uGridDim: gridDimension, + dRenderMode: ValueCell.create(props.renderMode), + tTransferTex: transferTex, + + dGridTexType: ValueCell.create(gridTexture.ref.value.depth > 0 ? '3d' : '2d'), + uGridTexDim: gridTextureDim, tGridTex: gridTexture, } } - export function updateValues(values: DirectVolume3dValues, props: Props) { - updateBaseValues(values, props) + export function updateValues(values: DirectVolumeValues, props: Props) { + ValueCell.updateIfChanged(values.uIsoValue, props.isoValueAbsolute) + ValueCell.updateIfChanged(values.uAlpha, props.alpha) + ValueCell.updateIfChanged(values.dUseFog, props.useFog) + ValueCell.updateIfChanged(values.dRenderMode, props.renderMode) + + const controlPoints = getControlPointsFromString(props.controlPoints) + createTransferFunctionTexture(controlPoints, values.tTransferTex) } } \ No newline at end of file diff --git a/src/mol-geo/geometry/geometry.ts b/src/mol-geo/geometry/geometry.ts index b8920b17a75cd1b065fe7d909d9cf592c6a955d9..d9e7e2f0d212972df39a0fc4638fa956a40b58e3 100644 --- a/src/mol-geo/geometry/geometry.ts +++ b/src/mol-geo/geometry/geometry.ts @@ -17,7 +17,7 @@ import { SizeType } from './size-data'; import { Lines } from './lines/lines'; import { paramDefaultValues, RangeParam, BooleanParam, SelectParam, ColorParam, StructureParam, ValueParam } from 'mol-view/parameter' import { Structure } from 'mol-model/structure'; -import { DirectVolume2d, DirectVolume3d } from './direct-volume/direct-volume'; +import { DirectVolume } from './direct-volume/direct-volume'; import { Context } from 'mol-gl/webgl/context'; // @@ -43,8 +43,7 @@ export type GeometryKindType = { 'mesh': Mesh, 'points': Points, 'lines': Lines, - 'direct-volume-2d': DirectVolume2d, - 'direct-volume-3d': DirectVolume3d + 'direct-volume': DirectVolume, } export type GeometryKind = keyof GeometryKindType export type Geometry = Helpers.ValueOf<GeometryKindType> @@ -55,8 +54,7 @@ export namespace Geometry { case 'mesh': return geometry.triangleCount * 3 case 'points': return geometry.pointCount case 'lines': return geometry.lineCount * 2 * 3 - case 'direct-volume-2d': return 12 * 3 - case 'direct-volume-3d': return 12 * 3 + case 'direct-volume': return 12 * 3 } } diff --git a/src/mol-geo/representation/structure/index.ts b/src/mol-geo/representation/structure/index.ts index f1b8d592bac06a5b8e403e4b82be4e2410c53467..b5c094fc2efb84ec161a72296e1d7015d7076a16 100644 --- a/src/mol-geo/representation/structure/index.ts +++ b/src/mol-geo/representation/structure/index.ts @@ -14,7 +14,7 @@ import { Mesh } from '../../geometry/mesh/mesh'; import { Points } from '../../geometry/points/points'; import { Lines } from '../../geometry/lines/lines'; import { SelectParam, paramDefaultValues } from 'mol-view/parameter'; -import { DirectVolume2d, DirectVolume3d } from '../../geometry/direct-volume/direct-volume'; +import { DirectVolume } from '../../geometry/direct-volume/direct-volume'; export interface StructureRepresentation<P extends RepresentationProps = {}> extends Representation<Structure, P> { } @@ -48,8 +48,7 @@ export const DefaultStructureLinesProps = paramDefaultValues(StructureLinesParam export type StructureLinesProps = typeof DefaultStructureLinesProps export const StructureDirectVolumeParams = { - ...DirectVolume2d.Params, - ...DirectVolume3d.Params, + ...DirectVolume.Params, ...StructureParams, } export const DefaultStructureDirectVolumeProps = paramDefaultValues(StructureDirectVolumeParams) diff --git a/src/mol-geo/representation/structure/units-visual.ts b/src/mol-geo/representation/structure/units-visual.ts index 8961e75cc9fd6e871b94c601a8f890c197e339a2..3f7a963ec67e96884b75331d9a12b3514bbeca40 100644 --- a/src/mol-geo/representation/structure/units-visual.ts +++ b/src/mol-geo/representation/structure/units-visual.ts @@ -15,7 +15,7 @@ import { LocationIterator } from '../../util/location-iterator'; import { Mesh } from '../../geometry/mesh/mesh'; import { MarkerAction, applyMarkerAction, createMarkers } from '../../geometry/marker-data'; import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci'; -import { MeshRenderObject, PointsRenderObject, LinesRenderObject, DirectVolume2dRenderObject, DirectVolume3dRenderObject } from 'mol-gl/render-object'; +import { MeshRenderObject, PointsRenderObject, LinesRenderObject, DirectVolumeRenderObject } from 'mol-gl/render-object'; import { createUnitsMeshRenderObject, createUnitsPointsRenderObject, createUnitsTransform, createUnitsLinesRenderObject, createUnitsDirectVolumeRenderObject } from './visual/util/common'; import { deepEqual, ValueCell, UUID } from 'mol-util'; import { Interval } from 'mol-data/int'; @@ -25,7 +25,7 @@ import { createColors, ColorProps } from '../../geometry/color-data'; import { createSizes, SizeProps } from '../../geometry/size-data'; import { Lines } from '../../geometry/lines/lines'; import { MultiSelectParam, paramDefaultValues } from 'mol-view/parameter'; -import { DirectVolume2d, DirectVolume3d } from '../../geometry/direct-volume/direct-volume'; +import { DirectVolume } from '../../geometry/direct-volume/direct-volume'; export const UnitKindInfo = { 'atomic': {}, @@ -526,15 +526,15 @@ export const UnitsDirectVolumeParams = { } export const DefaultUnitsDirectVolumeProps = paramDefaultValues(UnitsDirectVolumeParams) export type UnitsDirectVolumeProps = typeof DefaultUnitsDirectVolumeProps -export interface UnitsDirectVolumeVisualBuilder<P extends UnitsDirectVolumeProps> extends UnitsVisualBuilder<P, DirectVolume2d | DirectVolume3d> { } +export interface UnitsDirectVolumeVisualBuilder<P extends UnitsDirectVolumeProps> extends UnitsVisualBuilder<P, DirectVolume> { } export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builder: UnitsDirectVolumeVisualBuilder<P>): UnitsVisual<P> { const { defaultProps, createGeometry, createLocationIterator, getLoci, mark, setUpdateState } = builder const updateState = VisualUpdateState.create() - let renderObject: DirectVolume2dRenderObject | DirectVolume3dRenderObject | undefined + let renderObject: DirectVolumeRenderObject | undefined let currentProps: P - let directVolume: DirectVolume2d | DirectVolume3d + let directVolume: DirectVolume let currentGroup: Unit.SymmetryGroup let currentStructure: Structure let locationIt: LocationIterator @@ -551,9 +551,7 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builde currentConformationId = Unit.conformationId(unit) directVolume = includesUnitKind(currentProps.unitKinds, unit) ? await createGeometry(ctx, unit, currentStructure, currentProps, directVolume) - : (webgl.isWebGL2 ? - DirectVolume2d.createEmpty(directVolume as DirectVolume2d) : - DirectVolume3d.createEmpty(directVolume as DirectVolume3d)) + : DirectVolume.createEmpty(directVolume) // TODO create empty location iterator when not in unitKinds locationIt = createLocationIterator(group) @@ -598,9 +596,7 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builde if (updateState.createGeometry) { directVolume = includesUnitKind(newProps.unitKinds, unit) ? await createGeometry(ctx, unit, currentStructure, newProps, directVolume) - : (webgl.isWebGL2 ? - DirectVolume2d.createEmpty(directVolume as DirectVolume2d) : - DirectVolume3d.createEmpty(directVolume as DirectVolume3d)) + : DirectVolume.createEmpty(directVolume) updateState.updateColor = true } @@ -608,11 +604,7 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builde await createColors(ctx, locationIt, newProps, renderObject.values) } - if (renderObject.type === 'direct-volume-2d') { - DirectVolume2d.updateValues(renderObject.values, newProps) - } else { - DirectVolume3d.updateValues(renderObject.values, newProps) - } + DirectVolume.updateValues(renderObject.values, newProps) updateRenderableState(renderObject.state, newProps) currentProps = newProps diff --git a/src/mol-geo/representation/structure/visual/gaussian-density-volume.ts b/src/mol-geo/representation/structure/visual/gaussian-density-volume.ts index 932cdad4e138e4a19f03360ecd814e456179ee92..94bcd294a930ba8498e324a9eea043890225a34b 100644 --- a/src/mol-geo/representation/structure/visual/gaussian-density-volume.ts +++ b/src/mol-geo/representation/structure/visual/gaussian-density-volume.ts @@ -11,9 +11,9 @@ import { UnitsDirectVolumeVisual, UnitsDirectVolumeParams } from '../units-visua import { StructureElementIterator, getElementLoci, markElement } from './util/element'; import { GaussianDensityProps, GaussianDensityParams, computeUnitGaussianDensityTexture } from 'mol-model/structure/structure/unit/gaussian-density'; import { paramDefaultValues } from 'mol-view/parameter'; -import { DirectVolume2d, DirectVolume3d } from '../../../geometry/direct-volume/direct-volume'; +import { DirectVolume } from '../../../geometry/direct-volume/direct-volume'; -async function createGaussianDensityVolume(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianDensityProps, directVolume?: DirectVolume2d | DirectVolume3d): Promise<DirectVolume2d | DirectVolume3d> { +async function createGaussianDensityVolume(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianDensityProps, directVolume?: DirectVolume): Promise<DirectVolume> { const { webgl } = props if (webgl === undefined) throw new Error('createGaussianDensityVolume requires `webgl` in props') @@ -22,11 +22,7 @@ async function createGaussianDensityVolume(ctx: RuntimeContext, unit: Unit, stru const densityTextureData = await computeUnitGaussianDensityTexture(unit, p, oldTexture).runInContext(ctx) const { transform, texture, bbox, gridDimension } = densityTextureData - directVolume = texture.depth === 0 ? - DirectVolume2d.create(bbox, gridDimension, transform, texture, directVolume as DirectVolume2d) : - DirectVolume3d.create(bbox, gridDimension, transform, texture, directVolume as DirectVolume3d) - - return directVolume; + return DirectVolume.create(bbox, gridDimension, transform, texture, directVolume) } export const GaussianDensityVolumeParams = { diff --git a/src/mol-geo/representation/structure/visual/util/common.ts b/src/mol-geo/representation/structure/visual/util/common.ts index f4784ed423e8a528644bbfd412aab0c13fb522c8..09b4ffdaa96503b11c6dd4f8d458585ebf92e99f 100644 --- a/src/mol-geo/representation/structure/visual/util/common.ts +++ b/src/mol-geo/representation/structure/visual/util/common.ts @@ -8,14 +8,14 @@ import { Unit, Structure } from 'mol-model/structure'; import { LocationIterator } from '../../../../util/location-iterator'; import { Mesh } from '../../../../geometry/mesh/mesh'; import { StructureProps } from '../..'; -import { createMeshRenderObject, createPointsRenderObject, createLinesRenderObject, createDirectVolume2dRenderObject, createDirectVolume3dRenderObject } from 'mol-gl/render-object'; +import { createMeshRenderObject, createPointsRenderObject, createLinesRenderObject, createDirectVolumeRenderObject } from 'mol-gl/render-object'; import { RuntimeContext } from 'mol-task'; import { TransformData, createIdentityTransform, createTransform } from '../../../../geometry/transform-data'; import { Points } from '../../../../geometry/points/points'; import { createRenderableState } from '../../../../geometry/geometry'; import { Mat4 } from 'mol-math/linear-algebra'; import { Lines } from '../../../../geometry/lines/lines'; -import { DirectVolume2d, DirectVolume3d } from '../../../../geometry/direct-volume/direct-volume'; +import { DirectVolume } from '../../../../geometry/direct-volume/direct-volume'; export function createUnitsTransform({ units }: Unit.SymmetryGroup, transformData?: TransformData) { const unitCount = units.length @@ -63,19 +63,17 @@ type StructureLinesProps = Lines.Props & StructureProps export async function createUnitsLinesRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, lines: Lines, locationIt: LocationIterator, props: StructureLinesProps) { const transform = createUnitsTransform(group) const values = await Lines.createValues(ctx, lines, transform, locationIt, props) - console.log('values', values) const state = createRenderableState(props) return createLinesRenderObject(values, state) } // direct-volume -type StructureDirectVolumeProps = DirectVolume2d.Props & DirectVolume3d.Props & StructureProps +type StructureDirectVolumeProps = DirectVolume.Props & StructureProps -export async function createUnitsDirectVolumeRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, directVolume: DirectVolume2d | DirectVolume3d, locationIt: LocationIterator, props: StructureDirectVolumeProps) { +export async function createUnitsDirectVolumeRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, directVolume: DirectVolume, locationIt: LocationIterator, props: StructureDirectVolumeProps) { const transform = createUnitsTransform(group) + const values = await DirectVolume.createValues(ctx, directVolume, transform, locationIt, props) const state = createRenderableState(props) - return directVolume.kind === 'direct-volume-2d' ? - createDirectVolume2dRenderObject(await DirectVolume2d.createValues(ctx, directVolume, transform, locationIt, props), state) : - createDirectVolume3dRenderObject(await DirectVolume3d.createValues(ctx, directVolume, transform, locationIt, props), state) + return createDirectVolumeRenderObject(values, state) } \ No newline at end of file diff --git a/src/mol-geo/representation/volume/direct-volume.ts b/src/mol-geo/representation/volume/direct-volume.ts index 2a70a4ba92ced244dd3149799c80960539196e02..1dd1e9446bcad8bab3e1f2918d6fb1acd4917277 100644 --- a/src/mol-geo/representation/volume/direct-volume.ts +++ b/src/mol-geo/representation/volume/direct-volume.ts @@ -7,17 +7,16 @@ import { VolumeData } from 'mol-model/volume' import { RuntimeContext } from 'mol-task' import { VolumeVisual, VolumeRepresentation } from '.'; -import { DirectVolume2dRenderObject, createDirectVolume2dRenderObject, DirectVolume3dRenderObject, createDirectVolume3dRenderObject } from 'mol-gl/render-object'; +import { DirectVolumeRenderObject, createDirectVolumeRenderObject } from 'mol-gl/render-object'; import { PickingId } from '../../geometry/picking'; import { MarkerAction } from '../../geometry/marker-data'; import { Loci, EmptyLoci } from 'mol-model/loci'; import { createRenderableState, updateRenderableState, Geometry } from '../../geometry/geometry'; import { paramDefaultValues } from 'mol-view/parameter'; -import { DirectVolume2d, DirectVolume3d } from '../../geometry/direct-volume/direct-volume'; +import { DirectVolume } from '../../geometry/direct-volume/direct-volume'; import { Vec3, Mat4 } from 'mol-math/linear-algebra'; import { Box3D } from 'mol-math/geometry'; import { Context } from 'mol-gl/webgl/context'; -import { DirectVolume3dValues, DirectVolume2dValues } from 'mol-gl/renderable/direct-volume'; import { createTexture } from 'mol-gl/webgl/texture'; import { LocationIterator } from 'mol-geo/util/location-iterator'; import { NullLocation } from 'mol-model/location'; @@ -86,7 +85,7 @@ function createVolumeTexture2d(volume: VolumeData, maxTextureSize: number) { return textureImage } -export function createDirectVolume2d(ctx: RuntimeContext, webgl: Context, volume: VolumeData, directVolume?: DirectVolume2d) { +export function createDirectVolume2d(ctx: RuntimeContext, webgl: Context, volume: VolumeData, directVolume?: DirectVolume) { const gridDimension = volume.data.space.dimensions as Vec3 const textureImage = createVolumeTexture2d(volume, webgl.maxTextureSize) // debugTexture(createImageData(textureImage.array, textureImage.width, textureImage.height), 1/3) @@ -99,7 +98,7 @@ export function createDirectVolume2d(ctx: RuntimeContext, webgl: Context, volume const texture = directVolume ? directVolume.gridTexture.ref.value : createTexture(webgl, 'image-uint8', 'rgba', 'ubyte', 'linear') texture.load(textureImage) - return DirectVolume2d.create(bbox, dim, transform, texture, directVolume) + return DirectVolume.create(bbox, dim, transform, texture, directVolume) } // 3d volume texture @@ -126,7 +125,7 @@ function createVolumeTexture3d(volume: VolumeData) { return textureVolume } -export function createDirectVolume3d(ctx: RuntimeContext, webgl: Context, volume: VolumeData, directVolume?: DirectVolume3d) { +export function createDirectVolume3d(ctx: RuntimeContext, webgl: Context, volume: VolumeData, directVolume?: DirectVolume) { const gridDimension = volume.data.space.dimensions as Vec3 const textureVolume = createVolumeTexture3d(volume) const transform = VolumeData.getGridToCartesianTransform(volume) @@ -135,23 +134,23 @@ export function createDirectVolume3d(ctx: RuntimeContext, webgl: Context, volume const texture = directVolume ? directVolume.gridTexture.ref.value : createTexture(webgl, 'volume-uint8', 'rgba', 'ubyte', 'linear') texture.load(textureVolume) - return DirectVolume3d.create(bbox, gridDimension, transform, texture, directVolume) + return DirectVolume.create(bbox, gridDimension, transform, texture, directVolume) } // export const DirectVolumeParams = { ...Geometry.Params, - ...DirectVolume2d.Params + ...DirectVolume.Params } export const DefaultDirectVolumeProps = paramDefaultValues(DirectVolumeParams) export type DirectVolumeProps = typeof DefaultDirectVolumeProps export function DirectVolumeVisual(): VolumeVisual<DirectVolumeProps> { let currentProps = DefaultDirectVolumeProps - let renderObject: DirectVolume2dRenderObject | DirectVolume3dRenderObject + let renderObject: DirectVolumeRenderObject let currentVolume: VolumeData - let directVolume: DirectVolume2d | DirectVolume3d + let directVolume: DirectVolume async function create(ctx: RuntimeContext, volume: VolumeData, props: Partial<DirectVolumeProps> = {}) { const { webgl } = props @@ -167,14 +166,13 @@ export function DirectVolumeVisual(): VolumeVisual<DirectVolumeProps> { const transform = createIdentityTransform() if (webgl.isWebGL2) { - console.log('creating 3d volume') - directVolume = await createDirectVolume3d(ctx, webgl, volume, directVolume as DirectVolume3d) - const values = await DirectVolume3d.createValues(ctx, directVolume as DirectVolume3d, transform, locationIt, currentProps) - renderObject = createDirectVolume3dRenderObject(values, state) + directVolume = await createDirectVolume3d(ctx, webgl, volume, directVolume) + const values = await DirectVolume.createValues(ctx, directVolume, transform, locationIt, currentProps) + renderObject = createDirectVolumeRenderObject(values, state) } else { - directVolume = await createDirectVolume2d(ctx, webgl, volume, directVolume as DirectVolume2d) - const values = await DirectVolume2d.createValues(ctx, directVolume as DirectVolume2d, transform, locationIt, currentProps) - renderObject = createDirectVolume2dRenderObject(values, state) + directVolume = await createDirectVolume2d(ctx, webgl, volume, directVolume) + const values = await DirectVolume.createValues(ctx, directVolume, transform, locationIt, currentProps) + renderObject = createDirectVolumeRenderObject(values, state) } } @@ -187,11 +185,7 @@ export function DirectVolumeVisual(): VolumeVisual<DirectVolumeProps> { // newProps.isoValueAbsolute = VolumeIsoValue.calcAbsolute(currentVolume.dataStats, props.isoValueRelative) } - if (webgl.isWebGL2) { - DirectVolume3d.updateValues(renderObject.values as DirectVolume3dValues, newProps) - } else { - DirectVolume2d.updateValues(renderObject.values as DirectVolume2dValues, newProps) - } + DirectVolume.updateValues(renderObject.values, newProps) updateRenderableState(renderObject.state, newProps) currentProps = newProps diff --git a/src/mol-gl/render-object.ts b/src/mol-gl/render-object.ts index f600d65a55be3f7acba20bfe1782bb821abc3df3..34dff9145a52c963fec6d56525bb790c7138c361 100644 --- a/src/mol-gl/render-object.ts +++ b/src/mol-gl/render-object.ts @@ -9,7 +9,7 @@ import { RenderableValues } from './renderable/schema'; import { idFactory } from 'mol-util/id-factory'; import { Context } from './webgl/context'; import { GaussianDensityValues, GaussianDensityRenderable } from './renderable/gaussian-density'; -import { DirectVolume2dValues, DirectVolume2dRenderable, DirectVolume3dValues, DirectVolume3dRenderable } from './renderable/direct-volume'; +import { DirectVolumeValues, DirectVolumeRenderable } from './renderable/direct-volume'; const getNextId = idFactory(0, 0x7FFFFFFF) @@ -18,10 +18,9 @@ export interface MeshRenderObject extends BaseRenderObject { type: 'mesh', value export interface PointsRenderObject extends BaseRenderObject { type: 'points', values: PointsValues } export interface LinesRenderObject extends BaseRenderObject { type: 'lines', values: LinesValues } export interface GaussianDensityRenderObject extends BaseRenderObject { type: 'gaussian-density', values: GaussianDensityValues } -export interface DirectVolume2dRenderObject extends BaseRenderObject { type: 'direct-volume-2d', values: DirectVolume2dValues } -export interface DirectVolume3dRenderObject extends BaseRenderObject { type: 'direct-volume-3d', values: DirectVolume3dValues } +export interface DirectVolumeRenderObject extends BaseRenderObject { type: 'direct-volume', values: DirectVolumeValues } -export type RenderObject = MeshRenderObject | PointsRenderObject | LinesRenderObject | GaussianDensityRenderObject | DirectVolume2dRenderObject | DirectVolume3dRenderObject +export type RenderObject = MeshRenderObject | PointsRenderObject | LinesRenderObject | GaussianDensityRenderObject | DirectVolumeRenderObject // @@ -37,11 +36,8 @@ export function createLinesRenderObject(values: LinesValues, state: RenderableSt export function createGaussianDensityRenderObject(values: GaussianDensityValues, state: RenderableState): GaussianDensityRenderObject { return { id: getNextId(), type: 'gaussian-density', values, state } } -export function createDirectVolume2dRenderObject(values: DirectVolume2dValues, state: RenderableState): DirectVolume2dRenderObject { - return { id: getNextId(), type: 'direct-volume-2d', values, state } -} -export function createDirectVolume3dRenderObject(values: DirectVolume3dValues, state: RenderableState): DirectVolume3dRenderObject { - return { id: getNextId(), type: 'direct-volume-3d', values, state } +export function createDirectVolumeRenderObject(values: DirectVolumeValues, state: RenderableState): DirectVolumeRenderObject { + return { id: getNextId(), type: 'direct-volume', values, state } } export function createRenderable(ctx: Context, o: RenderObject): Renderable<any> { @@ -50,7 +46,6 @@ export function createRenderable(ctx: Context, o: RenderObject): Renderable<any> case 'points': return PointsRenderable(ctx, o.id, o.values, o.state) case 'lines': return LinesRenderable(ctx, o.id, o.values, o.state) case 'gaussian-density': return GaussianDensityRenderable(ctx, o.id, o.values, o.state) - case 'direct-volume-2d': return DirectVolume2dRenderable(ctx, o.id, o.values, o.state) - case 'direct-volume-3d': return DirectVolume3dRenderable(ctx, o.id, o.values, o.state) + case 'direct-volume': return DirectVolumeRenderable(ctx, o.id, o.values, o.state) } } \ No newline at end of file diff --git a/src/mol-gl/renderable/direct-volume.ts b/src/mol-gl/renderable/direct-volume.ts index 2f043942bdcba998defbbdc4ff89185847dec904..0f9ddcbbe2f9c3a47952449055f2d40b8d73e2e5 100644 --- a/src/mol-gl/renderable/direct-volume.ts +++ b/src/mol-gl/renderable/direct-volume.ts @@ -11,7 +11,7 @@ import { AttributeSpec, Values, UniformSpec, GlobalUniformSchema, InternalSchema import { DirectVolumeShaderCode } from '../shader-code'; import { ValueCell } from 'mol-util'; -export const DirectVolumeBaseSchema = { +export const DirectVolumeSchema = { aColor: AttributeSpec('float32', 3, 0), // TODO not used, just for type checking uColor: UniformSpec('v3'), uColorTexDim: UniformSpec('v2'), @@ -45,54 +45,24 @@ export const DirectVolumeBaseSchema = { uGridDim: UniformSpec('v3'), dRenderMode: DefineSpec('string', ['isosurface', 'volume']), tTransferTex: TextureSpec('image-uint8', 'rgba', 'ubyte', 'linear'), + + dGridTexType: DefineSpec('string', ['2d', '3d']), + uGridTexDim: UniformSpec('v3'), + tGridTex: TextureSpec('texture', 'rgba', 'ubyte', 'linear'), } -export type DirectVolumeBaseSchema = typeof DirectVolumeBaseSchema -export type DirectVolumeBaseValues = Values<DirectVolumeBaseSchema> +export type DirectVolumeSchema = typeof DirectVolumeSchema +export type DirectVolumeValues = Values<DirectVolumeSchema> -function getInternalValues(ctx: Context, id: number): InternalValues { - return { +export function DirectVolumeRenderable(ctx: Context, id: number, values: DirectVolumeValues, state: RenderableState): Renderable<DirectVolumeValues> { + const schema = { ...GlobalUniformSchema, ...InternalSchema, ...DirectVolumeSchema } + const internalValues: InternalValues = { uObjectId: ValueCell.create(id) } -} - -function DirectVolumeRenderable<T extends DirectVolumeBaseValues, S extends DirectVolumeBaseSchema>(ctx: Context, id: number, values: T, state: RenderableState, schema: S): Renderable<T> { - const fullSchema = Object.assign({}, GlobalUniformSchema, InternalSchema, schema) - const internalValues = getInternalValues(ctx, id) - const fullValues = Object.assign({}, values, internalValues) const shaderCode = DirectVolumeShaderCode - const renderItem = createRenderItem(ctx, 'triangles', shaderCode, fullSchema, fullValues) + const renderItem = createRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }) const renderable = createRenderable(renderItem, values, state); Object.defineProperty(renderable, 'opaque', { get: () => false }); return renderable -} - -// via 2d texture - -export const DirectVolume2dSchema = { - ...DirectVolumeBaseSchema, - dGridTexType: DefineSpec('string', ['2d']), - uGridTexDim: UniformSpec('v2'), - tGridTex: TextureSpec('texture2d', 'rgba', 'ubyte', 'linear'), -} -export type DirectVolume2dSchema = typeof DirectVolume2dSchema -export type DirectVolume2dValues = Values<DirectVolume2dSchema> - -export function DirectVolume2dRenderable(ctx: Context, id: number, values: DirectVolume2dValues, state: RenderableState): Renderable<DirectVolume2dValues> { - return DirectVolumeRenderable(ctx, id, values, state, DirectVolume2dSchema) -} - -// via 3d texture - -export const DirectVolume3dSchema = { - ...DirectVolumeBaseSchema, - dGridTexType: DefineSpec('string', ['3d']), - tGridTex: TextureSpec('texture3d', 'rgba', 'ubyte', 'linear'), -} -export type DirectVolume3dSchema = typeof DirectVolume3dSchema -export type DirectVolume3dValues = Values<DirectVolume3dSchema> - -export function DirectVolume3dRenderable(ctx: Context, id: number, values: DirectVolume3dValues, state: RenderableState): Renderable<DirectVolume3dValues> { - return DirectVolumeRenderable(ctx, id, values, state, DirectVolume3dSchema) } \ No newline at end of file diff --git a/src/mol-gl/renderable/gaussian-density.ts b/src/mol-gl/renderable/gaussian-density.ts index 5d2a4f5c5736d5cc42c62df713131964f64459d8..e07143628e3072a56b856b868be844bae86f65d7 100644 --- a/src/mol-gl/renderable/gaussian-density.ts +++ b/src/mol-gl/renderable/gaussian-density.ts @@ -25,9 +25,9 @@ export const GaussianDensitySchema = { uBboxMax: UniformSpec('v3'), uBboxSize: UniformSpec('v3'), uGridDim: UniformSpec('v3'), - uGridTexDim: UniformSpec('v2'), + uGridTexDim: UniformSpec('v3'), uAlpha: UniformSpec('f'), - tMinDistanceTex: TextureSpec('texture3d', 'rgba', 'ubyte', 'nearest'), + tMinDistanceTex: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'), dGridTexType: DefineSpec('string', ['2d', '3d']), dCalcType: DefineSpec('string', ['density', 'minDistance', 'groupId']), diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index 42a09454eaceeaf2c5072cd8849f588b51ba1109..0e5826819aece71768921e486e6402fdba701bf2 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/src/mol-gl/renderable/schema.ts @@ -43,6 +43,7 @@ export type KindValue = { 'image-float32': TextureImage<Float32Array> 'volume-uint8': TextureVolume<Uint8Array> 'volume-float32': TextureVolume<Float32Array> + 'texture': Texture 'texture2d': Texture 'texture3d': Texture diff --git a/src/mol-gl/shader/direct-volume.frag b/src/mol-gl/shader/direct-volume.frag index c6411cda132603ddbe799fa838e39267c67a2fe0..be043efe5976a30d8fda7721da0bba2dd4e38632 100644 --- a/src/mol-gl/shader/direct-volume.frag +++ b/src/mol-gl/shader/direct-volume.frag @@ -29,7 +29,7 @@ uniform sampler2D tMarker; #if defined(dGridTexType_2d) precision mediump sampler2D; uniform sampler2D tGridTex; - uniform vec2 uGridTexDim; + uniform vec3 uGridTexDim; #elif defined(dGridTexType_3d) precision mediump sampler3D; uniform sampler3D tGridTex; @@ -64,11 +64,11 @@ const float albedo = 0.95; #if defined(dGridTexType_2d) vec4 textureVal(vec3 pos) { - return texture3dFrom2dLinear(tGridTex, pos, uGridDim, uGridTexDim); + return texture3dFrom2dLinear(tGridTex, pos, uGridDim, uGridTexDim.xy); } vec4 textureGroup(vec3 pos) { vec3 nearestPos = floor(pos * uGridDim + 0.5) / uGridDim + 0.5 / uGridDim; - return texture3dFrom2dNearest(tGridTex, nearestPos, uGridDim, uGridTexDim); + return texture3dFrom2dNearest(tGridTex, nearestPos, uGridDim, uGridTexDim.xy); } #elif defined(dGridTexType_3d) vec4 textureVal(vec3 pos) { diff --git a/src/mol-gl/shader/gaussian-density.frag b/src/mol-gl/shader/gaussian-density.frag index 0f6dfe324e629fb4e33c7b91349acdc261853758..ce7bacf7acdf79d87af242c8d8e20379041f83dd 100644 --- a/src/mol-gl/shader/gaussian-density.frag +++ b/src/mol-gl/shader/gaussian-density.frag @@ -13,7 +13,7 @@ varying float vRadius; #if defined(dGridTexType_2d) precision mediump sampler2D; uniform sampler2D tMinDistanceTex; - uniform vec2 uGridTexDim; + uniform vec3 uGridTexDim; #elif defined(dGridTexType_3d) precision highp sampler3D; uniform sampler3D tMinDistanceTex; @@ -36,7 +36,7 @@ uniform float uAlpha; #if defined(dCalcType_groupId) #if defined(dGridTexType_2d) vec4 textureMinDist(vec3 pos) { - return texture3dFrom2dNearest(tMinDistanceTex, pos, uGridDim, uGridTexDim); + return texture3dFrom2dNearest(tMinDistanceTex, pos, uGridDim, uGridTexDim.xy); } #elif defined(dGridTexType_3d) vec4 textureMinDist(vec3 pos) { diff --git a/src/mol-gl/webgl/render-item.ts b/src/mol-gl/webgl/render-item.ts index ec3d687d23fba19bbe89a1d09ed2e00ce6b87a60..d2f59286b1510bfa5a39281e59e9b6373d50a6e4 100644 --- a/src/mol-gl/webgl/render-item.ts +++ b/src/mol-gl/webgl/render-item.ts @@ -227,8 +227,8 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S Object.keys(textureValues).forEach(k => { const value = textureValues[k] if (value.ref.version !== versions[k]) { - // update of textures with kind 'texture2d' or 'texture3d' is done externally - if (schema[k].kind !== 'texture2d' && schema[k].kind !== 'texture3d') { + // update of textures with kind 'texture' is done externally + if (schema[k].kind !== 'texture') { // console.log('texture version changed, uploading image', k) textures[k].load(value.ref.value as TextureImage<any> | TextureVolume<any>) versions[k] = value.ref.version @@ -246,8 +246,8 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S deleteVertexArray(ctx, vertexArrays[k]) }) Object.keys(textures).forEach(k => { - // lifetime of textures with kind 'texture2d' or 'texture3d' is defined externally - if (schema[k].kind !== 'texture2d' && schema[k].kind !== 'texture3d') { + // lifetime of textures with kind 'texture' is defined externally + if (schema[k].kind !== 'texture') { textures[k].destroy() } }) diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts index e51497592f8d242be50a2ab3b594afdbac5229c5..c7bbe7ab70fe380ebb94b67fb69727674229765d 100644 --- a/src/mol-gl/webgl/texture.ts +++ b/src/mol-gl/webgl/texture.ts @@ -19,8 +19,7 @@ export type TextureKindValue = { 'image-float32': TextureImage<Float32Array> 'volume-uint8': TextureVolume<Uint8Array> 'volume-float32': TextureVolume<Float32Array> - 'texture2d': Texture - 'texture3d': Texture + 'texture': Texture } export type TextureValueType = Helpers.ValueOf<TextureKindValue> export type TextureKind = keyof TextureKindValue @@ -35,13 +34,11 @@ export function getTarget(ctx: Context, kind: TextureKind): number { switch (kind) { case 'image-uint8': return gl.TEXTURE_2D case 'image-float32': return gl.TEXTURE_2D - case 'texture2d': return gl.TEXTURE_2D } if (isWebGL2(gl)) { switch (kind) { case 'volume-uint8': return gl.TEXTURE_3D case 'volume-float32': return gl.TEXTURE_3D - case 'texture3d': return gl.TEXTURE_3D } } throw new Error('unknown texture kind') @@ -252,7 +249,7 @@ export function createTextures(ctx: Context, schema: RenderableSchema, values: T Object.keys(schema).forEach((k, i) => { const spec = schema[k] if (spec.type === 'texture') { - if (spec.kind === 'texture2d' || spec.kind === 'texture3d') { + if (spec.kind === 'texture') { textures[k] = values[k].ref.value as Texture } else { const texture = createTexture(ctx, spec.kind, spec.format, spec.dataType, spec.filter) diff --git a/src/mol-math/geometry/gaussian-density/gpu.ts b/src/mol-math/geometry/gaussian-density/gpu.ts index 62f9a56d26dd5e5a379af2c5a06e71eaf96c061f..2c8a8ddda83090c2ac8a4f1e6675d3aaeb99b2a1 100644 --- a/src/mol-math/geometry/gaussian-density/gpu.ts +++ b/src/mol-math/geometry/gaussian-density/gpu.ts @@ -10,7 +10,7 @@ import { PositionData, DensityData, DensityTextureData } from '../common' import { Box3D } from '../../geometry' import { GaussianDensityProps, getDelta } from '../gaussian-density' import { OrderedSet } from 'mol-data/int' -import { Vec3, Tensor, Mat4, Vec2 } from '../../linear-algebra' +import { Vec3, Tensor, Mat4 } from '../../linear-algebra' import { GaussianDensityValues } from 'mol-gl/renderable/gaussian-density' import { ValueCell, defaults } from 'mol-util' import { RenderableState, Renderable } from 'mol-gl/renderable' @@ -241,7 +241,7 @@ function getGaussianDensityRenderObject(webgl: Context, drawCount: number, posit uBboxMax: ValueCell.create(box.max), uBboxSize: ValueCell.create(extent), uGridDim: ValueCell.create(dimensions), - uGridTexDim: ValueCell.create(Vec2.create(texDimX, texDimY)), + uGridTexDim: ValueCell.create(Vec3.create(texDimX, texDimY, 0)), uAlpha: ValueCell.create(smoothness), tMinDistanceTex: ValueCell.create(minDistanceTexture),