//
// Created by sebastian on 02.08.26.
//

#include "PickingSystem.h"

std::pair<glm::vec3, glm::vec3> engine::PickingSystem::screenToRay(const glm::vec2 &ndc, const Camera &camera) {
    glm::mat4 invVP = glm::inverse(camera.getProjectionMatrix() * camera.getViewMatrix());
    glm::vec4 nearPoint = invVP * glm::vec4(ndc.x, ndc.y, -1.0f, 1.0f); // Y invertiert (Screen vs. NDC)
    glm::vec4 farPoint  = invVP * glm::vec4(ndc.x, ndc.y,  1.0f, 1.0f);
    nearPoint /= nearPoint.w;
    farPoint  /= farPoint.w;
    auto origin = glm::vec3(nearPoint);
    glm::vec3 dir = glm::normalize(glm::vec3(farPoint) - glm::vec3(nearPoint));
    return {origin, dir};
}

bool engine::PickingSystem::raySphereIntersect(const glm::vec3 &origin, const glm::vec3 &dir, const glm::vec3 &center,
    float radius, float &t) {
    glm::vec3 oc = origin - center;
    float b = glm::dot(oc, dir);
    float c = glm::dot(oc, oc) - radius * radius;
    float discriminant = b * b - c;
    if (discriminant < 0.0f) return false;
    t = -b - std::sqrt(discriminant);
    return t >= 0.0f;
}
