Skip to content

Commit

Permalink
Merge pull request #15 from fszewczyk/entity-selection
Browse files Browse the repository at this point in the history
Entity Selection
  • Loading branch information
fszewczyk authored Oct 29, 2024
2 parents 3e4ac1a + 340c47a commit 65f798c
Show file tree
Hide file tree
Showing 27 changed files with 460 additions and 108 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/Rendering)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/Runtime)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/UI)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/InputManager)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/Math)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/Systems)

add_executable(ShkyeraEngine src/main.cpp)
Expand Down
1 change: 1 addition & 0 deletions src/AssetManager/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ target_link_libraries(
AssetManager
PUBLIC

Math
stb_image
glfw
glm
Expand Down
54 changes: 38 additions & 16 deletions src/AssetManager/Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <fstream>
#include <sstream>
#include <unordered_map>
#include <numeric>
#include <functional>

#include <AssetManager/Mesh.hpp>
Expand All @@ -22,8 +23,8 @@ Mesh::Mesh(const std::string& filepath) {
loadFromFile(filepath);
}

Mesh::Mesh(const std::vector<Vertex>& vertices, std::vector<uint32_t> indices) {
uploadToGPU(vertices, indices);
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<uint32_t> indices) : _vertices(std::move(vertices)), _indices(std::move(indices)) {
uploadToGPU();
}

// Destructor to clean up OpenGL resources
Expand All @@ -33,8 +34,26 @@ Mesh::~Mesh() {
glDeleteBuffers(1, &_ebo);
}

Box Mesh::getBoundingBox() const {
if (_vertices.empty()) {
return shkyera::Box();
}

glm::vec3 minBounds(FLT_MAX);
glm::vec3 maxBounds(-FLT_MAX);

for (const auto& vertex : _vertices) {
minBounds = glm::min(minBounds, vertex.position);
maxBounds = glm::max(maxBounds, vertex.position);
}

glm::vec3 center = (minBounds + maxBounds) * 0.5f;
glm::vec3 extents = (maxBounds - minBounds) * 0.5f;

static std::vector<glm::vec3> calculateNormals(const std::vector<Mesh::Vertex>& vertices, const std::vector<unsigned int>& indices) {
return shkyera::Box(center, extents, glm::mat3(1.0f));
}

static std::vector<glm::vec3> calculateNormals(const std::vector<Mesh::Vertex>& vertices, const std::vector<uint32_t>& indices) {
std::unordered_map<glm::vec3, glm::vec3> vertexToNormalMap;
std::unordered_map<glm::vec3, std::vector<glm::vec3>> faceNormals;

Expand Down Expand Up @@ -66,7 +85,6 @@ static std::vector<glm::vec3> calculateNormals(const std::vector<Mesh::Vertex>&
}
averagedNormal = glm::normalize(averagedNormal);

// Map the averaged normal back to the vertices
vertexToNormalMap[position] = averagedNormal;
}

Expand All @@ -90,8 +108,12 @@ void Mesh::loadFromFile(const std::string& filepath) {
return;
}

std::vector<Vertex> vertices;
std::vector<unsigned int> indices;
_vertices.clear();
_indices.clear();

size_t numberOfVertices = std::accumulate(shapes.begin(), shapes.end(), 0, [](size_t accumulatedSize, const auto& shape) { return accumulatedSize + shape.mesh.indices.size(); });
_vertices.reserve(numberOfVertices);
_indices.reserve(numberOfVertices);

bool hasNormals = false;

Expand Down Expand Up @@ -121,24 +143,24 @@ void Mesh::loadFromFile(const std::string& filepath) {
);
}

vertices.emplace_back(position, normal, texcoord);
indices.push_back(indices.size());
_vertices.emplace_back(position, normal, texcoord);
_indices.emplace_back(_indices.size());
}
}

if (!hasNormals) {
auto calculatedNormals = calculateNormals(vertices, indices);
auto calculatedNormals = calculateNormals(_vertices, _indices);

for (size_t i = 0; i < vertices.size(); ++i) {
vertices[i].normal = calculatedNormals[i];
for (size_t i = 0; i < _vertices.size(); ++i) {
_vertices[i].normal = calculatedNormals[i];
}
}

uploadToGPU(vertices, indices);
uploadToGPU();
}

void Mesh::uploadToGPU(const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices) {
_meshSize = static_cast<GLsizei>(indices.size());
void Mesh::uploadToGPU() {
_meshSize = static_cast<GLsizei>(_indices.size());

// Create VAO
glGenVertexArrays(1, &_vao);
Expand All @@ -147,12 +169,12 @@ void Mesh::uploadToGPU(const std::vector<Vertex>& vertices, const std::vector<un
// Create VBO (vertex buffer object)
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(Vertex), _vertices.data(), GL_STATIC_DRAW);

// Create EBO (element buffer object)
glGenBuffers(1, &_ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(unsigned int), _indices.data(), GL_STATIC_DRAW);

// Define vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position)); // Position
Expand Down
12 changes: 9 additions & 3 deletions src/AssetManager/Mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

#include <glm/glm.hpp>
#include <glad/glad.h>
#include <AssetManager/Asset.hpp>
#include <vector>
#include <string>

#include <AssetManager/Asset.hpp>
#include <Math/Box.hpp>

namespace shkyera {

class Mesh : public Asset {
Expand All @@ -20,12 +22,14 @@ class Mesh : public Asset {
};

Mesh(const std::string& filepath);
Mesh(const std::vector<Vertex>& vertices, std::vector<uint32_t> indices);
Mesh(std::vector<Vertex> vertices, std::vector<uint32_t> indices);
~Mesh();

void bind() const { glBindVertexArray(_vao); }
void unbind() const { glBindVertexArray(0); }

Box getBoundingBox() const;

GLuint getVAO() const { return _vao; }
GLuint getVBO() const { return _vbo; }
GLuint getEBO() const { return _ebo; }
Expand All @@ -40,8 +44,10 @@ class Mesh : public Asset {

private:
void loadFromFile(const std::string& filepath);
void uploadToGPU(const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices);
void uploadToGPU();

std::vector<Vertex> _vertices;
std::vector<uint32_t> _indices;
GLuint _vao, _vbo, _ebo;
GLsizei _meshSize;
};
Expand Down
7 changes: 6 additions & 1 deletion src/Components/BaseComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@

namespace shkyera {

enum ComponentMode {
DEVELOPMENT,
PRODUCTION
};

/**
* @brief Base component for implementing update functionality.
*
* Serves as a base for components utilizing CRTP to invoke derived class update implementations.
*
* @tparam Derived Type of the derived class inheriting from BaseComponent.
*/
template <typename Derived>
template <typename Derived, ComponentMode Mode = PRODUCTION>
class BaseComponent {
public:
/**
Expand Down
44 changes: 44 additions & 0 deletions src/Components/BoxColliderComponent.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once

#include <string>

#include <Math/Box.hpp>
#include <Components/BaseComponent.hpp>
#include <Components/TransformComponent.hpp>

namespace shkyera {

template<ComponentMode Mode = PRODUCTION>
class BoxColliderComponent : public BaseComponent<BoxColliderComponent<Mode>, Mode> {
public:
BoxColliderComponent() = default;
BoxColliderComponent(const Box& box) : box(box) {}

bool intersect(const TransformComponent& transform, const Ray& ray, float& near, float& far) const {
glm::vec3 position = transform.getPosition();
glm::vec3 scale = transform.getScale();
glm::vec3 orientation = transform.getOrientation();

glm::mat4 transformMatrix = glm::translate(glm::mat4(1.0f), position);

transformMatrix = glm::rotate(transformMatrix, orientation.y, glm::vec3(0.0f, 1.0f, 0.0f));
transformMatrix = glm::rotate(transformMatrix, orientation.x, glm::vec3(1.0f, 0.0f, 0.0f));
transformMatrix = glm::rotate(transformMatrix, orientation.z, glm::vec3(0.0f, 0.0f, 1.0f));

transformMatrix = glm::scale(transformMatrix, scale);

glm::mat4 invTransformMatrix = glm::inverse(transformMatrix);
glm::vec3 localRayOrigin = glm::vec3(invTransformMatrix * glm::vec4(ray.origin, 1.0f));
glm::vec3 localRayDirection = glm::normalize(glm::vec3(invTransformMatrix * glm::vec4(ray.direction, 0.0f)));

Ray localRay { localRayOrigin, localRayDirection };

return box.intersect(localRay, near, far);
}



Box box;
};

} // namespace shkyera
2 changes: 2 additions & 0 deletions src/Components/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_library(
${CMAKE_CURRENT_LIST_DIR}/ModelComponent.hpp
${CMAKE_CURRENT_LIST_DIR}/WireframeComponent.hpp
${CMAKE_CURRENT_LIST_DIR}/PointLightComponent.hpp
${CMAKE_CURRENT_LIST_DIR}/BoxColliderComponent.hpp
)

target_include_directories(
Expand All @@ -25,6 +26,7 @@ target_link_libraries(
INTERFACE

Rendering
Math
glad
glm
)
Expand Down
28 changes: 27 additions & 1 deletion src/Components/CameraComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <Math/Ray.hpp>
#include <Components/TransformComponent.hpp>

namespace shkyera {
Expand All @@ -25,7 +27,6 @@ class CameraComponent {
glm::vec3 position = transformComponent.getPosition();
glm::vec3 orientation = transformComponent.getOrientation();

// Calculate direction vectors
glm::vec3 front;
front.x = cos(orientation.y) * cos(orientation.x);
front.y = sin(orientation.x);
Expand All @@ -49,6 +50,31 @@ class CameraComponent {
return glm::ortho(-halfWidth, halfWidth, -halfHeight, halfHeight, nearPlane, farPlane);
}
}

Ray getRayAt(const TransformComponent& transformComponent, float x, float y) const {
glm::mat4 viewMatrix = getViewMatrix(transformComponent);

glm::mat4 invViewProj = glm::inverse(getProjectionMatrix() * viewMatrix);

float ndcX = 2.0f * x - 1.0f;
float ndcY = 1.0f - 2.0f * y;

glm::vec4 nearPoint = glm::vec4(ndcX, ndcY, -1.0f, 1.0f);
glm::vec4 farPoint = glm::vec4(ndcX, ndcY, 1.0f, 1.0f);

glm::vec4 nearWorld = invViewProj * nearPoint;
glm::vec4 farWorld = invViewProj * farPoint;

nearWorld /= nearWorld.w;
farWorld /= farWorld.w;

glm::vec3 rayOrigin = glm::vec3(nearWorld);

glm::vec3 rayDirection = glm::normalize(glm::vec3(farWorld) - rayOrigin);

return { rayOrigin, rayDirection };
}

};

} // namespace shkyera
1 change: 1 addition & 0 deletions src/InputManager/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ target_link_libraries(
PUBLIC

glfw
glm::glm
)
31 changes: 23 additions & 8 deletions src/InputManager/InputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@ InputManager& InputManager::getInstance() {
return manager;
}

void InputManager::setCoordinateSystem(CoordinateSystem system, glm::vec2 topLeftCorner, glm::vec2 bottomRightCorner) {
_coordinateSystems[system] = {topLeftCorner, bottomRightCorner};
}

glm::vec2 InputManager::getRelativeMousePosition(CoordinateSystem system) {
if(_coordinateSystems.count(system) != 0)
{
const auto& [topLeft, bottomRight] = _coordinateSystems.at(system);
return (_latestMousePosition - topLeft) / (bottomRight - topLeft);
}
return {0, 0};
}

glm::vec2 InputManager::getMousePosition(CoordinateSystem system) {
if(_coordinateSystems.count(system) != 0)
{
const auto& [topLeft, _bottomRight] = _coordinateSystems.at(system);
return _latestMousePosition - topLeft;
}
return {0, 0};
}

void InputManager::registerKeyCallback(Key key, std::function<void()> callback) {
_keyCallbacks[key].push_back(callback);
}
Expand Down Expand Up @@ -50,6 +72,7 @@ void InputManager::processInput(GLFWwindow* window) {

double xPos, yPos;
glfwGetCursorPos(window, &xPos, &yPos);
_latestMousePosition = {xPos, yPos};
for (const auto& callback : _mouseMoveCallbacks) {
callback(xPos, yPos);
}
Expand All @@ -73,20 +96,12 @@ void InputManager::processMouseButton(GLFWwindow* window, MouseButton button) {


void InputManager::onMouseButtonDown(MouseButton button) {
if(_mouseButtonDownCallbacks.count(button) == 0) {
return;
}

for(const auto& callback : _mouseButtonDownCallbacks[button]) {
callback();
}
}

void InputManager::onMouseButtonUp(MouseButton button) {
if(_mouseButtonUpCallbacks.count(button) == 0) {
return;
}

for(const auto& callback : _mouseButtonUpCallbacks[button]) {
callback();
}
Expand Down
Loading

0 comments on commit 65f798c

Please sign in to comment.