Added sub asset data members

Changed some control flow in asset manager to accommodate for subassets
Read/Write meta files for assets with sub assets
This commit is contained in:
Xiao Qi 2022-11-04 17:20:42 +08:00
parent 6984653b64
commit 1f0d54486d
6 changed files with 234 additions and 49 deletions

View File

@ -22,5 +22,10 @@ namespace SHADE
AssetID id; AssetID id;
AssetType type; AssetType type;
AssetPath path; AssetPath path;
bool isSubAsset;
std::vector<SHAsset*> subAssets;
AssetID parent;
}; };
} }

View File

@ -46,10 +46,11 @@ enum class AssetType : AssetTypeMeta
SHADER, SHADER,
SHADER_BUILT_IN, SHADER_BUILT_IN,
TEXTURE, TEXTURE,
MESH, MODEL,
SCENE, SCENE,
PREFAB, PREFAB,
MATERIAL, MATERIAL,
MESH,
MAX_COUNT MAX_COUNT
}; };
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) }; constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
@ -83,7 +84,7 @@ constexpr std::string_view SCENE_EXTENSION {".shade"};
constexpr std::string_view PREFAB_EXTENSION {".shprefab"}; constexpr std::string_view PREFAB_EXTENSION {".shprefab"};
constexpr std::string_view MATERIAL_EXTENSION {".shmat"}; constexpr std::string_view MATERIAL_EXTENSION {".shmat"};
constexpr std::string_view TEXTURE_EXTENSION {".shtex"}; constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
constexpr std::string_view MESH_EXTENSION {".shmesh"}; constexpr std::string_view MODEL_EXTENSION {".shmodel"};
constexpr std::string_view EXTENSIONS[] = { constexpr std::string_view EXTENSIONS[] = {
AUDIO_EXTENSION, AUDIO_EXTENSION,
@ -91,7 +92,7 @@ constexpr std::string_view EXTENSIONS[] = {
SHADER_BUILT_IN_EXTENSION, SHADER_BUILT_IN_EXTENSION,
MATERIAL_EXTENSION, MATERIAL_EXTENSION,
TEXTURE_EXTENSION, TEXTURE_EXTENSION,
MESH_EXTENSION, MODEL_EXTENSION,
SCRIPT_EXTENSION, SCRIPT_EXTENSION,
SCENE_EXTENSION, SCENE_EXTENSION,
PREFAB_EXTENSION, PREFAB_EXTENSION,

View File

@ -16,7 +16,7 @@
#include "SHAssetManager.h" #include "SHAssetManager.h"
#include "SHAssetMetaHandler.h" #include "SHAssetMetaHandler.h"
#include "Libraries/Loaders/SHMeshLoader.h" #include "Libraries/Loaders/SHModelLoader.h"
#include "Libraries/Loaders/SHTextureLoader.h" #include "Libraries/Loaders/SHTextureLoader.h"
#include "Libraries/Loaders/SHShaderSourceLoader.h" #include "Libraries/Loaders/SHShaderSourceLoader.h"
#include "Libraries/Loaders/SHTextBasedLoader.h" #include "Libraries/Loaders/SHTextBasedLoader.h"
@ -178,7 +178,8 @@ namespace SHADE
name, name,
id, id,
type, type,
newPath newPath,
false
}; };
assetCollection.insert({ assetCollection.insert({
@ -187,7 +188,8 @@ namespace SHADE
name, name,
id, id,
type, type,
newPath newPath,
false
) )
}); });
@ -324,25 +326,32 @@ namespace SHADE
return result; return result;
} }
AssetID SHAssetManager::CompileAsset(AssetPath const& path) noexcept void SHAssetManager::CompileAsset(AssetPath const& path) noexcept
{ {
SHAsset newAsset if (!std::filesystem::exists(path))
{ {
.name = path.stem().string() SHLOG_ERROR("Path provided does not point to a file: {}", path.string());
}; return;
}
AssetPath newPath;
auto const ext{ path.extension().string() }; auto const ext{ path.extension().string() };
if (ext == GLSL_EXTENSION.data()) if (ext == GLSL_EXTENSION.data())
{ {
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value(); newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN); }
newAsset.type = AssetType::SHADER_BUILT_IN; else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
{
std::string command = MODEL_COMPILER_EXE.data();
command += " " + path.string();
std::system(command.c_str());
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
modelPath += MODEL_EXTENSION;
newPath = modelPath;
GenerateNewMeta(newPath);
} }
assetCollection.insert({ newAsset.id, newAsset });
SHAssetMetaHandler::WriteMetaData(newAsset);
return newAsset.id;
} }
FolderPointer SHAssetManager::GetRootFolder() noexcept FolderPointer SHAssetManager::GetRootFolder() noexcept
@ -395,23 +404,15 @@ namespace SHADE
for (auto const& path : paths) for (auto const& path : paths)
{ {
SHAsset newAsset AssetPath newPath;
{
.name = path.stem().string()
};
auto const ext{ path.extension().string() }; auto const ext{ path.extension().string() };
if (ext == GLSL_EXTENSION.data()) if (ext == GLSL_EXTENSION.data())
{ {
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value(); newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN);
newAsset.type = AssetType::SHADER_BUILT_IN;
} }
else if (ext == DDS_EXTENSION.data()) else if (ext == DDS_EXTENSION.data())
{ {
newAsset.path = SHTextureCompiler::CompileTextureAsset(path).value(); newPath = SHTextureCompiler::CompileTextureAsset(path).value();
newAsset.id = GenerateAssetID(AssetType::TEXTURE);
newAsset.type = AssetType::TEXTURE;
} }
else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data()) else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
{ {
@ -419,15 +420,12 @@ namespace SHADE
command += " " + path.string(); command += " " + path.string();
std::system(command.c_str()); std::system(command.c_str());
std::string newPath = path.string().substr(0, path.string().find_last_of('.')); std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
newPath += MESH_EXTENSION; modelPath += MODEL_EXTENSION;
newAsset.path = newPath; newPath = modelPath;
newAsset.id = GenerateAssetID(AssetType::MESH);
newAsset.type = AssetType::MESH;
} }
assetCollection.insert({ newAsset.id, newAsset }); GenerateNewMeta(newPath);
SHAssetMetaHandler::WriteMetaData(newAsset);
} }
} }
@ -442,10 +440,11 @@ namespace SHADE
loaders[static_cast<size_t>(AssetType::SHADER)] = dynamic_cast<SHAssetLoader*>(new SHShaderSourceLoader()); loaders[static_cast<size_t>(AssetType::SHADER)] = dynamic_cast<SHAssetLoader*>(new SHShaderSourceLoader());
loaders[static_cast<size_t>(AssetType::SHADER_BUILT_IN)] = loaders[static_cast<size_t>(AssetType::SHADER)]; loaders[static_cast<size_t>(AssetType::SHADER_BUILT_IN)] = loaders[static_cast<size_t>(AssetType::SHADER)];
loaders[static_cast<size_t>(AssetType::TEXTURE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader()); loaders[static_cast<size_t>(AssetType::TEXTURE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader());
loaders[static_cast<size_t>(AssetType::MESH)] = dynamic_cast<SHAssetLoader*>(new SHMeshLoader()); loaders[static_cast<size_t>(AssetType::MODEL)] = dynamic_cast<SHAssetLoader*>(new SHModelLoader());
loaders[static_cast<size_t>(AssetType::SCENE)] = dynamic_cast<SHAssetLoader*>(new SHTextBasedLoader()); loaders[static_cast<size_t>(AssetType::SCENE)] = dynamic_cast<SHAssetLoader*>(new SHTextBasedLoader());
loaders[static_cast<size_t>(AssetType::PREFAB)] = loaders[static_cast<size_t>(AssetType::SCENE)]; loaders[static_cast<size_t>(AssetType::PREFAB)] = loaders[static_cast<size_t>(AssetType::SCENE)];
loaders[static_cast<size_t>(AssetType::MATERIAL)] = loaders[static_cast<size_t>(AssetType::SCENE)]; loaders[static_cast<size_t>(AssetType::MATERIAL)] = loaders[static_cast<size_t>(AssetType::SCENE)];
loaders[static_cast<size_t>(AssetType::MESH)] = nullptr;
} }
/**************************************************************************** /****************************************************************************
@ -453,9 +452,9 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
void SHAssetManager::Load() noexcept void SHAssetManager::Load() noexcept
{ {
//CompileAll();
BuildAssetCollection(); BuildAssetCollection();
InitLoaders(); InitLoaders();
//CompileAll();
//LoadAllData(); //LoadAllData();
} }
@ -473,8 +472,12 @@ namespace SHADE
SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept
{ {
SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path); if (asset.isSubAsset)
{
return LoadSubData(asset);
}
SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path);
if (data == nullptr) if (data == nullptr)
{ {
SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string()); SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string());
@ -487,13 +490,120 @@ namespace SHADE
return data; return data;
} }
void SHAssetManager::LoadDataFromScratch(AssetPath path) noexcept SHAssetData* SHAssetManager::LoadSubData(SHAsset const& asset) noexcept
{ {
auto const& parent = assetCollection[asset.parent];
auto parentData = loaders[static_cast<size_t>(parent.type)]->Load(parent.path);
if (parentData == nullptr)
{
SHLOG_ERROR("Unable to load asset into memory: {}\n", parent.path.string());
}
else
{
assetData.emplace(parent.id, parentData);
if (parent.type == AssetType::MODEL)
{
auto parentModel = reinterpret_cast<SHModelAsset*>(parentData);
for (auto i {0}; i < parent.subAssets.size(); ++i)
{
assetData.emplace(
parent.subAssets[i]->id,
parentModel->subMeshes[i]
);
}
}
return assetData[asset.id];
}
return parentData;
}
void SHAssetManager::LoadNewData(AssetPath path) noexcept
{
}
void SHAssetManager::GenerateNewMeta(AssetPath path) noexcept
{
auto const ext = path.extension().string();
if (ext == SHADER_BUILT_IN_EXTENSION.data())
{
SHAsset newAsset{
path.stem().string(),
GenerateAssetID(AssetType::SHADER_BUILT_IN),
AssetType::SHADER_BUILT_IN,
path,
false
};
assetCollection.emplace(newAsset.id, newAsset);
SHAssetMetaHandler::WriteMetaData(newAsset);
}
else if (ext == TEXTURE_EXTENSION.data())
{
SHAsset newAsset{
path.stem().string(),
GenerateAssetID(AssetType::SHADER_BUILT_IN),
AssetType::SHADER_BUILT_IN,
path,
false
};
assetCollection.emplace(newAsset.id, newAsset);
SHAssetMetaHandler::WriteMetaData(newAsset);
}
else if (ext == MODEL_EXTENSION)
{
SHAsset newAsset{
path.stem().string(),
GenerateAssetID(AssetType::MODEL),
AssetType::MODEL,
path,
false
};
assetCollection.emplace(newAsset.id, newAsset);
SHModelAsset* const data = reinterpret_cast<SHModelAsset*>(LoadData(newAsset));
assetData.emplace(newAsset.id, data);
for(auto const& subMesh : data->subMeshes)
{
SHAsset subAsset{
.name = subMesh->header.name,
.id = GenerateAssetID(AssetType::MESH),
.type = AssetType::MESH,
.isSubAsset = true,
.parent = newAsset.id
};
assetCollection.emplace(subAsset.id, subAsset);
assetCollection[newAsset.id].subAssets.push_back(&assetCollection[subAsset.id]);
assetData.emplace(subAsset.id, subMesh);
}
SHAssetMetaHandler::WriteMetaData(assetCollection[newAsset.id]);
}
} }
void SHAssetManager::BuildAssetCollection() noexcept void SHAssetManager::BuildAssetCollection() noexcept
{ {
SHFileSystem::BuildDirectory(ASSET_ROOT.data(), folderRoot, assetCollection); SHFileSystem::BuildDirectory(ASSET_ROOT.data(), folderRoot, assetCollection);
for (auto& asset : std::ranges::views::values(assetCollection))
{
if (!asset.subAssets.empty())
{
// Add subasset data into map, replace pointer and free heap memory
for (auto i{ 0 }; i < asset.subAssets.size(); ++i)
{
auto const id = asset.subAssets[i]->id;
assetCollection[id] = *asset.subAssets[i];
delete asset.subAssets[i];
asset.subAssets[i] = &assetCollection[id];
}
}
}
} }
} }

View File

@ -87,7 +87,7 @@ namespace SHADE
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept; static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept; static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
static AssetID CompileAsset(AssetPath const& path) noexcept; static void CompileAsset(AssetPath const& path) noexcept;
static FolderPointer GetRootFolder() noexcept; static FolderPointer GetRootFolder() noexcept;
@ -96,7 +96,10 @@ namespace SHADE
static void InitLoaders() noexcept; static void InitLoaders() noexcept;
static void LoadAllData() noexcept; static void LoadAllData() noexcept;
static SHAssetData* LoadData(SHAsset const& asset) noexcept; static SHAssetData* LoadData(SHAsset const& asset) noexcept;
static void LoadDataFromScratch(AssetPath path) noexcept; static SHAssetData* LoadSubData(SHAsset const& asset) noexcept;
static void LoadNewData(AssetPath path) noexcept;
static void GenerateNewMeta(AssetPath path) noexcept;
inline static void BuildAssetCollection() noexcept; inline static void BuildAssetCollection() noexcept;
static bool IsRecognised(char const*) noexcept; static bool IsRecognised(char const*) noexcept;

View File

@ -9,7 +9,6 @@
******************************************************************************/ ******************************************************************************/
#include "SHpch.h" #include "SHpch.h"
#include "SHAssetMetaHandler.h" #include "SHAssetMetaHandler.h"
#include <fstream>
#include <sstream> #include <sstream>
namespace SHADE namespace SHADE
@ -21,11 +20,15 @@ namespace SHADE
* \brief Helper function to retrieve field value from meta data file * \brief Helper function to retrieve field value from meta data file
* for processing * for processing
****************************************************************************/ ****************************************************************************/
void GetFieldValue(std::ifstream& file, std::string& line) noexcept bool GetFieldValue(std::ifstream& file, std::string& line) noexcept
{ {
line = ""; line = "";
std::getline(file, line); if (std::getline(file, line))
{
line = line.substr(line.find_last_of(':') + 2, line.length()); line = line.substr(line.find_last_of(':') + 2, line.length());
return true;
}
return false;
} }
/**************************************************************************** /****************************************************************************
@ -66,7 +69,8 @@ namespace SHADE
std::ifstream metaFile{ path.string(), std::ios_base::in }; std::ifstream metaFile{ path.string(), std::ios_base::in };
if (!metaFile.is_open()) if (!metaFile.is_open())
{ {
// Error unable to open SHLOG_ERROR("Unable to open meta file: {}", path.string());
return {};
} }
std::string line; std::string line;
@ -93,6 +97,43 @@ namespace SHADE
typeStream >> type; typeStream >> type;
meta.type = static_cast<AssetType>(type); meta.type = static_cast<AssetType>(type);
meta.isSubAsset = false;
// Burn Line
if (std::getline(metaFile, line))
{
// Name Line
while(GetFieldValue(metaFile, line))
{
auto subAsset = new SHAsset();
// Get resource name
std::stringstream nameStream{ line };
AssetName name;
nameStream >> name;
subAsset->name = name;
// Get resource id
GetFieldValue(metaFile, line);
std::stringstream idStream{ line };
AssetID id;
idStream >> id;
subAsset->id = id;
// Get resource type
GetFieldValue(metaFile, line);
std::stringstream typeStream{ line };
AssetTypeMeta type;
typeStream >> type;
subAsset->type = static_cast<AssetType>(type);
subAsset->isSubAsset = true;
subAsset->parent = meta.id;
meta.subAssets.push_back(subAsset);
}
}
metaFile.close(); metaFile.close();
meta.path = path.parent_path().string() + "/" + path.stem().string(); meta.path = path.parent_path().string() + "/" + path.stem().string();
@ -108,6 +149,12 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
{ {
if (meta.isSubAsset)
{
SHLOG_WARNING("Cannot write subasset meta: {}", meta.name);
return;
}
//TODO: Write into binary eventually //TODO: Write into binary eventually
std::string path{ meta.path.string() }; std::string path{ meta.path.string() };
path.append(META_EXTENSION); path.append(META_EXTENSION);
@ -124,7 +171,23 @@ namespace SHADE
metaFile << "ID: " << meta.id << "\n"; metaFile << "ID: " << meta.id << "\n";
metaFile << "Type: " << static_cast<AssetTypeMeta>(meta.type) << std::endl; metaFile << "Type: " << static_cast<AssetTypeMeta>(meta.type) << std::endl;
if (!meta.subAssets.empty())
{
metaFile << "Sub Assets:\n";
for (auto const& subAsset : meta.subAssets)
{
WriteSubAssetMeta(metaFile, *subAsset);
}
}
metaFile.close(); metaFile.close();
} }
void SHAssetMetaHandler::WriteSubAssetMeta(std::ofstream& metaFile, SHAsset const& subAsset) noexcept
{
metaFile << "Name: " << subAsset.name << "\n";
metaFile << "ID: " << subAsset.id << "\n";
metaFile << "Type: " << static_cast<AssetTypeMeta>(subAsset.type) << std::endl;
}
} }

View File

@ -12,6 +12,7 @@
#include "SHAssetMacros.h" #include "SHAssetMacros.h"
#include "SHAsset.h" #include "SHAsset.h"
#include <fstream>
namespace SHADE namespace SHADE
{ {
@ -45,6 +46,8 @@ namespace SHADE
* \brief Writes meta data into text file * \brief Writes meta data into text file
****************************************************************************/ ****************************************************************************/
static void WriteMetaData(SHAsset const&) noexcept; static void WriteMetaData(SHAsset const&) noexcept;
static void WriteSubAssetMeta(std::ofstream&, SHAsset const&) noexcept;
}; };
} }