diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /sp/src/public/mathlib/compressed_vector.h | |
| parent | Mark some more files as text. (diff) | |
| download | source-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.h | 1216 |
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 + |