fix mouse picking
This commit is contained in:
@@ -114,6 +114,14 @@ struct Mat4 {
|
|||||||
return reinterpret_cast<T*>(this)[offset];
|
return reinterpret_cast<T*>(this)[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T* data() {
|
||||||
|
return reinterpret_cast<T*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* data() const{
|
||||||
|
return reinterpret_cast<const T*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
T at(std::size_t row, std::size_t column) const {
|
T at(std::size_t row, std::size_t column) const {
|
||||||
return operator[](row * MATRIX_SIZE + column);
|
return operator[](row * MATRIX_SIZE + column);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ namespace maths {
|
|||||||
// Vectors //
|
// Vectors //
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec2<T> operator+(const Vec2<T>& vect, const Vec2<T>& other) {
|
||||||
|
return {vect.x + other.x, vect.y + other.y};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Vec3<T> operator- (const Vec3<T>& vect) {
|
Vec3<T> operator- (const Vec3<T>& vect) {
|
||||||
return { -vect.x, -vect.y, -vect.z };
|
return { -vect.x, -vect.y, -vect.z };
|
||||||
@@ -32,6 +37,13 @@ Vec3<T> Normalize(const Vec3<T>& vect) {
|
|||||||
return { vect.x / length, vect.y / length, vect.z / length };
|
return { vect.x / length, vect.y / length, vect.z / length };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec4<T> Normalize(const Vec4<T>& vect) {
|
||||||
|
T length = std::sqrt(vect.x * vect.x + vect.y * vect.y + vect.z * vect.z + vect.w * vect.w);
|
||||||
|
|
||||||
|
return { vect.x / length, vect.y / length, vect.z / length, vect.w / length };
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T Dot(const Vec3<T>& vect, const Vec3<T>& other) {
|
T Dot(const Vec3<T>& vect, const Vec3<T>& other) {
|
||||||
return vect.x * other.x + vect.y * other.y + vect.z * other.z;
|
return vect.x * other.x + vect.y * other.y + vect.z * other.z;
|
||||||
@@ -59,9 +71,9 @@ template<typename T>
|
|||||||
Vec4<T> Dot(const Mat4<T>& mat, const Vec4<T>& vect) {
|
Vec4<T> Dot(const Mat4<T>& mat, const Vec4<T>& vect) {
|
||||||
return {
|
return {
|
||||||
Dot(*reinterpret_cast<const Vec4<T>*>(&mat), vect),
|
Dot(*reinterpret_cast<const Vec4<T>*>(&mat), vect),
|
||||||
Dot(*reinterpret_cast<const Vec4<T>*>(&mat[Mat4<T>::MATRIX_SIZE]), vect),
|
Dot(*reinterpret_cast<const Vec4<T>*>(mat.data() + Mat4<T>::MATRIX_SIZE), vect),
|
||||||
Dot(*reinterpret_cast<const Vec4<T>*>(&mat[2 * Mat4<T>::MATRIX_SIZE]), vect),
|
Dot(*reinterpret_cast<const Vec4<T>*>(mat.data() + 2 * Mat4<T>::MATRIX_SIZE), vect),
|
||||||
Dot(*reinterpret_cast<const Vec4<T>*>(&mat[3 * Mat4<T>::MATRIX_SIZE]), vect),
|
Dot(*reinterpret_cast<const Vec4<T>*>(mat.data() + 3 * Mat4<T>::MATRIX_SIZE), vect),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,15 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
|
struct Camera {
|
||||||
|
Mat4f viewMatrix;
|
||||||
|
Mat4f projectionMatrix;
|
||||||
|
Mat4f InvViewMatrix;
|
||||||
|
Mat4f InvProjectionMatrix;
|
||||||
|
|
||||||
|
Vec3f CamPos;
|
||||||
|
};
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
static constexpr float m_AnimationSpeed = 2.0f;
|
static constexpr float m_AnimationSpeed = 2.0f;
|
||||||
@@ -24,9 +33,7 @@ private:
|
|||||||
|
|
||||||
Vec3f m_BackgroundColor;
|
Vec3f m_BackgroundColor;
|
||||||
|
|
||||||
bool m_IsometricView = true;
|
Camera m_Camera {};
|
||||||
float m_IsometricShade = m_IsometricView;
|
|
||||||
Vec2f m_CamPos{};
|
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
~Renderer();
|
||||||
@@ -41,15 +48,12 @@ public:
|
|||||||
|
|
||||||
void SetZoom(float zoom);
|
void SetZoom(float zoom);
|
||||||
void SetCamMovement(const Vec2f& mov);
|
void SetCamMovement(const Vec2f& mov);
|
||||||
void SetCamPos(const Vec2f& newPos);
|
void SetCamPos(const Vec3f& newPos);
|
||||||
void SetIsometricView(bool isometric); // false = 2D true = Isometric
|
|
||||||
|
|
||||||
void SetBackgroundColor(const Vec3f& color) { m_BackgroundColor = color; }
|
void SetBackgroundColor(const Vec3f& color) { m_BackgroundColor = color; }
|
||||||
|
|
||||||
Vec2f GetCursorWorldPos(const Vec2f& cursorPos, float aspectRatio, float zoom, float windowWidth, float windowHeight);
|
Vec2f GetCursorWorldPos(const Vec2f& cursorPos, float windowWidth, float windowHeight);
|
||||||
private:
|
private:
|
||||||
void UpdateIsometricView();
|
|
||||||
void UpdateIsometricFade();
|
|
||||||
void InitShaders();
|
void InitShaders();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
#include "misc/Easing.h"
|
#include "misc/Easing.h"
|
||||||
#include "misc/Maths.h"
|
#include "misc/Maths.h"
|
||||||
|
|
||||||
|
#include <misc/Log.h>
|
||||||
|
#include <misc/Format.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
@@ -23,14 +26,6 @@ Renderer::~Renderer() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::UpdateIsometricView() {
|
|
||||||
//float isometricEased = utils::EaseInOutExpo(m_IsometricShade);
|
|
||||||
m_WorldShader->Start();
|
|
||||||
//m_WorldShader->SetIsometricView(isometricEased);
|
|
||||||
m_EntityShader->Start();
|
|
||||||
//m_EntityShader->SetIsometricView(isometricEased);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::InitShaders() {
|
void Renderer::InitShaders() {
|
||||||
m_WorldShader = std::make_unique<shader::WorldShader>();
|
m_WorldShader = std::make_unique<shader::WorldShader>();
|
||||||
m_WorldShader->LoadShader();
|
m_WorldShader->LoadShader();
|
||||||
@@ -75,34 +70,18 @@ void Renderer::RenderModel(const Model& model) {
|
|||||||
model.vao->Unbind();
|
model.vao->Unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::UpdateIsometricFade() {
|
|
||||||
static std::uint64_t lastTime = utils::GetTime();
|
|
||||||
if (m_IsometricShade != static_cast<float>(m_IsometricView)) {
|
|
||||||
float step = static_cast<float>(utils::GetTime() - lastTime) / 1000.0f * m_AnimationSpeed;
|
|
||||||
if (m_IsometricShade < m_IsometricView) {
|
|
||||||
m_IsometricShade += step;
|
|
||||||
} else {
|
|
||||||
m_IsometricShade -= step;
|
|
||||||
}
|
|
||||||
m_IsometricShade = std::min(m_IsometricShade, 1.0f);
|
|
||||||
m_IsometricShade = std::max(m_IsometricShade, 0.0f);
|
|
||||||
UpdateIsometricView();
|
|
||||||
}
|
|
||||||
lastTime = utils::GetTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::Prepare() {
|
void Renderer::Prepare() {
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glClearColor(m_BackgroundColor.r, m_BackgroundColor.g, m_BackgroundColor.b, 0);
|
glClearColor(m_BackgroundColor.r, m_BackgroundColor.g, m_BackgroundColor.b, 0);
|
||||||
UpdateIsometricFade();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Resize(int width, int height) {
|
void Renderer::Resize(int width, int height) {
|
||||||
Mat4f projectionMatrix = maths::Perspective(80.0f / 180.0f * M_PI, static_cast<float>(width) / height, 0.1f, 160.0f);
|
m_Camera.projectionMatrix = maths::Perspective(80.0f / 180.0f * M_PI, static_cast<float>(width) / height, 0.1f, 160.0f);
|
||||||
|
m_Camera.InvProjectionMatrix = maths::Inverse(m_Camera.projectionMatrix);
|
||||||
m_WorldShader->Start();
|
m_WorldShader->Start();
|
||||||
m_WorldShader->SetProjectionMatrix(projectionMatrix);
|
m_WorldShader->SetProjectionMatrix(m_Camera.projectionMatrix);
|
||||||
m_EntityShader->Start();
|
m_EntityShader->Start();
|
||||||
m_WorldShader->SetProjectionMatrix(projectionMatrix);
|
m_WorldShader->SetProjectionMatrix(m_Camera.projectionMatrix);
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,37 +93,39 @@ void Renderer::SetZoom(float zoom) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetCamMovement(const Vec2f& mov) {
|
void Renderer::SetCamMovement(const Vec2f& mov) {
|
||||||
m_CamPos.x += mov.x;
|
m_Camera.CamPos.x += mov.x;
|
||||||
m_CamPos.y += -mov.y;
|
m_Camera.CamPos.y += -mov.y;
|
||||||
SetCamPos(m_CamPos);
|
SetCamPos(m_Camera.CamPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetCamPos(const Vec2f& newPos) {
|
void Renderer::SetCamPos(const Vec3f& newPos) {
|
||||||
m_CamPos = newPos;
|
m_Camera.CamPos = newPos;
|
||||||
Mat4f viewMatrix = maths::Look({m_CamPos.x, 50, m_CamPos.y}, {0, -1, -0.0001}, {0, 1, 0});
|
m_Camera.viewMatrix = maths::Look(m_Camera.CamPos, {0, -1, -0.0001}, {0, 1, 0});
|
||||||
|
m_Camera.InvViewMatrix = maths::Inverse(m_Camera.viewMatrix);
|
||||||
m_WorldShader->Start();
|
m_WorldShader->Start();
|
||||||
m_WorldShader->SetViewMatrix(viewMatrix);
|
m_WorldShader->SetViewMatrix(m_Camera.viewMatrix);
|
||||||
m_EntityShader->Start();
|
m_EntityShader->Start();
|
||||||
m_EntityShader->SetViewMatrix(viewMatrix);
|
m_EntityShader->SetViewMatrix(m_Camera.viewMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetIsometricView(bool isometric) {
|
Vec2f Renderer::GetCursorWorldPos(const Vec2f& cursorPos, float windowWidth, float windowHeight) {
|
||||||
m_IsometricView = isometric;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2f Renderer::GetCursorWorldPos(const Vec2f& cursorPos, float aspectRatio, float zoom, float windowWidth, float windowHeight) {
|
float relativeX = 1 - (cursorPos.x / windowWidth * 2);
|
||||||
float isometricEased = utils::EaseInOutExpo(m_IsometricShade);
|
float relativeY = 1 - (cursorPos.y / windowHeight * 2);
|
||||||
|
|
||||||
float relativeX = (cursorPos.x / windowWidth * 2) - 1;
|
Vec4f rayClip {relativeX, relativeY, -1.0f, 1.0f};
|
||||||
float relativeY = (cursorPos.y / windowHeight * 2) - 1;
|
|
||||||
|
|
||||||
float deltaX = relativeX * aspectRatio / zoom;
|
Vec4f rayEye = maths::Dot(m_Camera.InvProjectionMatrix , rayClip);
|
||||||
float deltaY = relativeY / zoom;
|
rayEye = {rayEye.x, rayEye.y, -1.0f, 0.0f};
|
||||||
|
|
||||||
float worldX = m_CamPos.x + deltaX * (1 - isometricEased) + (0.5 * deltaX + deltaY) * isometricEased;
|
Vec4f rayWorld = maths::Dot(m_Camera.InvViewMatrix, rayEye);
|
||||||
float worldY = m_CamPos.y + deltaY * (1 - isometricEased) + (-0.5 * deltaX + deltaY) * isometricEased;
|
rayWorld.w = 0;
|
||||||
|
|
||||||
return { worldX, worldY };
|
maths::Normalize(rayWorld);
|
||||||
|
|
||||||
|
float lambda = - m_Camera.CamPos.y / rayWorld.y;
|
||||||
|
|
||||||
|
return {lambda * rayWorld.x + m_Camera.CamPos.x, lambda * rayWorld.z + m_Camera.CamPos.z};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ void WorldRenderer::Click() {
|
|||||||
|
|
||||||
void WorldRenderer::SetCamPos(float camX, float camY) {
|
void WorldRenderer::SetCamPos(float camX, float camY) {
|
||||||
m_CamPos = { camX, camY };
|
m_CamPos = { camX, camY };
|
||||||
m_Renderer->SetCamPos(m_CamPos);
|
m_Renderer->SetCamPos({ camX, 50, camY });
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::DetectClick() {
|
void WorldRenderer::DetectClick() {
|
||||||
@@ -232,11 +232,11 @@ void WorldRenderer::OnTowerRemove(game::TowerPtr tower) {
|
|||||||
|
|
||||||
Vec2f WorldRenderer::GetCursorWorldPos() const {
|
Vec2f WorldRenderer::GetCursorWorldPos() const {
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
return m_Renderer->GetCursorWorldPos({ io.MousePos.x, io.MousePos.y }, Display::GetAspectRatio(), m_Zoom, Display::GetWindowWidth(), Display::GetWindowHeight());
|
return m_Renderer->GetCursorWorldPos({ io.MousePos.x, io.MousePos.y }, Display::GetWindowWidth(), Display::GetWindowHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2f WorldRenderer::GetClickWorldPos() const {
|
Vec2f WorldRenderer::GetClickWorldPos() const {
|
||||||
return m_Renderer->GetCursorWorldPos(m_LastClicked, Display::GetAspectRatio(), m_Zoom, Display::GetWindowWidth(), Display::GetWindowHeight());
|
return m_Renderer->GetCursorWorldPos(m_LastClicked, Display::GetWindowWidth(), Display::GetWindowHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ void FrameMenu::Render() {
|
|||||||
if (ImGui::Checkbox("V-Sync", &m_VSync)) {
|
if (ImGui::Checkbox("V-Sync", &m_VSync)) {
|
||||||
SDL_GL_SetSwapInterval(m_VSync);
|
SDL_GL_SetSwapInterval(m_VSync);
|
||||||
}
|
}
|
||||||
if (ImGui::Checkbox("Vue Isometrique ?", &m_IsometricView)) {
|
|
||||||
GetClient()->GetRenderer()->SetIsometricView(m_IsometricView);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
ImGui::Checkbox("Demo Window", &m_ShowDemoWindow);
|
ImGui::Checkbox("Demo Window", &m_ShowDemoWindow);
|
||||||
|
|||||||
Reference in New Issue
Block a user