UNPKG

ol

Version:

OpenLayers mapping library

138 lines (109 loc) 3.66 kB
/** * Returns a low part of a float value that can be encoded to Float32 without recision loss * @param {number} float Number in float64 precision * @return {number} Low part of the float value */ export function getLowPart(float) { return float - getHighPart(float); } /** * Returns a high part of a float value that can be encoded to Float32 without precision loss * @param {number} float Number in float64 precision * @return {number} High part of the float value */ export function getHighPart(float) { return Math.fround(float); } /** * These arithmetic functions are mostly inspired the ones in luma.gl: https://github.com/visgl/luma.gl/blob/master/modules/shadertools/src/modules/math/fp64/fp64-arithmetic-glsl.ts * and https://blog.cyclemap.link/2011-06-09-glsl-part2-emu/ * Note that we use the `u_one` uniform here to ensure that the compiler doesn't simplify the calculations; otherwise these will have no effect at all * @type {string} */ export const FLOAT64_ARITHMETIC_FN = ` vec2 df_from(float value) { return vec2(value, 0.); } float df_float(vec2 df) { return df.x; } vec2 df_add(vec2 dfa, vec2 dfb) { vec2 dfc; float t1, t2, e; t1 = dfa.x * u_one + dfb.x * u_one; e = t1 * u_one - dfa.x * u_one; t2 = ((dfb.x - e) + (dfa.x - (t1 - e))) * u_one + dfa.y + dfb.y * u_one; dfc.x = t1 * u_one + t2 * u_one; dfc.y = t2 - (dfc.x - t1) * u_one; return dfc; } vec2 df_sub(vec2 dfa, vec2 dfb) { vec2 dfc; float e, t1, t2; t1 = dfa.x - dfb.x; e = t1 - dfa.x; t2 = ((-dfb.x - e) + (dfa.x - (t1 - e))) + dfa.y - dfb.y; dfc.x = t1 + t2; dfc.y = t2 - (dfc.x - t1); return dfc; } vec2 df_mul(vec2 dfa, vec2 dfb) { vec2 dfc; float c11, c21, c2, e, t1, t2; float a1, a2, b1, b2, cona, conb, split = 4097.; cona = dfa.x * split * u_one; conb = dfb.x * split * u_one; a1 = cona * u_one - (cona - dfa.x); b1 = conb * u_one - (conb - dfb.x); a2 = dfa.x * u_one - a1; b2 = dfb.x * u_one - b1 * u_one; c11 = dfa.x * u_one * dfb.x * u_one; c21 = a2 * b2 * u_one + (a2 * b1 + (a1 * b2 + (a1 * b1 - c11))) * u_one; c2 = dfa.x * dfb.y * u_one + dfa.y * dfb.x * u_one; t1 = c11 + c2 * u_one; e = t1 - c11 * u_one; t2 = dfa.y * dfb.y * u_one + ((c2 - e) + (c11 - (t1 - e))) + c21 * u_one; dfc.x = t1 * u_one + t2 * u_one; dfc.y = t2 - (dfc.x - t1) * u_one; return dfc; } vec2 df_div(vec2 dfa, vec2 dfb) { vec2 dfc; float c11, c21, c2, e, t1, t2, t11, t12, t21, t22; float a1, a2, b1, b2, cona, conb, split = 4097.; float s1, s2; s1 = dfa.x / dfb.x * u_one; cona = s1 * split * u_one; conb = dfb.x * split * u_one; a1 = cona - (cona - s1) * u_one; b1 = conb - (conb - dfb.x) * u_one; a2 = s1 - a1 * u_one; b2 = dfb.x - b1 * u_one; c11 = s1 * dfb.x * u_one; c21 = (((a1 * b1 - c11) + a1 * b2) + a2 * b1) + a2 * b2 * u_one; c2 = s1 * dfb.y * u_one; t1 = c11 + c2 * u_one; e = t1 - c11 * u_one; t2 = ((c2 - e) + (c11 - (t1 - e))) + c21 * u_one; t12 = t1 + t2 * u_one; t22 = t2 - (t12 - t1) * u_one; t11 = dfa.x - t12 * u_one; e = t11 - dfa.x * u_one; t21 = ((-t12 - e) + (dfa.x - (t11 - e))) + dfa.y - t22 * u_one; s2 = (t11 + t21) / dfb.x * u_one; dfc.x = s1 + s2 * u_one; dfc.y = s2 - (dfc.x - s1) * u_one; return dfc; } float df_mod(vec2 df, vec2 m) { vec2 q = df_div(df, m) * u_one; float qf = floor(q.x); float frac = q.x - qf + q.y * u_one; if (frac < 0.0) qf -= 1.0; if (frac >= 1.0) qf += 1.0; vec2 prod = df_mul(df_from(qf), m); vec2 rem = df_add(df_from(df.x), df_from(-prod.x)) * u_one; rem.y += df.y - prod.y; return rem.x + rem.y * u_one; } `;