From efb094403c722e592ececb0d1a3bb13ccb71ad26 Mon Sep 17 00:00:00 2001 From: Akhilesh Halageri Date: Mon, 27 Jan 2025 14:17:35 -0600 Subject: [PATCH] virutal nodes --- src/datasource/graphene/backend.ts | 4 ---- src/mesh/frontend.ts | 2 +- src/mesh/multiscale.ts | 37 ++++++++++++++++++------------ 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/datasource/graphene/backend.ts b/src/datasource/graphene/backend.ts index b59d282754..2abe5d964d 100644 --- a/src/datasource/graphene/backend.ts +++ b/src/datasource/graphene/backend.ts @@ -225,10 +225,6 @@ function decodeMultiscaleManifestChunk(chunk: GrapheneMultiscaleManifestChunk, r clipLowerBound: vec3.clone(response.clipLowerBound), clipUpperBound: vec3.clone(response.clipUpperBound), }; - console.log("original chunkShape", chunk.manifest.chunkShape.join()); - chunk.manifest.chunkShape[0] /= 8; - chunk.manifest.chunkShape[1] /= 8; - chunk.manifest.chunkShape[2] /= 40; chunk.fragmentIds = response.fragments; chunk.manifest.clipLowerBound.fill(0); chunk.manifest.clipUpperBound.fill(10000000); diff --git a/src/mesh/frontend.ts b/src/mesh/frontend.ts index 8260fc06aa..9e55bb4d2b 100644 --- a/src/mesh/frontend.ts +++ b/src/mesh/frontend.ts @@ -890,7 +890,7 @@ export class MultiscaleMeshLayer extends PerspectiveViewRenderLayer>> 31); + const virtual = childBeginAndVirtual >>> 31; + if (virtual) { + lodScale = 0; + } + const empty = childEndAndEmpty >>> 31; + callback(lod, row, lodScale / pixelSize, empty | virtual); } - if ( - lod > 0 && - (lodScale === 0 || pixelSize * detailCutoff < lodScale) - ) { + if (lod > 0 && (lodScale === 0 || pixelSize * detailCutoff < lodScale)) { const nextPriorLodScale = lodScale === 0 ? priorLodScale : lodScale; + const childBegin = (childBeginAndVirtual & 0x7fffffff) >>> 0; const childEnd = (childEndAndEmpty & 0x7fffffff) >>> 0; for (let childRow = childBegin; childRow < childEnd; ++childRow) { handleChunk(lod - 1, childRow, nextPriorLodScale); @@ -349,7 +352,7 @@ export function getMultiscaleChunksToDraw( emitChunksUpTo(0, 0); } -export function validateOctree(octree: Uint32Array) { +export function validateOctree(octree: Uint32Array, allowDuplicateChildren: boolean = false) { if (octree.length % 5 !== 0) { throw new Error("Invalid length"); } @@ -357,32 +360,36 @@ export function validateOctree(octree: Uint32Array) { const seenNodes = new Set(); function exploreNode(node: number) { if (seenNodes.has(node)) { - throw new Error("Previously seen node"); + throw new Error(`Previously seen node: ${node}`); } seenNodes.add(node); if (node < 0 || node >= numNodes) { - throw new Error("Invalid node reference"); + throw new Error(`Invalid node reference: ${node}`); } const x = octree[node * 5]; const y = octree[node * 5 + 1]; const z = octree[node * 5 + 2]; - const beginChild = octree[node * 5 + 3]; - const endChild = octree[node * 5 + 4]; + const beginChild = (octree[node * 5 + 3] & 0x7fffffff) >>> 0; + const endChild = (octree[node * 5 + 4] & 0x7fffffff) >>> 0; if ( beginChild < 0 || endChild < 0 || endChild < beginChild || endChild > numNodes || - beginChild + 8 < endChild + (!allowDuplicateChildren && beginChild + 8 < endChild) ) { - throw new Error("Invalid child references"); + throw new Error( + `Invalid child references: node ${node} specifies beginChild=${beginChild}, endChild=${endChild}`, + ); } for (let child = beginChild; child < endChild; ++child) { const childX = octree[child * 5]; const childY = octree[child * 5 + 1]; const childZ = octree[child * 5 + 2]; if (childX >>> 1 !== x || childY >>> 1 !== y || childZ >>> 1 !== z) { - throw new Error("invalid child"); + throw new Error( + `invalid child position: parent=${node} child=${child} childX=${childX} childY=${childY} childZ=${childZ} parentX=${x} parentY=${y} parentZ=${z}`, + ); } exploreNode(child); }