summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoCommon/Assets/CustomAssetLibrary.h4
-rw-r--r--Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp6
-rw-r--r--Source/Core/VideoCommon/Assets/CustomAssetLoader.h5
-rw-r--r--Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp107
-rw-r--r--Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h1
-rw-r--r--Source/Core/VideoCommon/Assets/MeshAsset.cpp15
-rw-r--r--Source/Core/VideoCommon/Assets/MeshAsset.h9
7 files changed, 147 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h b/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h
index 78cea9a3e9..b4831ea650 100644
--- a/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h
+++ b/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h
@@ -11,6 +11,7 @@
namespace VideoCommon
{
struct MaterialData;
+struct MeshData;
struct PixelShaderData;
struct TextureData;
@@ -48,5 +49,8 @@ public:
// Loads a material
virtual LoadInfo LoadMaterial(const AssetID& asset_id, MaterialData* data) = 0;
+
+ // Loads a mesh
+ virtual LoadInfo LoadMesh(const AssetID& asset_id, MeshData* data) = 0;
};
} // namespace VideoCommon
diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp b/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp
index 134b18b496..dfe640ffe8 100644
--- a/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp
+++ b/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp
@@ -97,4 +97,10 @@ CustomAssetLoader::LoadMaterial(const CustomAssetLibrary::AssetID& asset_id,
{
return LoadOrCreateAsset<MaterialAsset>(asset_id, m_materials, std::move(library));
}
+
+std::shared_ptr<MeshAsset> CustomAssetLoader::LoadMesh(const CustomAssetLibrary::AssetID& asset_id,
+ std::shared_ptr<CustomAssetLibrary> library)
+{
+ return LoadOrCreateAsset<MeshAsset>(asset_id, m_meshes, std::move(library));
+}
} // namespace VideoCommon
diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLoader.h b/Source/Core/VideoCommon/Assets/CustomAssetLoader.h
index 920f62e830..7ddb746ca6 100644
--- a/Source/Core/VideoCommon/Assets/CustomAssetLoader.h
+++ b/Source/Core/VideoCommon/Assets/CustomAssetLoader.h
@@ -13,6 +13,7 @@
#include "Common/WorkQueueThread.h"
#include "VideoCommon/Assets/CustomAsset.h"
#include "VideoCommon/Assets/MaterialAsset.h"
+#include "VideoCommon/Assets/MeshAsset.h"
#include "VideoCommon/Assets/ShaderAsset.h"
#include "VideoCommon/Assets/TextureAsset.h"
@@ -47,6 +48,9 @@ public:
std::shared_ptr<MaterialAsset> LoadMaterial(const CustomAssetLibrary::AssetID& asset_id,
std::shared_ptr<CustomAssetLibrary> library);
+ std::shared_ptr<MeshAsset> LoadMesh(const CustomAssetLibrary::AssetID& asset_id,
+ std::shared_ptr<CustomAssetLibrary> library);
+
private:
// TODO C++20: use a 'derived_from' concept against 'CustomAsset' when available
template <typename AssetType>
@@ -80,6 +84,7 @@ private:
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<GameTextureAsset>> m_game_textures;
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<PixelShaderAsset>> m_pixel_shaders;
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<MaterialAsset>> m_materials;
+ std::map<CustomAssetLibrary::AssetID, std::weak_ptr<MeshAsset>> m_meshes;
std::thread m_asset_monitor_thread;
Common::Flag m_asset_monitor_thread_shutdown;
diff --git a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp
index ff20d117c2..be5159b448 100644
--- a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp
+++ b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp
@@ -4,13 +4,16 @@
#include "VideoCommon/Assets/DirectFilesystemAssetLibrary.h"
#include <algorithm>
+#include <vector>
#include <fmt/std.h>
#include "Common/FileUtil.h"
+#include "Common/IOFile.h"
#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
#include "VideoCommon/Assets/MaterialAsset.h"
+#include "VideoCommon/Assets/MeshAsset.h"
#include "VideoCommon/Assets/ShaderAsset.h"
#include "VideoCommon/Assets/TextureAsset.h"
#include "VideoCommon/RenderState.h"
@@ -220,6 +223,110 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadMaterial(const As
return LoadInfo{json_data.size(), GetLastAssetWriteTime(asset_id)};
}
+CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadMesh(const AssetID& asset_id,
+ MeshData* data)
+{
+ const auto asset_map = GetAssetMapForID(asset_id);
+
+ // Asset map for a mesh is the mesh and some metadata
+ if (asset_map.size() != 2)
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' expected to have two files mapped!", asset_id);
+ return {};
+ }
+
+ const auto metadata = asset_map.find("metadata");
+ const auto mesh = asset_map.find("mesh");
+ if (metadata == asset_map.end())
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' expected to have a metadata entry mapped!", asset_id);
+ return {};
+ }
+
+ if (mesh == asset_map.end())
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' expected to have a mesh entry mapped!", asset_id);
+ return {};
+ }
+
+ std::size_t metadata_size;
+ {
+ std::error_code ec;
+ metadata_size = std::filesystem::file_size(metadata->second, ec);
+ if (ec)
+ {
+ ERROR_LOG_FMT(VIDEO,
+ "Asset '{}' error - failed to get mesh metadata file size with error '{}'!",
+ asset_id, ec);
+ return {};
+ }
+ }
+ std::size_t mesh_size;
+ {
+ std::error_code ec;
+ mesh_size = std::filesystem::file_size(mesh->second, ec);
+ if (ec)
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to get mesh file size with error '{}'!",
+ asset_id, ec);
+ return {};
+ }
+ }
+ const auto approx_mem_size = metadata_size + mesh_size;
+
+ File::IOFile file(PathToString(mesh->second), "rb");
+ if (!file.IsOpen())
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to open mesh file '{}'!", asset_id,
+ PathToString(mesh->second));
+ return {};
+ }
+
+ std::vector<u8> bytes;
+ bytes.reserve(file.GetSize());
+ file.ReadBytes(bytes.data(), file.GetSize());
+ if (!MeshData::FromDolphinMesh(bytes, data))
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to load the mesh file '{}'!", asset_id,
+ PathToString(mesh->second));
+ return {};
+ }
+
+ std::string json_data;
+ if (!File::ReadFileToString(PathToString(metadata->second), json_data))
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to load the json file '{}'!", asset_id,
+ PathToString(metadata->second));
+ return {};
+ }
+
+ picojson::value root;
+ const auto error = picojson::parse(root, json_data);
+
+ if (!error.empty())
+ {
+ ERROR_LOG_FMT(VIDEO,
+ "Asset '{}' error - failed to load the json file '{}', due to parse error: {}",
+ asset_id, PathToString(metadata->second), error);
+ return {};
+ }
+ if (!root.is<picojson::object>())
+ {
+ ERROR_LOG_FMT(
+ VIDEO,
+ "Asset '{}' error - failed to load the json file '{}', due to root not being an object!",
+ asset_id, PathToString(metadata->second));
+ return {};
+ }
+
+ const auto& root_obj = root.get<picojson::object>();
+
+ if (!MeshData::FromJson(asset_id, root_obj, data))
+ return {};
+
+ return LoadInfo{approx_mem_size, GetLastAssetWriteTime(asset_id)};
+}
+
CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const AssetID& asset_id,
TextureData* data)
{
diff --git a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h
index 244b49c88b..c4d99baf82 100644
--- a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h
+++ b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h
@@ -23,6 +23,7 @@ public:
LoadInfo LoadTexture(const AssetID& asset_id, TextureData* data) override;
LoadInfo LoadPixelShader(const AssetID& asset_id, PixelShaderData* data) override;
LoadInfo LoadMaterial(const AssetID& asset_id, MaterialData* data) override;
+ LoadInfo LoadMesh(const AssetID& asset_id, MeshData* data) override;
// Gets the latest time from amongst all the files in the asset map
TimeType GetLastAssetWriteTime(const AssetID& asset_id) const override;
diff --git a/Source/Core/VideoCommon/Assets/MeshAsset.cpp b/Source/Core/VideoCommon/Assets/MeshAsset.cpp
index b8dd029375..05a4ba0961 100644
--- a/Source/Core/VideoCommon/Assets/MeshAsset.cpp
+++ b/Source/Core/VideoCommon/Assets/MeshAsset.cpp
@@ -12,6 +12,7 @@
#include "Common/IOFile.h"
#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
+#include "VideoCommon/Assets/CustomAssetLibrary.h"
namespace VideoCommon
{
@@ -645,4 +646,18 @@ bool MeshData::FromGLTF(std::string_view gltf_file, MeshData* data)
ERROR_LOG_FMT(VIDEO, "GLTF '{}' has invalid extension", gltf_file);
return false;
}
+
+CustomAssetLibrary::LoadInfo MeshAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id)
+{
+ auto potential_data = std::make_shared<MeshData>();
+ const auto loaded_info = m_owning_library->LoadMesh(asset_id, potential_data.get());
+ if (loaded_info.m_bytes_loaded == 0)
+ return {};
+ {
+ std::lock_guard lk(m_data_lock);
+ m_loaded = true;
+ m_data = std::move(potential_data);
+ }
+ return loaded_info;
+}
} // namespace VideoCommon
diff --git a/Source/Core/VideoCommon/Assets/MeshAsset.h b/Source/Core/VideoCommon/Assets/MeshAsset.h
index eb23f39783..a678b14cee 100644
--- a/Source/Core/VideoCommon/Assets/MeshAsset.h
+++ b/Source/Core/VideoCommon/Assets/MeshAsset.h
@@ -57,4 +57,13 @@ struct MeshData
std::map<std::string, CustomAssetLibrary::AssetID, std::less<>>
m_mesh_material_to_material_asset_id;
};
+
+class MeshAsset final : public CustomLoadableAsset<MeshData>
+{
+public:
+ using CustomLoadableAsset::CustomLoadableAsset;
+
+private:
+ CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override;
+};
} // namespace VideoCommon