#include "raycast.hpp" static float get_intersect_point(Vector2 ray_origin, Vector2 ray_dir, Vector2 line1, Vector2 line2) { Vector2 line_dir = Vector2Subtract(line2, line1); float D = ray_dir.x * line_dir.y - ray_dir.y * line_dir.x; float u = ((line1.x - ray_origin.x) * ray_dir.y - (line1.y - ray_origin.y) * ray_dir.x) / D; float t = ((line1.x - ray_origin.x) * line_dir.y - (line1.y - ray_origin.y) * line_dir.x) / D; if (0 <= u && u <= 1 && t >= 0) { return t; } else { return -1; } } static void set_nearest_hit(RayHitResult *nearest_hit, float hit, Vector2 line1, Vector2 line2) { bool got_hit = hit >= 0; bool is_gotten_hit_better = (nearest_hit->hit < 0 || nearest_hit->hit > hit); if (got_hit && is_gotten_hit_better) { nearest_hit->hit = hit; nearest_hit->line1 = line1; nearest_hit->line2 = line2; } } static void get_intersect_with_polygon(RayHitResult *result, Vector2 ray_origin, Vector2 ray_dir, Vector2 *points, int point_count) { if (point_count < 2) return; for (int i = 0; i < point_count-1; i++) { Vector2 p1 = points[i]; Vector2 p2 = points[i+1]; float hit = get_intersect_point(ray_origin, ray_dir, p1, p2); set_nearest_hit(result, hit, p1, p2); } if (point_count > 2) { Vector2 p1 = points[0]; Vector2 p2 = points[point_count-1]; float hit = get_intersect_point(ray_origin, ray_dir, p1, p2); set_nearest_hit(result, hit, p1, p2); } } static void get_intersect_with_obstacles(RayHitResult *result, Vector2 ray_origin, Vector2 ray_dir, std::vector *obstacles) { for (int i = 0; i < (*obstacles).size(); i++) { Obstacle *obstacle = &(*obstacles)[i]; get_intersect_with_polygon(result, ray_origin, ray_dir, obstacle->points.data(), obstacle->points.size()); } } static void get_intersect_with_world(RayHitResult *result, Vector2 ray_origin, Vector2 ray_dir, World *world) { get_intersect_with_obstacles(result, ray_origin, ray_dir, &world->obstacles); if (result->hit == -1 && !world->looping_walls) { Vector2 lines[] = { { 0 , 0 }, { world->size.x, 0 }, { world->size.x, world->size.y }, { 0 , world->size.y } }; get_intersect_with_polygon(result, ray_origin, ray_dir, lines, 4); } }