#pragma once
#include "../config.h"
#include "../scene/scene_elements.h"

class RayInfo {
	public:
		DT_FP hit_distance;
		bool hit;
		bool error;
		Object* hit_object;
		Material* hit_material;

		RayInfo(void) {
			reset();
		}
		void reset(void) {
			hit_distance = MAX_FP;
			hit_object = NULL;
			hit_material = NULL;
			hit = false;
			error = false;
		}
		void set_hit(Object* obj, DT_FP dist) {
			hit_object = obj;
			hit_material = hit_object->material;
			hit_distance = dist;
			hit = true;
		}
};
class Ray {
	public:
		DT_FP origin[3];
	private:
		DT_FP direction[3];
		DT_FP direction_reciprocal[3];
		DT_FP direction_negative[3];
		bool needs_update_reciprocal;
		bool needs_update_negative;
	public:
		Ray(DT_FP origin[3], DT_FP direction[3]) {
			glLib::Math::Vec::copy3(origin,this->origin);
			set_direction(direction);
			needs_update_reciprocal = true;
			needs_update_negative = true;
		}
		inline DT_FP* get_direction(void) { return direction; }
		inline DT_FP* get_direction_reciprocal(void) {
			if (needs_update_reciprocal) {
				glLib::Math::Vec::reciprocal3(direction,direction_reciprocal);
				needs_update_reciprocal = false;
			}
			return direction_reciprocal;
		}
		inline DT_FP* get_direction_negative(void) {
			if (needs_update_negative) {
				glLib::Math::Vec::negate3(direction,direction_negative);
				needs_update_negative = false;
			}
			return direction_negative;
		}
		inline void set_direction(DT_FP direction[3]) {
			glLib::Math::Vec::copy3(direction,this->direction);
			needs_update_reciprocal = true;
			needs_update_negative = true;
		}
};