Files
OpenVulkano/openVulkanoCpp/Scene/Camera.cpp
2024-11-04 22:52:05 +02:00

69 lines
1.8 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "Camera.hpp"
#include "Scene/Scene.hpp"
#include "Scene/SimpleDrawable.hpp"
#include "Scene/Geometry.hpp"
#include "Scene/Shader/Shader.hpp"
#include "Scene/TextDrawable.hpp"
#include "Scene/Prefabs/LabelDrawable.hpp"
#include "Scene/Ray.hpp"
#include "Scene/TextDrawable.hpp"
namespace OpenVulkano::Scene
{
std::optional<DrawableRayHit> PerspectiveCamera::CastRay(const Math::Vector2i& xy) const
{
using namespace Math::Utils;
auto scene = GetScene();
// nds
float ndsX = (2.f * xy.x) / m_width - 1.0f;
float ndsY = (2.f * xy.y) / m_height - 1.0f;
Math::Vector4f rayClip = { ndsX, ndsY, 0, 1.f };
Math::Vector4f rayEye = inverse(m_projection) * rayClip;
rayEye.z = -1;
rayEye.a = 0;
Math::Vector3f rayWorld = normalize(inverse(m_view) * rayEye);
std::optional<DrawableRayHit> res;
for (Drawable* d: scene->rayHittableDrawables)
{
const auto& m = d->GetNodes()[0]->GetWorldMatrix();
const Math::Vector3f rayLocalDir = normalize(inverse(m) * Math::Vector4f(rayWorld, 0));
const Math::Vector4f rayLocalPos = inverse(m) * m_camPosition;
const Ray ray(rayLocalPos, rayLocalDir);
if (auto hit = d->Intersect(ray))
{
// choose the closest one
if (!res || (hit->distance < res->distance))
{
res = hit;
res->drawable = d;
}
}
}
if (res)
{
if (SimpleDrawable* sd = dynamic_cast<SimpleDrawable*>(res->drawable))
{
Logger::APP->info("Ray intersects object {}", sd->GetMesh()->name);
}
else if (LabelDrawable* sd = dynamic_cast<LabelDrawable*>(res->drawable))
{
Logger::APP->info("Ray intersects label {}", sd->GetTexts().front().GetText());
}
}
return res;
}
}