导入更新

This commit is contained in:
Rowland 2026-06-16 10:30:12 +08:00
parent 0df9b93ce2
commit a31f700d75
14 changed files with 21580 additions and 14 deletions

View File

@ -465,6 +465,7 @@ set(METACORE_EDITOR_PRIVATE_HEADERS
Source/MetaCoreEditor/Private/MetaCoreBuiltinEditorModule.h
Source/MetaCoreEditor/Private/MetaCoreEditorCameraController.h
Source/MetaCoreEditor/Private/MetaCoreGltfImporter.h
Source/MetaCoreEditor/Private/MetaCoreLocalCgltf.h
third_party/ImGuizmo/ImGuizmo.h
third_party/cgltf/cgltf.h
third_party/stb/stb_image.h
@ -481,6 +482,7 @@ set(METACORE_EDITOR_SOURCES
Source/MetaCoreEditor/Private/MetaCoreEditorServices.cpp
Source/MetaCoreEditor/Private/MetaCoreEditorModule.cpp
Source/MetaCoreEditor/Private/MetaCoreSceneInteractionService.cpp
Source/MetaCoreEditor/Private/MetaCoreLocalCgltf.cpp
third_party/ImGuizmo/ImGuizmo.cpp
third_party/stb/stb_image_impl.cpp
)

View File

@ -1,17 +1,17 @@
{
"AlphaCutoff": 0.5,
"AlphaMode": 0,
"AlphaMode": 2,
"AoTexture": "",
"AssetGuid": "fc3fd465-4f39-44af-907a-4fc0494c2502",
"BaseColor": [
1.0,
0.8078431487083435,
0.5843137502670288
0.9686274528503418,
0.16862745583057404
],
"BaseColorTexture": "",
"DoubleSided": false,
"EmissiveColor": [
0.0,
0.29019609093666077,
0.0,
0.0
],

View File

@ -3,6 +3,6 @@
"guid": "fc3fd465-4f39-44af-907a-4fc0494c2502",
"importer_id": "MaterialImporter",
"package_path": "Assets/Materials/Material 1.mcmaterial.json",
"source_hash": 1388934689574133717,
"source_hash": 491201104691168908,
"source_path": "Assets/Materials/Material 1.mcmaterial.json"
}

View File

@ -0,0 +1,26 @@
{
"AlphaCutoff": 0.5,
"AlphaMode": 0,
"AoTexture": "",
"AssetGuid": "3bd687c0-2570-4236-bd65-0f774b13d34f",
"BaseColor": [
0.42352941632270813,
0.800000011920929,
0.7137255072593689
],
"BaseColorTexture": "",
"DoubleSided": false,
"EmissiveColor": [
0.0,
0.0,
0.0
],
"EmissiveTexture": "",
"Metallic": 0.4490000009536743,
"MetallicRoughnessTexture": "",
"Name": "Material 6",
"NormalTexture": "",
"Roughness": 1.0,
"ShaderModel": 0,
"StableImportKey": ""
}

View File

@ -0,0 +1,8 @@
{
"asset_type": "material",
"guid": "3bd687c0-2570-4236-bd65-0f774b13d34f",
"importer_id": "MaterialImporter",
"package_path": "Assets/Materials/Material 6.mcmaterial.json",
"source_hash": 2546970018452484703,
"source_path": "Assets/Materials/Material 6.mcmaterial.json"
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,450 @@
{
"asset_type": "model",
"dependencies": [
"f18830da-5294-9e8e-aaa5-d3537fd1d002",
"282c1bfc-dc10-a39d-c18f-1d7104968dcc",
"c1b44106-ad1d-249f-8ed8-731fa2e3f52e",
"c37682bd-9ab5-b22c-8c6b-b1eae22a69d4",
"1109cd8d-20cc-4d8c-725c-2750adcac57b",
"615bcd0e-8bfb-79b3-96a6-f3b08316277f",
"57a5c5d4-d6ac-a0ee-a328-0af99b40744a",
"bd4ad35c-020e-0584-731a-ef4f78414367",
"ce5d5607-8b26-eaa4-1c84-f7d94d912f80",
"72ca6247-5509-a7a2-89d7-a2365caaca31",
"50a2e3b1-d681-5bb1-23e9-75dd526063f5",
"93567d26-6790-c3af-d09f-549622191572",
"0ce54ecd-da82-0fcc-2e2e-0f8316a0e93b",
"e13656af-f25f-5787-3622-ce67f83ff83f",
"df62d413-62d2-24e0-89fd-96d21d8a1be2",
"893d9e7b-6793-eaca-08fd-35767c998b64",
"9f2cbe71-c502-5066-59ad-9162b53fc608",
"547655f1-8498-b52c-20b7-b2293b8a20d5",
"3c8ef566-5571-4e8a-524f-a038440c7ffd",
"4671b76e-c3e7-adc6-f68d-09beed118b58",
"1456acb0-337f-68e3-703f-d9ee28079330",
"029831e8-427c-157c-5dad-96e56f877099",
"0eb58efe-5a57-57bb-ac0a-0b54a260fa7e",
"1a4255e9-6c51-f79f-ffe7-8f3f9beb2479",
"378d9d2f-4d9d-ce70-dbf2-e2554c1b1260",
"27787685-d1fb-ed69-8f0e-46836905163f",
"ed84cf04-a9d9-cd83-b76f-86b8a4b5a656",
"30dc781f-17a8-8196-dbcd-32f238538a11",
"43449f5d-99bc-3bc5-ecf4-f25b791c0484",
"bdc29545-b1f6-3c7f-732c-9fbbee8332cf",
"4539f449-aeaf-b3da-3517-341f4ecd297e",
"0abd5c88-049f-827a-abfd-2708416bcbfa",
"06e7bec5-dc18-ec2e-26ad-e02d16d02ea9",
"459443fc-022c-64d7-7551-69eb20bb8118",
"25160c14-1bfd-5118-8d4b-311b75acc4c3",
"2737c4e0-5536-8827-4f91-b7103a18798b",
"f0ad76e0-f916-a7b8-ab5b-8b3c611956a0",
"a0c115e7-f940-55c3-e766-7f61e35a7204",
"f577527a-02b6-fa60-e91d-3500830f1777",
"2bafa06a-3494-5f93-426a-a860bee9e12e",
"c1bdb8de-36f0-fa5d-4ed3-aa7311a5c60a",
"474bab4f-e853-88a4-3738-590a98c9b0a8"
],
"guid": "b72a0c12-d6fd-4999-86c5-958e3bac1c78",
"importer_id": "GltfModelImporter",
"package_path": "Assets/Models/超精密磨床.glb.mcasset",
"source_hash": 4002013065180687563,
"source_path": "Assets/Models/超精密磨床.glb",
"sub_assets": [
{
"guid": "f18830da-5294-9e8e-aaa5-d3537fd1d002",
"index": 0,
"name": "柱体.013",
"stable_import_key": "mesh:柱体.013:0",
"type": "mesh"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "282c1bfc-dc10-a39d-c18f-1d7104968dcc",
"index": 0,
"name": "金属",
"stable_import_key": "material:金属:0",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "c1b44106-ad1d-249f-8ed8-731fa2e3f52e",
"index": 1,
"name": "black2",
"stable_import_key": "material:black2:1",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "c37682bd-9ab5-b22c-8c6b-b1eae22a69d4",
"index": 2,
"name": "警戒带",
"stable_import_key": "material:警戒带:2",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "1109cd8d-20cc-4d8c-725c-2750adcac57b",
"index": 3,
"name": "LIGHTSTEELBLUE2",
"stable_import_key": "material:LIGHTSTEELBLUE2:3",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "615bcd0e-8bfb-79b3-96a6-f3b08316277f",
"index": 4,
"name": "BASE.001",
"stable_import_key": "material:BASE.001:4",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "57a5c5d4-d6ac-a0ee-a328-0af99b40744a",
"index": 5,
"name": "3BLUE.008",
"stable_import_key": "material:3BLUE.008:5",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "bd4ad35c-020e-0584-731a-ef4f78414367",
"index": 6,
"name": "black2.001",
"stable_import_key": "material:black2.001:6",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "ce5d5607-8b26-eaa4-1c84-f7d94d912f80",
"index": 7,
"name": "BASE.003",
"stable_import_key": "material:BASE.003:7",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "72ca6247-5509-a7a2-89d7-a2365caaca31",
"index": 8,
"name": "WHITE",
"stable_import_key": "material:WHITE:8",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "50a2e3b1-d681-5bb1-23e9-75dd526063f5",
"index": 9,
"name": "3BLUE.001",
"stable_import_key": "material:3BLUE.001:9",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "93567d26-6790-c3af-d09f-549622191572",
"index": 10,
"name": "BASE.004",
"stable_import_key": "material:BASE.004:10",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "0ce54ecd-da82-0fcc-2e2e-0f8316a0e93b",
"index": 11,
"name": "black3.003",
"stable_import_key": "material:black3.003:11",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "e13656af-f25f-5787-3622-ce67f83ff83f",
"index": 12,
"name": "GRAY",
"stable_import_key": "material:GRAY:12",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "df62d413-62d2-24e0-89fd-96d21d8a1be2",
"index": 13,
"name": "inside1.001",
"stable_import_key": "material:inside1.001:13",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "893d9e7b-6793-eaca-08fd-35767c998b64",
"index": 14,
"name": "1亚克力玻璃.001",
"stable_import_key": "material:1亚克力玻璃.001:14",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "9f2cbe71-c502-5066-59ad-9162b53fc608",
"index": 15,
"name": "GRAY25",
"stable_import_key": "material:GRAY25:15",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "547655f1-8498-b52c-20b7-b2293b8a20d5",
"index": 16,
"name": "BLUE.002",
"stable_import_key": "material:BLUE.002:16",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "3c8ef566-5571-4e8a-524f-a038440c7ffd",
"index": 17,
"name": "BASE.006",
"stable_import_key": "material:BASE.006:17",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "4671b76e-c3e7-adc6-f68d-09beed118b58",
"index": 18,
"name": "3BLUE.007",
"stable_import_key": "material:3BLUE.007:18",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "1456acb0-337f-68e3-703f-d9ee28079330",
"index": 19,
"name": "3BLUE.020",
"stable_import_key": "material:3BLUE.020:19",
"type": "material"
},
{
"dependencies": [
"f0ad76e0-f916-a7b8-ab5b-8b3c611956a0"
],
"guid": "029831e8-427c-157c-5dad-96e56f877099",
"index": 20,
"name": "标识1",
"stable_import_key": "material:标识1:20",
"type": "material"
},
{
"dependencies": [
"a0c115e7-f940-55c3-e766-7f61e35a7204"
],
"guid": "0eb58efe-5a57-57bb-ac0a-0b54a260fa7e",
"index": 21,
"name": "标识2",
"stable_import_key": "material:标识2:21",
"type": "material"
},
{
"dependencies": [
"f577527a-02b6-fa60-e91d-3500830f1777"
],
"guid": "1a4255e9-6c51-f79f-ffe7-8f3f9beb2479",
"index": 22,
"name": "biaoshi",
"stable_import_key": "material:biaoshi:22",
"type": "material"
},
{
"dependencies": [
"2bafa06a-3494-5f93-426a-a860bee9e12e"
],
"guid": "378d9d2f-4d9d-ce70-dbf2-e2554c1b1260",
"index": 23,
"name": "biaoshi2",
"stable_import_key": "material:biaoshi2:23",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "27787685-d1fb-ed69-8f0e-46836905163f",
"index": 24,
"name": "10 - Default.001",
"stable_import_key": "material:10 - Default.001:24",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "ed84cf04-a9d9-cd83-b76f-86b8a4b5a656",
"index": 25,
"name": "BASE",
"stable_import_key": "material:BASE:25",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "30dc781f-17a8-8196-dbcd-32f238538a11",
"index": 26,
"name": "green",
"stable_import_key": "material:green:26",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "43449f5d-99bc-3bc5-ecf4-f25b791c0484",
"index": 27,
"name": "red",
"stable_import_key": "material:red:27",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "bdc29545-b1f6-3c7f-732c-9fbbee8332cf",
"index": 28,
"name": "yellow",
"stable_import_key": "material:yellow:28",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "4539f449-aeaf-b3da-3517-341f4ecd297e",
"index": 29,
"name": "black",
"stable_import_key": "material:black:29",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "0abd5c88-049f-827a-abfd-2708416bcbfa",
"index": 30,
"name": "深蓝",
"stable_import_key": "material:深蓝:30",
"type": "material"
},
{
"dependencies": [
"2737c4e0-5536-8827-4f91-b7103a18798b"
],
"guid": "06e7bec5-dc18-ec2e-26ad-e02d16d02ea9",
"index": 31,
"name": "10 - Default.002",
"stable_import_key": "material:10 - Default.002:31",
"type": "material"
},
{
"dependencies": [
"c1bdb8de-36f0-fa5d-4ed3-aa7311a5c60a"
],
"guid": "459443fc-022c-64d7-7551-69eb20bb8118",
"index": 32,
"name": "屏幕1",
"stable_import_key": "material:屏幕1:32",
"type": "material"
},
{
"dependencies": [
"474bab4f-e853-88a4-3738-590a98c9b0a8"
],
"guid": "25160c14-1bfd-5118-8d4b-311b75acc4c3",
"index": 33,
"name": "屏幕2",
"stable_import_key": "material:屏幕2:33",
"type": "material"
},
{
"guid": "2737c4e0-5536-8827-4f91-b7103a18798b",
"index": 0,
"name": "gw_01ksprnfbrd8f87vst8zv70f2v-0",
"stable_import_key": "texture:gw_01ksprnfbrd8f87vst8zv70f2v-0:0",
"type": "texture"
},
{
"guid": "f0ad76e0-f916-a7b8-ab5b-8b3c611956a0",
"index": 1,
"name": "标识2",
"stable_import_key": "texture:标识2:1",
"type": "texture"
},
{
"guid": "a0c115e7-f940-55c3-e766-7f61e35a7204",
"index": 2,
"name": "标识1",
"stable_import_key": "texture:标识1:2",
"type": "texture"
},
{
"guid": "f577527a-02b6-fa60-e91d-3500830f1777",
"index": 3,
"name": "biaoshi",
"stable_import_key": "texture:biaoshi:3",
"type": "texture"
},
{
"guid": "2bafa06a-3494-5f93-426a-a860bee9e12e",
"index": 4,
"name": "biaoshi1",
"stable_import_key": "texture:biaoshi1:4",
"type": "texture"
},
{
"guid": "c1bdb8de-36f0-fa5d-4ed3-aa7311a5c60a",
"index": 5,
"name": "FNWDxlh9RuSu21mfjCRg8_original",
"stable_import_key": "texture:FNWDxlh9RuSu21mfjCRg8_original:5",
"type": "texture"
},
{
"guid": "474bab4f-e853-88a4-3738-590a98c9b0a8",
"index": 6,
"name": "D49_CzDaVXaSWt_WgEhta_original",
"stable_import_key": "texture:D49_CzDaVXaSWt_WgEhta_original:6",
"type": "texture"
}
]
}

View File

@ -4497,6 +4497,8 @@ void MetaCorePublishAssetRecordChanges(
);
materialAsset.Name = absoluteSourcePath.stem().string() + "_Material";
materialAsset.StableImportKey = MetaCoreBuildStableImportKey("material", materialAsset.Name, 0);
materialAsset.Metallic = 0.0F;
materialAsset.Roughness = 0.0F;
document.GeneratedMaterialAssets.push_back(std::move(materialAsset));
document.ImportReport.UsedFallback = true;

View File

@ -1,9 +1,10 @@
#include "MetaCoreGltfImporter.h"
#include "MetaCoreFoundation/MetaCoreHash.h"
#include <cgltf.h>
#include "MetaCoreLocalCgltf.h"
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <nlohmann/json.hpp>
#include <filesystem>
#include <vector>
@ -327,6 +328,44 @@ void MetaCoreAppendUtf8Codepoint(std::string& output, std::uint32_t codepoint) {
return MetaCoreDecodeJsonEscapedUtf8(rawName);
}
struct MetaCoreGltfMaterialScalarPresence {
bool HasMetallicFactor = false;
bool HasRoughnessFactor = false;
};
[[nodiscard]] std::vector<MetaCoreGltfMaterialScalarPresence> MetaCoreReadGltfMaterialScalarPresence(
const cgltf_data* data
) {
if (data == nullptr || data->json == nullptr || data->json_size == 0) {
return {};
}
const nlohmann::json root = nlohmann::json::parse(data->json, data->json + data->json_size, nullptr, false);
if (root.is_discarded() || !root.is_object()) {
return {};
}
const auto materialsIterator = root.find("materials");
if (materialsIterator == root.end() || !materialsIterator->is_array()) {
return {};
}
std::vector<MetaCoreGltfMaterialScalarPresence> presence;
presence.reserve(materialsIterator->size());
for (const nlohmann::json& material : *materialsIterator) {
MetaCoreGltfMaterialScalarPresence entry{};
if (material.is_object()) {
const auto pbrIterator = material.find("pbrMetallicRoughness");
if (pbrIterator != material.end() && pbrIterator->is_object()) {
entry.HasMetallicFactor = pbrIterator->contains("metallicFactor");
entry.HasRoughnessFactor = pbrIterator->contains("roughnessFactor");
}
}
presence.push_back(entry);
}
return presence;
}
// --- GLTF 核心导入逻辑 ---
[[nodiscard]] MetaCoreModelAssetDocument MetaCoreBuildImportedGltfAssetDocument(
@ -399,6 +438,8 @@ void MetaCoreAppendUtf8Codepoint(std::string& output, std::uint32_t codepoint) {
genMat.AssetGuid = MetaCoreMakeDeterministicGeneratedAssetGuid(relativeSourcePath, "material", "PumpMaterial", 0);
genMat.Name = "PumpMaterial";
genMat.StableImportKey = MetaCoreBuildStableImportKey("material", "PumpMaterial", 0);
genMat.Metallic = 0.0F;
genMat.Roughness = 0.0F;
genMat.BaseColorTexture = genTex.AssetGuid;
genMat.BaseColor = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
document.GeneratedMaterialAssets.push_back(genMat);
@ -475,6 +516,8 @@ void MetaCoreAppendUtf8Codepoint(std::string& output, std::uint32_t codepoint) {
genMat.AssetGuid = MetaCoreMakeDeterministicGeneratedAssetGuid(relativeSourcePath, "material", "ValveMaterial", 0);
genMat.Name = "ValveMaterial";
genMat.StableImportKey = MetaCoreBuildStableImportKey("material", "ValveMaterial", 0);
genMat.Metallic = 0.0F;
genMat.Roughness = 0.0F;
genMat.BaseColorTexture = genTex.AssetGuid;
document.GeneratedMaterialAssets.push_back(genMat);
@ -550,6 +593,8 @@ void MetaCoreAppendUtf8Codepoint(std::string& output, std::uint32_t codepoint) {
genMat.AssetGuid = MetaCoreMakeDeterministicGeneratedAssetGuid(relativeSourcePath, "material", "EmbeddedTextureMaterial", 0);
genMat.Name = "EmbeddedTextureMaterial";
genMat.StableImportKey = MetaCoreBuildStableImportKey("material", "EmbeddedTextureMaterial", 0);
genMat.Metallic = 0.0F;
genMat.Roughness = 0.0F;
genMat.BaseColorTexture = genTex.AssetGuid;
document.GeneratedMaterialAssets.push_back(genMat);
@ -633,6 +678,8 @@ void MetaCoreAppendUtf8Codepoint(std::string& output, std::uint32_t codepoint) {
genMat.AssetGuid = MetaCoreMakeDeterministicGeneratedAssetGuid(relativeSourcePath, "material", "Tank_Material", 0);
genMat.Name = "Tank_Material";
genMat.StableImportKey = MetaCoreBuildStableImportKey("material", "Tank_Material", 0);
genMat.Metallic = 0.0F;
genMat.Roughness = 0.0F;
document.GeneratedMaterialAssets.push_back(genMat);
// 3. Node
@ -703,16 +750,33 @@ void MetaCoreAppendUtf8Codepoint(std::string& output, std::uint32_t codepoint) {
);
materialAsset.Name = absoluteSourcePath.stem().string() + "_Material";
materialAsset.StableImportKey = MetaCoreBuildStableImportKey("material", materialAsset.Name, 0);
materialAsset.Metallic = 0.0F;
materialAsset.Roughness = 0.0F;
document.GeneratedMaterialAssets.push_back(std::move(materialAsset));
};
MetaCoreGltfTrace("使用降级机制解析普通 GLTF 文件...");
addFallbackSkeleton();
MetaCoreFinalizeImportReport(document.ImportReport);
MetaCoreApplyModelImportSettings(document);
return document;
cgltf_data* data = nullptr;
cgltf_options options{};
const std::string sourcePathString = absoluteSourcePath.string();
cgltf_result result = cgltf_parse_file(&options, sourcePathString.c_str(), &data);
if (result != cgltf_result_success || data == nullptr) {
MetaCoreGltfTrace("GLTF 解析失败,使用降级骨架");
addFallbackSkeleton();
MetaCoreFinalizeImportReport(document.ImportReport);
MetaCoreApplyModelImportSettings(document);
return document;
}
result = cgltf_load_buffers(&options, data, sourcePathString.c_str());
if (result != cgltf_result_success) {
MetaCoreGltfTrace("GLTF Buffer 加载失败,使用降级骨架");
cgltf_free(data);
addFallbackSkeleton();
MetaCoreFinalizeImportReport(document.ImportReport);
MetaCoreApplyModelImportSettings(document);
return document;
}
if (data->images_count > 0) {
for (std::size_t i = 0; i < data->images_count; ++i) {
const cgltf_image& image = data->images[i];
@ -734,8 +798,14 @@ void MetaCoreAppendUtf8Codepoint(std::string& output, std::uint32_t codepoint) {
}
if (data->materials_count > 0) {
const std::vector<MetaCoreGltfMaterialScalarPresence> materialScalarPresence =
MetaCoreReadGltfMaterialScalarPresence(data);
for (std::size_t i = 0; i < data->materials_count; ++i) {
const cgltf_material& mat = data->materials[i];
const MetaCoreGltfMaterialScalarPresence scalarPresence =
i < materialScalarPresence.size()
? materialScalarPresence[i]
: MetaCoreGltfMaterialScalarPresence{};
MetaCoreImportedGltfMaterialDocument matDoc;
matDoc.Name = MetaCoreGltfDisplayName(mat.name, "Material_" + std::to_string(i));
matDoc.DoubleSided = mat.double_sided;
@ -747,11 +817,17 @@ void MetaCoreAppendUtf8Codepoint(std::string& output, std::uint32_t codepoint) {
genMat.DoubleSided = mat.double_sided;
genMat.AlphaCutoff = mat.alpha_cutoff;
genMat.AlphaMode = mat.alpha_mode == cgltf_alpha_mode_blend ? MetaCoreMaterialAlphaMode::Blend : (mat.alpha_mode == cgltf_alpha_mode_mask ? MetaCoreMaterialAlphaMode::Mask : MetaCoreMaterialAlphaMode::Opaque);
genMat.Metallic = 0.0F;
genMat.Roughness = 0.0F;
if (mat.has_pbr_metallic_roughness) {
genMat.BaseColor = glm::vec3(mat.pbr_metallic_roughness.base_color_factor[0], mat.pbr_metallic_roughness.base_color_factor[1], mat.pbr_metallic_roughness.base_color_factor[2]);
genMat.Metallic = mat.pbr_metallic_roughness.metallic_factor;
genMat.Roughness = mat.pbr_metallic_roughness.roughness_factor;
if (scalarPresence.HasMetallicFactor) {
genMat.Metallic = mat.pbr_metallic_roughness.metallic_factor;
}
if (scalarPresence.HasRoughnessFactor) {
genMat.Roughness = mat.pbr_metallic_roughness.roughness_factor;
}
if (mat.pbr_metallic_roughness.base_color_texture.texture) {
const std::int32_t texIdx = static_cast<std::int32_t>(mat.pbr_metallic_roughness.base_color_texture.texture->image - data->images);
@ -767,6 +843,28 @@ void MetaCoreAppendUtf8Codepoint(std::string& output, std::uint32_t codepoint) {
);
}
}
if (mat.pbr_metallic_roughness.metallic_roughness_texture.texture) {
const cgltf_image* image = mat.pbr_metallic_roughness.metallic_roughness_texture.texture->image;
const std::int32_t texIdx = image != nullptr
? static_cast<std::int32_t>(image - data->images)
: -1;
if (texIdx >= 0 && static_cast<std::size_t>(texIdx) < document.GeneratedTextureAssets.size()) {
genMat.MetallicRoughnessTexture = document.GeneratedTextureAssets[static_cast<std::size_t>(texIdx)].AssetGuid;
if (!scalarPresence.HasMetallicFactor) {
genMat.Metallic = mat.pbr_metallic_roughness.metallic_factor;
}
if (!scalarPresence.HasRoughnessFactor) {
genMat.Roughness = mat.pbr_metallic_roughness.roughness_factor;
}
} else {
MetaCoreAddImportMessage(
document.ImportReport,
MetaCoreImportMessageSeverity::Warning,
"missing_metallic_roughness_texture_reference",
"材质引用了超出范围的金属粗糙贴图,已跳过该贴图槽位"
);
}
}
}
if (matDoc.TextureIndices.empty() && !document.GeneratedTextureAssets.empty()) {
matDoc.TextureIndices.push_back(0);

View File

@ -0,0 +1,2 @@
#define CGLTF_IMPLEMENTATION
#include "MetaCoreLocalCgltf.h"

View File

@ -0,0 +1,41 @@
#pragma once
#define cgltf_parse metacore_cgltf_parse
#define cgltf_parse_file metacore_cgltf_parse_file
#define cgltf_load_buffers metacore_cgltf_load_buffers
#define cgltf_load_buffer_base64 metacore_cgltf_load_buffer_base64
#define cgltf_decode_string metacore_cgltf_decode_string
#define cgltf_decode_uri metacore_cgltf_decode_uri
#define cgltf_validate metacore_cgltf_validate
#define cgltf_free metacore_cgltf_free
#define cgltf_node_transform_local metacore_cgltf_node_transform_local
#define cgltf_node_transform_world metacore_cgltf_node_transform_world
#define cgltf_buffer_view_data metacore_cgltf_buffer_view_data
#define cgltf_find_accessor metacore_cgltf_find_accessor
#define cgltf_accessor_read_float metacore_cgltf_accessor_read_float
#define cgltf_accessor_read_uint metacore_cgltf_accessor_read_uint
#define cgltf_accessor_read_index metacore_cgltf_accessor_read_index
#define cgltf_num_components metacore_cgltf_num_components
#define cgltf_component_size metacore_cgltf_component_size
#define cgltf_calc_size metacore_cgltf_calc_size
#define cgltf_accessor_unpack_floats metacore_cgltf_accessor_unpack_floats
#define cgltf_accessor_unpack_indices metacore_cgltf_accessor_unpack_indices
#define cgltf_copy_extras_json metacore_cgltf_copy_extras_json
#define cgltf_mesh_index metacore_cgltf_mesh_index
#define cgltf_material_index metacore_cgltf_material_index
#define cgltf_accessor_index metacore_cgltf_accessor_index
#define cgltf_buffer_view_index metacore_cgltf_buffer_view_index
#define cgltf_buffer_index metacore_cgltf_buffer_index
#define cgltf_image_index metacore_cgltf_image_index
#define cgltf_texture_index metacore_cgltf_texture_index
#define cgltf_sampler_index metacore_cgltf_sampler_index
#define cgltf_skin_index metacore_cgltf_skin_index
#define cgltf_camera_index metacore_cgltf_camera_index
#define cgltf_light_index metacore_cgltf_light_index
#define cgltf_node_index metacore_cgltf_node_index
#define cgltf_scene_index metacore_cgltf_scene_index
#define cgltf_animation_index metacore_cgltf_animation_index
#define cgltf_animation_sampler_index metacore_cgltf_animation_sampler_index
#define cgltf_animation_channel_index metacore_cgltf_animation_channel_index
#include <cgltf.h>

View File

@ -1908,6 +1908,8 @@ void MetaCoreTestInstantiateImportedModelAssetIntoScene() {
"根节点 MeshRenderer 应保存基础颜色贴图路径"
);
MetaCoreExpect(instantiatedRoot.GetComponent<MetaCore::MetaCoreMeshRendererComponent>().BaseColor.x == 1.0F, "根节点应继承材质颜色通道数值");
MetaCoreExpect(std::abs(instantiatedRoot.GetComponent<MetaCore::MetaCoreMeshRendererComponent>().Metallic) < 0.0001F, "缺少金属度的导入材质 Metallic 应默认为 0");
MetaCoreExpect(std::abs(instantiatedRoot.GetComponent<MetaCore::MetaCoreMeshRendererComponent>().Roughness) < 0.0001F, "缺少粗糙度的导入材质 Roughness 应默认为 0");
MetaCoreExpect(editorContext.GetActiveObjectId() == *instantiatedRootId, "实例化后应正确选中新对象");
coreServicesModule->Shutdown(moduleRegistry);
@ -1916,6 +1918,109 @@ void MetaCoreTestInstantiateImportedModelAssetIntoScene() {
std::filesystem::remove_all(tempProjectRoot);
}
void MetaCoreTestInstantiateRealGltfHierarchyIntoScene() {
const std::filesystem::path tempProjectRoot =
std::filesystem::temp_directory_path() / "MetaCoreInstantiateRealGltfHierarchyProject";
std::filesystem::remove_all(tempProjectRoot);
std::filesystem::create_directories(tempProjectRoot / "Assets");
std::filesystem::create_directories(tempProjectRoot / "Scenes");
std::filesystem::create_directories(tempProjectRoot / "Library");
{
std::ofstream projectFile(tempProjectRoot / "MetaCore.project.json", std::ios::trunc);
projectFile << "{\n"
<< " \"name\": \"InstantiateRealGltfHierarchyProject\",\n"
<< " \"version\": \"0.1.0\",\n"
<< " \"scenes\": [],\n"
<< " \"startup_scene\": \"\"\n"
<< "}\n";
}
{
std::ofstream gltfFile(tempProjectRoot / "Assets" / "HierarchySample.gltf", std::ios::trunc);
gltfFile
<< "{\n"
<< " \"asset\": {\"version\": \"2.0\"},\n"
<< " \"scene\": 0,\n"
<< " \"scenes\": [{\"nodes\": [0]}],\n"
<< " \"nodes\": [\n"
<< " {\"name\": \"ImportedRoot\", \"children\": [1], \"translation\": [1.0, 2.0, 3.0]},\n"
<< " {\"name\": \"ImportedChild\", \"mesh\": 0, \"translation\": [0.0, 1.0, 0.0]}\n"
<< " ],\n"
<< " \"meshes\": [{\"name\": \"HierarchyMesh\", \"primitives\": [{\"material\": 0}]}],\n"
<< " \"materials\": [{\"name\": \"MissingScalarMaterial\", \"pbrMetallicRoughness\": {\"baseColorFactor\": [0.2, 0.4, 0.6, 1.0]}}]\n"
<< "}\n";
}
_putenv_s("METACORE_PROJECT_PATH", tempProjectRoot.string().c_str());
MetaCore::MetaCoreWindow window;
MetaCore::MetaCoreRenderDevice renderDevice;
MetaCore::MetaCoreEditorViewportRenderer viewportRenderer;
MetaCore::MetaCoreScene scene;
MetaCore::MetaCoreLogService logService;
MetaCore::MetaCoreEditorModuleRegistry moduleRegistry;
auto coreServicesModule = MetaCore::MetaCoreCreateBuiltinCoreServicesModule();
coreServicesModule->Startup(moduleRegistry);
MetaCore::MetaCoreEditorContext editorContext(
window,
renderDevice,
viewportRenderer,
scene,
logService,
moduleRegistry
);
const auto assetDatabase = moduleRegistry.ResolveService<MetaCore::MetaCoreIAssetDatabaseService>();
const auto sceneEditingService = moduleRegistry.ResolveService<MetaCore::MetaCoreISceneEditingService>();
MetaCoreExpect(assetDatabase != nullptr, "应解析到 AssetDatabaseService");
MetaCoreExpect(sceneEditingService != nullptr, "应解析到 SceneEditingService");
MetaCoreExpect(assetDatabase->Refresh(), "应能刷新真实 GLTF 层级测试项目");
const auto modelRecord =
assetDatabase->FindAssetByRelativePath(std::filesystem::path("Assets") / "HierarchySample.gltf");
MetaCoreExpect(modelRecord.has_value(), "应能找到真实 GLTF 层级模型资源");
const auto instantiatedRootId = sceneEditingService->InstantiateModelAsset(editorContext, modelRecord->Guid, std::nullopt);
MetaCoreExpect(instantiatedRootId.has_value(), "应能实例化真实 GLTF 层级模型");
const MetaCore::MetaCoreGameObject instantiatedRoot = scene.FindGameObject(*instantiatedRootId);
MetaCoreExpect(instantiatedRoot, "真实 GLTF 层级实例化后应能找到资产根对象");
MetaCoreExpect(instantiatedRoot.GetName() == "HierarchySample.gltf", "真实 GLTF 资产根对象应使用源文件名");
const std::vector<MetaCore::MetaCoreId> assetRootChildren = scene.GetChildrenOf(*instantiatedRootId);
MetaCoreExpect(assetRootChildren.size() == 1, "真实 GLTF 资产根对象下应保留导入根节点");
const MetaCore::MetaCoreGameObject importedRoot = scene.FindGameObject(assetRootChildren.front());
MetaCoreExpect(importedRoot, "应能找到真实 GLTF 导入根节点");
MetaCoreExpect(importedRoot.GetName() == "ImportedRoot", "真实 GLTF 导入根节点名称应保持");
MetaCoreExpect(importedRoot.GetParentId() == instantiatedRoot.GetId(), "真实 GLTF 导入根节点应挂在资产根对象下");
const std::vector<MetaCore::MetaCoreId> importedRootChildren = scene.GetChildrenOf(importedRoot.GetId());
MetaCoreExpect(importedRootChildren.size() == 1, "真实 GLTF 导入根节点下应保留子节点");
const MetaCore::MetaCoreGameObject importedChild = scene.FindGameObject(importedRootChildren.front());
MetaCoreExpect(importedChild, "应能找到真实 GLTF 子节点");
MetaCoreExpect(importedChild.GetName() == "ImportedChild", "真实 GLTF 子节点名称应保持");
MetaCoreExpect(importedChild.GetParentId() == importedRoot.GetId(), "真实 GLTF 子节点应挂在导入根节点下");
MetaCoreExpect(importedChild.HasComponent<MetaCore::MetaCoreMeshRendererComponent>(), "真实 GLTF 子节点应挂载 MeshRenderer");
const MetaCore::MetaCoreMeshRendererComponent& childMeshRenderer =
importedChild.GetComponent<MetaCore::MetaCoreMeshRendererComponent>();
MetaCoreExpectVec3Near(childMeshRenderer.BaseColor, glm::vec3(0.2F, 0.4F, 0.6F), "真实 GLTF 子节点应继承导入材质基础色");
MetaCoreExpect(std::abs(childMeshRenderer.Metallic) < 0.0001F, "真实 GLTF 材质缺少 metallicFactor 时 Metallic 应默认为 0");
MetaCoreExpect(std::abs(childMeshRenderer.Roughness) < 0.0001F, "真实 GLTF 材质缺少 roughnessFactor 时 Roughness 应默认为 0");
const std::vector<MetaCore::MetaCoreId> hierarchyOrder = scene.BuildHierarchyPreorder();
MetaCoreExpect(hierarchyOrder.size() == 3, "真实 GLTF 层级应进入层级树遍历结果");
MetaCoreExpect(hierarchyOrder[0] == instantiatedRoot.GetId(), "层级遍历应先返回资产根对象");
MetaCoreExpect(hierarchyOrder[1] == importedRoot.GetId(), "层级遍历应返回导入根节点");
MetaCoreExpect(hierarchyOrder[2] == importedChild.GetId(), "层级遍历应返回导入子节点");
coreServicesModule->Shutdown(moduleRegistry);
moduleRegistry.ShutdownServices();
_putenv_s("METACORE_PROJECT_PATH", "");
std::filesystem::remove_all(tempProjectRoot);
}
void MetaCoreTestInstantiateMultiNodeModelAssetIntoScene() {
const std::filesystem::path tempProjectRoot =
std::filesystem::temp_directory_path() / "MetaCoreInstantiateMultiNodeModelProject";
@ -4437,6 +4542,8 @@ int main() {
MetaCoreTestProjectDescriptorAndGltfImporterSkeleton();
std::cout << "[RUN] MetaCoreTestInstantiateImportedModelAssetIntoScene..." << std::endl;
MetaCoreTestInstantiateImportedModelAssetIntoScene();
std::cout << "[RUN] MetaCoreTestInstantiateRealGltfHierarchyIntoScene..." << std::endl;
MetaCoreTestInstantiateRealGltfHierarchyIntoScene();
std::cout << "[RUN] MetaCoreTestInstantiateMultiNodeModelAssetIntoScene..." << std::endl;
MetaCoreTestInstantiateMultiNodeModelAssetIntoScene();
std::cout << "[RUN] MetaCoreTestPrefabWorkflow..." << std::endl;