From 9df517f3b30885d78c5ce63a5add0d002680d9b6 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 21 Oct 2022 20:28:54 +0800 Subject: [PATCH] SP3-170 SP3-238 Restructured asset and asset loading library types to be derived from common base class. Storage of assets and loaders based on pointers. Created general templated calls to get data from asset manager based on asset type passed in as template argument. More concise internal interface when loading and storing assets with libraries --- Assets/Cube.003.shmesh.shmeta | 2 +- Assets/Cube.012.shmesh.shmeta | 2 +- .../RaccoonPreTexturedVer1_Base9.shtex.shmeta | 2 +- SHADE_Application/src/Scenes/SBTestScene.cpp | 47 +- .../src/Assets/Asset Types/SHAnimationAsset.h | 4 +- .../src/Assets/Asset Types/SHAssetData.h | 19 + .../src/Assets/Asset Types/SHInternalAsset.h | 21 + .../src/Assets/Asset Types/SHMeshAsset.h | 6 +- .../src/Assets/Asset Types/SHTextureAsset.h | 3 +- .../src/Assets/Libraries/SHAssetLoader.h | 21 + .../src/Assets/Libraries/SHAssimpLibrary.cpp | 26 +- .../src/Assets/Libraries/SHAssimpLibrary.h | 6 +- .../src/Assets/Libraries/SHMeshCompiler.cpp | 2 +- .../src/Assets/Libraries/SHMeshLoader.cpp | 13 +- .../src/Assets/Libraries/SHMeshLoader.h | 6 +- .../src/Assets/Libraries/SHTextureLoader.cpp | 9 + .../src/Assets/Libraries/SHTextureLoader.h | 17 +- SHADE_Engine/src/Assets/SHAsset.h | 5 +- SHADE_Engine/src/Assets/SHAssetMacros.h | 51 ++- SHADE_Engine/src/Assets/SHAssetManager.cpp | 422 ++++-------------- SHADE_Engine/src/Assets/SHAssetManager.h | 80 ++-- .../src/Assets/SHAssetMetaHandler.cpp | 14 +- 22 files changed, 300 insertions(+), 478 deletions(-) create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHAssetData.h create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h create mode 100644 SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h diff --git a/Assets/Cube.003.shmesh.shmeta b/Assets/Cube.003.shmesh.shmeta index d41be546..207f3999 100644 --- a/Assets/Cube.003.shmesh.shmeta +++ b/Assets/Cube.003.shmesh.shmeta @@ -1,3 +1,3 @@ Name: Cube.003 ID: 110152941 -Type:  +Type: 6 diff --git a/Assets/Cube.012.shmesh.shmeta b/Assets/Cube.012.shmesh.shmeta index d5cd1090..3af04f93 100644 --- a/Assets/Cube.012.shmesh.shmeta +++ b/Assets/Cube.012.shmesh.shmeta @@ -1,3 +1,3 @@ Name: Cube.012 ID: 107348815 -Type:  +Type: 6 diff --git a/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta index f8c267d9..3905aa4f 100644 --- a/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta +++ b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta @@ -1,3 +1,3 @@ Name: RaccoonPreTexturedVer1_Base9 ID: 91918845 -Type:  +Type: 4 diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index f1d656ee..50a87fd3 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -13,6 +13,9 @@ #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" +#include "Assets/Asset Types/SHMeshAsset.h" +#include "Assets/Asset Types/SHTextureAsset.h" + #include "Assets/SHAssetManager.h" using namespace SHADE; @@ -39,34 +42,26 @@ namespace Sandbox // Create temp meshes const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); + auto assets = SHAssetManager::GetAllAssets(); + //Test Racoon mesh - auto meshes = SHADE::SHAssetManager::GetAllMeshes(); - std::vector> handles; - for (auto const& mesh : meshes) - { - if (mesh.header.meshName == "Cube.012") - { - handles.push_back(graphicsSystem->AddMesh( - mesh.header.vertexCount, - mesh.vertexPosition.data(), - mesh.texCoords.data(), - mesh.vertexTangent.data(), - mesh.vertexNormal.data(), - mesh.header.indexCount, - mesh.indices.data() - )); - } - } + auto mesh = SHAssetManager::GetData(107348815); + Handle handle; + handle = (graphicsSystem->AddMesh( + mesh->header.vertexCount, + mesh->vertexPosition.data(), + mesh->texCoords.data(), + mesh->vertexTangent.data(), + mesh->vertexNormal.data(), + mesh->header.indexCount, + mesh->indices.data() + )); graphicsSystem->BuildMeshBuffers(); // Load Textures - auto textures = SHADE::SHAssetManager::GetAllTextures(); - std::vector> texHandles; - for (const auto& tex : textures) - { - auto texture = graphicsSystem->Add(tex); - texHandles.push_back(texture); - } + auto texture = SHAssetManager::GetData(91918845); + Handle texHandle; + texHandle = graphicsSystem->Add(*texture); graphicsSystem->BuildTextures(); // Create Materials @@ -116,7 +111,7 @@ namespace Sandbox auto& renderable = *SHComponentManager::GetComponent_s(raccoonSpin); auto& transform = *SHComponentManager::GetComponent_s(raccoonSpin); - renderable.Mesh = handles.front(); + renderable.Mesh = handle; renderable.SetMaterial(customMat); renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); @@ -157,7 +152,7 @@ namespace Sandbox auto& renderableShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); auto& transformShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); - renderableShowcase.Mesh = handles.front(); + renderableShowcase.Mesh = handle; renderableShowcase.SetMaterial(customMat); renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h index 76f4c0ac..b411a11e 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h @@ -12,11 +12,11 @@ #include #include -#include "SH_API.h" +#include "SHAssetData.h" namespace SHADE { - struct SH_API SHAnimationAsset + struct SH_API SHAnimationAsset : SHAssetData { std::string name; diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAssetData.h b/SHADE_Engine/src/Assets/Asset Types/SHAssetData.h new file mode 100644 index 00000000..8db9824c --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHAssetData.h @@ -0,0 +1,19 @@ +/*************************************************************************//** + * \file SHAssetDataBase.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. + *****************************************************************************/ +#pragma once + +namespace SHADE +{ + struct SHAssetData + { + virtual ~SHAssetData(){} + }; +} diff --git a/SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h new file mode 100644 index 00000000..8bef34e9 --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h @@ -0,0 +1,21 @@ +/*************************************************************************//** + * \file SHInternalAsset.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. + *****************************************************************************/ +#pragma once + +#include "SHAsset.h" + +namespace SHADE +{ + struct SHInternalAsset : SHAsset + { + + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h index 68c0d150..20b442ba 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h @@ -14,7 +14,7 @@ #include #include "Math/SHMath.h" -#include "SH_API.h" +#include "SHAssetData.h" namespace SHADE { @@ -22,10 +22,10 @@ namespace SHADE { uint32_t vertexCount; uint32_t indexCount; - std::string meshName; + std::string name; }; - struct SH_API SHMeshAsset + struct SH_API SHMeshAsset : SHAssetData { bool compiled; bool changed; diff --git a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h index d24b6c02..d26a2c30 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h @@ -2,10 +2,11 @@ #include "tinyddsloader.h" #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" +#include "SHAssetData.h" namespace SHADE { - struct SHTextureAsset + struct SHTextureAsset : SHAssetData { bool compiled; diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h b/SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h new file mode 100644 index 00000000..41595519 --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h @@ -0,0 +1,21 @@ +/*************************************************************************//** + * \file SHAssetLoader.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. + *****************************************************************************/ +#pragma once + +#include "Assets/Asset Types/SHAssetData.h" + +namespace SHADE +{ + struct SHAssetLoader + { + virtual SHAssetData* Load(AssetPath path) = 0; + }; +} diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp index feea9f35..f4be0b68 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp @@ -51,13 +51,11 @@ namespace SHADE } } - SHMeshAsset SHAssimpLibrary::ProcessMesh(aiMesh const& mesh) noexcept + SHMeshAsset* SHAssimpLibrary::ProcessMesh(aiMesh const& mesh) noexcept { - SHMeshAsset result - { - .compiled { false}, - .changed { false } - }; + SHMeshAsset* result = new SHMeshAsset(); + result->compiled = false; + result->changed = false; for (size_t i{0}; i < mesh.mNumVertices; ++i) { @@ -66,7 +64,7 @@ namespace SHADE vertex.x = mesh.mVertices[i].x; vertex.y = mesh.mVertices[i].y; vertex.z = mesh.mVertices[i].z; - result.vertexPosition.push_back(vertex); + result->vertexPosition.push_back(vertex); // Tex coords SHVec2 texCoord{0.f, 0.f}; @@ -75,7 +73,7 @@ namespace SHADE texCoord.x = mesh.mTextureCoords[0][i].x; texCoord.y = mesh.mTextureCoords[0][i].y; } - result.texCoords.push_back(texCoord); + result->texCoords.push_back(texCoord); // Normals SHVec3 normal{0.f, 0.f, 0.f}; @@ -85,7 +83,7 @@ namespace SHADE normal.y = mesh.mNormals[i].y; normal.z = mesh.mNormals[i].z; } - result.vertexNormal.push_back(normal); + result->vertexNormal.push_back(normal); // Tangent SHVec3 tangent{0.f, 0.f, 0.f}; @@ -95,7 +93,7 @@ namespace SHADE tangent.y = mesh.mTangents[i].y; tangent.z = mesh.mTangents[i].z; } - result.vertexTangent.push_back(tangent); + result->vertexTangent.push_back(tangent); } for (size_t i {0}; i < mesh.mNumFaces; ++i) @@ -103,13 +101,13 @@ namespace SHADE aiFace face = mesh.mFaces[i]; for (size_t j{0}; j < face.mNumIndices; ++j) { - result.indices.push_back(face.mIndices[j]); + result->indices.push_back(face.mIndices[j]); } } - result.header.vertexCount = static_cast(result.vertexPosition.size()); - result.header.indexCount = static_cast(result.indices.size()); - result.header.meshName = mesh.mName.C_Str(); + result->header.vertexCount = static_cast(result->vertexPosition.size()); + result->header.indexCount = static_cast(result->indices.size()); + result->header.name = mesh.mName.C_Str(); return result; } diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h index a4a0447a..83755b4c 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h @@ -22,13 +22,13 @@ namespace SHADE class SHAssimpLibrary { private: - using MeshVectorRef = std::vector&; - using AnimVectorRef = std::vector&; + using MeshVectorRef = std::vector&; + using AnimVectorRef = std::vector&; static Assimp::Importer aiImporter; static void ProcessNode(aiNode const& node, aiScene const& scene,MeshVectorRef meshes) noexcept; static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept; - static SHMeshAsset ProcessMesh(aiMesh const& mesh) noexcept; + static SHMeshAsset* ProcessMesh(aiMesh const& mesh) noexcept; public: static void LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept; diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp index 8026f0e1..2346714e 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp @@ -20,7 +20,7 @@ std::string SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, A { std::string newPath{ path.string() }; newPath = newPath.substr(0, newPath.find_last_of('/') + 1); - newPath += asset.header.meshName + MESH_EXTENSION; + newPath += asset.header.name + MESH_EXTENSION.data(); std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc }; if (!file.is_open()) diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp index 73fed1fb..90dd58d4 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp @@ -16,7 +16,7 @@ namespace SHADE { - void SHMeshLoader::LoadSHMesh(SHMeshAsset& mesh, AssetPath path) noexcept + void SHMeshLoader::LoadSHMesh(AssetPath path, SHMeshAsset& mesh) noexcept { std::ifstream file{ path.string(), std::ios::in | std::ios::binary }; if (!file.is_open()) @@ -56,7 +56,7 @@ namespace SHADE mesh.header.indexCount = indexCount; mesh.header.vertexCount = vertCount; - mesh.header.meshName = name; + mesh.header.name = name; mesh.vertexPosition = std::move(vertPos); mesh.vertexTangent = std::move(vertTan); @@ -66,4 +66,13 @@ namespace SHADE file.close(); } + + SHAssetData* SHMeshLoader::Load(AssetPath path) + { + auto result = new SHMeshAsset(); + + LoadSHMesh(path, *result); + + return result; + } } diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h index f01b942a..34c4e5d2 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h @@ -12,11 +12,13 @@ #pragma once #include "../SHAssetMacros.h" #include "../Asset Types/SHMeshAsset.h" +#include "SHAssetLoader.h" namespace SHADE { - struct SHMeshLoader + struct SHMeshLoader : public SHAssetLoader { - static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept; + void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept; + SHAssetData* Load(AssetPath path) override; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp index 5147562a..8b986524 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp @@ -133,6 +133,15 @@ namespace SHADE file.close(); } + SHAssetData* SHTextureLoader::Load(AssetPath path) + { + auto result = new SHTextureAsset(); + + LoadImageAsset(path, *result); + + return result; + } + void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset) { if (path.extension().string() == DDS_EXTENSION) diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h index eb61ea91..8bdf91b1 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h @@ -15,19 +15,20 @@ #include "../SHAssetMacros.h" #include "../Asset Types/SHTextureAsset.h" #include "tinyddsloader.h" +#include "SHAssetLoader.h" namespace SHADE { - class SHTextureLoader + class SHTextureLoader : public SHAssetLoader { private: - static std::string TinyDDSResultToString(tinyddsloader::Result value); - static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear); - - - static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept; + std::string TinyDDSResultToString(tinyddsloader::Result value); + vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear); + + void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept; public: - static void LoadImageAsset(AssetPath paths, SHTextureAsset& image); - static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; + void LoadImageAsset(AssetPath paths, SHTextureAsset& image); + void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; + SHAssetData* Load(AssetPath path) override; }; } diff --git a/SHADE_Engine/src/Assets/SHAsset.h b/SHADE_Engine/src/Assets/SHAsset.h index 8d7b55d1..86e8a722 100644 --- a/SHADE_Engine/src/Assets/SHAsset.h +++ b/SHADE_Engine/src/Assets/SHAsset.h @@ -12,11 +12,12 @@ #pragma once #include "Filesystem/SHFileSystem.h" -#include "SHAssetMacros.h" +#include "Assets/SHAssetMacros.h" +#include "SH_API.h" namespace SHADE { - struct SHAsset + struct SH_API SHAsset { AssetName name; AssetID id; diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 61c5879d..0fdfa04e 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -32,12 +32,12 @@ typedef std::filesystem::path AssetPath; typedef unsigned char* AssetData; typedef std::string AssetMetaVersion; typedef std::string AssetExtension; -typedef unsigned char AssetTypeMeta; +typedef size_t AssetTypeMeta; typedef FMOD::Sound* SHSound; // Asset Meta Version -#define ASSET_META_VER "1.0" +constexpr std::string_view ASSET_META_VER { "1.0" }; // Asset type enum enum class AssetType : AssetTypeMeta @@ -53,34 +53,35 @@ enum class AssetType : AssetTypeMeta SCENE, PREFAB, AUDIO_WAV, - DDS + DDS, + MAX_COUNT }; //Directory #ifdef _PUBLISH -#define ASSET_ROOT "Assets" +constexpr std::string_view ASSET_ROOT {"Assets"}; #else -#define ASSET_ROOT "../../Assets" +constexpr std::string_view ASSET_ROOT {"../../Assets"}; #endif // ASSET EXTENSIONS -#define META_EXTENSION ".shmeta" -#define IMAGE_EXTENSION ".png" -#define AUDIO_EXTENSION ".ogg" -#define AUDIO_WAV_EXTENSION ".wav" -#define SHADER_EXTENSION ".glsl" -#define SCRIPT_EXTENSION ".cs" -#define SCENE_EXTENSION ".SHADE" -#define PREFAB_EXTENSION ".SHPrefab" -#define MATERIAL_EXTENSION ".SHMat" -#define TEXTURE_EXTENSION ".shtex" -#define DDS_EXTENSION ".dds" -#define FBX_EXTENSION ".fbx" -#define GLTF_EXTENSION ".gltf" -#define MESH_EXTENSION ".shmesh" +constexpr std::string_view META_EXTENSION {".shmeta"}; +constexpr std::string_view IMAGE_EXTENSION {".png"}; +constexpr std::string_view AUDIO_EXTENSION {".ogg"}; +constexpr std::string_view AUDIO_WAV_EXTENSION {".wav"}; +constexpr std::string_view SHADER_EXTENSION {".glsl"}; +constexpr std::string_view SCRIPT_EXTENSION {".cs"}; +constexpr std::string_view SCENE_EXTENSION {".SHADE"}; +constexpr std::string_view PREFAB_EXTENSION {".SHPrefab"}; +constexpr std::string_view MATERIAL_EXTENSION {".SHMat"}; +constexpr std::string_view TEXTURE_EXTENSION {".shtex"}; +constexpr std::string_view DDS_EXTENSION {".dds"}; +constexpr std::string_view FBX_EXTENSION {".fbx"}; +constexpr std::string_view GLTF_EXTENSION {".gltf"}; +constexpr std::string_view MESH_EXTENSION {".shmesh"}; -std::string const EXTENSIONS[] = { +constexpr std::string_view EXTENSIONS[] = { AUDIO_EXTENSION, SHADER_EXTENSION, MATERIAL_EXTENSION, @@ -96,10 +97,12 @@ std::string const EXTENSIONS[] = { GLTF_EXTENSION }; +constexpr size_t TYPE_COUNT {static_cast(AssetType::MAX_COUNT) }; + // Error flags -#define FILE_NOT_FOUND_ERR "FILE NOT FOUND" -#define META_NOT_FOUND_ERR "META NOT FOUND" -#define ASSET_NOT_FOUND_ERR "ASSET NOT FOUND" -#define EXT_DOES_NOT_EXIST "TYPE DOES NOT HAVE EXTENSION DEFINED" +constexpr std::string_view FILE_NOT_FOUND_ERR {"FILE NOT FOUND"}; +constexpr std::string_view META_NOT_FOUND_ERR {"META NOT FOUND"}; +constexpr std::string_view ASSET_NOT_FOUND_ERR {"ASSET NOT FOUND"}; +constexpr std::string_view EXT_DOES_NOT_EXIST {"TYPE DOES NOT HAVE EXTENSION DEFINED"}; #endif // !SH_ASSET_MACROS_H diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index faca24b2..2658e83b 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -26,11 +26,10 @@ namespace SHADE FMOD::System* SHAssetManager::audioSystem; std::unordered_map* SHAssetManager::audioSoundList; - std::vector SHAssetManager::assetCollection; - std::unordered_map SHAssetManager::assetRegistry; + std::vector SHAssetManager::loaders(TYPE_COUNT); - std::unordered_map SHAssetManager::meshCollection; - std::unordered_map SHAssetManager::textureCollection; + std::vector SHAssetManager::assetCollection; + std::unordered_map SHAssetManager::assetData; /**************************************************************************** * \brief Static function to generate asset ID. @@ -81,7 +80,37 @@ namespace SHADE // return std::filesystem::path(); //} - return std::filesystem::path(ASSET_ROOT + folder + path.filename().string()); + return std::filesystem::path(std::string(ASSET_ROOT) + folder + path.filename().string()); + } + + AssetPath SHAssetManager::GenerateNewPath(AssetName name, AssetType type) + { + std::string folder; + + switch(type) + { + case AssetType::SCENE: + folder = "scenes/"; + break; + + case AssetType::PREFAB: + folder = "prefabs/"; + break; + + case AssetType::MATERIAL: + folder = "materials/"; + break; + + default: + folder = "/"; + } + + return std::filesystem::path{ + std::string(ASSET_ROOT) + + folder + + name + + std::string(EXTENSIONS[static_cast(type)]) + }; } /**************************************************************************** @@ -117,7 +146,7 @@ namespace SHADE // folder = ""; // break; //} - AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) }; + AssetPath path{ std::string{ASSET_ROOT} + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) }; SHAssetMetaHandler::WriteMetaData(meta); @@ -126,6 +155,19 @@ namespace SHADE return id; } + AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept + { + AssetID id = GenerateAssetID(type); + + assetCollection.emplace_back( + name, + id, + type, + GenerateNewPath(name, type), + 0 + ); + return id; + } /**************************************************************************** * \brief Import new asset from outside editor window. * @@ -134,7 +176,10 @@ namespace SHADE ****************************************************************************/ AssetID SHAssetManager::ImportNewAsset(char const* p) noexcept { - std::filesystem::path const path{ p }; + std::filesystem::path const path{ p }; + + auto const type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()); + auto const id = GenerateAssetID(type); std::filesystem::path const newPath{ GenerateLocalPath(path) }; if (newPath.empty()) @@ -145,11 +190,7 @@ namespace SHADE std::filesystem::copy(path, newPath); - AssetID id{ RetrieveAsset(newPath.string().c_str()) }; - if (id != 0) - { - LoadData(id); - } + assetCollection.push_back(CreateAssetFromPath(newPath)); return id; } @@ -160,158 +201,14 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::RefreshAllAssets() noexcept { - std::vector metaFiles; - std::vector AssetFiles; - //SHFileSystem::LoadAllFiles(metaFiles, AssetFiles); - //std::vector AssetFilesVerified; - std::vector AssetFilesNew; - - for (auto const& asset : AssetFiles) - { - bool found = false; - for (auto it {metaFiles.begin()}; it != metaFiles.end(); ++it) - { - std::string fileExtCheck{ asset.filename().string() }; - fileExtCheck += META_EXTENSION; - if (it->filename().string() == fileExtCheck) - { - metaFiles.erase(it); - found = true; - break; - } - } - - if (!found && IsRecognised(asset.extension().string().c_str())) - { - AssetFilesNew.push_back(asset); - } - } - - std::vector newLoad; - newLoad.reserve(AssetFilesNew.size()); - - //TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa) - for (auto const& file : AssetFilesNew) - { - newLoad.push_back(RegisterAssetNew(file)); - } - - //UpdateAllSpriteSets(); - - } - - //void SHAssetManager::LoadDataTemp(std::string p) noexcept - //{ - // AssetPath path{ p }; - - // if (path.extension().string() == FBX_EXTENSION - // || path.extension().string() == GLTF_EXTENSION - // || path.extension().string() == MESH_EXTENSION) - // { - // LoadGLTF( - // { - // .name {path.filename().string()}, - // .id {0}, - // .type {AssetType::MESH}, - // .path {path}, - // .location {0} - // } - // ); - // } - // else if (path.extension().string() == DDS_EXTENSION - // || path.extension().string() == TEXTURE_EXTENSION) - // { - // LoadDDS( - // { - // .name {path.filename().string()}, - // .id {0}, - // .type {AssetType::DDS}, - // .path {path}, - // .location {0} - // } - // ); - // } - //} - - std::vector SHAssetManager::GetAllMeshes() noexcept - { - std::vector result; - for (auto const& mesh : meshCollection) - { - result.push_back(mesh.second); - } - - return result; - } - - std::vector SHAssetManager::GetAllTextures() noexcept - { - std::vector result; - for (auto const& dds : textureCollection) - { - result.push_back(dds.second); - } - - return result; - } - - SHMeshAsset const* SHAssetManager::GetMesh(AssetID id) noexcept - { - if (meshCollection.find(id) == meshCollection.end()) - { - return nullptr; - } - - return &meshCollection[id]; - } - - SHTextureAsset const* SHAssetManager::GetTexture(AssetID id) noexcept - { - if (textureCollection.find(id) == textureCollection.end()) - { - return nullptr; - } - - return &textureCollection[id]; - } - - /**************************************************************************** - * \param Path for meta data file - * \param Path for asset file - - * \brief Links meta data to asset in registries. Meta data should - * already exist - ****************************************************************************/ - void SHAssetManager::RegisterAsset(AssetPath const& metaPath, AssetPath const& path) noexcept - { - SHAsset const meta = SHAssetMetaHandler::RetrieveMetaData(metaPath); - - assetCollection.push_back(meta); - } - - /**************************************************************************** - * \param Path for asset file - - * \brief Creates new meta data for new asset. - ****************************************************************************/ - SHAsset SHAssetManager::RegisterAssetNew(AssetPath const& asset) noexcept - { - SHAsset meta; - meta.type = SHAssetMetaHandler::GetTypeFromExtension(asset.extension().string()); - meta.id = GenerateAssetID(meta.type); - - assetCollection.push_back(meta); - - SHAssetMetaHandler::WriteMetaData(meta); - return assetCollection.back(); } bool SHAssetManager::IsRecognised(char const* ext) noexcept { for (auto const& e : EXTENSIONS) { - if (strcmp(ext, e.c_str()) == 0) + if (strcmp(ext, e.data()) == 0) { return true; } @@ -320,60 +217,31 @@ namespace SHADE return false; } - void SHAssetManager::LoadGLTF(AssetPath path) noexcept + SHAsset SHAssetManager::CreateAssetFromPath(AssetPath path) noexcept { - std::vector meshes; - std::vector anims; - - SHAssimpLibrary::LoadFromFile(path, meshes, anims); + SHAsset result; - for (auto const& mesh : meshes) - { - auto id{ GenerateAssetID(AssetType::MESH) }; - meshCollection.emplace(id, mesh); + result.name = path.stem().string(); + result.type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()); + result.id = GenerateAssetID(result.type); + result.path = path; - AssetPath path; - if (!mesh.compiled) - { - path = SHMeshCompiler::CompileMeshBinary(mesh, path); - } - - assetCollection.emplace_back( - mesh.header.meshName, - id, - AssetType::MESH, - path, - 0 - ); - } - - for (auto const& anim : anims) - { - //TODO Register anim resource and compile into binary - } + return result; } - void SHAssetManager::LoadDDS(SHAsset asset) noexcept + void SHAssetManager::InitLoaders() noexcept { - SHTextureAsset image; - - SHTextureLoader::LoadImageAsset(asset.path, image); - - if (!image.compiled) - { - auto id{ GenerateAssetID(AssetType::TEXTURE) }; - textureCollection.emplace(id, image); - - auto path{ SHTextureCompiler::CompileTextureBinary(image, asset.path) }; - - assetCollection.emplace_back( - image.name, - id, - AssetType::TEXTURE, - path, - 0 - ); - } + loaders[static_cast(AssetType::AUDIO)] = nullptr; + loaders[static_cast(AssetType::SHADER)] = nullptr; + loaders[static_cast(AssetType::MATERIAL)] = nullptr; + loaders[static_cast(AssetType::IMAGE)] = dynamic_cast(new SHTextureLoader()); + loaders[static_cast(AssetType::TEXTURE)] = nullptr; + loaders[static_cast(AssetType::MESH)] = dynamic_cast(new SHMeshLoader()); + loaders[static_cast(AssetType::SCRIPT)] = nullptr; + loaders[static_cast(AssetType::SCENE)] = nullptr; + loaders[static_cast(AssetType::PREFAB)] = nullptr; + loaders[static_cast(AssetType::AUDIO_WAV)] = nullptr; + loaders[static_cast(AssetType::DDS)] = nullptr; } /**************************************************************************** @@ -381,7 +249,8 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::Load() noexcept { - RetrieveAssets(); + InitLoaders(); + BuildAssetCollection(); LoadAllData(); } @@ -390,143 +259,40 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::LoadAllData() noexcept { - //TODO Remove when on demand loading is done for (auto const& asset : assetCollection) { - switch (asset.type) - { - case AssetType::MESH: - meshCollection.emplace(asset.id, SHMeshAsset()); - SHMeshLoader::LoadSHMesh(meshCollection[asset.id], asset.path); - break; - - case AssetType::TEXTURE: - textureCollection.emplace(asset.id, SHTextureAsset()); - SHTextureLoader::LoadSHTexture(asset.path, textureCollection[asset.id]); - break; - - default: - void; - } + SHAssetData* data = loaders[static_cast(asset.type)]->Load(asset.path); + assetData.emplace(asset.id, data); } } - void SHAssetManager::LoadData(AssetID id) noexcept + SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept { - (void)id; - } + SHAssetData* data = loaders[static_cast(asset.type)]->Load(asset.path); - /**************************************************************************** - * \brief Retrieve all asset files and meta files from filesystem - ****************************************************************************/ - void SHAssetManager::RetrieveAssets() noexcept - { - std::vector metaFiles; - std::vector AssetFiles; - - for (auto const dir : std::filesystem::recursive_directory_iterator(ASSET_ROOT)) + if (data == nullptr) { - if (dir.path().extension().string() == META_EXTENSION) - { - auto meta{ SHAssetMetaHandler::RetrieveMetaData(dir.path()) }; - - assetCollection.push_back(meta); - assetRegistry.emplace(meta.id, meta); - } - } - - //TODO: Write new function for file manager to loop through all files - //SHFileSystem::StartupFillDirectories(ASSET_ROOT); - //FolderPointer rootFolder = SHFileSystem::GetRoot(); - - //for (auto const& meta : metaFiles) - //{ - // for (std::vector::const_iterator it{ AssetFiles.cbegin() }; - // it != AssetFiles.cend(); - // ++it) - // { - // // Asset exists for meta file - // std::string fileExtCheck{ it->filename().string() }; - // fileExtCheck += META_EXTENSION; - // if (meta.filename().string() == fileExtCheck) - // { - // RegisterAsset(meta, *it); - // AssetFiles.erase(it); - // break; - // } - // } - //} - - //TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa) - //for (auto const& file : AssetFiles) - //{ - // if (IsRecognised(file.extension().string().c_str())) - // { - // SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file)); - // } - // else - // { - // std::cout << "Unsupported File Format: " << file.filename() << "\n"; - // } - //} - } - - AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept - { - std::filesystem::path p{ path }; - if (IsRecognised(p.extension().string().c_str())) - { - SHAsset const& meta{ RegisterAssetNew(p) }; - SHAssetMetaHandler::WriteMetaData(meta); - return meta.id; + SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string()); } else { - std::cout << "Unsupported File Format: " << p.filename() << "\n"; + assetData.emplace(asset.id, data); } - // Assert that file imported is not recognised - return 0; + return data; } - /**************************************************************************** - * \param Full path of file - - * \brief Extracts file name from path. Formats file name into readable - * with spaces and capitalises first letter of every word - ****************************************************************************/ - AssetName SHAssetManager::GetNameFromPath(AssetPath filepath) noexcept + void SHAssetManager::BuildAssetCollection() noexcept { - std::string name{ filepath.filename().string() }; - name = name.substr(0, name.find_last_of('.')); - - //if (name[0] <= 122 && name[0] >= 97) - //{ - // name[0] -= 32; - //} - - //for (size_t i{ 1 }; i < name.length(); ++i) - //{ - // // Replace all underscores with spaces - // if (name[i] == '_') - // { - // name[i] = ' '; - // continue; - // } - - // if (name[i + 1] <= 'Z' && name[i + 1] >= 'A' - // && name[i] <= 'z' && name[i] >= 'a') - // { - // name.insert(i + 1, 1, ' '); - // continue; - // } - - // if (name[i - 1] == ' ' && name[i] <= 'z' && name[i] >= 'a') - // { - // name[i] -= 32; - // } - //} - - return name; + for (auto const& dir : std::filesystem::recursive_directory_iterator{ASSET_ROOT}) + { + if (dir.is_regular_file()) + { + if (dir.path().extension().string() == META_EXTENSION.data()) + { + assetCollection.push_back(SHAssetMetaHandler::RetrieveMetaData(dir.path())); + } + } + } } } diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index b2c4216b..74029bdd 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -11,9 +11,10 @@ #pragma once #include "tinyddsloader.h" #include "SHAsset.h" +#include "Asset Types/SHAssetData.h" +#include "Libraries/SHAssetLoader.h" +#include -#include "Asset Types/SHMeshAsset.h" -#include "Asset Types/SHTextureAsset.h" #include "SH_API.h" namespace SHADE @@ -28,6 +29,8 @@ namespace SHADE static AssetPath GenerateLocalPath(AssetPath path) noexcept; + static AssetPath GenerateNewPath(AssetName name, AssetType type); + /**************************************************************************** * \brief Deallocate all memory used by resource data ****************************************************************************/ @@ -54,6 +57,7 @@ namespace SHADE * \return resource id generated for new asset ****************************************************************************/ static AssetID CreateNewAsset(AssetType, AssetName) noexcept; + static AssetID CreateAsset(AssetName name, AssetType type) noexcept; /**************************************************************************** * \brief Import new resource from outside editor window. @@ -70,67 +74,49 @@ namespace SHADE static void RefreshAllAssets() noexcept; // -------------------------------------------------------------------------/ - //TODO: TEMPORARY FOR TESTING GLTF & DDS - //static void LoadDataTemp(std::string path) noexcept; - static std::vector GetAllMeshes() noexcept; - static std::vector GetAllTextures() noexcept; + template + static std::enable_if_t, T const * const> GetData(AssetID id) noexcept + { + if (assetData.contains(id)) + { + for (auto const& asset : assetCollection) + { + if (asset.id == id) + { + assetData.emplace(id, LoadData(asset)); + return dynamic_cast(assetData[id]); + } + } - static SHMeshAsset const* GetMesh(AssetID id) noexcept; - static SHTextureAsset const* GetTexture(AssetID id) noexcept; - - // Specialised load calls - static void LoadGLTF(AssetPath path) noexcept; - static void LoadDDS(SHAsset asset) noexcept; + SHLOG_ERROR("Asset ID provided does not exist: {}", id); + return nullptr; + } + + return dynamic_cast(assetData[id]); + } private: /**************************************************************************** * \brief Load resource data into memory ****************************************************************************/ static void LoadAllData() noexcept; - static void LoadData(AssetID id) noexcept; + static SHAssetData* LoadData(SHAsset const& asset) noexcept; - /**************************************************************************** - * \brief Retrieve all resource files and meta files from filesystem - ****************************************************************************/ - static void RetrieveAssets() noexcept; - - static AssetID RetrieveAsset(char const* path) noexcept; - - /**************************************************************************** - * \param Full path of file - - * \brief Extracts file name from path. Formats file name into readable - * with spaces and capitalises first letter of every word - ****************************************************************************/ - static AssetName GetNameFromPath(AssetPath) noexcept; - - /**************************************************************************** - * \param Path for meta data file - * \param Path for resource file - - * \brief Links meta data to resource in registries. Meta data should - * already exist - ****************************************************************************/ - static void RegisterAsset(AssetPath const&, AssetPath const&) noexcept; - - /**************************************************************************** - * \param Path for resource file - - * \brief Creates new meta data for new resource. - ****************************************************************************/ - static SHAsset RegisterAssetNew(AssetPath const&) noexcept; + inline static void BuildAssetCollection() noexcept; static bool IsRecognised(char const*) noexcept; + + static SHAsset CreateAssetFromPath(AssetPath path) noexcept; + static void InitLoaders() noexcept; static FMOD::System* audioSystem; static std::unordered_map* audioSoundList; + static std::vector loaders; + // For all resources static std::vector assetCollection; - static std::unordered_map assetRegistry; - - static std::unordered_map meshCollection; - static std::unordered_map textureCollection; + static std::unordered_map assetData; }; } diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp index 442c3d96..1bfec00d 100644 --- a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp +++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp @@ -37,7 +37,7 @@ namespace SHADE { for (int i{0}; i < EXTENSIONS->size(); ++i) { - if (ext == EXTENSIONS[i]) + if (strcmp(ext.c_str(), EXTENSIONS[i].data()) == 0) { return static_cast(i); } @@ -53,7 +53,7 @@ namespace SHADE ****************************************************************************/ AssetExtension SHAssetMetaHandler::GetExtensionFromType(AssetType type) noexcept { - return EXTENSIONS[static_cast(type)]; + return AssetExtension(EXTENSIONS[static_cast(type)]); } /**************************************************************************** @@ -124,16 +124,6 @@ namespace SHADE metaFile << "ID: " << meta.id << "\n"; metaFile << "Type: " << static_cast(meta.type) << std::endl; - ////TODO Add in information that is specific to types like mesh - //switch(meta.type) - //{ - //case AssetType::MESH: - // break; - - //default: - // break; - //} - metaFile.close(); }