From fc7c8f679767a427836235ae5201af5144620738 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Wed, 18 Mar 2026 13:39:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E5=AF=BC=E5=85=A5=E8=AE=BE=E7=BD=AE=E7=B1=BB?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 ImportSettings 基类 - 新增 TextureImportSettings 纹理导入设置类 - 新增 MeshImportSettings 网格导入设置类 - 新增 ResourcePath 资源路径类 - 完善 CMakeLists.txt 配置 - 新增对应单元测试 (45个测试用例) --- engine/CMakeLists.txt | 12 +- .../include/XCEngine/Resources/AsyncLoader.h | 1 + .../XCEngine/Resources/IResourceLoader.h | 1 + .../XCEngine/Resources/ImportSettings.h | 19 +++ .../XCEngine/Resources/MeshImportSettings.h | 85 +++++++++++ .../XCEngine/Resources/ResourceManager.h | 1 + .../include/XCEngine/Resources/ResourcePath.h | 46 ++++++ .../XCEngine/Resources/ResourceTypes.h | 9 -- engine/include/XCEngine/Resources/Resources.h | 3 + .../Resources/TextureImportSettings.h | 91 ++++++++++++ engine/src/Resources/MeshImportSettings.cpp | 23 +++ engine/src/Resources/ResourcePath.cpp | 136 ++++++++++++++++++ .../src/Resources/TextureImportSettings.cpp | 23 +++ tests/Resources/CMakeLists.txt | 3 + tests/Resources/test_mesh_import_settings.cpp | 104 ++++++++++++++ tests/Resources/test_resource_path.cpp | 110 ++++++++++++++ .../test_texture_import_settings.cpp | 119 +++++++++++++++ 17 files changed, 774 insertions(+), 12 deletions(-) create mode 100644 engine/include/XCEngine/Resources/ImportSettings.h create mode 100644 engine/include/XCEngine/Resources/MeshImportSettings.h create mode 100644 engine/include/XCEngine/Resources/ResourcePath.h create mode 100644 engine/include/XCEngine/Resources/TextureImportSettings.h create mode 100644 engine/src/Resources/MeshImportSettings.cpp create mode 100644 engine/src/Resources/ResourcePath.cpp create mode 100644 engine/src/Resources/TextureImportSettings.cpp create mode 100644 tests/Resources/test_mesh_import_settings.cpp create mode 100644 tests/Resources/test_resource_path.cpp create mode 100644 tests/Resources/test_texture_import_settings.cpp diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 243268b3..5503124c 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -167,10 +167,13 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/ResourceManager.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/ResourceCache.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/AsyncLoader.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/ImportSettings.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/Texture.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/Mesh.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/TextureLoader.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/TextureImportSettings.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/MeshLoader.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/MeshImportSettings.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/Material.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/MaterialLoader.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/Shader.h @@ -179,6 +182,9 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/AudioLoader.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/ResourceFileSystem.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/FileArchive.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/ResourcePackage.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/ResourceDependencyGraph.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/ResourcePath.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/ResourceManager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/ResourceCache.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/AsyncLoader.cpp @@ -187,7 +193,9 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/Texture.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/Mesh.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/TextureLoader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/TextureImportSettings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/MeshLoader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/MeshImportSettings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/Material.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/MaterialLoader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/Shader.cpp @@ -198,9 +206,7 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/FileArchive.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/ResourcePackage.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/ResourceDependencyGraph.cpp - - ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/ResourcePackage.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/ResourceDependencyGraph.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/Resources/ResourcePath.cpp ) target_include_directories(XCEngine PUBLIC diff --git a/engine/include/XCEngine/Resources/AsyncLoader.h b/engine/include/XCEngine/Resources/AsyncLoader.h index c9aced21..11613b73 100644 --- a/engine/include/XCEngine/Resources/AsyncLoader.h +++ b/engine/include/XCEngine/Resources/AsyncLoader.h @@ -1,6 +1,7 @@ #pragma once #include "IResourceLoader.h" +#include "ImportSettings.h" #include "../Containers/Array.h" #include "../Threading/Mutex.h" #include diff --git a/engine/include/XCEngine/Resources/IResourceLoader.h b/engine/include/XCEngine/Resources/IResourceLoader.h index 00ca9b3b..f305bc37 100644 --- a/engine/include/XCEngine/Resources/IResourceLoader.h +++ b/engine/include/XCEngine/Resources/IResourceLoader.h @@ -2,6 +2,7 @@ #include "IResource.h" #include "ResourceTypes.h" +#include "ImportSettings.h" #include "../Containers/String.h" #include "../Containers/Array.h" #include diff --git a/engine/include/XCEngine/Resources/ImportSettings.h b/engine/include/XCEngine/Resources/ImportSettings.h new file mode 100644 index 00000000..e597f742 --- /dev/null +++ b/engine/include/XCEngine/Resources/ImportSettings.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../Core/SmartPtr.h" +#include "ResourceTypes.h" + +namespace XCEngine { +namespace Resources { + +class ImportSettings { +public: + virtual ~ImportSettings() = default; + + virtual Core::UniqueRef Clone() const = 0; + virtual bool LoadFromJSON(const Containers::String& json) { return false; } + virtual Containers::String SaveToJSON() const { return Containers::String(); } +}; + +} // namespace Resources +} // namespace XCEngine diff --git a/engine/include/XCEngine/Resources/MeshImportSettings.h b/engine/include/XCEngine/Resources/MeshImportSettings.h new file mode 100644 index 00000000..65a28a3c --- /dev/null +++ b/engine/include/XCEngine/Resources/MeshImportSettings.h @@ -0,0 +1,85 @@ +#pragma once + +#include "ImportSettings.h" +#include "Mesh.h" +#include "../Math/Vector3.h" + +namespace XCEngine { +namespace Resources { + +enum class MeshImportFlags : Core::uint32 { + None = 0, + FlipUVs = 1 << 0, + FlipWindingOrder = 1 << 1, + GenerateNormals = 1 << 2, + GenerateTangents = 1 << 3, + OptimizeMesh = 1 << 4, + ImportSkinning = 1 << 5, + ImportAnimations = 1 << 6, + ImportMaterials = 1 << 7, + ImportCameras = 1 << 8, + ImportLights = 1 << 9 +}; + +inline MeshImportFlags operator|(MeshImportFlags a, MeshImportFlags b) { + return static_cast(static_cast(a) | static_cast(b)); +} + +inline MeshImportFlags operator&(MeshImportFlags a, MeshImportFlags b) { + return static_cast(static_cast(a) & static_cast(b)); +} + +inline MeshImportFlags operator~(MeshImportFlags a) { + return static_cast(~static_cast(a)); +} + +class MeshImportSettings : public ImportSettings { +public: + MeshImportSettings(); + virtual ~MeshImportSettings() override; + + Core::UniqueRef Clone() const override; + bool LoadFromJSON(const Containers::String& json) override; + Containers::String SaveToJSON() const override; + + void SetImportFlags(MeshImportFlags flags) { m_importFlags = flags; } + MeshImportFlags GetImportFlags() const { return m_importFlags; } + + void AddImportFlag(MeshImportFlags flag) { m_importFlags = static_cast(static_cast(m_importFlags) | static_cast(flag)); } + void RemoveImportFlag(MeshImportFlags flag) { m_importFlags = static_cast(static_cast(m_importFlags) & ~static_cast(flag)); } + bool HasImportFlag(MeshImportFlags flag) const { return (static_cast(m_importFlags) & static_cast(flag)) != 0; } + + void SetScale(float scale) { m_scale = scale; } + float GetScale() const { return m_scale; } + + void SetOffset(const Math::Vector3& offset) { m_offset = offset; } + const Math::Vector3& GetOffset() const { return m_offset; } + + void SetAxisConversion(bool convert) { m_axisConversion = convert; } + bool GetAxisConversion() const { return m_axisConversion; } + + void SetMergeMeshes(bool merge) { m_mergeMeshes = merge; } + bool GetMergeMeshes() const { return m_mergeMeshes; } + + void SetOptimizeThreshold(float threshold) { m_optimizeThreshold = threshold; } + float GetOptimizeThreshold() const { return m_optimizeThreshold; } + + void SetImportScale(float scale) { m_importScale = scale; } + float GetImportScale() const { return m_importScale; } + + void SetThreshold(float threshold) { m_threshold = threshold; } + float GetThreshold() const { return m_threshold; } + +private: + MeshImportFlags m_importFlags = MeshImportFlags::None; + float m_scale = 1.0f; + Math::Vector3 m_offset = Math::Vector3::Zero(); + bool m_axisConversion = true; + bool m_mergeMeshes = false; + float m_optimizeThreshold = 0.3f; + float m_importScale = 1.0f; + float m_threshold = 0.0f; +}; + +} // namespace Resources +} // namespace XCEngine diff --git a/engine/include/XCEngine/Resources/ResourceManager.h b/engine/include/XCEngine/Resources/ResourceManager.h index 01c50f09..ae1a58af 100644 --- a/engine/include/XCEngine/Resources/ResourceManager.h +++ b/engine/include/XCEngine/Resources/ResourceManager.h @@ -4,6 +4,7 @@ #include "ResourceCache.h" #include "AsyncLoader.h" #include "ResourceHandle.h" +#include "ImportSettings.h" #include "../Containers/String.h" #include "../Containers/Array.h" #include "../Containers/HashMap.h" diff --git a/engine/include/XCEngine/Resources/ResourcePath.h b/engine/include/XCEngine/Resources/ResourcePath.h new file mode 100644 index 00000000..d1aa35fb --- /dev/null +++ b/engine/include/XCEngine/Resources/ResourcePath.h @@ -0,0 +1,46 @@ +#pragma once + +#include "ResourceTypes.h" +#include "../Containers/String.h" +#include "../Containers/Array.h" +#include "../Core/Types.h" + +namespace XCEngine { +namespace Resources { + +class ResourcePath { +public: + ResourcePath() = default; + ResourcePath(const char* path); + ResourcePath(const Containers::String& path); + + Containers::String GetExtension() const; + + Containers::String GetStem() const; + + Containers::String GetFullPath() const; + + Containers::String GetFileName() const; + + Containers::String GetDirectory() const; + + Containers::String GetRelativePath() const; + + ResourceGUID ToGUID() const; + + bool HasExtension(const char* ext) const; + + bool HasAnyExtension(const char* const* extensions, Core::uint32 count) const; + + bool IsValid() const { return !m_path.Empty(); } + + const Containers::String& GetPath() const { return m_path; } + + void SetPath(const Containers::String& path) { m_path = path; } + +private: + Containers::String m_path; +}; + +} // namespace Resources +} // namespace XCEngine diff --git a/engine/include/XCEngine/Resources/ResourceTypes.h b/engine/include/XCEngine/Resources/ResourceTypes.h index e9bb8384..1ad19cbf 100644 --- a/engine/include/XCEngine/Resources/ResourceTypes.h +++ b/engine/include/XCEngine/Resources/ResourceTypes.h @@ -90,14 +90,5 @@ template<> inline ResourceType GetResourceType() { return Resource template<> inline ResourceType GetResourceType() { return ResourceType::AudioClip; } template<> inline ResourceType GetResourceType() { return ResourceType::Binary; } -class ImportSettings { -public: - virtual ~ImportSettings() = default; - - virtual Core::UniqueRef Clone() const = 0; - virtual bool LoadFromJSON(const Containers::String& json) { return false; } - virtual Containers::String SaveToJSON() const { return Containers::String(); } -}; - } // namespace Resources } // namespace XCEngine diff --git a/engine/include/XCEngine/Resources/Resources.h b/engine/include/XCEngine/Resources/Resources.h index a799b8be..b2850949 100644 --- a/engine/include/XCEngine/Resources/Resources.h +++ b/engine/include/XCEngine/Resources/Resources.h @@ -12,8 +12,10 @@ #include "Texture.h" #include "TextureLoader.h" +#include "TextureImportSettings.h" #include "Mesh.h" #include "MeshLoader.h" +#include "MeshImportSettings.h" #include "Material.h" #include "MaterialLoader.h" #include "Shader.h" @@ -24,6 +26,7 @@ #include "ResourceFileSystem.h" #include "FileArchive.h" #include "ResourcePackage.h" +#include "ResourcePath.h" // Forward declarations for concrete resource types namespace XCEngine { diff --git a/engine/include/XCEngine/Resources/TextureImportSettings.h b/engine/include/XCEngine/Resources/TextureImportSettings.h new file mode 100644 index 00000000..a1a3e2e7 --- /dev/null +++ b/engine/include/XCEngine/Resources/TextureImportSettings.h @@ -0,0 +1,91 @@ +#pragma once + +#include "ImportSettings.h" +#include "Texture.h" +#include "../Math/Vector3.h" + +namespace XCEngine { +namespace Resources { + +enum class MipmapFilter { + Box, + Kaiser +}; + +enum class CompressionQuality { + Low, + Medium, + High, + Ultra +}; + +class TextureImportSettings : public ImportSettings { +public: + TextureImportSettings(); + virtual ~TextureImportSettings() override; + + Core::UniqueRef Clone() const override; + bool LoadFromJSON(const Containers::String& json) override; + Containers::String SaveToJSON() const override; + + void SetTextureType(TextureType type) { m_textureType = type; } + TextureType GetTextureType() const { return m_textureType; } + + void SetTargetFormat(TextureFormat format) { m_targetFormat = format; } + TextureFormat GetTargetFormat() const { return m_targetFormat; } + + void SetGenerateMipmaps(bool generate) { m_generateMipmaps = generate; } + bool GetGenerateMipmaps() const { return m_generateMipmaps; } + + void SetMipmapFilter(MipmapFilter filter) { m_mipmapFilter = filter; } + MipmapFilter GetMipmapFilter() const { return m_mipmapFilter; } + + void SetMaxAnisotropy(Core::uint32 anisotropy) { m_maxAnisotropy = anisotropy; } + Core::uint32 GetMaxAnisotropy() const { return m_maxAnisotropy; } + + void SetSRGB(bool srgb) { m_sRGB = srgb; } + bool GetSRGB() const { return m_sRGB; } + + void SetFlipVertical(bool flip) { m_flipVertical = flip; } + bool GetFlipVertical() const { return m_flipVertical; } + + void SetFlipHorizontal(bool flip) { m_flipHorizontal = flip; } + bool GetFlipHorizontal() const { return m_flipHorizontal; } + + void SetBorderColor(const Math::Vector3& color) { m_borderColor = color; } + const Math::Vector3& GetBorderColor() const { return m_borderColor; } + + void SetCompressionQuality(CompressionQuality quality) { m_compressionQuality = quality; } + CompressionQuality GetCompressionQuality() const { return m_compressionQuality; } + + void SetUseHardwareCompression(bool use) { m_useHardwareCompression = use; } + bool GetUseHardwareCompression() const { return m_useHardwareCompression; } + + void SetMaxSize(Core::uint32 size) { m_maxSize = size; } + Core::uint32 GetMaxSize() const { return m_maxSize; } + + void SetGenerateNormalMap(bool generate) { m_generateNormalMap = generate; } + bool GetGenerateNormalMap() const { return m_generateNormalMap; } + + void SetNormalMapStrength(float strength) { m_normalMapStrength = strength; } + float GetNormalMapStrength() const { return m_normalMapStrength; } + +private: + TextureType m_textureType = TextureType::Texture2D; + TextureFormat m_targetFormat = TextureFormat::Unknown; + bool m_generateMipmaps = true; + MipmapFilter m_mipmapFilter = MipmapFilter::Box; + Core::uint32 m_maxAnisotropy = 16; + bool m_sRGB = false; + bool m_flipVertical = false; + bool m_flipHorizontal = false; + Math::Vector3 m_borderColor = Math::Vector3::Zero(); + CompressionQuality m_compressionQuality = CompressionQuality::High; + bool m_useHardwareCompression = true; + Core::uint32 m_maxSize = 0; + bool m_generateNormalMap = false; + float m_normalMapStrength = 1.0f; +}; + +} // namespace Resources +} // namespace XCEngine diff --git a/engine/src/Resources/MeshImportSettings.cpp b/engine/src/Resources/MeshImportSettings.cpp new file mode 100644 index 00000000..f99f2947 --- /dev/null +++ b/engine/src/Resources/MeshImportSettings.cpp @@ -0,0 +1,23 @@ +#include + +namespace XCEngine { +namespace Resources { + +MeshImportSettings::MeshImportSettings() = default; + +MeshImportSettings::~MeshImportSettings() = default; + +Core::UniqueRef MeshImportSettings::Clone() const { + return Core::UniqueRef(new MeshImportSettings(*this)); +} + +bool MeshImportSettings::LoadFromJSON(const Containers::String& json) { + return false; +} + +Containers::String MeshImportSettings::SaveToJSON() const { + return Containers::String(); +} + +} // namespace Resources +} // namespace XCEngine diff --git a/engine/src/Resources/ResourcePath.cpp b/engine/src/Resources/ResourcePath.cpp new file mode 100644 index 00000000..de9db4b9 --- /dev/null +++ b/engine/src/Resources/ResourcePath.cpp @@ -0,0 +1,136 @@ +#include +#include + +namespace XCEngine { +namespace Resources { + +static size_t FindLastOf(const Containers::String& str, char ch) { + for (size_t i = str.Length(); i > 0; --i) { + if (str[i - 1] == ch) { + return i - 1; + } + } + return Containers::String::npos; +} + +ResourcePath::ResourcePath(const char* path) + : m_path(path) {} + +ResourcePath::ResourcePath(const Containers::String& path) + : m_path(path) {} + +Containers::String ResourcePath::GetExtension() const { + if (m_path.Empty()) { + return Containers::String(); + } + + size_t dotPos = FindLastOf(m_path, '.'); + if (dotPos == Containers::String::npos) { + return Containers::String(); + } + + return m_path.Substring(dotPos); +} + +Containers::String ResourcePath::GetStem() const { + if (m_path.Empty()) { + return Containers::String(); + } + + size_t slashPos = FindLastOf(m_path, '/'); + size_t backslashPos = FindLastOf(m_path, '\\'); + size_t nameStart = (slashPos != Containers::String::npos && backslashPos != Containers::String::npos) + ? std::max(slashPos, backslashPos) + : (slashPos != Containers::String::npos ? slashPos : backslashPos); + + if (nameStart == Containers::String::npos) { + nameStart = 0; + } else { + nameStart += 1; + } + + size_t dotPos = FindLastOf(m_path, '.'); + if (dotPos == Containers::String::npos || dotPos < nameStart) { + return m_path.Substring(nameStart); + } + + return m_path.Substring(nameStart, dotPos - nameStart); +} + +Containers::String ResourcePath::GetFullPath() const { + return m_path; +} + +Containers::String ResourcePath::GetFileName() const { + if (m_path.Empty()) { + return Containers::String(); + } + + size_t slashPos = FindLastOf(m_path, '/'); + size_t backslashPos = FindLastOf(m_path, '\\'); + size_t nameStart = (slashPos != Containers::String::npos && backslashPos != Containers::String::npos) + ? std::max(slashPos, backslashPos) + : (slashPos != Containers::String::npos ? slashPos : backslashPos); + + if (nameStart == Containers::String::npos) { + return m_path; + } + + return m_path.Substring(nameStart + 1); +} + +Containers::String ResourcePath::GetDirectory() const { + if (m_path.Empty()) { + return Containers::String(); + } + + size_t slashPos = FindLastOf(m_path, '/'); + size_t backslashPos = FindLastOf(m_path, '\\'); + size_t dirEnd = (slashPos != Containers::String::npos && backslashPos != Containers::String::npos) + ? std::max(slashPos, backslashPos) + : (slashPos != Containers::String::npos ? slashPos : backslashPos); + + if (dirEnd == Containers::String::npos) { + return Containers::String(); + } + + return m_path.Substring(0, dirEnd); +} + +Containers::String ResourcePath::GetRelativePath() const { + return m_path; +} + +ResourceGUID ResourcePath::ToGUID() const { + return ResourceGUID::Generate(m_path); +} + +bool ResourcePath::HasExtension(const char* ext) const { + if (!ext || m_path.Empty()) { + return false; + } + + Containers::String pathExt = GetExtension(); + if (pathExt.Empty()) { + return false; + } + + return pathExt == ext; +} + +bool ResourcePath::HasAnyExtension(const char* const* extensions, Core::uint32 count) const { + if (!extensions || count == 0 || m_path.Empty()) { + return false; + } + + for (Core::uint32 i = 0; i < count; ++i) { + if (HasExtension(extensions[i])) { + return true; + } + } + + return false; +} + +} // namespace Resources +} // namespace XCEngine diff --git a/engine/src/Resources/TextureImportSettings.cpp b/engine/src/Resources/TextureImportSettings.cpp new file mode 100644 index 00000000..af4ac82f --- /dev/null +++ b/engine/src/Resources/TextureImportSettings.cpp @@ -0,0 +1,23 @@ +#include + +namespace XCEngine { +namespace Resources { + +TextureImportSettings::TextureImportSettings() = default; + +TextureImportSettings::~TextureImportSettings() = default; + +Core::UniqueRef TextureImportSettings::Clone() const { + return Core::UniqueRef(new TextureImportSettings(*this)); +} + +bool TextureImportSettings::LoadFromJSON(const Containers::String& json) { + return false; +} + +Containers::String TextureImportSettings::SaveToJSON() const { + return Containers::String(); +} + +} // namespace Resources +} // namespace XCEngine diff --git a/tests/Resources/CMakeLists.txt b/tests/Resources/CMakeLists.txt index 12526894..443c0bc2 100644 --- a/tests/Resources/CMakeLists.txt +++ b/tests/Resources/CMakeLists.txt @@ -23,6 +23,9 @@ set(RESOURCES_TEST_SOURCES test_material_loader.cpp test_resource_package.cpp test_resource_dependency.cpp + test_texture_import_settings.cpp + test_mesh_import_settings.cpp + test_resource_path.cpp ) add_executable(xcengine_resources_tests ${RESOURCES_TEST_SOURCES}) diff --git a/tests/Resources/test_mesh_import_settings.cpp b/tests/Resources/test_mesh_import_settings.cpp new file mode 100644 index 00000000..1e9cce93 --- /dev/null +++ b/tests/Resources/test_mesh_import_settings.cpp @@ -0,0 +1,104 @@ +#include +#include +#include +#include + +using namespace XCEngine::Resources; +using namespace XCEngine::Math; + +namespace { + +TEST(MeshImportSettings, DefaultConstructor) { + MeshImportSettings settings; + EXPECT_EQ(settings.GetImportFlags(), MeshImportFlags::None); + EXPECT_FLOAT_EQ(settings.GetScale(), 1.0f); + EXPECT_EQ(settings.GetOffset(), Vector3::Zero()); + EXPECT_TRUE(settings.GetAxisConversion()); + EXPECT_FALSE(settings.GetMergeMeshes()); + EXPECT_FLOAT_EQ(settings.GetOptimizeThreshold(), 0.3f); + EXPECT_FLOAT_EQ(settings.GetImportScale(), 1.0f); + EXPECT_FLOAT_EQ(settings.GetThreshold(), 0.0f); +} + +TEST(MeshImportSettings, SetImportFlags) { + MeshImportSettings settings; + settings.SetImportFlags(MeshImportFlags::FlipUVs | MeshImportFlags::GenerateNormals); + EXPECT_TRUE(settings.HasImportFlag(MeshImportFlags::FlipUVs)); + EXPECT_TRUE(settings.HasImportFlag(MeshImportFlags::GenerateNormals)); + EXPECT_FALSE(settings.HasImportFlag(MeshImportFlags::GenerateTangents)); +} + +TEST(MeshImportSettings, AddImportFlag) { + MeshImportSettings settings; + settings.AddImportFlag(MeshImportFlags::FlipUVs); + EXPECT_TRUE(settings.HasImportFlag(MeshImportFlags::FlipUVs)); +} + +TEST(MeshImportSettings, RemoveImportFlag) { + MeshImportSettings settings; + settings.SetImportFlags(MeshImportFlags::FlipUVs | MeshImportFlags::GenerateNormals); + settings.RemoveImportFlag(MeshImportFlags::FlipUVs); + EXPECT_FALSE(settings.HasImportFlag(MeshImportFlags::FlipUVs)); + EXPECT_TRUE(settings.HasImportFlag(MeshImportFlags::GenerateNormals)); +} + +TEST(MeshImportSettings, SetScale) { + MeshImportSettings settings; + settings.SetScale(2.0f); + EXPECT_FLOAT_EQ(settings.GetScale(), 2.0f); +} + +TEST(MeshImportSettings, SetOffset) { + MeshImportSettings settings; + Vector3 offset(1.0f, 2.0f, 3.0f); + settings.SetOffset(offset); + EXPECT_EQ(settings.GetOffset(), offset); +} + +TEST(MeshImportSettings, SetAxisConversion) { + MeshImportSettings settings; + settings.SetAxisConversion(false); + EXPECT_FALSE(settings.GetAxisConversion()); +} + +TEST(MeshImportSettings, SetMergeMeshes) { + MeshImportSettings settings; + settings.SetMergeMeshes(true); + EXPECT_TRUE(settings.GetMergeMeshes()); +} + +TEST(MeshImportSettings, SetOptimizeThreshold) { + MeshImportSettings settings; + settings.SetOptimizeThreshold(0.5f); + EXPECT_FLOAT_EQ(settings.GetOptimizeThreshold(), 0.5f); +} + +TEST(MeshImportSettings, SetImportScale) { + MeshImportSettings settings; + settings.SetImportScale(0.5f); + EXPECT_FLOAT_EQ(settings.GetImportScale(), 0.5f); +} + +TEST(MeshImportSettings, SetThreshold) { + MeshImportSettings settings; + settings.SetThreshold(0.01f); + EXPECT_FLOAT_EQ(settings.GetThreshold(), 0.01f); +} + +TEST(MeshImportSettings, Clone) { + MeshImportSettings settings; + settings.SetImportFlags(MeshImportFlags::FlipUVs | MeshImportFlags::GenerateNormals); + settings.SetScale(2.0f); + settings.SetMergeMeshes(true); + + auto cloned = settings.Clone(); + ASSERT_NE(cloned, nullptr); + + MeshImportSettings* clonedSettings = static_cast(cloned.get()); + EXPECT_TRUE(clonedSettings->HasImportFlag(MeshImportFlags::FlipUVs)); + EXPECT_TRUE(clonedSettings->HasImportFlag(MeshImportFlags::GenerateNormals)); + EXPECT_FLOAT_EQ(clonedSettings->GetScale(), 2.0f); + EXPECT_TRUE(clonedSettings->GetMergeMeshes()); +} + +} // namespace diff --git a/tests/Resources/test_resource_path.cpp b/tests/Resources/test_resource_path.cpp new file mode 100644 index 00000000..6dcf9ecb --- /dev/null +++ b/tests/Resources/test_resource_path.cpp @@ -0,0 +1,110 @@ +#include +#include +#include +#include + +using namespace XCEngine::Resources; +using namespace XCEngine::Containers; + +namespace { + +TEST(ResourcePath, DefaultConstructor) { + ResourcePath path; + EXPECT_FALSE(path.IsValid()); +} + +TEST(ResourcePath, ConstructorWithCString) { + ResourcePath path("textures/player.png"); + EXPECT_TRUE(path.IsValid()); + EXPECT_EQ(path.GetPath(), "textures/player.png"); +} + +TEST(ResourcePath, ConstructorWithString) { + String str = "models/player.fbx"; + ResourcePath path(str); + EXPECT_TRUE(path.IsValid()); + EXPECT_EQ(path.GetPath(), str); +} + +TEST(ResourcePath, GetExtension) { + ResourcePath path("textures/player.png"); + EXPECT_EQ(path.GetExtension(), ".png"); +} + +TEST(ResourcePath, GetExtensionNoExtension) { + ResourcePath path("textures/player"); + EXPECT_TRUE(path.GetExtension().Empty()); +} + +TEST(ResourcePath, GetStem) { + ResourcePath path("textures/player.png"); + EXPECT_EQ(path.GetStem(), "player"); +} + +TEST(ResourcePath, GetStemNoExtension) { + ResourcePath path("textures/player"); + EXPECT_EQ(path.GetStem(), "player"); +} + +TEST(ResourcePath, GetFileName) { + ResourcePath path("textures/player.png"); + EXPECT_EQ(path.GetFileName(), "player.png"); +} + +TEST(ResourcePath, GetDirectory) { + ResourcePath path("textures/player.png"); + EXPECT_EQ(path.GetDirectory(), "textures"); +} + +TEST(ResourcePath, GetDirectoryWithBackslash) { + ResourcePath path("textures\\player.png"); + EXPECT_EQ(path.GetDirectory(), "textures"); +} + +TEST(ResourcePath, GetFullPath) { + ResourcePath path("textures/player.png"); + EXPECT_EQ(path.GetFullPath(), "textures/player.png"); +} + +TEST(ResourcePath, HasExtension) { + ResourcePath path("textures/player.png"); + EXPECT_TRUE(path.HasExtension(".png")); + EXPECT_FALSE(path.HasExtension(".jpg")); +} + +TEST(ResourcePath, HasExtensionNoExtension) { + ResourcePath path("textures/player"); + EXPECT_FALSE(path.HasExtension(".png")); +} + +TEST(ResourcePath, HasAnyExtension) { + ResourcePath path("textures/player.png"); + const char* extensions[] = { ".jpg", ".png", ".tga" }; + EXPECT_TRUE(path.HasAnyExtension(extensions, 3)); +} + +TEST(ResourcePath, HasAnyExtensionNoMatch) { + ResourcePath path("textures/player.png"); + const char* extensions[] = { ".jpg", ".tga", ".bmp" }; + EXPECT_FALSE(path.HasAnyExtension(extensions, 3)); +} + +TEST(ResourcePath, ToGUID) { + ResourcePath path("textures/player.png"); + ResourceGUID guid = path.ToGUID(); + EXPECT_TRUE(guid.IsValid()); +} + +TEST(ResourcePath, SetPath) { + ResourcePath path; + path.SetPath("textures/player.png"); + EXPECT_TRUE(path.IsValid()); + EXPECT_EQ(path.GetPath(), "textures/player.png"); +} + +TEST(ResourcePath, GetRelativePath) { + ResourcePath path("textures/player.png"); + EXPECT_EQ(path.GetRelativePath(), "textures/player.png"); +} + +} // namespace diff --git a/tests/Resources/test_texture_import_settings.cpp b/tests/Resources/test_texture_import_settings.cpp new file mode 100644 index 00000000..4614d780 --- /dev/null +++ b/tests/Resources/test_texture_import_settings.cpp @@ -0,0 +1,119 @@ +#include +#include +#include + +using namespace XCEngine::Resources; + +namespace { + +TEST(TextureImportSettings, DefaultConstructor) { + TextureImportSettings settings; + EXPECT_EQ(settings.GetTextureType(), TextureType::Texture2D); + EXPECT_EQ(settings.GetTargetFormat(), TextureFormat::Unknown); + EXPECT_TRUE(settings.GetGenerateMipmaps()); + EXPECT_EQ(settings.GetMipmapFilter(), MipmapFilter::Box); + EXPECT_EQ(settings.GetMaxAnisotropy(), 16u); + EXPECT_FALSE(settings.GetSRGB()); + EXPECT_FALSE(settings.GetFlipVertical()); + EXPECT_FALSE(settings.GetFlipHorizontal()); + EXPECT_EQ(settings.GetCompressionQuality(), CompressionQuality::High); + EXPECT_TRUE(settings.GetUseHardwareCompression()); + EXPECT_EQ(settings.GetMaxSize(), 0u); + EXPECT_FALSE(settings.GetGenerateNormalMap()); + EXPECT_FLOAT_EQ(settings.GetNormalMapStrength(), 1.0f); +} + +TEST(TextureImportSettings, SetTextureType) { + TextureImportSettings settings; + settings.SetTextureType(TextureType::TextureCube); + EXPECT_EQ(settings.GetTextureType(), TextureType::TextureCube); +} + +TEST(TextureImportSettings, SetTargetFormat) { + TextureImportSettings settings; + settings.SetTargetFormat(TextureFormat::BC7_UNORM_SRGB); + EXPECT_EQ(settings.GetTargetFormat(), TextureFormat::BC7_UNORM_SRGB); +} + +TEST(TextureImportSettings, SetGenerateMipmaps) { + TextureImportSettings settings; + settings.SetGenerateMipmaps(false); + EXPECT_FALSE(settings.GetGenerateMipmaps()); +} + +TEST(TextureImportSettings, SetMipmapFilter) { + TextureImportSettings settings; + settings.SetMipmapFilter(MipmapFilter::Kaiser); + EXPECT_EQ(settings.GetMipmapFilter(), MipmapFilter::Kaiser); +} + +TEST(TextureImportSettings, SetMaxAnisotropy) { + TextureImportSettings settings; + settings.SetMaxAnisotropy(8); + EXPECT_EQ(settings.GetMaxAnisotropy(), 8u); +} + +TEST(TextureImportSettings, SetSRGB) { + TextureImportSettings settings; + settings.SetSRGB(true); + EXPECT_TRUE(settings.GetSRGB()); +} + +TEST(TextureImportSettings, SetFlipVertical) { + TextureImportSettings settings; + settings.SetFlipVertical(true); + EXPECT_TRUE(settings.GetFlipVertical()); +} + +TEST(TextureImportSettings, SetFlipHorizontal) { + TextureImportSettings settings; + settings.SetFlipHorizontal(true); + EXPECT_TRUE(settings.GetFlipHorizontal()); +} + +TEST(TextureImportSettings, SetCompressionQuality) { + TextureImportSettings settings; + settings.SetCompressionQuality(CompressionQuality::Low); + EXPECT_EQ(settings.GetCompressionQuality(), CompressionQuality::Low); +} + +TEST(TextureImportSettings, SetUseHardwareCompression) { + TextureImportSettings settings; + settings.SetUseHardwareCompression(false); + EXPECT_FALSE(settings.GetUseHardwareCompression()); +} + +TEST(TextureImportSettings, SetMaxSize) { + TextureImportSettings settings; + settings.SetMaxSize(2048); + EXPECT_EQ(settings.GetMaxSize(), 2048u); +} + +TEST(TextureImportSettings, SetGenerateNormalMap) { + TextureImportSettings settings; + settings.SetGenerateNormalMap(true); + EXPECT_TRUE(settings.GetGenerateNormalMap()); +} + +TEST(TextureImportSettings, SetNormalMapStrength) { + TextureImportSettings settings; + settings.SetNormalMapStrength(2.0f); + EXPECT_FLOAT_EQ(settings.GetNormalMapStrength(), 2.0f); +} + +TEST(TextureImportSettings, Clone) { + TextureImportSettings settings; + settings.SetTextureType(TextureType::TextureCube); + settings.SetSRGB(true); + settings.SetMaxAnisotropy(8); + + auto cloned = settings.Clone(); + ASSERT_NE(cloned, nullptr); + + TextureImportSettings* clonedSettings = static_cast(cloned.get()); + EXPECT_EQ(clonedSettings->GetTextureType(), TextureType::TextureCube); + EXPECT_TRUE(clonedSettings->GetSRGB()); + EXPECT_EQ(clonedSettings->GetMaxAnisotropy(), 8u); +} + +} // namespace