OpenVDB
13.0.0
Toggle main menu visibility
Loading...
Searching...
No Matches
QuantizedUnitVec.h
Go to the documentation of this file.
1
// Copyright Contributors to the OpenVDB Project
2
// SPDX-License-Identifier: Apache-2.0
3
4
#ifndef OPENVDB_MATH_QUANTIZED_UNIT_VEC_HAS_BEEN_INCLUDED
5
#define OPENVDB_MATH_QUANTIZED_UNIT_VEC_HAS_BEEN_INCLUDED
6
7
#include <
openvdb/Platform.h
>
8
#include <openvdb/version.h>
9
#include "
Vec3.h
"
10
11
namespace
openvdb
{
12
OPENVDB_USE_VERSION_NAMESPACE
13
namespace
OPENVDB_VERSION_NAME
{
14
namespace
math {
15
16
/// @brief Unit vector occupying only 16 bits
17
/// @details Stores two quantized components. Based on the
18
/// "Higher Accuracy Quantized Normals" article from GameDev.Net LLC, 2000
19
class
OPENVDB_API
QuantizedUnitVec
20
{
21
public
:
22
template
<
typename
T>
static
uint16_t
pack
(
const
Vec3<T>
& vec);
23
static
Vec3s
unpack
(
const
uint16_t data);
24
25
static
void
flipSignBits
(uint16_t&);
26
27
private
:
28
QuantizedUnitVec() {}
29
30
// bit masks
31
static
const
uint16_t MASK_SLOTS = 0x1FFF;
// 0001111111111111
32
static
const
uint16_t MASK_XSLOT = 0x1F80;
// 0001111110000000
33
static
const
uint16_t MASK_YSLOT = 0x007F;
// 0000000001111111
34
static
const
uint16_t MASK_XSIGN = 0x8000;
// 1000000000000000
35
static
const
uint16_t MASK_YSIGN = 0x4000;
// 0100000000000000
36
static
const
uint16_t MASK_ZSIGN = 0x2000;
// 0010000000000000
37
38
// normalization weights, 32 kilobytes.
39
static
float
sNormalizationWeights[MASK_SLOTS + 1];
40
};
// class QuantizedUnitVec
41
42
43
////////////////////////////////////////
44
45
46
template
<
typename
T>
47
inline
uint16_t
48
QuantizedUnitVec::pack
(
const
Vec3<T>
& vec)
49
{
50
if
(
math::isZero
(vec))
return
0;
51
52
uint16_t data = 0;
53
T x(vec[0]), y(vec[1]), z(vec[2]);
54
55
// The sign of the three components are first stored using
56
// 3-bits and can then safely be discarded.
57
if
(x < T(0.0)) { data |= MASK_XSIGN; x = -x; }
58
if
(y < T(0.0)) { data |= MASK_YSIGN; y = -y; }
59
if
(z < T(0.0)) { data |= MASK_ZSIGN; z = -z; }
60
61
// The z component is discarded and x & y are quantized in
62
// the 0 to 126 range.
63
T w = T(126.0) / (x + y + z);
64
uint16_t xbits =
static_cast<
uint16_t
>
((x * w));
65
uint16_t ybits =
static_cast<
uint16_t
>
((y * w));
66
67
// The remaining 13 bits in our 16 bit word are dividied into a
68
// 6-bit x-slot and a 7-bit y-slot. Both the xbits and the ybits
69
// can still be represented using (2^7 - 1) quantization levels.
70
71
// If the xbits requre more than 6-bits, store the complement.
72
// (xbits + ybits < 127, thus if xbits > 63 => ybits <= 63)
73
if
(xbits > 63) {
74
xbits =
static_cast<
uint16_t
>
(127 - xbits);
75
ybits =
static_cast<
uint16_t
>
(127 - ybits);
76
}
77
78
// Pack components into their respective slots.
79
data =
static_cast<
uint16_t
>
(data | (xbits << 7));
80
data =
static_cast<
uint16_t
>
(data | ybits);
81
return
data;
82
}
83
84
85
inline
Vec3s
86
QuantizedUnitVec::unpack
(
const
uint16_t data)
87
{
88
const
float
w = sNormalizationWeights[data & MASK_SLOTS];
89
90
uint16_t xbits =
static_cast<
uint16_t
>
((data & MASK_XSLOT) >> 7);
91
uint16_t ybits =
static_cast<
uint16_t
>
(data & MASK_YSLOT);
92
93
// Check if the complement components where stored and revert.
94
if
((xbits + ybits) > 126) {
95
xbits =
static_cast<
uint16_t
>
(127 - xbits);
96
ybits =
static_cast<
uint16_t
>
(127 - ybits);
97
}
98
99
Vec3s
vec(
float
(xbits) * w,
float
(ybits) * w,
float
(126 - xbits - ybits) * w);
100
101
if
(data & MASK_XSIGN) vec[0] = -vec[0];
102
if
(data & MASK_YSIGN) vec[1] = -vec[1];
103
if
(data & MASK_ZSIGN) vec[2] = -vec[2];
104
return
vec;
105
}
106
107
108
////////////////////////////////////////
109
110
111
inline
void
112
QuantizedUnitVec::flipSignBits
(uint16_t& v)
113
{
114
v =
static_cast<
uint16_t
>
((v & MASK_SLOTS) | (~v & ~MASK_SLOTS));
115
}
116
117
}
// namespace math
118
}
// namespace OPENVDB_VERSION_NAME
119
}
// namespace openvdb
120
121
#endif
// OPENVDB_MATH_QUANTIZED_UNIT_VEC_HAS_BEEN_INCLUDED
Platform.h
OPENVDB_API
#define OPENVDB_API
Definition
Platform.h:291
Vec3.h
openvdb::v13_0::math::QuantizedUnitVec::unpack
static Vec3s unpack(const uint16_t data)
Definition
QuantizedUnitVec.h:86
openvdb::v13_0::math::QuantizedUnitVec::flipSignBits
static void flipSignBits(uint16_t &)
Definition
QuantizedUnitVec.h:112
openvdb::v13_0::math::QuantizedUnitVec::pack
static uint16_t pack(const Vec3< T > &vec)
Definition
QuantizedUnitVec.h:48
openvdb::v13_0::math::Vec3
Definition
Vec3.h:25
openvdb::v13_0::math::isZero
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition
Math.h:350
openvdb::v13_0::math::Vec3s
Vec3< float > Vec3s
Definition
Vec3.h:664
openvdb
Definition
Exceptions.h:13
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition
version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition
version.h.in:218
openvdb
math
QuantizedUnitVec.h
Generated by
1.18.0