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;
AssetType type;
AssetPath path;
bool isSubAsset;
std::vector<SHAsset*> subAssets;
AssetID parent;
};
}

View File

@ -46,10 +46,11 @@ enum class AssetType : AssetTypeMeta
SHADER,
SHADER_BUILT_IN,
TEXTURE,
MESH,
MODEL,
SCENE,
PREFAB,
MATERIAL,
MESH,
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 MATERIAL_EXTENSION {".shmat"};
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[] = {
AUDIO_EXTENSION,
@ -91,7 +92,7 @@ constexpr std::string_view EXTENSIONS[] = {
SHADER_BUILT_IN_EXTENSION,
MATERIAL_EXTENSION,
TEXTURE_EXTENSION,
MESH_EXTENSION,
MODEL_EXTENSION,
SCRIPT_EXTENSION,
SCENE_EXTENSION,
PREFAB_EXTENSION,

View File

@ -16,7 +16,7 @@
#include "SHAssetManager.h"
#include "SHAssetMetaHandler.h"
#include "Libraries/Loaders/SHMeshLoader.h"
#include "Libraries/Loaders/SHModelLoader.h"
#include "Libraries/Loaders/SHTextureLoader.h"
#include "Libraries/Loaders/SHShaderSourceLoader.h"
#include "Libraries/Loaders/SHTextBasedLoader.h"
@ -178,7 +178,8 @@ namespace SHADE
name,
id,
type,
newPath
newPath,
false
};
assetCollection.insert({
@ -187,7 +188,8 @@ namespace SHADE
name,
id,
type,
newPath
newPath,
false
)
});
@ -324,25 +326,32 @@ namespace SHADE
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() };
if (ext == GLSL_EXTENSION.data())
{
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN);
newAsset.type = AssetType::SHADER_BUILT_IN;
newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
}
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
@ -395,23 +404,15 @@ namespace SHADE
for (auto const& path : paths)
{
SHAsset newAsset
{
.name = path.stem().string()
};
AssetPath newPath;
auto const ext{ path.extension().string() };
if (ext == GLSL_EXTENSION.data())
{
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN);
newAsset.type = AssetType::SHADER_BUILT_IN;
newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
}
else if (ext == DDS_EXTENSION.data())
{
newAsset.path = SHTextureCompiler::CompileTextureAsset(path).value();
newAsset.id = GenerateAssetID(AssetType::TEXTURE);
newAsset.type = AssetType::TEXTURE;
newPath = SHTextureCompiler::CompileTextureAsset(path).value();
}
else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
{
@ -419,15 +420,12 @@ namespace SHADE
command += " " + path.string();
std::system(command.c_str());
std::string newPath = path.string().substr(0, path.string().find_last_of('.'));
newPath += MESH_EXTENSION;
newAsset.path = newPath;
newAsset.id = GenerateAssetID(AssetType::MESH);
newAsset.type = AssetType::MESH;
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
modelPath += MODEL_EXTENSION;
newPath = modelPath;
}
assetCollection.insert({ newAsset.id, newAsset });
SHAssetMetaHandler::WriteMetaData(newAsset);
GenerateNewMeta(newPath);
}
}
@ -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_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::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::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::MESH)] = nullptr;
}
/****************************************************************************
@ -453,9 +452,9 @@ namespace SHADE
****************************************************************************/
void SHAssetManager::Load() noexcept
{
//CompileAll();
BuildAssetCollection();
InitLoaders();
//CompileAll();
//LoadAllData();
}
@ -473,8 +472,12 @@ namespace SHADE
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)
{
SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string());
@ -487,13 +490,120 @@ namespace SHADE
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
{
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<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
static AssetID CompileAsset(AssetPath const& path) noexcept;
static void CompileAsset(AssetPath const& path) noexcept;
static FolderPointer GetRootFolder() noexcept;
@ -96,7 +96,10 @@ namespace SHADE
static void InitLoaders() noexcept;
static void LoadAllData() 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;
static bool IsRecognised(char const*) noexcept;

View File

@ -9,7 +9,6 @@
******************************************************************************/
#include "SHpch.h"
#include "SHAssetMetaHandler.h"
#include <fstream>
#include <sstream>
namespace SHADE
@ -21,11 +20,15 @@ namespace SHADE
* \brief Helper function to retrieve field value from meta data file
* for processing
****************************************************************************/
void GetFieldValue(std::ifstream& file, std::string& line) noexcept
bool GetFieldValue(std::ifstream& file, std::string& line) noexcept
{
line = "";
std::getline(file, line);
if (std::getline(file, line))
{
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 };
if (!metaFile.is_open())
{
// Error unable to open
SHLOG_ERROR("Unable to open meta file: {}", path.string());
return {};
}
std::string line;
@ -93,6 +97,43 @@ namespace SHADE
typeStream >> 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();
meta.path = path.parent_path().string() + "/" + path.stem().string();
@ -108,6 +149,12 @@ namespace SHADE
****************************************************************************/
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
{
if (meta.isSubAsset)
{
SHLOG_WARNING("Cannot write subasset meta: {}", meta.name);
return;
}
//TODO: Write into binary eventually
std::string path{ meta.path.string() };
path.append(META_EXTENSION);
@ -124,7 +171,23 @@ namespace SHADE
metaFile << "ID: " << meta.id << "\n";
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();
}
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 "SHAsset.h"
#include <fstream>
namespace SHADE
{
@ -45,6 +46,8 @@ namespace SHADE
* \brief Writes meta data into text file
****************************************************************************/
static void WriteMetaData(SHAsset const&) noexcept;
static void WriteSubAssetMeta(std::ofstream&, SHAsset const&) noexcept;
};
}