#include "pch.h" #include "proj.h" mat4_row_major proj::matrix; float proj::d_, proj::centerx, proj::centery; void proj::init(float* mat4x3, float d, float centerX, float centerY) { /*for (auto colIndex = 0; colIndex < 4; ++colIndex) { // Todo: out of bounds read from mat4x3? for (int rowIndex = colIndex, i = 4; i > 0; rowIndex += 4, --i) { ((float*)&matrix)[rowIndex] = mat4x3[rowIndex]; } }*/ memcpy(&matrix, mat4x3, sizeof(float) * 4 * 3); matrix.Row3.X = 0.0; matrix.Row3.Y = 0.0; matrix.Row3.Z = 0.0; matrix.Row3.W = 1.0; d_ = d; centerx = centerX; centery = centerY; } vector3 proj::matrix_vector_multiply(const mat4_row_major& mat, const vector3& vec) { vector3 dstVec; const float x = vec.X, y = vec.Y, z = vec.Z; dstVec.X = z * mat.Row0.Z + y * mat.Row0.Y + x * mat.Row0.X + mat.Row0.W; dstVec.Y = z * mat.Row1.Z + y * mat.Row1.Y + x * mat.Row1.X + mat.Row1.W; dstVec.Z = z * mat.Row2.Z + y * mat.Row2.Y + x * mat.Row2.X + mat.Row2.W; return dstVec; } float proj::z_distance(const vector3& vec) { auto projVec = matrix_vector_multiply(matrix, vec); return maths::magnitude(projVec); } vector2i proj::xform_to_2d(const vector2& vec) { vector3 vec3{ vec.X, vec.Y, 0 }; return xform_to_2d(vec3); } vector2i proj::xform_to_2d(const vector3& vec) { float projCoef; auto projVec = matrix_vector_multiply(matrix, vec); if (projVec.Z == 0.0f) projCoef = 999999.88f; else projCoef = d_ / projVec.Z; return { static_cast(projVec.X * projCoef + centerx), static_cast(projVec.Y * projCoef + centery) }; } void proj::recenter(float centerX, float centerY) { centerx = centerX; centery = centerY; }