@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
71 lines (65 loc) • 1.64 kB
JavaScript
function reduce_even_wrap(x) {
// reduces to the range [-1, 3] by removing *even* windings:
// ... -3, -1, 1, 3, 5 ... → cycle every 2
return x - 2 * Math.floor((x + 1) * 0.5);
}
/**
* Octahedral UV wrapping.
* Full winding support without breaking octahedral seam rules.
*
* ```
* +-----+-----+
* | 6 /|\ 5 |
* | / | \ |
* | / | \ |
* | / 2 | 1 \ |
* |/ | \|
* +-----+-----+
* |\ 3 | 4 /|
* | \ | / |
* | \ | / |
* | \ | / |
* | 7 \|/ 8 |
* +-----+-----+
*```
*
* @param {number[]} out_uv - Array to write the wrapped UVs into
* @param {number} out_offset - Index to start writing at
* @param {number[]} in_uv - Input UV array (can be outside 0..1)
* @param {number} in_offset - Index to start reading from
*
* @author Alex Goldring
* @copyright Company Named Limited (c) 2025
*/
export function octahedral_uv_wrap(
out_uv, out_offset,
in_uv, in_offset
) {
let u = in_uv[in_offset];
let v = in_uv[in_offset + 1];
// First collapse infinite windings into [-1, 1] range.
u = reduce_even_wrap(u);
v = reduce_even_wrap(v);
// Left side (u < 0)
if (u < 0) {
u = -u;
v = 1 - v;
}
// Right side (u > 1)
else if (u > 1) {
u = 2 - u;
v = 1 - v;
}
// Top (v < 0)
if (v < 0) {
v = -v;
u = 1 - u;
}
// Bottom (v > 1)
else if (v > 1) {
v = 2 - v;
u = 1 - u;
}
out_uv[out_offset] = u;
out_uv[out_offset + 1] = v;
}