
#include "Matrix4x4.h"
#include <cmath>


void Matrix4x4::Identity(void)
{
	m[0][0] = 1.0f;
	m[0][1] = 0.0f;
	m[0][2] = 0.0f;
	m[0][3] = 0.0f;

	m[1][0] = 0.0f;
	m[1][1] = 1.0f;
	m[1][2] = 0.0f;
	m[1][3] = 0.0f;

	m[2][0] = 0.0f;
	m[2][1] = 0.0f;
	m[2][2] = 1.0f;
	m[2][3] = 0.0f;

	m[3][0] = 0.0f;
	m[3][1] = 0.0f;
	m[3][2] = 0.0f;
	m[3][3] = 1.0f;
}


void Matrix4x4::RotateX(float angle)
{
	Identity();

	m[1][1] = cosf(angle);
	m[2][2] = cosf(angle);
	m[1][2] = sinf(angle);
	m[2][1] = -sinf(angle);
}


void Matrix4x4::RotateY(float angle)
{
	Identity();

	m[0][0] = cosf(angle);
	m[2][2] = cosf(angle);
	m[0][2] = -sinf(angle);
	m[2][0] = sinf(angle);
}


void Matrix4x4::RotateZ(float angle)
{
	Identity();

	m[0][0] = cosf(angle);
	m[1][1] = cosf(angle);
	m[0][1] = sinf(angle);
	m[1][0] = -sinf(angle);
}


void Matrix4x4::Scale(float scale)
{
	Identity();

	m[0][0] = scale;
	m[1][1] = scale;
	m[2][2] = scale;
}


void Matrix4x4::Multiply(const Matrix4x4& other)
{
	Matrix4x4 temp = {};

	for (unsigned int i = 0u; i < 4u; ++i)
	{
		for (unsigned int j = 0u; j < 4u; ++j)
		{
			temp.m[i][j] = m[i][0] * other.m[0][j] + m[i][1] * other.m[1][j] + m[i][2] * other.m[2][j] + m[i][3] * other.m[3][j];
		}
	}

	for (unsigned int i = 0u; i < 4u; ++i)
	{
		for (unsigned int j = 0u; j < 4u; ++j)
		{
			m[i][j] = temp.m[i][j];
		}
	}
}


Vec4 Matrix4x4::Transform(const Vec4& other) const
{
	return Vec4
	{
		m[0][0] * other.x + m[1][0] * other.y + m[2][0] * other.z + m[3][0] * other.w,
		m[0][1] * other.x + m[1][1] * other.y + m[2][1] * other.z + m[3][1] * other.w,
		m[0][2] * other.x + m[1][2] * other.y + m[2][2] * other.z + m[3][2] * other.w,
		m[0][3] * other.x + m[1][3] * other.y + m[2][3] * other.z + m[3][3] * other.w
	};
}
