aboutsummaryrefslogtreecommitdiff
path: root/sp/src/public/mathlib/compressed_vector.h
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /sp/src/public/mathlib/compressed_vector.h
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'sp/src/public/mathlib/compressed_vector.h')
-rw-r--r--sp/src/public/mathlib/compressed_vector.h1216
1 files changed, 608 insertions, 608 deletions
diff --git a/sp/src/public/mathlib/compressed_vector.h b/sp/src/public/mathlib/compressed_vector.h
index 6eb3ac5d..6a495229 100644
--- a/sp/src/public/mathlib/compressed_vector.h
+++ b/sp/src/public/mathlib/compressed_vector.h
@@ -1,608 +1,608 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-
-#ifndef COMPRESSED_VECTOR_H
-#define COMPRESSED_VECTOR_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <math.h>
-#include <float.h>
-
-// For vec_t, put this somewhere else?
-#include "basetypes.h"
-
-// For rand(). We really need a library!
-#include <stdlib.h>
-
-#include "tier0/dbg.h"
-#include "mathlib/vector.h"
-
-#include "mathlib/mathlib.h"
-
-#if defined( _X360 )
-#pragma bitfield_order( push, lsb_to_msb )
-#endif
-//=========================================================
-// fit a 3D vector into 32 bits
-//=========================================================
-
-class Vector32
-{
-public:
- // Construction/destruction:
- Vector32(void);
- Vector32(vec_t X, vec_t Y, vec_t Z);
-
- // assignment
- Vector32& operator=(const Vector &vOther);
- operator Vector ();
-
-private:
- unsigned short x:10;
- unsigned short y:10;
- unsigned short z:10;
- unsigned short exp:2;
-};
-
-inline Vector32& Vector32::operator=(const Vector &vOther)
-{
- CHECK_VALID(vOther);
-
- static float expScale[4] = { 4.0f, 16.0f, 32.f, 64.f };
-
- float fmax = Max( fabs( vOther.x ), fabs( vOther.y ) );
- fmax = Max( fmax, (float)fabs( vOther.z ) );
-
- for (exp = 0; exp < 3; exp++)
- {
- if (fmax < expScale[exp])
- break;
- }
- Assert( fmax < expScale[exp] );
-
- float fexp = 512.0f / expScale[exp];
-
- x = Clamp( (int)(vOther.x * fexp) + 512, 0, 1023 );
- y = Clamp( (int)(vOther.y * fexp) + 512, 0, 1023 );
- z = Clamp( (int)(vOther.z * fexp) + 512, 0, 1023 );
- return *this;
-}
-
-
-inline Vector32::operator Vector ()
-{
- Vector tmp;
-
- static float expScale[4] = { 4.0f, 16.0f, 32.f, 64.f };
-
- float fexp = expScale[exp] / 512.0f;
-
- tmp.x = (((int)x) - 512) * fexp;
- tmp.y = (((int)y) - 512) * fexp;
- tmp.z = (((int)z) - 512) * fexp;
- return tmp;
-}
-
-
-//=========================================================
-// Fit a unit vector into 32 bits
-//=========================================================
-
-class Normal32
-{
-public:
- // Construction/destruction:
- Normal32(void);
- Normal32(vec_t X, vec_t Y, vec_t Z);
-
- // assignment
- Normal32& operator=(const Vector &vOther);
- operator Vector ();
-
-private:
- unsigned short x:15;
- unsigned short y:15;
- unsigned short zneg:1;
-};
-
-
-inline Normal32& Normal32::operator=(const Vector &vOther)
-{
- CHECK_VALID(vOther);
-
- x = Clamp( (int)(vOther.x * 16384) + 16384, 0, 32767 );
- y = Clamp( (int)(vOther.y * 16384) + 16384, 0, 32767 );
- zneg = (vOther.z < 0);
- //x = vOther.x;
- //y = vOther.y;
- //z = vOther.z;
- return *this;
-}
-
-
-inline Normal32::operator Vector ()
-{
- Vector tmp;
-
- tmp.x = ((int)x - 16384) * (1 / 16384.0);
- tmp.y = ((int)y - 16384) * (1 / 16384.0);
- tmp.z = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y );
- if (zneg)
- tmp.z = -tmp.z;
- return tmp;
-}
-
-
-//=========================================================
-// 64 bit Quaternion
-//=========================================================
-
-class Quaternion64
-{
-public:
- // Construction/destruction:
- Quaternion64(void);
- Quaternion64(vec_t X, vec_t Y, vec_t Z);
-
- // assignment
- // Quaternion& operator=(const Quaternion64 &vOther);
- Quaternion64& operator=(const Quaternion &vOther);
- operator Quaternion ();
-private:
- uint64 x:21;
- uint64 y:21;
- uint64 z:21;
- uint64 wneg:1;
-};
-
-
-inline Quaternion64::operator Quaternion ()
-{
- Quaternion tmp;
-
- // shift to -1048576, + 1048575, then round down slightly to -1.0 < x < 1.0
- tmp.x = ((int)x - 1048576) * (1 / 1048576.5f);
- tmp.y = ((int)y - 1048576) * (1 / 1048576.5f);
- tmp.z = ((int)z - 1048576) * (1 / 1048576.5f);
- tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z );
- if (wneg)
- tmp.w = -tmp.w;
- return tmp;
-}
-
-inline Quaternion64& Quaternion64::operator=(const Quaternion &vOther)
-{
- CHECK_VALID(vOther);
-
- x = Clamp( (int)(vOther.x * 1048576) + 1048576, 0, 2097151 );
- y = Clamp( (int)(vOther.y * 1048576) + 1048576, 0, 2097151 );
- z = Clamp( (int)(vOther.z * 1048576) + 1048576, 0, 2097151 );
- wneg = (vOther.w < 0);
- return *this;
-}
-
-//=========================================================
-// 48 bit Quaternion
-//=========================================================
-
-class Quaternion48
-{
-public:
- // Construction/destruction:
- Quaternion48(void);
- Quaternion48(vec_t X, vec_t Y, vec_t Z);
-
- // assignment
- // Quaternion& operator=(const Quaternion48 &vOther);
- Quaternion48& operator=(const Quaternion &vOther);
- operator Quaternion ();
-private:
- unsigned short x:16;
- unsigned short y:16;
- unsigned short z:15;
- unsigned short wneg:1;
-};
-
-
-inline Quaternion48::operator Quaternion ()
-{
- Quaternion tmp;
-
- tmp.x = ((int)x - 32768) * (1 / 32768.0);
- tmp.y = ((int)y - 32768) * (1 / 32768.0);
- tmp.z = ((int)z - 16384) * (1 / 16384.0);
- tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z );
- if (wneg)
- tmp.w = -tmp.w;
- return tmp;
-}
-
-inline Quaternion48& Quaternion48::operator=(const Quaternion &vOther)
-{
- CHECK_VALID(vOther);
-
- x = Clamp( (int)(vOther.x * 32768) + 32768, 0, 65535 );
- y = Clamp( (int)(vOther.y * 32768) + 32768, 0, 65535 );
- z = Clamp( (int)(vOther.z * 16384) + 16384, 0, 32767 );
- wneg = (vOther.w < 0);
- return *this;
-}
-
-//=========================================================
-// 32 bit Quaternion
-//=========================================================
-
-class Quaternion32
-{
-public:
- // Construction/destruction:
- Quaternion32(void);
- Quaternion32(vec_t X, vec_t Y, vec_t Z);
-
- // assignment
- // Quaternion& operator=(const Quaternion48 &vOther);
- Quaternion32& operator=(const Quaternion &vOther);
- operator Quaternion ();
-private:
- unsigned int x:11;
- unsigned int y:10;
- unsigned int z:10;
- unsigned int wneg:1;
-};
-
-
-inline Quaternion32::operator Quaternion ()
-{
- Quaternion tmp;
-
- tmp.x = ((int)x - 1024) * (1 / 1024.0);
- tmp.y = ((int)y - 512) * (1 / 512.0);
- tmp.z = ((int)z - 512) * (1 / 512.0);
- tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z );
- if (wneg)
- tmp.w = -tmp.w;
- return tmp;
-}
-
-inline Quaternion32& Quaternion32::operator=(const Quaternion &vOther)
-{
- CHECK_VALID(vOther);
-
- x = Clamp( (int)(vOther.x * 1024) + 1024, 0, 2047 );
- y = Clamp( (int)(vOther.y * 512) + 512, 0, 1023 );
- z = Clamp( (int)(vOther.z * 512) + 512, 0, 1023 );
- wneg = (vOther.w < 0);
- return *this;
-}
-
-//=========================================================
-// 16 bit float
-//=========================================================
-
-
-const int float32bias = 127;
-const int float16bias = 15;
-
-const float maxfloat16bits = 65504.0f;
-
-class float16
-{
-public:
- //float16() {}
- //float16( float f ) { m_storage.rawWord = ConvertFloatTo16bits(f); }
-
- void Init() { m_storage.rawWord = 0; }
-// float16& operator=(const float16 &other) { m_storage.rawWord = other.m_storage.rawWord; return *this; }
-// float16& operator=(const float &other) { m_storage.rawWord = ConvertFloatTo16bits(other); return *this; }
-// operator unsigned short () { return m_storage.rawWord; }
-// operator float () { return Convert16bitFloatTo32bits( m_storage.rawWord ); }
- unsigned short GetBits() const
- {
- return m_storage.rawWord;
- }
- float GetFloat() const
- {
- return Convert16bitFloatTo32bits( m_storage.rawWord );
- }
- void SetFloat( float in )
- {
- m_storage.rawWord = ConvertFloatTo16bits( in );
- }
-
- bool IsInfinity() const
- {
- return m_storage.bits.biased_exponent == 31 && m_storage.bits.mantissa == 0;
- }
- bool IsNaN() const
- {
- return m_storage.bits.biased_exponent == 31 && m_storage.bits.mantissa != 0;
- }
-
- bool operator==(const float16 other) const { return m_storage.rawWord == other.m_storage.rawWord; }
- bool operator!=(const float16 other) const { return m_storage.rawWord != other.m_storage.rawWord; }
-
-// bool operator< (const float other) const { return GetFloat() < other; }
-// bool operator> (const float other) const { return GetFloat() > other; }
-
-protected:
- union float32bits
- {
- float rawFloat;
- struct
- {
- unsigned int mantissa : 23;
- unsigned int biased_exponent : 8;
- unsigned int sign : 1;
- } bits;
- };
-
- union float16bits
- {
- unsigned short rawWord;
- struct
- {
- unsigned short mantissa : 10;
- unsigned short biased_exponent : 5;
- unsigned short sign : 1;
- } bits;
- };
-
- static bool IsNaN( float16bits in )
- {
- return in.bits.biased_exponent == 31 && in.bits.mantissa != 0;
- }
- static bool IsInfinity( float16bits in )
- {
- return in.bits.biased_exponent == 31 && in.bits.mantissa == 0;
- }
-
- // 0x0001 - 0x03ff
- static unsigned short ConvertFloatTo16bits( float input )
- {
- if ( input > maxfloat16bits )
- input = maxfloat16bits;
- else if ( input < -maxfloat16bits )
- input = -maxfloat16bits;
-
- float16bits output;
- float32bits inFloat;
-
- inFloat.rawFloat = input;
-
- output.bits.sign = inFloat.bits.sign;
-
- if ( (inFloat.bits.biased_exponent==0) && (inFloat.bits.mantissa==0) )
- {
- // zero
- output.bits.mantissa = 0;
- output.bits.biased_exponent = 0;
- }
- else if ( (inFloat.bits.biased_exponent==0) && (inFloat.bits.mantissa!=0) )
- {
- // denorm -- denorm float maps to 0 half
- output.bits.mantissa = 0;
- output.bits.biased_exponent = 0;
- }
- else if ( (inFloat.bits.biased_exponent==0xff) && (inFloat.bits.mantissa==0) )
- {
-#if 0
- // infinity
- output.bits.mantissa = 0;
- output.bits.biased_exponent = 31;
-#else
- // infinity maps to maxfloat
- output.bits.mantissa = 0x3ff;
- output.bits.biased_exponent = 0x1e;
-#endif
- }
- else if ( (inFloat.bits.biased_exponent==0xff) && (inFloat.bits.mantissa!=0) )
- {
-#if 0
- // NaN
- output.bits.mantissa = 1;
- output.bits.biased_exponent = 31;
-#else
- // NaN maps to zero
- output.bits.mantissa = 0;
- output.bits.biased_exponent = 0;
-#endif
- }
- else
- {
- // regular number
- int new_exp = inFloat.bits.biased_exponent-127;
-
- if (new_exp<-24)
- {
- // this maps to 0
- output.bits.mantissa = 0;
- output.bits.biased_exponent = 0;
- }
-
- if (new_exp<-14)
- {
- // this maps to a denorm
- output.bits.biased_exponent = 0;
- unsigned int exp_val = ( unsigned int )( -14 - ( inFloat.bits.biased_exponent - float32bias ) );
- if( exp_val > 0 && exp_val < 11 )
- {
- output.bits.mantissa = ( 1 << ( 10 - exp_val ) ) + ( inFloat.bits.mantissa >> ( 13 + exp_val ) );
- }
- }
- else if (new_exp>15)
- {
-#if 0
- // map this value to infinity
- output.bits.mantissa = 0;
- output.bits.biased_exponent = 31;
-#else
- // to big. . . maps to maxfloat
- output.bits.mantissa = 0x3ff;
- output.bits.biased_exponent = 0x1e;
-#endif
- }
- else
- {
- output.bits.biased_exponent = new_exp+15;
- output.bits.mantissa = (inFloat.bits.mantissa >> 13);
- }
- }
- return output.rawWord;
- }
-
- static float Convert16bitFloatTo32bits( unsigned short input )
- {
- float32bits output;
- const float16bits &inFloat = *((float16bits *)&input);
-
- if( IsInfinity( inFloat ) )
- {
- return maxfloat16bits * ( ( inFloat.bits.sign == 1 ) ? -1.0f : 1.0f );
- }
- if( IsNaN( inFloat ) )
- {
- return 0.0;
- }
- if( inFloat.bits.biased_exponent == 0 && inFloat.bits.mantissa != 0 )
- {
- // denorm
- const float half_denorm = (1.0f/16384.0f); // 2^-14
- float mantissa = ((float)(inFloat.bits.mantissa)) / 1024.0f;
- float sgn = (inFloat.bits.sign)? -1.0f :1.0f;
- output.rawFloat = sgn*mantissa*half_denorm;
- }
- else
- {
- // regular number
- unsigned mantissa = inFloat.bits.mantissa;
- unsigned biased_exponent = inFloat.bits.biased_exponent;
- unsigned sign = ((unsigned)inFloat.bits.sign) << 31;
- biased_exponent = ( (biased_exponent - float16bias + float32bias) * (biased_exponent != 0) ) << 23;
- mantissa <<= (23-10);
-
- *((unsigned *)&output) = ( mantissa | biased_exponent | sign );
- }
-
- return output.rawFloat;
- }
-
-
- float16bits m_storage;
-};
-
-class float16_with_assign : public float16
-{
-public:
- float16_with_assign() {}
- float16_with_assign( float f ) { m_storage.rawWord = ConvertFloatTo16bits(f); }
-
- float16& operator=(const float16 &other) { m_storage.rawWord = ((float16_with_assign &)other).m_storage.rawWord; return *this; }
- float16& operator=(const float &other) { m_storage.rawWord = ConvertFloatTo16bits(other); return *this; }
-// operator unsigned short () const { return m_storage.rawWord; }
- operator float () const { return Convert16bitFloatTo32bits( m_storage.rawWord ); }
-};
-
-//=========================================================
-// Fit a 3D vector in 48 bits
-//=========================================================
-
-class Vector48
-{
-public:
- // Construction/destruction:
- Vector48(void) {}
- Vector48(vec_t X, vec_t Y, vec_t Z) { x.SetFloat( X ); y.SetFloat( Y ); z.SetFloat( Z ); }
-
- // assignment
- Vector48& operator=(const Vector &vOther);
- operator Vector ();
-
- const float operator[]( int i ) const { return (((float16 *)this)[i]).GetFloat(); }
-
- float16 x;
- float16 y;
- float16 z;
-};
-
-inline Vector48& Vector48::operator=(const Vector &vOther)
-{
- CHECK_VALID(vOther);
-
- x.SetFloat( vOther.x );
- y.SetFloat( vOther.y );
- z.SetFloat( vOther.z );
- return *this;
-}
-
-
-inline Vector48::operator Vector ()
-{
- Vector tmp;
-
- tmp.x = x.GetFloat();
- tmp.y = y.GetFloat();
- tmp.z = z.GetFloat();
-
- return tmp;
-}
-
-//=========================================================
-// Fit a 2D vector in 32 bits
-//=========================================================
-
-class Vector2d32
-{
-public:
- // Construction/destruction:
- Vector2d32(void) {}
- Vector2d32(vec_t X, vec_t Y) { x.SetFloat( X ); y.SetFloat( Y ); }
-
- // assignment
- Vector2d32& operator=(const Vector &vOther);
- Vector2d32& operator=(const Vector2D &vOther);
-
- operator Vector2D ();
-
- void Init( vec_t ix = 0.f, vec_t iy = 0.f);
-
- float16_with_assign x;
- float16_with_assign y;
-};
-
-inline Vector2d32& Vector2d32::operator=(const Vector2D &vOther)
-{
- x.SetFloat( vOther.x );
- y.SetFloat( vOther.y );
- return *this;
-}
-
-inline Vector2d32::operator Vector2D ()
-{
- Vector2D tmp;
-
- tmp.x = x.GetFloat();
- tmp.y = y.GetFloat();
-
- return tmp;
-}
-
-inline void Vector2d32::Init( vec_t ix, vec_t iy )
-{
- x.SetFloat(ix);
- y.SetFloat(iy);
-}
-
-#if defined( _X360 )
-#pragma bitfield_order( pop )
-#endif
-
-#endif
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+
+#ifndef COMPRESSED_VECTOR_H
+#define COMPRESSED_VECTOR_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <math.h>
+#include <float.h>
+
+// For vec_t, put this somewhere else?
+#include "basetypes.h"
+
+// For rand(). We really need a library!
+#include <stdlib.h>
+
+#include "tier0/dbg.h"
+#include "mathlib/vector.h"
+
+#include "mathlib/mathlib.h"
+
+#if defined( _X360 )
+#pragma bitfield_order( push, lsb_to_msb )
+#endif
+//=========================================================
+// fit a 3D vector into 32 bits
+//=========================================================
+
+class Vector32
+{
+public:
+ // Construction/destruction:
+ Vector32(void);
+ Vector32(vec_t X, vec_t Y, vec_t Z);
+
+ // assignment
+ Vector32& operator=(const Vector &vOther);
+ operator Vector ();
+
+private:
+ unsigned short x:10;
+ unsigned short y:10;
+ unsigned short z:10;
+ unsigned short exp:2;
+};
+
+inline Vector32& Vector32::operator=(const Vector &vOther)
+{
+ CHECK_VALID(vOther);
+
+ static float expScale[4] = { 4.0f, 16.0f, 32.f, 64.f };
+
+ float fmax = Max( fabs( vOther.x ), fabs( vOther.y ) );
+ fmax = Max( fmax, (float)fabs( vOther.z ) );
+
+ for (exp = 0; exp < 3; exp++)
+ {
+ if (fmax < expScale[exp])
+ break;
+ }
+ Assert( fmax < expScale[exp] );
+
+ float fexp = 512.0f / expScale[exp];
+
+ x = Clamp( (int)(vOther.x * fexp) + 512, 0, 1023 );
+ y = Clamp( (int)(vOther.y * fexp) + 512, 0, 1023 );
+ z = Clamp( (int)(vOther.z * fexp) + 512, 0, 1023 );
+ return *this;
+}
+
+
+inline Vector32::operator Vector ()
+{
+ Vector tmp;
+
+ static float expScale[4] = { 4.0f, 16.0f, 32.f, 64.f };
+
+ float fexp = expScale[exp] / 512.0f;
+
+ tmp.x = (((int)x) - 512) * fexp;
+ tmp.y = (((int)y) - 512) * fexp;
+ tmp.z = (((int)z) - 512) * fexp;
+ return tmp;
+}
+
+
+//=========================================================
+// Fit a unit vector into 32 bits
+//=========================================================
+
+class Normal32
+{
+public:
+ // Construction/destruction:
+ Normal32(void);
+ Normal32(vec_t X, vec_t Y, vec_t Z);
+
+ // assignment
+ Normal32& operator=(const Vector &vOther);
+ operator Vector ();
+
+private:
+ unsigned short x:15;
+ unsigned short y:15;
+ unsigned short zneg:1;
+};
+
+
+inline Normal32& Normal32::operator=(const Vector &vOther)
+{
+ CHECK_VALID(vOther);
+
+ x = Clamp( (int)(vOther.x * 16384) + 16384, 0, 32767 );
+ y = Clamp( (int)(vOther.y * 16384) + 16384, 0, 32767 );
+ zneg = (vOther.z < 0);
+ //x = vOther.x;
+ //y = vOther.y;
+ //z = vOther.z;
+ return *this;
+}
+
+
+inline Normal32::operator Vector ()
+{
+ Vector tmp;
+
+ tmp.x = ((int)x - 16384) * (1 / 16384.0);
+ tmp.y = ((int)y - 16384) * (1 / 16384.0);
+ tmp.z = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y );
+ if (zneg)
+ tmp.z = -tmp.z;
+ return tmp;
+}
+
+
+//=========================================================
+// 64 bit Quaternion
+//=========================================================
+
+class Quaternion64
+{
+public:
+ // Construction/destruction:
+ Quaternion64(void);
+ Quaternion64(vec_t X, vec_t Y, vec_t Z);
+
+ // assignment
+ // Quaternion& operator=(const Quaternion64 &vOther);
+ Quaternion64& operator=(const Quaternion &vOther);
+ operator Quaternion ();
+private:
+ uint64 x:21;
+ uint64 y:21;
+ uint64 z:21;
+ uint64 wneg:1;
+};
+
+
+inline Quaternion64::operator Quaternion ()
+{
+ Quaternion tmp;
+
+ // shift to -1048576, + 1048575, then round down slightly to -1.0 < x < 1.0
+ tmp.x = ((int)x - 1048576) * (1 / 1048576.5f);
+ tmp.y = ((int)y - 1048576) * (1 / 1048576.5f);
+ tmp.z = ((int)z - 1048576) * (1 / 1048576.5f);
+ tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z );
+ if (wneg)
+ tmp.w = -tmp.w;
+ return tmp;
+}
+
+inline Quaternion64& Quaternion64::operator=(const Quaternion &vOther)
+{
+ CHECK_VALID(vOther);
+
+ x = Clamp( (int)(vOther.x * 1048576) + 1048576, 0, 2097151 );
+ y = Clamp( (int)(vOther.y * 1048576) + 1048576, 0, 2097151 );
+ z = Clamp( (int)(vOther.z * 1048576) + 1048576, 0, 2097151 );
+ wneg = (vOther.w < 0);
+ return *this;
+}
+
+//=========================================================
+// 48 bit Quaternion
+//=========================================================
+
+class Quaternion48
+{
+public:
+ // Construction/destruction:
+ Quaternion48(void);
+ Quaternion48(vec_t X, vec_t Y, vec_t Z);
+
+ // assignment
+ // Quaternion& operator=(const Quaternion48 &vOther);
+ Quaternion48& operator=(const Quaternion &vOther);
+ operator Quaternion ();
+private:
+ unsigned short x:16;
+ unsigned short y:16;
+ unsigned short z:15;
+ unsigned short wneg:1;
+};
+
+
+inline Quaternion48::operator Quaternion ()
+{
+ Quaternion tmp;
+
+ tmp.x = ((int)x - 32768) * (1 / 32768.0);
+ tmp.y = ((int)y - 32768) * (1 / 32768.0);
+ tmp.z = ((int)z - 16384) * (1 / 16384.0);
+ tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z );
+ if (wneg)
+ tmp.w = -tmp.w;
+ return tmp;
+}
+
+inline Quaternion48& Quaternion48::operator=(const Quaternion &vOther)
+{
+ CHECK_VALID(vOther);
+
+ x = Clamp( (int)(vOther.x * 32768) + 32768, 0, 65535 );
+ y = Clamp( (int)(vOther.y * 32768) + 32768, 0, 65535 );
+ z = Clamp( (int)(vOther.z * 16384) + 16384, 0, 32767 );
+ wneg = (vOther.w < 0);
+ return *this;
+}
+
+//=========================================================
+// 32 bit Quaternion
+//=========================================================
+
+class Quaternion32
+{
+public:
+ // Construction/destruction:
+ Quaternion32(void);
+ Quaternion32(vec_t X, vec_t Y, vec_t Z);
+
+ // assignment
+ // Quaternion& operator=(const Quaternion48 &vOther);
+ Quaternion32& operator=(const Quaternion &vOther);
+ operator Quaternion ();
+private:
+ unsigned int x:11;
+ unsigned int y:10;
+ unsigned int z:10;
+ unsigned int wneg:1;
+};
+
+
+inline Quaternion32::operator Quaternion ()
+{
+ Quaternion tmp;
+
+ tmp.x = ((int)x - 1024) * (1 / 1024.0);
+ tmp.y = ((int)y - 512) * (1 / 512.0);
+ tmp.z = ((int)z - 512) * (1 / 512.0);
+ tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z );
+ if (wneg)
+ tmp.w = -tmp.w;
+ return tmp;
+}
+
+inline Quaternion32& Quaternion32::operator=(const Quaternion &vOther)
+{
+ CHECK_VALID(vOther);
+
+ x = Clamp( (int)(vOther.x * 1024) + 1024, 0, 2047 );
+ y = Clamp( (int)(vOther.y * 512) + 512, 0, 1023 );
+ z = Clamp( (int)(vOther.z * 512) + 512, 0, 1023 );
+ wneg = (vOther.w < 0);
+ return *this;
+}
+
+//=========================================================
+// 16 bit float
+//=========================================================
+
+
+const int float32bias = 127;
+const int float16bias = 15;
+
+const float maxfloat16bits = 65504.0f;
+
+class float16
+{
+public:
+ //float16() {}
+ //float16( float f ) { m_storage.rawWord = ConvertFloatTo16bits(f); }
+
+ void Init() { m_storage.rawWord = 0; }
+// float16& operator=(const float16 &other) { m_storage.rawWord = other.m_storage.rawWord; return *this; }
+// float16& operator=(const float &other) { m_storage.rawWord = ConvertFloatTo16bits(other); return *this; }
+// operator unsigned short () { return m_storage.rawWord; }
+// operator float () { return Convert16bitFloatTo32bits( m_storage.rawWord ); }
+ unsigned short GetBits() const
+ {
+ return m_storage.rawWord;
+ }
+ float GetFloat() const
+ {
+ return Convert16bitFloatTo32bits( m_storage.rawWord );
+ }
+ void SetFloat( float in )
+ {
+ m_storage.rawWord = ConvertFloatTo16bits( in );
+ }
+
+ bool IsInfinity() const
+ {
+ return m_storage.bits.biased_exponent == 31 && m_storage.bits.mantissa == 0;
+ }
+ bool IsNaN() const
+ {
+ return m_storage.bits.biased_exponent == 31 && m_storage.bits.mantissa != 0;
+ }
+
+ bool operator==(const float16 other) const { return m_storage.rawWord == other.m_storage.rawWord; }
+ bool operator!=(const float16 other) const { return m_storage.rawWord != other.m_storage.rawWord; }
+
+// bool operator< (const float other) const { return GetFloat() < other; }
+// bool operator> (const float other) const { return GetFloat() > other; }
+
+protected:
+ union float32bits
+ {
+ float rawFloat;
+ struct
+ {
+ unsigned int mantissa : 23;
+ unsigned int biased_exponent : 8;
+ unsigned int sign : 1;
+ } bits;
+ };
+
+ union float16bits
+ {
+ unsigned short rawWord;
+ struct
+ {
+ unsigned short mantissa : 10;
+ unsigned short biased_exponent : 5;
+ unsigned short sign : 1;
+ } bits;
+ };
+
+ static bool IsNaN( float16bits in )
+ {
+ return in.bits.biased_exponent == 31 && in.bits.mantissa != 0;
+ }
+ static bool IsInfinity( float16bits in )
+ {
+ return in.bits.biased_exponent == 31 && in.bits.mantissa == 0;
+ }
+
+ // 0x0001 - 0x03ff
+ static unsigned short ConvertFloatTo16bits( float input )
+ {
+ if ( input > maxfloat16bits )
+ input = maxfloat16bits;
+ else if ( input < -maxfloat16bits )
+ input = -maxfloat16bits;
+
+ float16bits output;
+ float32bits inFloat;
+
+ inFloat.rawFloat = input;
+
+ output.bits.sign = inFloat.bits.sign;
+
+ if ( (inFloat.bits.biased_exponent==0) && (inFloat.bits.mantissa==0) )
+ {
+ // zero
+ output.bits.mantissa = 0;
+ output.bits.biased_exponent = 0;
+ }
+ else if ( (inFloat.bits.biased_exponent==0) && (inFloat.bits.mantissa!=0) )
+ {
+ // denorm -- denorm float maps to 0 half
+ output.bits.mantissa = 0;
+ output.bits.biased_exponent = 0;
+ }
+ else if ( (inFloat.bits.biased_exponent==0xff) && (inFloat.bits.mantissa==0) )
+ {
+#if 0
+ // infinity
+ output.bits.mantissa = 0;
+ output.bits.biased_exponent = 31;
+#else
+ // infinity maps to maxfloat
+ output.bits.mantissa = 0x3ff;
+ output.bits.biased_exponent = 0x1e;
+#endif
+ }
+ else if ( (inFloat.bits.biased_exponent==0xff) && (inFloat.bits.mantissa!=0) )
+ {
+#if 0
+ // NaN
+ output.bits.mantissa = 1;
+ output.bits.biased_exponent = 31;
+#else
+ // NaN maps to zero
+ output.bits.mantissa = 0;
+ output.bits.biased_exponent = 0;
+#endif
+ }
+ else
+ {
+ // regular number
+ int new_exp = inFloat.bits.biased_exponent-127;
+
+ if (new_exp<-24)
+ {
+ // this maps to 0
+ output.bits.mantissa = 0;
+ output.bits.biased_exponent = 0;
+ }
+
+ if (new_exp<-14)
+ {
+ // this maps to a denorm
+ output.bits.biased_exponent = 0;
+ unsigned int exp_val = ( unsigned int )( -14 - ( inFloat.bits.biased_exponent - float32bias ) );
+ if( exp_val > 0 && exp_val < 11 )
+ {
+ output.bits.mantissa = ( 1 << ( 10 - exp_val ) ) + ( inFloat.bits.mantissa >> ( 13 + exp_val ) );
+ }
+ }
+ else if (new_exp>15)
+ {
+#if 0
+ // map this value to infinity
+ output.bits.mantissa = 0;
+ output.bits.biased_exponent = 31;
+#else
+ // to big. . . maps to maxfloat
+ output.bits.mantissa = 0x3ff;
+ output.bits.biased_exponent = 0x1e;
+#endif
+ }
+ else
+ {
+ output.bits.biased_exponent = new_exp+15;
+ output.bits.mantissa = (inFloat.bits.mantissa >> 13);
+ }
+ }
+ return output.rawWord;
+ }
+
+ static float Convert16bitFloatTo32bits( unsigned short input )
+ {
+ float32bits output;
+ const float16bits &inFloat = *((float16bits *)&input);
+
+ if( IsInfinity( inFloat ) )
+ {
+ return maxfloat16bits * ( ( inFloat.bits.sign == 1 ) ? -1.0f : 1.0f );
+ }
+ if( IsNaN( inFloat ) )
+ {
+ return 0.0;
+ }
+ if( inFloat.bits.biased_exponent == 0 && inFloat.bits.mantissa != 0 )
+ {
+ // denorm
+ const float half_denorm = (1.0f/16384.0f); // 2^-14
+ float mantissa = ((float)(inFloat.bits.mantissa)) / 1024.0f;
+ float sgn = (inFloat.bits.sign)? -1.0f :1.0f;
+ output.rawFloat = sgn*mantissa*half_denorm;
+ }
+ else
+ {
+ // regular number
+ unsigned mantissa = inFloat.bits.mantissa;
+ unsigned biased_exponent = inFloat.bits.biased_exponent;
+ unsigned sign = ((unsigned)inFloat.bits.sign) << 31;
+ biased_exponent = ( (biased_exponent - float16bias + float32bias) * (biased_exponent != 0) ) << 23;
+ mantissa <<= (23-10);
+
+ *((unsigned *)&output) = ( mantissa | biased_exponent | sign );
+ }
+
+ return output.rawFloat;
+ }
+
+
+ float16bits m_storage;
+};
+
+class float16_with_assign : public float16
+{
+public:
+ float16_with_assign() {}
+ float16_with_assign( float f ) { m_storage.rawWord = ConvertFloatTo16bits(f); }
+
+ float16& operator=(const float16 &other) { m_storage.rawWord = ((float16_with_assign &)other).m_storage.rawWord; return *this; }
+ float16& operator=(const float &other) { m_storage.rawWord = ConvertFloatTo16bits(other); return *this; }
+// operator unsigned short () const { return m_storage.rawWord; }
+ operator float () const { return Convert16bitFloatTo32bits( m_storage.rawWord ); }
+};
+
+//=========================================================
+// Fit a 3D vector in 48 bits
+//=========================================================
+
+class Vector48
+{
+public:
+ // Construction/destruction:
+ Vector48(void) {}
+ Vector48(vec_t X, vec_t Y, vec_t Z) { x.SetFloat( X ); y.SetFloat( Y ); z.SetFloat( Z ); }
+
+ // assignment
+ Vector48& operator=(const Vector &vOther);
+ operator Vector ();
+
+ const float operator[]( int i ) const { return (((float16 *)this)[i]).GetFloat(); }
+
+ float16 x;
+ float16 y;
+ float16 z;
+};
+
+inline Vector48& Vector48::operator=(const Vector &vOther)
+{
+ CHECK_VALID(vOther);
+
+ x.SetFloat( vOther.x );
+ y.SetFloat( vOther.y );
+ z.SetFloat( vOther.z );
+ return *this;
+}
+
+
+inline Vector48::operator Vector ()
+{
+ Vector tmp;
+
+ tmp.x = x.GetFloat();
+ tmp.y = y.GetFloat();
+ tmp.z = z.GetFloat();
+
+ return tmp;
+}
+
+//=========================================================
+// Fit a 2D vector in 32 bits
+//=========================================================
+
+class Vector2d32
+{
+public:
+ // Construction/destruction:
+ Vector2d32(void) {}
+ Vector2d32(vec_t X, vec_t Y) { x.SetFloat( X ); y.SetFloat( Y ); }
+
+ // assignment
+ Vector2d32& operator=(const Vector &vOther);
+ Vector2d32& operator=(const Vector2D &vOther);
+
+ operator Vector2D ();
+
+ void Init( vec_t ix = 0.f, vec_t iy = 0.f);
+
+ float16_with_assign x;
+ float16_with_assign y;
+};
+
+inline Vector2d32& Vector2d32::operator=(const Vector2D &vOther)
+{
+ x.SetFloat( vOther.x );
+ y.SetFloat( vOther.y );
+ return *this;
+}
+
+inline Vector2d32::operator Vector2D ()
+{
+ Vector2D tmp;
+
+ tmp.x = x.GetFloat();
+ tmp.y = y.GetFloat();
+
+ return tmp;
+}
+
+inline void Vector2d32::Init( vec_t ix, vec_t iy )
+{
+ x.SetFloat(ix);
+ y.SetFloat(iy);
+}
+
+#if defined( _X360 )
+#pragma bitfield_order( pop )
+#endif
+
+#endif
+