diff --git a/Source/Core/Loader/ERS_ModelLoader/CMakeLists.txt b/Source/Core/Loader/ERS_ModelLoader/CMakeLists.txt index 32112af4df..18f44085dd 100644 --- a/Source/Core/Loader/ERS_ModelLoader/CMakeLists.txt +++ b/Source/Core/Loader/ERS_ModelLoader/CMakeLists.txt @@ -11,8 +11,10 @@ add_library(ERS_ModelLoader "ERS_CLASS_AssetStreamingManager.cpp" "ERS_CLASS_AsyncTextureUpdater.cpp" "ERS_CLASS_AssetStreamingSystemResourceMonitor.cpp" + "ERS_FUNCTION_Legacy_PreprocessTextureInfo.cpp" "ERS_FUNCTION_ModelMetadataDecoderV0.0.0.cpp" "ERS_FUNCTION_ModelMetadataDecoderV0.0.1.cpp" + "ERS_FUNCTION_ModelMetadataDecoderV0.0.2.cpp" "ERS_FUNCTION_ModelMetadataDecoderManager.cpp" # Add Header Files (.h) @@ -20,8 +22,10 @@ add_library(ERS_ModelLoader "ERS_CLASS_AssetStreamingManager.h" "ERS_CLASS_AsyncTextureUpdater.h" "ERS_CLASS_AssetStreamingSystemResourceMonitor.h" + "ERS_FUNCTION_Legacy_PreprocessTextureInfo.h" "ERS_FUNCTION_ModelMetadataDecoderV0.0.0.h" "ERS_FUNCTION_ModelMetadataDecoderV0.0.1.h" + "ERS_FUNCTION_ModelMetadataDecoderV0.0.2.h" "ERS_FUNCTION_ModelMetadataDecoderManager.h" diff --git a/Source/Core/Loader/ERS_ModelLoader/ERS_CLASS_ModelLoader.cpp b/Source/Core/Loader/ERS_ModelLoader/ERS_CLASS_ModelLoader.cpp index 12e08a22a5..4d555ef7ac 100644 --- a/Source/Core/Loader/ERS_ModelLoader/ERS_CLASS_ModelLoader.cpp +++ b/Source/Core/Loader/ERS_ModelLoader/ERS_CLASS_ModelLoader.cpp @@ -471,14 +471,12 @@ void ERS_CLASS_ModelLoader::ProcessNode(ERS_STRUCT_Model* Model, aiNode *Node, c // Process Meshes In Current Node for (unsigned int i = 0; i < Node->mNumMeshes; i++) { aiMesh* Mesh = Scene->mMeshes[Node->mMeshes[i]]; - Model->Meshes.push_back( - ProcessMesh( - Model, - (unsigned long)Mesh->mNumVertices, - (unsigned long)Mesh->mNumFaces*3, - Mesh, - Scene - ) + ProcessMesh( + Model, + (unsigned long)Mesh->mNumVertices, + (unsigned long)Mesh->mNumFaces*3, + Mesh, + Scene ); } @@ -495,6 +493,8 @@ ERS_STRUCT_Mesh ERS_CLASS_ModelLoader::ProcessMesh(ERS_STRUCT_Model* Model, unsi // Create Data Holders ERS_STRUCT_Mesh OutputMesh; + OutputMesh = Model->Meshes[Model->NumMeshes_]; + OutputMesh.Vertices.reserve(PreallocVertSize); @@ -563,12 +563,15 @@ ERS_STRUCT_Mesh ERS_CLASS_ModelLoader::ProcessMesh(ERS_STRUCT_Model* Model, unsi } } - // Process Materials - aiMaterial* Material = Scene->mMaterials[Mesh->mMaterialIndex]; - IdentifyMeshTextures(Material, &OutputMesh); + // // Process Materials + // aiMaterial* Material = Scene->mMaterials[Mesh->mMaterialIndex]; + // IdentifyMeshTextures(Material, &OutputMesh); // Return Populated Mesh + Model->Meshes[Model->NumMeshes_] = OutputMesh; + Model->NumMeshes_++; + return OutputMesh; } @@ -576,25 +579,25 @@ ERS_STRUCT_Mesh ERS_CLASS_ModelLoader::ProcessMesh(ERS_STRUCT_Model* Model, unsi void ERS_CLASS_ModelLoader::IdentifyMeshTextures(aiMaterial* Mat, ERS_STRUCT_Mesh* Mesh) { std::vector> TextureTypes; - TextureTypes.push_back(std::make_pair(aiTextureType_AMBIENT, "texture_ambient")); + TextureTypes.push_back(std::make_pair(aiTextureType_AMBIENT, "texture_ambient")); TextureTypes.push_back(std::make_pair(aiTextureType_AMBIENT_OCCLUSION, "texture_ambient_occlusion")); - TextureTypes.push_back(std::make_pair(aiTextureType_BASE_COLOR, "texture_base_color")); - TextureTypes.push_back(std::make_pair(aiTextureType_DIFFUSE, "texture_diffuse")); + TextureTypes.push_back(std::make_pair(aiTextureType_BASE_COLOR, "texture_base_color")); + TextureTypes.push_back(std::make_pair(aiTextureType_DIFFUSE, "texture_diffuse")); TextureTypes.push_back(std::make_pair(aiTextureType_DIFFUSE_ROUGHNESS, "texture_diffuse_roughness")); - TextureTypes.push_back(std::make_pair(aiTextureType_DISPLACEMENT, "texture_displacement")); - TextureTypes.push_back(std::make_pair(aiTextureType_EMISSION_COLOR, "texture_emission_color")); - TextureTypes.push_back(std::make_pair(aiTextureType_EMISSIVE, "texture_emissive")); - TextureTypes.push_back(std::make_pair(aiTextureType_HEIGHT, "texture_height")); - TextureTypes.push_back(std::make_pair(aiTextureType_LIGHTMAP, "texture_lightmap")); - TextureTypes.push_back(std::make_pair(aiTextureType_METALNESS, "texture_metalness")); - TextureTypes.push_back(std::make_pair(aiTextureType_NONE, "texture_none")); - TextureTypes.push_back(std::make_pair(aiTextureType_NORMAL_CAMERA, "texture_normal_camera")); - TextureTypes.push_back(std::make_pair(aiTextureType_NORMALS, "texture_normals")); - TextureTypes.push_back(std::make_pair(aiTextureType_OPACITY, "texture_opacity")); - TextureTypes.push_back(std::make_pair(aiTextureType_REFLECTION, "texture_reflection")); - TextureTypes.push_back(std::make_pair(aiTextureType_SHININESS, "texture_shininess")); - TextureTypes.push_back(std::make_pair(aiTextureType_SPECULAR, "texture_specular")); - TextureTypes.push_back(std::make_pair(aiTextureType_UNKNOWN, "texture_unknown")); + TextureTypes.push_back(std::make_pair(aiTextureType_DISPLACEMENT, "texture_displacement")); + TextureTypes.push_back(std::make_pair(aiTextureType_EMISSION_COLOR, "texture_emission_color")); + TextureTypes.push_back(std::make_pair(aiTextureType_EMISSIVE, "texture_emissive")); + TextureTypes.push_back(std::make_pair(aiTextureType_HEIGHT, "texture_height")); + TextureTypes.push_back(std::make_pair(aiTextureType_LIGHTMAP, "texture_lightmap")); + TextureTypes.push_back(std::make_pair(aiTextureType_METALNESS, "texture_metalness")); + TextureTypes.push_back(std::make_pair(aiTextureType_NONE, "texture_none")); + TextureTypes.push_back(std::make_pair(aiTextureType_NORMAL_CAMERA, "texture_normal_camera")); + TextureTypes.push_back(std::make_pair(aiTextureType_NORMALS, "texture_normals")); + TextureTypes.push_back(std::make_pair(aiTextureType_OPACITY, "texture_opacity")); + TextureTypes.push_back(std::make_pair(aiTextureType_REFLECTION, "texture_reflection")); + TextureTypes.push_back(std::make_pair(aiTextureType_SHININESS, "texture_shininess")); + TextureTypes.push_back(std::make_pair(aiTextureType_SPECULAR, "texture_specular")); + TextureTypes.push_back(std::make_pair(aiTextureType_UNKNOWN, "texture_unknown")); // Iterate Over All Texture Types for (unsigned int TextureTypeIndex = 0; TextureTypeIndex < TextureTypes.size(); TextureTypeIndex++) { diff --git a/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_Legacy_PreprocessTextureInfo.cpp b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_Legacy_PreprocessTextureInfo.cpp new file mode 100644 index 0000000000..db71586727 --- /dev/null +++ b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_Legacy_PreprocessTextureInfo.cpp @@ -0,0 +1,132 @@ +//======================================================================// +// This file is part of the BrainGenix-ERS Environment Rendering System // +//======================================================================// + +#include + + +void ERS_FUNCTION_Legacy_PreprocessTextureInfo(YAML::Node Metadata, ERS_STRUCT_Model* Model, ERS_STRUCT_SystemUtils* SystemUtils, long AssetID, bool LogEnable) { + + SystemUtils->Logger_->Log("Using Legacy Model Texture Identification", 4, LogEnable); + + // Read Mesh + Assimp::Importer Importer; + std::unique_ptr ModelData = std::make_unique(); + SystemUtils->ERS_IOSubsystem_->ReadAsset(Metadata["ModelID"].as(), ModelData.get()); + const aiScene* Scene = Importer.ReadFileFromMemory(ModelData->Data.get(), (int)ModelData->Size_B, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_CalcTangentSpace | aiProcess_PreTransformVertices | aiProcess_JoinIdenticalVertices, ""); + + // Log Errors + if (!Scene || Scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !Scene->mRootNode) { + SystemUtils->Logger_->Log(std::string(std::string("Model Loading Error: ") + std::string(Importer.GetErrorString())).c_str(), 10); + Model->IsReadyForGPU = false; + return; + } + + // Decode Mesh, Create Texture Pointers + ERS_LEGACY_FUNCTION_ProcessNode(Model, Scene->mRootNode, Scene); + +} + + + + + +void ERS_LEGACY_FUNCTION_ProcessNode(ERS_STRUCT_Model* Model, aiNode *Node, const aiScene *Scene) { + + + // Process Meshes In Current Node + for (unsigned int i = 0; i < Node->mNumMeshes; i++) { + aiMesh* Mesh = Scene->mMeshes[Node->mMeshes[i]]; + Model->Meshes.push_back( + ERS_LEGACY_FUNCTION_ProcessMesh( + Model, + (unsigned long)Mesh->mNumVertices, + (unsigned long)Mesh->mNumFaces*3, + Mesh, + Scene + ) + ); + + } + + // Process Children Nodes + for (unsigned int i = 0; i < Node->mNumChildren; i++) { + ERS_LEGACY_FUNCTION_ProcessNode(Model, Node->mChildren[i], Scene); + } + +} + +ERS_STRUCT_Mesh ERS_LEGACY_FUNCTION_ProcessMesh(ERS_STRUCT_Model* Model, unsigned long PreallocVertSize, unsigned long PreallocIndSize, aiMesh *Mesh, const aiScene *Scene) { + + // Create Data Holders + ERS_STRUCT_Mesh OutputMesh; + + // Process Materials + aiMaterial* Material = Scene->mMaterials[Mesh->mMaterialIndex]; + ERS_LEGACY_FUNCTION_IdentifyMeshTextures(Material, &OutputMesh); + + + // Return Populated Mesh + return OutputMesh; + +} + +void ERS_LEGACY_FUNCTION_IdentifyMeshTextures(aiMaterial* Mat, ERS_STRUCT_Mesh* Mesh) { + + std::vector> TextureTypes; + TextureTypes.push_back(std::make_pair(aiTextureType_AMBIENT, "texture_ambient")); + TextureTypes.push_back(std::make_pair(aiTextureType_AMBIENT_OCCLUSION, "texture_ambient_occlusion")); + TextureTypes.push_back(std::make_pair(aiTextureType_BASE_COLOR, "texture_base_color")); + TextureTypes.push_back(std::make_pair(aiTextureType_DIFFUSE, "texture_diffuse")); + TextureTypes.push_back(std::make_pair(aiTextureType_DIFFUSE_ROUGHNESS, "texture_diffuse_roughness")); + TextureTypes.push_back(std::make_pair(aiTextureType_DISPLACEMENT, "texture_displacement")); + TextureTypes.push_back(std::make_pair(aiTextureType_EMISSION_COLOR, "texture_emission_color")); + TextureTypes.push_back(std::make_pair(aiTextureType_EMISSIVE, "texture_emissive")); + TextureTypes.push_back(std::make_pair(aiTextureType_HEIGHT, "texture_height")); + TextureTypes.push_back(std::make_pair(aiTextureType_LIGHTMAP, "texture_lightmap")); + TextureTypes.push_back(std::make_pair(aiTextureType_METALNESS, "texture_metalness")); + TextureTypes.push_back(std::make_pair(aiTextureType_NONE, "texture_none")); + TextureTypes.push_back(std::make_pair(aiTextureType_NORMAL_CAMERA, "texture_normal_camera")); + TextureTypes.push_back(std::make_pair(aiTextureType_NORMALS, "texture_normals")); + TextureTypes.push_back(std::make_pair(aiTextureType_OPACITY, "texture_opacity")); + TextureTypes.push_back(std::make_pair(aiTextureType_REFLECTION, "texture_reflection")); + TextureTypes.push_back(std::make_pair(aiTextureType_SHININESS, "texture_shininess")); + TextureTypes.push_back(std::make_pair(aiTextureType_SPECULAR, "texture_specular")); + TextureTypes.push_back(std::make_pair(aiTextureType_UNKNOWN, "texture_unknown")); + + // Iterate Over All Texture Types + for (unsigned int TextureTypeIndex = 0; TextureTypeIndex < TextureTypes.size(); TextureTypeIndex++) { + + aiTextureType Type = TextureTypes[TextureTypeIndex].first; + std::string TypeName = TextureTypes[TextureTypeIndex].second; + + // Iterate Through Textures For This Type + for (unsigned int i=0; i< Mat->GetTextureCount(Type); i++) { + + + // Calculate Texture Path + aiString TextureString; + Mat->GetTexture(Type, i, &TextureString); + std::string TextureIdentifier = std::string(std::string(TextureString.C_Str())); + + // Search Texture List For Index Of Same Match, Add To List Of Unique Textures If Not Found + bool AlreadyHasTexture = false; + for (unsigned long x = 0; x < Mesh->Loader_RequestedTextureInformation_.size(); x++) { + if (Mesh->Loader_RequestedTextureInformation_[x].second == TextureIdentifier) { + AlreadyHasTexture = true; + break; + } + } + + // If It's Not Already In The List, Add IT + if (!AlreadyHasTexture) { + Mesh->Loader_RequestedTextureInformation_.push_back(std::make_pair(TypeName, TextureIdentifier)); + } + + + } + + } + +} + diff --git a/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_Legacy_PreprocessTextureInfo.h b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_Legacy_PreprocessTextureInfo.h new file mode 100644 index 0000000000..2382f50408 --- /dev/null +++ b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_Legacy_PreprocessTextureInfo.h @@ -0,0 +1,85 @@ +//======================================================================// +// This file is part of the BrainGenix-ERS Environment Rendering System // +//======================================================================// + +#pragma once + +// Standard Libraries (BG convention: use <> instead of "") +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Third-Party Libraries (BG convention: use <> instead of "") +#include +#include + +#include + +#include +#include +#include + + +// Internal Libraries (BG convention: use <> instead of "") +#include +#include +#include +#include + +#include + + + + + + +/** + * @brief Loads mesh texture information for legacy model formats that don't have this already encoded in them. + * + * @param Metadata + * @param Model + * @param SystemUtils + * @param AssetID + * @param LogEnable + */ +void ERS_FUNCTION_Legacy_PreprocessTextureInfo(YAML::Node Metadata, ERS_STRUCT_Model* Model, ERS_STRUCT_SystemUtils* SystemUtils, long AssetID, bool LogEnable); + + + + +/** + * @brief Populates Texture Request Information For The Mesh + * + * @param Mat + * @param Mesh + */ +void ERS_LEGACY_FUNCTION_IdentifyMeshTextures(aiMaterial* Mat, ERS_STRUCT_Mesh* Mesh); + +/** + * @brief Function Used To Process Subnodes Of SceneFiles. + * + * @param Node + * @param Scene + */ +void ERS_LEGACY_FUNCTION_ProcessNode(ERS_STRUCT_Model* Model, aiNode *Node, const aiScene *Scene); + +/** + * @brief Process Meshes From Model. + * + * @param Model + * @param Mesh + * @param Scene + * @return ERS_STRUCT_Mesh + */ +ERS_STRUCT_Mesh ERS_LEGACY_FUNCTION_ProcessMesh(ERS_STRUCT_Model* Model, unsigned long PreallocVertSize, unsigned long PerallocIndSize, aiMesh *Mesh, const aiScene *Scene); \ No newline at end of file diff --git a/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderManager.cpp b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderManager.cpp index ba0a681eac..4c12ab56aa 100644 --- a/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderManager.cpp +++ b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderManager.cpp @@ -18,13 +18,18 @@ bool ERS_FUNCTION_DecodeModelMetadata(YAML::Node Metadata, ERS_STRUCT_Model* Mod bool Status = false; if (FormatVersion == "0.0.0") { SystemUtils->Logger_->Log("Determined Model Metadata Version To Be '0.0.0', Attempting To Decode Model Metadata", 3, LogEnable); + ERS_FUNCTION_Legacy_PreprocessTextureInfo(Metadata, Model, SystemUtils, AssetID, LogEnable); Status = ERS_FUNCTION_DecodeModelMetadataV000(Metadata, Model, SystemUtils, AssetID, LogEnable); } else if (FormatVersion == "0.0.1") { SystemUtils->Logger_->Log("Determined Model Metadata Version To Be '0.0.1', Attempting To Decode Model Metadata", 3, LogEnable); + ERS_FUNCTION_Legacy_PreprocessTextureInfo(Metadata, Model, SystemUtils, AssetID, LogEnable); Status = ERS_FUNCTION_DecodeModelMetadataV001(Metadata, Model, SystemUtils, AssetID, LogEnable); + } else if (FormatVersion == "0.0.2") { + SystemUtils->Logger_->Log("Determined Model Metadata Version To Be '0.0.2', Attempting To Decode Model Metadata", 3, LogEnable); + Status = ERS_FUNCTION_DecodeModelMetadataV002(Metadata, Model, SystemUtils, AssetID, LogEnable); } else { // Failed To Decode Version - SystemUtils->Logger_->Log("Failed To Decode Metadata Version, Aborting Load", 8); + SystemUtils->Logger_->Log("Unsupported Format Version, Aborting Load", 8); return false; } diff --git a/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderManager.h b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderManager.h index 79f09f179b..c58d37dbe8 100644 --- a/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderManager.h +++ b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderManager.h @@ -18,8 +18,11 @@ #include #include +#include + #include #include +#include /** diff --git a/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderV0.0.2.cpp b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderV0.0.2.cpp new file mode 100644 index 0000000000..4d3aafdab0 --- /dev/null +++ b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderV0.0.2.cpp @@ -0,0 +1,160 @@ +//======================================================================// +// This file is part of the BrainGenix-ERS Environment Rendering System // +//======================================================================// + +#include + + +bool ERS_FUNCTION_DecodeModelMetadataV002(YAML::Node Metadata, ERS_STRUCT_Model* Model, ERS_STRUCT_SystemUtils* SystemUtils, long AssetID, bool LogEnable) { + + + // Setup Processing Variables + bool DecodeStatus = true; + + // Attempt To Decode, Handle Errors + try { + + SystemUtils->Logger_->Log("Decoding Model Metadata", 3, LogEnable); + + if (Model->Name == "Loading...") { + if (Metadata["Name"]) { + std::string Name = Metadata["Name"].as(); + Model->Name = Name.substr(Name.find_last_of("/") + 1, Name.length()-1); + } else { + Model->Name = "_Error_"; + SystemUtils->Logger_->Log(std::string("Error Loading Name From Model Metadata '") + std::to_string(AssetID) + "'", 7); + DecodeStatus = false; + } + } + + if (Metadata["ModelID"]) { + Model->ModelDataID = Metadata["ModelID"].as(); + } else { + Model->ModelDataID = -1; + SystemUtils->Logger_->Log(std::string("Error Loading 3DAssetID From Model Metadata '") + std::to_string(AssetID) + "'", 7); + DecodeStatus = false; + } + + if (Metadata["Vertices"]) { + Model->TotalVertices_ = Metadata["Vertices"].as(); + } else { + Model->TotalVertices_ = -1; + SystemUtils->Logger_->Log(std::string("Error Loading Vertices Parameter From Model Metadata '") + std::to_string(AssetID) + "'", 7); + DecodeStatus = false; + } + + if (Metadata["Indices"]) { + Model->TotalIndices_ = Metadata["Indices"].as(); + } else { + Model->TotalIndices_ = -1; + SystemUtils->Logger_->Log(std::string("Error Loading Indices Parameter From Model Metadata '") + std::to_string(AssetID) + "'", 7); + DecodeStatus = false; + } + + if (Metadata["BoundingBoxX"] && Metadata["BoundingBoxY"] && Metadata["BoundingBoxZ"]) { + double BoxX = Metadata["BoundingBoxX"].as(); + double BoxY = Metadata["BoundingBoxY"].as(); + double BoxZ = Metadata["BoundingBoxZ"].as(); + Model->BoxScale_ = glm::vec3(BoxX, BoxY, BoxZ); + } else { + Model->BoxScale_ = glm::vec3(1.0f); + SystemUtils->Logger_->Log(std::string("Error Loading Bounding Box Size Parameter From Model Metadata '") + std::to_string(AssetID) + "'", 7); + DecodeStatus = false; + } + + if (Metadata["OffsetX"] && Metadata["OffsetY"] && Metadata["OffsetZ"]) { + double OffsetX = Metadata["OffsetX"].as(); + double OffsetY = Metadata["OffsetY"].as(); + double OffsetZ = Metadata["OffsetZ"].as(); + Model->BoxOffset_ = glm::vec3(OffsetX, OffsetY, OffsetZ); + } else { + Model->BoxOffset_ = glm::vec3(0.0f); + SystemUtils->Logger_->Log(std::string("Error Loading Origin Offset Parameter From Model Metadata '") + std::to_string(AssetID) + "'", 7); + DecodeStatus = false; + } + + if (Metadata["Textures"]) { + YAML::Node TexturePathNode = Metadata["Textures"]; + for (YAML::const_iterator it=TexturePathNode.begin(); it!=TexturePathNode.end(); ++it) { + + // Setup Texture Struct + ERS_STRUCT_Texture Texture; + Texture.Path = it->first.as(); + SystemUtils->Logger_->Log(std::string("Found Texture '") + Texture.Path + "'", 3, LogEnable); + + // Add All Levels To This Texture + YAML::Node TextureLevels = it->second; + for (YAML::const_iterator LevelIterator = TextureLevels.begin(); LevelIterator != TextureLevels.end(); ++LevelIterator) { + + YAML::Node LevelInfo = LevelIterator->second; + ERS_STRUCT_TextureLevel TexLevel; + TexLevel.LevelTextureAssetID = LevelInfo["TextureLevelAssetID"].as(); + TexLevel.LevelTextureOpenGLID = 0; + TexLevel.LevelMemorySizeBytes = LevelInfo["TextureLevelMemorySizeBytes"].as(); + TexLevel.LevelResolution = std::make_pair(LevelInfo["TextureLevelResolutionX"].as(), LevelInfo["TextureLevelResolutionY"].as()); + TexLevel.LevelChannel = LevelInfo["TextureLevelNumberChannels"].as(); + TexLevel.LevelBitmap = nullptr; + TexLevel.LevelLoadedInRAM = false; + TexLevel.LevelLoadedInVRAM = false; + TexLevel.Level = LevelIterator->first.as(); + Texture.TextureLevels.push_back(TexLevel); + + SystemUtils->Logger_->Log(std::string("Detected Texture Level '") + std::to_string(LevelIterator->first.as()) + + "', Resolution '" + std::to_string(LevelInfo["TextureLevelResolutionX"].as()) + + "x" + std::to_string(LevelInfo["TextureLevelResolutionY"].as()) + + "'", 1, LogEnable); + + } + Model->Textures_.push_back(Texture); + } + + if (Model->Textures_.size() > 0) { + Model->MaxTextureLevel_ = Model->Textures_[0].TextureLevels.size() - 1; + } else { + Model->MaxTextureLevel_ = -1; + } + + + } else { + SystemUtils->Logger_->Log(std::string("Error Loading Texture Manifest From Model Metadata'") + std::to_string(AssetID) + "'", 7); + DecodeStatus = false; + } + + + if (Metadata["Meshes"]) { + YAML::Node MeshNode = Metadata["Meshes"]; + for (YAML::const_iterator it=MeshNode.begin(); it!=MeshNode.end(); ++it) { + + // Setup Mesh Struct + ERS_STRUCT_Mesh Mesh; + + // Add All Levels To This Texture + YAML::Node MeshTextures = it->second; + for (YAML::const_iterator LevelIterator = MeshTextures.begin(); LevelIterator != MeshTextures.end(); ++LevelIterator) { + + YAML::Node MeshTexture = LevelIterator->second; + Mesh.Loader_RequestedTextureInformation_.push_back(std::make_pair(MeshTexture["Type"].as(), MeshTexture["Identifier"].as())); + + + } + Model->Meshes.push_back(Mesh); + } + } + + SystemUtils->Logger_->Log("Finished Decoding Model Metadata", 3, LogEnable); + return DecodeStatus; + + } catch(YAML::BadSubscript&) { + SystemUtils->Logger_->Log(std::string(std::string("Error Loading Model '") + std::to_string(AssetID) + std::string("', Asset Metadata Corrupt")).c_str(), 9); + return false; + + } catch(YAML::TypedBadConversion&) { + SystemUtils->Logger_->Log(std::string(std::string("Error Loading Model '") + std::to_string(AssetID) + std::string("', ModelID/TextureIDs Corrupt")).c_str(), 9); + return false; + + } catch(YAML::TypedBadConversion&) { + SystemUtils->Logger_->Log(std::string(std::string("Error Loading Model '") + std::to_string(AssetID) + std::string("', Model Name Corrupt")).c_str(), 9); + return false; + } + +} \ No newline at end of file diff --git a/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderV0.0.2.h b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderV0.0.2.h new file mode 100644 index 0000000000..4fa25dad01 --- /dev/null +++ b/Source/Core/Loader/ERS_ModelLoader/ERS_FUNCTION_ModelMetadataDecoderV0.0.2.h @@ -0,0 +1,35 @@ +//======================================================================// +// This file is part of the BrainGenix-ERS Environment Rendering System // +//======================================================================// + +#pragma once + +// Standard Libraries (BG convention: use <> instead of "") +#include +#include + +// Third-Party Libraries (BG convention: use <> instead of "") +#include + +#include +#include + +// Internal Libraries (BG convention: use <> instead of "") +#include +#include +#include +#include + + +/** + * @brief Decodes model metadata from the yaml system. + * Handles metadata for model with version 0 - or unspecified. + * + * @param Metadata + * @param Model + * @param SystemUtils + * @param AssetID + * @return true + * @return false + */ +bool ERS_FUNCTION_DecodeModelMetadataV002(YAML::Node Metadata, ERS_STRUCT_Model* Model, ERS_STRUCT_SystemUtils* SystemUtils, long AssetID, bool LogEnable = true); \ No newline at end of file diff --git a/Source/Core/Renderer/ERS_CLASS_VisualRenderer/ERS_FUNCTION_DrawMesh.cpp b/Source/Core/Renderer/ERS_CLASS_VisualRenderer/ERS_FUNCTION_DrawMesh.cpp index 4b34035c76..d41b975685 100644 --- a/Source/Core/Renderer/ERS_CLASS_VisualRenderer/ERS_FUNCTION_DrawMesh.cpp +++ b/Source/Core/Renderer/ERS_CLASS_VisualRenderer/ERS_FUNCTION_DrawMesh.cpp @@ -58,7 +58,7 @@ void ERS_FUNCTION_DrawMesh(ERS_STRUCT_Mesh* Mesh, ERS_STRUCT_OpenGLDefaults* Ope Number = std::to_string(AmbientOcclusionHandle++); TypeID = 1; HasAmbientOcclusion = true; - } else if(Type == "texture_diffuse") { + } else if(Type == "texture_diffuse" || Type == "texture_base_color") { Number = std::to_string(DiffuseHandle++); TypeID = 2; HasDiffuse = true; diff --git a/Source/Core/Structures/ERS_STRUCT_Model/ERS_STRUCT_Model.h b/Source/Core/Structures/ERS_STRUCT_Model/ERS_STRUCT_Model.h index 59d9f83a42..d52c90cf85 100644 --- a/Source/Core/Structures/ERS_STRUCT_Model/ERS_STRUCT_Model.h +++ b/Source/Core/Structures/ERS_STRUCT_Model/ERS_STRUCT_Model.h @@ -35,6 +35,7 @@ struct ERS_STRUCT_Model { std::string Name = "Name Not Assigned"; long ShaderOverrideIndex_ = -1; /**Logger_->Log("Identifying Mesh Textures", 3); - AddTexture(Data, Model, Material, aiTextureType_AMBIENT, "texture_ambient", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_AMBIENT_OCCLUSION, "texture_ambient_occlusion", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_BASE_COLOR, "texture_base_color", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_DIFFUSE, "texture_diffuse", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_DIFFUSE_ROUGHNESS, "texture_diffuse_roughness", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_DISPLACEMENT, "texture_displacement", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_EMISSION_COLOR, "texture_emission_color", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_EMISSIVE, "texture_emissive", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_HEIGHT, "texture_height", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_LIGHTMAP, "texture_lightmap", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_METALNESS, "texture_metalness", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_NORMAL_CAMERA, "texture_normal_camera", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_NORMALS, "texture_normals", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_OPACITY, "texture_opacity", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_REFLECTION, "texture_reflection", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_SHININESS, "texture_shininess", ModelDirectory); - AddTexture(Data, Model, Material, aiTextureType_SPECULAR, "texture_specular", ModelDirectory); - SystemUtils_->Logger_->Log("Finshed Mesh Texture Identification", 4); + + + +void IdentifyMeshTextures(aiMaterial* Mat, ERS_STRUCT_Mesh* Mesh) { + + std::vector> TextureTypes; + TextureTypes.push_back(std::make_pair(aiTextureType_AMBIENT, "texture_ambient")); + TextureTypes.push_back(std::make_pair(aiTextureType_AMBIENT_OCCLUSION, "texture_ambient_occlusion")); + TextureTypes.push_back(std::make_pair(aiTextureType_BASE_COLOR, "texture_base_color")); + TextureTypes.push_back(std::make_pair(aiTextureType_DIFFUSE, "texture_diffuse")); + TextureTypes.push_back(std::make_pair(aiTextureType_DIFFUSE_ROUGHNESS, "texture_diffuse_roughness")); + TextureTypes.push_back(std::make_pair(aiTextureType_DISPLACEMENT, "texture_displacement")); + TextureTypes.push_back(std::make_pair(aiTextureType_EMISSION_COLOR, "texture_emission_color")); + TextureTypes.push_back(std::make_pair(aiTextureType_EMISSIVE, "texture_emissive")); + TextureTypes.push_back(std::make_pair(aiTextureType_HEIGHT, "texture_height")); + TextureTypes.push_back(std::make_pair(aiTextureType_LIGHTMAP, "texture_lightmap")); + TextureTypes.push_back(std::make_pair(aiTextureType_METALNESS, "texture_metalness")); + TextureTypes.push_back(std::make_pair(aiTextureType_NONE, "texture_none")); + TextureTypes.push_back(std::make_pair(aiTextureType_NORMAL_CAMERA, "texture_normal_camera")); + TextureTypes.push_back(std::make_pair(aiTextureType_NORMALS, "texture_normals")); + TextureTypes.push_back(std::make_pair(aiTextureType_OPACITY, "texture_opacity")); + TextureTypes.push_back(std::make_pair(aiTextureType_REFLECTION, "texture_reflection")); + TextureTypes.push_back(std::make_pair(aiTextureType_SHININESS, "texture_shininess")); + TextureTypes.push_back(std::make_pair(aiTextureType_SPECULAR, "texture_specular")); + TextureTypes.push_back(std::make_pair(aiTextureType_UNKNOWN, "texture_unknown")); + + // Iterate Over All Texture Types + for (unsigned int TextureTypeIndex = 0; TextureTypeIndex < TextureTypes.size(); TextureTypeIndex++) { + + aiTextureType Type = TextureTypes[TextureTypeIndex].first; + std::string TypeName = TextureTypes[TextureTypeIndex].second; + + // Iterate Through Textures For This Type + for (unsigned int i=0; i< Mat->GetTextureCount(Type); i++) { + + + // Calculate Texture Path + aiString TextureString; + Mat->GetTexture(Type, i, &TextureString); + std::string TextureIdentifier = std::string(std::string(TextureString.C_Str())); + + //std::string Message = std::string("Model Requesting Texture Of Type '") + TypeName + std::string("' With Identifier '") + TextureIdentifier + std::string("'"); + //SystemUtils_->Logger_->Log(Message, 3); + + // Search Texture List For Index Of Same Match, Add To List Of Unique Textures If Not Found + bool AlreadyHasTexture = false; + for (unsigned long x = 0; x < Mesh->Loader_RequestedTextureInformation_.size(); x++) { + if (Mesh->Loader_RequestedTextureInformation_[x].second == TextureIdentifier) { + //SystemUtils_->Logger_->Log(std::string("Found Matching Texture '") + Mesh->Loader_RequestedTextureInformation_[x].second + "'", 3); + AlreadyHasTexture = true; + break; + } + } + + // If It's Not Already In The List, Add IT + if (!AlreadyHasTexture) { + Mesh->Loader_RequestedTextureInformation_.push_back(std::make_pair(TypeName, TextureIdentifier)); + } + + + } + + } } -ERS_STRUCT_Mesh ERS_CLASS_ExternalModelLoader::ProcessMesh(ERS_STRUCT_ModelWriterData &Data, ERS_STRUCT_Model* Model, aiMesh *Mesh, const aiScene *Scene, std::string ModelDirectory) { - // Process Materials - aiMaterial* Material = Scene->mMaterials[Mesh->mMaterialIndex]; - HandleMeshTextures(Data, Model, Material, ModelDirectory); + +ERS_STRUCT_Mesh ERS_CLASS_ExternalModelLoader::ProcessMesh(ERS_STRUCT_ModelWriterData &Data, ERS_STRUCT_Model* Model, aiMesh *Mesh, const aiScene *Scene, std::string ModelDirectory) { + // Create Data Holders ERS_STRUCT_Mesh OutputMesh; + // Process Materials + aiMaterial* Material = Scene->mMaterials[Mesh->mMaterialIndex]; + HandleMeshTextures(Data, Model, Material, ModelDirectory, &OutputMesh); + // IdentifyMeshTextures(Material, &OutputMesh); + // Iterate Through Meshes' Vertices for (unsigned int i = 0; i < Mesh->mNumVertices; i++) { @@ -415,7 +462,36 @@ ERS_STRUCT_Mesh ERS_CLASS_ExternalModelLoader::ProcessMesh(ERS_STRUCT_ModelWrite return OutputMesh; } -void ERS_CLASS_ExternalModelLoader::AddTexture(ERS_STRUCT_ModelWriterData &Data, ERS_STRUCT_Model* Model, aiMaterial *Mat, aiTextureType Type, std::string TypeName, std::string ModelDirectory) { + + + + + + +void ERS_CLASS_ExternalModelLoader::HandleMeshTextures(ERS_STRUCT_ModelWriterData &Data, ERS_STRUCT_Model* Model, aiMaterial* Material, std::string ModelDirectory, ERS_STRUCT_Mesh* TargetMesh) { + + SystemUtils_->Logger_->Log("Identifying Mesh Textures", 3); + AddTexture(Data, Model, Material, aiTextureType_AMBIENT, "texture_ambient", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_AMBIENT_OCCLUSION, "texture_ambient_occlusion", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_BASE_COLOR, "texture_base_color", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_DIFFUSE, "texture_diffuse", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_DIFFUSE_ROUGHNESS, "texture_diffuse_roughness", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_DISPLACEMENT, "texture_displacement", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_EMISSION_COLOR, "texture_emission_color", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_EMISSIVE, "texture_emissive", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_HEIGHT, "texture_height", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_LIGHTMAP, "texture_lightmap", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_METALNESS, "texture_metalness", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_NORMAL_CAMERA, "texture_normal_camera", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_NORMALS, "texture_normals", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_OPACITY, "texture_opacity", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_REFLECTION, "texture_reflection", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_SHININESS, "texture_shininess", ModelDirectory, TargetMesh); + AddTexture(Data, Model, Material, aiTextureType_SPECULAR, "texture_specular", ModelDirectory, TargetMesh); + SystemUtils_->Logger_->Log("Finshed Mesh Texture Identification", 4); + +} +void ERS_CLASS_ExternalModelLoader::AddTexture(ERS_STRUCT_ModelWriterData &Data, ERS_STRUCT_Model* Model, aiMaterial *Mat, aiTextureType Type, std::string TypeName, std::string ModelDirectory, ERS_STRUCT_Mesh* TargetMesh) { for (unsigned int i=0; i< Mat->GetTextureCount(Type); i++) { @@ -431,6 +507,7 @@ void ERS_CLASS_ExternalModelLoader::AddTexture(ERS_STRUCT_ModelWriterData &Data, Data.TextureList.push_back(FilePath); Data.TextureNames.push_back(Str.C_Str()); } + TargetMesh->Loader_RequestedTextureInformation_.push_back(std::make_pair(TypeName, Str.C_Str())); } @@ -544,20 +621,3 @@ bool ERS_CLASS_ExternalModelLoader::LoadModel(std::string ModelPath, ERS_STRUCT_ } } - - - - //todo: - // then, add the modelwriter to "GUI_Window_ImportAsset" so it can proeprly export things - // then moake it write those models with this class (basically, have the importer load the model with this file, then write it with ERS_modelwriter) - // then make the importer class (in utils), have multithreading, and allow it to import a list of models (or something like that for batch importing) - // finally, add the new import button to import a batch of models and have it traverse the filesystem to find said models given a directory. - - - - - - - - - diff --git a/Source/Core/Utils/ERS_CLASS_ExternalModelLoader/ERS_CLASS_ExternalModelLoader.h b/Source/Core/Utils/ERS_CLASS_ExternalModelLoader/ERS_CLASS_ExternalModelLoader.h index 44c2352f4c..c2e3b776e5 100644 --- a/Source/Core/Utils/ERS_CLASS_ExternalModelLoader/ERS_CLASS_ExternalModelLoader.h +++ b/Source/Core/Utils/ERS_CLASS_ExternalModelLoader/ERS_CLASS_ExternalModelLoader.h @@ -86,7 +86,7 @@ class ERS_CLASS_ExternalModelLoader { * @param Type * @param TypeName */ - void AddTexture(ERS_STRUCT_ModelWriterData &Data, ERS_STRUCT_Model* Model, aiMaterial *Mat, aiTextureType Type, std::string TypeName, std::string ModelDirectory); + void AddTexture(ERS_STRUCT_ModelWriterData &Data, ERS_STRUCT_Model* Model, aiMaterial *Mat, aiTextureType Type, std::string TypeName, std::string ModelDirectory, ERS_STRUCT_Mesh* TargetMesh); /** @@ -119,7 +119,7 @@ class ERS_CLASS_ExternalModelLoader { * @param Material * @param ModelDirectory */ - void HandleMeshTextures(ERS_STRUCT_ModelWriterData &Data, ERS_STRUCT_Model* Model, aiMaterial* Material, std::string ModelDirectory); + void HandleMeshTextures(ERS_STRUCT_ModelWriterData &Data, ERS_STRUCT_Model* Model, aiMaterial* Material, std::string ModelDirectory, ERS_STRUCT_Mesh* TargetMesh); /** * @brief Finds and loads all the relevant textures into memory. diff --git a/Source/Core/Writers/ERS_ModelWriter/ERS_ModelWriter.cpp b/Source/Core/Writers/ERS_ModelWriter/ERS_ModelWriter.cpp index 470287b90f..e9f9ac721f 100644 --- a/Source/Core/Writers/ERS_ModelWriter/ERS_ModelWriter.cpp +++ b/Source/Core/Writers/ERS_ModelWriter/ERS_ModelWriter.cpp @@ -268,7 +268,7 @@ std::string ERS_CLASS_ModelWriter::GenerateModelMetadata(ERS_STRUCT_ModelWriterD MetadataEmitter<Log("Saving Mesh-Texture Relationship Information To ERS Metadata Header", 4); + for (unsigned int i = 0; i < Data.Model->Meshes.size(); i++) { + MetadataEmitter<Meshes[i].Loader_RequestedTextureInformation_.size(); x++) { + MetadataEmitter<Meshes[i].Loader_RequestedTextureInformation_[x].second; + MetadataEmitter<Meshes[i].Loader_RequestedTextureInformation_[x].first; + + MetadataEmitter<TotalVertices_;