fix: restore backpack material import output

This commit is contained in:
2026-04-02 22:34:25 +08:00
parent 71923267e9
commit 5ff97b437a
13 changed files with 212 additions and 23 deletions

View File

@@ -6,6 +6,7 @@
#include <XCEngine/Resources/Material/Material.h>
#include <XCEngine/Resources/Texture/Texture.h>
#include <XCEngine/Resources/Texture/TextureLoader.h>
#include <XCEngine/Resources/Texture/TextureImportSettings.h>
#include <XCEngine/Core/Asset/ResourceManager.h>
#include <XCEngine/Core/Math/Matrix4.h>
#include <assimp/Importer.hpp>
@@ -14,6 +15,7 @@
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <algorithm>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <limits>
@@ -131,6 +133,22 @@ Containers::String BuildSubResourcePath(const Containers::String& sourcePath,
return Containers::String(path.c_str());
}
TextureImportSettings BuildMaterialTextureImportSettings(const char* propertyName) {
TextureImportSettings settings;
(void)propertyName;
settings.SetSRGB(false);
settings.SetTargetFormat(TextureFormat::RGBA8_UNORM);
return settings;
}
std::string BuildTextureCacheKey(const std::string& pathKey, const TextureImportSettings& settings) {
std::string cacheKey = pathKey;
cacheKey += settings.GetSRGB() ? "|srgb" : "|linear";
cacheKey += "|fmt=";
cacheKey += std::to_string(static_cast<int>(settings.GetTargetFormat()));
return cacheKey;
}
Containers::String GetResourceNameFromPath(const Containers::String& path) {
const std::filesystem::path filePath(path.CStr());
const std::string fileName = filePath.filename().string();
@@ -243,8 +261,9 @@ Texture* CreateRawTexture(const Containers::String& texturePath,
Texture* LoadEmbeddedTexture(const aiTexture& embeddedTexture,
const Containers::String& texturePath,
const TextureImportSettings& settings,
TextureImportContext& context) {
const std::string cacheKey(texturePath.CStr());
const std::string cacheKey = BuildTextureCacheKey(texturePath.CStr(), settings);
const auto cacheIt = context.textureCache.find(cacheKey);
if (cacheIt != context.textureCache.end()) {
return cacheIt->second;
@@ -254,7 +273,8 @@ Texture* LoadEmbeddedTexture(const aiTexture& embeddedTexture,
if (embeddedTexture.mHeight == 0) {
LoadResult result = context.textureLoader.LoadFromMemory(texturePath,
embeddedTexture.pcData,
embeddedTexture.mWidth);
embeddedTexture.mWidth,
&settings);
if (result) {
texture = static_cast<Texture*>(result.resource);
}
@@ -272,7 +292,11 @@ Texture* LoadEmbeddedTexture(const aiTexture& embeddedTexture,
}
texture = CreateRawTexture(texturePath,
TextureFormat::RGBA8_UNORM,
settings.GetTargetFormat() != TextureFormat::Unknown
? settings.GetTargetFormat()
: (settings.GetSRGB()
? TextureFormat::RGBA8_SRGB
: TextureFormat::RGBA8_UNORM),
embeddedTexture.mWidth,
embeddedTexture.mHeight,
rgbaPixels.data(),
@@ -288,25 +312,30 @@ Texture* LoadEmbeddedTexture(const aiTexture& embeddedTexture,
}
Texture* LoadExternalTexture(const std::filesystem::path& textureFilePath,
const TextureImportSettings& settings,
TextureImportContext& context) {
const std::string normalizedPath = textureFilePath.lexically_normal().string();
const auto cacheIt = context.textureCache.find(normalizedPath);
const std::string cacheKey = BuildTextureCacheKey(normalizedPath, settings);
const auto cacheIt = context.textureCache.find(cacheKey);
if (cacheIt != context.textureCache.end()) {
return cacheIt->second;
}
LoadResult result = context.textureLoader.Load(Containers::String(normalizedPath.c_str()));
LoadResult result = context.textureLoader.Load(Containers::String(normalizedPath.c_str()), &settings);
if (!result) {
return nullptr;
}
Texture* texture = static_cast<Texture*>(result.resource);
context.textureCache.emplace(normalizedPath, texture);
context.textureCache.emplace(cacheKey, texture);
context.ownedTextures.push_back(texture);
return texture;
}
Texture* LoadTextureReference(const aiString& textureReference, TextureImportContext& context) {
Texture* LoadTextureReference(
const aiString& textureReference,
const TextureImportSettings& settings,
TextureImportContext& context) {
if (textureReference.length == 0) {
return nullptr;
}
@@ -327,7 +356,7 @@ Texture* LoadTextureReference(const aiString& textureReference, TextureImportCon
"embedded_texture",
embeddedTextureIndex,
Containers::String(extension.c_str()));
return LoadEmbeddedTexture(*embeddedTexture, texturePath, context);
return LoadEmbeddedTexture(*embeddedTexture, texturePath, settings, context);
}
std::filesystem::path resolvedPath(textureReference.C_Str());
@@ -335,11 +364,12 @@ Texture* LoadTextureReference(const aiString& textureReference, TextureImportCon
resolvedPath = context.sourceDirectory / resolvedPath;
}
return LoadExternalTexture(resolvedPath, context);
return LoadExternalTexture(resolvedPath, settings, context);
}
Texture* LoadMaterialTexture(const aiMaterial& assimpMaterial,
std::initializer_list<aiTextureType> textureTypes,
const TextureImportSettings& settings,
TextureImportContext& context) {
for (aiTextureType textureType : textureTypes) {
if (assimpMaterial.GetTextureCount(textureType) == 0) {
@@ -351,7 +381,7 @@ Texture* LoadMaterialTexture(const aiMaterial& assimpMaterial,
continue;
}
Texture* texture = LoadTextureReference(texturePath, context);
Texture* texture = LoadTextureReference(texturePath, settings, context);
if (texture != nullptr) {
return texture;
}
@@ -360,12 +390,27 @@ Texture* LoadMaterialTexture(const aiMaterial& assimpMaterial,
return nullptr;
}
bool HasMaterialTexture(
const aiMaterial& assimpMaterial,
std::initializer_list<aiTextureType> textureTypes) {
for (aiTextureType textureType : textureTypes) {
if (assimpMaterial.GetTextureCount(textureType) > 0) {
return true;
}
}
return false;
}
void ImportMaterialProperties(const aiMaterial& assimpMaterial, Material& material) {
float opacity = 1.0f;
if (assimpMaterial.Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS) {
material.SetFloat("opacity", opacity);
}
const bool hasBaseColorTexture =
HasMaterialTexture(assimpMaterial, { aiTextureType_BASE_COLOR, aiTextureType_DIFFUSE });
aiColor4D baseColor;
if (assimpMaterial.Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR, baseColor) == AI_SUCCESS) {
material.SetFloat4("baseColor",
@@ -374,7 +419,9 @@ void ImportMaterialProperties(const aiMaterial& assimpMaterial, Material& materi
aiColor3D diffuseColor;
if (assimpMaterial.Get(AI_MATKEY_COLOR_DIFFUSE, diffuseColor) == AI_SUCCESS) {
material.SetFloat4("baseColor",
Math::Vector4(diffuseColor.r, diffuseColor.g, diffuseColor.b, opacity));
hasBaseColorTexture
? Math::Vector4(1.0f, 1.0f, 1.0f, opacity)
: Math::Vector4(diffuseColor.r, diffuseColor.g, diffuseColor.b, opacity));
}
}
@@ -416,7 +463,8 @@ void ImportMaterialTextures(const aiMaterial& assimpMaterial,
TextureImportContext& context) {
auto assignTexture = [&](const char* propertyName,
std::initializer_list<aiTextureType> textureTypes) {
Texture* texture = LoadMaterialTexture(assimpMaterial, textureTypes, context);
const TextureImportSettings settings = BuildMaterialTextureImportSettings(propertyName);
Texture* texture = LoadMaterialTexture(assimpMaterial, textureTypes, settings, context);
if (texture != nullptr) {
material.SetTexture(Containers::String(propertyName), ResourceHandle<Texture>(texture));
}