Skip to content

Commit

Permalink
Small Fixes + Updates to Viv. (visgl#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilan-gold authored Aug 13, 2021
1 parent 579fb3e commit 753b128
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 50 deletions.
6 changes: 2 additions & 4 deletions modules/viv/layers/ImageLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,8 @@ const ImageLayer = class extends CompositeLayer {
this.state.abortController.abort();
}

updateState({ changeFlags, props, oldProps }) {
const { propsChanged } = changeFlags;
const loaderChanged =
typeof propsChanged === 'string' && propsChanged.includes('props.loader');
updateState({ props, oldProps }) {
const loaderChanged = props.loader !== oldProps.loader;
const loaderSelectionChanged =
props.loaderSelection !== oldProps.loaderSelection;

Expand Down
28 changes: 11 additions & 17 deletions modules/viv/layers/MultiscaleImageLayer/MultiscaleImageLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ import {
SIGNAL_ABORTED
} from '../../loaders/utils';

// From https://github.com/visgl/deck.gl/pull/4616/files#diff-4d6a2e500c0e79e12e562c4f1217dc80R128
const DECK_GL_TILE_SIZE = 512;

const defaultProps = {
pickable: { type: 'boolean', value: true, compare: true },
onHover: { type: 'function', value: null, compare: false },
Expand Down Expand Up @@ -109,7 +106,6 @@ const MultiscaleImageLayer = class extends CompositeLayer {
// https://github.com/visgl/deck.gl/pull/4616/files#diff-4d6a2e500c0e79e12e562c4f1217dc80R128
// The z level can be wrong for showing the correct scales because of the calculation deck.gl does
// so we need to invert it for fetching tiles and minZoom/maxZoom.
const zoomOffset = Math.log2(DECK_GL_TILE_SIZE / tileSize);
const getTileData = async ({ x, y, z, signal }) => {
// Early return if no loaderSelection
if (!loaderSelection || loaderSelection.length === 0) {
Expand All @@ -122,7 +118,7 @@ const MultiscaleImageLayer = class extends CompositeLayer {
// which felt odd to me to beign with.
// The image-tile example works without, this but I have a feeling there is something
// going on with our pyramids and/or rendering that is different.
const resolution = Math.round(-z + zoomOffset);
const resolution = Math.round(-z);
const getTile = selection => {
const config = { x, y, selection, signal };
return loader[resolution].getTile(config);
Expand Down Expand Up @@ -176,20 +172,18 @@ const MultiscaleImageLayer = class extends CompositeLayer {
id: `Tiled-Image-${id}`,
getTileData,
dtype,
// If you scale a matrix up or down, that is like zooming in or out. After
// https://github.com/visgl/deck.gl/pull/4616/files#diff-4d6a2e500c0e79e12e562c4f1217dc80R128,
// tileSize controls the zoom level that the tile indexer thinks you are at for fetching tiles.
// Because the indexing offsets `z` by math.log2(TILE_SIZE / tileSize), passing in
// tileSize * (1 / modelMatrix.getScale()[0]) from this layer as below to TileLayer gives an offset of
// math.log2(TILE_SIZE / (tileSize * (1 / modelMatrix.getScale()[0]))) = math.log2(TILE_SIZE / tileSize) + Math.log2(modelMatrix.getScale()[0])
// as desired so that the z level used for indexing the tiles is larger (i.e more zoomed in) if the image is scaled larger, and vice-versa if scaled smaller.
tileSize: modelMatrix
? tileSize * (1 / modelMatrix.getScale()[0])
: tileSize,
tileSize,
// If you scale a matrix up or down, that is like zooming in or out. zoomOffset controls
// how the zoom level you fetch tiles at is offset, allowing us to fetch higher resolution tiles
// while at a lower "absolute" zoom level. If you didn't use this prop, an image that is scaled
// up would always look "low resolution" no matter the level of the image pyramid you are looking at.
zoomOffset: Math.round(
Math.log2(modelMatrix ? modelMatrix.getScale()[0] : 1)
),
extent: [0, 0, width, height],
// See the above note within for why the use of zoomOffset and the rounding necessary.
minZoom: Math.round(-(loader.length - 1) + zoomOffset),
maxZoom: Math.round(zoomOffset),
minZoom: Math.round(-(loader.length - 1)),
maxZoom: 0,
// We want a no-overlap caching strategy with an opacity < 1 to prevent
// multiple rendered sublayers (some of which have been cached) from overlapping
refinementStrategy:
Expand Down
80 changes: 51 additions & 29 deletions modules/viv/layers/VolumeLayer/VolumeLayer.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { CompositeLayer, COORDINATE_SYSTEM } from '@deck.gl/core';
import GL from '@luma.gl/constants';
import { TextLayer } from '@deck.gl/layers';
import { isWebGL2 } from '@luma.gl/core';
import { Matrix4 } from 'math.gl';
import XR3DLayer from '../XR3DLayer';
import { getPhysicalSizeScalingMatrix } from '../utils';
import { RENDERING_MODES } from '../../constants';
import { getVolume } from './utils';
import { getVolume, getTextLayer } from './utils';

const defaultProps = {
pickable: false,
Expand Down Expand Up @@ -39,7 +39,8 @@ const defaultProps = {
compare: true
},
onUpdate: { type: 'function', value: () => {}, compare: true },
useProgressIndicator: { type: 'boolean', value: true, compare: true }
useProgressIndicator: { type: 'boolean', value: true, compare: true },
useWebGL1Warning: { type: 'boolean', value: true, compare: true }
};

/**
Expand All @@ -61,6 +62,7 @@ const defaultProps = {
* @property {function=} onViewportLoad Function that gets called when the data in the viewport loads.
* @property {Array.<Object>=} clippingPlanes List of math.gl [Plane](https://math.gl/modules/culling/docs/api-reference/plane) objects.
* @property {boolean=} useProgressIndicator Whether or not to use the default progress text + indicator (default is true)
* @property {boolean=} useWebGL1Warning Whether or not to use the default WebGL1 warning (default is true)
* @property {function=} onUpdate A callback to be used for getting updates of the progress, ({ progress }) => {}
*/

Expand All @@ -69,20 +71,33 @@ const defaultProps = {
* @ignore
*/
const VolumeLayer = class extends CompositeLayer {
clearState() {
this.setState({
height: null,
width: null,
depth: null,
data: null,
physicalSizeScalingMatrix: null,
resolutionMatrix: null,
progress: 0,
abortController: null
});
}

finalizeState() {
this.state.abortController.abort();
}

updateState({ changeFlags, oldProps, props }) {
const { propsChanged } = changeFlags;
const loaderChanged =
typeof propsChanged === 'string' && propsChanged.includes('props.loader');
const resolutionChanged =
typeof propsChanged === 'string' &&
propsChanged.includes('props.resolution');
updateState({ oldProps, props }) {
const loaderChanged = props.loader !== oldProps.loader;
const resolutionChanged = props.resolution !== oldProps.resolution;
const loaderSelectionChanged =
props.loaderSelection !== oldProps.loaderSelection;
// Only fetch new data to render if loader has changed
if (resolutionChanged) {
// Clear last volume.
this.clearState();
}
if (loaderChanged || loaderSelectionChanged || resolutionChanged) {
const {
loader,
Expand Down Expand Up @@ -140,7 +155,13 @@ const VolumeLayer = class extends CompositeLayer {
}

renderLayers() {
const { loader, id, resolution, useProgressIndicator } = this.props;
const {
loader,
id,
resolution,
useProgressIndicator,
useWebGL1Warning
} = this.props;
const { dtype } = loader[resolution];
const {
data,
Expand All @@ -151,26 +172,27 @@ const VolumeLayer = class extends CompositeLayer {
physicalSizeScalingMatrix,
resolutionMatrix
} = this.state;
const { gl } = this.context;
if (!isWebGL2(gl) && useWebGL1Warning) {
const { viewport } = this.context;
return getTextLayer(
[
'Volume rendering is only available on browsers that support WebGL2. If you',
'are using Safari, you can turn on WebGL2 by navigating in the top menubar',
'to check Develop > Experimental Features > WebGL 2.0 and then refreshing',
'the page.'
].join('\n'),
viewport,
id
);
}
if (!(width && height) && useProgressIndicator) {
const { viewport } = this.context;
return new TextLayer({
id: `loading-text-layer-${id}`,
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
data: [
{
text: `Loading Volume ${String((progress || 0) * 100).slice(
0,
5
)}%...`,
position: viewport.position
}
],
getColor: [220, 220, 220, 255],
getSize: 25,
sizeUnits: 'meters',
sizeScale: 2 ** -viewport.zoom,
fontFamily: 'Helvetica'
});
return getTextLayer(
`Loading Volume ${String((progress || 0) * 100).slice(0, 5)}%...`,
viewport,
id
);
}
return new XR3DLayer(this.props, {
channelData: { data, width, height, depth },
Expand Down
21 changes: 21 additions & 0 deletions modules/viv/layers/VolumeLayer/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* global globalThis */
import { COORDINATE_SYSTEM } from '@deck.gl/core';
import { TextLayer } from '@deck.gl/layers';
import { getImageSize } from '../../loaders/utils';

/**
Expand Down Expand Up @@ -62,3 +65,21 @@ export async function getVolume({
depth: depthDownsampled
};
}

export const getTextLayer = (text, viewport, id) => {
return new TextLayer({
id: `text-${id}`,
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
data: [
{
text,
position: viewport.position
}
],
getColor: [220, 220, 220, 255],
getSize: 25,
sizeUnits: 'meters',
sizeScale: 2 ** -viewport.zoom,
fontFamily: 'Helvetica'
});
};

0 comments on commit 753b128

Please sign in to comment.