Skip to content

Commit

Permalink
Added cache for normal model matrix, optimized assimp model loading
Browse files Browse the repository at this point in the history
  • Loading branch information
denyskryvytskyi committed Apr 2, 2024
1 parent 313e765 commit 971bd85
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 59 deletions.
4 changes: 2 additions & 2 deletions Engine/res/shaders/mesh_phong.vert
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ layout(location = 2) in vec2 a_UV;

uniform mat4 u_ViewProjection;
uniform mat4 u_Model;
uniform mat4 u_InversedNormalModel;
uniform mat4 u_NormalModel;

out vec3 v_FragPos;
out vec3 v_Normal;
Expand All @@ -18,6 +18,6 @@ void main()
vec4 worldPos = u_Model * vec4(a_Position, 1.0);
gl_Position = u_ViewProjection * worldPos;
v_FragPos = vec3(worldPos);
v_Normal = mat3(transpose(u_InversedNormalModel)) * a_Normal;
v_Normal = mat3(u_NormalModel) * a_Normal;
v_UV = a_UV;
}
38 changes: 19 additions & 19 deletions Engine/src/Events/EventManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ void EventManager::Shutdown()
m_subscribers.clear();
}

void EventManager::Subscribe(EventId eventId, UniquePtr<IEventHandlerWrapper>&& handler, HandlerId handlerId)
void EventManager::Subscribe(EventType eventType, UniquePtr<IEventHandlerWrapper>&& handler, EventId eventId)
{
if (handlerId) {
auto subscribers = m_subscribersByHandlerId.find(eventId);
if (eventId) {
auto subscribers = m_subscribersByEventId.find(eventType);

if (subscribers != m_subscribersByHandlerId.end()) {
if (subscribers != m_subscribersByEventId.end()) {
auto& handlersMap = subscribers->second;
auto handlers = handlersMap.find(handlerId);
auto handlers = handlersMap.find(eventId);
if (handlers != handlersMap.end()) {
handlers->second.emplace_back(std::move(handler));
return;
}
}
m_subscribersByHandlerId[eventId][handlerId].emplace_back(std::move(handler));
m_subscribersByEventId[eventType][eventId].emplace_back(std::move(handler));

} else {
auto subscribers = m_subscribers.find(eventId);
auto subscribers = m_subscribers.find(eventType);
if (subscribers != m_subscribers.end()) {
auto& handlers = subscribers->second;
for (auto& it : handlers) {
Expand All @@ -36,18 +36,18 @@ void EventManager::Subscribe(EventId eventId, UniquePtr<IEventHandlerWrapper>&&
}
handlers.emplace_back(std::move(handler));
} else {
m_subscribers[eventId].emplace_back(std::move(handler));
m_subscribers[eventType].emplace_back(std::move(handler));
}
}
}

void EventManager::Unsubscribe(EventId eventId, const std::string& handlerName, HandlerId handlerId)
void EventManager::Unsubscribe(EventType eventType, const std::string& handlerName, EventId eventId)
{
if (handlerId) {
auto subscribers = m_subscribersByHandlerId.find(eventId);
if (subscribers != m_subscribersByHandlerId.end()) {
if (eventId) {
auto subscribers = m_subscribersByEventId.find(eventType);
if (subscribers != m_subscribersByEventId.end()) {
auto& handlersMap = subscribers->second;
auto handlers = handlersMap.find(handlerId);
auto handlers = handlersMap.find(eventId);
if (handlers != handlersMap.end()) {
auto& callbacks = handlers->second;
for (auto it = callbacks.begin(); it != callbacks.end(); ++it) {
Expand All @@ -59,7 +59,7 @@ void EventManager::Unsubscribe(EventId eventId, const std::string& handlerName,
}
}
} else {
auto handlersIt = m_subscribers.find(eventId);
auto handlersIt = m_subscribers.find(eventType);
if (handlersIt != m_subscribers.end()) {
auto& handlers = handlersIt->second;
for (auto it = handlers.begin(); it != handlers.end(); ++it) {
Expand All @@ -72,14 +72,14 @@ void EventManager::Unsubscribe(EventId eventId, const std::string& handlerName,
}
}

void EventManager::TriggerEvent(const Event& event_, HandlerId handlerId)
void EventManager::TriggerEvent(const Event& event_, EventId eventId)
{
for (auto& handler : m_subscribers[event_.GetEventType()]) {
handler->Exec(event_);
}

auto& handlersMap = m_subscribersByHandlerId[event_.GetEventType()];
auto handlers = handlersMap.find(handlerId);
auto& handlersMap = m_subscribersByEventId[event_.GetEventType()];
auto handlers = handlersMap.find(eventId);
if (handlers != handlersMap.end()) {
auto& callbacks = handlers->second;
for (auto it = callbacks.begin(); it != callbacks.end();) {
Expand All @@ -94,9 +94,9 @@ void EventManager::TriggerEvent(const Event& event_, HandlerId handlerId)
}
}

void EventManager::QueueEvent(UniquePtr<Event>&& event_, HandlerId handlerId)
void EventManager::QueueEvent(UniquePtr<Event>&& event_, EventId eventId)
{
m_eventsQueue.emplace_back(std::move(event_), handlerId);
m_eventsQueue.emplace_back(std::move(event_), eventId);
}

void EventManager::DispatchEvents()
Expand Down
34 changes: 17 additions & 17 deletions Engine/src/Events/EventManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace elv::events {

using EventId = std::uint32_t;
using HandlerId = std::uint64_t;
using EventType = std::uint32_t;
using EventId = std::uint64_t;

class EventManager {
public:
Expand All @@ -15,42 +15,42 @@ class EventManager {

void Shutdown();

void Subscribe(EventId eventId, UniquePtr<IEventHandlerWrapper>&& handler, HandlerId handlerId);
void Unsubscribe(EventId eventId, const std::string& handlerName, HandlerId handlerId);
void TriggerEvent(const Event& event_, HandlerId handlerId);
void QueueEvent(UniquePtr<Event>&& event_, HandlerId handlerId);
void Subscribe(EventType eventType, UniquePtr<IEventHandlerWrapper>&& handler, EventId eventId);
void Unsubscribe(EventType eventType, const std::string& handlerName, EventId eventId);
void TriggerEvent(const Event& event_, EventId eventId);
void QueueEvent(UniquePtr<Event>&& event_, EventId eventId);
void DispatchEvents();

private:
std::vector<std::pair<UniquePtr<Event>, HandlerId>> m_eventsQueue;
std::unordered_map<EventId, std::vector<UniquePtr<IEventHandlerWrapper>>> m_subscribers;
std::unordered_map<EventId, std::unordered_map<HandlerId, std::vector<UniquePtr<IEventHandlerWrapper>>>> m_subscribersByHandlerId;
std::vector<std::pair<UniquePtr<Event>, EventId>> m_eventsQueue;
std::unordered_map<EventType, std::vector<UniquePtr<IEventHandlerWrapper>>> m_subscribers;
std::unordered_map<EventType, std::unordered_map<EventId, std::vector<UniquePtr<IEventHandlerWrapper>>>> m_subscribersByEventId;
};

extern EventManager gEventManager;

template<typename EventType>
inline void Subscribe(const EventHandler<EventType>& callback, HandlerId handlerId = 0, const bool unsubscribeOnSuccess = false)
inline void Subscribe(const EventHandler<EventType>& callback, EventId eventId = 0, const bool unsubscribeOnSuccess = false)
{
UniquePtr<IEventHandlerWrapper> handler = MakeUniquePtr<EventHandlerWrapper<EventType>>(callback, unsubscribeOnSuccess);
gEventManager.Subscribe(EventType::GetStaticEventType(), std::move(handler), handlerId);
gEventManager.Subscribe(EventType::GetStaticEventType(), std::move(handler), eventId);
}

template<typename EventType>
inline void Unsubscribe(const EventHandler<EventType>& callback, HandlerId handlerId = 0)
inline void Unsubscribe(const EventHandler<EventType>& callback, EventId eventId = 0)
{
const std::string handlerName = callback.target_type().name();
gEventManager.Unsubscribe(EventType::GetStaticEventType(), handlerName, handlerId);
gEventManager.Unsubscribe(EventType::GetStaticEventType(), handlerName, eventId);
}

inline void TriggerEvent(const Event& triggeredEvent, HandlerId handlerId = 0)
inline void TriggerEvent(const Event& triggeredEvent, EventId eventId = 0)
{
gEventManager.TriggerEvent(triggeredEvent, handlerId);
gEventManager.TriggerEvent(triggeredEvent, eventId);
}

inline void QueueEvent(UniquePtr<Event>&& queuedEvent, HandlerId handlerId = 0)
inline void QueueEvent(UniquePtr<Event>&& queuedEvent, EventId eventId = 0)
{
gEventManager.QueueEvent(std::forward<UniquePtr<Event>>(queuedEvent), handlerId);
gEventManager.QueueEvent(std::forward<UniquePtr<Event>>(queuedEvent), eventId);
}

} // namespace elv::events
2 changes: 1 addition & 1 deletion Engine/src/Resources/ModelImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void ImportModel(const std::string& path, LoadedMeshesInfo& info)
PROFILE(fmt::format("Model {} is loaded: ", path));

Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate);
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_ImproveCacheLocality | aiProcess_OptimizeMeshes | aiProcess_OptimizeGraph);

if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
EL_CORE_ERROR("ASSIMP: Failed to load model {}", path);
Expand Down
4 changes: 2 additions & 2 deletions Engine/src/Scene/Components/TransformComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class TransformComponent {
TransformComponent(const lia::vec3& pos, const lia::vec3& scale = { 1.0f }, const lia::vec3& rotation = { 0.0f });

void UpdateLocalMatrix();
const lia::mat4& GetLocalMatrix() const { return localMatrix; }

public:
bool isDirty { true };
Expand All @@ -20,7 +19,8 @@ class TransformComponent {
lia::vec3 scale { 1.0f };

lia::mat4 localMatrix;
lia::mat4 worldMatrix;
lia::mat4 modelMatrix; // world space
lia::mat4 normalMatrix; // matrix to handle transformation for the normal vector
};
void to_json(nlohmann::json& j, const TransformComponent& t);
void from_json(const nlohmann::json& j, TransformComponent& t);
Expand Down
6 changes: 4 additions & 2 deletions Engine/src/Scene/SceneGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,21 @@ void SceneGraph::OnUpdate(Scene* scene)

if (transform.isDirty || node.isParentDirty) {
transform.UpdateLocalMatrix();
transform.worldMatrix = transform.GetLocalMatrix();
transform.modelMatrix = transform.localMatrix;

ecs::Entity parentId = node.parent;
while (parentId != ecs::INVALID_ENTITY_ID) {
if (!scene->HasComponent<TransformComponent>(parentId)) {
break;
}
const auto& parentTransform = m_transformsPool->GetComponent(parentId);
transform.worldMatrix = transform.worldMatrix * parentTransform.GetLocalMatrix();
transform.modelMatrix = transform.modelMatrix * parentTransform.localMatrix;

const auto& parentNode = m_sceneNodesPool->GetComponent(parentId);
parentId = parentNode.parent;
}

transform.normalMatrix = lia::transpose(lia::inverse(transform.modelMatrix));
}
}
}
Expand Down
35 changes: 19 additions & 16 deletions Engine/src/Scene/Systems/RenderSystem.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "RenderSystem.h"

#include "Core/Application.h"
#include "Core/Profiler.h"
#include "Renderer/CameraController.h"
#include "Renderer/Mesh.h"
#include "Renderer/Renderer.h"
Expand Down Expand Up @@ -111,20 +112,22 @@ void RenderSystem::OnRender(float dt)
// TODO: Need to implement sorting logic for proper rendering of transparent objects

// render static mesh
auto meshPool = m_pScene->GetComponentPool<StaticMeshComponent>();
auto& meshComponents = meshPool->GetComponents();
for (std::uint32_t i = 0; i < meshPool->Size(); ++i) {
auto entity = meshPool->GetEntity(i);

if (m_pScene->HasComponent<TransformComponent>(entity)) {
auto& meshComponent = meshComponents[i];
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);

// TODO: maybe cache inverse world matrix too
m_shader->SetMatrix4("u_InversedNormalModel", lia::inverse(transform.worldMatrix));
const auto& meshPtr = meshComponent.GetMeshPtr();
if (meshPtr) {
Renderer::Submit(m_shader, meshPtr, transform.worldMatrix);
{
// PROFILE_SCOPE("Static Meshes rendered in: ");
auto meshPool = m_pScene->GetComponentPool<StaticMeshComponent>();
auto& meshComponents = meshPool->GetComponents();
for (std::uint32_t i = 0; i < meshPool->Size(); ++i) {
auto entity = meshPool->GetEntity(i);

if (m_pScene->HasComponent<TransformComponent>(entity)) {
auto& meshComponent = meshComponents[i];
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);

m_shader->SetMatrix4("u_NormalModel", transform.normalMatrix);
const auto& meshPtr = meshComponent.GetMeshPtr();
if (meshPtr) {
Renderer::Submit(m_shader, meshPtr, transform.modelMatrix);
}
}
}
}
Expand All @@ -151,7 +154,7 @@ void RenderSystem::OnRender(float dt)
m_lightShader->SetVector3f("u_Color.ambient", pointLight.ambient);
m_lightShader->SetVector3f("u_Color.diffuse", pointLight.diffuse);

Renderer::Submit(m_lightShader, m_debugLightMesh, transform.worldMatrix);
Renderer::Submit(m_lightShader, m_debugLightMesh, transform.modelMatrix);
}
}
}
Expand All @@ -169,7 +172,7 @@ void RenderSystem::OnRender(float dt)
m_lightShader->SetVector3f("u_Color.ambient", spotlight.ambient);
m_lightShader->SetVector3f("u_Color.diffuse", spotlight.diffuse);

Renderer::Submit(m_lightShader, m_debugLightMesh, transform.worldMatrix);
Renderer::Submit(m_lightShader, m_debugLightMesh, transform.modelMatrix);
}
}
}
Expand Down

0 comments on commit 971bd85

Please sign in to comment.