Browse Source

add support for marking direct volume isosurfaces

Alexander Rose 6 years ago
parent
commit
d82635b254

+ 17 - 3
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()

+ 21 - 3
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

+ 1 - 1
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
 }

+ 11 - 3
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;

+ 3 - 1
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