diff --git a/src/skeleton/frontend.ts b/src/skeleton/frontend.ts index a5d072365..d2839a626 100644 --- a/src/skeleton/frontend.ts +++ b/src/skeleton/frontend.ts @@ -26,7 +26,6 @@ import type { LayerView, MouseSelectionState, PickState, - UserLayer, VisibleLayerInfo, } from "#src/layer/index.js"; import type { PerspectivePanel } from "#src/perspective_view/panel.js"; @@ -130,7 +129,7 @@ import { DATA_TYPE_SIGNED, DataType } from "#src/util/data_type.js"; import { RefCounted } from "#src/util/disposable.js"; import type { ValueOrError } from "#src/util/error.js"; import { makeValueOrError, valueOrThrow } from "#src/util/error.js"; -import { mat4 } from "#src/util/geom.js"; +import { kOneVec4, mat4, type vec4 } from "#src/util/geom.js"; import { verifyFinitePositiveFloat } from "#src/util/json.js"; import * as matrix from "#src/util/matrix.js"; import { getObjectId } from "#src/util/object_id.js"; @@ -183,6 +182,9 @@ import { import { defineVertexId, VertexIdHelper } from "#src/webgl/vertex_id.js"; import type { RPC } from "#src/worker_rpc.js"; +const DEBUG_SPATIAL_SKELETON_OVERLAY = false; +const DEBUG_EXCLUDED_SEGMENTS = false; + const tempMat2 = mat4.create(); const DEFAULT_FRAGMENT_MAIN = `void main() { emitDefault(); @@ -323,6 +325,23 @@ class RenderHelper extends RefCounted { } private defineDynamicSegmentAppearance(builder: ShaderBuilder) { + // Regular path no debugging alpha and color + let colorExpression = `return ${this.segmentColorShaderManager.prefix}(segmentId);`; + let alphaExpression = `return isVisible ? uVisibleAlpha : uHiddenAlpha;`; + let excludedSegmentAlpha = "0.0"; + + // Override usual alpha and color calculations to enable some debug modes + if (DEBUG_EXCLUDED_SEGMENTS) { + colorExpression = ` + if (${this.excludedSegmentsShaderManager.hasFunctionName}(segmentId)) { + return vec3(0.0, 0.0, 1.0); + } + ${colorExpression} + `; + if (!DEBUG_SPATIAL_SKELETON_OVERLAY) alphaExpression = `return 0.0;`; + excludedSegmentAlpha = "1.0"; + } + this.visibleSegmentsShaderManager.defineShader(builder); this.excludedSegmentsShaderManager.defineShader(builder); this.segmentColorShaderManager.defineShader(builder); @@ -330,7 +349,6 @@ class RenderHelper extends RefCounted { builder.addUniform("highp float", "uVisibleAlpha"); builder.addUniform("highp float", "uHiddenAlpha"); builder.addUniform("highp vec3", "uSegmentDefaultColor"); - builder.addUniform("highp uint", "uSkipVisibleSegments"); builder.addUniform("highp uint", "uUseSegmentDefaultColor"); builder.addUniform("highp uint", "uUseSegmentStatedColors"); builder.addFragmentCode(` @@ -348,17 +366,14 @@ vec3 getSegmentLookupColor(uint64_t segmentId) { if (uUseSegmentDefaultColor != 0u) { return uSegmentDefaultColor; } - return ${this.segmentColorShaderManager.prefix}(segmentId); + ${colorExpression} } float getSegmentLookupAlpha(uint64_t segmentId) { if (${this.excludedSegmentsShaderManager.hasFunctionName}(segmentId)) { - return 0.0; + return ${excludedSegmentAlpha}; } bool isVisible = ${this.visibleSegmentsShaderManager.hasFunctionName}(segmentId); - if (uSkipVisibleSegments != 0u && isVisible) { - return 0.0; - } - return isVisible ? uVisibleAlpha : uHiddenAlpha; + ${alphaExpression} } vec4 getSegmentAppearance(highp uint segmentValue) { uint64_t segmentId = getSegmentAppearanceId(segmentValue); @@ -370,7 +385,6 @@ vec4 getSegmentAppearance(highp uint segmentValue) { enableDynamicSegmentAppearance( gl: GL, shader: ShaderProgram, - skipVisibleSegments: boolean, excludedSegments?: Uint64Set, ) { if (!this.dynamicSegmentAppearance) return; @@ -401,10 +415,6 @@ vec4 getSegmentAppearance(highp uint segmentValue) { shader.uniform("uHiddenAlpha"), this.base.displayState.hiddenObjectAlpha.value, ); - gl.uniform1ui( - shader.uniform("uSkipVisibleSegments"), - skipVisibleSegments ? 1 : 0, - ); const colorGroupState = this.base.displayState.segmentationColorGroupState.value; @@ -418,13 +428,18 @@ vec4 getSegmentAppearance(highp uint segmentValue) { gl.uniform1ui(shader.uniform("uUseSegmentDefaultColor"), 0); } else { gl.uniform1ui(shader.uniform("uUseSegmentDefaultColor"), 1); - gl.uniform3f( + gl.uniform3fv( shader.uniform("uSegmentDefaultColor"), segmentDefaultColor[0], segmentDefaultColor[1], segmentDefaultColor[2], ); } + if (DEBUG_SPATIAL_SKELETON_OVERLAY && excludedSegments === undefined) { + // Use a red color for everything in the overlay + gl.uniform1ui(shader.uniform("uUseSegmentDefaultColor"), 1); + gl.uniform3f(shader.uniform("uSegmentDefaultColor"), 1.0, 0.0, 0.0); + } const segmentStatedColors = colorGroupState.segmentStatedColors; if (segmentStatedColors.size === 0) { @@ -880,18 +895,8 @@ void emitDefault() { this.vertexIdHelper.enable(); } - setColor(gl: GL, shader: ShaderProgram, color: Float32Array | number[]) { - const a = - (color as Float32Array).length >= 4 - ? (color as Float32Array)[3] - : this.base.displayState.objectAlpha.value; - gl.uniform4f( - shader.uniform("uColor"), - (color as Float32Array)[0], - (color as Float32Array)[1], - (color as Float32Array)[2], - a, - ); + setColor(gl: GL, shader: ShaderProgram, color: vec4) { + gl.uniform4fv(shader.uniform("uColor"), color); } setPickID(gl: GL, shader: ShaderProgram, pickID: number) { @@ -906,7 +911,7 @@ void emitDefault() { gl.uniform1ui(shader.uniform("uPickInstanceStride"), stride); } - drawSkeleton( + drawSkeletons( gl: GL, edgeShader: ShaderProgram, nodeShader: ShaderProgram | null, @@ -1235,9 +1240,9 @@ export class SkeletonLayer extends RefCounted { } if (color !== undefined) { edgeShader.bind(); - renderHelper.setColor(gl, edgeShader, color as Float32Array); + renderHelper.setColor(gl, edgeShader, color); nodeShader.bind(); - renderHelper.setColor(gl, nodeShader, color as Float32Array); + renderHelper.setColor(gl, nodeShader, color); } if (pickIndex !== undefined) { edgeShader.bind(); @@ -1245,7 +1250,7 @@ export class SkeletonLayer extends RefCounted { nodeShader.bind(); renderHelper.setPickID(gl, nodeShader, pickIndex); } - renderHelper.drawSkeleton( + renderHelper.drawSkeletons( gl, edgeShader, nodeShader, @@ -1886,11 +1891,6 @@ function updateSpatialSkeletonGridRenderScaleHistogram( } } -type VisibleSpatialChunksBySource = Map< - string, - readonly SpatiallyIndexedSkeletonChunk[] ->; - interface SpatialSkeletonDisplayState { spatialSkeletonGridLevel2d?: WatchableValueInterface; spatialSkeletonGridLevel3d?: WatchableValueInterface; @@ -1929,15 +1929,6 @@ export class SpatiallyIndexedSkeletonLayer segmentTextureFormat, selectedNodeTextureFormat, ]; - private regularSkeletonLayerWatchable = new WatchableValue(false); - private regularSkeletonLayerUserLayer: UserLayer | undefined; - private removeRegularSkeletonLayerUserLayerListener: - | (() => boolean) - | undefined; - private visibleChunksByView = new Map< - SpatiallyIndexedSkeletonView, - VisibleSpatialChunksBySource - >(); gridLevel: WatchableValueInterface; lod: WatchableValueInterface; private selectedNodeId: @@ -2227,54 +2218,6 @@ export class SpatiallyIndexedSkeletonLayer return this.overlayChunk; } - private computeHasRegularSkeletonLayer(userLayer: UserLayer) { - for (const renderLayer of userLayer.renderLayers) { - if ( - renderLayer instanceof PerspectiveViewSkeletonLayer || - renderLayer instanceof SliceViewPanelSkeletonLayer - ) { - return true; - } - } - return false; - } - - private updateHasRegularSkeletonLayerWatchable( - userLayer: UserLayer | undefined, - ) { - if (this.regularSkeletonLayerUserLayer !== userLayer) { - this.removeRegularSkeletonLayerUserLayerListener?.(); - this.removeRegularSkeletonLayerUserLayerListener = undefined; - this.regularSkeletonLayerUserLayer = userLayer; - if (userLayer !== undefined) { - const update = () => { - const nextValue = this.computeHasRegularSkeletonLayer(userLayer); - if (this.regularSkeletonLayerWatchable.value !== nextValue) { - this.regularSkeletonLayerWatchable.value = nextValue; - this.redrawNeeded.dispatch(); - } - }; - update(); - this.removeRegularSkeletonLayerUserLayerListener = - userLayer.layersChanged.add(update); - } else if (this.regularSkeletonLayerWatchable.value) { - this.regularSkeletonLayerWatchable.value = false; - this.redrawNeeded.dispatch(); - } - } - return this.regularSkeletonLayerWatchable.value; - } - - private lodMatches( - chunk: SpatiallyIndexedSkeletonChunk, - targetLod: number | undefined, - ) { - if (targetLod === undefined || chunk.lod === undefined) { - return true; - } - return Math.abs(chunk.lod - targetLod) < 1e-6; - } - sources: SpatiallyIndexedSkeletonSourceEntry[]; sources2d: SpatiallyIndexedSkeletonSourceEntry[]; source: SpatiallyIndexedSkeletonSource; @@ -2291,9 +2234,6 @@ export class SpatiallyIndexedSkeletonLayer ) { super(); this.registerDisposer(() => { - this.removeRegularSkeletonLayerUserLayerListener?.(); - this.removeRegularSkeletonLayerUserLayerListener = undefined; - this.regularSkeletonLayerUserLayer = undefined; this.disposeOverlayChunk(); }); let sources3d: SpatiallyIndexedSkeletonSourceEntry[]; @@ -2481,46 +2421,6 @@ export class SpatiallyIndexedSkeletonLayer }; } - private getVisibleChunksForView(view: SpatiallyIndexedSkeletonView) { - return this.visibleChunksByView.get(view); - } - - private *iterateCandidateChunks( - selectedSources: readonly SpatiallyIndexedSkeletonSourceEntry[], - targetLod: number | undefined, - options: { - view?: SpatiallyIndexedSkeletonView; - } = {}, - ): Iterable { - const visibleChunksBySource = - options.view === undefined - ? undefined - : this.getVisibleChunksForView(options.view); - const useVisibleChunks = visibleChunksBySource !== undefined; - for (const sourceEntry of selectedSources) { - if (useVisibleChunks) { - const visibleChunks = visibleChunksBySource.get( - getObjectId(sourceEntry.chunkSource), - ); - if (visibleChunks === undefined) { - continue; - } - for (const chunk of visibleChunks) { - if (!this.lodMatches(chunk, targetLod)) continue; - if (chunk.state !== ChunkState.GPU_MEMORY) continue; - yield chunk; - } - continue; - } - for (const chunk of sourceEntry.chunkSource.chunks.values()) { - const typedChunk = chunk as SpatiallyIndexedSkeletonChunk; - if (!this.lodMatches(typedChunk, targetLod)) continue; - if (typedChunk.state !== ChunkState.GPU_MEMORY) continue; - yield typedChunk; - } - } - } - invalidateSourceCaches() { let invalidated = false; for (const chunkSource of this.iterateUniqueChunkSources()) { @@ -2604,27 +2504,28 @@ export class SpatiallyIndexedSkeletonLayer }; } - updateVisibleChunksForView( + getVisibleChunksInCurrentViewAndLod( view: SpatiallyIndexedSkeletonView, + gridLevel: number | undefined, transformedSources: readonly TransformedSource[][], projectionParameters: any, lod: number | undefined, - ) { + ): SpatiallyIndexedSkeletonChunk[] { if (lod === undefined) { - this.visibleChunksByView.delete(view); - return; + return []; } + const selectedSourceIds = new Set( + this.selectSourcesForViewAndGrid(view, gridLevel).map((s) => + getObjectId(s.chunkSource), + ), + ); const lodSuffix = `:${lod}`; - const chunksBySource: VisibleSpatialChunksBySource = new Map(); + const result: SpatiallyIndexedSkeletonChunk[] = []; const seenChunkKeysBySource = new Map>(); for (const scales of transformedSources) { for (const tsource of scales) { const sourceId = getObjectId(tsource.source); - let visibleChunks = chunksBySource.get(sourceId); - if (visibleChunks === undefined) { - visibleChunks = []; - chunksBySource.set(sourceId, visibleChunks); - } + if (!selectedSourceIds.has(sourceId)) continue; let seenChunkKeys = seenChunkKeysBySource.get(sourceId); if (seenChunkKeys === undefined) { seenChunkKeys = new Set(); @@ -2636,24 +2537,20 @@ export class SpatiallyIndexedSkeletonLayer tsource, (positionInChunks) => { const chunkKey = `${positionInChunks.join()}${lodSuffix}`; - if (seenChunkKeys!.has(chunkKey)) { - return; - } + if (seenChunkKeys!.has(chunkKey)) return; seenChunkKeys!.add(chunkKey); const chunkSource = tsource.source as SpatiallyIndexedSkeletonSource; const chunk = chunkSource.chunks.get(chunkKey) as | SpatiallyIndexedSkeletonChunk | undefined; - if (chunk?.state !== ChunkState.GPU_MEMORY) { - return; - } - (visibleChunks as SpatiallyIndexedSkeletonChunk[]).push(chunk); + if (chunk?.state !== ChunkState.GPU_MEMORY) return; + result.push(chunk); }, ); } } - this.visibleChunksByView.set(view, chunksBySource); + return result; } private areVisibleChunksReady( @@ -2769,13 +2666,10 @@ export class SpatiallyIndexedSkeletonLayer modelMatrix: mat4, lineWidth: number, pointDiameter: number, - hasRegularSkeletonLayer: boolean, - selectedSources: readonly SpatiallyIndexedSkeletonSourceEntry[], - targetLod: number | undefined, - view: SpatiallyIndexedSkeletonView, + visibleChunks: SpatiallyIndexedSkeletonChunk[], ) { + if (visibleChunks.length === 0) return; const { gl } = this; - const excludedSegments = this.getBrowsePassExcludedSegments(); const edgeShaderResult = renderHelper.edgeShaderGetter( renderContext.emitter, ); @@ -2789,9 +2683,12 @@ export class SpatiallyIndexedSkeletonLayer if (edgeShader === null || nodeShader === null) { return; } + const excludedSegments = this.getBrowsePassExcludedSegments(); const { shaderControlState } = this.displayState.skeletonRenderingOptions; + edgeShader.bind(); renderHelper.beginLayer(gl, edgeShader, renderContext, modelMatrix); + gl.uniform1f(edgeShader.uniform("uLineWidth"), lineWidth); renderHelper.setEdgePickInstanceStride(gl, edgeShader, 0); setControlsInShader( gl, @@ -2799,7 +2696,17 @@ export class SpatiallyIndexedSkeletonLayer shaderControlState, edgeShaderParameters.parseResult.controls, ); - gl.uniform1f(edgeShader.uniform("uLineWidth"), lineWidth); + renderHelper.setColor(gl, edgeShader, kOneVec4); + renderHelper.enableDynamicSegmentAppearance( + gl, + edgeShader, + excludedSegments, + ); + if (renderContext.emitPickID) { + renderHelper.setPickID(gl, edgeShader, 0); + renderHelper.setEdgePickInstanceStride(gl, edgeShader, 0); + } + nodeShader.bind(); renderHelper.beginLayer(gl, nodeShader, renderContext, modelMatrix); gl.uniform1f(nodeShader.uniform("uNodeDiameter"), pointDiameter); @@ -2810,38 +2717,18 @@ export class SpatiallyIndexedSkeletonLayer shaderControlState, nodeShaderParameters.parseResult.controls, ); - const baseColor = new Float32Array([1, 1, 1, 1]); - edgeShader.bind(); - renderHelper.setColor(gl, edgeShader, baseColor); - renderHelper.enableDynamicSegmentAppearance( - gl, - edgeShader, - hasRegularSkeletonLayer, - excludedSegments, - ); - nodeShader.bind(); - renderHelper.setColor(gl, nodeShader, baseColor); + renderHelper.setColor(gl, nodeShader, kOneVec4); renderHelper.enableDynamicSegmentAppearance( gl, nodeShader, - hasRegularSkeletonLayer, excludedSegments, ); if (renderContext.emitPickID) { - edgeShader.bind(); - renderHelper.setPickID(gl, edgeShader, 0); - renderHelper.setEdgePickInstanceStride(gl, edgeShader, 0); - nodeShader.bind(); renderHelper.setPickID(gl, nodeShader, 0); renderHelper.setNodePickInstanceStride(gl, nodeShader, 0); } - for (const chunk of this.iterateCandidateChunks( - selectedSources, - targetLod, - { - view, - }, - )) { + + for (const chunk of visibleChunks) { if (renderContext.emitPickID) { let edgePickId = 0; let edgePickStride = 0; @@ -2878,7 +2765,7 @@ export class SpatiallyIndexedSkeletonLayer renderHelper.setPickID(gl, nodeShader, nodePickId); renderHelper.setNodePickInstanceStride(gl, nodeShader, nodePickStride); } - renderHelper.drawSkeleton( + renderHelper.drawSkeletons( gl, edgeShader, nodeShader, @@ -2898,7 +2785,6 @@ export class SpatiallyIndexedSkeletonLayer modelMatrix: mat4, lineWidth: number, pointDiameter: number, - hasRegularSkeletonLayer: boolean, ) { const overlayChunk = this.resolveSourceBackedOverlayChunk(); if (overlayChunk === undefined) { @@ -2919,6 +2805,7 @@ export class SpatiallyIndexedSkeletonLayer return; } const { shaderControlState } = this.displayState.skeletonRenderingOptions; + edgeShader.bind(); renderHelper.beginLayer(gl, edgeShader, renderContext, modelMatrix); renderHelper.setEdgePickInstanceStride(gl, edgeShader, 0); @@ -2929,31 +2816,8 @@ export class SpatiallyIndexedSkeletonLayer edgeShaderParameters.parseResult.controls, ); gl.uniform1f(edgeShader.uniform("uLineWidth"), lineWidth); - nodeShader.bind(); - renderHelper.beginLayer(gl, nodeShader, renderContext, modelMatrix); - gl.uniform1f(nodeShader.uniform("uNodeDiameter"), pointDiameter); - renderHelper.setNodePickInstanceStride(gl, nodeShader, 0); - setControlsInShader( - gl, - nodeShader, - shaderControlState, - nodeShaderParameters.parseResult.controls, - ); - const baseColor = new Float32Array([1, 1, 1, 1]); - edgeShader.bind(); - renderHelper.setColor(gl, edgeShader, baseColor); - renderHelper.enableDynamicSegmentAppearance( - gl, - edgeShader, - hasRegularSkeletonLayer, - ); - nodeShader.bind(); - renderHelper.setColor(gl, nodeShader, baseColor); - renderHelper.enableDynamicSegmentAppearance( - gl, - nodeShader, - hasRegularSkeletonLayer, - ); + renderHelper.setColor(gl, edgeShader, kOneVec4); + renderHelper.enableDynamicSegmentAppearance(gl, edgeShader); if (renderContext.emitPickID) { const edgePickId = overlayChunk.numIndices > 0 && @@ -2969,14 +2833,27 @@ export class SpatiallyIndexedSkeletonLayer } satisfies SpatiallyIndexedSkeletonPickData, ) : 0; - edgeShader.bind(); renderHelper.setPickID(gl, edgeShader, edgePickId); renderHelper.setEdgePickInstanceStride( gl, edgeShader, edgePickId === 0 ? 0 : 1, ); - nodeShader.bind(); + } + + nodeShader.bind(); + renderHelper.beginLayer(gl, nodeShader, renderContext, modelMatrix); + gl.uniform1f(nodeShader.uniform("uNodeDiameter"), pointDiameter); + renderHelper.setNodePickInstanceStride(gl, nodeShader, 0); + setControlsInShader( + gl, + nodeShader, + shaderControlState, + nodeShaderParameters.parseResult.controls, + ); + renderHelper.setColor(gl, nodeShader, kOneVec4); + renderHelper.enableDynamicSegmentAppearance(gl, nodeShader); + if (renderContext.emitPickID) { const nodePickId = overlayChunk.numVertices > 0 && overlayChunk.pickNodeIds !== undefined && @@ -3001,7 +2878,8 @@ export class SpatiallyIndexedSkeletonLayer nodePickId === 0 ? 0 : 1, ); } - renderHelper.drawSkeleton( + + renderHelper.drawSkeletons( gl, edgeShader, nodeShader, @@ -3016,20 +2894,15 @@ export class SpatiallyIndexedSkeletonLayer draw( renderContext: SliceViewPanelRenderContext | PerspectiveViewRenderContext, layer: RenderLayer, - renderHelper: RenderHelper, + overlayRenderHelper: RenderHelper, browseRenderHelper: RenderHelper, renderOptions: ViewSpecificSkeletonRenderingOptions, attachment: VisibleLayerInfo< LayerView, ThreeDimensionalRenderLayerAttachmentState >, - drawOptions?: { - view?: SpatiallyIndexedSkeletonView; - gridLevel?: number; - lod?: number; - }, + visibleChunks: SpatiallyIndexedSkeletonChunk[], ) { - const lineWidth = renderOptions.lineWidth.value; const { displayState } = this; if ( displayState.objectAlpha.value <= 0.0 && @@ -3044,20 +2917,12 @@ export class SpatiallyIndexedSkeletonLayer ); if (modelMatrix === undefined) return; - const hasRegularSkeletonLayer = this.updateHasRegularSkeletonLayerWatchable( - layer.userLayer, - ); - const targetLod = drawOptions?.lod; - const view = drawOptions?.view ?? "3d"; + const lineWidth = renderOptions.lineWidth.value; const pointDiameter = getSkeletonNodeDiameter( renderOptions.mode.value, lineWidth, ); - const selectedSources = this.selectSourcesForViewAndGrid( - view, - drawOptions?.gridLevel, - ); this.drawBrowsePass( renderContext, layer, @@ -3065,19 +2930,15 @@ export class SpatiallyIndexedSkeletonLayer modelMatrix, lineWidth, pointDiameter, - hasRegularSkeletonLayer, - selectedSources, - targetLod, - view, + visibleChunks, ); this.drawInspectionOverlayPass( renderContext, layer, - renderHelper, + overlayRenderHelper, modelMatrix, lineWidth, pointDiameter, - hasRegularSkeletonLayer, ); } @@ -3322,8 +3183,9 @@ export class PerspectiveViewSpatiallyIndexedSkeletonLayer extends PerspectiveVie const displayState = this.base.displayState as SkeletonLayerDisplayState & SpatialSkeletonDisplayState; const lodValue = displayState.skeletonLod?.value; - this.base.updateVisibleChunksForView( + const visibleChunks = this.base.getVisibleChunksInCurrentViewAndLod( "3d", + displayState.spatialSkeletonGridLevel3d?.value, this.transformedSources, renderContext.projectionParameters, lodValue, @@ -3350,11 +3212,7 @@ export class PerspectiveViewSpatiallyIndexedSkeletonLayer extends PerspectiveVie this.browseRenderHelper, this.renderOptions, attachment, - { - view: "3d", - gridLevel: displayState.spatialSkeletonGridLevel3d?.value, - lod: lodValue, - }, + visibleChunks, ); } @@ -3622,8 +3480,9 @@ export class SliceViewPanelSpatiallyIndexedSkeletonLayer extends SliceViewPanelR const displayState = this.base.displayState as SkeletonLayerDisplayState & SpatialSkeletonDisplayState; const lodValue = displayState.spatialSkeletonLod2d?.value; - this.base.updateVisibleChunksForView( + const visibleChunks = this.base.getVisibleChunksInCurrentViewAndLod( "2d", + displayState.spatialSkeletonGridLevel2d?.value, this.transformedSources, renderContext.sliceView.projectionParameters.value, lodValue, @@ -3650,11 +3509,7 @@ export class SliceViewPanelSpatiallyIndexedSkeletonLayer extends SliceViewPanelR this.browseRenderHelper, this.renderOptions, attachment, - { - view: "2d", - gridLevel: displayState.spatialSkeletonGridLevel2d?.value, - lod: lodValue, - }, + visibleChunks, ); } diff --git a/src/util/geom.ts b/src/util/geom.ts index 8801ee9a7..5c428cc19 100644 --- a/src/util/geom.ts +++ b/src/util/geom.ts @@ -32,6 +32,7 @@ export const kAxes = [ export const kZeroVec = vec3.fromValues(0, 0, 0); export const kZeroVec4 = vec4.fromValues(0, 0, 0, 0); export const kOneVec = vec3.fromValues(1, 1, 1); +export const kOneVec4 = vec4.fromValues(1, 1, 1, 1); export const kInfinityVec = vec3.fromValues(Infinity, Infinity, Infinity); export const kIdentityQuat = quat.create();