UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

101 lines (74 loc) 3.22 kB
import { assert } from "../../../../core/assert.js"; import { passThrough } from "../../../../core/function/passThrough.js"; import { clamp01 } from "../../../../core/math/clamp01.js"; import { NumericInterval } from "../../../../core/math/interval/NumericInterval.js"; import { ParameterLookupTable } from "../../../graphics/particles/particular/engine/parameter/ParameterLookupTable.js"; import { sampler2d_scale } from "../../../graphics/texture/sampler/resize/sampler2d_scale.js"; import { Sampler2D } from "../../../graphics/texture/sampler/Sampler2D.js"; import { logger } from "../../../logging/GlobalLogger.js"; const heatmap_lut = new ParameterLookupTable(4); heatmap_lut.write([ 0, 0, 0, 255, 0, 0, 255, 255, 0, 179, 179, 255, 0, 255, 0, 255, 255, 255, 0, 255, 255, 5, 5, 255 ]); heatmap_lut.computeUniformPositions(); /** * Color to use when sampled value is NaN * @type {number[]} */ const NAN_COLOR = [0, 0, 0, 0]; /** * @param {Object} params * @param {TerrainOverlay} params.overlay * @param {Sampler2D} params.sampler * @param {ParameterLookupTable} [params.lut] * @param {NumericInterval} [params.range] Range of values of interest within the sampler that are to be mapped onto LUT * @param {function(number):number} [params.lookupScaleFunction] * @param {number} [params.channel] */ export function paintTerrainOverlayViaLookupTable({ overlay, sampler, lut = heatmap_lut, range = new NumericInterval(0, 1), lookupScaleFunction = passThrough, channel = 0 }) { assert.isNonNegativeInteger(channel, 'channel'); assert.lessThan(channel, sampler.itemSize); let i, j; const colorSample = []; const w = overlay.size.x; const h = overlay.size.y; const buffer = Sampler2D.uint8(4, w, h); // rescale source const scaled_sampler = sampler.clone(); scaled_sampler.resize(w, h); sampler2d_scale(sampler, scaled_sampler); let NaN_count = 0; for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { const p = scaled_sampler.readChannel(i, j, channel); if (Number.isNaN(p)) { // handle NaN values by writing special color buffer.write(i, j, NAN_COLOR); NaN_count++; continue; } const transformed_value = lookupScaleFunction(p); const remapped_value = range.normalizeValue(transformed_value); const position = clamp01(remapped_value); lut.sample(position, colorSample); buffer.write(i, j, colorSample); } } overlay.clear(); overlay.writeData(buffer.data); if (NaN_count > 0) { logger.warn(`sampler had ${NaN_count} NaN values`); } }