#include "visual_engine.h"

rbx::matrix4_t rbx::visual_engine::get_view_matrix() {
	auto vm = read<matrix4_t>(this->self + offsets::viewmatrix);
	return vm;
}

rbx::vector2_t rbx::visual_engine::get_dimensions() {
	auto dimensions = vector2_t{ (float)(GetSystemMetrics(0)), (float)(GetSystemMetrics(1)) };
	return dimensions;
}

rbx::vector2_t rbx::visual_engine::world_to_screen(const vector3_t& world) {
	vector2_t screen { -1, -1 };
	auto dimensions = get_dimensions();
	auto vm = get_view_matrix();
	vector4_t vec4;

	vec4.x = (world.x * vm.data[0]) + (world.y * vm.data[1]) + (world.z * vm.data[2]) + vm.data[3];
	vec4.y = (world.x * vm.data[4]) + (world.y * vm.data[5]) + (world.z * vm.data[6]) + vm.data[7];
	vec4.z = (world.x * vm.data[8]) + (world.y * vm.data[9]) + (world.z * vm.data[10]) + vm.data[11];
	vec4.w = (world.x * vm.data[12]) + (world.y * vm.data[13]) + (world.z * vm.data[14]) + vm.data[15];

	if (vec4.w < 0.1f)
		return screen;

	vector3_t ndc;
	ndc.x = vec4.x / vec4.w;
	ndc.y = vec4.y / vec4.w;
	ndc.z = vec4.z / vec4.w;

	screen.x = (dimensions.x / 2.f * ndc.x) + (dimensions.x / 2.f);
	screen.y = -(dimensions.y / 2.f * ndc.y) + (dimensions.y / 2.f);

	return screen;
}