@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
67 lines (63 loc) • 2.29 kB
JavaScript
/**
* Uniform float quantization to an N-bit unsigned integer.
*
* Maps `[min, max]` linearly to `[0, 2^bits - 1]` using nearest-integer rounding.
* Values outside the range are clamped. Round-trip error is bounded by
* `(max - min) / (2 * (2^bits - 1))`.
*
* Pure functions; safe to call on the hot path. Caller is responsible for
* passing the same `min`, `max`, and `bits` on both sender and receiver — there
* is no on-wire metadata.
*
* @author Alex Goldring
* @copyright Company Named Limited (c) 2025
*/
/**
* Quantize `value` from the inclusive range `[min, max]` to an unsigned integer
* in `[0, 2^bits - 1]`.
*
* Passing `NaN` for `value` returns `NaN` (both clamp comparisons are false on
* NaN, so `Math.round(NaN * max_int)` propagates). Callers must guard against
* NaN at the boundary — a downstream `DataView.setUintXX` will silently coerce
* NaN to 0, hiding the upstream bug.
*
* @param {number} value
* @param {number} min
* @param {number} max must be > min
* @param {number} bits 1..30 (keep below 31 to stay in safe signed-shift territory)
* @returns {number} unsigned integer in [0, 2^bits - 1]
*/
export function quantize_float(value, min, max, bits) {
const max_int = (1 << bits) - 1;
const normalized = (value - min) / (max - min);
const clamped = normalized < 0 ? 0 : (normalized > 1 ? 1 : normalized);
return Math.round(clamped * max_int);
}
/**
* Inverse of {@link quantize_float}. Decodes an unsigned integer back into a float
* in `[min, max]`.
*
* @param {number} quantized
* @param {number} min
* @param {number} max
* @param {number} bits
* @returns {number}
*/
export function dequantize_float(quantized, min, max, bits) {
const max_int = (1 << bits) - 1;
return min + (quantized / max_int) * (max - min);
}
/**
* Round-trip a value through quantize+dequantize. Useful when sender and receiver
* must simulate from the same quantized state to remain in sync (state-sync /
* deterministic rollback).
*
* @param {number} value
* @param {number} min
* @param {number} max
* @param {number} bits
* @returns {number}
*/
export function quantize_then_dequantize_float(value, min, max, bits) {
return dequantize_float(quantize_float(value, min, max, bits), min, max, bits);
}