UNPKG

@itwin/core-frontend

Version:
96 lines 6.36 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module WebGL */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ContourUniforms = void 0; const core_common_1 = require("@itwin/core-common"); const Sync_1 = require("./Sync"); const LineCode_1 = require("./LineCode"); /** Maintains state for uniforms related to contour display. * @internal */ class ContourUniforms { // We use 1.5x ContourDisplay.maxContourGroups of indexable vec4 uniforms, also limited to 14 by the feature lookup texture packing scheme _contourDefsSize = Math.ceil(core_common_1.ContourDisplay.maxContourGroups * 1.5); _contourDefs = new Float32Array(this._contourDefsSize * 4); _contourDisplay; syncKey = 0; get contourDisplay() { return this._contourDisplay; } packColor(startNdx, majorColor, minorColor) { // pack 2 bytes major (upper) minor (lower) into each float this._contourDefs[startNdx] = majorColor.r * 256 + minorColor.r; this._contourDefs[startNdx + 1] = majorColor.g * 256 + minorColor.g; this._contourDefs[startNdx + 2] = majorColor.b * 256 + minorColor.b; } packPatWidth(startNdx, majorPattern, minorPattern, majorWidth, minorWidth, showGeometry) { // pack 2 bytes into this float, which is 4th float of vec4 // width is a 4-bit value that is biased by 1.0 and has 3-bits value with one fraction bit, so range is 1.0 to 8.5 // pattern is a line code index 0 to 10 (0 is solid) // pack major into upper byte (upper nibble -> pattern, lower nibble -> 4-bit encoded width) // pack minor into lower byte (upper nibble -> pattern, lower nibble -> 4-bit encoded width) // NB: showGeometry flag is packed into bit 16 (above major pattern) const majWt = Math.floor((Math.min(8.5, Math.max(1.0, majorWidth)) - 1.0) * 2 + 0.5); const minWt = Math.floor((Math.min(8.5, Math.max(1.0, minorWidth)) - 1.0) * 2 + 0.5); this._contourDefs[startNdx + 3] = (showGeometry ? 65536 : 0) + majorPattern * 4096 + majWt * 256 + minorPattern * 16 + minWt; } packIntervals(startNdx, even, minorInterval, majorIntervalCount) { // minorInterval is a float of interval in meters, majorIntervalCount is an int > 0 count of minor inteverals per major interval // minorInterval is stored in r or b (0 or 2) and majorIntervalCount is stored in g or a (1 or 3) depending on even or odd index const offset = (even ? 0 : 1) * 2; this._contourDefs[startNdx + offset] = minorInterval <= 0.0 ? 1.0 : minorInterval; majorIntervalCount = Math.floor(majorIntervalCount + 0.5); this._contourDefs[startNdx + offset + 1] = majorIntervalCount < 1.0 ? 1.0 : majorIntervalCount; } update(target) { if (this.contourDisplay && target.currentContours && this.contourDisplay.equals(target.currentContours)) { return; } (0, Sync_1.desync)(this); this._contourDisplay = target.currentContours; if (undefined === this.contourDisplay) return; /* uniform packing for contourDefs: The line pattern code is put into 4 bits, and the width is packed into 4 bits, so together with the pattern use 8 bits. This and the color bytes are then packed 2 bytes per float component, major in upper, as a float (e.g.: majorByte * 256 + minorByte) The minorInterval and majorCount each take a full float component, so they are combined with a second entry to use a full vec4 Because of this, the overal indexing for a given contourDef is a bit different E.g.: the first 2 contour definitions (if both used) are packed into the first 3 vec4 uniform indexes like so: 0.r = majCol[0].r << 8 | minCol[0].r (0 to 65535 as float) 0.g = majCol[0].g << 8 | minCol[0].g (0 to 65535 as float) 0.r = majCol[0].b << 8 | minCol[0].b (0 to 65535 as float) 0.r = (majPat[0] << 12 | majW[0] << 8) | (minPat[0] << 4 | minW[0]) (0 to 65535 as float) 1.r = minorInterval[0] (as float) 1.g = majorCount[0] (int, as float) 1.b = minorInterval[1] (as float) 1.a = majorCount[1] (int, as float) 2.r = majCol[1].r << 8 | minCol[1].r (0 to 65535 as float) 2.g = majCol[1].g << 8 | minCol[1].g (0 to 65535 as float) 2.r = majCol[1].b << 8 | minCol[1].b (0 to 65535 as float) 2.r = (majPat[1] << 12 | majW[1] << 8) | (minPat[1] << 4 | minW[1]) (0 to 65535 as float) Then this usage pattern repeats the same way with every 2 contour definitions used taking 3 vec4 uniforms. (If just 1 contour def remains then it takes 2 vec4 uniforms, of which 1.5 is actually used.) */ for (let index = 0, len = this.contourDisplay.groups.length; index < len && index < core_common_1.ContourDisplay.maxContourGroups; ++index) { const contourDef = this.contourDisplay.groups[index].contourDef; const even = (index & 1) === 0; const colorDefsNdx = (even ? index * 1.5 : (index - 1) * 1.5 + 2) * 4; this.packColor(colorDefsNdx, contourDef.majorStyle.color, contourDef.minorStyle.color); this.packPatWidth(colorDefsNdx, LineCode_1.LineCode.valueFromLinePixels(contourDef.majorStyle.pattern), LineCode_1.LineCode.valueFromLinePixels(contourDef.minorStyle.pattern), contourDef.majorStyle.pixelWidth, contourDef.minorStyle.pixelWidth, contourDef.showGeometry); const intervalsPairNdx = (Math.floor(index * 0.5) * 3 + 1) * 4; this.packIntervals(intervalsPairNdx, even, contourDef.minorInterval, contourDef.majorIntervalCount); } } bindcontourDefs(uniform) { if (!(0, Sync_1.sync)(this, uniform)) uniform.setUniform4fv(this._contourDefs); } } exports.ContourUniforms = ContourUniforms; //# sourceMappingURL=ContourUniforms.js.map