OpenVDB 3.2.0

QuantizedUnitVec.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2016 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30
31 #ifndef OPENVDB_MATH_QUANTIZED_UNIT_VEC_HAS_BEEN_INCLUDED
32 #define OPENVDB_MATH_QUANTIZED_UNIT_VEC_HAS_BEEN_INCLUDED
33
34 #include <openvdb/Platform.h>
35 #include <openvdb/version.h>
36 #include "Vec3.h"
37 #include <tbb/atomic.h>
38
39 namespace openvdb {
40 OPENVDB_USE_VERSION_NAMESPACE
41 namespace OPENVDB_VERSION_NAME {
42 namespace math {
43
44
45 // Bit compression method that effciently represents a unit vector using
46 // 2 bytes i.e. 16 bits of data by only storing two quantized components.
47 // Based on "Higher Accuracy Quantized Normals" article from GameDev.Net LLC, 2000
48
49 class OPENVDB_API QuantizedUnitVec
50 {
51 public:
52
53 template <typename T>
54 static uint16_t pack(const Vec3<T>& vec);
55 static Vec3s unpack(const uint16_t data);
56
57 static void flipSignBits(uint16_t&);
58
59 private:
60 QuantizedUnitVec() {}
61
62 // threadsafe initialization function for the normalization weights.
63 static void init();
64
65 // bit masks
66 static const uint16_t MASK_SLOTS = 0x1FFF; // 0001111111111111
67 static const uint16_t MASK_XSLOT = 0x1F80; // 0001111110000000
68 static const uint16_t MASK_YSLOT = 0x007F; // 0000000001111111
69 static const uint16_t MASK_XSIGN = 0x8000; // 1000000000000000
70 static const uint16_t MASK_YSIGN = 0x4000; // 0100000000000000
71 static const uint16_t MASK_ZSIGN = 0x2000; // 0010000000000000
72
73 // initialization flag.
74 static bool sInitialized;
75
76 // normalization weights, 32 kilobytes.
77 static float sNormalizationWeights[MASK_SLOTS + 1];
78 }; // class QuantizedUnitVec
79
80
82
83
84 template <typename T>
85 inline uint16_t
86 QuantizedUnitVec::pack(const Vec3<T>& vec)
87 {
88 if (math::isZero(vec)) return 0;
89
90 uint16_t data = 0;
91 T x(vec[0]), y(vec[1]), z(vec[2]);
92
93 // The sign of the three components are first stored using
94 // 3-bits and can then safely be discarded.
95 if (x < T(0.0)) { data |= MASK_XSIGN; x = -x; }
96 if (y < T(0.0)) { data |= MASK_YSIGN; y = -y; }
97 if (z < T(0.0)) { data |= MASK_ZSIGN; z = -z; }
98
99 // The z component is discarded and x & y are quantized in
100 // the 0 to 126 range.
101 T w = T(126.0) / (x + y + z);
102 uint16_t xbits = static_cast<uint16_t>((x * w));
103 uint16_t ybits = static_cast<uint16_t>((y * w));
104
105 // The remaining 13 bits in our 16 bit word are dividied into a
106 // 6-bit x-slot and a 7-bit y-slot. Both the xbits and the ybits
107 // can still be represented using (2^7 - 1) quantization levels.
108
109 // If the xbits requre more than 6-bits, store the complement.
110 // (xbits + ybits < 127, thus if xbits > 63 => ybits <= 63)
111 if(xbits > 63) {
112 xbits = static_cast<uint16_t>(127 - xbits);
113 ybits = static_cast<uint16_t>(127 - ybits);
114 }
115
116 // Pack components into their respective slots.
117 data = static_cast<uint16_t>(data | (xbits << 7));
118 data = static_cast<uint16_t>(data | ybits);
119 return data;
120 }
121
122
123 inline Vec3s
124 QuantizedUnitVec::unpack(const uint16_t data)
125 {
126 if (!sInitialized) init();
127
128 const float w = sNormalizationWeights[data & MASK_SLOTS];
129
130 uint16_t xbits = static_cast<uint16_t>((data & MASK_XSLOT) >> 7);
131 uint16_t ybits = static_cast<uint16_t>(data & MASK_YSLOT);
132
133 // Check if the complement components where stored and revert.
134 if ((xbits + ybits) > 126) {
135 xbits = static_cast<uint16_t>(127 - xbits);
136 ybits = static_cast<uint16_t>(127 - ybits);
137 }
138
139 Vec3s vec(float(xbits) * w, float(ybits) * w, float(126 - xbits - ybits) * w);
140
141 if (data & MASK_XSIGN) vec[0] = -vec[0];
142 if (data & MASK_YSIGN) vec[1] = -vec[1];
143 if (data & MASK_ZSIGN) vec[2] = -vec[2];
144 return vec;
145 }
146
147
149
150
151 inline void
152 QuantizedUnitVec::flipSignBits(uint16_t& v)
153 {
154 v = static_cast<uint16_t>((v & MASK_SLOTS) | (~v & ~MASK_SLOTS));
155 }
156
157
158 } // namespace math
159 } // namespace OPENVDB_VERSION_NAME
160 } // namespace openvdb
161
162 #endif // OPENVDB_MATH_QUANTIZED_UNIT_VEC_HAS_BEEN_INCLUDED
163
164 // Copyright (c) 2012-2016 DreamWorks Animation LLC
165 // All rights reserved. This software is distributed under the
166 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
OPENVDB_API
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:195
Vec3.h
openvdb::v3_2_0::math::Vec3
Definition: Mat.h:146
openvdb::v3_2_0::math::isZero
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:324
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:43
openvdb
Definition: Exceptions.h:39
openvdb::v3_2_0::math::QuantizedUnitVec
Definition: QuantizedUnitVec.h:49
version.h
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Platform.h