// #include "HydraActorManager.h" #include "../actor/HydraActor.h" #include "../engine/HydraEngine.h" #include "../ecs/HydraEntityManager.h" #include "../ecs/HydraECS.h" #include "../ecs/components/HydraPositionComponent.h" #include "../ecs/systems/HydraTransformSystem.h" #include "../fileaccess/HydraGLTFLoader.h" #include "../task/actor/HydraLoadGLTFFileTask.hpp" #include "../scheduler/HydraTaskScheduler.h" #include HydraActor *const HydraActorManager::GetActor(HydraID actorID) { if (actorID < MAX_ACTORS) { return m_actors[actorID]; } return nullptr; } std::vector &HydraActorManager::GetChildren(HydraID actor_id) { return m_actors[actor_id]->m_children; } void HydraActorManager::DeleteActor(HydraID actorID) { m_actors_waiting_for_delete.push_back(actorID); } void HydraActorManager::_SetActorDeleted(HydraID actorID) { if (m_actors[actorID] != nullptr) { delete m_actors[actorID]; } m_actors[actorID] = nullptr; m_available_actor_ids.push_back(actorID); } HydraID HydraActorManager::LoadActor(std::string filename) { HydraID actor_id = INVALID_HYDRA_ID; HydraTaskScheduler* task_scheduler = GetEngine()->TaskScheduler(); HydraID load_task_id = task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraLoadGLTFFileTask* load_task = static_cast(task_scheduler->GetTask(load_task_id)); load_task->Initialise(filename, &actor_id); task_scheduler->WaitForTask(load_task_id); return actor_id; } /* HydraID HydraActorManager::_ProcessGLTFNode(aiScene const *scene, aiNode *parent_node, std::vectormaterial_lookup) { HydraID parent_actor_id = CreateActor(); HydraECS *ecs = GetEngine()->ECS(); HydraECSPositionComponent position_component; aiVector3D tmp_scaling = {}; aiQuaternion tmp_rotation = {}; aiVector3D tmp_position = {}; parent_node->mTransformation.Decompose(tmp_scaling, tmp_rotation, tmp_position); glm::dvec3 scaling = glm::dvec3(tmp_scaling.x, tmp_scaling.y, tmp_scaling.z); glm::quat rotation = glm::quat(tmp_rotation.w, tmp_rotation.x, tmp_rotation.y, tmp_rotation.z); glm::dvec3 position = glm::dvec3(tmp_position.x, tmp_position.y, tmp_position.z); ecs->AddComponent(parent_actor_id, position_component); SetPosition(parent_actor_id, position, rotation, false); for (uint32_t i_mesh = 0; i_mesh < parent_node->mNumMeshes; i_mesh++) { aiMesh *mesh = scene->mMeshes[parent_node->mMeshes[i_mesh]]; _ProcessGLTFMesh(scene, parent_actor_id, mesh, material_lookup); } for (uint32_t i_node = 0; i_node < parent_node->mNumChildren; i_node++) { HydraID child_actor_id = _ProcessGLTFNode(scene, parent_node->mChildren[i_node], material_lookup); SetRelationship(parent_actor_id, child_actor_id); } return parent_actor_id; } void HydraActorManager::_ProcessGLTFMesh(aiScene const *scene, HydraID parent_actor_id, aiMesh *mesh, std::vectormaterial_lookup) { HydraID mesh_actor_id = CreateActor(); aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex]; std::vector vertexes; HydraECS *ecs = GetEngine()->ECS(); HydraECSPositionComponent position_component = {}; ecs->AddComponent(mesh_actor_id, position_component); for (uint32_t i_face = 0; i_face < mesh->mNumFaces; i_face++) { aiFace face = mesh->mFaces[i_face]; for (uint32_t i_index = 0; i_index < face.mNumIndices; i_index++) { uint32_t current_idx = face.mIndices[i_index]; StandardVertexStruct vert = {}; if (mesh->HasPositions()) { vert.vertex[0] = mesh->mVertices[current_idx].x; vert.vertex[1] = mesh->mVertices[current_idx].y; vert.vertex[2] = mesh->mVertices[current_idx].z; } if (mesh->HasNormals()) { vert.normal[0] = mesh->mNormals[current_idx].x; vert.normal[1] = mesh->mNormals[current_idx].y; vert.normal[2] = mesh->mNormals[current_idx].z; } if (mesh->HasTextureCoords(0)) { vert.uv[0] = mesh->mTextureCoords[0][current_idx].x; vert.uv[1] = mesh->mTextureCoords[0][current_idx].y; } vert.indexes[0] = mesh_actor_id; vertexes.push_back(vert); } } HydraMeshManager *mesh_manager = GetEngine()->MeshManager(); HydraID mesh_id = mesh_manager->CreateMesh(mesh_actor_id); mesh_manager->SetVertexes(mesh_id, vertexes); mesh_manager->CalculateNormals(mesh_id); HydraECSMeshComponent mesh_comp; mesh_comp.mesh_id = mesh_id; ecs->AddComponent(mesh_actor_id, mesh_comp); aiString mat_name; mat->Get(AI_MATKEY_NAME, mat_name); HydraID material_id = material_lookup[mesh->mMaterialIndex]; if(material_id != INVALID_HYDRA_ID) { HydraECSMaterialComponent mat_comp; mat_comp.material_id = material_id; ecs->AddComponent(mesh_actor_id, mat_comp); HydraMaterialStruct const * const mat_data = GetEngine()->MaterialManager()->GetMaterial(material_id); GetEngine()->BufferManager()->AddMaterial(mesh_actor_id, material_id, *mat_data); } mesh_manager->SetMeshWaiting(mesh_id); //Add renderable component HydraPipelineManager* pipeline_manager = GetEngine()->PipelineManager(); uint32_t pipeline_id = pipeline_manager->GetPipelineID("FORWARD"); uint32_t shadow_pipeline_id = pipeline_manager->GetPipelineID("SHADOW"); uint32_t deferred_pipeline_id = pipeline_manager->GetPipelineID("DEFERRED"); HydraECSRenderableComponent render_comp; if(pipeline_id != INVALID_HYDRA_ID) { render_comp.pipelines.set(pipeline_id); } render_comp.pipelines.set(shadow_pipeline_id); render_comp.pipelines.set(deferred_pipeline_id); ecs->AddComponent(mesh_actor_id, render_comp); SetRelationship(parent_actor_id, mesh_actor_id); } /// @brief Load all of the scene textures /// @param scene containing scene /// @param texture_lookup index of texture in the scene to the Hydra texture ID void HydraActorManager::_ProcessGLTFTextures(aiScene const *scene, std::vector &texture_lookup) { HydraTextureManager *texture_manager = GetEngine()->TextureManager(); // Make space for the texture lookups texture_lookup.resize(scene->mNumTextures); for (uint32_t i_tex = 0; i_tex < scene->mNumTextures; i_tex++) { aiTexture *tex = scene->mTextures[i_tex]; // Create a holder for the texture HydraID texture_id = texture_manager->CreateTexture(0, 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, false); // load the texture data from the scene texture texture_manager->FillTexture(texture_id, reinterpret_cast(tex->pcData), tex->mWidth); // store the texture id against the scene index for the texture. Materials will have *n where n is the index texture_lookup[i_tex] = texture_id; texture_manager->FinaliseTexture(texture_id); } } void HydraActorManager::_ProcessGLTFMaterials(aiScene const *scene, std::vector& texture_lookup, std::vector& material_lookup, std::string filename) { material_lookup.resize(scene->mNumMaterials); HydraTextureManager *texture_manager = GetEngine()->TextureManager(); for (uint32_t i_mat = 0; i_mat < scene->mNumMaterials; i_mat++) { HydraMaterialStruct material; aiMaterial *mat = scene->mMaterials[i_mat]; aiColor3D color(0.f, 0.f, 0.f); aiString name; mat->Get(AI_MATKEY_COLOR_DIFFUSE, color); mat->Get(AI_MATKEY_NAME, name); std::string mat_name = filename + std::to_string(i_mat); aiTexture diffuse_tex; uint32_t diffuse_tex_count = mat->GetTextureCount(aiTextureType::aiTextureType_DIFFUSE); // have to do something here for multiple diffuse textures at some point. aiString texture_path; aiTextureMapping texture_mapping; uint32_t uv_index; if (diffuse_tex_count > 0) { mat->GetTexture(aiTextureType::aiTextureType_DIFFUSE, 0, &texture_path, &texture_mapping, &uv_index); std::string path = std::string(texture_path.C_Str()); uint32_t texture_index = atoi(path.substr(1).c_str()); HydraID texture_id = texture_lookup[texture_index]; material.diffuse_texture = texture_id; material.texture_types += static_cast(HYDRA_TEXTURE_TYPE::DIFFUSE_TEXTURE); } material.diffuse_colour = glm::vec4(color.r, color.g, color.b, 1); HydraID material_id = GetEngine()->MaterialManager()->CreateMaterial(mat_name, material); material_lookup[i_mat] = material_id; if (material_id == INVALID_HYDRA_ID) { throw std::runtime_error("Could not create material"); } } } */ HydraID HydraActorManager::_SaveActor(HydraActor *actor) { HydraECS *ecs = GetEngine()->ECS(); if (m_available_actor_ids.size() > 0) { HydraID id = m_available_actor_ids.front(); m_available_actor_ids.pop_front(); actor->m_id = id; m_actors[id] = actor; return id; } delete actor; return INVALID_HYDRA_ID; } void HydraActorManager::Initialise(size_t max_actors) { m_max_actors = max_actors; std::lock_guard lock(m_mutex); m_actors.resize(max_actors); for (int i = 0; i < max_actors; i++) { m_available_actor_ids.push_back(i); } } void HydraActorManager::TickActors(float delta_t) { // std::lock_guard lock(m_mutex); // // HydraID barrierID = GetEngine()->TaskScheduler()->CreateBarrier(); // for (int i = 0; i < m_actors_to_tick_fixed.size(); i++) // { // HydraID tick_actors_task_id = GetEngine()->TaskScheduler()->CreateTask(HydraThreadAffinity::General); // if (tick_actors_task_id != INVALID_HYDRA_ID) // { // ((HydraFixedTickActorTask *)(GetEngine()->TaskScheduler()->GetTask(tick_actors_task_id)))->Initialise(m_actors_to_tick_fixed[i], delta_t); // GetEngine()->TaskScheduler()->StartTask(tick_actors_task_id); // } // } // GetEngine()->TaskScheduler()->WaitForBarrier(barrierID); } void HydraActorManager::InitialiseActor(HydraID actorID) { HydraActor *actor = GetActor(actorID); if (actor != nullptr) { // actor->InitialiseComponents(); m_actors_waiting_for_init.push_back(actorID); } } void HydraActorManager::Shutdown() { std::lock_guard lock(m_mutex); // for (HydraID actor_id = 0; actor_id < MAX_ACTORS; actor_id++) // { // if (m_actors[actor_id] != nullptr) // { // HydraActor *actor = m_actors[actor_id]; // m_actors[actor_id]->m_status = HydraActorStatus::WAITING_FOR_DELETE; // _RemoveActorFromTickFixed(actor_id); // _RemoveActorFromWaiting(actor_id); // actor->Destroy(); // // for (int i = 0; i < m_actors[actor_id]->m_component_types.size(); i++) // // { // // GetEngine()->ComponentManager()->DeleteComponent(m_actors[actor_id]->m_component_types[i], actor_id); // // } // // HydraID delete_task_id = GetEngine()->TaskScheduler()->CreateTask(HydraThreadAffinity::General); // // HydraDeleteActorTask *task = (HydraDeleteActorTask *)GetEngine()->TaskScheduler()->GetTask(delete_task_id); // // task->Initialise(actor_id); // // GetEngine()->TaskScheduler()->WaitForTask(delete_task_id); // } // _SetActorDeleted(actor_id); // } } void HydraActorManager::RotateActor(HydraID actorID, float euler_x, float euler_y, float euler_z) { HydraECS *ecs = GetEngine()->ECS(); HydraPositionComponent &pos_comp = ecs->GetComponent(actorID); pos_comp.orientation[0] += euler_x; pos_comp.orientation[1] += euler_y; pos_comp.orientation[2] += euler_z; pos_comp.needs_update = true; ecs->GetSystem()->UpdateTransform(actorID); } void HydraActorManager::SetPosition(HydraID actorID, glm::dvec3 position) { HydraECS *ecs = GetEngine()->ECS(); HydraPositionComponent &pos_comp = ecs->GetComponent(actorID); pos_comp.position = position; // if (ecs->HasComponent(actorID)) // { // HydraECSPhysicsComponent &phys_comp = ecs->GetComponent(actorID); // // const float* matrix = glm::value_ptr(GetActorPose(actorID)); // phys_comp.physics_definition.pose = GetActorPose(actorID); // } if(!pos_comp.needs_update) { ecs->GetSystem()->UpdateTransform(actorID); } } void HydraActorManager::SetOrientation(HydraID actorID, float x, float y, float z) { HydraECS *ecs = GetEngine()->ECS(); HydraPositionComponent &pos_comp = ecs->GetComponent(actorID); pos_comp.orientation = glm::vec3(x, y, z); if(!pos_comp.needs_update) { // if (ecs->HasComponent(actorID)) // { // HydraECSPhysicsComponent &phys_comp = ecs->GetComponent(actorID); // phys_comp.physics_definition.pose = GetActorPose(actorID); // } ecs->GetSystem()->UpdateTransform(actorID); } } void HydraActorManager::SetScale(HydraID actor_id, glm::dvec3 scaling) { HydraECS *ecs = GetEngine()->ECS(); HydraPositionComponent &pos_comp = ecs->GetComponent(actor_id); pos_comp.scale = glm::vec3(scaling); // if (ecs->HasComponent(actorID)) // { // HydraECSPhysicsComponent &phys_comp = ecs->GetComponent(actorID); // phys_comp.physics_definition.pose = GetActorPose(actorID); // } if(!pos_comp.needs_update) { ecs->GetSystem()->UpdateTransform(actor_id); } } void HydraActorManager::SetRelationship(HydraID parent_id, HydraID child_id) { HydraActor *parent_actor = GetActor(parent_id); HydraActor *child_actor = GetActor(child_id); child_actor->m_parent_id = parent_id; parent_actor->m_children.push_back(child_id); } void HydraActorManager::TranslateActor(HydraID actorID, glm::dvec3 translation) { HydraECS *ecs = GetEngine()->ECS(); HydraPositionComponent &pos_comp = ecs->GetComponent(actorID); pos_comp.position = pos_comp.position + translation; // if (ecs->HasComponent(actorID)) // { // HydraECSPhysicsComponent &phys_comp = ecs->GetComponent(actorID); // // const float* matrix = glm::value_ptr(GetActorPose(actorID)); // // std::copy(matrix, matrix + 16, phys_comp.physics_definition.pose); // phys_comp.physics_definition.pose = GetActorPose(actorID); // } ecs->GetSystem()->UpdateTransform(actorID); } void HydraActorManager::AddComponentType(HydraID actorID, uint32_t component_type) { if (actorID < m_actors.size()) { HydraActor *actor = m_actors[actorID]; if (actor != nullptr) { actor->m_component_types.push_back(component_type); actor->m_components_waiting++; } } } glm::mat4 HydraActorManager::GetActorPose(HydraID actorID) { HydraPositionComponent &pos = GetEngine()->ECS()->GetComponent(actorID); glm::mat4 model_matrix = pos.transform; // if (pos.needs_update) // { // glm::mat4 trans_matrix = glm::translate(pos.position); // glm::mat4 rot_matrix = glm::toMat4(glm::quat(pos.orientation)); // model_matrix = trans_matrix * rot_matrix; // } return model_matrix; } glm::vec3 HydraActorManager::GetActorOrientation(HydraID actorID) { HydraECS *ecs = GetEngine()->ECS(); HydraPositionComponent &pos_comp = ecs->GetComponent(actorID); return pos_comp.orientation; } glm::vec3 HydraActorManager::GetActorVelocity(HydraID actorID) { return glm::dvec3(0, 0, 0); } glm::dvec3 HydraActorManager::GetActorPosition(HydraID actorID) { HydraECS *ecs = GetEngine()->ECS(); HydraPositionComponent &pos_comp = ecs->GetComponent(actorID); return pos_comp.position; } bool HydraActorManager::HasComponentType(HydraID actorID, uint32_t component_type) { if (actorID < m_actors.size()) { HydraActor *actor = m_actors[actorID]; if (actor != nullptr) { for (int i = 0; i < actor->m_component_types.size(); i++) { if (actor->m_component_types[i] == component_type) { return true; } } } } return false; } void HydraActorManager::RemoveComponentType(HydraID actorID, uint32_t component_type) { if (actorID < m_actors.size()) { HydraActor *actor = m_actors[actorID]; if (actor != nullptr) { uint32_t comp_type = static_cast(component_type); if (actor->m_component_types.size() > comp_type) { actor->m_component_types.erase(actor->m_component_types.begin() + comp_type); } } } } HydraID HydraActorManager::GetParent(HydraID actor_id) { return m_actors[actor_id]->m_parent_id; } HydraID HydraActorManager::GetRoot(HydraID actor_id) { HydraID parent_id = GetParent(actor_id); if(parent_id == INVALID_HYDRA_ID) { return actor_id; } return GetRoot(parent_id); }