
///////////////////////////////////////////////////////////////////////////////
//
// File   : Asura_CompressedVector3_101010N.h
// Author : Andy Tate
// Date   : 9-Jul-2008
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE

#ifndef __ASURA_COMPRESSEDVECTOR3_101010N_H__
#define __ASURA_COMPRESSEDVECTOR3_101010N_H__

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura_Maths.h"


////////////////////////////////////////////////////////////////////////////////
// Forward class declarations...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Class declaration...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Class        : Asura_CompressedVector3_101010N
// Author       : Andy Tate
// Date         : 9-Jul-2008
//
// Description  : Class to hold a 3-component vector in compressed form
//				  (specifically using 10-bits per component and ensuring that
//				  the vector is normalised in the first place).
////////////////////////////////////////////////////////////////////////////////

class Asura_CompressedVector3_101010N
{
	// Friend classes...
	friend class Asura_Chunk_Stream;

public:
	// Public functions...
	Asura_CompressedVector3_101010N(void)	{}
	//~Asura_CompressedVector3_101010N();

	Asura_CompressedVector3_101010N(const float fX, const float fY, const float fZ)
	{
		m_uValue	= (Asura_Maths::FloatToInt(fX * 511.0f) <<  0)
					+ (Asura_Maths::FloatToInt(fY * 511.0f) << 10)
					+ (Asura_Maths::FloatToInt(fZ * 511.0f) << 20);
	}

	Asura_CompressedVector3_101010N(const Asura_Vector_3& xVector)
	{
		m_uValue	= (Asura_Maths::FloatToInt(xVector.GetX() * 511.0f) <<  0)
					+ (Asura_Maths::FloatToInt(xVector.GetY() * 511.0f) << 10)
					+ (Asura_Maths::FloatToInt(xVector.GetZ() * 511.0f) << 20);
	}

	Asura_CompressedVector3_101010N(const Asura_AVector3& xVector)
	{
		m_uValue	= (Asura_Maths::FloatToInt(xVector.GetX() * 511.0f) <<  0)
					+ (Asura_Maths::FloatToInt(xVector.GetY() * 511.0f) << 10)
					+ (Asura_Maths::FloatToInt(xVector.GetZ() * 511.0f) << 20);
	}

	Asura_CompressedVector3_101010N(const Asura_CompressedVector3_101010N& xOther)
	: m_uValue(xOther.m_uValue)
	{
	}

	// Assignment operators...
	Asura_CompressedVector3_101010N& operator=(const Asura_Vector_3& xVector)
	{
		m_uValue	= (Asura_Maths::FloatToInt(xVector.GetX() * 511.0f) <<  0)
					+ (Asura_Maths::FloatToInt(xVector.GetY() * 511.0f) << 10)
					+ (Asura_Maths::FloatToInt(xVector.GetZ() * 511.0f) << 20);
		return(*this);
	}

	Asura_CompressedVector3_101010N& operator=(const Asura_AVector3& xVector)
	{
		m_uValue	= (Asura_Maths::FloatToInt(xVector.GetX() * 511.0f) <<  0)
					+ (Asura_Maths::FloatToInt(xVector.GetY() * 511.0f) << 10)
					+ (Asura_Maths::FloatToInt(xVector.GetZ() * 511.0f) << 20);
		return(*this);
	}

	Asura_CompressedVector3_101010N& operator=(const Asura_CompressedVector3_101010N& xOther)
	{
		m_uValue	= xOther.m_uValue;
		return(*this);
	}

	// Accessor functions...
	void GetVector(float& fX, float& fY, float& fZ) const
	{
		fX	= (static_cast<int>(m_uValue <<  2) >> 22) * (1.0f / 511.0f);
		fY	= (static_cast<int>(m_uValue << 12) >> 22) * (1.0f / 511.0f);
		fZ	= (static_cast<int>(m_uValue << 22) >> 22) * (1.0f / 511.0f);
	}

	void GetVector(Asura_Vector_3& xVector) const
	{
		float	fX, fY, fZ;

		GetVector(fX, fY, fZ);
		xVector	= Asura_Vector_3(fX, fY, fZ);
	}

	void GetVector(Asura_AVector3& xVector) const
	{
		float	fX, fY, fZ;

		GetVector(fX, fY, fZ);
		xVector	= Asura_AVector3(fX, fY, fZ);
	}


protected:
	// Protected variables...

	// Protected functions...


private:
	// Private variables...
	u_int	m_uValue;	// The integer version of the value.

	// Private functions...

};   // End of class 'Asura_CompressedVector3_101010N'.


#endif   // ifndef __ASURA_COMPRESSEDVECTOR3_101010N_H__


/// End of file. ///
