@itwin/core-frontend
Version:
iTwin.js frontend components
94 lines • 4.14 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Tiles
*/
import { assert } from "@itwin/core-bentley";
import { ImdlEdgeVisibility } from "./ImdlSchema";
import { calculateEdgeTableParams } from "../internal/render/EdgeParams";
import { VertexIndices } from "../internal/render/VertexIndices";
/** Iterate over the compact edges.
* @note The same object is returned on each iteration, mutated in place.
* @internal
*/
export function* compactEdgeIterator(visibilityFlags, normalPairs, numIndices, decodeIndex) {
let bitIndex = 0;
let flagsIndex = 0;
let normalIndex = 0;
const output = { index0: 0, index1: 1 };
for (let i = 0; i < numIndices; i++) {
const visibility = (visibilityFlags[flagsIndex] >> bitIndex) & 3;
bitIndex += 2;
if (bitIndex === 8) {
bitIndex = 0;
flagsIndex++;
}
if (ImdlEdgeVisibility.Hidden === visibility || ImdlEdgeVisibility.VisibleDuplicate === visibility) {
continue;
}
output.index0 = decodeIndex(i);
output.index1 = decodeIndex(i % 3 === 2 ? i - 2 : i + 1);
if (ImdlEdgeVisibility.Silhouette === visibility) {
assert(undefined !== normalPairs);
output.normals = normalPairs[normalIndex++];
}
else {
output.normals = undefined;
}
yield output;
}
}
function setUint24(edgeTable, byteIndex, value) {
edgeTable[byteIndex + 0] = value & 0x0000ff;
edgeTable[byteIndex + 1] = (value & 0x00ff00) >>> 8;
edgeTable[byteIndex + 2] = (value & 0xff0000) >>> 16;
}
/** Convert an [[ImdlCompactEdges]] to an [[IndexedEdgeParams]].
* @internal
*/
export function indexedEdgeParamsFromCompactEdges(compact) {
const numSilhouettes = compact.normalPairs?.length ?? 0;
const numTotalEdges = compact.numVisibleEdges + numSilhouettes;
if (numTotalEdges <= 0)
return undefined;
// Each edge is a quad consisting of six vertices. Each vertex is an identical 24-bit index into the lookup table.
const indices = new VertexIndices(new Uint8Array(numTotalEdges * 6 * 3));
for (let i = 0; i < numTotalEdges; i++)
for (let j = 0; j < 6; j++)
indices.setNthIndex(i * 6 + j, i);
const { width, height, silhouettePadding, silhouetteStartByteIndex } = calculateEdgeTableParams(compact.numVisibleEdges, numSilhouettes, compact.maxEdgeTableDimension);
const edgeTable = new Uint8Array(width * height * 4);
let curVisibleIndex = 0;
let curSilhouetteIndex = 0;
for (const edge of compactEdgeIterator(compact.visibility, compact.normalPairs, compact.vertexIndices.length, (vertIdx) => compact.vertexIndices.decodeIndex(vertIdx))) {
if (undefined === edge.normals) {
const index = curVisibleIndex++;
const byteIndex = index * 6;
setUint24(edgeTable, byteIndex, edge.index0);
setUint24(edgeTable, byteIndex + 3, edge.index1);
}
else {
const index = curSilhouetteIndex++;
const byteIndex = silhouetteStartByteIndex + silhouettePadding + index * 10;
setUint24(edgeTable, byteIndex, edge.index0);
setUint24(edgeTable, byteIndex + 3, edge.index1);
edgeTable[byteIndex + 6] = edge.normals & 0xff;
edgeTable[byteIndex + 7] = (edge.normals & 0xff00) >>> 8;
edgeTable[byteIndex + 8] = (edge.normals & 0xff0000) >>> 16;
edgeTable[byteIndex + 9] = (edge.normals & 0xff000000) >>> 24;
}
}
return {
indices: indices.data,
edges: {
data: edgeTable,
width,
height,
numSegments: compact.numVisibleEdges,
silhouettePadding,
},
};
}
//# sourceMappingURL=CompactEdges.js.map