represent 0, -1 and 1 precisely by integers
| 77 | |
| 78 | // represent 0, -1 and 1 precisely by integers |
| 79 | inline uint32_t quantize_direction(const pgl_vec3f &n) |
| 80 | { |
| 81 | const float nl1 = 1.f / (std::fabs(n.x) + std::fabs(n.y) + std::fabs(n.z)); |
| 82 | pgl_vec2f pn = {n.x * nl1, n.y * nl1}; |
| 83 | if (n.z <= 0.0f) |
| 84 | { |
| 85 | pgl_vec2f signNotZero = {pn.x >= 0.0f ? 1.0f : -1.0f, pn.y >= 0.0f ? 1.0f : -1.0f}; |
| 86 | pgl_vec2f b = {std::abs(pn.y), std::abs(pn.x)}; |
| 87 | pn = {(1.f - b.x) * signNotZero.x, (1.f - b.y) * signNotZero.y}; |
| 88 | } |
| 89 | const float f = float(0x8000u); |
| 90 | const int32_t i = int(0x8000u); |
| 91 | |
| 92 | pn.x *= f; |
| 93 | pn.y *= f; |
| 94 | |
| 95 | const int32_t imin = -0x7FFF; |
| 96 | const int32_t imax = 0x7FFF; |
| 97 | const int32_t ix = std::max(imin, std::min(imax, (int32_t)pn.x)); |
| 98 | const int32_t iy = std::max(imin, std::min(imax, (int32_t)pn.y)); |
| 99 | const uint32_t ux = i + ix; |
| 100 | const uint32_t uy = i + iy; |
| 101 | return ux | (uy << 16); |
| 102 | } |
| 103 | |
| 104 | inline pgl_vec3f dequantize_direction(const uint32_t word) |
| 105 | { |
no test coverage detected