ovr_sdk

view LibOVR/Src/Net/OVR_BitStream.h @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
line source
1 /************************************************************************************
3 PublicHeader: n/a
4 Filename : OVR_BitStream.h
5 Content : A generic serialization toolkit for packing data to a binary stream.
6 Created : June 10, 2014
7 Authors : Kevin Jenkins
9 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
11 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
12 you may not use the Oculus VR Rift SDK except in compliance with the License,
13 which is provided at the time of installation or download, or which
14 otherwise accompanies this software in either electronic or hard copy form.
16 You may obtain a copy of the License at
18 http://www.oculusvr.com/licenses/LICENSE-3.2
20 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
21 distributed under the License is distributed on an "AS IS" BASIS,
22 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 See the License for the specific language governing permissions and
24 limitations under the License.
26 ************************************************************************************/
28 #ifndef OVR_Bitstream_h
29 #define OVR_Bitstream_h
31 #include <math.h>
32 #include "../Kernel/OVR_Types.h"
33 #include "../Kernel/OVR_Std.h"
34 #include "../Kernel/OVR_String.h"
36 namespace OVR { namespace Net {
38 typedef uint32_t BitSize_t;
39 #define BITSTREAM_STACK_ALLOCATION_SIZE 256
40 #define BITS_TO_BYTES(x) (((x)+7)>>3)
41 #define BYTES_TO_BITS(x) ((x)<<3)
44 //-----------------------------------------------------------------------------
45 // BitStream
47 // Generic serialization class to binary stream
48 class BitStream : public NewOverrideBase
49 {
50 public:
51 /// Default Constructor
52 BitStream();
54 /// \brief Create the bitstream, with some number of bytes to immediately allocate.
55 /// \details There is no benefit to calling this, unless you know exactly how many bytes you need and it is greater than BITSTREAM_STACK_ALLOCATION_SIZE.
56 /// In that case all it does is save you one or more realloc calls.
57 /// \param[in] initialBytesToAllocate the number of bytes to pre-allocate.
58 BitStream( const unsigned int initialBytesToAllocate );
60 /// \brief Initialize the BitStream, immediately setting the data it contains to a predefined pointer.
61 /// \details Set \a _copyData to true if you want to make an internal copy of the data you are passing. Set it to false to just save a pointer to the data.
62 /// You shouldn't call Write functions with \a _copyData as false, as this will write to unallocated memory
63 /// 99% of the time you will use this function to cast Packet::data to a bitstream for reading, in which case you should write something as follows:
64 /// \code
65 /// RakNet::BitStream bs(packet->data, packet->length, false);
66 /// \endcode
67 /// \param[in] _data An array of bytes.
68 /// \param[in] lengthInBytes Size of the \a _data.
69 /// \param[in] _copyData true or false to make a copy of \a _data or not.
70 BitStream( char* _data, const unsigned int lengthInBytes, bool _copyData );
72 // Destructor
73 ~BitStream();
75 public:
76 /// Resets the bitstream for reuse.
77 void Reset( void );
79 /// \brief Bidirectional serialize/deserialize any integral type to/from a bitstream.
80 /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping.
81 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
82 /// \param[in] inOutTemplateVar The value to write
83 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
84 template <class templateType>
85 bool Serialize(bool writeToBitstream, templateType &inOutTemplateVar);
87 /// \brief Bidirectional serialize/deserialize any integral type to/from a bitstream.
88 /// \details If the current value is different from the last value
89 /// the current value will be written. Otherwise, a single bit will be written
90 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
91 /// \param[in] inOutCurrentValue The current value to write
92 /// \param[in] lastValue The last value to compare against. Only used if \a writeToBitstream is true.
93 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
94 template <class templateType>
95 bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue);
97 /// \brief Bidirectional version of SerializeDelta when you don't know what the last value is, or there is no last value.
98 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
99 /// \param[in] inOutCurrentValue The current value to write
100 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
101 template <class templateType>
102 bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue);
104 /// \brief Bidirectional serialize/deserialize any integral type to/from a bitstream.
105 /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping.
106 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
107 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
108 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
109 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
110 /// \param[in] inOutTemplateVar The value to write
111 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
112 template <class templateType>
113 bool SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar);
115 /// \brief Bidirectional serialize/deserialize any integral type to/from a bitstream.
116 /// \details If the current value is different from the last value
117 /// the current value will be written. Otherwise, a single bit will be written
118 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
119 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
120 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
121 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
122 /// \param[in] inOutCurrentValue The current value to write
123 /// \param[in] lastValue The last value to compare against. Only used if \a writeToBitstream is true.
124 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
125 template <class templateType>
126 bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue);
128 /// \brief Save as SerializeCompressedDelta(templateType &currentValue, const templateType &lastValue) when we have an unknown second parameter
129 /// \return true on data read. False on insufficient data in bitstream
130 template <class templateType>
131 bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutTemplateVar);
133 /// \brief Bidirectional serialize/deserialize an array or casted stream or raw data. This does NOT do endian swapping.
134 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
135 /// \param[in] inOutByteArray a byte buffer
136 /// \param[in] numberOfBytes the size of \a input in bytes
137 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
138 bool Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes );
140 /// \brief Serialize a float into 2 bytes, spanning the range between \a floatMin and \a floatMax
141 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
142 /// \param[in] inOutFloat The float to write
143 /// \param[in] floatMin Predetermined minimum value of f
144 /// \param[in] floatMax Predetermined maximum value of f
145 bool SerializeFloat16(bool writeToBitstream, float &inOutFloat, float floatMin, float floatMax);
147 /// Serialize one type casted to another (smaller) type, to save bandwidth
148 /// serializationType should be uint8_t, uint16_t, uint24_t, or uint32_t
149 /// Example: int num=53; SerializeCasted<uint8_t>(true, num); would use 1 byte to write what would otherwise be an integer (4 or 8 bytes)
150 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
151 /// \param[in] value The value to serialize
152 template <class serializationType, class sourceType >
153 bool SerializeCasted( bool writeToBitstream, sourceType &value );
155 /// Given the minimum and maximum values for an integer type, figure out the minimum number of bits to represent the range
156 /// Then serialize only those bits
157 /// \note A static is used so that the required number of bits for (maximum-minimum) is only calculated once. This does require that \a minimum and \maximum are fixed values for a given line of code for the life of the program
158 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
159 /// \param[in] value Integer value to write, which should be between \a minimum and \a maximum
160 /// \param[in] minimum Minimum value of \a value
161 /// \param[in] maximum Maximum value of \a value
162 /// \param[in] allowOutsideRange If true, all sends will take an extra bit, however value can deviate from outside \a minimum and \a maximum. If false, will assert if the value deviates
163 template <class templateType>
164 bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange=false );
165 /// \param[in] requiredBits Primarily for internal use, called from above function() after calculating number of bits needed to represent maximum-minimum
166 template <class templateType>
167 bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange=false );
169 /// \brief Bidirectional serialize/deserialize a normalized 3D vector, using (at most) 4 bytes + 3 bits instead of 12-24 bytes.
170 /// \details Will further compress y or z axis aligned vectors.
171 /// Accurate to 1/32767.5.
172 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
173 /// \param[in] x x
174 /// \param[in] y y
175 /// \param[in] z z
176 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
177 template <class templateType> // templateType for this function must be a float or double
178 bool SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z );
180 /// \brief Bidirectional serialize/deserialize a vector, using 10 bytes instead of 12.
181 /// \details Loses accuracy to about 3/10ths and only saves 2 bytes, so only use if accuracy is not important.
182 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
183 /// \param[in] x x
184 /// \param[in] y y
185 /// \param[in] z z
186 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
187 template <class templateType> // templateType for this function must be a float or double
188 bool SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z );
190 /// \brief Bidirectional serialize/deserialize a normalized quaternion in 6 bytes + 4 bits instead of 16 bytes. Slightly lossy.
191 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
192 /// \param[in] w w
193 /// \param[in] x x
194 /// \param[in] y y
195 /// \param[in] z z
196 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
197 template <class templateType> // templateType for this function must be a float or double
198 bool SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z);
200 /// \brief Bidirectional serialize/deserialize an orthogonal matrix by creating a quaternion, and writing 3 components of the quaternion in 2 bytes each.
201 /// \details Use 6 bytes instead of 36
202 /// Lossy, although the result is renormalized
203 /// \return true on success, false on failure.
204 template <class templateType> // templateType for this function must be a float or double
205 bool SerializeOrthMatrix(
206 bool writeToBitstream,
207 templateType &m00, templateType &m01, templateType &m02,
208 templateType &m10, templateType &m11, templateType &m12,
209 templateType &m20, templateType &m21, templateType &m22 );
211 /// \brief Bidirectional serialize/deserialize numberToSerialize bits to/from the input.
212 /// \details Right aligned data means in the case of a partial byte, the bits are aligned
213 /// from the right (bit 0) rather than the left (as in the normal
214 /// internal representation) You would set this to true when
215 /// writing user data, and false when copying bitstream data, such
216 /// as writing one bitstream to another
217 /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data
218 /// \param[in] inOutByteArray The data
219 /// \param[in] numberOfBitsToSerialize The number of bits to write
220 /// \param[in] rightAlignedBits if true data will be right aligned
221 /// \return true if \a writeToBitstream is true. true if \a writeToBitstream is false and the read was successful. false if \a writeToBitstream is false and the read was not successful.
222 bool SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits = true );
224 /// \brief Write any integral type to a bitstream.
225 /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping.
226 /// \param[in] inTemplateVar The value to write
227 template <class templateType>
228 void Write(const templateType &inTemplateVar);
230 /// \brief Write the dereferenced pointer to any integral type to a bitstream.
231 /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping.
232 /// \param[in] inTemplateVar The value to write
233 template <class templateType>
234 void WritePtr(templateType *inTemplateVar);
236 /// \brief Write any integral type to a bitstream.
237 /// \details If the current value is different from the last value
238 /// the current value will be written. Otherwise, a single bit will be written
239 /// \param[in] currentValue The current value to write
240 /// \param[in] lastValue The last value to compare against
241 template <class templateType>
242 void WriteDelta(const templateType &currentValue, const templateType &lastValue);
244 /// \brief WriteDelta when you don't know what the last value is, or there is no last value.
245 /// \param[in] currentValue The current value to write
246 template <class templateType>
247 void WriteDelta(const templateType &currentValue);
249 /// \brief Write any integral type to a bitstream.
250 /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping.
251 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
252 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
253 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
254 /// \param[in] inTemplateVar The value to write
255 template <class templateType>
256 void WriteCompressed(const templateType &inTemplateVar);
258 /// \brief Write any integral type to a bitstream.
259 /// \details If the current value is different from the last value
260 /// the current value will be written. Otherwise, a single bit will be written
261 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
262 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
263 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
264 /// \param[in] currentValue The current value to write
265 /// \param[in] lastValue The last value to compare against
266 template <class templateType>
267 void WriteCompressedDelta(const templateType &currentValue, const templateType &lastValue);
269 /// \brief Save as WriteCompressedDelta(const templateType &currentValue, const templateType &lastValue) when we have an unknown second parameter
270 template <class templateType>
271 void WriteCompressedDelta(const templateType &currentValue);
273 /// \brief Read any integral type from a bitstream.
274 /// \details Define __BITSTREAM_NATIVE_END if you need endian swapping.
275 /// \param[in] outTemplateVar The value to read
276 /// \return true on success, false on failure.
277 template <class templateType>
278 bool Read(templateType &outTemplateVar);
280 /// \brief Read any integral type from a bitstream.
281 /// \details If the written value differed from the value compared against in the write function,
282 /// var will be updated. Otherwise it will retain the current value.
283 /// ReadDelta is only valid from a previous call to WriteDelta
284 /// \param[in] outTemplateVar The value to read
285 /// \return true on success, false on failure.
286 template <class templateType>
287 bool ReadDelta(templateType &outTemplateVar);
289 /// \brief Read any integral type from a bitstream.
290 /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping.
291 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
292 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
293 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
294 /// \param[in] outTemplateVar The value to read
295 /// \return true on success, false on failure.
296 template <class templateType>
297 bool ReadCompressed(templateType &outTemplateVar);
299 /// \brief Read any integral type from a bitstream.
300 /// \details If the written value differed from the value compared against in the write function,
301 /// var will be updated. Otherwise it will retain the current value.
302 /// the current value will be updated.
303 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
304 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
305 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
306 /// ReadCompressedDelta is only valid from a previous call to WriteDelta
307 /// \param[in] outTemplateVar The value to read
308 /// \return true on success, false on failure.
309 template <class templateType>
310 bool ReadCompressedDelta(templateType &outTemplateVar);
312 /// \brief Read one bitstream to another.
313 /// \param[in] numberOfBits bits to read
314 /// \param bitStream the bitstream to read into from
315 /// \return true on success, false on failure.
316 bool Read( BitStream *bitStream, BitSize_t numberOfBits );
317 bool Read( BitStream *bitStream );
318 bool Read( BitStream &bitStream, BitSize_t numberOfBits );
319 bool Read( BitStream &bitStream );
321 /// \brief Write an array or casted stream or raw data. This does NOT do endian swapping.
322 /// \param[in] inputByteArray a byte buffer
323 /// \param[in] numberOfBytes the size of \a input in bytes
324 void Write( const char* inputByteArray, const unsigned int numberOfBytes );
326 /// \brief Write one bitstream to another.
327 /// \param[in] numberOfBits bits to write
328 /// \param bitStream the bitstream to copy from
329 void Write( BitStream *bitStream, BitSize_t numberOfBits );
330 void Write( BitStream *bitStream );
331 void Write( BitStream &bitStream, BitSize_t numberOfBits );
332 void Write( BitStream &bitStream );\
334 /// \brief Write a float into 2 bytes, spanning the range between \a floatMin and \a floatMax
335 /// \param[in] x The float to write
336 /// \param[in] floatMin Predetermined minimum value of f
337 /// \param[in] floatMax Predetermined maximum value of f
338 void WriteFloat16( float x, float floatMin, float floatMax );
340 /// Write one type serialized as another (smaller) type, to save bandwidth
341 /// serializationType should be uint8_t, uint16_t, uint24_t, or uint32_t
342 /// Example: int num=53; WriteCasted<uint8_t>(num); would use 1 byte to write what would otherwise be an integer (4 or 8 bytes)
343 /// \param[in] value The value to write
344 template <class serializationType, class sourceType >
345 void WriteCasted( const sourceType &value );
347 /// Given the minimum and maximum values for an integer type, figure out the minimum number of bits to represent the range
348 /// Then write only those bits
349 /// \note A static is used so that the required number of bits for (maximum-minimum) is only calculated once. This does require that \a minimum and \maximum are fixed values for a given line of code for the life of the program
350 /// \param[in] value Integer value to write, which should be between \a minimum and \a maximum
351 /// \param[in] minimum Minimum value of \a value
352 /// \param[in] maximum Maximum value of \a value
353 /// \param[in] allowOutsideRange If true, all sends will take an extra bit, however value can deviate from outside \a minimum and \a maximum. If false, will assert if the value deviates. This should match the corresponding value passed to Read().
354 template <class templateType>
355 void WriteBitsFromIntegerRange( const templateType value, const templateType minimum, const templateType maximum, bool allowOutsideRange=false );
356 /// \param[in] requiredBits Primarily for internal use, called from above function() after calculating number of bits needed to represent maximum-minimum
357 template <class templateType>
358 void WriteBitsFromIntegerRange( const templateType value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange=false );
360 /// \brief Write a normalized 3D vector, using (at most) 4 bytes + 3 bits instead of 12-24 bytes.
361 /// \details Will further compress y or z axis aligned vectors.
362 /// Accurate to 1/32767.5.
363 /// \param[in] x x
364 /// \param[in] y y
365 /// \param[in] z z
366 template <class templateType> // templateType for this function must be a float or double
367 void WriteNormVector( templateType x, templateType y, templateType z );
369 /// \brief Write a vector, using 10 bytes instead of 12.
370 /// \details Loses accuracy to about 3/10ths and only saves 2 bytes,
371 /// so only use if accuracy is not important.
372 /// \param[in] x x
373 /// \param[in] y y
374 /// \param[in] z z
375 template <class templateType> // templateType for this function must be a float or double
376 void WriteVector( templateType x, templateType y, templateType z );
378 /// \brief Write a normalized quaternion in 6 bytes + 4 bits instead of 16 bytes. Slightly lossy.
379 /// \param[in] w w
380 /// \param[in] x x
381 /// \param[in] y y
382 /// \param[in] z z
383 template <class templateType> // templateType for this function must be a float or double
384 void WriteNormQuat( templateType w, templateType x, templateType y, templateType z);
386 /// \brief Write an orthogonal matrix by creating a quaternion, and writing 3 components of the quaternion in 2 bytes each.
387 /// \details Use 6 bytes instead of 36
388 /// Lossy, although the result is renormalized
389 template <class templateType> // templateType for this function must be a float or double
390 void WriteOrthMatrix(
391 templateType m00, templateType m01, templateType m02,
392 templateType m10, templateType m11, templateType m12,
393 templateType m20, templateType m21, templateType m22 );
395 /// \brief Read an array or casted stream of byte.
396 /// \details The array is raw data. There is no automatic endian conversion with this function
397 /// \param[in] output The result byte array. It should be larger than @em numberOfBytes.
398 /// \param[in] numberOfBytes The number of byte to read
399 /// \return true on success false if there is some missing bytes.
400 bool Read( char* output, const unsigned int numberOfBytes );
402 /// \brief Read a float into 2 bytes, spanning the range between \a floatMin and \a floatMax
403 /// \param[in] outFloat The float to read
404 /// \param[in] floatMin Predetermined minimum value of f
405 /// \param[in] floatMax Predetermined maximum value of f
406 bool ReadFloat16( float &outFloat, float floatMin, float floatMax );
408 /// Read one type serialized to another (smaller) type, to save bandwidth
409 /// serializationType should be uint8_t, uint16_t, uint24_t, or uint32_t
410 /// Example: int num; ReadCasted<uint8_t>(num); would read 1 bytefrom the stream, and put the value in an integer
411 /// \param[in] value The value to write
412 template <class serializationType, class sourceType >
413 bool ReadCasted( sourceType &value );
415 /// Given the minimum and maximum values for an integer type, figure out the minimum number of bits to represent the range
416 /// Then read only those bits
417 /// \note A static is used so that the required number of bits for (maximum-minimum) is only calculated once. This does require that \a minimum and \maximum are fixed values for a given line of code for the life of the program
418 /// \param[in] value Integer value to read, which should be between \a minimum and \a maximum
419 /// \param[in] minimum Minimum value of \a value
420 /// \param[in] maximum Maximum value of \a value
421 /// \param[in] allowOutsideRange If true, all sends will take an extra bit, however value can deviate from outside \a minimum and \a maximum. If false, will assert if the value deviates. This should match the corresponding value passed to Write().
422 template <class templateType>
423 bool ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange=false );
424 /// \param[in] requiredBits Primarily for internal use, called from above function() after calculating number of bits needed to represent maximum-minimum
425 template <class templateType>
426 bool ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange=false );
428 /// \brief Read a normalized 3D vector, using (at most) 4 bytes + 3 bits instead of 12-24 bytes.
429 /// \details Will further compress y or z axis aligned vectors.
430 /// Accurate to 1/32767.5.
431 /// \param[in] x x
432 /// \param[in] y y
433 /// \param[in] z z
434 /// \return true on success, false on failure.
435 template <class templateType> // templateType for this function must be a float or double
436 bool ReadNormVector( templateType &x, templateType &y, templateType &z );
438 /// \brief Read 3 floats or doubles, using 10 bytes, where those float or doubles comprise a vector.
439 /// \details Loses accuracy to about 3/10ths and only saves 2 bytes,
440 /// so only use if accuracy is not important.
441 /// \param[in] x x
442 /// \param[in] y y
443 /// \param[in] z z
444 /// \return true on success, false on failure.
445 template <class templateType> // templateType for this function must be a float or double
446 bool ReadVector( templateType &x, templateType &y, templateType &z );
448 /// \brief Read a normalized quaternion in 6 bytes + 4 bits instead of 16 bytes.
449 /// \param[in] w w
450 /// \param[in] x x
451 /// \param[in] y y
452 /// \param[in] z z
453 /// \return true on success, false on failure.
454 template <class templateType> // templateType for this function must be a float or double
455 bool ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z);
457 /// \brief Read an orthogonal matrix from a quaternion, reading 3 components of the quaternion in 2 bytes each and extrapolatig the 4th.
458 /// \details Use 6 bytes instead of 36
459 /// Lossy, although the result is renormalized
460 /// \return true on success, false on failure.
461 template <class templateType> // templateType for this function must be a float or double
462 bool ReadOrthMatrix(
463 templateType &m00, templateType &m01, templateType &m02,
464 templateType &m10, templateType &m11, templateType &m12,
465 templateType &m20, templateType &m21, templateType &m22 );
467 /// \brief Sets the read pointer back to the beginning of your data.
468 void ResetReadPointer( void );
470 /// \brief Sets the write pointer back to the beginning of your data.
471 void ResetWritePointer( void );
473 /// \brief This is good to call when you are done with the stream to make
474 /// sure you didn't leave any data left over void
475 void AssertStreamEmpty( void );
477 /// \brief RAKNET_DEBUG_PRINTF the bits in the stream. Great for debugging.
478 void PrintBits( char *out ) const;
479 void PrintBits( void ) const;
480 void PrintHex( char *out ) const;
481 void PrintHex( void ) const;
483 /// \brief Ignore data we don't intend to read
484 /// \param[in] numberOfBits The number of bits to ignore
485 void IgnoreBits( const BitSize_t numberOfBits );
487 /// \brief Ignore data we don't intend to read
488 /// \param[in] numberOfBits The number of bytes to ignore
489 void IgnoreBytes( const unsigned int numberOfBytes );
491 /// \brief Move the write pointer to a position on the array.
492 /// \param[in] offset the offset from the start of the array.
493 /// \attention
494 /// \details Dangerous if you don't know what you are doing!
495 /// For efficiency reasons you can only write mid-stream if your data is byte aligned.
496 void SetWriteOffset( const BitSize_t offset );
498 /// \brief Returns the length in bits of the stream
499 inline BitSize_t GetNumberOfBitsUsed( void ) const {return GetWriteOffset();}
500 inline BitSize_t GetWriteOffset( void ) const {return numberOfBitsUsed;}
502 /// \brief Returns the length in bytes of the stream
503 inline BitSize_t GetNumberOfBytesUsed( void ) const {return BITS_TO_BYTES( numberOfBitsUsed );}
505 /// \brief Returns the number of bits into the stream that we have read
506 inline BitSize_t GetReadOffset( void ) const {return readOffset;}
508 /// \brief Sets the read bit index
509 void SetReadOffset( const BitSize_t newReadOffset ) {readOffset=newReadOffset;}
511 /// \brief Returns the number of bits left in the stream that haven't been read
512 inline BitSize_t GetNumberOfUnreadBits( void ) const {return numberOfBitsUsed - readOffset;}
514 /// \brief Makes a copy of the internal data for you \a _data will point to
515 /// the stream. Partial bytes are left aligned.
516 /// \param[out] _data The allocated copy of GetData()
517 /// \return The length in bits of the stream.
518 BitSize_t CopyData( unsigned char** _data ) const;
520 /// \internal
521 /// Set the stream to some initial data.
522 void SetData( unsigned char *inByteArray );
524 /// Gets the data that BitStream is writing to / reading from.
525 /// Partial bytes are left aligned.
526 /// \return A pointer to the internal state
527 inline char* GetData( void ) const {return (char*) data;}
529 /// \brief Write numberToWrite bits from the input source.
530 /// \details Right aligned data means in the case of a partial byte, the bits are aligned
531 /// from the right (bit 0) rather than the left (as in the normal
532 /// internal representation) You would set this to true when
533 /// writing user data, and false when copying bitstream data, such
534 /// as writing one bitstream to another.
535 /// \param[in] inByteArray The data
536 /// \param[in] numberOfBitsToWrite The number of bits to write
537 /// \param[in] rightAlignedBits if true data will be right aligned
538 void WriteBits( const unsigned char* inByteArray, BitSize_t numberOfBitsToWrite, const bool rightAlignedBits = true );
540 /// \brief Align the bitstream to the byte boundary and then write the
541 /// specified number of bits.
542 /// \details This is faster than WriteBits but
543 /// wastes the bits to do the alignment and requires you to call
544 /// ReadAlignedBits at the corresponding read position.
545 /// \param[in] inByteArray The data
546 /// \param[in] numberOfBytesToWrite The size of input.
547 void WriteAlignedBytes( const unsigned char *inByteArray, const unsigned int numberOfBytesToWrite );
549 // Endian swap bytes already in the bitstream
550 void EndianSwapBytes( int byteOffset, int length );
552 /// \brief Aligns the bitstream, writes inputLength, and writes input. Won't write beyond maxBytesToWrite
553 /// \param[in] inByteArray The data
554 /// \param[in] inputLength The size of input.
555 /// \param[in] maxBytesToWrite Max bytes to write
556 void WriteAlignedBytesSafe( const char *inByteArray, const unsigned int inputLength, const unsigned int maxBytesToWrite );
558 /// \brief Read bits, starting at the next aligned bits.
559 /// \details Note that the modulus 8 starting offset of the sequence must be the same as
560 /// was used with WriteBits. This will be a problem with packet
561 /// coalescence unless you byte align the coalesced packets.
562 /// \param[in] inOutByteArray The byte array larger than @em numberOfBytesToRead
563 /// \param[in] numberOfBytesToRead The number of byte to read from the internal state
564 /// \return true if there is enough byte.
565 bool ReadAlignedBytes( unsigned char *inOutByteArray, const unsigned int numberOfBytesToRead );
567 /// \brief Reads what was written by WriteAlignedBytesSafe.
568 /// \param[in] inOutByteArray The data
569 /// \param[in] maxBytesToRead Maximum number of bytes to read
570 /// \return true on success, false on failure.
571 bool ReadAlignedBytesSafe( char *inOutByteArray, int &inputLength, const int maxBytesToRead );
572 bool ReadAlignedBytesSafe( char *inOutByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead );
574 /// \brief Same as ReadAlignedBytesSafe() but allocates the memory for you using new, rather than assuming it is safe to write to
575 /// \param[in] outByteArray outByteArray will be deleted if it is not a pointer to 0
576 /// \return true on success, false on failure.
577 bool ReadAlignedBytesSafeAlloc( char **outByteArray, int &inputLength, const unsigned int maxBytesToRead );
578 bool ReadAlignedBytesSafeAlloc( char **outByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead );
580 /// \brief Align the next write and/or read to a byte boundary.
581 /// \details This can be used to 'waste' bits to byte align for efficiency reasons It
582 /// can also be used to force coalesced bitstreams to start on byte
583 /// boundaries so so WriteAlignedBits and ReadAlignedBits both
584 /// calculate the same offset when aligning.
585 inline void AlignWriteToByteBoundary( void ) {numberOfBitsUsed += 8 - ( (( numberOfBitsUsed - 1 ) & 7) + 1 );}
587 /// \brief Align the next write and/or read to a byte boundary.
588 /// \details This can be used to 'waste' bits to byte align for efficiency reasons It
589 /// can also be used to force coalesced bitstreams to start on byte
590 /// boundaries so so WriteAlignedBits and ReadAlignedBits both
591 /// calculate the same offset when aligning.
592 inline void AlignReadToByteBoundary( void ) {readOffset += 8 - ( (( readOffset - 1 ) & 7 ) + 1 );}
594 /// \brief Read \a numberOfBitsToRead bits to the output source.
595 /// \details alignBitsToRight should be set to true to convert internal
596 /// bitstream data to userdata. It should be false if you used
597 /// WriteBits with rightAlignedBits false
598 /// \param[in] inOutByteArray The resulting bits array
599 /// \param[in] numberOfBitsToRead The number of bits to read
600 /// \param[in] alignBitsToRight if true bits will be right aligned.
601 /// \return true if there is enough bits to read
602 bool ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsToRead, const bool alignBitsToRight = true );
604 /// \brief Write a 0
605 void Write0( void );
607 /// \brief Write a 1
608 void Write1( void );
610 /// \brief Reads 1 bit and returns true if that bit is 1 and false if it is 0.
611 bool ReadBit( void );
613 /// \brief If we used the constructor version with copy data off, this
614 /// *makes sure it is set to on and the data pointed to is copied.
615 void AssertCopyData( void );
617 /// \brief Use this if you pass a pointer copy to the constructor
618 /// *(_copyData==false) and want to overallocate to prevent
619 /// reallocation.
620 void SetNumberOfBitsAllocated( const BitSize_t lengthInBits );
622 /// \brief Reallocates (if necessary) in preparation of writing numberOfBitsToWrite
623 void AddBitsAndReallocate( const BitSize_t numberOfBitsToWrite );
625 /// \internal
626 /// \return How many bits have been allocated internally
627 BitSize_t GetNumberOfBitsAllocated(void) const;
629 /// Write zeros until the bitstream is filled up to \a bytes
630 void PadWithZeroToByteLength( unsigned int bytes );
632 /// Get the number of leading zeros for a number
633 /// \param[in] x Number to test
634 static int NumberOfLeadingZeroes( uint8_t x );
635 static int NumberOfLeadingZeroes( uint16_t x );
636 static int NumberOfLeadingZeroes( uint32_t x );
637 static int NumberOfLeadingZeroes( uint64_t x );
638 static int NumberOfLeadingZeroes( int8_t x );
639 static int NumberOfLeadingZeroes( int16_t x );
640 static int NumberOfLeadingZeroes( int32_t x );
641 static int NumberOfLeadingZeroes( int64_t x );
643 /// \internal Unrolled inner loop, for when performance is critical
644 void WriteAlignedVar8(const char *inByteArray);
645 /// \internal Unrolled inner loop, for when performance is critical
646 bool ReadAlignedVar8(char *inOutByteArray);
647 /// \internal Unrolled inner loop, for when performance is critical
648 void WriteAlignedVar16(const char *inByteArray);
649 /// \internal Unrolled inner loop, for when performance is critical
650 bool ReadAlignedVar16(char *inOutByteArray);
651 /// \internal Unrolled inner loop, for when performance is critical
652 void WriteAlignedVar32(const char *inByteArray);
653 /// \internal Unrolled inner loop, for when performance is critical
654 bool ReadAlignedVar32(char *inOutByteArray);
656 inline void Write(const char * const inStringVar)
657 {
658 uint16_t l = (uint16_t) OVR_strlen(inStringVar);
659 Write(l);
660 WriteAlignedBytes((const unsigned char*) inStringVar, (const unsigned int) l);
661 }
662 inline void Write(const unsigned char * const inTemplateVar)
663 {
664 Write((const char*)inTemplateVar);
665 }
666 inline void Write(char * const inTemplateVar)
667 {
668 Write((const char*)inTemplateVar);
669 }
670 inline void Write(unsigned char * const inTemplateVar)
671 {
672 Write((const char*)inTemplateVar);
673 }
675 /// ---- Member function template specialization declarations ----
676 // Used for VC7
677 #if defined(OVR_CC_MSVC) && _MSC_VER == 1300
678 /// Write a bool to a bitstream.
679 /// \param[in] var The value to write
680 template <>
681 void Write(const bool &var);
683 /// Write a RakNetGUID to a bitsteam
684 /// \param[in] var The value to write
685 template <>
686 void Write(const RakNetGuid &var);
688 /// Write a string to a bitstream
689 /// \param[in] var The value to write
690 template <>
691 void Write(const char* const &var);
692 template <>
693 void Write(const unsigned char* const &var);
694 template <>
695 void Write(char* const &var);
696 template <>
697 void Write(unsigned char* const &var);
698 template <>
699 void Write(const OVR::String &var);
701 /// \brief Write a bool delta.
702 /// \details Same thing as just calling Write
703 /// \param[in] currentValue The current value to write
704 /// \param[in] lastValue The last value to compare against
705 template <>
706 void WriteDelta(const bool &currentValue, const bool &lastValue);
708 template <>
709 void WriteCompressed(const bool &var);
711 /// For values between -1 and 1
712 template <>
713 void WriteCompressed(const float &var);
715 /// For values between -1 and 1
716 template <>
717 void WriteCompressed(const double &var);
719 /// \brief Write a bool delta.
720 /// \details Same thing as just calling Write
721 /// \param[in] currentValue The current value to write
722 /// \param[in] lastValue The last value to compare against
723 template <>
724 void WriteCompressedDelta(const bool &currentValue, const bool &lastValue);
726 /// \brief Save as WriteCompressedDelta(bool currentValue, const templateType &lastValue)
727 /// when we have an unknown second bool
728 template <>
729 void WriteCompressedDelta(const bool &currentValue);
731 /// \brief Read a bool from a bitstream.
732 /// \param[in] var The value to read
733 /// \return true on success, false on failure.
734 template <>
735 bool Read(bool &var);
737 /// \brief Read a String from a bitstream.
738 /// \param[in] var The value to read
739 /// \return true on success, false on failure.
740 template <>
741 bool Read(char *&var);
742 template <>
743 bool Read(wchar_t *&var);
744 template <>
745 bool Read(unsigned char *&var);
747 /// \brief Read a bool from a bitstream.
748 /// \param[in] var The value to read
749 /// \return true on success, false on failure.
750 template <>
751 bool ReadDelta(bool &var);
753 template <>
754 bool ReadCompressed(bool &var);
756 template <>
757 bool ReadCompressed(float &var);
759 /// For values between -1 and 1
760 /// \return true on success, false on failure.
761 template <>
762 bool ReadCompressed(double &var);
764 template <>
765 bool ReadCompressed(char* &var);
766 template <>
767 bool ReadCompressed(wchar_t* &var);
768 template <>
769 bool ReadCompressed(unsigned char *&var);
770 template <>
771 bool ReadCompressed(OVR::String &var);
773 /// \brief Read a bool from a bitstream.
774 /// \param[in] var The value to read
775 /// \return true on success, false on failure.
776 template <>
777 bool ReadCompressedDelta(bool &var);
778 #endif
780 inline static bool DoEndianSwap(void) {
781 #ifndef __BITSTREAM_NATIVE_END
782 return IsNetworkOrder()==false;
783 #else
784 return false;
785 #endif
786 }
787 inline static bool IsBigEndian(void)
788 {
789 return IsNetworkOrder();
790 }
791 inline static bool IsNetworkOrder(void) {bool r = IsNetworkOrderInternal(); return r;}
792 // Not inline, won't compile on PC due to winsock include errors
793 static bool IsNetworkOrderInternal(void);
794 static void ReverseBytes(unsigned char *inByteArray, unsigned char *inOutByteArray, const unsigned int length);
795 static void ReverseBytesInPlace(unsigned char *inOutData,const unsigned int length);
797 private:
799 BitStream( const BitStream & /*invalid*/) : numberOfBitsUsed(0), numberOfBitsAllocated(0), readOffset(0),data(NULL), copyData(false) {
800 OVR_ASSERT(0);
801 }
803 BitStream& operator = ( const BitStream& /*invalid*/ ) {
804 OVR_ASSERT(0);
805 static BitStream i;
806 return i;
807 }
809 /// \brief Assume the input source points to a native type, compress and write it.
810 void WriteCompressed( const unsigned char* inByteArray, const unsigned int size, const bool unsignedData );
812 /// \brief Assume the input source points to a compressed native type. Decompress and read it.
813 bool ReadCompressed( unsigned char* inOutByteArray, const unsigned int size, const bool unsignedData );
816 BitSize_t numberOfBitsUsed;
818 BitSize_t numberOfBitsAllocated;
820 BitSize_t readOffset;
822 unsigned char *data;
824 /// true if the internal buffer is copy of the data passed to the constructor
825 bool copyData;
827 /// BitStreams that use less than BITSTREAM_STACK_ALLOCATION_SIZE use the stack, rather than the heap to store data. It switches over if BITSTREAM_STACK_ALLOCATION_SIZE is exceeded
828 unsigned char stackData[BITSTREAM_STACK_ALLOCATION_SIZE];
829 };
831 template <class templateType>
832 inline bool BitStream::Serialize(bool writeToBitstream, templateType &inOutTemplateVar)
833 {
834 if (writeToBitstream)
835 Write(inOutTemplateVar);
836 else
837 return Read(inOutTemplateVar);
838 return true;
839 }
841 template <class templateType>
842 inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue)
843 {
844 if (writeToBitstream)
845 WriteDelta(inOutCurrentValue, lastValue);
846 else
847 return ReadDelta(inOutCurrentValue);
848 return true;
849 }
851 template <class templateType>
852 inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue)
853 {
854 if (writeToBitstream)
855 WriteDelta(inOutCurrentValue);
856 else
857 return ReadDelta(inOutCurrentValue);
858 return true;
859 }
861 template <class templateType>
862 inline bool BitStream::SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar)
863 {
864 if (writeToBitstream)
865 WriteCompressed(inOutTemplateVar);
866 else
867 return ReadCompressed(inOutTemplateVar);
868 return true;
869 }
871 template <class templateType>
872 inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue)
873 {
874 if (writeToBitstream)
875 WriteCompressedDelta(inOutCurrentValue,lastValue);
876 else
877 return ReadCompressedDelta(inOutCurrentValue);
878 return true;
879 }
880 //Stoppedhere
881 template <class templateType>
882 inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue)
883 {
884 if (writeToBitstream)
885 WriteCompressedDelta(inOutCurrentValue);
886 else
887 return ReadCompressedDelta(inOutCurrentValue);
888 return true;
889 }
891 inline bool BitStream::Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes )
892 {
893 if (writeToBitstream)
894 Write(inOutByteArray, numberOfBytes);
895 else
896 return Read(inOutByteArray, numberOfBytes);
897 return true;
898 }
900 template <class serializationType, class sourceType >
901 bool BitStream::SerializeCasted( bool writeToBitstream, sourceType &value )
902 {
903 if (writeToBitstream) WriteCasted<serializationType>(value);
904 else return ReadCasted<serializationType>(value);
905 return true;
906 }
908 template <class templateType>
909 bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange )
910 {
911 int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
912 return SerializeBitsFromIntegerRange(writeToBitstream,value,minimum,maximum,requiredBits,allowOutsideRange);
913 }
914 template <class templateType>
915 bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange )
916 {
917 if (writeToBitstream) WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
918 else return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
919 return true;
920 }
922 template <class templateType>
923 inline bool BitStream::SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z )
924 {
925 if (writeToBitstream)
926 WriteNormVector(x,y,z);
927 else
928 return ReadNormVector(x,y,z);
929 return true;
930 }
932 template <class templateType>
933 inline bool BitStream::SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z )
934 {
935 if (writeToBitstream)
936 WriteVector(x,y,z);
937 else
938 return ReadVector(x,y,z);
939 return true;
940 }
942 template <class templateType>
943 inline bool BitStream::SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z)
944 {
945 if (writeToBitstream)
946 WriteNormQuat(w,x,y,z);
947 else
948 return ReadNormQuat(w,x,y,z);
949 return true;
950 }
952 template <class templateType>
953 inline bool BitStream::SerializeOrthMatrix(
954 bool writeToBitstream,
955 templateType &m00, templateType &m01, templateType &m02,
956 templateType &m10, templateType &m11, templateType &m12,
957 templateType &m20, templateType &m21, templateType &m22 )
958 {
959 if (writeToBitstream)
960 WriteOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22);
961 else
962 return ReadOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22);
963 return true;
964 }
966 inline bool BitStream::SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits )
967 {
968 if (writeToBitstream)
969 WriteBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits);
970 else
971 return ReadBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits);
972 return true;
973 }
975 template <class templateType>
976 inline void BitStream::Write(const templateType &inTemplateVar)
977 {
978 #ifdef OVR_CC_MSVC
979 #pragma warning(disable:4127) // conditional expression is constant
980 #endif
981 if (sizeof(inTemplateVar)==1)
982 WriteBits( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true );
983 else
984 {
985 #ifndef __BITSTREAM_NATIVE_END
986 if (DoEndianSwap())
987 {
988 unsigned char output[sizeof(templateType)];
989 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType));
990 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true );
991 }
992 else
993 #endif
994 WriteBits( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true );
995 }
996 }
998 template <class templateType>
999 inline void BitStream::WritePtr(templateType *inTemplateVar)
1001 #ifdef OVR_CC_MSVC
1002 #pragma warning(disable:4127) // conditional expression is constant
1003 #endif
1004 if (sizeof(templateType)==1)
1005 WriteBits( ( unsigned char* ) inTemplateVar, sizeof( templateType ) * 8, true );
1006 else
1008 #ifndef __BITSTREAM_NATIVE_END
1009 if (DoEndianSwap())
1011 unsigned char output[sizeof(templateType)];
1012 ReverseBytes((unsigned char*) inTemplateVar, output, sizeof(templateType));
1013 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true );
1015 else
1016 #endif
1017 WriteBits( ( unsigned char* ) inTemplateVar, sizeof(templateType) * 8, true );
1021 /// \brief Write a bool to a bitstream.
1022 /// \param[in] inTemplateVar The value to write
1023 template <>
1024 inline void BitStream::Write(const bool &inTemplateVar)
1026 if ( inTemplateVar )
1027 Write1();
1028 else
1029 Write0();
1033 /// \brief Write a string to a bitstream.
1034 /// \param[in] var The value to write
1035 template <>
1036 inline void BitStream::Write(const OVR::String &inTemplateVar)
1038 uint16_t l = (uint16_t) inTemplateVar.GetLength();
1039 Write(l);
1040 WriteAlignedBytes((const unsigned char*) inTemplateVar.ToCStr(), (const unsigned int) l);
1042 template <>
1043 inline void BitStream::Write(const char * const &inStringVar)
1045 uint16_t l = (uint16_t) strlen(inStringVar);
1046 Write(l);
1047 WriteAlignedBytes((const unsigned char*) inStringVar, (const unsigned int) l);
1049 template <>
1050 inline void BitStream::Write(const unsigned char * const &inTemplateVar)
1052 Write((const char*)inTemplateVar);
1054 template <>
1055 inline void BitStream::Write(char * const &inTemplateVar)
1057 Write((const char*)inTemplateVar);
1059 template <>
1060 inline void BitStream::Write(unsigned char * const &inTemplateVar)
1062 Write((const char*)inTemplateVar);
1065 /// \brief Write any integral type to a bitstream.
1066 /// \details If the current value is different from the last value
1067 /// the current value will be written. Otherwise, a single bit will be written
1068 /// \param[in] currentValue The current value to write
1069 /// \param[in] lastValue The last value to compare against
1070 template <class templateType>
1071 inline void BitStream::WriteDelta(const templateType &currentValue, const templateType &lastValue)
1073 if (currentValue==lastValue)
1075 Write(false);
1077 else
1079 Write(true);
1080 Write(currentValue);
1084 /// \brief Write a bool delta. Same thing as just calling Write
1085 /// \param[in] currentValue The current value to write
1086 /// \param[in] lastValue The last value to compare against
1087 template <>
1088 inline void BitStream::WriteDelta(const bool &currentValue, const bool &lastValue)
1090 (void) lastValue;
1092 Write(currentValue);
1095 /// \brief WriteDelta when you don't know what the last value is, or there is no last value.
1096 /// \param[in] currentValue The current value to write
1097 template <class templateType>
1098 inline void BitStream::WriteDelta(const templateType &currentValue)
1100 Write(true);
1101 Write(currentValue);
1104 /// \brief Write any integral type to a bitstream.
1105 /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping.
1106 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
1107 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
1108 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
1109 /// \param[in] inTemplateVar The value to write
1110 template <class templateType>
1111 inline void BitStream::WriteCompressed(const templateType &inTemplateVar)
1113 #ifdef OVR_CC_MSVC
1114 #pragma warning(disable:4127) // conditional expression is constant
1115 #endif
1116 if (sizeof(inTemplateVar)==1)
1117 WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true );
1118 else
1120 #ifndef __BITSTREAM_NATIVE_END
1121 #ifdef OVR_CC_MSVC
1122 #pragma warning(disable:4244) // '=' : conversion from 'unsigned long' to 'uint16_t', possible loss of data
1123 #endif
1125 if (DoEndianSwap())
1127 unsigned char output[sizeof(templateType)];
1128 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType));
1129 WriteCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true );
1131 else
1132 #endif
1133 WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true );
1137 template <>
1138 inline void BitStream::WriteCompressed(const bool &inTemplateVar)
1140 Write(inTemplateVar);
1143 /// For values between -1 and 1
1144 template <>
1145 inline void BitStream::WriteCompressed(const float &inTemplateVar)
1147 OVR_ASSERT(inTemplateVar > -1.01f && inTemplateVar < 1.01f);
1148 float varCopy=inTemplateVar;
1149 if (varCopy < -1.0f)
1150 varCopy=-1.0f;
1151 if (varCopy > 1.0f)
1152 varCopy=1.0f;
1153 Write((uint16_t)((varCopy+1.0f)*32767.5f));
1156 /// For values between -1 and 1
1157 template <>
1158 inline void BitStream::WriteCompressed(const double &inTemplateVar)
1160 OVR_ASSERT(inTemplateVar > -1.01 && inTemplateVar < 1.01);
1161 double varCopy=inTemplateVar;
1162 if (varCopy < -1.0f)
1163 varCopy=-1.0f;
1164 if (varCopy > 1.0f)
1165 varCopy=1.0f;
1166 Write((uint32_t)((varCopy+1.0)*2147483648.0));
1169 /// \brief Write any integral type to a bitstream.
1170 /// \details If the current value is different from the last value
1171 /// the current value will be written. Otherwise, a single bit will be written
1172 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
1173 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
1174 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
1175 /// \param[in] currentValue The current value to write
1176 /// \param[in] lastValue The last value to compare against
1177 template <class templateType>
1178 inline void BitStream::WriteCompressedDelta(const templateType &currentValue, const templateType &lastValue)
1180 if (currentValue==lastValue)
1182 Write(false);
1184 else
1186 Write(true);
1187 WriteCompressed(currentValue);
1191 /// \brief Write a bool delta. Same thing as just calling Write
1192 /// \param[in] currentValue The current value to write
1193 /// \param[in] lastValue The last value to compare against
1194 template <>
1195 inline void BitStream::WriteCompressedDelta(const bool &currentValue, const bool &lastValue)
1197 (void) lastValue;
1199 Write(currentValue);
1202 /// \brief Save as WriteCompressedDelta(const templateType &currentValue, const templateType &lastValue)
1203 /// when we have an unknown second parameter
1204 template <class templateType>
1205 inline void BitStream::WriteCompressedDelta(const templateType &currentValue)
1207 Write(true);
1208 WriteCompressed(currentValue);
1211 /// \brief Save as WriteCompressedDelta(bool currentValue, const templateType &lastValue)
1212 /// when we have an unknown second bool
1213 template <>
1214 inline void BitStream::WriteCompressedDelta(const bool &currentValue)
1216 Write(currentValue);
1219 /// \brief Read any integral type from a bitstream. Define __BITSTREAM_NATIVE_END if you need endian swapping.
1220 /// \param[in] outTemplateVar The value to read
1221 template <class templateType>
1222 inline bool BitStream::Read(templateType &outTemplateVar)
1224 #ifdef OVR_CC_MSVC
1225 #pragma warning(disable:4127) // conditional expression is constant
1226 #endif
1227 if (sizeof(outTemplateVar)==1)
1228 return ReadBits( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true );
1229 else
1231 #ifndef __BITSTREAM_NATIVE_END
1232 #ifdef OVR_CC_MSVC
1233 #pragma warning(disable:4244) // '=' : conversion from 'unsigned long' to 'uint16_t', possible loss of data
1234 #endif
1235 if (DoEndianSwap())
1237 unsigned char output[sizeof(templateType)];
1238 if (ReadBits( ( unsigned char* ) output, sizeof(templateType) * 8, true ))
1240 ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType));
1241 return true;
1243 return false;
1245 else
1246 #endif
1247 return ReadBits( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true );
1251 /// \brief Read a bool from a bitstream.
1252 /// \param[in] outTemplateVar The value to read
1253 template <>
1254 inline bool BitStream::Read(bool &outTemplateVar)
1256 if ( readOffset + 1 > numberOfBitsUsed )
1257 return false;
1259 if ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) // Is it faster to just write it out here?
1260 outTemplateVar = true;
1261 else
1262 outTemplateVar = false;
1264 // Has to be on a different line for Mac
1265 readOffset++;
1267 return true;
1270 template <>
1271 inline bool BitStream::Read(OVR::String &outTemplateVar)
1273 bool b;
1274 uint16_t l;
1275 b=Read(l);
1276 if (b && l>0)
1278 AlignReadToByteBoundary();
1279 outTemplateVar.AssignString((const char*) (data + ( readOffset >> 3 )), (size_t) l);
1280 IgnoreBytes(l);
1282 else
1284 AlignReadToByteBoundary();
1286 return b;
1288 template <>
1289 inline bool BitStream::Read(char *&varString)
1291 bool b;
1292 uint16_t l;
1293 b=Read(l);
1294 if (b && l>0)
1296 memcpy(varString, data + ( readOffset >> 3 ), l);
1297 IgnoreBytes(l);
1299 else
1301 AlignReadToByteBoundary();
1303 return b;
1305 template <>
1306 inline bool BitStream::Read(unsigned char *&varString)
1308 bool b;
1309 uint16_t l;
1310 b=Read(l);
1311 if (b && l>0)
1313 memcpy(varString, data + ( readOffset >> 3 ), l);
1314 IgnoreBytes(l);
1316 else
1318 AlignReadToByteBoundary();
1320 return b;
1323 /// \brief Read any integral type from a bitstream.
1324 /// \details If the written value differed from the value compared against in the write function,
1325 /// var will be updated. Otherwise it will retain the current value.
1326 /// ReadDelta is only valid from a previous call to WriteDelta
1327 /// \param[in] outTemplateVar The value to read
1328 template <class templateType>
1329 inline bool BitStream::ReadDelta(templateType &outTemplateVar)
1331 bool dataWritten;
1332 bool success;
1333 success=Read(dataWritten);
1334 if (dataWritten)
1335 success=Read(outTemplateVar);
1336 return success;
1339 /// \brief Read a bool from a bitstream.
1340 /// \param[in] outTemplateVar The value to read
1341 template <>
1342 inline bool BitStream::ReadDelta(bool &outTemplateVar)
1344 return Read(outTemplateVar);
1347 /// \brief Read any integral type from a bitstream.
1348 /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping.
1349 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
1350 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
1351 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
1352 /// \param[in] outTemplateVar The value to read
1353 template <class templateType>
1354 inline bool BitStream::ReadCompressed(templateType &outTemplateVar)
1356 #ifdef OVR_CC_MSVC
1357 #pragma warning(disable:4127) // conditional expression is constant
1358 #endif
1359 if (sizeof(outTemplateVar)==1)
1360 return ReadCompressed( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true );
1361 else
1363 #ifndef __BITSTREAM_NATIVE_END
1364 if (DoEndianSwap())
1366 unsigned char output[sizeof(templateType)];
1367 if (ReadCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true ))
1369 ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType));
1370 return true;
1372 return false;
1374 else
1375 #endif
1376 return ReadCompressed( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true );
1380 template <>
1381 inline bool BitStream::ReadCompressed(bool &outTemplateVar)
1383 return Read(outTemplateVar);
1386 /// For values between -1 and 1
1387 template <>
1388 inline bool BitStream::ReadCompressed(float &outTemplateVar)
1390 uint16_t compressedFloat;
1391 if (Read(compressedFloat))
1393 outTemplateVar = ((float)compressedFloat / 32767.5f - 1.0f);
1394 return true;
1396 return false;
1399 /// For values between -1 and 1
1400 template <>
1401 inline bool BitStream::ReadCompressed(double &outTemplateVar)
1403 uint32_t compressedFloat;
1404 if (Read(compressedFloat))
1406 outTemplateVar = ((double)compressedFloat / 2147483648.0 - 1.0);
1407 return true;
1409 return false;
1412 /// \brief Read any integral type from a bitstream.
1413 /// \details If the written value differed from the value compared against in the write function,
1414 /// var will be updated. Otherwise it will retain the current value.
1415 /// the current value will be updated.
1416 /// For floating point, this is lossy, using 2 bytes for a float and 4 for a double. The range must be between -1 and +1.
1417 /// For non-floating point, this is lossless, but only has benefit if you use less than half the bits of the type
1418 /// If you are not using __BITSTREAM_NATIVE_END the opposite is true for types larger than 1 byte
1419 /// ReadCompressedDelta is only valid from a previous call to WriteDelta
1420 /// \param[in] outTemplateVar The value to read
1421 template <class templateType>
1422 inline bool BitStream::ReadCompressedDelta(templateType &outTemplateVar)
1424 bool dataWritten;
1425 bool success;
1426 success=Read(dataWritten);
1427 if (dataWritten)
1428 success=ReadCompressed(outTemplateVar);
1429 return success;
1432 /// \brief Read a bool from a bitstream.
1433 /// \param[in] outTemplateVar The value to read
1434 template <>
1435 inline bool BitStream::ReadCompressedDelta(bool &outTemplateVar)
1437 return Read(outTemplateVar);
1440 template <class destinationType, class sourceType >
1441 void BitStream::WriteCasted( const sourceType &value )
1443 destinationType val = (destinationType) value;
1444 Write(val);
1447 template <class templateType>
1448 void BitStream::WriteBitsFromIntegerRange( const templateType value, const templateType minimum,const templateType maximum, bool allowOutsideRange )
1450 int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
1451 WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
1453 template <class templateType>
1454 void BitStream::WriteBitsFromIntegerRange( const templateType value, const templateType minimum,const templateType maximum, const int requiredBits, bool allowOutsideRange )
1456 OVR_ASSERT(maximum>=minimum);
1457 OVR_ASSERT(allowOutsideRange==true || (value>=minimum && value<=maximum));
1458 if (allowOutsideRange)
1460 if (value<minimum || value>maximum)
1462 Write(true);
1463 Write(value);
1464 return;
1466 Write(false);
1468 templateType valueOffMin=value-minimum;
1469 if (IsBigEndian()==true)
1471 unsigned char output[sizeof(templateType)];
1472 ReverseBytes((unsigned char*)&valueOffMin, output, sizeof(templateType));
1473 WriteBits(output,requiredBits);
1475 else
1477 WriteBits((unsigned char*) &valueOffMin,requiredBits);
1481 template <class templateType> // templateType for this function must be a float or double
1482 void BitStream::WriteNormVector( templateType x, templateType y, templateType z )
1484 #ifdef _DEBUG
1485 OVR_ASSERT(x <= 1.01 && y <= 1.01 && z <= 1.01 && x >= -1.01 && y >= -1.01 && z >= -1.01);
1486 #endif
1488 WriteFloat16((float)x,-1.0f,1.0f);
1489 WriteFloat16((float)y,-1.0f,1.0f);
1490 WriteFloat16((float)z,-1.0f,1.0f);
1493 template <class templateType> // templateType for this function must be a float or double
1494 void BitStream::WriteVector( templateType x, templateType y, templateType z )
1496 templateType magnitude = sqrt(x * x + y * y + z * z);
1497 Write((float)magnitude);
1498 if (magnitude > 0.00001f)
1500 WriteCompressed((float)(x/magnitude));
1501 WriteCompressed((float)(y/magnitude));
1502 WriteCompressed((float)(z/magnitude));
1503 // Write((uint16_t)((x/magnitude+1.0f)*32767.5f));
1504 // Write((uint16_t)((y/magnitude+1.0f)*32767.5f));
1505 // Write((uint16_t)((z/magnitude+1.0f)*32767.5f));
1509 template <class templateType> // templateType for this function must be a float or double
1510 void BitStream::WriteNormQuat( templateType w, templateType x, templateType y, templateType z)
1512 Write((bool)(w<0.0));
1513 Write((bool)(x<0.0));
1514 Write((bool)(y<0.0));
1515 Write((bool)(z<0.0));
1516 Write((uint16_t)(fabs(x)*65535.0));
1517 Write((uint16_t)(fabs(y)*65535.0));
1518 Write((uint16_t)(fabs(z)*65535.0));
1519 // Leave out w and calculate it on the target
1522 template <class templateType> // templateType for this function must be a float or double
1523 void BitStream::WriteOrthMatrix(
1524 templateType m00, templateType m01, templateType m02,
1525 templateType m10, templateType m11, templateType m12,
1526 templateType m20, templateType m21, templateType m22 )
1529 double qw;
1530 double qx;
1531 double qy;
1532 double qz;
1534 // Convert matrix to quat
1535 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
1536 float sum;
1537 sum = 1 + m00 + m11 + m22;
1538 if (sum < 0.0f) sum=0.0f;
1539 qw = sqrt( sum ) / 2;
1540 sum = 1 + m00 - m11 - m22;
1541 if (sum < 0.0f) sum=0.0f;
1542 qx = sqrt( sum ) / 2;
1543 sum = 1 - m00 + m11 - m22;
1544 if (sum < 0.0f) sum=0.0f;
1545 qy = sqrt( sum ) / 2;
1546 sum = 1 - m00 - m11 + m22;
1547 if (sum < 0.0f) sum=0.0f;
1548 qz = sqrt( sum ) / 2;
1549 if (qw < 0.0) qw=0.0;
1550 if (qx < 0.0) qx=0.0;
1551 if (qy < 0.0) qy=0.0;
1552 if (qz < 0.0) qz=0.0;
1553 #ifdef OVR_OS_WIN32
1554 qx = _copysign( (double) qx, (double) (m21 - m12) );
1555 qy = _copysign( (double) qy, (double) (m02 - m20) );
1556 qz = _copysign( (double) qz, (double) (m10 - m01) );
1557 #else
1558 qx = copysign( (double) qx, (double) (m21 - m12) );
1559 qy = copysign( (double) qy, (double) (m02 - m20) );
1560 qz = copysign( (double) qz, (double) (m10 - m01) );
1561 #endif
1563 WriteNormQuat(qw,qx,qy,qz);
1566 template <class serializationType, class sourceType >
1567 bool BitStream::ReadCasted( sourceType &value )
1569 serializationType val;
1570 bool success = Read(val);
1571 value=(sourceType) val;
1572 return success;
1575 template <class templateType>
1576 bool BitStream::ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange )
1578 int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
1579 return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
1581 template <class templateType>
1582 bool BitStream::ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange )
1584 OVR_ASSERT_AND_UNUSED(maximum>=minimum, maximum);
1585 if (allowOutsideRange)
1587 bool isOutsideRange;
1588 Read(isOutsideRange);
1589 if (isOutsideRange)
1590 return Read(value);
1592 unsigned char output[sizeof(templateType)];
1593 memset(output,0,sizeof(output));
1594 bool success = ReadBits(output,requiredBits);
1595 if (success)
1597 if (IsBigEndian()==true)
1598 ReverseBytesInPlace(output,sizeof(output));
1599 memcpy(&value,output,sizeof(output));
1601 value+=minimum;
1604 return success;
1607 template <class templateType> // templateType for this function must be a float or double
1608 bool BitStream::ReadNormVector( templateType &x, templateType &y, templateType &z )
1610 float xIn,yIn,zIn;
1611 ReadFloat16(xIn,-1.0f,1.0f);
1612 ReadFloat16(yIn,-1.0f,1.0f);
1613 ReadFloat16(zIn,-1.0f,1.0f);
1614 x=xIn;
1615 y=yIn;
1616 z=zIn;
1617 return true;
1620 template <class templateType> // templateType for this function must be a float or double
1621 bool BitStream::ReadVector( templateType &x, templateType &y, templateType &z )
1623 float magnitude;
1624 //uint16_t sx,sy,sz;
1625 if (!Read(magnitude))
1626 return false;
1627 if (magnitude>0.00001f)
1629 // Read(sx);
1630 // Read(sy);
1631 // if (!Read(sz))
1632 // return false;
1633 // x=((float)sx / 32767.5f - 1.0f) * magnitude;
1634 // y=((float)sy / 32767.5f - 1.0f) * magnitude;
1635 // z=((float)sz / 32767.5f - 1.0f) * magnitude;
1636 float cx=0.0f,cy=0.0f,cz=0.0f;
1637 ReadCompressed(cx);
1638 ReadCompressed(cy);
1639 if (!ReadCompressed(cz))
1640 return false;
1641 x=cx;
1642 y=cy;
1643 z=cz;
1644 x*=magnitude;
1645 y*=magnitude;
1646 z*=magnitude;
1648 else
1650 x=0.0;
1651 y=0.0;
1652 z=0.0;
1654 return true;
1657 template <class templateType> // templateType for this function must be a float or double
1658 bool BitStream::ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z)
1660 bool cwNeg=false, cxNeg=false, cyNeg=false, czNeg=false;
1661 uint16_t cx,cy,cz;
1662 Read(cwNeg);
1663 Read(cxNeg);
1664 Read(cyNeg);
1665 Read(czNeg);
1666 Read(cx);
1667 Read(cy);
1668 if (!Read(cz))
1669 return false;
1671 // Calculate w from x,y,z
1672 x=(templateType)(cx/65535.0);
1673 y=(templateType)(cy/65535.0);
1674 z=(templateType)(cz/65535.0);
1675 if (cxNeg) x=-x;
1676 if (cyNeg) y=-y;
1677 if (czNeg) z=-z;
1678 float difference = 1.0f - x*x - y*y - z*z;
1679 if (difference < 0.0f)
1680 difference=0.0f;
1681 w = (templateType)(sqrt(difference));
1682 if (cwNeg)
1683 w=-w;
1685 return true;
1688 template <class templateType> // templateType for this function must be a float or double
1689 bool BitStream::ReadOrthMatrix(
1690 templateType &m00, templateType &m01, templateType &m02,
1691 templateType &m10, templateType &m11, templateType &m12,
1692 templateType &m20, templateType &m21, templateType &m22 )
1694 float qw,qx,qy,qz;
1695 if (!ReadNormQuat(qw,qx,qy,qz))
1696 return false;
1698 // Quat to orthogonal rotation matrix
1699 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
1700 double sqw = (double)qw*(double)qw;
1701 double sqx = (double)qx*(double)qx;
1702 double sqy = (double)qy*(double)qy;
1703 double sqz = (double)qz*(double)qz;
1704 m00 = (templateType)(sqx - sqy - sqz + sqw); // since sqw + sqx + sqy + sqz =1
1705 m11 = (templateType)(-sqx + sqy - sqz + sqw);
1706 m22 = (templateType)(-sqx - sqy + sqz + sqw);
1708 double tmp1 = (double)qx*(double)qy;
1709 double tmp2 = (double)qz*(double)qw;
1710 m10 = (templateType)(2.0 * (tmp1 + tmp2));
1711 m01 = (templateType)(2.0 * (tmp1 - tmp2));
1713 tmp1 = (double)qx*(double)qz;
1714 tmp2 = (double)qy*(double)qw;
1715 m20 =(templateType)(2.0 * (tmp1 - tmp2));
1716 m02 = (templateType)(2.0 * (tmp1 + tmp2));
1717 tmp1 = (double)qy*(double)qz;
1718 tmp2 = (double)qx*(double)qw;
1719 m21 = (templateType)(2.0 * (tmp1 + tmp2));
1720 m12 = (templateType)(2.0 * (tmp1 - tmp2));
1722 return true;
1725 template <class templateType>
1726 BitStream& operator<<(BitStream& out, templateType& c)
1728 out.Write(c);
1729 return out;
1731 template <class templateType>
1732 BitStream& operator>>(BitStream& in, templateType& c)
1734 bool success = in.Read(c);
1735 (void)success;
1737 OVR_ASSERT(success);
1738 return in;
1742 }} // OVR::Net
1744 #endif