#include "HydraTransformSystem.h" #include "../../engine/HydraEngine.h" #include "../HydraECS.h" #include "../components/HydraPositionComponent.h" #include "../../scheduler/HydraTaskScheduler.h" #include "../../task/buffer/HydraCreateGPUBufferTask.hpp" #include "../../task/buffer/HydraUpdateWholeGPUBufferTask.hpp" #include "../../actor/HydraActorManager.h" void HydraTransformSystem::UpdateTransform(HydraID actor_id) { HydraECS *ecs = GetEngine()->ECS(); HydraPositionComponent &pos_comp = ecs->GetComponent(actor_id); pos_comp.needs_update = true; m_entities_to_update.push(actor_id); } void HydraTransformSystem::Initialise() { HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler(); HydraID create_gpu_buffer_task_id = task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraCreateGPUBufferTask *task = static_cast(task_scheduler->GetTask(create_gpu_buffer_task_id)); task->Intialise("PositionsBuffer", 1, MAX_ACTORS * sizeof(glm::mat4), &m_transform_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER); task_scheduler->WaitForTask(create_gpu_buffer_task_id); m_model_matrix.resize(MAX_ACTORS); } void HydraTransformSystem::UpdateSystem(float delta_t_seconds) { HydraECS *ecs = GetEngine()->ECS(); while(m_entities_to_update.size() > 0) { HydraID actor_id = m_entities_to_update.front(); m_entities_to_update.pop(); HydraPositionComponent &pos_comp = ecs->GetComponent(actor_id); if(pos_comp.needs_update) { HydraID parent_id = GetEngine()->ActorManager()->GetRoot(actor_id); glm::mat4 identity = glm::mat4(1); _UpdateChild(INVALID_HYDRA_ID, parent_id, identity); } } _WriteToGPU(); } void HydraTransformSystem::InitialiseComponent(HydraID actor_id) { HydraECS *ecs = GetEngine()->ECS(); HydraPositionComponent &pos_comp = ecs->GetComponent(actor_id); if (pos_comp.needs_update) { glm::mat4 identity = glm::mat4(1); _UpdateChild(INVALID_HYDRA_ID, actor_id, identity); } } void HydraTransformSystem::_UpdateChild(HydraID parent_id, HydraID actor_id, glm::mat4 parent_transform) { HydraECS *ecs = GetEngine()->ECS(); std::vector &child_ids = GetEngine()->ActorManager()->GetChildren(actor_id); glm::mat4 trans = parent_transform; if (ecs->HasComponent(actor_id)) { HydraPositionComponent &pos_comp = ecs->GetComponent(actor_id); glm::mat4 trans_matrix = glm::translate(glm::vec3(pos_comp.position.x, pos_comp.position.y, pos_comp.position.z)); glm::mat4 rot_matrix = glm::toMat4(glm::quat(pos_comp.orientation)); glm::mat4 scale_matrix = glm::scale(pos_comp.scale); glm::mat4 model_matrix = trans_matrix * rot_matrix * scale_matrix; pos_comp.transform = trans * model_matrix; pos_comp.needs_update = false; m_model_matrix[actor_id] = pos_comp.transform; trans = pos_comp.transform; } for (uint32_t child_idx = 0; child_idx < child_ids.size(); child_idx++) { _UpdateChild(actor_id, child_ids[child_idx], trans); } } void HydraTransformSystem::_WriteToGPU() { HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler(); HydraID update_buffer_task_id = task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraUpdateWholeGPUBufferTask *task = static_cast(task_scheduler->GetTask(update_buffer_task_id)); task->Intialise(m_transform_buffer_id, &m_model_matrix[0]); task_scheduler->WaitForTask(update_buffer_task_id); }