implement ray casting events
This commit is contained in:
40
openVulkanoCpp/Controller/CameraController.cpp
Normal file
40
openVulkanoCpp/Controller/CameraController.cpp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#include "CameraController.hpp"
|
||||||
|
#include "Scene/Camera.hpp"
|
||||||
|
#include "Input/InputDeviceMouse.hpp"
|
||||||
|
#include "Input/InputDeviceController.hpp"
|
||||||
|
#include "Input/InputManager.hpp"
|
||||||
|
#include "Input/Touch/InputDeviceTouch.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
CameraController::CameraController(Scene::Camera* camera)
|
||||||
|
{
|
||||||
|
m_inputManager = Input::InputManager::GetInstance();
|
||||||
|
m_camera = camera;
|
||||||
|
m_actionCastRay = m_inputManager->GetAction("cast ray");
|
||||||
|
m_actionCastRay->BindKey(Input::InputKey::Mouse::BUTTON_1);
|
||||||
|
// BIND FOR TOUCH
|
||||||
|
m_actionCastRay->BindKey(Input::InputKey::Touch::AXIS_TAP_X);
|
||||||
|
m_actionCastRay->BindKey(Input::InputKey::Touch::AXIS_TAP_X);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraController::Tick()
|
||||||
|
{
|
||||||
|
Input::InputDeviceMouse* mouse = static_cast<Input::InputDeviceMouse*>(m_inputManager->GetDevice(Input::InputDeviceType::MOUSE));
|
||||||
|
Input::InputDeviceTouch* touch = static_cast<Input::InputDeviceTouch*>(m_inputManager->GetDevice(Input::InputDeviceType::TOUCH));
|
||||||
|
if (m_camera->CanCastRay() && m_inputManager->GetButton(m_actionCastRay))
|
||||||
|
{
|
||||||
|
if (mouse && mouse->GetButtonDown(Input::InputKey::Mouse::BUTTON_1))
|
||||||
|
{
|
||||||
|
Math::Vector2i pos = mouse->GetMousePosition();
|
||||||
|
mouse->onLeftButtonClick.NotifyAll(pos);
|
||||||
|
}
|
||||||
|
else if (touch)
|
||||||
|
{
|
||||||
|
Math::Vector2i pos = touch->GetTapPosition();
|
||||||
|
touch->OnTap.NotifyAll(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,12 @@
|
|||||||
|
|
||||||
namespace OpenVulkano
|
namespace OpenVulkano
|
||||||
{
|
{
|
||||||
|
namespace Input
|
||||||
|
{
|
||||||
|
class InputAction;
|
||||||
|
class InputManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Scene
|
namespace Scene
|
||||||
{
|
{
|
||||||
class Camera;
|
class Camera;
|
||||||
@@ -18,22 +24,26 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
class CameraController : public ITickable, ICloseable
|
class CameraController : public ITickable, ICloseable
|
||||||
{
|
{
|
||||||
Scene::Camera* m_camera;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CameraController(Scene::Camera* camera = nullptr)
|
Scene::Camera* m_camera;
|
||||||
: m_camera(camera)
|
Input::InputAction* m_actionCastRay;
|
||||||
{}
|
Input::InputManager* m_inputManager;
|
||||||
|
|
||||||
|
CameraController(Scene::Camera* camera = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~CameraController() override = default;
|
~CameraController() override = default;
|
||||||
|
|
||||||
|
void Tick() override;
|
||||||
|
|
||||||
virtual void Init(Scene::Camera* camera) { m_camera = camera; }
|
virtual void Init(Scene::Camera* camera) { m_camera = camera; }
|
||||||
|
|
||||||
void Close() override { m_camera = nullptr; }
|
void Close() override { m_camera = nullptr; }
|
||||||
|
|
||||||
void SetCamera(Scene::Camera* camera) { m_camera = camera; }
|
void SetCamera(Scene::Camera* camera) { m_camera = camera; }
|
||||||
|
|
||||||
|
Input::InputAction* GetActionCastRay() { return m_actionCastRay; }
|
||||||
|
|
||||||
Scene::Camera* GetCamera() { return m_camera; }
|
Scene::Camera* GetCamera() { return m_camera; }
|
||||||
|
|
||||||
virtual void SetActive() {}
|
virtual void SetActive() {}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "Base/FrameMetadata.hpp"
|
#include "Base/FrameMetadata.hpp"
|
||||||
#include "Scene/Camera.hpp"
|
#include "Scene/Camera.hpp"
|
||||||
#include "Input/InputManager.hpp"
|
#include "Input/InputManager.hpp"
|
||||||
|
#include "Input/InputDeviceMouse.hpp"
|
||||||
#include "Input/InputKey.hpp"
|
#include "Input/InputKey.hpp"
|
||||||
|
|
||||||
namespace OpenVulkano
|
namespace OpenVulkano
|
||||||
@@ -39,6 +40,8 @@ namespace OpenVulkano
|
|||||||
vec *= m_boostFactor;
|
vec *= m_boostFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CameraController::Tick();
|
||||||
|
|
||||||
m_yaw -= input->GetAxis(m_actionLookSide) * timeScale / 2.0f;
|
m_yaw -= input->GetAxis(m_actionLookSide) * timeScale / 2.0f;
|
||||||
m_pitch -= input->GetAxis(m_actionLookUp) * timeScale / 2.0f;
|
m_pitch -= input->GetAxis(m_actionLookUp) * timeScale / 2.0f;
|
||||||
m_pitch = std::min(1.4f, std::max(-1.4f, m_pitch));
|
m_pitch = std::min(1.4f, std::max(-1.4f, m_pitch));
|
||||||
@@ -48,6 +51,7 @@ namespace OpenVulkano
|
|||||||
Math::Matrix4f camTransformation = Math::Utils::toMat4(rot);
|
Math::Matrix4f camTransformation = Math::Utils::toMat4(rot);
|
||||||
camTransformation[3] = Math::Vector4f(m_position, 1);
|
camTransformation[3] = Math::Vector4f(m_position, 1);
|
||||||
GetCamera()->SetMatrix(camTransformation);
|
GetCamera()->SetMatrix(camTransformation);
|
||||||
|
//CameraController::Tick();
|
||||||
CURRENT_FRAME.needsRedraw = true;
|
CURRENT_FRAME.needsRedraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "InputDevice.hpp"
|
#include "InputDevice.hpp"
|
||||||
#include "Math/Math.hpp"
|
#include "Math/Math.hpp"
|
||||||
|
#include "Base/Event.hpp"
|
||||||
|
|
||||||
namespace OpenVulkano
|
namespace OpenVulkano
|
||||||
{
|
{
|
||||||
@@ -143,6 +144,9 @@ namespace OpenVulkano
|
|||||||
{
|
{
|
||||||
return window == lastWindow;
|
return window == lastWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Event<Math::Vector2i> onLeftButtonClick;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,6 +85,18 @@ namespace OpenVulkano::Input
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputDevice* InputManager::GetDevice(InputDeviceType type) const
|
||||||
|
{
|
||||||
|
for (InputDevice* device: devices)
|
||||||
|
{
|
||||||
|
if (device->GetType() == type && type != InputDeviceType::UNKNOWN)
|
||||||
|
{
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void InputManager::Tick()
|
void InputManager::Tick()
|
||||||
{
|
{
|
||||||
for(InputDevice* device : devices)
|
for(InputDevice* device : devices)
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ namespace OpenVulkano::Input
|
|||||||
|
|
||||||
[[nodiscard]] bool GetButton(InputKey key) const;
|
[[nodiscard]] bool GetButton(InputKey key) const;
|
||||||
|
|
||||||
|
[[nodiscard]] InputDevice* GetDevice(InputDeviceType type) const;
|
||||||
|
|
||||||
[[nodiscard]] InputDevice* GetLastActiveDevice() const
|
[[nodiscard]] InputDevice* GetLastActiveDevice() const
|
||||||
{
|
{
|
||||||
return lastActiveDevice;
|
return lastActiveDevice;
|
||||||
|
|||||||
@@ -84,5 +84,6 @@ namespace OpenVulkano::Input
|
|||||||
[[nodiscard]] bool IsMultiTouch() const { return m_multiTouch; }
|
[[nodiscard]] bool IsMultiTouch() const { return m_multiTouch; }
|
||||||
|
|
||||||
Event<Touch&> OnTouchAdded, OnTouchDown, OnTouchUp, OnTouchMoved, OnTouchRemoved;
|
Event<Touch&> OnTouchAdded, OnTouchDown, OnTouchUp, OnTouchMoved, OnTouchRemoved;
|
||||||
|
Event<Math::Vector2i> OnTap;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
68
openVulkanoCpp/Scene/Camera.cpp
Normal file
68
openVulkanoCpp/Scene/Camera.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,10 @@
|
|||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
#include "Math/Math.hpp"
|
#include "Math/Math.hpp"
|
||||||
#include "Math/Frustum.hpp"
|
#include "Math/Frustum.hpp"
|
||||||
|
#include "Input/InputDeviceMouse.hpp"
|
||||||
|
#include "Input/Touch/InputDeviceTouch.hpp"
|
||||||
|
#include "Input/InputManager.hpp"
|
||||||
|
#include "Base/Logger.hpp"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
namespace OpenVulkano::Scene
|
namespace OpenVulkano::Scene
|
||||||
@@ -27,6 +31,7 @@ namespace OpenVulkano::Scene
|
|||||||
float m_contentScaleFactor = 1, m_zoom = 1; // For use with ortho camera
|
float m_contentScaleFactor = 1, m_zoom = 1; // For use with ortho camera
|
||||||
float m_interfaceOrientation = 0;
|
float m_interfaceOrientation = 0;
|
||||||
float m_padding = 0; //Unused
|
float m_padding = 0; //Unused
|
||||||
|
bool m_canCastRay = true;
|
||||||
|
|
||||||
Camera() : m_nearPlane(0), m_farPlane(0), m_width(0), m_height(0) {}
|
Camera() : m_nearPlane(0), m_farPlane(0), m_width(0), m_height(0) {}
|
||||||
|
|
||||||
@@ -45,6 +50,20 @@ namespace OpenVulkano::Scene
|
|||||||
m_farPlane = farPlane;
|
m_farPlane = farPlane;
|
||||||
Node::Init();
|
Node::Init();
|
||||||
UpdateProjectionMatrix();
|
UpdateProjectionMatrix();
|
||||||
|
if (m_canCastRay)
|
||||||
|
{
|
||||||
|
Input::InputDeviceMouse* mouse = static_cast<Input::InputDeviceMouse*>(Input::InputManager::GetInstance()->GetDevice(Input::InputDeviceType::MOUSE));
|
||||||
|
Input::InputDeviceTouch* touch = static_cast<Input::InputDeviceTouch*>(Input::InputManager::GetInstance()->GetDevice(Input::InputDeviceType::TOUCH));
|
||||||
|
if (mouse)
|
||||||
|
{
|
||||||
|
mouse->onLeftButtonClick += EventHandler(this, &Camera::CastRay);
|
||||||
|
}
|
||||||
|
else if (touch)
|
||||||
|
{
|
||||||
|
touch->OnTap += EventHandler(this, &Camera::CastRay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -66,6 +85,8 @@ namespace OpenVulkano::Scene
|
|||||||
|
|
||||||
[[nodiscard]] float FarPlane() const { return m_farPlane; }
|
[[nodiscard]] float FarPlane() const { return m_farPlane; }
|
||||||
|
|
||||||
|
[[nodiscard]] bool CanCastRay() const { return m_canCastRay; }
|
||||||
|
|
||||||
void SetContentScaleFactor(float contentScale = 1)
|
void SetContentScaleFactor(float contentScale = 1)
|
||||||
{
|
{
|
||||||
m_contentScaleFactor = 1.0f / contentScale;
|
m_contentScaleFactor = 1.0f / contentScale;
|
||||||
@@ -83,6 +104,8 @@ namespace OpenVulkano::Scene
|
|||||||
|
|
||||||
virtual void UpdateProjectionMatrix() = 0;
|
virtual void UpdateProjectionMatrix() = 0;
|
||||||
|
|
||||||
|
virtual std::optional<DrawableRayHit> CastRay(const Math::Vector2i& xy) const = 0;
|
||||||
|
|
||||||
void UpdateViewProjectionMatrix()
|
void UpdateViewProjectionMatrix()
|
||||||
{
|
{
|
||||||
m_viewProjection = m_projection * m_view;
|
m_viewProjection = m_projection * m_view;
|
||||||
@@ -241,6 +264,8 @@ namespace OpenVulkano::Scene
|
|||||||
SetProjectionMatrix(Math::Utils::perspectiveRH_ZO(m_fov, m_aspect, m_nearPlane, m_farPlane));
|
SetProjectionMatrix(Math::Utils::perspectiveRH_ZO(m_fov, m_aspect, m_nearPlane, m_farPlane));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<DrawableRayHit> CastRay(const Math::Vector2i& xy) const override;
|
||||||
|
|
||||||
[[nodiscard]] bool IsPerspective() const override { return true; }
|
[[nodiscard]] bool IsPerspective() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -254,6 +279,11 @@ namespace OpenVulkano::Scene
|
|||||||
SetProjectionMatrix(Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane));
|
SetProjectionMatrix(Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<DrawableRayHit> CastRay(const Math::Vector2i& xy) const override
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool IsOrtho() const override { return true; }
|
[[nodiscard]] bool IsOrtho() const override { return true; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user