/* * 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 "Input/InputManager.hpp" #include "SceneIntersectionTestController.hpp" #include "Scene.hpp" #include "SimpleDrawable.hpp" #include "Prefabs/LabelDrawable.hpp" namespace OpenVulkano::Scene { void SceneIntersectionTestController::Tick() { Input::InputManager* input = Input::InputManager::GetInstance(); if (input->GetButtonDown(m_actionClick)) { const float x = input->GetAxis(m_actionClickX); const float y = input->GetAxis(m_actionClickY); const Ray ray = m_camera->CastRay(Math::Vector2i(x, y)); const auto& camPos = m_camera->GetPosition(); const auto scene = m_camera->GetScene(); std::optional res; for (Drawable* d : scene->rayHittableDrawables) { for (Node* n : d->GetNodes()) { const auto& m = n->GetWorldMatrix(); const Math::Vector3f rayLocalDir = normalize(inverse(m) * Math::Vector4f(ray.GetDir(), 0)); const Math::Vector4f rayLocalPos = inverse(m) * camPos; const Ray ray(rayLocalPos, rayLocalDir); if (auto hit = d->Intersect(ray)) { // choose the closest one if (!res || (hit->distance2 < res->distance2)) { res = hit; res->drawable = d; res->node = n; } } } } if (res) { OnHit.NotifyAll(*res); } } } void SceneIntersectionTestController::SetDefaultKeybindings() { auto input = Input::InputManager::GetInstance(); m_actionClick = input->GetAction("ClickIntersection"); m_actionClick->BindKey(Input::InputKey::Mouse::BUTTON_1); m_actionClick->BindKey(Input::InputKey::Touch::BUTTON_TAP); m_actionClickX = input->GetAction("ClickIntersectionPosX"); m_actionClickX->BindKey(Input::InputKey::Touch::Axis::AXIS_TAP_X); m_actionClickX->BindKey(Input::InputKey::Mouse::Axis::AXIS_X_ABS); m_actionClickY = input->GetAction("ClickIntersectionPosY"); m_actionClickY->BindKey(Input::InputKey::Touch::Axis::AXIS_TAP_Y); m_actionClickY->BindKey(Input::InputKey::Mouse::Axis::AXIS_Y_ABS); } }