SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BitStream.h
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2019, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
20
21 #ifndef __BITSTREAM_H
22 #define __BITSTREAM_H
23
24 #include "memoryoverride.h"
25 #include "defines.h"
26 #include "Export.h"
27 #include "types.h"
28 #include "string.h"
29 #include "wstring.h"
30 #include "assert.h"
31 #include <cmath>
32 #include <float.h>
33
34 #ifdef _MSC_VER
35 #pragma warning( push )
36 #endif
37
38 // MSWin uses _copysign, others use copysign...
39 #ifndef _WIN32
40 #define _copysign copysign
41 #endif
42
43 namespace SLNet
44 {
47 class RAK_DLL_EXPORT BitStream
48 {
49
50 public:
51 // GetInstance() and DestroyInstance(instance*)
52 STATIC_FACTORY_DECLARATIONS(BitStream)
53
54
55 BitStream();
56
61 BitStream( const unsigned int initialBytesToAllocate );
62
73 BitStream( unsigned char* _data, const unsigned int lengthInBytes, bool _copyData );
74
75 // Destructor
76 ~BitStream();
77
79 void Reset( void );
80
86 template <class templateType>
87 bool Serialize(bool writeToBitstream, templateType &inOutTemplateVar);
88
96 template <class templateType>
97 bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue);
98
103 template <class templateType>
104 bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue);
105
114 template <class templateType>
115 bool SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar);
116
127 template <class templateType>
128 bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue);
129
132 template <class templateType>
133 bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutTemplateVar);
134
140 bool Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes );
141
147 bool SerializeFloat16(bool writeToBitstream, float &inOutFloat, float floatMin, float floatMax);
148
154 template <class serializationType, class sourceType >
155 bool SerializeCasted( bool writeToBitstream, sourceType &value );
156
165 template <class templateType>
166 bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange=false );
168 template <class templateType>
169 bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange=false );
170
179 template <class templateType> // templateType for this function must be a float or double
180 bool SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z );
181
189 template <class templateType> // templateType for this function must be a float or double
190 bool SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z );
191
199 template <class templateType> // templateType for this function must be a float or double
200 bool SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z);
201
206 template <class templateType> // templateType for this function must be a float or double
207 bool SerializeOrthMatrix(
208 bool writeToBitstream,
209 templateType &m00, templateType &m01, templateType &m02,
210 templateType &m10, templateType &m11, templateType &m12,
211 templateType &m20, templateType &m21, templateType &m22 );
212
224 bool SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits = true );
225
229 template <class templateType>
230 void Write(const templateType &inTemplateVar);
231
235 template <class templateType>
236 void WritePtr(templateType *inTemplateVar);
237
243 template <class templateType>
244 void WriteDelta(const templateType &currentValue, const templateType &lastValue);
245
248 template <class templateType>
249 void WriteDelta(const templateType &currentValue);
250
257 template <class templateType>
258 void WriteCompressed(const templateType &inTemplateVar);
259
268 template <class templateType>
269 void WriteCompressedDelta(const templateType &currentValue, const templateType &lastValue);
270
272 template <class templateType>
273 void WriteCompressedDelta(const templateType &currentValue);
274
279 template <class templateType>
280 bool Read(templateType &outTemplateVar);
281
287 bool Read(wchar_t *&varString);
288 bool Read(wchar_t *&varString, size_t varStringLength);
289
296 template <class templateType>
297 bool ReadDelta(templateType &outTemplateVar);
298
306 template <class templateType>
307 bool ReadCompressed(templateType &outTemplateVar);
308
316 bool ReadCompressed(wchar_t *&varString);
317 bool ReadCompressed(wchar_t *&varString, size_t varStringLength);
318
329 template <class templateType>
330 bool ReadCompressedDelta(templateType &outTemplateVar);
331
336 bool Read( BitStream *bitStream, BitSize_t numberOfBits );
337 bool Read( BitStream *bitStream );
338 bool Read( BitStream &bitStream, BitSize_t numberOfBits );
339 bool Read( BitStream &bitStream );
340
344 void Write( const char* inputByteArray, const unsigned int numberOfBytes );
345
349 void Write( BitStream *bitStream, BitSize_t numberOfBits );
350 void Write( BitStream *bitStream );
351 void Write( BitStream &bitStream, BitSize_t numberOfBits );
352 void Write( BitStream &bitStream );\
353
358 void WriteFloat16( float x, float floatMin, float floatMax );
359
364 template <class serializationType, class sourceType >
365 void WriteCasted( const sourceType &value );
366
374 template <class templateType>
375 void WriteBitsFromIntegerRange( const templateType value, const templateType minimum, const templateType maximum, bool allowOutsideRange=false );
377 template <class templateType>
378 void WriteBitsFromIntegerRange( const templateType value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange=false );
379
386 template <class templateType> // templateType for this function must be a float or double
387 void WriteNormVector( templateType x, templateType y, templateType z );
388
395 template <class templateType> // templateType for this function must be a float or double
396 void WriteVector( templateType x, templateType y, templateType z );
397
403 template <class templateType> // templateType for this function must be a float or double
404 void WriteNormQuat( templateType w, templateType x, templateType y, templateType z);
405
409 template <class templateType> // templateType for this function must be a float or double
410 void WriteOrthMatrix(
411 templateType m00, templateType m01, templateType m02,
412 templateType m10, templateType m11, templateType m12,
413 templateType m20, templateType m21, templateType m22 );
414
420 bool Read( char* output, const unsigned int numberOfBytes );
421
426 bool ReadFloat16( float &outFloat, float floatMin, float floatMax );
427
432 template <class serializationType, class sourceType >
433 bool ReadCasted( sourceType &value );
434
442 template <class templateType>
443 bool ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange=false );
445 template <class templateType>
446 bool ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange=false );
447
455 template <class templateType> // templateType for this function must be a float or double
456 bool ReadNormVector( templateType &x, templateType &y, templateType &z );
457
465 template <class templateType> // templateType for this function must be a float or double
466 bool ReadVector( templateType &x, templateType &y, templateType &z );
467
474 template <class templateType> // templateType for this function must be a float or double
475 bool ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z);
476
481 template <class templateType> // templateType for this function must be a float or double
482 bool ReadOrthMatrix(
483 templateType &m00, templateType &m01, templateType &m02,
484 templateType &m10, templateType &m11, templateType &m12,
485 templateType &m20, templateType &m21, templateType &m22 );
486
488 void ResetReadPointer( void );
489
491 void ResetWritePointer( void );
492
495 void AssertStreamEmpty( void );
496
498 void PrintBits( char *out ) const;
499 void PrintBits( char *out, size_t outLength ) const;
500 void PrintBits( void ) const;
501 void PrintHex( char *out) const;
502 void PrintHex( char *out, size_t outLength ) const;
503 void PrintHex( void ) const;
504
507 void IgnoreBits( const BitSize_t numberOfBits );
508
511 void IgnoreBytes( const unsigned int numberOfBytes );
512
518 void SetWriteOffset( const BitSize_t offset );
519
521 inline BitSize_t GetNumberOfBitsUsed( void ) const {return GetWriteOffset();}
522 inline BitSize_t GetWriteOffset( void ) const {return numberOfBitsUsed;}
523
525 inline BitSize_t GetNumberOfBytesUsed( void ) const {return BITS_TO_BYTES( numberOfBitsUsed );}
526
528 inline BitSize_t GetReadOffset( void ) const {return readOffset;}
529
531 void SetReadOffset( const BitSize_t newReadOffset ) {readOffset=newReadOffset;}
532
534 inline BitSize_t GetNumberOfUnreadBits( void ) const { return readOffset > numberOfBitsUsed ? 0 : numberOfBitsUsed - readOffset; }
535
540 BitSize_t CopyData( unsigned char** _data ) const;
541
544 void SetData( unsigned char *inByteArray );
545
549 inline unsigned char* GetData( void ) const {return data;}
550
560 void WriteBits( const unsigned char* inByteArray, BitSize_t numberOfBitsToWrite, const bool rightAlignedBits = true );
561
569 void WriteAlignedBytes( const unsigned char *inByteArray, const unsigned int numberOfBytesToWrite );
570
571 // Endian swap bytes already in the bitstream
572 void EndianSwapBytes( int byteOffset, int length );
573
578 void WriteAlignedBytesSafe( const char *inByteArray, const unsigned int inputLength, const unsigned int maxBytesToWrite );
579
587 bool ReadAlignedBytes( unsigned char *inOutByteArray, const unsigned int numberOfBytesToRead );
588
593 bool ReadAlignedBytesSafe( char *inOutByteArray, int &inputLength, const int maxBytesToRead );
594 bool ReadAlignedBytesSafe( char *inOutByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead );
595
599 bool ReadAlignedBytesSafeAlloc( char **outByteArray, int &inputLength, const unsigned int maxBytesToRead );
600 bool ReadAlignedBytesSafeAlloc( char **outByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead );
601
607 inline void AlignWriteToByteBoundary( void ) {numberOfBitsUsed += 8 - ( (( numberOfBitsUsed - 1 ) & 7) + 1 );}
608
614 inline void AlignReadToByteBoundary( void ) {readOffset += 8 - ( (( readOffset - 1 ) & 7 ) + 1 );}
615
624 bool ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsToRead, const bool alignBitsToRight = true );
625
627 void Write0( void );
628
630 void Write1( void );
631
633 bool ReadBit( void );
634
637 void AssertCopyData( void );
638
642 void SetNumberOfBitsAllocated( const BitSize_t lengthInBits );
643
645 void AddBitsAndReallocate( const BitSize_t numberOfBitsToWrite );
646
649 BitSize_t GetNumberOfBitsAllocated(void) const;
650
652 bool Read(char *varString);
653 bool Read(unsigned char *varString);
654
656 void PadWithZeroToByteLength( unsigned int bytes );
657
660 static int NumberOfLeadingZeroes( uint8_t x );
661 static int NumberOfLeadingZeroes( uint16_t x );
662 static int NumberOfLeadingZeroes( uint32_t x );
663 static int NumberOfLeadingZeroes( uint64_t x );
664 static int NumberOfLeadingZeroes( int8_t x );
665 static int NumberOfLeadingZeroes( int16_t x );
666 static int NumberOfLeadingZeroes( int32_t x );
667 static int NumberOfLeadingZeroes( int64_t x );
668
670 void WriteAlignedVar8(const char *inByteArray);
672 bool ReadAlignedVar8(char *inOutByteArray);
674 void WriteAlignedVar16(const char *inByteArray);
676 bool ReadAlignedVar16(char *inOutByteArray);
678 void WriteAlignedVar32(const char *inByteArray);
680 bool ReadAlignedVar32(char *inOutByteArray);
681
682 inline void Write(const char * const inStringVar)
683 {
684 RakString::Serialize(inStringVar, this);
685 }
686 inline void Write(const wchar_t * const inStringVar)
687 {
688 RakWString::Serialize(inStringVar, this);
689 }
690 inline void Write(const unsigned char * const inTemplateVar)
691 {
692 Write((const char*)inTemplateVar);
693 }
694 inline void Write(char * const inTemplateVar)
695 {
696 Write((const char*)inTemplateVar);
697 }
698 inline void Write(unsigned char * const inTemplateVar)
699 {
700 Write((const char*)inTemplateVar);
701 }
702 inline void WriteCompressed(const char * const inStringVar)
703 {
704 RakString::SerializeCompressed(inStringVar,this,0,false);
705 }
706 inline void WriteCompressed(const wchar_t * const inStringVar)
707 {
708 RakWString::Serialize(inStringVar,this);
709 }
710 inline void WriteCompressed(const unsigned char * const inTemplateVar)
711 {
712 WriteCompressed((const char*) inTemplateVar);
713 }
714 inline void WriteCompressed(char * const inTemplateVar)
715 {
716 WriteCompressed((const char*) inTemplateVar);
717 }
718 inline void WriteCompressed(unsigned char * const inTemplateVar)
719 {
720 WriteCompressed((const char*) inTemplateVar);
721 }
722
724 inline static bool DoEndianSwap(void) {
725 #ifndef __BITSTREAM_NATIVE_END
726 return IsNetworkOrder()==false;
727 #else
728 return false;
729 #endif
730 }
731 inline static bool IsBigEndian(void)
732 {
733 return IsNetworkOrder();
734 }
735 inline static bool IsNetworkOrder(void) {bool r = IsNetworkOrderInternal(); return r;}
736 // Not inline, won't compile on PC due to winsock include errors
737 static bool IsNetworkOrderInternal(void);
738 static void ReverseBytes(unsigned char *inByteArray, unsigned char *inOutByteArray, const unsigned int length);
739 static void ReverseBytesInPlace(unsigned char *inOutData,const unsigned int length);
740
741 private:
742
743 BitStream( const BitStream &invalid) {
744 (void) invalid;
745 RakAssert(0);
746 }
747
748 BitStream& operator = ( const BitStream& invalid ) {
749 (void) invalid;
750 RakAssert(0);
751 static BitStream i;
752 return i;
753 }
754
756 void WriteCompressed( const unsigned char* inByteArray, const unsigned int size, const bool unsignedData );
757
759 bool ReadCompressed( unsigned char* inOutByteArray, const unsigned int size, const bool unsignedData );
760
761
762 BitSize_t numberOfBitsUsed;
763
764 BitSize_t numberOfBitsAllocated;
765
766 BitSize_t readOffset;
767
768 unsigned char *data;
769
771 bool copyData;
772
774 unsigned char stackData[BITSTREAM_STACK_ALLOCATION_SIZE];
775 };
776
777 template <class templateType>
778 inline bool BitStream::Serialize(bool writeToBitstream, templateType &inOutTemplateVar)
779 {
780 if (writeToBitstream)
781 Write(inOutTemplateVar);
782 else
783 return Read(inOutTemplateVar);
784 return true;
785 }
786
787 template <class templateType>
788 inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue)
789 {
790 if (writeToBitstream)
791 WriteDelta(inOutCurrentValue, lastValue);
792 else
793 return ReadDelta(inOutCurrentValue);
794 return true;
795 }
796
797 template <class templateType>
798 inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue)
799 {
800 if (writeToBitstream)
801 WriteDelta(inOutCurrentValue);
802 else
803 return ReadDelta(inOutCurrentValue);
804 return true;
805 }
806
807 template <class templateType>
808 inline bool BitStream::SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar)
809 {
810 if (writeToBitstream)
811 WriteCompressed(inOutTemplateVar);
812 else
813 return ReadCompressed(inOutTemplateVar);
814 return true;
815 }
816
817 template <class templateType>
818 inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue)
819 {
820 if (writeToBitstream)
821 WriteCompressedDelta(inOutCurrentValue,lastValue);
822 else
823 return ReadCompressedDelta(inOutCurrentValue);
824 return true;
825 }
826 //Stoppedhere
827 template <class templateType>
828 inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue)
829 {
830 if (writeToBitstream)
831 WriteCompressedDelta(inOutCurrentValue);
832 else
833 return ReadCompressedDelta(inOutCurrentValue);
834 return true;
835 }
836
837 inline bool BitStream::Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes )
838 {
839 if (writeToBitstream)
840 Write(inOutByteArray, numberOfBytes);
841 else
842 return Read(inOutByteArray, numberOfBytes);
843 return true;
844 }
845
846 template <class serializationType, class sourceType >
847 bool BitStream::SerializeCasted( bool writeToBitstream, sourceType &value )
848 {
849 if (writeToBitstream) WriteCasted<serializationType>(value);
850 else return ReadCasted<serializationType>(value);
851 return true;
852 }
853
854 template <class templateType>
855 bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange )
856 {
857 int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
858 return SerializeBitsFromIntegerRange(writeToBitstream,value,minimum,maximum,requiredBits,allowOutsideRange);
859 }
860 template <class templateType>
861 bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange )
862 {
863 if (writeToBitstream) WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
864 else return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
865 return true;
866 }
867
868 template <class templateType>
869 inline bool BitStream::SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z )
870 {
871 if (writeToBitstream)
872 WriteNormVector(x,y,z);
873 else
874 return ReadNormVector(x,y,z);
875 return true;
876 }
877
878 template <class templateType>
879 inline bool BitStream::SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z )
880 {
881 if (writeToBitstream)
882 WriteVector(x,y,z);
883 else
884 return ReadVector(x,y,z);
885 return true;
886 }
887
888 template <class templateType>
889 inline bool BitStream::SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z)
890 {
891 if (writeToBitstream)
892 WriteNormQuat(w,x,y,z);
893 else
894 return ReadNormQuat(w,x,y,z);
895 return true;
896 }
897
898 template <class templateType>
899 inline bool BitStream::SerializeOrthMatrix(
900 bool writeToBitstream,
901 templateType &m00, templateType &m01, templateType &m02,
902 templateType &m10, templateType &m11, templateType &m12,
903 templateType &m20, templateType &m21, templateType &m22 )
904 {
905 if (writeToBitstream)
906 WriteOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22);
907 else
908 return ReadOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22);
909 return true;
910 }
911
912 inline bool BitStream::SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits )
913 {
914 if (writeToBitstream)
915 WriteBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits);
916 else
917 return ReadBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits);
918 return true;
919 }
920
921 template <class templateType>
922 inline void BitStream::Write(const templateType &inTemplateVar)
923 {
924 #ifdef _MSC_VER
925 #pragma warning(disable:4127) // conditional expression is constant
926 #endif
927 if (sizeof(inTemplateVar)==1)
928 WriteBits( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true );
929 else
930 {
931 #ifndef __BITSTREAM_NATIVE_END
932 if (DoEndianSwap())
933 {
934 unsigned char output[sizeof(templateType)];
935 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType));
936 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true );
937 }
938 else
939 #endif
940 WriteBits( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true );
941 }
942 }
943
944 template <class templateType>
945 inline void BitStream::WritePtr(templateType *inTemplateVar)
946 {
947 #ifdef _MSC_VER
948 #pragma warning(disable:4127) // conditional expression is constant
949 #endif
950 if (sizeof(templateType)==1)
951 WriteBits( ( unsigned char* ) inTemplateVar, sizeof( templateType ) * 8, true );
952 else
953 {
954 #ifndef __BITSTREAM_NATIVE_END
955 if (DoEndianSwap())
956 {
957 unsigned char output[sizeof(templateType)];
958 ReverseBytes((unsigned char*) inTemplateVar, output, sizeof(templateType));
959 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true );
960 }
961 else
962 #endif
963 WriteBits( ( unsigned char* ) inTemplateVar, sizeof(templateType) * 8, true );
964 }
965 }
966
969 template <>
970 inline void BitStream::Write(const bool &inTemplateVar)
971 {
972 if ( inTemplateVar )
973 Write1();
974 else
975 Write0();
976 }
977
978
981 template <>
982 inline void BitStream::Write(const SystemAddress &inTemplateVar)
983 {
984 Write(inTemplateVar.GetIPVersion());
985 if (inTemplateVar.GetIPVersion()==4)
986 {
987 // Hide the address so routers don't modify it
988 SystemAddress var2=inTemplateVar;
989 uint32_t binaryAddress=~inTemplateVar.address.addr4.sin_addr.s_addr;
990 // Don't endian swap the address or port
991 WriteBits((unsigned char*)&binaryAddress, sizeof(binaryAddress)*8, true);
992 unsigned short p = var2.GetPortNetworkOrder();
993 WriteBits((unsigned char*)&p, sizeof(unsigned short)*8, true);
994 }
995 else
996 {
997 #if RAKNET_SUPPORT_IPV6==1
998 // Don't endian swap
999 WriteBits((const unsigned char*) &inTemplateVar.address.addr6, sizeof(inTemplateVar.address.addr6)*8, true);
1000 #endif
1001 }
1002 }
1003
1004 template <>
1005 inline void BitStream::Write(const uint24_t &inTemplateVar)
1006 {
1007 AlignWriteToByteBoundary();
1008 AddBitsAndReallocate(3*8);
1009
1010 if (IsBigEndian()==false)
1011 {
1012 data[( numberOfBitsUsed >> 3 ) + 0] = ((unsigned char *)&inTemplateVar.val)[0];
1013 data[( numberOfBitsUsed >> 3 ) + 1] = ((unsigned char *)&inTemplateVar.val)[1];
1014 data[( numberOfBitsUsed >> 3 ) + 2] = ((unsigned char *)&inTemplateVar.val)[2];
1015 }
1016 else
1017 {
1018 data[( numberOfBitsUsed >> 3 ) + 0] = ((unsigned char *)&inTemplateVar.val)[3];
1019 data[( numberOfBitsUsed >> 3 ) + 1] = ((unsigned char *)&inTemplateVar.val)[2];
1020 data[( numberOfBitsUsed >> 3 ) + 2] = ((unsigned char *)&inTemplateVar.val)[1];
1021 }
1022
1023 numberOfBitsUsed+=3*8;
1024 }
1025
1026 template <>
1027 inline void BitStream::Write(const RakNetGUID &inTemplateVar)
1028 {
1029 Write(inTemplateVar.g);
1030 }
1031
1034 template <>
1035 inline void BitStream::Write(const RakString &inTemplateVar)
1036 {
1037 inTemplateVar.Serialize(this);
1038 }
1039 template <>
1040 inline void BitStream::Write(const RakWString &inTemplateVar)
1041 {
1042 inTemplateVar.Serialize(this);
1043 }
1044 template <>
1045 inline void BitStream::Write(const char * const &inStringVar)
1046 {
1047 RakString::Serialize(inStringVar, this);
1048 }
1049 template <>
1050 inline void BitStream::Write(const wchar_t * const &inStringVar)
1051 {
1052 RakWString::Serialize(inStringVar, this);
1053 }
1054 template <>
1055 inline void BitStream::Write(const unsigned char * const &inTemplateVar)
1056 {
1057 Write((const char*)inTemplateVar);
1058 }
1059 template <>
1060 inline void BitStream::Write(char * const &inTemplateVar)
1061 {
1062 Write((const char*)inTemplateVar);
1063 }
1064 template <>
1065 inline void BitStream::Write(unsigned char * const &inTemplateVar)
1066 {
1067 Write((const char*)inTemplateVar);
1068 }
1069
1075 template <class templateType>
1076 inline void BitStream::WriteDelta(const templateType &currentValue, const templateType &lastValue)
1077 {
1078 if (currentValue==lastValue)
1079 {
1080 Write(false);
1081 }
1082 else
1083 {
1084 Write(true);
1085 Write(currentValue);
1086 }
1087 }
1088
1092 template <>
1093 inline void BitStream::WriteDelta(const bool &currentValue, const bool &lastValue)
1094 {
1095 (void) lastValue;
1096
1097 Write(currentValue);
1098 }
1099
1102 template <class templateType>
1103 inline void BitStream::WriteDelta(const templateType &currentValue)
1104 {
1105 Write(true);
1106 Write(currentValue);
1107 }
1108
1115 template <class templateType>
1116 inline void BitStream::WriteCompressed(const templateType &inTemplateVar)
1117 {
1118 #ifdef _MSC_VER
1119 #pragma warning(disable:4127) // conditional expression is constant
1120 #endif
1121 if (sizeof(inTemplateVar)==1)
1122 WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true );
1123 else
1124 {
1125 #ifndef __BITSTREAM_NATIVE_END
1126 if (DoEndianSwap())
1127 {
1128 unsigned char output[sizeof(templateType)];
1129 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType));
1130 WriteCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true );
1131 }
1132 else
1133 #endif
1134 WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true );
1135 }
1136 }
1137
1138 template <>
1139 inline void BitStream::WriteCompressed(const SystemAddress &inTemplateVar)
1140 {
1141 Write(inTemplateVar);
1142 }
1143
1144 template <>
1145 inline void BitStream::WriteCompressed(const RakNetGUID &inTemplateVar)
1146 {
1147 Write(inTemplateVar);
1148 }
1149
1150 template <>
1151 inline void BitStream::WriteCompressed(const uint24_t &var)
1152 {
1153 Write(var);
1154 }
1155
1156 template <>
1157 inline void BitStream::WriteCompressed(const bool &inTemplateVar)
1158 {
1159 Write(inTemplateVar);
1160 }
1161
1163 template <>
1164 inline void BitStream::WriteCompressed(const float &inTemplateVar)
1165 {
1166 RakAssert(inTemplateVar > -1.01f && inTemplateVar < 1.01f);
1167 float varCopy=inTemplateVar;
1168 if (varCopy < -1.0f)
1169 varCopy=-1.0f;
1170 if (varCopy > 1.0f)
1171 varCopy=1.0f;
1172 Write((unsigned short)((varCopy+1.0f)*32767.5f));
1173 }
1174
1176 template <>
1177 inline void BitStream::WriteCompressed(const double &inTemplateVar)
1178 {
1179 RakAssert(inTemplateVar > -1.01 && inTemplateVar < 1.01);
1180 double varCopy=inTemplateVar;
1181 if (varCopy < -1.0f)
1182 varCopy=-1.0f;
1183 if (varCopy > 1.0f)
1184 varCopy=1.0f;
1185 Write((uint32_t)((varCopy+1.0)*2147483648.0));
1186 }
1187
1189 template <>
1190 inline void BitStream::WriteCompressed(const RakString &inTemplateVar)
1191 {
1192 inTemplateVar.SerializeCompressed(this,0,false);
1193 }
1194 template <>
1195 inline void BitStream::WriteCompressed(const RakWString &inTemplateVar)
1196 {
1197 inTemplateVar.Serialize(this);
1198 }
1199 template <>
1200 inline void BitStream::WriteCompressed(const char * const &inStringVar)
1201 {
1202 RakString::SerializeCompressed(inStringVar,this,0,false);
1203 }
1204 template <>
1205 inline void BitStream::WriteCompressed(const wchar_t * const &inStringVar)
1206 {
1207 RakWString::Serialize(inStringVar,this);
1208 }
1209 template <>
1210 inline void BitStream::WriteCompressed(const unsigned char * const &inTemplateVar)
1211 {
1212 WriteCompressed((const char*) inTemplateVar);
1213 }
1214 template <>
1215 inline void BitStream::WriteCompressed(char * const &inTemplateVar)
1216 {
1217 WriteCompressed((const char*) inTemplateVar);
1218 }
1219 template <>
1220 inline void BitStream::WriteCompressed(unsigned char * const &inTemplateVar)
1221 {
1222 WriteCompressed((const char*) inTemplateVar);
1223 }
1224
1225
1234 template <class templateType>
1235 inline void BitStream::WriteCompressedDelta(const templateType &currentValue, const templateType &lastValue)
1236 {
1237 if (currentValue==lastValue)
1238 {
1239 Write(false);
1240 }
1241 else
1242 {
1243 Write(true);
1244 WriteCompressed(currentValue);
1245 }
1246 }
1247
1251 template <>
1252 inline void BitStream::WriteCompressedDelta(const bool &currentValue, const bool &lastValue)
1253 {
1254 (void) lastValue;
1255
1256 Write(currentValue);
1257 }
1258
1261 template <class templateType>
1262 inline void BitStream::WriteCompressedDelta(const templateType &currentValue)
1263 {
1264 Write(true);
1265 WriteCompressed(currentValue);
1266 }
1267
1270 template <>
1271 inline void BitStream::WriteCompressedDelta(const bool &currentValue)
1272 {
1273 Write(currentValue);
1274 }
1275
1278 template <class templateType>
1279 inline bool BitStream::Read(templateType &outTemplateVar)
1280 {
1281 #ifdef _MSC_VER
1282 #pragma warning(disable:4127) // conditional expression is constant
1283 #endif
1284 if (sizeof(outTemplateVar)==1)
1285 return ReadBits( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true );
1286 else
1287 {
1288 #ifndef __BITSTREAM_NATIVE_END
1289 if (DoEndianSwap())
1290 {
1291 unsigned char output[sizeof(templateType)];
1292 if (ReadBits( ( unsigned char* ) output, sizeof(templateType) * 8, true ))
1293 {
1294 ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType));
1295 return true;
1296 }
1297 return false;
1298 }
1299 else
1300 #endif
1301 return ReadBits( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true );
1302 }
1303 }
1304
1307 template <>
1308 inline bool BitStream::Read(bool &outTemplateVar)
1309 {
1310 if (GetNumberOfUnreadBits() == 0)
1311 return false;
1312
1313 if ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) // Is it faster to just write it out here?
1314 outTemplateVar = true;
1315 else
1316 outTemplateVar = false;
1317
1318 // Has to be on a different line for Mac
1319 readOffset++;
1320
1321 return true;
1322 }
1323
1326 template <>
1327 inline bool BitStream::Read(SystemAddress &outTemplateVar)
1328 {
1329 unsigned char ipVersion;
1330 Read(ipVersion);
1331 if (ipVersion==4)
1332 {
1333 outTemplateVar.address.addr4.sin_family=AF_INET;
1334 // Read(var.binaryAddress);
1335 // Don't endian swap the address or port
1336 uint32_t binaryAddress;
1337 ReadBits( ( unsigned char* ) & binaryAddress, sizeof(binaryAddress) * 8, true );
1338 // Unhide the IP address, done to prevent routers from changing it
1339 outTemplateVar.address.addr4.sin_addr.s_addr=~binaryAddress;
1340 bool b = ReadBits(( unsigned char* ) & outTemplateVar.address.addr4.sin_port, sizeof(outTemplateVar.address.addr4.sin_port) * 8, true);
1341 outTemplateVar.debugPort=ntohs(outTemplateVar.address.addr4.sin_port);
1342 return b;
1343 }
1344 else
1345 {
1346 #if RAKNET_SUPPORT_IPV6==1
1347 bool b = ReadBits((unsigned char*) &outTemplateVar.address.addr6, sizeof(outTemplateVar.address.addr6)*8, true);
1348 outTemplateVar.debugPort=ntohs(outTemplateVar.address.addr6.sin6_port);
1349 return b;
1350 #else
1351 return false;
1352 #endif
1353 }
1354 }
1355
1356 template <>
1357 inline bool BitStream::Read(uint24_t &outTemplateVar)
1358 {
1359 AlignReadToByteBoundary();
1360 if (GetNumberOfUnreadBits() < 3*8)
1361 return false;
1362
1363 if (IsBigEndian()==false)
1364 {
1365 ((unsigned char *)&outTemplateVar.val)[0]=data[ (readOffset >> 3) + 0];
1366 ((unsigned char *)&outTemplateVar.val)[1]=data[ (readOffset >> 3) + 1];
1367 ((unsigned char *)&outTemplateVar.val)[2]=data[ (readOffset >> 3) + 2];
1368 ((unsigned char *)&outTemplateVar.val)[3]=0;
1369 }
1370 else
1371 {
1372
1373 ((unsigned char *)&outTemplateVar.val)[3]=data[ (readOffset >> 3) + 0];
1374 ((unsigned char *)&outTemplateVar.val)[2]=data[ (readOffset >> 3) + 1];
1375 ((unsigned char *)&outTemplateVar.val)[1]=data[ (readOffset >> 3) + 2];
1376 ((unsigned char *)&outTemplateVar.val)[0]=0;
1377 }
1378
1379 readOffset+=3*8;
1380 return true;
1381 }
1382
1383 template <>
1384 inline bool BitStream::Read(RakNetGUID &outTemplateVar)
1385 {
1386 return Read(outTemplateVar.g);
1387 }
1388
1389
1390 template <>
1391 inline bool BitStream::Read(RakString &outTemplateVar)
1392 {
1393 return outTemplateVar.Deserialize(this);
1394 }
1395 template <>
1396 inline bool BitStream::Read(RakWString &outTemplateVar)
1397 {
1398 return outTemplateVar.Deserialize(this);
1399 }
1400 template <>
1401 inline bool BitStream::Read(char *&varString)
1402 {
1403 return RakString::Deserialize(varString,this);
1404 }
1405 inline bool BitStream::Read(wchar_t *&varString)
1406 {
1407 return RakWString::Deserialize(varString, this);
1408 }
1409 inline bool BitStream::Read(wchar_t *&varString, size_t varStringLength)
1410 {
1411 return RakWString::Deserialize(varString,varStringLength,this);
1412 }
1413 template <>
1414 inline bool BitStream::Read(unsigned char *&varString)
1415 {
1416 return RakString::Deserialize((char*) varString,this);
1417 }
1418
1424 template <class templateType>
1425 inline bool BitStream::ReadDelta(templateType &outTemplateVar)
1426 {
1427 bool dataWritten;
1428 bool success;
1429 success=Read(dataWritten);
1430 if (dataWritten)
1431 success=Read(outTemplateVar);
1432 return success;
1433 }
1434
1437 template <>
1438 inline bool BitStream::ReadDelta(bool &outTemplateVar)
1439 {
1440 return Read(outTemplateVar);
1441 }
1442
1449 template <class templateType>
1450 inline bool BitStream::ReadCompressed(templateType &outTemplateVar)
1451 {
1452 #ifdef _MSC_VER
1453 #pragma warning(disable:4127) // conditional expression is constant
1454 #endif
1455 if (sizeof(outTemplateVar)==1)
1456 return ReadCompressed( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true );
1457 else
1458 {
1459 #ifndef __BITSTREAM_NATIVE_END
1460 if (DoEndianSwap())
1461 {
1462 unsigned char output[sizeof(templateType)];
1463 if (ReadCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true ))
1464 {
1465 ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType));
1466 return true;
1467 }
1468 return false;
1469 }
1470 else
1471 #endif
1472 return ReadCompressed( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true );
1473 }
1474 }
1475
1476 template <>
1477 inline bool BitStream::ReadCompressed(SystemAddress &outTemplateVar)
1478 {
1479 return Read(outTemplateVar);
1480 }
1481
1482 template <>
1483 inline bool BitStream::ReadCompressed(uint24_t &outTemplateVar)
1484 {
1485 return Read(outTemplateVar);
1486 }
1487
1488 template <>
1489 inline bool BitStream::ReadCompressed(RakNetGUID &outTemplateVar)
1490 {
1491 return Read(outTemplateVar);
1492 }
1493
1494 template <>
1495 inline bool BitStream::ReadCompressed(bool &outTemplateVar)
1496 {
1497 return Read(outTemplateVar);
1498 }
1499
1501 template <>
1502 inline bool BitStream::ReadCompressed(float &outTemplateVar)
1503 {
1504 unsigned short compressedFloat;
1505 if (Read(compressedFloat))
1506 {
1507 outTemplateVar = ((float)compressedFloat / 32767.5f - 1.0f);
1508 return true;
1509 }
1510 return false;
1511 }
1512
1514 template <>
1515 inline bool BitStream::ReadCompressed(double &outTemplateVar)
1516 {
1517 uint32_t compressedFloat;
1518 if (Read(compressedFloat))
1519 {
1520 outTemplateVar = ((double)compressedFloat / 2147483648.0 - 1.0);
1521 return true;
1522 }
1523 return false;
1524 }
1525
1527 template <>
1528 inline bool BitStream::ReadCompressed(RakString &outTemplateVar)
1529 {
1530 return outTemplateVar.DeserializeCompressed(this,false);
1531 }
1532 template <>
1533 inline bool BitStream::ReadCompressed(RakWString &outTemplateVar)
1534 {
1535 return outTemplateVar.Deserialize(this);
1536 }
1537 template <>
1538 inline bool BitStream::ReadCompressed(char *&outTemplateVar)
1539 {
1540 return RakString::DeserializeCompressed(outTemplateVar,this,false);
1541 }
1542 inline bool BitStream::ReadCompressed(wchar_t *&outTemplateVar)
1543 {
1544 return RakWString::Deserialize(outTemplateVar, this);
1545 }
1546 inline bool BitStream::ReadCompressed(wchar_t *&outTemplateVar, size_t varStringLength)
1547 {
1548 return RakWString::Deserialize(outTemplateVar,varStringLength,this);
1549 }
1550 template <>
1551 inline bool BitStream::ReadCompressed(unsigned char *&outTemplateVar)
1552 {
1553 return RakString::DeserializeCompressed((char*) outTemplateVar,this,false);
1554 }
1555
1565 template <class templateType>
1566 inline bool BitStream::ReadCompressedDelta(templateType &outTemplateVar)
1567 {
1568 bool dataWritten;
1569 bool success;
1570 success=Read(dataWritten);
1571 if (dataWritten)
1572 success=ReadCompressed(outTemplateVar);
1573 return success;
1574 }
1575
1578 template <>
1579 inline bool BitStream::ReadCompressedDelta(bool &outTemplateVar)
1580 {
1581 return Read(outTemplateVar);
1582 }
1583
1584 template <class destinationType, class sourceType >
1585 void BitStream::WriteCasted( const sourceType &value )
1586 {
1587 destinationType val = (destinationType) value;
1588 Write(val);
1589 }
1590
1591 template <class templateType>
1592 void BitStream::WriteBitsFromIntegerRange( const templateType value, const templateType minimum,const templateType maximum, bool allowOutsideRange )
1593 {
1594 int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
1595 WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
1596 }
1597 template <class templateType>
1598 void BitStream::WriteBitsFromIntegerRange( const templateType value, const templateType minimum,const templateType maximum, const int requiredBits, bool allowOutsideRange )
1599 {
1600 RakAssert(maximum>=minimum);
1601 RakAssert(allowOutsideRange==true || (value>=minimum && value<=maximum));
1602 if (allowOutsideRange)
1603 {
1604 if (value<minimum || value>maximum)
1605 {
1606 Write(true);
1607 Write(value);
1608 return;
1609 }
1610 Write(false);
1611 }
1612 templateType valueOffMin=value-minimum;
1613 if (IsBigEndian()==true)
1614 {
1615 unsigned char output[sizeof(templateType)];
1616 ReverseBytes((unsigned char*)&valueOffMin, output, sizeof(templateType));
1617 WriteBits(output,requiredBits);
1618 }
1619 else
1620 {
1621 WriteBits((unsigned char*) &valueOffMin,requiredBits);
1622 }
1623 }
1624
1625 template <class templateType> // templateType for this function must be a float or double
1626 void BitStream::WriteNormVector( templateType x, templateType y, templateType z )
1627 {
1628 #ifdef _DEBUG
1629 RakAssert(x <= 1.01 && y <= 1.01 && z <= 1.01 && x >= -1.01 && y >= -1.01 && z >= -1.01);
1630 #endif
1631
1632 WriteFloat16((float)x,-1.0f,1.0f);
1633 WriteFloat16((float)y,-1.0f,1.0f);
1634 WriteFloat16((float)z,-1.0f,1.0f);
1635 }
1636
1637 template <class templateType> // templateType for this function must be a float or double
1638 void BitStream::WriteVector( templateType x, templateType y, templateType z )
1639 {
1640 templateType magnitude = sqrt(x * x + y * y + z * z);
1641 Write((float)magnitude);
1642 if (magnitude > 0.00001f)
1643 {
1644 WriteCompressed((float)(x/magnitude));
1645 WriteCompressed((float)(y/magnitude));
1646 WriteCompressed((float)(z/magnitude));
1647 // Write((unsigned short)((x/magnitude+1.0f)*32767.5f));
1648 // Write((unsigned short)((y/magnitude+1.0f)*32767.5f));
1649 // Write((unsigned short)((z/magnitude+1.0f)*32767.5f));
1650 }
1651 }
1652
1653 template <class templateType> // templateType for this function must be a float or double
1654 void BitStream::WriteNormQuat( templateType w, templateType x, templateType y, templateType z)
1655 {
1656 Write((bool)(w<0.0));
1657 Write((bool)(x<0.0));
1658 Write((bool)(y<0.0));
1659 Write((bool)(z<0.0));
1660 Write((unsigned short)(fabs(x)*65535.0));
1661 Write((unsigned short)(fabs(y)*65535.0));
1662 Write((unsigned short)(fabs(z)*65535.0));
1663 // Leave out w and calculate it on the target
1664 }
1665
1666 template <class templateType> // templateType for this function must be a float or double
1667 void BitStream::WriteOrthMatrix(
1668 templateType m00, templateType m01, templateType m02,
1669 templateType m10, templateType m11, templateType m12,
1670 templateType m20, templateType m21, templateType m22 )
1671 {
1672
1673 double qw;
1674 double qx;
1675 double qy;
1676 double qz;
1677
1678 // Convert matrix to quat
1679 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
1680 float sum;
1681 sum = 1 + m00 + m11 + m22;
1682 if (sum < 0.0f) sum=0.0f;
1683 qw = sqrt( sum ) / 2;
1684 sum = 1 + m00 - m11 - m22;
1685 if (sum < 0.0f) sum=0.0f;
1686 qx = sqrt( sum ) / 2;
1687 sum = 1 - m00 + m11 - m22;
1688 if (sum < 0.0f) sum=0.0f;
1689 qy = sqrt( sum ) / 2;
1690 sum = 1 - m00 - m11 + m22;
1691 if (sum < 0.0f) sum=0.0f;
1692 qz = sqrt( sum ) / 2;
1693 if (qw < 0.0) qw=0.0;
1694 if (qx < 0.0) qx=0.0;
1695 if (qy < 0.0) qy=0.0;
1696 if (qz < 0.0) qz=0.0;
1697 qx = _copysign( (double) qx, (double) (m21 - m12) );
1698 qy = _copysign( (double) qy, (double) (m02 - m20) );
1699 qz = _copysign( (double) qz, (double) (m10 - m01) );
1700
1701 WriteNormQuat(qw,qx,qy,qz);
1702 }
1703
1704 template <class serializationType, class sourceType >
1705 bool BitStream::ReadCasted( sourceType &value )
1706 {
1707 serializationType val;
1708 bool success = Read(val);
1709 value=(sourceType) val;
1710 return success;
1711 }
1712
1713 template <class templateType>
1714 bool BitStream::ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, bool allowOutsideRange )
1715 {
1716 int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
1717 return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
1718 }
1719 template <class templateType>
1720 bool BitStream::ReadBitsFromIntegerRange( templateType &value, const templateType minimum, const templateType maximum, const int requiredBits, bool allowOutsideRange )
1721 {
1722 RakAssert(maximum>=minimum);
1723 if (allowOutsideRange)
1724 {
1725 bool isOutsideRange;
1726 Read(isOutsideRange);
1727 if (isOutsideRange)
1728 return Read(value);
1729 }
1730 unsigned char output[sizeof(templateType)];
1731 memset(output,0,sizeof(output));
1732 bool success = ReadBits(output,requiredBits);
1733 if (success)
1734 {
1735 if (IsBigEndian()==true)
1736 ReverseBytesInPlace(output,sizeof(output));
1737 memcpy(&value,output,sizeof(output));
1738
1739 value+=minimum;
1740 }
1741
1742 return success;
1743 }
1744
1745 template <class templateType> // templateType for this function must be a float or double
1746 bool BitStream::ReadNormVector( templateType &x, templateType &y, templateType &z )
1747 {
1748 float xIn,yIn,zIn;
1749 ReadFloat16(xIn,-1.0f,1.0f);
1750 ReadFloat16(yIn,-1.0f,1.0f);
1751 ReadFloat16(zIn,-1.0f,1.0f);
1752 x=xIn;
1753 y=yIn;
1754 z=zIn;
1755 return true;
1756 }
1757
1758 template <class templateType> // templateType for this function must be a float or double
1759 bool BitStream::ReadVector( templateType &x, templateType &y, templateType &z )
1760 {
1761 float magnitude;
1762 //unsigned short sx,sy,sz;
1763 if (!Read(magnitude))
1764 return false;
1765 if (magnitude>0.00001f)
1766 {
1767 // Read(sx);
1768 // Read(sy);
1769 // if (!Read(sz))
1770 // return false;
1771 // x=((float)sx / 32767.5f - 1.0f) * magnitude;
1772 // y=((float)sy / 32767.5f - 1.0f) * magnitude;
1773 // z=((float)sz / 32767.5f - 1.0f) * magnitude;
1774 float cx=0.0f,cy=0.0f,cz=0.0f;
1775 ReadCompressed(cx);
1776 ReadCompressed(cy);
1777 if (!ReadCompressed(cz))
1778 return false;
1779 x=cx;
1780 y=cy;
1781 z=cz;
1782 x*=magnitude;
1783 y*=magnitude;
1784 z*=magnitude;
1785 }
1786 else
1787 {
1788 x=0.0;
1789 y=0.0;
1790 z=0.0;
1791 }
1792 return true;
1793 }
1794
1795 template <class templateType> // templateType for this function must be a float or double
1796 bool BitStream::ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z)
1797 {
1798 bool cwNeg=false, cxNeg=false, cyNeg=false, czNeg=false;
1799 unsigned short cx,cy,cz;
1800 Read(cwNeg);
1801 Read(cxNeg);
1802 Read(cyNeg);
1803 Read(czNeg);
1804 Read(cx);
1805 Read(cy);
1806 if (!Read(cz))
1807 return false;
1808
1809 // Calculate w from x,y,z
1810 x=(templateType)(cx/65535.0);
1811 y=(templateType)(cy/65535.0);
1812 z=(templateType)(cz/65535.0);
1813 if (cxNeg) x=-x;
1814 if (cyNeg) y=-y;
1815 if (czNeg) z=-z;
1816 float difference = 1.0f - x*x - y*y - z*z;
1817 if (difference < 0.0f)
1818 difference=0.0f;
1819 w = (templateType)(sqrt(difference));
1820 if (cwNeg)
1821 w=-w;
1822
1823 return true;
1824 }
1825
1826 template <class templateType> // templateType for this function must be a float or double
1827 bool BitStream::ReadOrthMatrix(
1828 templateType &m00, templateType &m01, templateType &m02,
1829 templateType &m10, templateType &m11, templateType &m12,
1830 templateType &m20, templateType &m21, templateType &m22 )
1831 {
1832 float qw,qx,qy,qz;
1833 if (!ReadNormQuat(qw,qx,qy,qz))
1834 return false;
1835
1836 // Quat to orthogonal rotation matrix
1837 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
1838 double sqw = (double)qw*(double)qw;
1839 double sqx = (double)qx*(double)qx;
1840 double sqy = (double)qy*(double)qy;
1841 double sqz = (double)qz*(double)qz;
1842 m00 = (templateType)(sqx - sqy - sqz + sqw); // since sqw + sqx + sqy + sqz =1
1843 m11 = (templateType)(-sqx + sqy - sqz + sqw);
1844 m22 = (templateType)(-sqx - sqy + sqz + sqw);
1845
1846 double tmp1 = (double)qx*(double)qy;
1847 double tmp2 = (double)qz*(double)qw;
1848 m10 = (templateType)(2.0 * (tmp1 + tmp2));
1849 m01 = (templateType)(2.0 * (tmp1 - tmp2));
1850
1851 tmp1 = (double)qx*(double)qz;
1852 tmp2 = (double)qy*(double)qw;
1853 m20 =(templateType)(2.0 * (tmp1 - tmp2));
1854 m02 = (templateType)(2.0 * (tmp1 + tmp2));
1855 tmp1 = (double)qy*(double)qz;
1856 tmp2 = (double)qx*(double)qw;
1857 m21 = (templateType)(2.0 * (tmp1 + tmp2));
1858 m12 = (templateType)(2.0 * (tmp1 - tmp2));
1859
1860 return true;
1861 }
1862
1863 template <class templateType>
1864 BitStream& operator<<(BitStream& out, const templateType& c)
1865 {
1866 out.Write(c);
1867 return out;
1868 }
1869 template <class templateType>
1870 BitStream& operator>>(BitStream& in, templateType& c)
1871 {
1872 bool success = in.Read(c);
1873 (void)success;
1874
1875 RakAssert(success);
1876 return in;
1877 }
1878
1879 }
1880
1881 #ifdef _MSC_VER
1882 #pragma warning( pop )
1883 #endif
1884
1885 #endif