diff --git a/src/mol-geo/representation/structure/representation/molecular-surface.ts b/src/mol-geo/representation/structure/representation/molecular-surface.ts index e9546a1e5439e097bb698bb29ee8d0ab9228efaf..be412fc1ea8096999ffcee1aa20601da73984709 100644 --- a/src/mol-geo/representation/structure/representation/molecular-surface.ts +++ b/src/mol-geo/representation/structure/representation/molecular-surface.ts @@ -9,7 +9,7 @@ import { GaussianSurfaceVisual, GaussianSurfaceParams } from '../visual/gaussian import { StructureRepresentation } from '../units-representation'; import { Structure } from 'mol-model/structure'; import { MarkerAction } from '../../../geometry/marker-data'; -import { Loci } from 'mol-model/loci'; +import { Loci, isEmptyLoci } from 'mol-model/loci'; import { PickingId } from '../../../geometry/picking'; import { Task } from 'mol-task'; import { GaussianWireframeVisual, GaussianWireframeParams } from '../visual/gaussian-surface-wireframe'; @@ -63,10 +63,24 @@ export function MolecularSurfaceRepresentation(): MolecularSurfaceRepresentation }) }, getLoci: (pickingId: PickingId) => { - return gaussianSurfaceRepr.getLoci(pickingId) + const surfaceLoci = gaussianSurfaceRepr.getLoci(pickingId) + const wireframeLoci = gaussianWireframeRepr.getLoci(pickingId) + const volumeLoci = gaussianVolumeRepr.getLoci(pickingId) + if (isEmptyLoci(surfaceLoci)) { + if (isEmptyLoci(wireframeLoci)) { + return volumeLoci + } else { + return wireframeLoci + } + } else { + return surfaceLoci + } }, mark: (loci: Loci, action: MarkerAction) => { - return gaussianSurfaceRepr.mark(loci, action) + const markSurfaceElement = gaussianSurfaceRepr.mark(loci, action) + const markWireframeElement = gaussianWireframeRepr.mark(loci, action) + const markVolumeElement = gaussianVolumeRepr.mark(loci, action) + return markSurfaceElement || markWireframeElement || markVolumeElement }, destroy() { gaussianSurfaceRepr.destroy() diff --git a/src/mol-geo/representation/structure/units-visual.ts b/src/mol-geo/representation/structure/units-visual.ts index 50de4ef0f4b21c8347a2e833a6ae7c8ced69ac50..8961e75cc9fd6e871b94c601a8f890c197e339a2 100644 --- a/src/mol-geo/representation/structure/units-visual.ts +++ b/src/mol-geo/representation/structure/units-visual.ts @@ -529,7 +529,7 @@ export type UnitsDirectVolumeProps = typeof DefaultUnitsDirectVolumeProps export interface UnitsDirectVolumeVisualBuilder<P extends UnitsDirectVolumeProps> extends UnitsVisualBuilder<P, DirectVolume2d | DirectVolume3d> { } export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builder: UnitsDirectVolumeVisualBuilder<P>): UnitsVisual<P> { - const { defaultProps, createGeometry, createLocationIterator, getLoci, setUpdateState } = builder + const { defaultProps, createGeometry, createLocationIterator, getLoci, mark, setUpdateState } = builder const updateState = VisualUpdateState.create() let renderObject: DirectVolume2dRenderObject | DirectVolume3dRenderObject | undefined @@ -644,8 +644,26 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builde return renderObject ? getLoci(pickingId, currentGroup, renderObject.id) : EmptyLoci }, mark(loci: Loci, action: MarkerAction) { - // TODO - return false + if (!renderObject) return false + const { tMarker } = renderObject.values + const { groupCount, instanceCount } = locationIt + + function apply(interval: Interval) { + const start = Interval.start(interval) + const end = Interval.end(interval) + return applyMarkerAction(tMarker.ref.value.array, start, end, action) + } + + let changed = false + if (isEveryLoci(loci)) { + changed = apply(Interval.ofBounds(0, groupCount * instanceCount)) + } else { + changed = mark(loci, currentGroup, apply) + } + if (changed) { + ValueCell.update(tMarker, tMarker.ref.value) + } + return changed }, destroy() { // TODO diff --git a/src/mol-gl/renderable/direct-volume.ts b/src/mol-gl/renderable/direct-volume.ts index 2f043942bdcba998defbbdc4ff89185847dec904..b29b924cf314514e214fa77a500505068da02917 100644 --- a/src/mol-gl/renderable/direct-volume.ts +++ b/src/mol-gl/renderable/direct-volume.ts @@ -63,7 +63,7 @@ function DirectVolumeRenderable<T extends DirectVolumeBaseValues, S extends Dire const renderItem = createRenderItem(ctx, 'triangles', shaderCode, fullSchema, fullValues) const renderable = createRenderable(renderItem, values, state); - Object.defineProperty(renderable, 'opaque', { get: () => false }); + Object.defineProperty(renderable, 'opaque', { get: () => true }); return renderable } diff --git a/src/mol-gl/shader/direct-volume.frag b/src/mol-gl/shader/direct-volume.frag index eac50188c43ad18eb1effa2ad4640085980a21ee..a4c96b73207f7c68e0e78f188fd4cfc51707643a 100644 --- a/src/mol-gl/shader/direct-volume.frag +++ b/src/mol-gl/shader/direct-volume.frag @@ -122,23 +122,31 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) { gradient.y = textureVal(isoPos - dy).a - textureVal(isoPos + dy).a; gradient.z = textureVal(isoPos - dz).a - textureVal(isoPos + dz).a; gradient = normalize(gradient); - float d = float(dot(gradient, viewDir) > 0.0); gradient = (2.0 * d - 1.0) * gradient; + float group = floor(decodeIdRGB(textureGroup(isoPos).rgb) + 0.5); + #if defined(dColorType_instance) color = readFromTexture(tColor, instance, uColorTexDim).rgb; #elif defined(dColorType_group) - float group = floor(decodeIdRGB(textureGroup(isoPos).rgb) + 0.5); color = readFromTexture(tColor, group, uColorTexDim).rgb; #elif defined(dColorType_groupInstance) - float group = floor(decodeIdRGB(textureGroup(isoPos).rgb) + 0.5); color = readFromTexture(tColor, instance * float(uGroupCount) + group, uColorTexDim).rgb; #endif src.rgb = color * abs(dot(gradient, viewDir)); src.a = uAlpha; + float marker = readFromTexture(tMarker, instance * float(uGroupCount) + group, uMarkerTexDim).a * 256.0; + if (marker > 0.1) { + if (mod(marker, 2.0) < 0.1) { + src.rgb = mix(uHighlightColor, src.rgb, 0.3); + } else { + src.rgb = mix(uSelectColor, src.rgb, 0.3); + } + } + // draw interior darker if( (prevValue - uIsoValue) > 0.0 ) { src.rgb *= 0.5; diff --git a/src/mol-gl/shader/gaussian-density.frag b/src/mol-gl/shader/gaussian-density.frag index acb34cd16e76a1acee7d82f1e779af18843b58b4..827b662970e70cfbc401ec60e7e1cfcb4ad62bcc 100644 --- a/src/mol-gl/shader/gaussian-density.frag +++ b/src/mol-gl/shader/gaussian-density.frag @@ -64,7 +64,9 @@ void main() { gl_FragColor.a = 1.0 - encodeDistLog(dist); #elif defined(dCalcType_groupId) float minDistance = decodeDistLog(1.0 - textureMinDist(fragPos).a); - if (dist > minDistance + length(uBboxSize / uGridDim) / 1.5) + // TODO verify `length(uBboxSize / uGridDim) * 2.0` + // on some machines `* 2.0` is needed while on others `* 0.5` works + if (dist > minDistance + length(uBboxSize / uGridDim) * 2.0) discard; gl_FragColor.rgb = encodeIdRGB(vGroup); #endif