///////////////////////////////////////////////////////////////////////////////
//  S4D.cpp

#include "S4D.h"
#include "S3D.h"
#include "SColor.h"
#include "SMatrix.h"

S4D::S4D(void)
{
}

S4D::S4D(float fX_, float fY_, float fZ_, float fW_) :
fX(fX_),
fY(fY_),
fZ(fZ_),
fW(fW_)
{
}

S4D::S4D(const S3D& Pos) :
fX(Pos.fX),
fY(Pos.fY),
fZ(Pos.fZ),
fW(1.0f)
{
}

const S4D S4D::operator+(const S4D& Pos) const
{
	return S4D(fX + Pos.fX, fY + Pos.fY, fZ + Pos.fZ, fW + Pos.fW);
}

const S4D S4D::operator*(const SMatrix& m) const
{
	return S4D(
		fX * m.m[0][0] + fY * m.m[1][0] + fZ * m.m[2][0] + fW * m.m[3][0],
		fX * m.m[0][1] + fY * m.m[1][1] + fZ * m.m[2][1] + fW * m.m[3][1],
		fX * m.m[0][2] + fY * m.m[1][2] + fZ * m.m[2][2] + fW * m.m[3][2],
		fX * m.m[0][3] + fY * m.m[1][3] + fZ * m.m[2][3] + fW * m.m[3][3]);
}

float& S4D::operator[](int n)
{
	switch (n) {
	case 0:	return fX;
	case 1:	return fY;
	case 2:	return fZ;
	case 3:	return fW;
	}

	return fX;
}

const float& S4D::operator[](int n) const
{
	switch (n) {
	case 0:	return fX;
	case 1:	return fY;
	case 2:	return fZ;
	case 3:	return fW;
	}

	return fX;
}

void S4D::Set(float fX_, float fY_, float fZ_, float fW_)
{
	fX = fX_;
	fY = fY_;
	fZ = fZ_;
	fW = fW_;
}

const S3D S4D::GetS3D(void) const
{
	if (fW != 0.0f) {
		const float fInvW = 1 / fW;

		return S3D(fX * fInvW, fY * fInvW, fZ * fInvW);
	}

	return S3D(fX, fY, fZ);
}

const S3D S4D::GetS3DNotDivideW(void) const
{
	return S3D(fX, fY, fZ);
}

SColor S4D::GetSColor() const
{
	return SColor(fX, fY, fZ, fW);
}

